aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorLuciano Coelho <coelho@ti.com>2011-11-20 21:40:41 +0200
committerLuciano Coelho <coelho@ti.com>2012-04-12 08:43:55 +0300
commit90921014608d91a03766d0025fa32662dc7c5062 (patch)
treeadba69dd7be20600cdec0cc856263dc2ca3bfdb1 /drivers/net/wireless/wl12xx
parentwl12xx: increase scan timeout to 30s (diff)
downloadlinux-dev-90921014608d91a03766d0025fa32662dc7c5062.tar.xz
linux-dev-90921014608d91a03766d0025fa32662dc7c5062.zip
wireless/wl12xx/wl1251: move TI WLAN modules to a common ti subdirectory
Move wl12xx and wl1251 modules into a new drivers/net/wireless/ti directory. Add a TI WLAN Kconfig option and Makefile to support this change. Signed-off-by: Luciano Coelho <coelho@ti.com> Cc: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig48
-rw-r--r--drivers/net/wireless/wl12xx/Makefile15
-rw-r--r--drivers/net/wireless/wl12xx/acx.c1742
-rw-r--r--drivers/net/wireless/wl12xx/acx.h1314
-rw-r--r--drivers/net/wireless/wl12xx/boot.c794
-rw-r--r--drivers/net/wireless/wl12xx/boot.h120
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c1950
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h728
-rw-r--r--drivers/net/wireless/wl12xx/conf.h1326
-rw-r--r--drivers/net/wireless/wl12xx/debug.h102
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c1203
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.h33
-rw-r--r--drivers/net/wireless/wl12xx/event.c313
-rw-r--r--drivers/net/wireless/wl12xx/event.h141
-rw-r--r--drivers/net/wireless/wl12xx/ini.h220
-rw-r--r--drivers/net/wireless/wl12xx/init.c765
-rw-r--r--drivers/net/wireless/wl12xx/init.h39
-rw-r--r--drivers/net/wireless/wl12xx/io.c244
-rw-r--r--drivers/net/wireless/wl12xx/io.h181
-rw-r--r--drivers/net/wireless/wl12xx/main.c5633
-rw-r--r--drivers/net/wireless/wl12xx/ps.c304
-rw-r--r--drivers/net/wireless/wl12xx/ps.h41
-rw-r--r--drivers/net/wireless/wl12xx/reg.h555
-rw-r--r--drivers/net/wireless/wl12xx/rx.c284
-rw-r--r--drivers/net/wireless/wl12xx/rx.h132
-rw-r--r--drivers/net/wireless/wl12xx/scan.c790
-rw-r--r--drivers/net/wireless/wl12xx/scan.h233
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c378
-rw-r--r--drivers/net/wireless/wl12xx/spi.c442
-rw-r--r--drivers/net/wireless/wl12xx/testmode.c344
-rw-r--r--drivers/net/wireless/wl12xx/testmode.h31
-rw-r--r--drivers/net/wireless/wl12xx/tx.c1079
-rw-r--r--drivers/net/wireless/wl12xx/tx.h232
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h698
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h137
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_platform_data.c49
36 files changed, 0 insertions, 22640 deletions
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
deleted file mode 100644
index af08c8609c63..000000000000
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
-menuconfig WL12XX_MENU
- tristate "TI wl12xx driver support"
- depends on MAC80211 && EXPERIMENTAL
- ---help---
- This will enable TI wl12xx driver support for the following chips:
- wl1271, wl1273, wl1281 and wl1283.
- The drivers make use of the mac80211 stack.
-
-config WL12XX
- tristate "TI wl12xx support"
- depends on WL12XX_MENU && GENERIC_HARDIRQS
- depends on INET
- select FW_LOADER
- ---help---
- This module adds support for wireless adapters based on TI wl1271 and
- TI wl1273 chipsets. This module does *not* include support for wl1251.
- For wl1251 support, use the separate homonymous driver instead.
-
- If you choose to build a module, it will be called wl12xx. Say N if
- unsure.
-
-config WL12XX_SPI
- tristate "TI wl12xx SPI support"
- depends on WL12XX && SPI_MASTER
- select CRC7
- ---help---
- This module adds support for the SPI interface of adapters using
- TI wl12xx chipsets. Select this if your platform is using
- the SPI bus.
-
- If you choose to build a module, it'll be called wl12xx_spi.
- Say N if unsure.
-
-config WL12XX_SDIO
- tristate "TI wl12xx SDIO support"
- depends on WL12XX && MMC
- ---help---
- This module adds support for the SDIO interface of adapters using
- TI wl12xx chipsets. Select this if your platform is using
- the SDIO bus.
-
- If you choose to build a module, it'll be called wl12xx_sdio.
- Say N if unsure.
-
-config WL12XX_PLATFORM_DATA
- bool
- depends on WL12XX_SDIO != n || WL1251_SDIO != n
- default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
deleted file mode 100644
index 98f289c907a9..000000000000
--- a/drivers/net/wireless/wl12xx/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
- boot.o init.o debugfs.o scan.o
-
-wl12xx_spi-objs = spi.o
-wl12xx_sdio-objs = sdio.o
-
-wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
-obj-$(CONFIG_WL12XX) += wl12xx.o
-obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
-obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
-
-# small builtin driver bit
-obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
-
-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
deleted file mode 100644
index bc96db0683a5..000000000000
--- a/drivers/net/wireless/wl12xx/acx.c
+++ /dev/null
@@ -1,1742 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "acx.h"
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "wl12xx_80211.h"
-#include "reg.h"
-#include "ps.h"
-
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 wake_up_event, u8 listen_interval)
-{
- struct acx_wake_up_condition *wake_up;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)",
- wake_up_event, listen_interval);
-
- wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
- if (!wake_up) {
- ret = -ENOMEM;
- goto out;
- }
-
- wake_up->role_id = wlvif->role_id;
- wake_up->wake_up_event = wake_up_event;
- wake_up->listen_interval = listen_interval;
-
- ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
- wake_up, sizeof(*wake_up));
- if (ret < 0) {
- wl1271_warning("could not set wake up conditions: %d", ret);
- goto out;
- }
-
-out:
- kfree(wake_up);
- return ret;
-}
-
-int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
-{
- struct acx_sleep_auth *auth;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx sleep auth");
-
- auth = kzalloc(sizeof(*auth), GFP_KERNEL);
- if (!auth) {
- ret = -ENOMEM;
- goto out;
- }
-
- auth->sleep_auth = sleep_auth;
-
- ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
-
-out:
- kfree(auth);
- return ret;
-}
-
-int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- int power)
-{
- struct acx_current_tx_power *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power);
-
- if (power < 0 || power > 25)
- return -EINVAL;
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->current_tx_power = power * 10;
-
- ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("configure of tx power failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct acx_feature_config *feature;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx feature cfg");
-
- feature = kzalloc(sizeof(*feature), GFP_KERNEL);
- if (!feature) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
- feature->role_id = wlvif->role_id;
- feature->data_flow_options = 0;
- feature->options = 0;
-
- ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
- feature, sizeof(*feature));
- if (ret < 0) {
- wl1271_error("Couldnt set HW encryption");
- goto out;
- }
-
-out:
- kfree(feature);
- return ret;
-}
-
-int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
- size_t len)
-{
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx mem map");
-
- ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
-{
- struct acx_rx_msdu_lifetime *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
- ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("failed to set rx msdu life time: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_slot(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum acx_slot_type slot_time)
-{
- struct acx_slot *slot;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx slot");
-
- slot = kzalloc(sizeof(*slot), GFP_KERNEL);
- if (!slot) {
- ret = -ENOMEM;
- goto out;
- }
-
- slot->role_id = wlvif->role_id;
- slot->wone_index = STATION_WONE_INDEX;
- slot->slot_time = slot_time;
-
- ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
- if (ret < 0) {
- wl1271_warning("failed to set slot time: %d", ret);
- goto out;
- }
-
-out:
- kfree(slot);
- return ret;
-}
-
-int wl1271_acx_group_address_tbl(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable, void *mc_list, u32 mc_list_len)
-{
- struct acx_dot11_grp_addr_tbl *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx group address tbl");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* MAC filtering */
- acx->role_id = wlvif->role_id;
- acx->enabled = enable;
- acx->num_groups = mc_list_len;
- memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
-
- ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("failed to set group addr table: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_service_period_timeout(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct acx_rx_timeout *rx_timeout;
- int ret;
-
- rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
- if (!rx_timeout) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_ACX, "acx service period timeout");
-
- rx_timeout->role_id = wlvif->role_id;
- rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
- rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
-
- ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
- rx_timeout, sizeof(*rx_timeout));
- if (ret < 0) {
- wl1271_warning("failed to set service period timeout: %d",
- ret);
- goto out;
- }
-
-out:
- kfree(rx_timeout);
- return ret;
-}
-
-int wl1271_acx_rts_threshold(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u32 rts_threshold)
-{
- struct acx_rts_threshold *rts;
- int ret;
-
- /*
- * If the RTS threshold is not configured or out of range, use the
- * default value.
- */
- if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
- rts_threshold = wl->conf.rx.rts_threshold;
-
- wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
-
- rts = kzalloc(sizeof(*rts), GFP_KERNEL);
- if (!rts) {
- ret = -ENOMEM;
- goto out;
- }
-
- rts->role_id = wlvif->role_id;
- rts->threshold = cpu_to_le16((u16)rts_threshold);
-
- ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
- if (ret < 0) {
- wl1271_warning("failed to set rts threshold: %d", ret);
- goto out;
- }
-
-out:
- kfree(rts);
- return ret;
-}
-
-int wl1271_acx_dco_itrim_params(struct wl1271 *wl)
-{
- struct acx_dco_itrim_params *dco;
- struct conf_itrim_settings *c = &wl->conf.itrim;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
-
- dco = kzalloc(sizeof(*dco), GFP_KERNEL);
- if (!dco) {
- ret = -ENOMEM;
- goto out;
- }
-
- dco->enable = c->enable;
- dco->timeout = cpu_to_le32(c->timeout);
-
- ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
- dco, sizeof(*dco));
- if (ret < 0) {
- wl1271_warning("failed to set dco itrim parameters: %d", ret);
- goto out;
- }
-
-out:
- kfree(dco);
- return ret;
-}
-
-int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable_filter)
-{
- struct acx_beacon_filter_option *beacon_filter = NULL;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
-
- if (enable_filter &&
- wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
- goto out;
-
- beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
- if (!beacon_filter) {
- ret = -ENOMEM;
- goto out;
- }
-
- beacon_filter->role_id = wlvif->role_id;
- beacon_filter->enable = enable_filter;
-
- /*
- * When set to zero, and the filter is enabled, beacons
- * without the unicast TIM bit set are dropped.
- */
- beacon_filter->max_num_beacons = 0;
-
- ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
- beacon_filter, sizeof(*beacon_filter));
- if (ret < 0) {
- wl1271_warning("failed to set beacon filter opt: %d", ret);
- goto out;
- }
-
-out:
- kfree(beacon_filter);
- return ret;
-}
-
-int wl1271_acx_beacon_filter_table(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct acx_beacon_filter_ie_table *ie_table;
- int i, idx = 0;
- int ret;
- bool vendor_spec = false;
-
- wl1271_debug(DEBUG_ACX, "acx beacon filter table");
-
- ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
- if (!ie_table) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* configure default beacon pass-through rules */
- ie_table->role_id = wlvif->role_id;
- ie_table->num_ie = 0;
- for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
- struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
- ie_table->table[idx++] = r->ie;
- ie_table->table[idx++] = r->rule;
-
- if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
- /* only one vendor specific ie allowed */
- if (vendor_spec)
- continue;
-
- /* for vendor specific rules configure the
- additional fields */
- memcpy(&(ie_table->table[idx]), r->oui,
- CONF_BCN_IE_OUI_LEN);
- idx += CONF_BCN_IE_OUI_LEN;
- ie_table->table[idx++] = r->type;
- memcpy(&(ie_table->table[idx]), r->version,
- CONF_BCN_IE_VER_LEN);
- idx += CONF_BCN_IE_VER_LEN;
- vendor_spec = true;
- }
-
- ie_table->num_ie++;
- }
-
- ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
- ie_table, sizeof(*ie_table));
- if (ret < 0) {
- wl1271_warning("failed to set beacon filter table: %d", ret);
- goto out;
- }
-
-out:
- kfree(ie_table);
- return ret;
-}
-
-#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff
-
-int wl1271_acx_conn_monit_params(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable)
-{
- struct acx_conn_monit_params *acx;
- u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
- u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
- enable ? "enabled" : "disabled");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (enable) {
- threshold = wl->conf.conn.synch_fail_thold;
- timeout = wl->conf.conn.bss_lose_timeout;
- }
-
- acx->role_id = wlvif->role_id;
- acx->synch_fail_thold = cpu_to_le32(threshold);
- acx->bss_lose_timeout = cpu_to_le32(timeout);
-
- ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("failed to set connection monitor "
- "parameters: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-
-int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
-{
- struct acx_bt_wlan_coex *pta;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx sg enable");
-
- pta = kzalloc(sizeof(*pta), GFP_KERNEL);
- if (!pta) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (enable)
- pta->enable = wl->conf.sg.state;
- else
- pta->enable = CONF_SG_DISABLE;
-
- ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
- if (ret < 0) {
- wl1271_warning("failed to set softgemini enable: %d", ret);
- goto out;
- }
-
-out:
- kfree(pta);
- return ret;
-}
-
-int wl12xx_acx_sg_cfg(struct wl1271 *wl)
-{
- struct acx_bt_wlan_coex_param *param;
- struct conf_sg_settings *c = &wl->conf.sg;
- int i, ret;
-
- wl1271_debug(DEBUG_ACX, "acx sg cfg");
-
- param = kzalloc(sizeof(*param), GFP_KERNEL);
- if (!param) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* BT-WLAN coext parameters */
- for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
- param->params[i] = cpu_to_le32(c->params[i]);
- param->param_idx = CONF_SG_PARAMS_ALL;
-
- ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
- if (ret < 0) {
- wl1271_warning("failed to set sg config: %d", ret);
- goto out;
- }
-
-out:
- kfree(param);
- return ret;
-}
-
-int wl1271_acx_cca_threshold(struct wl1271 *wl)
-{
- struct acx_energy_detection *detection;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx cca threshold");
-
- detection = kzalloc(sizeof(*detection), GFP_KERNEL);
- if (!detection) {
- ret = -ENOMEM;
- goto out;
- }
-
- detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
- detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
-
- ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
- detection, sizeof(*detection));
- if (ret < 0)
- wl1271_warning("failed to set cca threshold: %d", ret);
-
-out:
- kfree(detection);
- return ret;
-}
-
-int wl1271_acx_bcn_dtim_options(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct acx_beacon_broadcast *bb;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
-
- bb = kzalloc(sizeof(*bb), GFP_KERNEL);
- if (!bb) {
- ret = -ENOMEM;
- goto out;
- }
-
- bb->role_id = wlvif->role_id;
- bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
- bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
- bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
- bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
-
- ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
- if (ret < 0) {
- wl1271_warning("failed to set rx config: %d", ret);
- goto out;
- }
-
-out:
- kfree(bb);
- return ret;
-}
-
-int wl1271_acx_aid(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid)
-{
- struct acx_aid *acx_aid;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx aid");
-
- acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
- if (!acx_aid) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx_aid->role_id = wlvif->role_id;
- acx_aid->aid = cpu_to_le16(aid);
-
- ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
- if (ret < 0) {
- wl1271_warning("failed to set aid: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx_aid);
- return ret;
-}
-
-int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
-{
- struct acx_event_mask *mask;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx event mbox mask");
-
- mask = kzalloc(sizeof(*mask), GFP_KERNEL);
- if (!mask) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* high event mask is unused */
- mask->high_event_mask = cpu_to_le32(0xffffffff);
- mask->event_mask = cpu_to_le32(event_mask);
-
- ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
- mask, sizeof(*mask));
- if (ret < 0) {
- wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
- goto out;
- }
-
-out:
- kfree(mask);
- return ret;
-}
-
-int wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum acx_preamble_type preamble)
-{
- struct acx_preamble *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx_set_preamble");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->preamble = preamble;
-
- ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of preamble failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum acx_ctsprotect_type ctsprotect)
-{
- struct acx_ctsprotect *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->ctsprotect = ctsprotect;
-
- ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of ctsprotect failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
-{
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx statistics");
-
- ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
- sizeof(*stats));
- if (ret < 0) {
- wl1271_warning("acx statistics failed: %d", ret);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct acx_rate_policy *acx;
- struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx rate policies");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
- wlvif->basic_rate, wlvif->rate_set);
-
- /* configure one basic rate class */
- acx->rate_policy_idx = cpu_to_le32(wlvif->sta.basic_rate_idx);
- acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate);
- acx->rate_policy.short_retry_limit = c->short_retry_limit;
- acx->rate_policy.long_retry_limit = c->long_retry_limit;
- acx->rate_policy.aflags = c->aflags;
-
- ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of rate policies failed: %d", ret);
- goto out;
- }
-
- /* configure one AP supported rate class */
- acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx);
- acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set);
- acx->rate_policy.short_retry_limit = c->short_retry_limit;
- acx->rate_policy.long_retry_limit = c->long_retry_limit;
- acx->rate_policy.aflags = c->aflags;
-
- ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of rate policies failed: %d", ret);
- goto out;
- }
-
- /*
- * configure one rate class for basic p2p operations.
- * (p2p packets should always go out with OFDM rates, even
- * if we are currently connected to 11b AP)
- */
- acx->rate_policy_idx = cpu_to_le32(wlvif->sta.p2p_rate_idx);
- acx->rate_policy.enabled_rates =
- cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P);
- acx->rate_policy.short_retry_limit = c->short_retry_limit;
- acx->rate_policy.long_retry_limit = c->long_retry_limit;
- acx->rate_policy.aflags = c->aflags;
-
- ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of rate policies failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
- u8 idx)
-{
- struct acx_rate_policy *acx;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
- idx, c->enabled_rates);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->rate_policy.enabled_rates = cpu_to_le32(c->enabled_rates);
- acx->rate_policy.short_retry_limit = c->short_retry_limit;
- acx->rate_policy.long_retry_limit = c->long_retry_limit;
- acx->rate_policy.aflags = c->aflags;
-
- acx->rate_policy_idx = cpu_to_le32(idx);
-
- ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of ap rate policy failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_ac_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop)
-{
- struct acx_ac_cfg *acx;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
- "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->ac = ac;
- acx->cw_min = cw_min;
- acx->cw_max = cpu_to_le16(cw_max);
- acx->aifsn = aifsn;
- acx->tx_op_limit = cpu_to_le16(txop);
-
- ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx ac cfg failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_tid_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 queue_id, u8 channel_type,
- u8 tsid, u8 ps_scheme, u8 ack_policy,
- u32 apsd_conf0, u32 apsd_conf1)
-{
- struct acx_tid_config *acx;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx tid config");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->queue_id = queue_id;
- acx->channel_type = channel_type;
- acx->tsid = tsid;
- acx->ps_scheme = ps_scheme;
- acx->ack_policy = ack_policy;
- acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
- acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
-
- ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of tid config failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
-{
- struct acx_frag_threshold *acx;
- int ret = 0;
-
- /*
- * If the fragmentation is not configured or out of range, use the
- * default value.
- */
- if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
- frag_threshold = wl->conf.tx.frag_threshold;
-
- wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
- ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of frag threshold failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_tx_config_options(struct wl1271 *wl)
-{
- struct acx_tx_config_options *acx;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx tx config options");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
- acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
- ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("Setting of tx options failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl12xx_acx_mem_cfg(struct wl1271 *wl)
-{
- struct wl12xx_acx_config_memory *mem_conf;
- struct conf_memory_settings *mem;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
-
- mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
- if (!mem_conf) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (wl->chip.id == CHIP_ID_1283_PG20)
- mem = &wl->conf.mem_wl128x;
- else
- mem = &wl->conf.mem_wl127x;
-
- /* memory config */
- mem_conf->num_stations = mem->num_stations;
- mem_conf->rx_mem_block_num = mem->rx_block_num;
- mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
- mem_conf->num_ssid_profiles = mem->ssid_profiles;
- mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
- mem_conf->dyn_mem_enable = mem->dynamic_memory;
- mem_conf->tx_free_req = mem->min_req_tx_blocks;
- mem_conf->rx_free_req = mem->min_req_rx_blocks;
- mem_conf->tx_min = mem->tx_min;
- mem_conf->fwlog_blocks = wl->conf.fwlog.mem_blocks;
-
- ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
- sizeof(*mem_conf));
- if (ret < 0) {
- wl1271_warning("wl1271 mem config failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(mem_conf);
- return ret;
-}
-
-int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
-{
- struct wl1271_acx_host_config_bitmap *bitmap_conf;
- int ret;
-
- bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
- if (!bitmap_conf) {
- ret = -ENOMEM;
- goto out;
- }
-
- bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
-
- ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
- bitmap_conf, sizeof(*bitmap_conf));
- if (ret < 0) {
- wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(bitmap_conf);
-
- return ret;
-}
-
-int wl1271_acx_init_mem_config(struct wl1271 *wl)
-{
- int ret;
-
- wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
- GFP_KERNEL);
- if (!wl->target_mem_map) {
- wl1271_error("couldn't allocate target memory map");
- return -ENOMEM;
- }
-
- /* we now ask for the firmware built memory map */
- ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
- sizeof(struct wl1271_acx_mem_map));
- if (ret < 0) {
- wl1271_error("couldn't retrieve firmware memory map");
- kfree(wl->target_mem_map);
- wl->target_mem_map = NULL;
- return ret;
- }
-
- /* initialize TX block book keeping */
- wl->tx_blocks_available =
- le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
- wl1271_debug(DEBUG_TX, "available tx blocks: %d",
- wl->tx_blocks_available);
-
- return 0;
-}
-
-int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
-{
- struct wl1271_acx_rx_config_opt *rx_conf;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
-
- rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
- if (!rx_conf) {
- ret = -ENOMEM;
- goto out;
- }
-
- rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
- rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
- rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
- rx_conf->queue_type = wl->conf.rx.queue_type;
-
- ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
- sizeof(*rx_conf));
- if (ret < 0) {
- wl1271_warning("wl1271 rx config opt failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(rx_conf);
- return ret;
-}
-
-int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable)
-{
- struct wl1271_acx_bet_enable *acx = NULL;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx bet enable");
-
- if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
- goto out;
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
- acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
-
- ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx bet enable failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_arp_ip_filter(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 enable, __be32 address)
-{
- struct wl1271_acx_arp_filter *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->version = ACX_IPV4_VERSION;
- acx->enable = enable;
-
- if (enable)
- memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
-
- ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("failed to set arp ip filter: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_pm_config(struct wl1271 *wl)
-{
- struct wl1271_acx_pm_config *acx = NULL;
- struct conf_pm_config_settings *c = &wl->conf.pm_config;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx pm config");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
- acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
-
- ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx pm config failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable)
-{
- struct wl1271_acx_keep_alive_mode *acx = NULL;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->enabled = enable;
-
- ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx keep alive mode failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_keep_alive_config(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 index, u8 tpl_valid)
-{
- struct wl1271_acx_keep_alive_config *acx = NULL;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx keep alive config");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
- acx->index = index;
- acx->tpl_validation = tpl_valid;
- acx->trigger = ACX_KEEP_ALIVE_NO_TX;
-
- ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx keep alive config failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable, s16 thold, u8 hyst)
-{
- struct wl1271_acx_rssi_snr_trigger *acx = NULL;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- wlvif->last_rssi_event = -1;
-
- acx->role_id = wlvif->role_id;
- acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
- acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
- acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
- if (enable)
- acx->enable = WL1271_ACX_TRIG_ENABLE;
- else
- acx->enable = WL1271_ACX_TRIG_DISABLE;
-
- acx->index = WL1271_ACX_TRIG_IDX_RSSI;
- acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
- acx->threshold = cpu_to_le16(thold);
- acx->hysteresis = hyst;
-
- ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
- struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->rssi_beacon = c->avg_weight_rssi_beacon;
- acx->rssi_data = c->avg_weight_rssi_data;
- acx->snr_beacon = c->avg_weight_snr_beacon;
- acx->snr_data = c->avg_weight_snr_data;
-
- ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
- struct ieee80211_sta_ht_cap *ht_cap,
- bool allow_ht_operation, u8 hlid)
-{
- struct wl1271_acx_ht_capabilities *acx;
- int ret = 0;
- u32 ht_capabilites = 0;
-
- wl1271_debug(DEBUG_ACX, "acx ht capabilities setting "
- "sta supp: %d sta cap: %d", ht_cap->ht_supported,
- ht_cap->cap);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (allow_ht_operation && ht_cap->ht_supported) {
- /* no need to translate capabilities - use the spec values */
- ht_capabilites = ht_cap->cap;
-
- /*
- * this bit is not employed by the spec but only by FW to
- * indicate peer HT support
- */
- ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;
-
- /* get data from A-MPDU parameters field */
- acx->ampdu_max_length = ht_cap->ampdu_factor;
- acx->ampdu_min_spacing = ht_cap->ampdu_density;
- }
-
- acx->hlid = hlid;
- acx->ht_capabilites = cpu_to_le32(ht_capabilites);
-
- ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx ht capabilities setting failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_set_ht_information(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- u16 ht_operation_mode)
-{
- struct wl1271_acx_ht_information *acx;
- int ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx ht information setting");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->role_id = wlvif->role_id;
- acx->ht_protection =
- (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
- acx->rifs_mode = 0;
- acx->gf_protection =
- !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
- acx->ht_tx_burst_limit = 0;
- acx->dual_cts_protection = 0;
-
- ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
-
- if (ret < 0) {
- wl1271_warning("acx ht information setting failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-/* Configure BA session initiator/receiver parameters setting in the FW. */
-int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct wl1271_acx_ba_initiator_policy *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx ba initiator policy");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* set for the current role */
- acx->role_id = wlvif->role_id;
- acx->tid_bitmap = wl->conf.ht.tx_ba_tid_bitmap;
- acx->win_size = wl->conf.ht.tx_ba_win_size;
- acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
-
- ret = wl1271_cmd_configure(wl,
- ACX_BA_SESSION_INIT_POLICY,
- acx,
- sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx ba initiator policy failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-/* setup BA session receiver setting in the FW. */
-int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
- u16 ssn, bool enable, u8 peer_hlid)
-{
- struct wl1271_acx_ba_receiver_setup *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx ba receiver session setting");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->hlid = peer_hlid;
- acx->tid = tid_index;
- acx->enable = enable;
- acx->win_size = wl->conf.ht.rx_ba_win_size;
- acx->ssn = ssn;
-
- ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx,
- sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx ba receiver session failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u64 *mactime)
-{
- struct wl12xx_acx_fw_tsf_information *tsf_info;
- int ret;
-
- tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
- if (!tsf_info) {
- ret = -ENOMEM;
- goto out;
- }
-
- tsf_info->role_id = wlvif->role_id;
-
- ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
- tsf_info, sizeof(*tsf_info));
- if (ret < 0) {
- wl1271_warning("acx tsf info interrogate failed");
- goto out;
- }
-
- *mactime = le32_to_cpu(tsf_info->current_tsf_low) |
- ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
-
-out:
- kfree(tsf_info);
- return ret;
-}
-
-int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable)
-{
- struct wl1271_acx_ps_rx_streaming *rx_streaming;
- u32 conf_queues, enable_queues;
- int i, ret = 0;
-
- wl1271_debug(DEBUG_ACX, "acx ps rx streaming");
-
- rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL);
- if (!rx_streaming) {
- ret = -ENOMEM;
- goto out;
- }
-
- conf_queues = wl->conf.rx_streaming.queues;
- if (enable)
- enable_queues = conf_queues;
- else
- enable_queues = 0;
-
- for (i = 0; i < 8; i++) {
- /*
- * Skip non-changed queues, to avoid redundant acxs.
- * this check assumes conf.rx_streaming.queues can't
- * be changed while rx_streaming is enabled.
- */
- if (!(conf_queues & BIT(i)))
- continue;
-
- rx_streaming->role_id = wlvif->role_id;
- rx_streaming->tid = i;
- rx_streaming->enable = enable_queues & BIT(i);
- rx_streaming->period = wl->conf.rx_streaming.interval;
- rx_streaming->timeout = wl->conf.rx_streaming.interval;
-
- ret = wl1271_cmd_configure(wl, ACX_PS_RX_STREAMING,
- rx_streaming,
- sizeof(*rx_streaming));
- if (ret < 0) {
- wl1271_warning("acx ps rx streaming failed: %d", ret);
- goto out;
- }
- }
-out:
- kfree(rx_streaming);
- return ret;
-}
-
-int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct wl1271_acx_ap_max_tx_retry *acx = NULL;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx ap max tx retry");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx)
- return -ENOMEM;
-
- acx->role_id = wlvif->role_id;
- acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries);
-
- ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx ap max tx retry failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct wl1271_acx_config_ps *config_ps;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx config ps");
-
- config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL);
- if (!config_ps) {
- ret = -ENOMEM;
- goto out;
- }
-
- config_ps->exit_retries = wl->conf.conn.psm_exit_retries;
- config_ps->enter_retries = wl->conf.conn.psm_entry_retries;
- config_ps->null_data_rate = cpu_to_le32(wlvif->basic_rate);
-
- ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps,
- sizeof(*config_ps));
-
- if (ret < 0) {
- wl1271_warning("acx config ps failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(config_ps);
- return ret;
-}
-
-int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
-{
- struct wl1271_acx_inconnection_sta *acx = NULL;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx)
- return -ENOMEM;
-
- memcpy(acx->addr, addr, ETH_ALEN);
-
- ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx set inconnaction sta failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1271_acx_fm_coex(struct wl1271 *wl)
-{
- struct wl1271_acx_fm_coex *acx;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx fm coex setting");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->enable = wl->conf.fm_coex.enable;
- acx->swallow_period = wl->conf.fm_coex.swallow_period;
- acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
- acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
- acx->m_divider_fref_set_1 =
- cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
- acx->m_divider_fref_set_2 =
- cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
- acx->coex_pll_stabilization_time =
- cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
- acx->ldo_stabilization_time =
- cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
- acx->fm_disturbed_band_margin =
- wl->conf.fm_coex.fm_disturbed_band_margin;
- acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
-
- ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx fm coex setting failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl)
-{
- struct wl12xx_acx_set_rate_mgmt_params *acx = NULL;
- struct conf_rate_policy_settings *conf = &wl->conf.rate;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx set rate mgmt params");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx)
- return -ENOMEM;
-
- acx->index = ACX_RATE_MGMT_ALL_PARAMS;
- acx->rate_retry_score = cpu_to_le16(conf->rate_retry_score);
- acx->per_add = cpu_to_le16(conf->per_add);
- acx->per_th1 = cpu_to_le16(conf->per_th1);
- acx->per_th2 = cpu_to_le16(conf->per_th2);
- acx->max_per = cpu_to_le16(conf->max_per);
- acx->inverse_curiosity_factor = conf->inverse_curiosity_factor;
- acx->tx_fail_low_th = conf->tx_fail_low_th;
- acx->tx_fail_high_th = conf->tx_fail_high_th;
- acx->per_alpha_shift = conf->per_alpha_shift;
- acx->per_add_shift = conf->per_add_shift;
- acx->per_beta1_shift = conf->per_beta1_shift;
- acx->per_beta2_shift = conf->per_beta2_shift;
- acx->rate_check_up = conf->rate_check_up;
- acx->rate_check_down = conf->rate_check_down;
- memcpy(acx->rate_retry_policy, conf->rate_retry_policy,
- sizeof(acx->rate_retry_policy));
-
- ret = wl1271_cmd_configure(wl, ACX_SET_RATE_MGMT_PARAMS,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1271_warning("acx set rate mgmt params failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl12xx_acx_config_hangover(struct wl1271 *wl)
-{
- struct wl12xx_acx_config_hangover *acx;
- struct conf_hangover_settings *conf = &wl->conf.hangover;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx config hangover");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->recover_time = cpu_to_le32(conf->recover_time);
- acx->hangover_period = conf->hangover_period;
- acx->dynamic_mode = conf->dynamic_mode;
- acx->early_termination_mode = conf->early_termination_mode;
- acx->max_period = conf->max_period;
- acx->min_period = conf->min_period;
- acx->increase_delta = conf->increase_delta;
- acx->decrease_delta = conf->decrease_delta;
- acx->quiet_time = conf->quiet_time;
- acx->increase_time = conf->increase_time;
- acx->window_size = acx->window_size;
-
- ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx,
- sizeof(*acx));
-
- if (ret < 0) {
- wl1271_warning("acx config hangover failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-
-}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
deleted file mode 100644
index a28fc044034c..000000000000
--- a/drivers/net/wireless/wl12xx/acx.h
+++ /dev/null
@@ -1,1314 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __ACX_H__
-#define __ACX_H__
-
-#include "wl12xx.h"
-#include "cmd.h"
-
-/*************************************************************************
-
- Host Interrupt Register (WiLink -> Host)
-
-**************************************************************************/
-/* HW Initiated interrupt Watchdog timer expiration */
-#define WL1271_ACX_INTR_WATCHDOG BIT(0)
-/* Init sequence is done (masked interrupt, detection through polling only ) */
-#define WL1271_ACX_INTR_INIT_COMPLETE BIT(1)
-/* Event was entered to Event MBOX #A*/
-#define WL1271_ACX_INTR_EVENT_A BIT(2)
-/* Event was entered to Event MBOX #B*/
-#define WL1271_ACX_INTR_EVENT_B BIT(3)
-/* Command processing completion*/
-#define WL1271_ACX_INTR_CMD_COMPLETE BIT(4)
-/* Signaling the host on HW wakeup */
-#define WL1271_ACX_INTR_HW_AVAILABLE BIT(5)
-/* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */
-#define WL1271_ACX_INTR_DATA BIT(6)
-/* Trace message on MBOX #A */
-#define WL1271_ACX_INTR_TRACE_A BIT(7)
-/* Trace message on MBOX #B */
-#define WL1271_ACX_INTR_TRACE_B BIT(8)
-
-#define WL1271_ACX_INTR_ALL 0xFFFFFFFF
-#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \
- WL1271_ACX_INTR_INIT_COMPLETE | \
- WL1271_ACX_INTR_EVENT_A | \
- WL1271_ACX_INTR_EVENT_B | \
- WL1271_ACX_INTR_CMD_COMPLETE | \
- WL1271_ACX_INTR_HW_AVAILABLE | \
- WL1271_ACX_INTR_DATA)
-
-#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
- WL1271_ACX_INTR_EVENT_A | \
- WL1271_ACX_INTR_EVENT_B | \
- WL1271_ACX_INTR_HW_AVAILABLE | \
- WL1271_ACX_INTR_DATA)
-
-/* Target's information element */
-struct acx_header {
- struct wl1271_cmd_header cmd;
-
- /* acx (or information element) header */
- __le16 id;
-
- /* payload length (not including headers */
- __le16 len;
-} __packed;
-
-struct acx_error_counter {
- struct acx_header header;
-
- /* The number of PLCP errors since the last time this */
- /* information element was interrogated. This field is */
- /* automatically cleared when it is interrogated.*/
- __le32 PLCP_error;
-
- /* The number of FCS errors since the last time this */
- /* information element was interrogated. This field is */
- /* automatically cleared when it is interrogated.*/
- __le32 FCS_error;
-
- /* The number of MPDUs without PLCP header errors received*/
- /* since the last time this information element was interrogated. */
- /* This field is automatically cleared when it is interrogated.*/
- __le32 valid_frame;
-
- /* the number of missed sequence numbers in the squentially */
- /* values of frames seq numbers */
- __le32 seq_num_miss;
-} __packed;
-
-enum wl12xx_role {
- WL1271_ROLE_STA = 0,
- WL1271_ROLE_IBSS,
- WL1271_ROLE_AP,
- WL1271_ROLE_DEVICE,
- WL1271_ROLE_P2P_CL,
- WL1271_ROLE_P2P_GO,
-
- WL12XX_INVALID_ROLE_TYPE = 0xff
-};
-
-enum wl1271_psm_mode {
- /* Active mode */
- WL1271_PSM_CAM = 0,
-
- /* Power save mode */
- WL1271_PSM_PS = 1,
-
- /* Extreme low power */
- WL1271_PSM_ELP = 2,
-};
-
-struct acx_sleep_auth {
- struct acx_header header;
-
- /* The sleep level authorization of the device. */
- /* 0 - Always active*/
- /* 1 - Power down mode: light / fast sleep*/
- /* 2 - ELP mode: Deep / Max sleep*/
- u8 sleep_auth;
- u8 padding[3];
-} __packed;
-
-enum {
- HOSTIF_PCI_MASTER_HOST_INDIRECT,
- HOSTIF_PCI_MASTER_HOST_DIRECT,
- HOSTIF_SLAVE,
- HOSTIF_PKT_RING,
- HOSTIF_DONTCARE = 0xFF
-};
-
-#define DEFAULT_UCAST_PRIORITY 0
-#define DEFAULT_RX_Q_PRIORITY 0
-#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
-#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
-#define TRACE_BUFFER_MAX_SIZE 256
-
-#define DP_RX_PACKET_RING_CHUNK_SIZE 1600
-#define DP_TX_PACKET_RING_CHUNK_SIZE 1600
-#define DP_RX_PACKET_RING_CHUNK_NUM 2
-#define DP_TX_PACKET_RING_CHUNK_NUM 2
-#define DP_TX_COMPLETE_TIME_OUT 20
-
-#define TX_MSDU_LIFETIME_MIN 0
-#define TX_MSDU_LIFETIME_MAX 3000
-#define TX_MSDU_LIFETIME_DEF 512
-#define RX_MSDU_LIFETIME_MIN 0
-#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
-#define RX_MSDU_LIFETIME_DEF 512000
-
-struct acx_rx_msdu_lifetime {
- struct acx_header header;
-
- /*
- * The maximum amount of time, in TU, before the
- * firmware discards the MSDU.
- */
- __le32 lifetime;
-} __packed;
-
-enum acx_slot_type {
- SLOT_TIME_LONG = 0,
- SLOT_TIME_SHORT = 1,
- DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
- MAX_SLOT_TIMES = 0xFF
-};
-
-#define STATION_WONE_INDEX 0
-
-struct acx_slot {
- struct acx_header header;
-
- u8 role_id;
- u8 wone_index; /* Reserved */
- u8 slot_time;
- u8 reserved[5];
-} __packed;
-
-
-#define ACX_MC_ADDRESS_GROUP_MAX (8)
-#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX)
-
-struct acx_dot11_grp_addr_tbl {
- struct acx_header header;
-
- u8 role_id;
- u8 enabled;
- u8 num_groups;
- u8 pad[1];
- u8 mac_table[ADDRESS_GROUP_MAX_LEN];
-} __packed;
-
-struct acx_rx_timeout {
- struct acx_header header;
-
- u8 role_id;
- u8 reserved;
- __le16 ps_poll_timeout;
- __le16 upsd_timeout;
- u8 padding[2];
-} __packed;
-
-struct acx_rts_threshold {
- struct acx_header header;
-
- u8 role_id;
- u8 reserved;
- __le16 threshold;
-} __packed;
-
-struct acx_beacon_filter_option {
- struct acx_header header;
-
- u8 role_id;
- u8 enable;
- /*
- * The number of beacons without the unicast TIM
- * bit set that the firmware buffers before
- * signaling the host about ready frames.
- * When set to 0 and the filter is enabled, beacons
- * without the unicast TIM bit set are dropped.
- */
- u8 max_num_beacons;
- u8 pad[1];
-} __packed;
-
-/*
- * ACXBeaconFilterEntry (not 221)
- * Byte Offset Size (Bytes) Definition
- * =========== ============ ==========
- * 0 1 IE identifier
- * 1 1 Treatment bit mask
- *
- * ACXBeaconFilterEntry (221)
- * Byte Offset Size (Bytes) Definition
- * =========== ============ ==========
- * 0 1 IE identifier
- * 1 1 Treatment bit mask
- * 2 3 OUI
- * 5 1 Type
- * 6 2 Version
- *
- *
- * Treatment bit mask - The information element handling:
- * bit 0 - The information element is compared and transferred
- * in case of change.
- * bit 1 - The information element is transferred to the host
- * with each appearance or disappearance.
- * Note that both bits can be set at the same time.
- */
-#define BEACON_FILTER_TABLE_MAX_IE_NUM (32)
-#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
-#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2)
-#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
-#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
- BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
- (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
- BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
-
-struct acx_beacon_filter_ie_table {
- struct acx_header header;
-
- u8 role_id;
- u8 num_ie;
- u8 pad[2];
- u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
-} __packed;
-
-struct acx_conn_monit_params {
- struct acx_header header;
-
- u8 role_id;
- u8 padding[3];
- __le32 synch_fail_thold; /* number of beacons missed */
- __le32 bss_lose_timeout; /* number of TU's from synch fail */
-} __packed;
-
-struct acx_bt_wlan_coex {
- struct acx_header header;
-
- u8 enable;
- u8 pad[3];
-} __packed;
-
-struct acx_bt_wlan_coex_param {
- struct acx_header header;
-
- __le32 params[CONF_SG_PARAMS_MAX];
- u8 param_idx;
- u8 padding[3];
-} __packed;
-
-struct acx_dco_itrim_params {
- struct acx_header header;
-
- u8 enable;
- u8 padding[3];
- __le32 timeout;
-} __packed;
-
-struct acx_energy_detection {
- struct acx_header header;
-
- /* The RX Clear Channel Assessment threshold in the PHY */
- __le16 rx_cca_threshold;
- u8 tx_energy_detection;
- u8 pad;
-} __packed;
-
-struct acx_beacon_broadcast {
- struct acx_header header;
-
- u8 role_id;
- /* Enables receiving of broadcast packets in PS mode */
- u8 rx_broadcast_in_ps;
-
- __le16 beacon_rx_timeout;
- __le16 broadcast_timeout;
-
- /* Consecutive PS Poll failures before updating the host */
- u8 ps_poll_threshold;
- u8 pad[1];
-} __packed;
-
-struct acx_event_mask {
- struct acx_header header;
-
- __le32 event_mask;
- __le32 high_event_mask; /* Unused */
-} __packed;
-
-#define SCAN_PASSIVE BIT(0)
-#define SCAN_5GHZ_BAND BIT(1)
-#define SCAN_TRIGGERED BIT(2)
-#define SCAN_PRIORITY_HIGH BIT(3)
-
-/* When set, disable HW encryption */
-#define DF_ENCRYPTION_DISABLE 0x01
-#define DF_SNIFF_MODE_ENABLE 0x80
-
-struct acx_feature_config {
- struct acx_header header;
-
- u8 role_id;
- u8 padding[3];
- __le32 options;
- __le32 data_flow_options;
-} __packed;
-
-struct acx_current_tx_power {
- struct acx_header header;
-
- u8 role_id;
- u8 current_tx_power;
- u8 padding[2];
-} __packed;
-
-struct acx_wake_up_condition {
- struct acx_header header;
-
- u8 role_id;
- u8 wake_up_event; /* Only one bit can be set */
- u8 listen_interval;
- u8 pad[1];
-} __packed;
-
-struct acx_aid {
- struct acx_header header;
-
- /*
- * To be set when associated with an AP.
- */
- u8 role_id;
- u8 reserved;
- __le16 aid;
-} __packed;
-
-enum acx_preamble_type {
- ACX_PREAMBLE_LONG = 0,
- ACX_PREAMBLE_SHORT = 1
-};
-
-struct acx_preamble {
- struct acx_header header;
-
- /*
- * When set, the WiLink transmits the frames with a short preamble and
- * when cleared, the WiLink transmits the frames with a long preamble.
- */
- u8 role_id;
- u8 preamble;
- u8 padding[2];
-} __packed;
-
-enum acx_ctsprotect_type {
- CTSPROTECT_DISABLE = 0,
- CTSPROTECT_ENABLE = 1
-};
-
-struct acx_ctsprotect {
- struct acx_header header;
- u8 role_id;
- u8 ctsprotect;
- u8 padding[2];
-} __packed;
-
-struct acx_tx_statistics {
- __le32 internal_desc_overflow;
-} __packed;
-
-struct acx_rx_statistics {
- __le32 out_of_mem;
- __le32 hdr_overflow;
- __le32 hw_stuck;
- __le32 dropped;
- __le32 fcs_err;
- __le32 xfr_hint_trig;
- __le32 path_reset;
- __le32 reset_counter;
-} __packed;
-
-struct acx_dma_statistics {
- __le32 rx_requested;
- __le32 rx_errors;
- __le32 tx_requested;
- __le32 tx_errors;
-} __packed;
-
-struct acx_isr_statistics {
- /* host command complete */
- __le32 cmd_cmplt;
-
- /* fiqisr() */
- __le32 fiqs;
-
- /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
- __le32 rx_headers;
-
- /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
- __le32 rx_completes;
-
- /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
- __le32 rx_mem_overflow;
-
- /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
- __le32 rx_rdys;
-
- /* irqisr() */
- __le32 irqs;
-
- /* (INT_STS_ND & INT_TRIG_TX_PROC) */
- __le32 tx_procs;
-
- /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
- __le32 decrypt_done;
-
- /* (INT_STS_ND & INT_TRIG_DMA0) */
- __le32 dma0_done;
-
- /* (INT_STS_ND & INT_TRIG_DMA1) */
- __le32 dma1_done;
-
- /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
- __le32 tx_exch_complete;
-
- /* (INT_STS_ND & INT_TRIG_COMMAND) */
- __le32 commands;
-
- /* (INT_STS_ND & INT_TRIG_RX_PROC) */
- __le32 rx_procs;
-
- /* (INT_STS_ND & INT_TRIG_PM_802) */
- __le32 hw_pm_mode_changes;
-
- /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
- __le32 host_acknowledges;
-
- /* (INT_STS_ND & INT_TRIG_PM_PCI) */
- __le32 pci_pm;
-
- /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
- __le32 wakeups;
-
- /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
- __le32 low_rssi;
-} __packed;
-
-struct acx_wep_statistics {
- /* WEP address keys configured */
- __le32 addr_key_count;
-
- /* default keys configured */
- __le32 default_key_count;
-
- __le32 reserved;
-
- /* number of times that WEP key not found on lookup */
- __le32 key_not_found;
-
- /* number of times that WEP key decryption failed */
- __le32 decrypt_fail;
-
- /* WEP packets decrypted */
- __le32 packets;
-
- /* WEP decrypt interrupts */
- __le32 interrupt;
-} __packed;
-
-#define ACX_MISSED_BEACONS_SPREAD 10
-
-struct acx_pwr_statistics {
- /* the amount of enters into power save mode (both PD & ELP) */
- __le32 ps_enter;
-
- /* the amount of enters into ELP mode */
- __le32 elp_enter;
-
- /* the amount of missing beacon interrupts to the host */
- __le32 missing_bcns;
-
- /* the amount of wake on host-access times */
- __le32 wake_on_host;
-
- /* the amount of wake on timer-expire */
- __le32 wake_on_timer_exp;
-
- /* the number of packets that were transmitted with PS bit set */
- __le32 tx_with_ps;
-
- /* the number of packets that were transmitted with PS bit clear */
- __le32 tx_without_ps;
-
- /* the number of received beacons */
- __le32 rcvd_beacons;
-
- /* the number of entering into PowerOn (power save off) */
- __le32 power_save_off;
-
- /* the number of entries into power save mode */
- __le16 enable_ps;
-
- /*
- * the number of exits from power save, not including failed PS
- * transitions
- */
- __le16 disable_ps;
-
- /*
- * the number of times the TSF counter was adjusted because
- * of drift
- */
- __le32 fix_tsf_ps;
-
- /* Gives statistics about the spread continuous missed beacons.
- * The 16 LSB are dedicated for the PS mode.
- * The 16 MSB are dedicated for the PS mode.
- * cont_miss_bcns_spread[0] - single missed beacon.
- * cont_miss_bcns_spread[1] - two continuous missed beacons.
- * cont_miss_bcns_spread[2] - three continuous missed beacons.
- * ...
- * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
- */
- __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
-
- /* the number of beacons in awake mode */
- __le32 rcvd_awake_beacons;
-} __packed;
-
-struct acx_mic_statistics {
- __le32 rx_pkts;
- __le32 calc_failure;
-} __packed;
-
-struct acx_aes_statistics {
- __le32 encrypt_fail;
- __le32 decrypt_fail;
- __le32 encrypt_packets;
- __le32 decrypt_packets;
- __le32 encrypt_interrupt;
- __le32 decrypt_interrupt;
-} __packed;
-
-struct acx_event_statistics {
- __le32 heart_beat;
- __le32 calibration;
- __le32 rx_mismatch;
- __le32 rx_mem_empty;
- __le32 rx_pool;
- __le32 oom_late;
- __le32 phy_transmit_error;
- __le32 tx_stuck;
-} __packed;
-
-struct acx_ps_statistics {
- __le32 pspoll_timeouts;
- __le32 upsd_timeouts;
- __le32 upsd_max_sptime;
- __le32 upsd_max_apturn;
- __le32 pspoll_max_apturn;
- __le32 pspoll_utilization;
- __le32 upsd_utilization;
-} __packed;
-
-struct acx_rxpipe_statistics {
- __le32 rx_prep_beacon_drop;
- __le32 descr_host_int_trig_rx_data;
- __le32 beacon_buffer_thres_host_int_trig_rx_data;
- __le32 missed_beacon_host_int_trig_rx_data;
- __le32 tx_xfr_host_int_trig_rx_data;
-} __packed;
-
-struct acx_statistics {
- struct acx_header header;
-
- struct acx_tx_statistics tx;
- struct acx_rx_statistics rx;
- struct acx_dma_statistics dma;
- struct acx_isr_statistics isr;
- struct acx_wep_statistics wep;
- struct acx_pwr_statistics pwr;
- struct acx_aes_statistics aes;
- struct acx_mic_statistics mic;
- struct acx_event_statistics event;
- struct acx_ps_statistics ps;
- struct acx_rxpipe_statistics rxpipe;
-} __packed;
-
-struct acx_rate_class {
- __le32 enabled_rates;
- u8 short_retry_limit;
- u8 long_retry_limit;
- u8 aflags;
- u8 reserved;
-};
-
-struct acx_rate_policy {
- struct acx_header header;
-
- __le32 rate_policy_idx;
- struct acx_rate_class rate_policy;
-} __packed;
-
-struct acx_ac_cfg {
- struct acx_header header;
- u8 role_id;
- u8 ac;
- u8 aifsn;
- u8 cw_min;
- __le16 cw_max;
- __le16 tx_op_limit;
-} __packed;
-
-struct acx_tid_config {
- struct acx_header header;
- u8 role_id;
- u8 queue_id;
- u8 channel_type;
- u8 tsid;
- u8 ps_scheme;
- u8 ack_policy;
- u8 padding[2];
- __le32 apsd_conf[2];
-} __packed;
-
-struct acx_frag_threshold {
- struct acx_header header;
- __le16 frag_threshold;
- u8 padding[2];
-} __packed;
-
-struct acx_tx_config_options {
- struct acx_header header;
- __le16 tx_compl_timeout; /* msec */
- __le16 tx_compl_threshold; /* number of packets */
-} __packed;
-
-struct wl12xx_acx_config_memory {
- struct acx_header header;
-
- u8 rx_mem_block_num;
- u8 tx_min_mem_block_num;
- u8 num_stations;
- u8 num_ssid_profiles;
- __le32 total_tx_descriptors;
- u8 dyn_mem_enable;
- u8 tx_free_req;
- u8 rx_free_req;
- u8 tx_min;
- u8 fwlog_blocks;
- u8 padding[3];
-} __packed;
-
-struct wl1271_acx_mem_map {
- struct acx_header header;
-
- __le32 code_start;
- __le32 code_end;
-
- __le32 wep_defkey_start;
- __le32 wep_defkey_end;
-
- __le32 sta_table_start;
- __le32 sta_table_end;
-
- __le32 packet_template_start;
- __le32 packet_template_end;
-
- /* Address of the TX result interface (control block) */
- __le32 tx_result;
- __le32 tx_result_queue_start;
-
- __le32 queue_memory_start;
- __le32 queue_memory_end;
-
- __le32 packet_memory_pool_start;
- __le32 packet_memory_pool_end;
-
- __le32 debug_buffer1_start;
- __le32 debug_buffer1_end;
-
- __le32 debug_buffer2_start;
- __le32 debug_buffer2_end;
-
- /* Number of blocks FW allocated for TX packets */
- __le32 num_tx_mem_blocks;
-
- /* Number of blocks FW allocated for RX packets */
- __le32 num_rx_mem_blocks;
-
- /* the following 4 fields are valid in SLAVE mode only */
- u8 *tx_cbuf;
- u8 *rx_cbuf;
- __le32 rx_ctrl;
- __le32 tx_ctrl;
-} __packed;
-
-struct wl1271_acx_rx_config_opt {
- struct acx_header header;
-
- __le16 mblk_threshold;
- __le16 threshold;
- __le16 timeout;
- u8 queue_type;
- u8 reserved;
-} __packed;
-
-
-struct wl1271_acx_bet_enable {
- struct acx_header header;
-
- u8 role_id;
- u8 enable;
- u8 max_consecutive;
- u8 padding[1];
-} __packed;
-
-#define ACX_IPV4_VERSION 4
-#define ACX_IPV6_VERSION 6
-#define ACX_IPV4_ADDR_SIZE 4
-
-/* bitmap of enabled arp_filter features */
-#define ACX_ARP_FILTER_ARP_FILTERING BIT(0)
-#define ACX_ARP_FILTER_AUTO_ARP BIT(1)
-
-struct wl1271_acx_arp_filter {
- struct acx_header header;
- u8 role_id;
- u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
- u8 enable; /* bitmap of enabled ARP filtering features */
- u8 padding[1];
- u8 address[16]; /* The configured device IP address - all ARP
- requests directed to this IP address will pass
- through. For IPv4, the first four bytes are
- used. */
-} __packed;
-
-struct wl1271_acx_pm_config {
- struct acx_header header;
-
- __le32 host_clk_settling_time;
- u8 host_fast_wakeup_support;
- u8 padding[3];
-} __packed;
-
-struct wl1271_acx_keep_alive_mode {
- struct acx_header header;
-
- u8 role_id;
- u8 enabled;
- u8 padding[2];
-} __packed;
-
-enum {
- ACX_KEEP_ALIVE_NO_TX = 0,
- ACX_KEEP_ALIVE_PERIOD_ONLY
-};
-
-enum {
- ACX_KEEP_ALIVE_TPL_INVALID = 0,
- ACX_KEEP_ALIVE_TPL_VALID
-};
-
-struct wl1271_acx_keep_alive_config {
- struct acx_header header;
-
- u8 role_id;
- u8 index;
- u8 tpl_validation;
- u8 trigger;
- __le32 period;
-} __packed;
-
-#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
-#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
-#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
-
-struct wl1271_acx_host_config_bitmap {
- struct acx_header header;
-
- __le32 host_cfg_bitmap;
-} __packed;
-
-enum {
- WL1271_ACX_TRIG_TYPE_LEVEL = 0,
- WL1271_ACX_TRIG_TYPE_EDGE,
-};
-
-enum {
- WL1271_ACX_TRIG_DIR_LOW = 0,
- WL1271_ACX_TRIG_DIR_HIGH,
- WL1271_ACX_TRIG_DIR_BIDIR,
-};
-
-enum {
- WL1271_ACX_TRIG_ENABLE = 1,
- WL1271_ACX_TRIG_DISABLE,
-};
-
-enum {
- WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0,
- WL1271_ACX_TRIG_METRIC_RSSI_DATA,
- WL1271_ACX_TRIG_METRIC_SNR_BEACON,
- WL1271_ACX_TRIG_METRIC_SNR_DATA,
-};
-
-enum {
- WL1271_ACX_TRIG_IDX_RSSI = 0,
- WL1271_ACX_TRIG_COUNT = 8,
-};
-
-struct wl1271_acx_rssi_snr_trigger {
- struct acx_header header;
-
- u8 role_id;
- u8 metric;
- u8 type;
- u8 dir;
- __le16 threshold;
- __le16 pacing; /* 0 - 60000 ms */
- u8 hysteresis;
- u8 index;
- u8 enable;
- u8 padding[1];
-};
-
-struct wl1271_acx_rssi_snr_avg_weights {
- struct acx_header header;
-
- u8 role_id;
- u8 padding[3];
- u8 rssi_beacon;
- u8 rssi_data;
- u8 snr_beacon;
- u8 snr_data;
-};
-
-
-/* special capability bit (not employed by the 802.11n spec) */
-#define WL12XX_HT_CAP_HT_OPERATION BIT(16)
-
-/*
- * ACX_PEER_HT_CAP
- * Configure HT capabilities - declare the capabilities of the peer
- * we are connected to.
- */
-struct wl1271_acx_ht_capabilities {
- struct acx_header header;
-
- /* bitmask of capability bits supported by the peer */
- __le32 ht_capabilites;
-
- /* Indicates to which link these capabilities apply. */
- u8 hlid;
-
- /*
- * This the maximum A-MPDU length supported by the AP. The FW may not
- * exceed this length when sending A-MPDUs
- */
- u8 ampdu_max_length;
-
- /* This is the minimal spacing required when sending A-MPDUs to the AP*/
- u8 ampdu_min_spacing;
-
- u8 padding;
-} __packed;
-
-/*
- * ACX_HT_BSS_OPERATION
- * Configure HT capabilities - AP rules for behavior in the BSS.
- */
-struct wl1271_acx_ht_information {
- struct acx_header header;
-
- u8 role_id;
-
- /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
- u8 rifs_mode;
-
- /* Values: 0 - 3 like in spec */
- u8 ht_protection;
-
- /* Values: 0 - GF protection not required, 1 - GF protection required */
- u8 gf_protection;
-
- /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/
- u8 ht_tx_burst_limit;
-
- /*
- * Values: 0 - Dual CTS protection not required,
- * 1 - Dual CTS Protection required
- * Note: When this value is set to 1 FW will protect all TXOP with RTS
- * frame and will not use CTS-to-self regardless of the value of the
- * ACX_CTS_PROTECTION information element
- */
- u8 dual_cts_protection;
-
- u8 padding[2];
-} __packed;
-
-#define RX_BA_MAX_SESSIONS 2
-
-struct wl1271_acx_ba_initiator_policy {
- struct acx_header header;
-
- /* Specifies role Id, Range 0-7, 0xFF means ANY role. */
- u8 role_id;
-
- /*
- * Per TID setting for allowing TX BA. Set a bit to 1 to allow
- * TX BA sessions for the corresponding TID.
- */
- u8 tid_bitmap;
-
- /* Windows size in number of packets */
- u8 win_size;
-
- u8 padding1[1];
-
- /* As initiator inactivity timeout in time units(TU) of 1024us */
- u16 inactivity_timeout;
-
- u8 padding[2];
-} __packed;
-
-struct wl1271_acx_ba_receiver_setup {
- struct acx_header header;
-
- /* Specifies link id, range 0-31 */
- u8 hlid;
-
- u8 tid;
-
- u8 enable;
-
- /* Windows size in number of packets */
- u8 win_size;
-
- /* BA session starting sequence number. RANGE 0-FFF */
- u16 ssn;
-
- u8 padding[2];
-} __packed;
-
-struct wl12xx_acx_fw_tsf_information {
- struct acx_header header;
-
- u8 role_id;
- u8 padding1[3];
- __le32 current_tsf_high;
- __le32 current_tsf_low;
- __le32 last_bttt_high;
- __le32 last_tbtt_low;
- u8 last_dtim_count;
- u8 padding2[3];
-} __packed;
-
-struct wl1271_acx_ps_rx_streaming {
- struct acx_header header;
-
- u8 role_id;
- u8 tid;
- u8 enable;
-
- /* interval between triggers (10-100 msec) */
- u8 period;
-
- /* timeout before first trigger (0-200 msec) */
- u8 timeout;
- u8 padding[3];
-} __packed;
-
-struct wl1271_acx_ap_max_tx_retry {
- struct acx_header header;
-
- u8 role_id;
- u8 padding_1;
-
- /*
- * the number of frames transmission failures before
- * issuing the aging event.
- */
- __le16 max_tx_retry;
-} __packed;
-
-struct wl1271_acx_config_ps {
- struct acx_header header;
-
- u8 exit_retries;
- u8 enter_retries;
- u8 padding[2];
- __le32 null_data_rate;
-} __packed;
-
-struct wl1271_acx_inconnection_sta {
- struct acx_header header;
-
- u8 addr[ETH_ALEN];
- u8 padding1[2];
-} __packed;
-
-/*
- * ACX_FM_COEX_CFG
- * set the FM co-existence parameters.
- */
-struct wl1271_acx_fm_coex {
- struct acx_header header;
- /* enable(1) / disable(0) the FM Coex feature */
- u8 enable;
- /*
- * Swallow period used in COEX PLL swallowing mechanism.
- * 0xFF = use FW default
- */
- u8 swallow_period;
- /*
- * The N divider used in COEX PLL swallowing mechanism for Fref of
- * 38.4/19.2 Mhz. 0xFF = use FW default
- */
- u8 n_divider_fref_set_1;
- /*
- * The N divider used in COEX PLL swallowing mechanism for Fref of
- * 26/52 Mhz. 0xFF = use FW default
- */
- u8 n_divider_fref_set_2;
- /*
- * The M divider used in COEX PLL swallowing mechanism for Fref of
- * 38.4/19.2 Mhz. 0xFFFF = use FW default
- */
- __le16 m_divider_fref_set_1;
- /*
- * The M divider used in COEX PLL swallowing mechanism for Fref of
- * 26/52 Mhz. 0xFFFF = use FW default
- */
- __le16 m_divider_fref_set_2;
- /*
- * The time duration in uSec required for COEX PLL to stabilize.
- * 0xFFFFFFFF = use FW default
- */
- __le32 coex_pll_stabilization_time;
- /*
- * The time duration in uSec required for LDO to stabilize.
- * 0xFFFFFFFF = use FW default
- */
- __le16 ldo_stabilization_time;
- /*
- * The disturbed frequency band margin around the disturbed frequency
- * center (single sided).
- * For example, if 2 is configured, the following channels will be
- * considered disturbed channel:
- * 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
- * 0xFF = use FW default
- */
- u8 fm_disturbed_band_margin;
- /*
- * The swallow clock difference of the swallowing mechanism.
- * 0xFF = use FW default
- */
- u8 swallow_clk_diff;
-} __packed;
-
-#define ACX_RATE_MGMT_ALL_PARAMS 0xff
-struct wl12xx_acx_set_rate_mgmt_params {
- struct acx_header header;
-
- u8 index; /* 0xff to configure all params */
- u8 padding1;
- __le16 rate_retry_score;
- __le16 per_add;
- __le16 per_th1;
- __le16 per_th2;
- __le16 max_per;
- u8 inverse_curiosity_factor;
- u8 tx_fail_low_th;
- u8 tx_fail_high_th;
- u8 per_alpha_shift;
- u8 per_add_shift;
- u8 per_beta1_shift;
- u8 per_beta2_shift;
- u8 rate_check_up;
- u8 rate_check_down;
- u8 rate_retry_policy[ACX_RATE_MGMT_NUM_OF_RATES];
- u8 padding2[2];
-} __packed;
-
-struct wl12xx_acx_config_hangover {
- struct acx_header header;
-
- __le32 recover_time;
- u8 hangover_period;
- u8 dynamic_mode;
- u8 early_termination_mode;
- u8 max_period;
- u8 min_period;
- u8 increase_delta;
- u8 decrease_delta;
- u8 quiet_time;
- u8 increase_time;
- u8 window_size;
- u8 padding[2];
-} __packed;
-
-enum {
- ACX_WAKE_UP_CONDITIONS = 0x0000,
- ACX_MEM_CFG = 0x0001,
- ACX_SLOT = 0x0002,
- ACX_AC_CFG = 0x0003,
- ACX_MEM_MAP = 0x0004,
- ACX_AID = 0x0005,
- ACX_MEDIUM_USAGE = 0x0006,
- ACX_STATISTICS = 0x0007,
- ACX_PWR_CONSUMPTION_STATISTICS = 0x0008,
- ACX_TID_CFG = 0x0009,
- ACX_PS_RX_STREAMING = 0x000A,
- ACX_BEACON_FILTER_OPT = 0x000B,
- ACX_NOISE_HIST = 0x000C,
- ACX_HDK_VERSION = 0x000D,
- ACX_PD_THRESHOLD = 0x000E,
- ACX_TX_CONFIG_OPT = 0x000F,
- ACX_CCA_THRESHOLD = 0x0010,
- ACX_EVENT_MBOX_MASK = 0x0011,
- ACX_CONN_MONIT_PARAMS = 0x0012,
- ACX_DISABLE_BROADCASTS = 0x0013,
- ACX_BCN_DTIM_OPTIONS = 0x0014,
- ACX_SG_ENABLE = 0x0015,
- ACX_SG_CFG = 0x0016,
- ACX_FM_COEX_CFG = 0x0017,
- ACX_BEACON_FILTER_TABLE = 0x0018,
- ACX_ARP_IP_FILTER = 0x0019,
- ACX_ROAMING_STATISTICS_TBL = 0x001A,
- ACX_RATE_POLICY = 0x001B,
- ACX_CTS_PROTECTION = 0x001C,
- ACX_SLEEP_AUTH = 0x001D,
- ACX_PREAMBLE_TYPE = 0x001E,
- ACX_ERROR_CNT = 0x001F,
- ACX_IBSS_FILTER = 0x0020,
- ACX_SERVICE_PERIOD_TIMEOUT = 0x0021,
- ACX_TSF_INFO = 0x0022,
- ACX_CONFIG_PS_WMM = 0x0023,
- ACX_ENABLE_RX_DATA_FILTER = 0x0024,
- ACX_SET_RX_DATA_FILTER = 0x0025,
- ACX_GET_DATA_FILTER_STATISTICS = 0x0026,
- ACX_RX_CONFIG_OPT = 0x0027,
- ACX_FRAG_CFG = 0x0028,
- ACX_BET_ENABLE = 0x0029,
- ACX_RSSI_SNR_TRIGGER = 0x002A,
- ACX_RSSI_SNR_WEIGHTS = 0x002B,
- ACX_KEEP_ALIVE_MODE = 0x002C,
- ACX_SET_KEEP_ALIVE_CONFIG = 0x002D,
- ACX_BA_SESSION_INIT_POLICY = 0x002E,
- ACX_BA_SESSION_RX_SETUP = 0x002F,
- ACX_PEER_HT_CAP = 0x0030,
- ACX_HT_BSS_OPERATION = 0x0031,
- ACX_COEX_ACTIVITY = 0x0032,
- ACX_BURST_MODE = 0x0033,
- ACX_SET_RATE_MGMT_PARAMS = 0x0034,
- ACX_GET_RATE_MGMT_PARAMS = 0x0035,
- ACX_SET_RATE_ADAPT_PARAMS = 0x0036,
- ACX_SET_DCO_ITRIM_PARAMS = 0x0037,
- ACX_GEN_FW_CMD = 0x0038,
- ACX_HOST_IF_CFG_BITMAP = 0x0039,
- ACX_MAX_TX_FAILURE = 0x003A,
- ACX_UPDATE_INCONNECTION_STA_LIST = 0x003B,
- DOT11_RX_MSDU_LIFE_TIME = 0x003C,
- DOT11_CUR_TX_PWR = 0x003D,
- DOT11_RTS_THRESHOLD = 0x003E,
- DOT11_GROUP_ADDRESS_TBL = 0x003F,
- ACX_PM_CONFIG = 0x0040,
- ACX_CONFIG_PS = 0x0041,
- ACX_CONFIG_HANGOVER = 0x0042,
- ACX_FEATURE_CFG = 0x0043,
- ACX_PROTECTION_CFG = 0x0044,
-};
-
-
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- u8 wake_up_event, u8 listen_interval);
-int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
-int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- int power);
-int wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_acx_mem_map(struct wl1271 *wl,
- struct acx_header *mem_map, size_t len);
-int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl);
-int wl1271_acx_slot(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum acx_slot_type slot_time);
-int wl1271_acx_group_address_tbl(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable, void *mc_list, u32 mc_list_len);
-int wl1271_acx_service_period_timeout(struct wl1271 *wl,
- struct wl12xx_vif *wlvif);
-int wl1271_acx_rts_threshold(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u32 rts_threshold);
-int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
-int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable_filter);
-int wl1271_acx_beacon_filter_table(struct wl1271 *wl,
- struct wl12xx_vif *wlvif);
-int wl1271_acx_conn_monit_params(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable);
-int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
-int wl12xx_acx_sg_cfg(struct wl1271 *wl);
-int wl1271_acx_cca_threshold(struct wl1271 *wl);
-int wl1271_acx_bcn_dtim_options(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_acx_aid(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid);
-int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask);
-int wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum acx_preamble_type preamble);
-int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum acx_ctsprotect_type ctsprotect);
-int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
-int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
- u8 idx);
-int wl1271_acx_ac_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop);
-int wl1271_acx_tid_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 queue_id, u8 channel_type,
- u8 tsid, u8 ps_scheme, u8 ack_policy,
- u32 apsd_conf0, u32 apsd_conf1);
-int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
-int wl1271_acx_tx_config_options(struct wl1271 *wl);
-int wl12xx_acx_mem_cfg(struct wl1271 *wl);
-int wl1271_acx_init_mem_config(struct wl1271 *wl);
-int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
-int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
-int wl1271_acx_smart_reflex(struct wl1271 *wl);
-int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable);
-int wl1271_acx_arp_ip_filter(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 enable, __be32 address);
-int wl1271_acx_pm_config(struct wl1271 *wl);
-int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *vif,
- bool enable);
-int wl1271_acx_keep_alive_config(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 index, u8 tpl_valid);
-int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable, s16 thold, u8 hyst);
-int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl,
- struct wl12xx_vif *wlvif);
-int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
- struct ieee80211_sta_ht_cap *ht_cap,
- bool allow_ht_operation, u8 hlid);
-int wl1271_acx_set_ht_information(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- u16 ht_operation_mode);
-int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
- struct wl12xx_vif *wlvif);
-int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
- u16 ssn, bool enable, u8 peer_hlid);
-int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u64 *mactime);
-int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable);
-int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
-int wl1271_acx_fm_coex(struct wl1271 *wl);
-int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
-int wl12xx_acx_config_hangover(struct wl1271 *wl);
-
-#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
deleted file mode 100644
index 88d60c40b7e3..000000000000
--- a/drivers/net/wireless/wl12xx/boot.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/slab.h>
-#include <linux/wl12xx.h>
-#include <linux/export.h>
-
-#include "debug.h"
-#include "acx.h"
-#include "reg.h"
-#include "boot.h"
-#include "io.h"
-#include "event.h"
-#include "rx.h"
-
-static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
-{
- u32 cpu_ctrl;
-
- /* 10.5.0 run the firmware (I) */
- cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL);
-
- /* 10.5.1 run the firmware (II) */
- cpu_ctrl |= flag;
- wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
-}
-
-static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl)
-{
- unsigned int quirks = 0;
- unsigned int *fw_ver = wl->chip.fw_ver;
-
- /* Only new station firmwares support routing fw logs to the host */
- if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
- (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
- quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
-
- /* This feature is not yet supported for AP mode */
- if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
- quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
-
- return quirks;
-}
-
-static void wl1271_parse_fw_ver(struct wl1271 *wl)
-{
- int ret;
-
- ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
- &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
- &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
- &wl->chip.fw_ver[4]);
-
- if (ret != 5) {
- wl1271_warning("fw version incorrect value");
- memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
- return;
- }
-
- /* Check if any quirks are needed with older fw versions */
- wl->quirks |= wl12xx_get_fw_ver_quirks(wl);
-}
-
-static void wl1271_boot_fw_version(struct wl1271 *wl)
-{
- struct wl1271_static_data *static_data;
-
- static_data = kmalloc(sizeof(*static_data), GFP_DMA);
- if (!static_data) {
- __WARN();
- return;
- }
-
- wl1271_read(wl, wl->cmd_box_addr, static_data, sizeof(*static_data),
- false);
-
- strncpy(wl->chip.fw_ver_str, static_data->fw_version,
- sizeof(wl->chip.fw_ver_str));
-
- kfree(static_data);
-
- /* make sure the string is NULL-terminated */
- wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
-
- wl1271_parse_fw_ver(wl);
-}
-
-static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
- size_t fw_data_len, u32 dest)
-{
- struct wl1271_partition_set partition;
- int addr, chunk_num, partition_limit;
- u8 *p, *chunk;
-
- /* whal_FwCtrl_LoadFwImageSm() */
-
- wl1271_debug(DEBUG_BOOT, "starting firmware upload");
-
- wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
- fw_data_len, CHUNK_SIZE);
-
- if ((fw_data_len % 4) != 0) {
- wl1271_error("firmware length not multiple of four");
- return -EIO;
- }
-
- chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
- if (!chunk) {
- wl1271_error("allocation for firmware upload chunk failed");
- return -ENOMEM;
- }
-
- memcpy(&partition, &wl12xx_part_table[PART_DOWN], sizeof(partition));
- partition.mem.start = dest;
- wl1271_set_partition(wl, &partition);
-
- /* 10.1 set partition limit and chunk num */
- chunk_num = 0;
- partition_limit = wl12xx_part_table[PART_DOWN].mem.size;
-
- while (chunk_num < fw_data_len / CHUNK_SIZE) {
- /* 10.2 update partition, if needed */
- addr = dest + (chunk_num + 2) * CHUNK_SIZE;
- if (addr > partition_limit) {
- addr = dest + chunk_num * CHUNK_SIZE;
- partition_limit = chunk_num * CHUNK_SIZE +
- wl12xx_part_table[PART_DOWN].mem.size;
- partition.mem.start = addr;
- wl1271_set_partition(wl, &partition);
- }
-
- /* 10.3 upload the chunk */
- addr = dest + chunk_num * CHUNK_SIZE;
- p = buf + chunk_num * CHUNK_SIZE;
- memcpy(chunk, p, CHUNK_SIZE);
- wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
- p, addr);
- wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
-
- chunk_num++;
- }
-
- /* 10.4 upload the last chunk */
- addr = dest + chunk_num * CHUNK_SIZE;
- p = buf + chunk_num * CHUNK_SIZE;
- memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
- wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
- fw_data_len % CHUNK_SIZE, p, addr);
- wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
-
- kfree(chunk);
- return 0;
-}
-
-static int wl1271_boot_upload_firmware(struct wl1271 *wl)
-{
- u32 chunks, addr, len;
- int ret = 0;
- u8 *fw;
-
- fw = wl->fw;
- chunks = be32_to_cpup((__be32 *) fw);
- fw += sizeof(u32);
-
- wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
-
- while (chunks--) {
- addr = be32_to_cpup((__be32 *) fw);
- fw += sizeof(u32);
- len = be32_to_cpup((__be32 *) fw);
- fw += sizeof(u32);
-
- if (len > 300000) {
- wl1271_info("firmware chunk too long: %u", len);
- return -EINVAL;
- }
- wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
- chunks, addr, len);
- ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
- if (ret != 0)
- break;
- fw += len;
- }
-
- return ret;
-}
-
-static int wl1271_boot_upload_nvs(struct wl1271 *wl)
-{
- size_t nvs_len, burst_len;
- int i;
- u32 dest_addr, val;
- u8 *nvs_ptr, *nvs_aligned;
-
- if (wl->nvs == NULL)
- return -ENODEV;
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
-
- if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
- if (nvs->general_params.dual_mode_select)
- wl->enable_11a = true;
- } else {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- wl->nvs_len,
- sizeof(struct wl128x_nvs_file));
- kfree(wl->nvs);
- wl->nvs = NULL;
- wl->nvs_len = 0;
- return -EILSEQ;
- }
-
- /* only the first part of the NVS needs to be uploaded */
- nvs_len = sizeof(nvs->nvs);
- nvs_ptr = (u8 *)nvs->nvs;
-
- } else {
- struct wl1271_nvs_file *nvs =
- (struct wl1271_nvs_file *)wl->nvs;
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
- * band configurations) can be removed when those NVS files stop
- * floating around.
- */
- if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
- wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
- if (nvs->general_params.dual_mode_select)
- wl->enable_11a = true;
- }
-
- if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
- (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl->enable_11a)) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- wl->nvs_len, sizeof(struct wl1271_nvs_file));
- kfree(wl->nvs);
- wl->nvs = NULL;
- wl->nvs_len = 0;
- return -EILSEQ;
- }
-
- /* only the first part of the NVS needs to be uploaded */
- nvs_len = sizeof(nvs->nvs);
- nvs_ptr = (u8 *) nvs->nvs;
- }
-
- /* update current MAC address to NVS */
- nvs_ptr[11] = wl->addresses[0].addr[0];
- nvs_ptr[10] = wl->addresses[0].addr[1];
- nvs_ptr[6] = wl->addresses[0].addr[2];
- nvs_ptr[5] = wl->addresses[0].addr[3];
- nvs_ptr[4] = wl->addresses[0].addr[4];
- nvs_ptr[3] = wl->addresses[0].addr[5];
-
- /*
- * Layout before the actual NVS tables:
- * 1 byte : burst length.
- * 2 bytes: destination address.
- * n bytes: data to burst copy.
- *
- * This is ended by a 0 length, then the NVS tables.
- */
-
- /* FIXME: Do we need to check here whether the LSB is 1? */
- while (nvs_ptr[0]) {
- burst_len = nvs_ptr[0];
- dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
-
- /*
- * Due to our new wl1271_translate_reg_addr function,
- * we need to add the REGISTER_BASE to the destination
- */
- dest_addr += REGISTERS_BASE;
-
- /* We move our pointer to the data */
- nvs_ptr += 3;
-
- for (i = 0; i < burst_len; i++) {
- if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
- goto out_badnvs;
-
- val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
- | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
- wl1271_debug(DEBUG_BOOT,
- "nvs burst write 0x%x: 0x%x",
- dest_addr, val);
- wl1271_write32(wl, dest_addr, val);
-
- nvs_ptr += 4;
- dest_addr += 4;
- }
-
- if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
- goto out_badnvs;
- }
-
- /*
- * We've reached the first zero length, the first NVS table
- * is located at an aligned offset which is at least 7 bytes further.
- * NOTE: The wl->nvs->nvs element must be first, in order to
- * simplify the casting, we assume it is at the beginning of
- * the wl->nvs structure.
- */
- nvs_ptr = (u8 *)wl->nvs +
- ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
-
- if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
- goto out_badnvs;
-
- nvs_len -= nvs_ptr - (u8 *)wl->nvs;
-
- /* Now we must set the partition correctly */
- wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
-
- /* Copy the NVS tables to a new block to ensure alignment */
- nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
- if (!nvs_aligned)
- return -ENOMEM;
-
- /* And finally we upload the NVS tables */
- wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
-
- kfree(nvs_aligned);
- return 0;
-
-out_badnvs:
- wl1271_error("nvs data is malformed");
- return -EILSEQ;
-}
-
-static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
-{
- wl1271_enable_interrupts(wl);
- wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
- WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
- wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
-}
-
-static int wl1271_boot_soft_reset(struct wl1271 *wl)
-{
- unsigned long timeout;
- u32 boot_data;
-
- /* perform soft reset */
- wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
-
- /* SOFT_RESET is self clearing */
- timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
- while (1) {
- boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET);
- wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
- if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
- break;
-
- if (time_after(jiffies, timeout)) {
- /* 1.2 check pWhalBus->uSelfClearTime if the
- * timeout was reached */
- wl1271_error("soft reset timeout");
- return -1;
- }
-
- udelay(SOFT_RESET_STALL_TIME);
- }
-
- /* disable Rx/Tx */
- wl1271_write32(wl, ENABLE, 0x0);
-
- /* disable auto calibration on start*/
- wl1271_write32(wl, SPARE_A2, 0xffff);
-
- return 0;
-}
-
-static int wl1271_boot_run_firmware(struct wl1271 *wl)
-{
- int loop, ret;
- u32 chip_id, intr;
-
- wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
-
- chip_id = wl1271_read32(wl, CHIP_ID_B);
-
- wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
-
- if (chip_id != wl->chip.id) {
- wl1271_error("chip id doesn't match after firmware boot");
- return -EIO;
- }
-
- /* wait for init to complete */
- loop = 0;
- while (loop++ < INIT_LOOP) {
- udelay(INIT_LOOP_DELAY);
- intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-
- if (intr == 0xffffffff) {
- wl1271_error("error reading hardware complete "
- "init indication");
- return -EIO;
- }
- /* check that ACX_INTR_INIT_COMPLETE is enabled */
- else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
- wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
- WL1271_ACX_INTR_INIT_COMPLETE);
- break;
- }
- }
-
- if (loop > INIT_LOOP) {
- wl1271_error("timeout waiting for the hardware to "
- "complete initialization");
- return -EIO;
- }
-
- /* get hardware config command mail box */
- wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR);
-
- /* get hardware config event mail box */
- wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
-
- /* set the working partition to its "running" mode offset */
- wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
-
- wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
- wl->cmd_box_addr, wl->event_box_addr);
-
- wl1271_boot_fw_version(wl);
-
- /*
- * in case of full asynchronous mode the firmware event must be
- * ready to receive event from the command mailbox
- */
-
- /* unmask required mbox events */
- wl->event_mask = BSS_LOSE_EVENT_ID |
- SCAN_COMPLETE_EVENT_ID |
- ROLE_STOP_COMPLETE_EVENT_ID |
- RSSI_SNR_TRIGGER_0_EVENT_ID |
- PSPOLL_DELIVERY_FAILURE_EVENT_ID |
- SOFT_GEMINI_SENSE_EVENT_ID |
- PERIODIC_SCAN_REPORT_EVENT_ID |
- PERIODIC_SCAN_COMPLETE_EVENT_ID |
- DUMMY_PACKET_EVENT_ID |
- PEER_REMOVE_COMPLETE_EVENT_ID |
- BA_SESSION_RX_CONSTRAINT_EVENT_ID |
- REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
- INACTIVE_STA_EVENT_ID |
- MAX_TX_RETRY_EVENT_ID |
- CHANNEL_SWITCH_COMPLETE_EVENT_ID;
-
- ret = wl1271_event_unmask(wl);
- if (ret < 0) {
- wl1271_error("EVENT mask setting failed");
- return ret;
- }
-
- wl1271_event_mbox_config(wl);
-
- /* firmware startup completed */
- return 0;
-}
-
-static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
-{
- u32 polarity;
-
- polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
-
- /* We use HIGH polarity, so unset the LOW bit */
- polarity &= ~POLARITY_LOW;
- wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
-
- return 0;
-}
-
-static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
-{
- u16 spare_reg;
-
- /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
- spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
- if (spare_reg == 0xFFFF)
- return -EFAULT;
- spare_reg |= (BIT(3) | BIT(5) | BIT(6));
- wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
-
- /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
- wl1271_top_reg_write(wl, SYS_CLK_CFG_REG,
- WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
-
- /* Delay execution for 15msec, to let the HW settle */
- mdelay(15);
-
- return 0;
-}
-
-static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
-{
- u16 tcxo_detection;
-
- tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG);
- if (tcxo_detection & TCXO_DET_FAILED)
- return false;
-
- return true;
-}
-
-static bool wl128x_is_fref_valid(struct wl1271 *wl)
-{
- u16 fref_detection;
-
- fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG);
- if (fref_detection & FREF_CLK_DETECT_FAIL)
- return false;
-
- return true;
-}
-
-static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
-{
- wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
- wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
- wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
-
- return 0;
-}
-
-static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
-{
- u16 spare_reg;
- u16 pll_config;
- u8 input_freq;
-
- /* Mask bits [3:1] in the sys_clk_cfg register */
- spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
- if (spare_reg == 0xFFFF)
- return -EFAULT;
- spare_reg |= BIT(2);
- wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
-
- /* Handle special cases of the TCXO clock */
- if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
- wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
- return wl128x_manually_configure_mcs_pll(wl);
-
- /* Set the input frequency according to the selected clock source */
- input_freq = (clk & 1) + 1;
-
- pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG);
- if (pll_config == 0xFFFF)
- return -EFAULT;
- pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
- pll_config |= MCS_PLL_ENABLE_HP;
- wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
-
- return 0;
-}
-
-/*
- * WL128x has two clocks input - TCXO and FREF.
- * TCXO is the main clock of the device, while FREF is used to sync
- * between the GPS and the cellular modem.
- * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
- * as the WLAN/BT main clock.
- */
-static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
-{
- u16 sys_clk_cfg;
-
- /* For XTAL-only modes, FREF will be used after switching from TCXO */
- if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
- wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
- if (!wl128x_switch_tcxo_to_fref(wl))
- return -EINVAL;
- goto fref_clk;
- }
-
- /* Query the HW, to determine which clock source we should use */
- sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG);
- if (sys_clk_cfg == 0xFFFF)
- return -EINVAL;
- if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
- goto fref_clk;
-
- /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
- if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
- wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
- if (!wl128x_switch_tcxo_to_fref(wl))
- return -EINVAL;
- goto fref_clk;
- }
-
- /* TCXO clock is selected */
- if (!wl128x_is_tcxo_valid(wl))
- return -EINVAL;
- *selected_clock = wl->tcxo_clock;
- goto config_mcs_pll;
-
-fref_clk:
- /* FREF clock is selected */
- if (!wl128x_is_fref_valid(wl))
- return -EINVAL;
- *selected_clock = wl->ref_clock;
-
-config_mcs_pll:
- return wl128x_configure_mcs_pll(wl, *selected_clock);
-}
-
-static int wl127x_boot_clk(struct wl1271 *wl)
-{
- u32 pause;
- u32 clk;
-
- if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
- wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
-
- if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
- wl->ref_clock == CONF_REF_CLK_38_4_E ||
- wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
- /* ref clk: 19.2/38.4/38.4-XTAL */
- clk = 0x3;
- else if (wl->ref_clock == CONF_REF_CLK_26_E ||
- wl->ref_clock == CONF_REF_CLK_52_E)
- /* ref clk: 26/52 */
- clk = 0x5;
- else
- return -EINVAL;
-
- if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
- u16 val;
- /* Set clock type (open drain) */
- val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
- val &= FREF_CLK_TYPE_BITS;
- wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
-
- /* Set clock pull mode (no pull) */
- val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
- val |= NO_PULL;
- wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
- } else {
- u16 val;
- /* Set clock polarity */
- val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY);
- val &= FREF_CLK_POLARITY_BITS;
- val |= CLK_REQ_OUTN_SEL;
- wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
- }
-
- wl1271_write32(wl, PLL_PARAMETERS, clk);
-
- pause = wl1271_read32(wl, PLL_PARAMETERS);
-
- wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
-
- pause &= ~(WU_COUNTER_PAUSE_VAL);
- pause |= WU_COUNTER_PAUSE_VAL;
- wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
-
- return 0;
-}
-
-/* uploads NVS and firmware */
-int wl1271_load_firmware(struct wl1271 *wl)
-{
- int ret = 0;
- u32 tmp, clk;
- int selected_clock = -1;
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- ret = wl128x_boot_clk(wl, &selected_clock);
- if (ret < 0)
- goto out;
- } else {
- ret = wl127x_boot_clk(wl);
- if (ret < 0)
- goto out;
- }
-
- /* Continue the ELP wake up sequence */
- wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
- udelay(500);
-
- wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
-
- /* Read-modify-write DRPW_SCRATCH_START register (see next state)
- to be used by DRPw FW. The RTRIM value will be added by the FW
- before taking DRPw out of reset */
-
- wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
- clk = wl1271_read32(wl, DRPW_SCRATCH_START);
-
- wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- clk |= ((selected_clock & 0x3) << 1) << 4;
- } else {
- clk |= (wl->ref_clock << 1) << 4;
- }
-
- wl1271_write32(wl, DRPW_SCRATCH_START, clk);
-
- wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
-
- /* Disable interrupts */
- wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
-
- ret = wl1271_boot_soft_reset(wl);
- if (ret < 0)
- goto out;
-
- /* 2. start processing NVS file */
- ret = wl1271_boot_upload_nvs(wl);
- if (ret < 0)
- goto out;
-
- /* write firmware's last address (ie. it's length) to
- * ACX_EEPROMLESS_IND_REG */
- wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
-
- wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
-
- tmp = wl1271_read32(wl, CHIP_ID_B);
-
- wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
-
- /* 6. read the EEPROM parameters */
- tmp = wl1271_read32(wl, SCR_PAD2);
-
- /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
- * to upload_fw) */
-
- if (wl->chip.id == CHIP_ID_1283_PG20)
- wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds);
-
- ret = wl1271_boot_upload_firmware(wl);
- if (ret < 0)
- goto out;
-
-out:
- return ret;
-}
-EXPORT_SYMBOL_GPL(wl1271_load_firmware);
-
-int wl1271_boot(struct wl1271 *wl)
-{
- int ret;
-
- /* upload NVS and firmware */
- ret = wl1271_load_firmware(wl);
- if (ret)
- return ret;
-
- /* 10.5 start firmware */
- ret = wl1271_boot_run_firmware(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_boot_write_irq_polarity(wl);
- if (ret < 0)
- goto out;
-
- wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
- WL1271_ACX_ALL_EVENTS_VECTOR);
-
- /* Enable firmware interrupts now */
- wl1271_boot_enable_interrupts(wl);
-
- wl1271_event_mbox_config(wl);
-
-out:
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
deleted file mode 100644
index c3adc09f403d..000000000000
--- a/drivers/net/wireless/wl12xx/boot.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __BOOT_H__
-#define __BOOT_H__
-
-#include "wl12xx.h"
-
-int wl1271_boot(struct wl1271 *wl);
-int wl1271_load_firmware(struct wl1271 *wl);
-
-#define WL1271_NO_SUBBANDS 8
-#define WL1271_NO_POWER_LEVELS 4
-#define WL1271_FW_VERSION_MAX_LEN 20
-
-struct wl1271_static_data {
- u8 mac_address[ETH_ALEN];
- u8 padding[2];
- u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
- u32 hw_version;
- u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
-};
-
-/* number of times we try to read the INIT interrupt */
-#define INIT_LOOP 20000
-
-/* delay between retries */
-#define INIT_LOOP_DELAY 50
-
-#define WU_COUNTER_PAUSE_VAL 0x3FF
-#define WELP_ARM_COMMAND_VAL 0x4
-
-#define OCP_REG_POLARITY 0x0064
-#define OCP_REG_CLK_TYPE 0x0448
-#define OCP_REG_CLK_POLARITY 0x0cb2
-#define OCP_REG_CLK_PULL 0x0cb4
-
-#define CMD_MBOX_ADDRESS 0x407B4
-
-#define POLARITY_LOW BIT(1)
-#define NO_PULL (BIT(14) | BIT(15))
-
-#define FREF_CLK_TYPE_BITS 0xfffffe7f
-#define CLK_REQ_PRCM 0x100
-#define FREF_CLK_POLARITY_BITS 0xfffff8ff
-#define CLK_REQ_OUTN_SEL 0x700
-
-/* PLL configuration algorithm for wl128x */
-#define SYS_CLK_CFG_REG 0x2200
-/* Bit[0] - 0-TCXO, 1-FREF */
-#define MCS_PLL_CLK_SEL_FREF BIT(0)
-/* Bit[3:2] - 01-TCXO, 10-FREF */
-#define WL_CLK_REQ_TYPE_FREF BIT(3)
-#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
-/* Bit[4] - 0-TCXO, 1-FREF */
-#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
-
-#define TCXO_ILOAD_INT_REG 0x2264
-#define TCXO_CLK_DETECT_REG 0x2266
-
-#define TCXO_DET_FAILED BIT(4)
-
-#define FREF_ILOAD_INT_REG 0x2084
-#define FREF_CLK_DETECT_REG 0x2086
-#define FREF_CLK_DETECT_FAIL BIT(4)
-
-/* Use this reg for masking during driver access */
-#define WL_SPARE_REG 0x2320
-#define WL_SPARE_VAL BIT(2)
-/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
-#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
-
-#define PLL_LOCK_COUNTERS_REG 0xD8C
-#define PLL_LOCK_COUNTERS_COEX 0x0F
-#define PLL_LOCK_COUNTERS_MCS 0xF0
-#define MCS_PLL_OVERRIDE_REG 0xD90
-#define MCS_PLL_CONFIG_REG 0xD92
-#define MCS_SEL_IN_FREQ_MASK 0x0070
-#define MCS_SEL_IN_FREQ_SHIFT 4
-#define MCS_PLL_CONFIG_REG_VAL 0x73
-#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
-
-#define MCS_PLL_M_REG 0xD94
-#define MCS_PLL_N_REG 0xD96
-#define MCS_PLL_M_REG_VAL 0xC8
-#define MCS_PLL_N_REG_VAL 0x07
-
-#define SDIO_IO_DS 0xd14
-
-/* SDIO/wSPI DS configuration values */
-enum {
- HCI_IO_DS_8MA = 0,
- HCI_IO_DS_4MA = 1, /* default */
- HCI_IO_DS_6MA = 2,
- HCI_IO_DS_2MA = 3,
-};
-
-/* end PLL configuration algorithm for wl128x */
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
deleted file mode 100644
index 82cb90a4a99c..000000000000
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ /dev/null
@@ -1,1950 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/etherdevice.h>
-#include <linux/ieee80211.h>
-#include <linux/slab.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "reg.h"
-#include "io.h"
-#include "acx.h"
-#include "wl12xx_80211.h"
-#include "cmd.h"
-#include "event.h"
-#include "tx.h"
-
-#define WL1271_CMD_FAST_POLL_COUNT 50
-
-/*
- * send command to firmware
- *
- * @wl: wl struct
- * @id: command id
- * @buf: buffer containing the command, must work with dma
- * @len: length of the buffer
- */
-int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
- size_t res_len)
-{
- struct wl1271_cmd_header *cmd;
- unsigned long timeout;
- u32 intr;
- int ret = 0;
- u16 status;
- u16 poll_count = 0;
-
- cmd = buf;
- cmd->id = cpu_to_le16(id);
- cmd->status = 0;
-
- WARN_ON(len % 4 != 0);
- WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags));
-
- wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
-
- wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
-
- timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
-
- intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
- while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
- if (time_after(jiffies, timeout)) {
- wl1271_error("command complete timeout");
- ret = -ETIMEDOUT;
- goto fail;
- }
-
- poll_count++;
- if (poll_count < WL1271_CMD_FAST_POLL_COUNT)
- udelay(10);
- else
- msleep(1);
-
- intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
- }
-
- /* read back the status code of the command */
- if (res_len == 0)
- res_len = sizeof(struct wl1271_cmd_header);
- wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false);
-
- status = le16_to_cpu(cmd->status);
- if (status != CMD_STATUS_SUCCESS) {
- wl1271_error("command execute failure %d", status);
- ret = -EIO;
- goto fail;
- }
-
- wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
- WL1271_ACX_INTR_CMD_COMPLETE);
- return 0;
-
-fail:
- WARN_ON(1);
- wl12xx_queue_recovery_work(wl);
- return ret;
-}
-
-int wl1271_cmd_general_parms(struct wl1271 *wl)
-{
- struct wl1271_general_parms_cmd *gen_parms;
- struct wl1271_ini_general_params *gp =
- &((struct wl1271_nvs_file *)wl->nvs)->general_params;
- bool answer = false;
- int ret;
-
- if (!wl->nvs)
- return -ENODEV;
-
- if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
- wl1271_warning("FEM index from INI out of bounds");
- return -EINVAL;
- }
-
- gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
- if (!gen_parms)
- return -ENOMEM;
-
- gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
-
- memcpy(&gen_parms->general_params, gp, sizeof(*gp));
-
- if (gp->tx_bip_fem_auto_detect)
- answer = true;
-
- /* Override the REF CLK from the NVS with the one from platform data */
- gen_parms->general_params.ref_clock = wl->ref_clock;
-
- ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
- if (ret < 0) {
- wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
- goto out;
- }
-
- gp->tx_bip_fem_manufacturer =
- gen_parms->general_params.tx_bip_fem_manufacturer;
-
- if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
- wl1271_warning("FEM index from FW out of bounds");
- ret = -EINVAL;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
- answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
-
-out:
- kfree(gen_parms);
- return ret;
-}
-
-int wl128x_cmd_general_parms(struct wl1271 *wl)
-{
- struct wl128x_general_parms_cmd *gen_parms;
- struct wl128x_ini_general_params *gp =
- &((struct wl128x_nvs_file *)wl->nvs)->general_params;
- bool answer = false;
- int ret;
-
- if (!wl->nvs)
- return -ENODEV;
-
- if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
- wl1271_warning("FEM index from ini out of bounds");
- return -EINVAL;
- }
-
- gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
- if (!gen_parms)
- return -ENOMEM;
-
- gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
-
- memcpy(&gen_parms->general_params, gp, sizeof(*gp));
-
- if (gp->tx_bip_fem_auto_detect)
- answer = true;
-
- /* Replace REF and TCXO CLKs with the ones from platform data */
- gen_parms->general_params.ref_clock = wl->ref_clock;
- gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
-
- ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
- if (ret < 0) {
- wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
- goto out;
- }
-
- gp->tx_bip_fem_manufacturer =
- gen_parms->general_params.tx_bip_fem_manufacturer;
-
- if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
- wl1271_warning("FEM index from FW out of bounds");
- ret = -EINVAL;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
- answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
-
-out:
- kfree(gen_parms);
- return ret;
-}
-
-int wl1271_cmd_radio_parms(struct wl1271 *wl)
-{
- struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
- struct wl1271_radio_parms_cmd *radio_parms;
- struct wl1271_ini_general_params *gp = &nvs->general_params;
- int ret;
-
- if (!wl->nvs)
- return -ENODEV;
-
- radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
- if (!radio_parms)
- return -ENOMEM;
-
- radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
-
- /* 2.4GHz parameters */
- memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
- sizeof(struct wl1271_ini_band_params_2));
- memcpy(&radio_parms->dyn_params_2,
- &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
- sizeof(struct wl1271_ini_fem_params_2));
-
- /* 5GHz parameters */
- memcpy(&radio_parms->static_params_5,
- &nvs->stat_radio_params_5,
- sizeof(struct wl1271_ini_band_params_5));
- memcpy(&radio_parms->dyn_params_5,
- &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
- sizeof(struct wl1271_ini_fem_params_5));
-
- wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
- radio_parms, sizeof(*radio_parms));
-
- ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
- if (ret < 0)
- wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
-
- kfree(radio_parms);
- return ret;
-}
-
-int wl128x_cmd_radio_parms(struct wl1271 *wl)
-{
- struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
- struct wl128x_radio_parms_cmd *radio_parms;
- struct wl128x_ini_general_params *gp = &nvs->general_params;
- int ret;
-
- if (!wl->nvs)
- return -ENODEV;
-
- radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
- if (!radio_parms)
- return -ENOMEM;
-
- radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
-
- /* 2.4GHz parameters */
- memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
- sizeof(struct wl128x_ini_band_params_2));
- memcpy(&radio_parms->dyn_params_2,
- &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
- sizeof(struct wl128x_ini_fem_params_2));
-
- /* 5GHz parameters */
- memcpy(&radio_parms->static_params_5,
- &nvs->stat_radio_params_5,
- sizeof(struct wl128x_ini_band_params_5));
- memcpy(&radio_parms->dyn_params_5,
- &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
- sizeof(struct wl128x_ini_fem_params_5));
-
- radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
-
- wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
- radio_parms, sizeof(*radio_parms));
-
- ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
- if (ret < 0)
- wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
-
- kfree(radio_parms);
- return ret;
-}
-
-int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
-{
- struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
- struct conf_rf_settings *rf = &wl->conf.rf;
- int ret;
-
- if (!wl->nvs)
- return -ENODEV;
-
- ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
- if (!ext_radio_parms)
- return -ENOMEM;
-
- ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
-
- memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
- rf->tx_per_channel_power_compensation_2,
- CONF_TX_PWR_COMPENSATION_LEN_2);
- memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
- rf->tx_per_channel_power_compensation_5,
- CONF_TX_PWR_COMPENSATION_LEN_5);
-
- wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
- ext_radio_parms, sizeof(*ext_radio_parms));
-
- ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
- if (ret < 0)
- wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
-
- kfree(ext_radio_parms);
- return ret;
-}
-
-/*
- * Poll the mailbox event field until any of the bits in the mask is set or a
- * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
- */
-static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
-{
- u32 *events_vector;
- u32 event;
- unsigned long timeout;
- int ret = 0;
-
- events_vector = kmalloc(sizeof(*events_vector), GFP_DMA);
-
- timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
-
- do {
- if (time_after(jiffies, timeout)) {
- wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
- (int)mask);
- ret = -ETIMEDOUT;
- goto out;
- }
-
- msleep(1);
-
- /* read from both event fields */
- wl1271_read(wl, wl->mbox_ptr[0], events_vector,
- sizeof(*events_vector), false);
- event = *events_vector & mask;
- wl1271_read(wl, wl->mbox_ptr[1], events_vector,
- sizeof(*events_vector), false);
- event |= *events_vector & mask;
- } while (!event);
-
-out:
- kfree(events_vector);
- return ret;
-}
-
-static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
-{
- int ret;
-
- ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask);
- if (ret != 0) {
- wl12xx_queue_recovery_work(wl);
- return ret;
- }
-
- return 0;
-}
-
-int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
- u8 *role_id)
-{
- struct wl12xx_cmd_role_enable *cmd;
- int ret;
-
- wl1271_debug(DEBUG_CMD, "cmd role enable");
-
- if (WARN_ON(*role_id != WL12XX_INVALID_ROLE_ID))
- return -EBUSY;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* get role id */
- cmd->role_id = find_first_zero_bit(wl->roles_map, WL12XX_MAX_ROLES);
- if (cmd->role_id >= WL12XX_MAX_ROLES) {
- ret = -EBUSY;
- goto out_free;
- }
-
- memcpy(cmd->mac_address, addr, ETH_ALEN);
- cmd->role_type = role_type;
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_ENABLE, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role enable");
- goto out_free;
- }
-
- __set_bit(cmd->role_id, wl->roles_map);
- *role_id = cmd->role_id;
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id)
-{
- struct wl12xx_cmd_role_disable *cmd;
- int ret;
-
- wl1271_debug(DEBUG_CMD, "cmd role disable");
-
- if (WARN_ON(*role_id == WL12XX_INVALID_ROLE_ID))
- return -ENOENT;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
- cmd->role_id = *role_id;
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_DISABLE, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role disable");
- goto out_free;
- }
-
- __clear_bit(*role_id, wl->roles_map);
- *role_id = WL12XX_INVALID_ROLE_ID;
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
-{
- unsigned long flags;
- u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
- if (link >= WL12XX_MAX_LINKS)
- return -EBUSY;
-
- /* these bits are used by op_tx */
- spin_lock_irqsave(&wl->wl_lock, flags);
- __set_bit(link, wl->links_map);
- __set_bit(link, wlvif->links_map);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- *hlid = link;
- return 0;
-}
-
-void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
-{
- unsigned long flags;
-
- if (*hlid == WL12XX_INVALID_LINK_ID)
- return;
-
- /* these bits are used by op_tx */
- spin_lock_irqsave(&wl->wl_lock, flags);
- __clear_bit(*hlid, wl->links_map);
- __clear_bit(*hlid, wlvif->links_map);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- /*
- * At this point op_tx() will not add more packets to the queues. We
- * can purge them.
- */
- wl1271_tx_reset_link_queues(wl, *hlid);
-
- *hlid = WL12XX_INVALID_LINK_ID;
-}
-
-static int wl12xx_get_new_session_id(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- if (wlvif->session_counter >= SESSION_COUNTER_MAX)
- wlvif->session_counter = 0;
-
- wlvif->session_counter++;
-
- return wlvif->session_counter;
-}
-
-static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct wl12xx_cmd_role_start *cmd;
- int ret;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wlvif->dev_role_id);
-
- cmd->role_id = wlvif->dev_role_id;
- if (wlvif->band == IEEE80211_BAND_5GHZ)
- cmd->band = WL12XX_BAND_5GHZ;
- cmd->channel = wlvif->channel;
-
- if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) {
- ret = wl12xx_allocate_link(wl, wlvif, &wlvif->dev_hlid);
- if (ret)
- goto out_free;
- }
- cmd->device.hlid = wlvif->dev_hlid;
- cmd->device.session = wl12xx_get_new_session_id(wl, wlvif);
-
- wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
- cmd->role_id, cmd->device.hlid, cmd->device.session);
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role enable");
- goto err_hlid;
- }
-
- goto out_free;
-
-err_hlid:
- /* clear links on error */
- wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct wl12xx_cmd_role_stop *cmd;
- int ret;
-
- if (WARN_ON(wlvif->dev_hlid == WL12XX_INVALID_LINK_ID))
- return -EINVAL;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "cmd role stop dev");
-
- cmd->role_id = wlvif->dev_role_id;
- cmd->disc_type = DISCONNECT_IMMEDIATE;
- cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role stop");
- goto out_free;
- }
-
- ret = wl1271_cmd_wait_for_event(wl, ROLE_STOP_COMPLETE_EVENT_ID);
- if (ret < 0) {
- wl1271_error("cmd role stop dev event completion error");
- goto out_free;
- }
-
- wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct wl12xx_cmd_role_start *cmd;
- int ret;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "cmd role start sta %d", wlvif->role_id);
-
- cmd->role_id = wlvif->role_id;
- if (wlvif->band == IEEE80211_BAND_5GHZ)
- cmd->band = WL12XX_BAND_5GHZ;
- cmd->channel = wlvif->channel;
- cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
- cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int);
- cmd->sta.ssid_type = WL12XX_SSID_TYPE_ANY;
- cmd->sta.ssid_len = wlvif->ssid_len;
- memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len);
- memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN);
- cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set);
-
- if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) {
- ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid);
- if (ret)
- goto out_free;
- }
- cmd->sta.hlid = wlvif->sta.hlid;
- cmd->sta.session = wl12xx_get_new_session_id(wl, wlvif);
- cmd->sta.remote_rates = cpu_to_le32(wlvif->rate_set);
-
- wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
- "basic_rate_set: 0x%x, remote_rates: 0x%x",
- wlvif->role_id, cmd->sta.hlid, cmd->sta.session,
- wlvif->basic_rate_set, wlvif->rate_set);
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role start sta");
- goto err_hlid;
- }
-
- goto out_free;
-
-err_hlid:
- /* clear links on error. */
- wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-/* use this function to stop ibss as well */
-int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct wl12xx_cmd_role_stop *cmd;
- int ret;
-
- if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID))
- return -EINVAL;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "cmd role stop sta %d", wlvif->role_id);
-
- cmd->role_id = wlvif->role_id;
- cmd->disc_type = DISCONNECT_IMMEDIATE;
- cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role stop sta");
- goto out_free;
- }
-
- wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct wl12xx_cmd_role_start *cmd;
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- int ret;
-
- wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id);
-
- /* trying to use hidden SSID with an old hostapd version */
- if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) {
- wl1271_error("got a null SSID from beacon/bss");
- ret = -EINVAL;
- goto out;
- }
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.global_hlid);
- if (ret < 0)
- goto out_free;
-
- ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.bcast_hlid);
- if (ret < 0)
- goto out_free_global;
-
- cmd->role_id = wlvif->role_id;
- cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
- cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
- cmd->ap.global_hlid = wlvif->ap.global_hlid;
- cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid;
- cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
- cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
- cmd->ap.dtim_interval = bss_conf->dtim_period;
- cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
- /* FIXME: Change when adding DFS */
- cmd->ap.reset_tsf = 1; /* By default reset AP TSF */
- cmd->channel = wlvif->channel;
-
- if (!bss_conf->hidden_ssid) {
- /* take the SSID from the beacon for backward compatibility */
- cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
- cmd->ap.ssid_len = wlvif->ssid_len;
- memcpy(cmd->ap.ssid, wlvif->ssid, wlvif->ssid_len);
- } else {
- cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
- cmd->ap.ssid_len = bss_conf->ssid_len;
- memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
- }
-
- cmd->ap.local_rates = cpu_to_le32(0xffffffff);
-
- switch (wlvif->band) {
- case IEEE80211_BAND_2GHZ:
- cmd->band = RADIO_BAND_2_4GHZ;
- break;
- case IEEE80211_BAND_5GHZ:
- cmd->band = RADIO_BAND_5GHZ;
- break;
- default:
- wl1271_warning("ap start - unknown band: %d", (int)wlvif->band);
- cmd->band = RADIO_BAND_2_4GHZ;
- break;
- }
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role start ap");
- goto out_free_bcast;
- }
-
- goto out_free;
-
-out_free_bcast:
- wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid);
-
-out_free_global:
- wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct wl12xx_cmd_role_stop *cmd;
- int ret;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "cmd role stop ap %d", wlvif->role_id);
-
- cmd->role_id = wlvif->role_id;
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role stop ap");
- goto out_free;
- }
-
- wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid);
- wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct wl12xx_cmd_role_start *cmd;
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- int ret;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_debug(DEBUG_CMD, "cmd role start ibss %d", wlvif->role_id);
-
- cmd->role_id = wlvif->role_id;
- if (wlvif->band == IEEE80211_BAND_5GHZ)
- cmd->band = WL12XX_BAND_5GHZ;
- cmd->channel = wlvif->channel;
- cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
- cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int);
- cmd->ibss.dtim_interval = bss_conf->dtim_period;
- cmd->ibss.ssid_type = WL12XX_SSID_TYPE_ANY;
- cmd->ibss.ssid_len = wlvif->ssid_len;
- memcpy(cmd->ibss.ssid, wlvif->ssid, wlvif->ssid_len);
- memcpy(cmd->ibss.bssid, vif->bss_conf.bssid, ETH_ALEN);
- cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set);
-
- if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) {
- ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid);
- if (ret)
- goto out_free;
- }
- cmd->ibss.hlid = wlvif->sta.hlid;
- cmd->ibss.remote_rates = cpu_to_le32(wlvif->rate_set);
-
- wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
- "basic_rate_set: 0x%x, remote_rates: 0x%x",
- wlvif->role_id, cmd->sta.hlid, cmd->sta.session,
- wlvif->basic_rate_set, wlvif->rate_set);
-
- wl1271_debug(DEBUG_CMD, "vif->bss_conf.bssid = %pM",
- vif->bss_conf.bssid);
-
- ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd role enable");
- goto err_hlid;
- }
-
- goto out_free;
-
-err_hlid:
- /* clear links on error. */
- wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-
-/**
- * send test command to firmware
- *
- * @wl: wl struct
- * @buf: buffer containing the command, with all headers, must work with dma
- * @len: length of the buffer
- * @answer: is answer needed
- */
-int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
-{
- int ret;
- size_t res_len = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd test");
-
- if (answer)
- res_len = buf_len;
-
- ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len);
-
- if (ret < 0) {
- wl1271_warning("TEST command failed");
- return ret;
- }
-
- return ret;
-}
-
-/**
- * read acx from firmware
- *
- * @wl: wl struct
- * @id: acx id
- * @buf: buffer for the response, including all headers, must work with dma
- * @len: length of buf
- */
-int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
-{
- struct acx_header *acx = buf;
- int ret;
-
- wl1271_debug(DEBUG_CMD, "cmd interrogate");
-
- acx->id = cpu_to_le16(id);
-
- /* payload length, does not include any headers */
- acx->len = cpu_to_le16(len - sizeof(*acx));
-
- ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len);
- if (ret < 0)
- wl1271_error("INTERROGATE command failed");
-
- return ret;
-}
-
-/**
- * write acx value to firmware
- *
- * @wl: wl struct
- * @id: acx id
- * @buf: buffer containing acx, including all headers, must work with dma
- * @len: length of buf
- */
-int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
-{
- struct acx_header *acx = buf;
- int ret;
-
- wl1271_debug(DEBUG_CMD, "cmd configure (%d)", id);
-
- acx->id = cpu_to_le16(id);
-
- /* payload length, does not include any headers */
- acx->len = cpu_to_le16(len - sizeof(*acx));
-
- ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0);
- if (ret < 0) {
- wl1271_warning("CONFIGURE command NOK");
- return ret;
- }
-
- return 0;
-}
-
-int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
-{
- struct cmd_enabledisable_path *cmd;
- int ret;
- u16 cmd_rx, cmd_tx;
-
- wl1271_debug(DEBUG_CMD, "cmd data path");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* the channel here is only used for calibration, so hardcoded to 1 */
- cmd->channel = 1;
-
- if (enable) {
- cmd_rx = CMD_ENABLE_RX;
- cmd_tx = CMD_ENABLE_TX;
- } else {
- cmd_rx = CMD_DISABLE_RX;
- cmd_tx = CMD_DISABLE_TX;
- }
-
- ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("rx %s cmd for channel %d failed",
- enable ? "start" : "stop", cmd->channel);
- goto out;
- }
-
- wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
- enable ? "start" : "stop", cmd->channel);
-
- ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("tx %s cmd for channel %d failed",
- enable ? "start" : "stop", cmd->channel);
- goto out;
- }
-
- wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
- enable ? "start" : "stop", cmd->channel);
-
-out:
- kfree(cmd);
- return ret;
-}
-
-int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 ps_mode, u16 auto_ps_timeout)
-{
- struct wl1271_cmd_ps_params *ps_params = NULL;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd set ps mode");
-
- ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
- if (!ps_params) {
- ret = -ENOMEM;
- goto out;
- }
-
- ps_params->role_id = wlvif->role_id;
- ps_params->ps_mode = ps_mode;
- ps_params->auto_ps_timeout = auto_ps_timeout;
-
- ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
- sizeof(*ps_params), 0);
- if (ret < 0) {
- wl1271_error("cmd set_ps_mode failed");
- goto out;
- }
-
-out:
- kfree(ps_params);
- return ret;
-}
-
-int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
- u16 template_id, void *buf, size_t buf_len,
- int index, u32 rates)
-{
- struct wl1271_cmd_template_set *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd template_set %d (role %d)",
- template_id, role_id);
-
- WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
- buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* during initialization wlvif is NULL */
- cmd->role_id = role_id;
- cmd->len = cpu_to_le16(buf_len);
- cmd->template_type = template_id;
- cmd->enabled_rates = cpu_to_le32(rates);
- cmd->short_retry_limit = wl->conf.tx.tmpl_short_retry_limit;
- cmd->long_retry_limit = wl->conf.tx.tmpl_long_retry_limit;
- cmd->index = index;
-
- if (buf)
- memcpy(cmd->template_data, buf, buf_len);
-
- ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_warning("cmd set_template failed: %d", ret);
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct sk_buff *skb = NULL;
- int size;
- void *ptr;
- int ret = -ENOMEM;
-
-
- if (wlvif->bss_type == BSS_TYPE_IBSS) {
- size = sizeof(struct wl12xx_null_data_template);
- ptr = NULL;
- } else {
- skb = ieee80211_nullfunc_get(wl->hw,
- wl12xx_wlvif_to_vif(wlvif));
- if (!skb)
- goto out;
- size = skb->len;
- ptr = skb->data;
- }
-
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_NULL_DATA, ptr, size, 0,
- wlvif->basic_rate);
-
-out:
- dev_kfree_skb(skb);
- if (ret)
- wl1271_warning("cmd buld null data failed %d", ret);
-
- return ret;
-
-}
-
-int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct sk_buff *skb = NULL;
- int ret = -ENOMEM;
-
- skb = ieee80211_nullfunc_get(wl->hw, vif);
- if (!skb)
- goto out;
-
- ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV,
- skb->data, skb->len,
- CMD_TEMPL_KLV_IDX_NULL_DATA,
- wlvif->basic_rate);
-
-out:
- dev_kfree_skb(skb);
- if (ret)
- wl1271_warning("cmd build klv null data failed %d", ret);
-
- return ret;
-
-}
-
-int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 aid)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct sk_buff *skb;
- int ret = 0;
-
- skb = ieee80211_pspoll_get(wl->hw, vif);
- if (!skb)
- goto out;
-
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_PS_POLL, skb->data,
- skb->len, 0, wlvif->basic_rate_set);
-
-out:
- dev_kfree_skb(skb);
- return ret;
-}
-
-int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 role_id, u8 band,
- const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct sk_buff *skb;
- int ret;
- u32 rate;
-
- skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
- ie, ie_len);
- if (!skb) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
-
- rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
- if (band == IEEE80211_BAND_2GHZ)
- ret = wl1271_cmd_template_set(wl, role_id,
- CMD_TEMPL_CFG_PROBE_REQ_2_4,
- skb->data, skb->len, 0, rate);
- else
- ret = wl1271_cmd_template_set(wl, role_id,
- CMD_TEMPL_CFG_PROBE_REQ_5,
- skb->data, skb->len, 0, rate);
-
-out:
- dev_kfree_skb(skb);
- return ret;
-}
-
-struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct sk_buff *skb)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- int ret;
- u32 rate;
-
- if (!skb)
- skb = ieee80211_ap_probereq_get(wl->hw, vif);
- if (!skb)
- goto out;
-
- wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
-
- rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
- if (wlvif->band == IEEE80211_BAND_2GHZ)
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_CFG_PROBE_REQ_2_4,
- skb->data, skb->len, 0, rate);
- else
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_CFG_PROBE_REQ_5,
- skb->data, skb->len, 0, rate);
-
- if (ret < 0)
- wl1271_error("Unable to set ap probe request template.");
-
-out:
- return skb;
-}
-
-int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret, extra;
- u16 fc;
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- struct sk_buff *skb;
- struct wl12xx_arp_rsp_template *tmpl;
- struct ieee80211_hdr_3addr *hdr;
- struct arphdr *arp_hdr;
-
- skb = dev_alloc_skb(sizeof(*hdr) + sizeof(__le16) + sizeof(*tmpl) +
- WL1271_EXTRA_SPACE_MAX);
- if (!skb) {
- wl1271_error("failed to allocate buffer for arp rsp template");
- return -ENOMEM;
- }
-
- skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX);
-
- tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl));
- memset(tmpl, 0, sizeof(tmpl));
-
- /* llc layer */
- memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
- tmpl->llc_type = cpu_to_be16(ETH_P_ARP);
-
- /* arp header */
- arp_hdr = &tmpl->arp_hdr;
- arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER);
- arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP);
- arp_hdr->ar_hln = ETH_ALEN;
- arp_hdr->ar_pln = 4;
- arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY);
-
- /* arp payload */
- memcpy(tmpl->sender_hw, vif->addr, ETH_ALEN);
- tmpl->sender_ip = wlvif->ip_addr;
-
- /* encryption space */
- switch (wlvif->encryption_type) {
- case KEY_TKIP:
- extra = WL1271_EXTRA_SPACE_TKIP;
- break;
- case KEY_AES:
- extra = WL1271_EXTRA_SPACE_AES;
- break;
- case KEY_NONE:
- case KEY_WEP:
- case KEY_GEM:
- extra = 0;
- break;
- default:
- wl1271_warning("Unknown encryption type: %d",
- wlvif->encryption_type);
- ret = -EINVAL;
- goto out;
- }
-
- if (extra) {
- u8 *space = skb_push(skb, extra);
- memset(space, 0, extra);
- }
-
- /* QoS header - BE */
- if (wlvif->sta.qos)
- memset(skb_push(skb, sizeof(__le16)), 0, sizeof(__le16));
-
- /* mac80211 header */
- hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr));
- memset(hdr, 0, sizeof(hdr));
- fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS;
- if (wlvif->sta.qos)
- fc |= IEEE80211_STYPE_QOS_DATA;
- else
- fc |= IEEE80211_STYPE_DATA;
- if (wlvif->encryption_type != KEY_NONE)
- fc |= IEEE80211_FCTL_PROTECTED;
-
- hdr->frame_control = cpu_to_le16(fc);
- memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN);
- memcpy(hdr->addr2, vif->addr, ETH_ALEN);
- memset(hdr->addr3, 0xff, ETH_ALEN);
-
- ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP,
- skb->data, skb->len, 0,
- wlvif->basic_rate);
-out:
- dev_kfree_skb(skb);
- return ret;
-}
-
-int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct ieee80211_qos_hdr template;
-
- memset(&template, 0, sizeof(template));
-
- memcpy(template.addr1, vif->bss_conf.bssid, ETH_ALEN);
- memcpy(template.addr2, vif->addr, ETH_ALEN);
- memcpy(template.addr3, vif->bss_conf.bssid, ETH_ALEN);
-
- template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_QOS_NULLFUNC |
- IEEE80211_FCTL_TODS);
-
- /* FIXME: not sure what priority to use here */
- template.qos_ctrl = cpu_to_le16(0);
-
- return wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_QOS_NULL_DATA, &template,
- sizeof(template), 0,
- wlvif->basic_rate);
-}
-
-int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid)
-{
- struct wl1271_cmd_set_keys *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->hlid = hlid;
- cmd->key_id = id;
- cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
- cmd->key_action = cpu_to_le16(KEY_SET_ID);
- cmd->key_type = KEY_WEP;
-
- ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_warning("cmd set_default_wep_key failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(cmd);
-
- return ret;
-}
-
-int wl1271_cmd_set_sta_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 action, u8 id, u8 key_type,
- u8 key_size, const u8 *key, const u8 *addr,
- u32 tx_seq_32, u16 tx_seq_16)
-{
- struct wl1271_cmd_set_keys *cmd;
- int ret = 0;
-
- /* hlid might have already been deleted */
- if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)
- return 0;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->hlid = wlvif->sta.hlid;
-
- if (key_type == KEY_WEP)
- cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
- else if (is_broadcast_ether_addr(addr))
- cmd->lid_key_type = BROADCAST_LID_TYPE;
- else
- cmd->lid_key_type = UNICAST_LID_TYPE;
-
- cmd->key_action = cpu_to_le16(action);
- cmd->key_size = key_size;
- cmd->key_type = key_type;
-
- cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
- cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
-
- cmd->key_id = id;
-
- if (key_type == KEY_TKIP) {
- /*
- * We get the key in the following form:
- * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
- * but the target is expecting:
- * TKIP - RX MIC - TX MIC
- */
- memcpy(cmd->key, key, 16);
- memcpy(cmd->key + 16, key + 24, 8);
- memcpy(cmd->key + 24, key + 16, 8);
-
- } else {
- memcpy(cmd->key, key, key_size);
- }
-
- wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
-
- ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_warning("could not set keys");
- goto out;
- }
-
-out:
- kfree(cmd);
-
- return ret;
-}
-
-/*
- * TODO: merge with sta/ibss into 1 set_key function.
- * note there are slight diffs
- */
-int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 action, u8 id, u8 key_type,
- u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
- u16 tx_seq_16)
-{
- struct wl1271_cmd_set_keys *cmd;
- int ret = 0;
- u8 lid_type;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd)
- return -ENOMEM;
-
- if (hlid == wlvif->ap.bcast_hlid) {
- if (key_type == KEY_WEP)
- lid_type = WEP_DEFAULT_LID_TYPE;
- else
- lid_type = BROADCAST_LID_TYPE;
- } else {
- lid_type = UNICAST_LID_TYPE;
- }
-
- wl1271_debug(DEBUG_CRYPT, "ap key action: %d id: %d lid: %d type: %d"
- " hlid: %d", (int)action, (int)id, (int)lid_type,
- (int)key_type, (int)hlid);
-
- cmd->lid_key_type = lid_type;
- cmd->hlid = hlid;
- cmd->key_action = cpu_to_le16(action);
- cmd->key_size = key_size;
- cmd->key_type = key_type;
- cmd->key_id = id;
- cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
- cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
-
- if (key_type == KEY_TKIP) {
- /*
- * We get the key in the following form:
- * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
- * but the target is expecting:
- * TKIP - RX MIC - TX MIC
- */
- memcpy(cmd->key, key, 16);
- memcpy(cmd->key + 16, key + 24, 8);
- memcpy(cmd->key + 24, key + 16, 8);
- } else {
- memcpy(cmd->key, key, key_size);
- }
-
- wl1271_dump(DEBUG_CRYPT, "TARGET AP KEY: ", cmd, sizeof(*cmd));
-
- ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_warning("could not set ap keys");
- goto out;
- }
-
-out:
- kfree(cmd);
- return ret;
-}
-
-int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
-{
- struct wl12xx_cmd_set_peer_state *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd set peer state (hlid=%d)", hlid);
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->hlid = hlid;
- cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
-
- ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send set peer state command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct ieee80211_sta *sta, u8 hlid)
-{
- struct wl12xx_cmd_add_peer *cmd;
- int i, ret;
- u32 sta_rates;
-
- wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid);
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(cmd->addr, sta->addr, ETH_ALEN);
- cmd->bss_index = WL1271_AP_BSS_INDEX;
- cmd->aid = sta->aid;
- cmd->hlid = hlid;
- cmd->sp_len = sta->max_sp;
- cmd->wmm = sta->wme ? 1 : 0;
-
- for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
- if (sta->wme && (sta->uapsd_queues & BIT(i)))
- cmd->psd_type[i] = WL1271_PSD_UPSD_TRIGGER;
- else
- cmd->psd_type[i] = WL1271_PSD_LEGACY;
-
- sta_rates = sta->supp_rates[wlvif->band];
- if (sta->ht_cap.ht_supported)
- sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET;
-
- cmd->supported_rates =
- cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates,
- wlvif->band));
-
- wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
- cmd->supported_rates, sta->uapsd_queues);
-
- ret = wl1271_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd add peer");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
-{
- struct wl12xx_cmd_remove_peer *cmd;
- int ret;
-
- wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid);
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->hlid = hlid;
- /* We never send a deauth, mac80211 is in charge of this */
- cmd->reason_opcode = 0;
- cmd->send_deauth_flag = 0;
-
- ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to initiate cmd remove peer");
- goto out_free;
- }
-
- /*
- * We are ok with a timeout here. The event is sometimes not sent
- * due to a firmware bug.
- */
- wl1271_cmd_wait_for_event_or_timeout(wl,
- PEER_REMOVE_COMPLETE_EVENT_ID);
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
-{
- struct wl12xx_cmd_config_fwlog *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd config firmware logger");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->logger_mode = wl->conf.fwlog.mode;
- cmd->log_severity = wl->conf.fwlog.severity;
- cmd->timestamp = wl->conf.fwlog.timestamp;
- cmd->output = wl->conf.fwlog.output;
- cmd->threshold = wl->conf.fwlog.threshold;
-
- ret = wl1271_cmd_send(wl, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send config firmware logger command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_start_fwlog(struct wl1271 *wl)
-{
- struct wl12xx_cmd_start_fwlog *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd start firmware logger");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send start firmware logger command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_stop_fwlog(struct wl1271 *wl)
-{
- struct wl12xx_cmd_stop_fwlog *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd stop firmware logger");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1271_cmd_send(wl, CMD_STOP_FWLOGGER, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send stop firmware logger command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 role_id)
-{
- struct wl12xx_cmd_roc *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", wlvif->channel, role_id);
-
- if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID))
- return -EINVAL;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->role_id = role_id;
- cmd->channel = wlvif->channel;
- switch (wlvif->band) {
- case IEEE80211_BAND_2GHZ:
- cmd->band = RADIO_BAND_2_4GHZ;
- break;
- case IEEE80211_BAND_5GHZ:
- cmd->band = RADIO_BAND_5GHZ;
- break;
- default:
- wl1271_error("roc - unknown band: %d", (int)wlvif->band);
- ret = -EINVAL;
- goto out_free;
- }
-
-
- ret = wl1271_cmd_send(wl, CMD_REMAIN_ON_CHANNEL, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send ROC command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-static int wl12xx_cmd_croc(struct wl1271 *wl, u8 role_id)
-{
- struct wl12xx_cmd_croc *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd croc (%d)", role_id);
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
- cmd->role_id = role_id;
-
- ret = wl1271_cmd_send(wl, CMD_CANCEL_REMAIN_ON_CHANNEL, cmd,
- sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send ROC command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id)
-{
- int ret = 0;
-
- if (WARN_ON(test_bit(role_id, wl->roc_map)))
- return 0;
-
- ret = wl12xx_cmd_roc(wl, wlvif, role_id);
- if (ret < 0)
- goto out;
-
- ret = wl1271_cmd_wait_for_event(wl,
- REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID);
- if (ret < 0) {
- wl1271_error("cmd roc event completion error");
- goto out;
- }
-
- __set_bit(role_id, wl->roc_map);
-out:
- return ret;
-}
-
-int wl12xx_croc(struct wl1271 *wl, u8 role_id)
-{
- int ret = 0;
-
- if (WARN_ON(!test_bit(role_id, wl->roc_map)))
- return 0;
-
- ret = wl12xx_cmd_croc(wl, role_id);
- if (ret < 0)
- goto out;
-
- __clear_bit(role_id, wl->roc_map);
-
- /*
- * Rearm the tx watchdog when removing the last ROC. This prevents
- * recoveries due to just finished ROCs - when Tx hasn't yet had
- * a chance to get out.
- */
- if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES)
- wl12xx_rearm_tx_watchdog_locked(wl);
-out:
- return ret;
-}
-
-int wl12xx_cmd_channel_switch(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct ieee80211_channel_switch *ch_switch)
-{
- struct wl12xx_cmd_channel_switch *cmd;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "cmd channel switch");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->role_id = wlvif->role_id;
- cmd->channel = ch_switch->channel->hw_value;
- cmd->switch_time = ch_switch->count;
- cmd->stop_tx = ch_switch->block_tx;
-
- /* FIXME: control from mac80211 in the future */
- cmd->post_switch_tx_disable = 0; /* Enable TX on the target channel */
-
- ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to send channel switch command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
-{
- struct wl12xx_cmd_stop_channel_switch *cmd;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "cmd stop channel switch");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("failed to stop channel switch command");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-
-out:
- return ret;
-}
-
-/* start dev role and roc on its channel */
-int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS)))
- return -EINVAL;
-
- ret = wl12xx_cmd_role_start_dev(wl, wlvif);
- if (ret < 0)
- goto out;
-
- ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
- if (ret < 0)
- goto out_stop;
-
- return 0;
-
-out_stop:
- wl12xx_cmd_role_stop_dev(wl, wlvif);
-out:
- return ret;
-}
-
-/* croc dev hlid, and stop the role */
-int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS)))
- return -EINVAL;
-
- /* flush all pending packets */
- wl1271_tx_work_locked(wl);
-
- if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
- ret = wl12xx_croc(wl, wlvif->dev_role_id);
- if (ret < 0)
- goto out;
- }
-
- ret = wl12xx_cmd_role_stop_dev(wl, wlvif);
- if (ret < 0)
- goto out;
-out:
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
deleted file mode 100644
index de217d92516b..000000000000
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __CMD_H__
-#define __CMD_H__
-
-#include "wl12xx.h"
-
-struct acx_header;
-
-int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
- size_t res_len);
-int wl1271_cmd_general_parms(struct wl1271 *wl);
-int wl128x_cmd_general_parms(struct wl1271 *wl);
-int wl1271_cmd_radio_parms(struct wl1271 *wl);
-int wl128x_cmd_radio_parms(struct wl1271 *wl);
-int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
-int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
- u8 *role_id);
-int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
-int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
-int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
-int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
-int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
-int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 ps_mode, u16 auto_ps_timeout);
-int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
- size_t len);
-int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
- u16 template_id, void *buf, size_t buf_len,
- int index, u32 rates);
-int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 aid);
-int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 role_id, u8 band,
- const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len);
-struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct sk_buff *skb);
-int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif);
-int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
- struct wl12xx_vif *wlvif);
-int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid);
-int wl1271_cmd_set_sta_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 action, u8 id, u8 key_type,
- u8 key_size, const u8 *key, const u8 *addr,
- u32 tx_seq_32, u16 tx_seq_16);
-int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 action, u8 id, u8 key_type,
- u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
- u16 tx_seq_16);
-int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid);
-int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id);
-int wl12xx_croc(struct wl1271 *wl, u8 role_id);
-int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct ieee80211_sta *sta, u8 hlid);
-int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid);
-int wl12xx_cmd_config_fwlog(struct wl1271 *wl);
-int wl12xx_cmd_start_fwlog(struct wl1271 *wl);
-int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);
-int wl12xx_cmd_channel_switch(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct ieee80211_channel_switch *ch_switch);
-int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl);
-int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 *hlid);
-void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid);
-
-enum wl1271_commands {
- CMD_INTERROGATE = 1, /* use this to read information elements */
- CMD_CONFIGURE = 2, /* use this to write information elements */
- CMD_ENABLE_RX = 3,
- CMD_ENABLE_TX = 4,
- CMD_DISABLE_RX = 5,
- CMD_DISABLE_TX = 6,
- CMD_SCAN = 7,
- CMD_STOP_SCAN = 8,
- CMD_SET_KEYS = 9,
- CMD_READ_MEMORY = 10,
- CMD_WRITE_MEMORY = 11,
- CMD_SET_TEMPLATE = 12,
- CMD_TEST = 13,
- CMD_NOISE_HIST = 14,
- CMD_QUIET_ELEMENT_SET_STATE = 15,
- CMD_SET_BCN_MODE = 16,
-
- CMD_MEASUREMENT = 17,
- CMD_STOP_MEASUREMENT = 18,
- CMD_SET_PS_MODE = 19,
- CMD_CHANNEL_SWITCH = 20,
- CMD_STOP_CHANNEL_SWICTH = 21,
- CMD_AP_DISCOVERY = 22,
- CMD_STOP_AP_DISCOVERY = 23,
- CMD_HEALTH_CHECK = 24,
- CMD_DEBUG = 25,
- CMD_TRIGGER_SCAN_TO = 26,
- CMD_CONNECTION_SCAN_CFG = 27,
- CMD_CONNECTION_SCAN_SSID_CFG = 28,
- CMD_START_PERIODIC_SCAN = 29,
- CMD_STOP_PERIODIC_SCAN = 30,
- CMD_SET_PEER_STATE = 31,
- CMD_REMAIN_ON_CHANNEL = 32,
- CMD_CANCEL_REMAIN_ON_CHANNEL = 33,
- CMD_CONFIG_FWLOGGER = 34,
- CMD_START_FWLOGGER = 35,
- CMD_STOP_FWLOGGER = 36,
-
- /* Access point commands */
- CMD_ADD_PEER = 37,
- CMD_REMOVE_PEER = 38,
-
- /* Role API */
- CMD_ROLE_ENABLE = 39,
- CMD_ROLE_DISABLE = 40,
- CMD_ROLE_START = 41,
- CMD_ROLE_STOP = 42,
-
- /* DFS */
- CMD_START_RADAR_DETECTION = 43,
- CMD_STOP_RADAR_DETECTION = 44,
-
- /* WIFI Direct */
- CMD_WFD_START_DISCOVERY = 45,
- CMD_WFD_STOP_DISCOVERY = 46,
- CMD_WFD_ATTRIBUTE_CONFIG = 47,
- CMD_NOP = 48,
- CMD_LAST_COMMAND,
-
- MAX_COMMAND_ID = 0xFFFF,
-};
-
-#define MAX_CMD_PARAMS 572
-
-enum {
- CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
- CMD_TEMPL_KLV_IDX_MAX = 4
-};
-
-enum cmd_templ {
- CMD_TEMPL_NULL_DATA = 0,
- CMD_TEMPL_BEACON,
- CMD_TEMPL_CFG_PROBE_REQ_2_4,
- CMD_TEMPL_CFG_PROBE_REQ_5,
- CMD_TEMPL_PROBE_RESPONSE,
- CMD_TEMPL_QOS_NULL_DATA,
- CMD_TEMPL_PS_POLL,
- CMD_TEMPL_KLV,
- CMD_TEMPL_DISCONNECT,
- CMD_TEMPL_PROBE_REQ_2_4, /* for firmware internal use only */
- CMD_TEMPL_PROBE_REQ_5, /* for firmware internal use only */
- CMD_TEMPL_BAR, /* for firmware internal use only */
- CMD_TEMPL_CTS, /*
- * For CTS-to-self (FastCTS) mechanism
- * for BT/WLAN coexistence (SoftGemini). */
- CMD_TEMPL_AP_BEACON,
- CMD_TEMPL_AP_PROBE_RESPONSE,
- CMD_TEMPL_ARP_RSP,
- CMD_TEMPL_DEAUTH_AP,
- CMD_TEMPL_TEMPORARY,
- CMD_TEMPL_LINK_MEASUREMENT_REPORT,
-
- CMD_TEMPL_MAX = 0xff
-};
-
-/* unit ms */
-#define WL1271_COMMAND_TIMEOUT 2000
-#define WL1271_CMD_TEMPL_DFLT_SIZE 252
-#define WL1271_CMD_TEMPL_MAX_SIZE 512
-#define WL1271_EVENT_TIMEOUT 750
-
-struct wl1271_cmd_header {
- __le16 id;
- __le16 status;
- /* payload */
- u8 data[0];
-} __packed;
-
-#define WL1271_CMD_MAX_PARAMS 572
-
-struct wl1271_command {
- struct wl1271_cmd_header header;
- u8 parameters[WL1271_CMD_MAX_PARAMS];
-} __packed;
-
-enum {
- CMD_MAILBOX_IDLE = 0,
- CMD_STATUS_SUCCESS = 1,
- CMD_STATUS_UNKNOWN_CMD = 2,
- CMD_STATUS_UNKNOWN_IE = 3,
- CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11,
- CMD_STATUS_RX_BUSY = 13,
- CMD_STATUS_INVALID_PARAM = 14,
- CMD_STATUS_TEMPLATE_TOO_LARGE = 15,
- CMD_STATUS_OUT_OF_MEMORY = 16,
- CMD_STATUS_STA_TABLE_FULL = 17,
- CMD_STATUS_RADIO_ERROR = 18,
- CMD_STATUS_WRONG_NESTING = 19,
- CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/
- CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
- CMD_STATUS_TEMPLATE_OOM = 23,
- CMD_STATUS_NO_RX_BA_SESSION = 24,
- MAX_COMMAND_STATUS = 0xff
-};
-
-#define CMDMBOX_HEADER_LEN 4
-#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
-
-enum {
- BSS_TYPE_IBSS = 0,
- BSS_TYPE_STA_BSS = 2,
- BSS_TYPE_AP_BSS = 3,
- MAX_BSS_TYPE = 0xFF
-};
-
-#define WL1271_JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */
-#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1
-#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10
-
-struct wl12xx_cmd_role_enable {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 role_type;
- u8 mac_address[ETH_ALEN];
-} __packed;
-
-struct wl12xx_cmd_role_disable {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 padding[3];
-} __packed;
-
-enum wl12xx_band {
- WL12XX_BAND_2_4GHZ = 0,
- WL12XX_BAND_5GHZ = 1,
- WL12XX_BAND_JAPAN_4_9_GHZ = 2,
- WL12XX_BAND_DEFAULT = WL12XX_BAND_2_4GHZ,
- WL12XX_BAND_INVALID = 0x7E,
- WL12XX_BAND_MAX_RADIO = 0x7F,
-};
-
-struct wl12xx_cmd_role_start {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 band;
- u8 channel;
- u8 padding;
-
- union {
- struct {
- u8 hlid;
- u8 session;
- u8 padding_1[54];
- } __packed device;
- /* sta & p2p_cli use the same struct */
- struct {
- u8 bssid[ETH_ALEN];
- u8 hlid; /* data hlid */
- u8 session;
- __le32 remote_rates; /* remote supported rates */
-
- /*
- * The target uses this field to determine the rate at
- * which to transmit control frame responses (such as
- * ACK or CTS frames).
- */
- __le32 basic_rate_set;
- __le32 local_rates; /* local supported rates */
-
- u8 ssid_type;
- u8 ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
-
- __le16 beacon_interval; /* in TBTTs */
- } __packed sta;
- struct {
- u8 bssid[ETH_ALEN];
- u8 hlid; /* data hlid */
- u8 dtim_interval;
- __le32 remote_rates; /* remote supported rates */
-
- __le32 basic_rate_set;
- __le32 local_rates; /* local supported rates */
-
- u8 ssid_type;
- u8 ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
-
- __le16 beacon_interval; /* in TBTTs */
-
- u8 padding_1[4];
- } __packed ibss;
- /* ap & p2p_go use the same struct */
- struct {
- __le16 aging_period; /* in secs */
- u8 beacon_expiry; /* in ms */
- u8 bss_index;
- /* The host link id for the AP's global queue */
- u8 global_hlid;
- /* The host link id for the AP's broadcast queue */
- u8 broadcast_hlid;
-
- __le16 beacon_interval; /* in TBTTs */
-
- __le32 basic_rate_set;
- __le32 local_rates; /* local supported rates */
-
- u8 dtim_interval;
-
- u8 ssid_type;
- u8 ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
-
- u8 reset_tsf;
-
- u8 padding_1[4];
- } __packed ap;
- };
-} __packed;
-
-struct wl12xx_cmd_role_stop {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 disc_type; /* only STA and P2P_CLI */
- __le16 reason; /* only STA and P2P_CLI */
-} __packed;
-
-struct cmd_enabledisable_path {
- struct wl1271_cmd_header header;
-
- u8 channel;
- u8 padding[3];
-} __packed;
-
-#define WL1271_RATE_AUTOMATIC 0
-
-struct wl1271_cmd_template_set {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 template_type;
- __le16 len;
- u8 index; /* relevant only for KLV_TEMPLATE type */
- u8 padding[3];
-
- __le32 enabled_rates;
- u8 short_retry_limit;
- u8 long_retry_limit;
- u8 aflags;
- u8 reserved;
-
- u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE];
-} __packed;
-
-#define TIM_ELE_ID 5
-#define PARTIAL_VBM_MAX 251
-
-struct wl1271_tim {
- u8 identity;
- u8 length;
- u8 dtim_count;
- u8 dtim_period;
- u8 bitmap_ctrl;
- u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
-} __packed;
-
-enum wl1271_cmd_ps_mode {
- STATION_AUTO_PS_MODE, /* Dynamic Power Save */
- STATION_ACTIVE_MODE,
- STATION_POWER_SAVE_MODE
-};
-
-struct wl1271_cmd_ps_params {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 ps_mode; /* STATION_* */
- u16 auto_ps_timeout;
-} __packed;
-
-/* HW encryption keys */
-#define NUM_ACCESS_CATEGORIES_COPY 4
-
-enum wl1271_cmd_key_action {
- KEY_ADD_OR_REPLACE = 1,
- KEY_REMOVE = 2,
- KEY_SET_ID = 3,
- MAX_KEY_ACTION = 0xffff,
-};
-
-enum wl1271_cmd_lid_key_type {
- UNICAST_LID_TYPE = 0,
- BROADCAST_LID_TYPE = 1,
- WEP_DEFAULT_LID_TYPE = 2
-};
-
-enum wl1271_cmd_key_type {
- KEY_NONE = 0,
- KEY_WEP = 1,
- KEY_TKIP = 2,
- KEY_AES = 3,
- KEY_GEM = 4,
-};
-
-struct wl1271_cmd_set_keys {
- struct wl1271_cmd_header header;
-
- /*
- * Indicates whether the HLID is a unicast key set
- * or broadcast key set. A special value 0xFF is
- * used to indicate that the HLID is on WEP-default
- * (multi-hlids). of type wl1271_cmd_lid_key_type.
- */
- u8 hlid;
-
- /*
- * In WEP-default network (hlid == 0xFF) used to
- * indicate which network STA/IBSS/AP role should be
- * changed
- */
- u8 lid_key_type;
-
- /*
- * Key ID - For TKIP and AES key types, this field
- * indicates the value that should be inserted into
- * the KeyID field of frames transmitted using this
- * key entry. For broadcast keys the index use as a
- * marker for TX/RX key.
- * For WEP default network (HLID=0xFF), this field
- * indicates the ID of the key to add or remove.
- */
- u8 key_id;
- u8 reserved_1;
-
- /* key_action_e */
- __le16 key_action;
-
- /* key size in bytes */
- u8 key_size;
-
- /* key_type_e */
- u8 key_type;
-
- /* This field holds the security key data to add to the STA table */
- u8 key[MAX_KEY_SIZE];
- __le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
- __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
-} __packed;
-
-struct wl1271_cmd_test_header {
- u8 id;
- u8 padding[3];
-} __packed;
-
-enum wl1271_channel_tune_bands {
- WL1271_CHANNEL_TUNE_BAND_2_4,
- WL1271_CHANNEL_TUNE_BAND_5,
- WL1271_CHANNEL_TUNE_BAND_4_9
-};
-
-#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
-
-#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
-#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
-#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
-
-struct wl1271_general_parms_cmd {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- struct wl1271_ini_general_params general_params;
-
- u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
- u8 sr_sen_n_p;
- u8 sr_sen_n_p_gain;
- u8 sr_sen_nrn;
- u8 sr_sen_prn;
- u8 padding[3];
-} __packed;
-
-struct wl128x_general_parms_cmd {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- struct wl128x_ini_general_params general_params;
-
- u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
- u8 sr_sen_n_p;
- u8 sr_sen_n_p_gain;
- u8 sr_sen_nrn;
- u8 sr_sen_prn;
- u8 padding[3];
-} __packed;
-
-struct wl1271_radio_parms_cmd {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- /* Static radio parameters */
- struct wl1271_ini_band_params_2 static_params_2;
- struct wl1271_ini_band_params_5 static_params_5;
-
- /* Dynamic radio parameters */
- struct wl1271_ini_fem_params_2 dyn_params_2;
- u8 padding2;
- struct wl1271_ini_fem_params_5 dyn_params_5;
- u8 padding3[2];
-} __packed;
-
-struct wl128x_radio_parms_cmd {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- /* Static radio parameters */
- struct wl128x_ini_band_params_2 static_params_2;
- struct wl128x_ini_band_params_5 static_params_5;
-
- u8 fem_vendor_and_options;
-
- /* Dynamic radio parameters */
- struct wl128x_ini_fem_params_2 dyn_params_2;
- u8 padding2;
- struct wl128x_ini_fem_params_5 dyn_params_5;
-} __packed;
-
-struct wl1271_ext_radio_parms_cmd {
- struct wl1271_cmd_header header;
-
- struct wl1271_cmd_test_header test;
-
- u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
- u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
- u8 padding[3];
-} __packed;
-
-/*
- * There are three types of disconnections:
- *
- * DISCONNECT_IMMEDIATE: the fw doesn't send any frames
- * DISCONNECT_DEAUTH: the fw generates a DEAUTH request with the reason
- * we have passed
- * DISCONNECT_DISASSOC: the fw generates a DESASSOC request with the reason
- * we have passed
- */
-enum wl1271_disconnect_type {
- DISCONNECT_IMMEDIATE,
- DISCONNECT_DEAUTH,
- DISCONNECT_DISASSOC
-};
-
-#define WL1271_CMD_STA_STATE_CONNECTED 1
-
-struct wl12xx_cmd_set_peer_state {
- struct wl1271_cmd_header header;
-
- u8 hlid;
- u8 state;
- u8 padding[2];
-} __packed;
-
-struct wl12xx_cmd_roc {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 channel;
- u8 band;
- u8 padding;
-};
-
-struct wl12xx_cmd_croc {
- struct wl1271_cmd_header header;
-
- u8 role_id;
- u8 padding[3];
-};
-
-enum wl12xx_ssid_type {
- WL12XX_SSID_TYPE_PUBLIC = 0,
- WL12XX_SSID_TYPE_HIDDEN = 1,
- WL12XX_SSID_TYPE_ANY = 2,
-};
-
-enum wl1271_psd_type {
- WL1271_PSD_LEGACY = 0,
- WL1271_PSD_UPSD_TRIGGER = 1,
- WL1271_PSD_LEGACY_PSPOLL = 2,
- WL1271_PSD_SAPSD = 3
-};
-
-struct wl12xx_cmd_add_peer {
- struct wl1271_cmd_header header;
-
- u8 addr[ETH_ALEN];
- u8 hlid;
- u8 aid;
- u8 psd_type[NUM_ACCESS_CATEGORIES_COPY];
- __le32 supported_rates;
- u8 bss_index;
- u8 sp_len;
- u8 wmm;
- u8 padding1;
-} __packed;
-
-struct wl12xx_cmd_remove_peer {
- struct wl1271_cmd_header header;
-
- u8 hlid;
- u8 reason_opcode;
- u8 send_deauth_flag;
- u8 padding1;
-} __packed;
-
-/*
- * Continuous mode - packets are transferred to the host periodically
- * via the data path.
- * On demand - Log messages are stored in a cyclic buffer in the
- * firmware, and only transferred to the host when explicitly requested
- */
-enum wl12xx_fwlogger_log_mode {
- WL12XX_FWLOG_CONTINUOUS,
- WL12XX_FWLOG_ON_DEMAND
-};
-
-/* Include/exclude timestamps from the log messages */
-enum wl12xx_fwlogger_timestamp {
- WL12XX_FWLOG_TIMESTAMP_DISABLED,
- WL12XX_FWLOG_TIMESTAMP_ENABLED
-};
-
-/*
- * Logs can be routed to the debug pinouts (where available), to the host bus
- * (SDIO/SPI), or dropped
- */
-enum wl12xx_fwlogger_output {
- WL12XX_FWLOG_OUTPUT_NONE,
- WL12XX_FWLOG_OUTPUT_DBG_PINS,
- WL12XX_FWLOG_OUTPUT_HOST,
-};
-
-struct wl12xx_cmd_config_fwlog {
- struct wl1271_cmd_header header;
-
- /* See enum wl12xx_fwlogger_log_mode */
- u8 logger_mode;
-
- /* Minimum log level threshold */
- u8 log_severity;
-
- /* Include/exclude timestamps from the log messages */
- u8 timestamp;
-
- /* See enum wl1271_fwlogger_output */
- u8 output;
-
- /* Regulates the frequency of log messages */
- u8 threshold;
-
- u8 padding[3];
-} __packed;
-
-struct wl12xx_cmd_start_fwlog {
- struct wl1271_cmd_header header;
-} __packed;
-
-struct wl12xx_cmd_stop_fwlog {
- struct wl1271_cmd_header header;
-} __packed;
-
-struct wl12xx_cmd_channel_switch {
- struct wl1271_cmd_header header;
-
- u8 role_id;
-
- /* The new serving channel */
- u8 channel;
- /* Relative time of the serving channel switch in TBTT units */
- u8 switch_time;
- /* Stop the role TX, should expect it after radar detection */
- u8 stop_tx;
- /* The target channel tx status 1-stopped 0-open*/
- u8 post_switch_tx_disable;
-
- u8 padding[3];
-} __packed;
-
-struct wl12xx_cmd_stop_channel_switch {
- struct wl1271_cmd_header header;
-} __packed;
-
-#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
deleted file mode 100644
index 5d2a9e004c72..000000000000
--- a/drivers/net/wireless/wl12xx/conf.h
+++ /dev/null
@@ -1,1326 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __CONF_H__
-#define __CONF_H__
-
-enum {
- CONF_HW_BIT_RATE_1MBPS = BIT(0),
- CONF_HW_BIT_RATE_2MBPS = BIT(1),
- CONF_HW_BIT_RATE_5_5MBPS = BIT(2),
- CONF_HW_BIT_RATE_6MBPS = BIT(3),
- CONF_HW_BIT_RATE_9MBPS = BIT(4),
- CONF_HW_BIT_RATE_11MBPS = BIT(5),
- CONF_HW_BIT_RATE_12MBPS = BIT(6),
- CONF_HW_BIT_RATE_18MBPS = BIT(7),
- CONF_HW_BIT_RATE_22MBPS = BIT(8),
- CONF_HW_BIT_RATE_24MBPS = BIT(9),
- CONF_HW_BIT_RATE_36MBPS = BIT(10),
- CONF_HW_BIT_RATE_48MBPS = BIT(11),
- CONF_HW_BIT_RATE_54MBPS = BIT(12),
- CONF_HW_BIT_RATE_MCS_0 = BIT(13),
- CONF_HW_BIT_RATE_MCS_1 = BIT(14),
- CONF_HW_BIT_RATE_MCS_2 = BIT(15),
- CONF_HW_BIT_RATE_MCS_3 = BIT(16),
- CONF_HW_BIT_RATE_MCS_4 = BIT(17),
- CONF_HW_BIT_RATE_MCS_5 = BIT(18),
- CONF_HW_BIT_RATE_MCS_6 = BIT(19),
- CONF_HW_BIT_RATE_MCS_7 = BIT(20)
-};
-
-enum {
- CONF_HW_RATE_INDEX_1MBPS = 0,
- CONF_HW_RATE_INDEX_2MBPS = 1,
- CONF_HW_RATE_INDEX_5_5MBPS = 2,
- CONF_HW_RATE_INDEX_6MBPS = 3,
- CONF_HW_RATE_INDEX_9MBPS = 4,
- CONF_HW_RATE_INDEX_11MBPS = 5,
- CONF_HW_RATE_INDEX_12MBPS = 6,
- CONF_HW_RATE_INDEX_18MBPS = 7,
- CONF_HW_RATE_INDEX_22MBPS = 8,
- CONF_HW_RATE_INDEX_24MBPS = 9,
- CONF_HW_RATE_INDEX_36MBPS = 10,
- CONF_HW_RATE_INDEX_48MBPS = 11,
- CONF_HW_RATE_INDEX_54MBPS = 12,
- CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
-};
-
-enum {
- CONF_HW_RXTX_RATE_MCS7_SGI = 0,
- CONF_HW_RXTX_RATE_MCS7,
- CONF_HW_RXTX_RATE_MCS6,
- CONF_HW_RXTX_RATE_MCS5,
- CONF_HW_RXTX_RATE_MCS4,
- CONF_HW_RXTX_RATE_MCS3,
- CONF_HW_RXTX_RATE_MCS2,
- CONF_HW_RXTX_RATE_MCS1,
- CONF_HW_RXTX_RATE_MCS0,
- CONF_HW_RXTX_RATE_54,
- CONF_HW_RXTX_RATE_48,
- CONF_HW_RXTX_RATE_36,
- CONF_HW_RXTX_RATE_24,
- CONF_HW_RXTX_RATE_22,
- CONF_HW_RXTX_RATE_18,
- CONF_HW_RXTX_RATE_12,
- CONF_HW_RXTX_RATE_11,
- CONF_HW_RXTX_RATE_9,
- CONF_HW_RXTX_RATE_6,
- CONF_HW_RXTX_RATE_5_5,
- CONF_HW_RXTX_RATE_2,
- CONF_HW_RXTX_RATE_1,
- CONF_HW_RXTX_RATE_MAX,
- CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
-};
-
-/* Rates between and including these are MCS rates */
-#define CONF_HW_RXTX_RATE_MCS_MIN CONF_HW_RXTX_RATE_MCS7_SGI
-#define CONF_HW_RXTX_RATE_MCS_MAX CONF_HW_RXTX_RATE_MCS0
-
-enum {
- CONF_SG_DISABLE = 0,
- CONF_SG_PROTECTIVE,
- CONF_SG_OPPORTUNISTIC
-};
-
-enum {
- /*
- * Configure the min and max time BT gains the antenna
- * in WLAN / BT master basic rate
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_ACL_BT_MASTER_MIN_BR = 0,
- CONF_SG_ACL_BT_MASTER_MAX_BR,
-
- /*
- * Configure the min and max time BT gains the antenna
- * in WLAN / BT slave basic rate
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_ACL_BT_SLAVE_MIN_BR,
- CONF_SG_ACL_BT_SLAVE_MAX_BR,
-
- /*
- * Configure the min and max time BT gains the antenna
- * in WLAN / BT master EDR
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_ACL_BT_MASTER_MIN_EDR,
- CONF_SG_ACL_BT_MASTER_MAX_EDR,
-
- /*
- * Configure the min and max time BT gains the antenna
- * in WLAN / BT slave EDR
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_ACL_BT_SLAVE_MIN_EDR,
- CONF_SG_ACL_BT_SLAVE_MAX_EDR,
-
- /*
- * The maximum time WLAN can gain the antenna
- * in WLAN PSM / BT master/slave BR
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_ACL_WLAN_PS_MASTER_BR,
- CONF_SG_ACL_WLAN_PS_SLAVE_BR,
-
- /*
- * The maximum time WLAN can gain the antenna
- * in WLAN PSM / BT master/slave EDR
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_ACL_WLAN_PS_MASTER_EDR,
- CONF_SG_ACL_WLAN_PS_SLAVE_EDR,
-
- /* TODO: explain these values */
- CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR,
- CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR,
- CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR,
- CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR,
- CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR,
- CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR,
- CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR,
- CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR,
-
- CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR,
- CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR,
- CONF_SG_ACL_PASSIVE_SCAN_BT_BR,
- CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR,
- CONF_SG_ACL_PASSIVE_SCAN_BT_EDR,
- CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR,
-
- /*
- * Compensation percentage of probe requests when scan initiated
- * during BT voice/ACL link.
- *
- * Range: 0 - 255 (%)
- */
- CONF_SG_AUTO_SCAN_PROBE_REQ,
-
- /*
- * Compensation percentage of probe requests when active scan initiated
- * during BT voice
- *
- * Range: 0 - 255 (%)
- */
- CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3,
-
- /*
- * Compensation percentage of WLAN active scan window if initiated
- * during BT A2DP
- *
- * Range: 0 - 1000 (%)
- */
- CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP,
-
- /*
- * Compensation percentage of WLAN passive scan window if initiated
- * during BT A2DP BR
- *
- * Range: 0 - 1000 (%)
- */
- CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR,
-
- /*
- * Compensation percentage of WLAN passive scan window if initiated
- * during BT A2DP EDR
- *
- * Range: 0 - 1000 (%)
- */
- CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR,
-
- /*
- * Compensation percentage of WLAN passive scan window if initiated
- * during BT voice
- *
- * Range: 0 - 1000 (%)
- */
- CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3,
-
- /* TODO: explain these values */
- CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN,
- CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN,
- CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN,
-
- /*
- * Defines whether the SG will force WLAN host to enter/exit PSM
- *
- * Range: 1 - SG can force, 0 - host handles PSM
- */
- CONF_SG_STA_FORCE_PS_IN_BT_SCO,
-
- /*
- * Defines antenna configuration (single/dual antenna)
- *
- * Range: 0 - single antenna, 1 - dual antenna
- */
- CONF_SG_ANTENNA_CONFIGURATION,
-
- /*
- * The threshold (percent) of max consecutive beacon misses before
- * increasing priority of beacon reception.
- *
- * Range: 0 - 100 (%)
- */
- CONF_SG_BEACON_MISS_PERCENT,
-
- /*
- * Protection time of the DHCP procedure.
- *
- * Range: 0 - 100000 (ms)
- */
- CONF_SG_DHCP_TIME,
-
- /*
- * RX guard time before the beginning of a new BT voice frame during
- * which no new WLAN trigger frame is transmitted.
- *
- * Range: 0 - 100000 (us)
- */
- CONF_SG_RXT,
-
- /*
- * TX guard time before the beginning of a new BT voice frame during
- * which no new WLAN frame is transmitted.
- *
- * Range: 0 - 100000 (us)
- */
-
- CONF_SG_TXT,
-
- /*
- * Enable adaptive RXT/TXT algorithm. If disabled, the host values
- * will be utilized.
- *
- * Range: 0 - disable, 1 - enable
- */
- CONF_SG_ADAPTIVE_RXT_TXT,
-
- /* TODO: explain this value */
- CONF_SG_GENERAL_USAGE_BIT_MAP,
-
- /*
- * Number of consecutive BT voice frames not interrupted by WLAN
- *
- * Range: 0 - 100
- */
- CONF_SG_HV3_MAX_SERVED,
-
- /*
- * The used WLAN legacy service period during active BT ACL link
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_PS_POLL_TIMEOUT,
-
- /*
- * The used WLAN UPSD service period during active BT ACL link
- *
- * Range: 0 - 255 (ms)
- */
- CONF_SG_UPSD_TIMEOUT,
-
- CONF_SG_CONSECUTIVE_CTS_THRESHOLD,
- CONF_SG_STA_RX_WINDOW_AFTER_DTIM,
- CONF_SG_STA_CONNECTION_PROTECTION_TIME,
-
- /* AP params */
- CONF_AP_BEACON_MISS_TX,
- CONF_AP_RX_WINDOW_AFTER_BEACON,
- CONF_AP_BEACON_WINDOW_INTERVAL,
- CONF_AP_CONNECTION_PROTECTION_TIME,
- CONF_AP_BT_ACL_VAL_BT_SERVE_TIME,
- CONF_AP_BT_ACL_VAL_WL_SERVE_TIME,
-
- /* CTS Diluting params */
- CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH,
- CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER,
-
- CONF_SG_TEMP_PARAM_1,
- CONF_SG_TEMP_PARAM_2,
- CONF_SG_TEMP_PARAM_3,
- CONF_SG_TEMP_PARAM_4,
- CONF_SG_TEMP_PARAM_5,
- CONF_SG_TEMP_PARAM_6,
- CONF_SG_TEMP_PARAM_7,
- CONF_SG_TEMP_PARAM_8,
- CONF_SG_TEMP_PARAM_9,
- CONF_SG_TEMP_PARAM_10,
-
- CONF_SG_PARAMS_MAX,
- CONF_SG_PARAMS_ALL = 0xff
-};
-
-struct conf_sg_settings {
- u32 params[CONF_SG_PARAMS_MAX];
- u8 state;
-};
-
-enum conf_rx_queue_type {
- CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */
- CONF_RX_QUEUE_TYPE_HIGH_PRIORITY, /* Management and voice packets */
-};
-
-struct conf_rx_settings {
- /*
- * The maximum amount of time, in TU, before the
- * firmware discards the MSDU.
- *
- * Range: 0 - 0xFFFFFFFF
- */
- u32 rx_msdu_life_time;
-
- /*
- * Packet detection threshold in the PHY.
- *
- * FIXME: details unknown.
- */
- u32 packet_detection_threshold;
-
- /*
- * The longest time the STA will wait to receive traffic from the AP
- * after a PS-poll has been transmitted.
- *
- * Range: 0 - 200000
- */
- u16 ps_poll_timeout;
- /*
- * The longest time the STA will wait to receive traffic from the AP
- * after a frame has been sent from an UPSD enabled queue.
- *
- * Range: 0 - 200000
- */
- u16 upsd_timeout;
-
- /*
- * The number of octets in an MPDU, below which an RTS/CTS
- * handshake is not performed.
- *
- * Range: 0 - 4096
- */
- u16 rts_threshold;
-
- /*
- * The RX Clear Channel Assessment threshold in the PHY
- * (the energy threshold).
- *
- * Range: ENABLE_ENERGY_D == 0x140A
- * DISABLE_ENERGY_D == 0xFFEF
- */
- u16 rx_cca_threshold;
-
- /*
- * Occupied Rx mem-blocks number which requires interrupting the host
- * (0 = no buffering, 0xffff = disabled).
- *
- * Range: u16
- */
- u16 irq_blk_threshold;
-
- /*
- * Rx packets number which requires interrupting the host
- * (0 = no buffering).
- *
- * Range: u16
- */
- u16 irq_pkt_threshold;
-
- /*
- * Max time in msec the FW may delay RX-Complete interrupt.
- *
- * Range: 1 - 100
- */
- u16 irq_timeout;
-
- /*
- * The RX queue type.
- *
- * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY,
- */
- u8 queue_type;
-};
-
-#define CONF_TX_MAX_RATE_CLASSES 10
-
-#define CONF_TX_RATE_MASK_UNSPECIFIED 0
-#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \
- CONF_HW_BIT_RATE_2MBPS)
-#define CONF_TX_RATE_RETRY_LIMIT 10
-
-/* basic rates for p2p operations (probe req/resp, etc.) */
-#define CONF_TX_RATE_MASK_BASIC_P2P (CONF_HW_BIT_RATE_6MBPS | \
- CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS)
-
-/*
- * Rates supported for data packets when operating as AP. Note the absence
- * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop
- * one. The rate dropped is not mandatory under any operating mode.
- */
-#define CONF_TX_AP_ENABLED_RATES (CONF_HW_BIT_RATE_1MBPS | \
- CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
- CONF_HW_BIT_RATE_6MBPS | CONF_HW_BIT_RATE_9MBPS | \
- CONF_HW_BIT_RATE_11MBPS | CONF_HW_BIT_RATE_12MBPS | \
- CONF_HW_BIT_RATE_18MBPS | CONF_HW_BIT_RATE_24MBPS | \
- CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
- CONF_HW_BIT_RATE_54MBPS)
-
-#define CONF_TX_CCK_RATES (CONF_HW_BIT_RATE_1MBPS | \
- CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
- CONF_HW_BIT_RATE_11MBPS)
-
-#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS | \
- CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS | \
- CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
- CONF_HW_BIT_RATE_54MBPS)
-
-#define CONF_TX_MCS_RATES (CONF_HW_BIT_RATE_MCS_0 | \
- CONF_HW_BIT_RATE_MCS_1 | CONF_HW_BIT_RATE_MCS_2 | \
- CONF_HW_BIT_RATE_MCS_3 | CONF_HW_BIT_RATE_MCS_4 | \
- CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 | \
- CONF_HW_BIT_RATE_MCS_7)
-
-/*
- * Default rates for management traffic when operating in AP mode. This
- * should be configured according to the basic rate set of the AP
- */
-#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
- CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
-
-/* default rates for working as IBSS (11b and OFDM) */
-#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
- CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
- CONF_HW_BIT_RATE_11MBPS | CONF_TX_OFDM_RATES);
-
-struct conf_tx_rate_class {
-
- /*
- * The rates enabled for this rate class.
- *
- * Range: CONF_HW_BIT_RATE_* bit mask
- */
- u32 enabled_rates;
-
- /*
- * The dot11 short retry limit used for TX retries.
- *
- * Range: u8
- */
- u8 short_retry_limit;
-
- /*
- * The dot11 long retry limit used for TX retries.
- *
- * Range: u8
- */
- u8 long_retry_limit;
-
- /*
- * Flags controlling the attributes of TX transmission.
- *
- * Range: bit 0: Truncate - when set, FW attempts to send a frame stop
- * when the total valid per-rate attempts have
- * been exhausted; otherwise transmissions
- * will continue at the lowest available rate
- * until the appropriate one of the
- * short_retry_limit, long_retry_limit,
- * dot11_max_transmit_msdu_life_time, or
- * max_tx_life_time, is exhausted.
- * 1: Preamble Override - indicates if the preamble type
- * should be used in TX.
- * 2: Preamble Type - the type of the preamble to be used by
- * the policy (0 - long preamble, 1 - short preamble.
- */
- u8 aflags;
-};
-
-#define CONF_TX_MAX_AC_COUNT 4
-
-/* Slot number setting to start transmission at PIFS interval */
-#define CONF_TX_AIFS_PIFS 1
-/* Slot number setting to start transmission at DIFS interval normal
- * DCF access */
-#define CONF_TX_AIFS_DIFS 2
-
-
-enum conf_tx_ac {
- CONF_TX_AC_BE = 0, /* best effort / legacy */
- CONF_TX_AC_BK = 1, /* background */
- CONF_TX_AC_VI = 2, /* video */
- CONF_TX_AC_VO = 3, /* voice */
- CONF_TX_AC_CTS2SELF = 4, /* fictitious AC, follows AC_VO */
- CONF_TX_AC_ANY_TID = 0x1f
-};
-
-struct conf_tx_ac_category {
- /*
- * The AC class identifier.
- *
- * Range: enum conf_tx_ac
- */
- u8 ac;
-
- /*
- * The contention window minimum size (in slots) for the access
- * class.
- *
- * Range: u8
- */
- u8 cw_min;
-
- /*
- * The contention window maximum size (in slots) for the access
- * class.
- *
- * Range: u8
- */
- u16 cw_max;
-
- /*
- * The AIF value (in slots) for the access class.
- *
- * Range: u8
- */
- u8 aifsn;
-
- /*
- * The TX Op Limit (in microseconds) for the access class.
- *
- * Range: u16
- */
- u16 tx_op_limit;
-};
-
-#define CONF_TX_MAX_TID_COUNT 8
-
-/* Allow TX BA on all TIDs but 6,7. These are currently reserved in the FW */
-#define CONF_TX_BA_ENABLED_TID_BITMAP 0x3F
-
-enum {
- CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/
- CONF_CHANNEL_TYPE_EDCF = 1, /* EDCA*/
- CONF_CHANNEL_TYPE_HCCA = 2, /* HCCA*/
-};
-
-enum {
- CONF_PS_SCHEME_LEGACY = 0,
- CONF_PS_SCHEME_UPSD_TRIGGER = 1,
- CONF_PS_SCHEME_LEGACY_PSPOLL = 2,
- CONF_PS_SCHEME_SAPSD = 3,
-};
-
-enum {
- CONF_ACK_POLICY_LEGACY = 0,
- CONF_ACK_POLICY_NO_ACK = 1,
- CONF_ACK_POLICY_BLOCK = 2,
-};
-
-
-struct conf_tx_tid {
- u8 queue_id;
- u8 channel_type;
- u8 tsid;
- u8 ps_scheme;
- u8 ack_policy;
- u32 apsd_conf[2];
-};
-
-struct conf_tx_settings {
- /*
- * The TX ED value for TELEC Enable/Disable.
- *
- * Range: 0, 1
- */
- u8 tx_energy_detection;
-
- /*
- * Configuration for rate classes for TX (currently only one
- * rate class supported). Used in non-AP mode.
- */
- struct conf_tx_rate_class sta_rc_conf;
-
- /*
- * Configuration for access categories for TX rate control.
- */
- u8 ac_conf_count;
- struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT];
-
- /*
- * AP-mode - allow this number of TX retries to a station before an
- * event is triggered from FW.
- * In AP-mode the hlids of unreachable stations are given in the
- * "sta_tx_retry_exceeded" member in the event mailbox.
- */
- u8 max_tx_retries;
-
- /*
- * AP-mode - after this number of seconds a connected station is
- * considered inactive.
- */
- u16 ap_aging_period;
-
- /*
- * Configuration for TID parameters.
- */
- u8 tid_conf_count;
- struct conf_tx_tid tid_conf[CONF_TX_MAX_TID_COUNT];
-
- /*
- * The TX fragmentation threshold.
- *
- * Range: u16
- */
- u16 frag_threshold;
-
- /*
- * Max time in msec the FW may delay frame TX-Complete interrupt.
- *
- * Range: u16
- */
- u16 tx_compl_timeout;
-
- /*
- * Completed TX packet count which requires to issue the TX-Complete
- * interrupt.
- *
- * Range: u16
- */
- u16 tx_compl_threshold;
-
- /*
- * The rate used for control messages and scanning on the 2.4GHz band
- *
- * Range: CONF_HW_BIT_RATE_* bit mask
- */
- u32 basic_rate;
-
- /*
- * The rate used for control messages and scanning on the 5GHz band
- *
- * Range: CONF_HW_BIT_RATE_* bit mask
- */
- u32 basic_rate_5;
-
- /*
- * TX retry limits for templates
- */
- u8 tmpl_short_retry_limit;
- u8 tmpl_long_retry_limit;
-
- /* Time in ms for Tx watchdog timer to expire */
- u32 tx_watchdog_timeout;
-};
-
-enum {
- CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/
- CONF_WAKE_UP_EVENT_DTIM = 0x02, /* Wake on every DTIM*/
- CONF_WAKE_UP_EVENT_N_DTIM = 0x04, /* Wake every Nth DTIM */
- CONF_WAKE_UP_EVENT_N_BEACONS = 0x08, /* Wake every Nth beacon */
- CONF_WAKE_UP_EVENT_BITS_MASK = 0x0F
-};
-
-#define CONF_MAX_BCN_FILT_IE_COUNT 32
-
-#define CONF_BCN_RULE_PASS_ON_CHANGE BIT(0)
-#define CONF_BCN_RULE_PASS_ON_APPEARANCE BIT(1)
-
-#define CONF_BCN_IE_OUI_LEN 3
-#define CONF_BCN_IE_VER_LEN 2
-
-struct conf_bcn_filt_rule {
- /*
- * IE number to which to associate a rule.
- *
- * Range: u8
- */
- u8 ie;
-
- /*
- * Rule to associate with the specific ie.
- *
- * Range: CONF_BCN_RULE_PASS_ON_*
- */
- u8 rule;
-
- /*
- * OUI for the vendor specifie IE (221)
- */
- u8 oui[CONF_BCN_IE_OUI_LEN];
-
- /*
- * Type for the vendor specifie IE (221)
- */
- u8 type;
-
- /*
- * Version for the vendor specifie IE (221)
- */
- u8 version[CONF_BCN_IE_VER_LEN];
-};
-
-#define CONF_MAX_RSSI_SNR_TRIGGERS 8
-
-enum {
- CONF_TRIG_METRIC_RSSI_BEACON = 0,
- CONF_TRIG_METRIC_RSSI_DATA,
- CONF_TRIG_METRIC_SNR_BEACON,
- CONF_TRIG_METRIC_SNR_DATA
-};
-
-enum {
- CONF_TRIG_EVENT_TYPE_LEVEL = 0,
- CONF_TRIG_EVENT_TYPE_EDGE
-};
-
-enum {
- CONF_TRIG_EVENT_DIR_LOW = 0,
- CONF_TRIG_EVENT_DIR_HIGH,
- CONF_TRIG_EVENT_DIR_BIDIR
-};
-
-struct conf_sig_weights {
-
- /*
- * RSSI from beacons average weight.
- *
- * Range: u8
- */
- u8 rssi_bcn_avg_weight;
-
- /*
- * RSSI from data average weight.
- *
- * Range: u8
- */
- u8 rssi_pkt_avg_weight;
-
- /*
- * SNR from beacons average weight.
- *
- * Range: u8
- */
- u8 snr_bcn_avg_weight;
-
- /*
- * SNR from data average weight.
- *
- * Range: u8
- */
- u8 snr_pkt_avg_weight;
-};
-
-enum conf_bcn_filt_mode {
- CONF_BCN_FILT_MODE_DISABLED = 0,
- CONF_BCN_FILT_MODE_ENABLED = 1
-};
-
-enum conf_bet_mode {
- CONF_BET_MODE_DISABLE = 0,
- CONF_BET_MODE_ENABLE = 1,
-};
-
-struct conf_conn_settings {
- /*
- * Firmware wakeup conditions configuration. The host may set only
- * one bit.
- *
- * Range: CONF_WAKE_UP_EVENT_*
- */
- u8 wake_up_event;
-
- /*
- * Listen interval for beacons or Dtims.
- *
- * Range: 0 for beacon and Dtim wakeup
- * 1-10 for x Dtims
- * 1-255 for x beacons
- */
- u8 listen_interval;
-
- /*
- * Firmware wakeup conditions during suspend
- * Range: CONF_WAKE_UP_EVENT_*
- */
- u8 suspend_wake_up_event;
-
- /*
- * Listen interval during suspend.
- * Currently will be in DTIMs (1-10)
- *
- */
- u8 suspend_listen_interval;
-
- /*
- * Enable or disable the beacon filtering.
- *
- * Range: CONF_BCN_FILT_MODE_*
- */
- enum conf_bcn_filt_mode bcn_filt_mode;
-
- /*
- * Configure Beacon filter pass-thru rules.
- */
- u8 bcn_filt_ie_count;
- struct conf_bcn_filt_rule bcn_filt_ie[CONF_MAX_BCN_FILT_IE_COUNT];
-
- /*
- * The number of consecutive beacons to lose, before the firmware
- * becomes out of synch.
- *
- * Range: u32
- */
- u32 synch_fail_thold;
-
- /*
- * After out-of-synch, the number of TU's to wait without a further
- * received beacon (or probe response) before issuing the BSS_EVENT_LOSE
- * event.
- *
- * Range: u32
- */
- u32 bss_lose_timeout;
-
- /*
- * Beacon receive timeout.
- *
- * Range: u32
- */
- u32 beacon_rx_timeout;
-
- /*
- * Broadcast receive timeout.
- *
- * Range: u32
- */
- u32 broadcast_timeout;
-
- /*
- * Enable/disable reception of broadcast packets in power save mode
- *
- * Range: 1 - enable, 0 - disable
- */
- u8 rx_broadcast_in_ps;
-
- /*
- * Consecutive PS Poll failures before sending event to driver
- *
- * Range: u8
- */
- u8 ps_poll_threshold;
-
- /*
- * Configuration of signal average weights.
- */
- struct conf_sig_weights sig_weights;
-
- /*
- * Specifies if beacon early termination procedure is enabled or
- * disabled.
- *
- * Range: CONF_BET_MODE_*
- */
- u8 bet_enable;
-
- /*
- * Specifies the maximum number of consecutive beacons that may be
- * early terminated. After this number is reached at least one full
- * beacon must be correctly received in FW before beacon ET
- * resumes.
- *
- * Range 0 - 255
- */
- u8 bet_max_consecutive;
-
- /*
- * Specifies the maximum number of times to try PSM entry if it fails
- * (if sending the appropriate null-func message fails.)
- *
- * Range 0 - 255
- */
- u8 psm_entry_retries;
-
- /*
- * Specifies the maximum number of times to try PSM exit if it fails
- * (if sending the appropriate null-func message fails.)
- *
- * Range 0 - 255
- */
- u8 psm_exit_retries;
-
- /*
- * Specifies the maximum number of times to try transmit the PSM entry
- * null-func frame for each PSM entry attempt
- *
- * Range 0 - 255
- */
- u8 psm_entry_nullfunc_retries;
-
- /*
- * Specifies the dynamic PS timeout in ms that will be used
- * by the FW when in AUTO_PS mode
- */
- u16 dynamic_ps_timeout;
-
- /*
- * Specifies whether dynamic PS should be disabled and PSM forced.
- * This is required for certain WiFi certification tests.
- */
- u8 forced_ps;
-
- /*
- *
- * Specifies the interval of the connection keep-alive null-func
- * frame in ms.
- *
- * Range: 1000 - 3600000
- */
- u32 keep_alive_interval;
-
- /*
- * Maximum listen interval supported by the driver in units of beacons.
- *
- * Range: u16
- */
- u8 max_listen_interval;
-};
-
-enum {
- CONF_REF_CLK_19_2_E,
- CONF_REF_CLK_26_E,
- CONF_REF_CLK_38_4_E,
- CONF_REF_CLK_52_E,
- CONF_REF_CLK_38_4_M_XTAL,
- CONF_REF_CLK_26_M_XTAL,
-};
-
-enum single_dual_band_enum {
- CONF_SINGLE_BAND,
- CONF_DUAL_BAND
-};
-
-#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15
-#define CONF_NUMBER_OF_SUB_BANDS_5 7
-#define CONF_NUMBER_OF_RATE_GROUPS 6
-#define CONF_NUMBER_OF_CHANNELS_2_4 14
-#define CONF_NUMBER_OF_CHANNELS_5 35
-
-struct conf_itrim_settings {
- /* enable dco itrim */
- u8 enable;
-
- /* moderation timeout in microsecs from the last TX */
- u32 timeout;
-};
-
-struct conf_pm_config_settings {
- /*
- * Host clock settling time
- *
- * Range: 0 - 30000 us
- */
- u32 host_clk_settling_time;
-
- /*
- * Host fast wakeup support
- *
- * Range: true, false
- */
- bool host_fast_wakeup_support;
-};
-
-struct conf_roam_trigger_settings {
- /*
- * The minimum interval between two trigger events.
- *
- * Range: 0 - 60000 ms
- */
- u16 trigger_pacing;
-
- /*
- * The weight for rssi/beacon average calculation
- *
- * Range: 0 - 255
- */
- u8 avg_weight_rssi_beacon;
-
- /*
- * The weight for rssi/data frame average calculation
- *
- * Range: 0 - 255
- */
- u8 avg_weight_rssi_data;
-
- /*
- * The weight for snr/beacon average calculation
- *
- * Range: 0 - 255
- */
- u8 avg_weight_snr_beacon;
-
- /*
- * The weight for snr/data frame average calculation
- *
- * Range: 0 - 255
- */
- u8 avg_weight_snr_data;
-};
-
-struct conf_scan_settings {
- /*
- * The minimum time to wait on each channel for active scans
- *
- * Range: u32 tu/1000
- */
- u32 min_dwell_time_active;
-
- /*
- * The maximum time to wait on each channel for active scans
- *
- * Range: u32 tu/1000
- */
- u32 max_dwell_time_active;
-
- /*
- * The minimum time to wait on each channel for passive scans
- *
- * Range: u32 tu/1000
- */
- u32 min_dwell_time_passive;
-
- /*
- * The maximum time to wait on each channel for passive scans
- *
- * Range: u32 tu/1000
- */
- u32 max_dwell_time_passive;
-
- /*
- * Number of probe requests to transmit on each active scan channel
- *
- * Range: u8
- */
- u16 num_probe_reqs;
-
- /*
- * Scan trigger (split scan) timeout. The FW will split the scan
- * operation into slices of the given time and allow the FW to schedule
- * other tasks in between.
- *
- * Range: u32 Microsecs
- */
- u32 split_scan_timeout;
-};
-
-struct conf_sched_scan_settings {
- /*
- * The base time to wait on the channel for active scans (in TU/1000).
- * The minimum dwell time is calculated according to this:
- * min_dwell_time = base + num_of_probes_to_be_sent * delta_per_probe
- * The maximum dwell time is calculated according to this:
- * max_dwell_time = min_dwell_time + max_dwell_time_delta
- */
- u32 base_dwell_time;
-
- /* The delta between the min dwell time and max dwell time for
- * active scans (in TU/1000s). The max dwell time is used by the FW once
- * traffic is detected on the channel.
- */
- u32 max_dwell_time_delta;
-
- /* Delta added to min dwell time per each probe in 2.4 GHz (TU/1000) */
- u32 dwell_time_delta_per_probe;
-
- /* Delta added to min dwell time per each probe in 5 GHz (TU/1000) */
- u32 dwell_time_delta_per_probe_5;
-
- /* time to wait on the channel for passive scans (in TU/1000) */
- u32 dwell_time_passive;
-
- /* time to wait on the channel for DFS scans (in TU/1000) */
- u32 dwell_time_dfs;
-
- /* number of probe requests to send on each channel in active scans */
- u8 num_probe_reqs;
-
- /* RSSI threshold to be used for filtering */
- s8 rssi_threshold;
-
- /* SNR threshold to be used for filtering */
- s8 snr_threshold;
-};
-
-/* these are number of channels on the band divided by two, rounded up */
-#define CONF_TX_PWR_COMPENSATION_LEN_2 7
-#define CONF_TX_PWR_COMPENSATION_LEN_5 18
-
-struct conf_rf_settings {
- /*
- * Per channel power compensation for 2.4GHz
- *
- * Range: s8
- */
- u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
-
- /*
- * Per channel power compensation for 5GHz
- *
- * Range: s8
- */
- u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
-};
-
-struct conf_ht_setting {
- u8 rx_ba_win_size;
- u8 tx_ba_win_size;
- u16 inactivity_timeout;
-
- /* bitmap of enabled TIDs for TX BA sessions */
- u8 tx_ba_tid_bitmap;
-};
-
-struct conf_memory_settings {
- /* Number of stations supported in IBSS mode */
- u8 num_stations;
-
- /* Number of ssid profiles used in IBSS mode */
- u8 ssid_profiles;
-
- /* Number of memory buffers allocated to rx pool */
- u8 rx_block_num;
-
- /* Minimum number of blocks allocated to tx pool */
- u8 tx_min_block_num;
-
- /* Disable/Enable dynamic memory */
- u8 dynamic_memory;
-
- /*
- * Minimum required free tx memory blocks in order to assure optimum
- * performance
- *
- * Range: 0-120
- */
- u8 min_req_tx_blocks;
-
- /*
- * Minimum required free rx memory blocks in order to assure optimum
- * performance
- *
- * Range: 0-120
- */
- u8 min_req_rx_blocks;
-
- /*
- * Minimum number of mem blocks (free+used) guaranteed for TX
- *
- * Range: 0-120
- */
- u8 tx_min;
-};
-
-struct conf_fm_coex {
- u8 enable;
- u8 swallow_period;
- u8 n_divider_fref_set_1;
- u8 n_divider_fref_set_2;
- u16 m_divider_fref_set_1;
- u16 m_divider_fref_set_2;
- u32 coex_pll_stabilization_time;
- u16 ldo_stabilization_time;
- u8 fm_disturbed_band_margin;
- u8 swallow_clk_diff;
-};
-
-struct conf_rx_streaming_settings {
- /*
- * RX Streaming duration (in msec) from last tx/rx
- *
- * Range: u32
- */
- u32 duration;
-
- /*
- * Bitmap of tids to be polled during RX streaming.
- * (Note: it doesn't look like it really matters)
- *
- * Range: 0x1-0xff
- */
- u8 queues;
-
- /*
- * RX Streaming interval.
- * (Note:this value is also used as the rx streaming timeout)
- * Range: 0 (disabled), 10 - 100
- */
- u8 interval;
-
- /*
- * enable rx streaming also when there is no coex activity
- */
- u8 always;
-};
-
-struct conf_fwlog {
- /* Continuous or on-demand */
- u8 mode;
-
- /*
- * Number of memory blocks dedicated for the FW logger
- *
- * Range: 1-3, or 0 to disable the FW logger
- */
- u8 mem_blocks;
-
- /* Minimum log level threshold */
- u8 severity;
-
- /* Include/exclude timestamps from the log messages */
- u8 timestamp;
-
- /* See enum wl1271_fwlogger_output */
- u8 output;
-
- /* Regulates the frequency of log messages */
- u8 threshold;
-};
-
-#define ACX_RATE_MGMT_NUM_OF_RATES 13
-struct conf_rate_policy_settings {
- u16 rate_retry_score;
- u16 per_add;
- u16 per_th1;
- u16 per_th2;
- u16 max_per;
- u8 inverse_curiosity_factor;
- u8 tx_fail_low_th;
- u8 tx_fail_high_th;
- u8 per_alpha_shift;
- u8 per_add_shift;
- u8 per_beta1_shift;
- u8 per_beta2_shift;
- u8 rate_check_up;
- u8 rate_check_down;
- u8 rate_retry_policy[ACX_RATE_MGMT_NUM_OF_RATES];
-};
-
-struct conf_hangover_settings {
- u32 recover_time;
- u8 hangover_period;
- u8 dynamic_mode;
- u8 early_termination_mode;
- u8 max_period;
- u8 min_period;
- u8 increase_delta;
- u8 decrease_delta;
- u8 quiet_time;
- u8 increase_time;
- u8 window_size;
-};
-
-struct conf_drv_settings {
- struct conf_sg_settings sg;
- struct conf_rx_settings rx;
- struct conf_tx_settings tx;
- struct conf_conn_settings conn;
- struct conf_itrim_settings itrim;
- struct conf_pm_config_settings pm_config;
- struct conf_roam_trigger_settings roam_trigger;
- struct conf_scan_settings scan;
- struct conf_sched_scan_settings sched_scan;
- struct conf_rf_settings rf;
- struct conf_ht_setting ht;
- struct conf_memory_settings mem_wl127x;
- struct conf_memory_settings mem_wl128x;
- struct conf_fm_coex fm_coex;
- struct conf_rx_streaming_settings rx_streaming;
- struct conf_fwlog fwlog;
- struct conf_rate_policy_settings rate;
- struct conf_hangover_settings hangover;
- u8 hci_io_ds;
-};
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/debug.h b/drivers/net/wireless/wl12xx/debug.h
deleted file mode 100644
index ec0fdc25b280..000000000000
--- a/drivers/net/wireless/wl12xx/debug.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2011 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <coelho@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
-
-#include <linux/bitops.h>
-#include <linux/printk.h>
-
-#define DRIVER_NAME "wl12xx"
-#define DRIVER_PREFIX DRIVER_NAME ": "
-
-enum {
- DEBUG_NONE = 0,
- DEBUG_IRQ = BIT(0),
- DEBUG_SPI = BIT(1),
- DEBUG_BOOT = BIT(2),
- DEBUG_MAILBOX = BIT(3),
- DEBUG_TESTMODE = BIT(4),
- DEBUG_EVENT = BIT(5),
- DEBUG_TX = BIT(6),
- DEBUG_RX = BIT(7),
- DEBUG_SCAN = BIT(8),
- DEBUG_CRYPT = BIT(9),
- DEBUG_PSM = BIT(10),
- DEBUG_MAC80211 = BIT(11),
- DEBUG_CMD = BIT(12),
- DEBUG_ACX = BIT(13),
- DEBUG_SDIO = BIT(14),
- DEBUG_FILTERS = BIT(15),
- DEBUG_ADHOC = BIT(16),
- DEBUG_AP = BIT(17),
- DEBUG_PROBE = BIT(18),
- DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP),
- DEBUG_ALL = ~0,
-};
-
-extern u32 wl12xx_debug_level;
-
-#define DEBUG_DUMP_LIMIT 1024
-
-#define wl1271_error(fmt, arg...) \
- pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
-
-#define wl1271_warning(fmt, arg...) \
- pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
-
-#define wl1271_notice(fmt, arg...) \
- pr_info(DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl1271_info(fmt, arg...) \
- pr_info(DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl1271_debug(level, fmt, arg...) \
- do { \
- if (level & wl12xx_debug_level) \
- pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \
- } while (0)
-
-/* TODO: use pr_debug_hex_dump when it becomes available */
-#define wl1271_dump(level, prefix, buf, len) \
- do { \
- if (level & wl12xx_debug_level) \
- print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
- DUMP_PREFIX_OFFSET, 16, 1, \
- buf, \
- min_t(size_t, len, DEBUG_DUMP_LIMIT), \
- 0); \
- } while (0)
-
-#define wl1271_dump_ascii(level, prefix, buf, len) \
- do { \
- if (level & wl12xx_debug_level) \
- print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
- DUMP_PREFIX_OFFSET, 16, 1, \
- buf, \
- min_t(size_t, len, DEBUG_DUMP_LIMIT), \
- true); \
- } while (0)
-
-#endif /* __DEBUG_H__ */
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
deleted file mode 100644
index e1cf72765965..000000000000
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ /dev/null
@@ -1,1203 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "debugfs.h"
-
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "acx.h"
-#include "ps.h"
-#include "io.h"
-#include "tx.h"
-
-/* ms */
-#define WL1271_DEBUGFS_STATS_LIFETIME 1000
-
-/* debugfs macros idea from mac80211 */
-#define DEBUGFS_FORMAT_BUFFER_SIZE 100
-static int wl1271_format_buffer(char __user *userbuf, size_t count,
- loff_t *ppos, char *fmt, ...)
-{
- va_list args;
- char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
- int res;
-
- va_start(args, fmt);
- res = vscnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
-
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
-static ssize_t name## _read(struct file *file, char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- struct wl1271 *wl = file->private_data; \
- return wl1271_format_buffer(userbuf, count, ppos, \
- fmt "\n", ##value); \
-} \
- \
-static const struct file_operations name## _ops = { \
- .read = name## _read, \
- .open = wl1271_open_file_generic, \
- .llseek = generic_file_llseek, \
-};
-
-#define DEBUGFS_ADD(name, parent) \
- entry = debugfs_create_file(#name, 0400, parent, \
- wl, &name## _ops); \
- if (!entry || IS_ERR(entry)) \
- goto err; \
-
-#define DEBUGFS_ADD_PREFIX(prefix, name, parent) \
- do { \
- entry = debugfs_create_file(#name, 0400, parent, \
- wl, &prefix## _## name## _ops); \
- if (!entry || IS_ERR(entry)) \
- goto err; \
- } while (0);
-
-#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
-static ssize_t sub## _ ##name## _read(struct file *file, \
- char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- struct wl1271 *wl = file->private_data; \
- \
- wl1271_debugfs_update_stats(wl); \
- \
- return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \
- wl->stats.fw_stats->sub.name); \
-} \
- \
-static const struct file_operations sub## _ ##name## _ops = { \
- .read = sub## _ ##name## _read, \
- .open = wl1271_open_file_generic, \
- .llseek = generic_file_llseek, \
-};
-
-#define DEBUGFS_FWSTATS_ADD(sub, name) \
- DEBUGFS_ADD(sub## _ ##name, stats)
-
-static void wl1271_debugfs_update_stats(struct wl1271 *wl)
-{
- int ret;
-
- mutex_lock(&wl->mutex);
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (wl->state == WL1271_STATE_ON && !wl->plt &&
- time_after(jiffies, wl->stats.fw_stats_update +
- msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
- wl1271_acx_statistics(wl, wl->stats.fw_stats);
- wl->stats.fw_stats_update = jiffies;
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1271_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u");
-/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u");
-/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u");
-
-DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);
-DEBUGFS_READONLY_FILE(excessive_retries, "%u",
- wl->stats.excessive_retries);
-
-static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- u32 queue_len;
- char buf[20];
- int res;
-
- queue_len = wl1271_tx_total_queue_count(wl);
-
- res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-static const struct file_operations tx_queue_len_ops = {
- .read = tx_queue_len_read,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
-
- int res;
- char buf[10];
-
- res = scnprintf(buf, sizeof(buf), "%d\n", state);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, res);
-}
-
-static ssize_t gpio_power_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in gpio_power");
- return -EINVAL;
- }
-
- mutex_lock(&wl->mutex);
-
- if (value)
- wl1271_power_on(wl);
- else
- wl1271_power_off(wl);
-
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations gpio_power_ops = {
- .read = gpio_power_read,
- .write = gpio_power_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t start_recovery_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
-
- mutex_lock(&wl->mutex);
- wl12xx_queue_recovery_work(wl);
- mutex_unlock(&wl->mutex);
-
- return count;
-}
-
-static const struct file_operations start_recovery_ops = {
- .write = start_recovery_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t dynamic_ps_timeout_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
-
- return wl1271_format_buffer(user_buf, count,
- ppos, "%d\n",
- wl->conf.conn.dynamic_ps_timeout);
-}
-
-static ssize_t dynamic_ps_timeout_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- struct wl12xx_vif *wlvif;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in dynamic_ps");
- return -EINVAL;
- }
-
- if (value < 1 || value > 65535) {
- wl1271_warning("dyanmic_ps_timeout is not in valid range");
- return -ERANGE;
- }
-
- mutex_lock(&wl->mutex);
-
- wl->conf.conn.dynamic_ps_timeout = value;
-
- if (wl->state == WL1271_STATE_OFF)
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /* In case we're already in PSM, trigger it again to set new timeout
- * immediately without waiting for re-association
- */
-
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
- wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations dynamic_ps_timeout_ops = {
- .read = dynamic_ps_timeout_read,
- .write = dynamic_ps_timeout_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t forced_ps_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
-
- return wl1271_format_buffer(user_buf, count,
- ppos, "%d\n",
- wl->conf.conn.forced_ps);
-}
-
-static ssize_t forced_ps_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- struct wl12xx_vif *wlvif;
- unsigned long value;
- int ret, ps_mode;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in forced_ps");
- return -EINVAL;
- }
-
- if (value != 1 && value != 0) {
- wl1271_warning("forced_ps should be either 0 or 1");
- return -ERANGE;
- }
-
- mutex_lock(&wl->mutex);
-
- if (wl->conf.conn.forced_ps == value)
- goto out;
-
- wl->conf.conn.forced_ps = value;
-
- if (wl->state == WL1271_STATE_OFF)
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /* In case we're already in PSM, trigger it again to switch mode
- * immediately without waiting for re-association
- */
-
- ps_mode = value ? STATION_POWER_SAVE_MODE : STATION_AUTO_PS_MODE;
-
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
- wl1271_ps_set_mode(wl, wlvif, ps_mode);
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations forced_ps_ops = {
- .read = forced_ps_read,
- .write = forced_ps_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t split_scan_timeout_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
-
- return wl1271_format_buffer(user_buf, count,
- ppos, "%d\n",
- wl->conf.scan.split_scan_timeout / 1000);
-}
-
-static ssize_t split_scan_timeout_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in split_scan_timeout");
- return -EINVAL;
- }
-
- if (value == 0)
- wl1271_info("split scan will be disabled");
-
- mutex_lock(&wl->mutex);
-
- wl->conf.scan.split_scan_timeout = value * 1000;
-
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations split_scan_timeout_ops = {
- .read = split_scan_timeout_read,
- .write = split_scan_timeout_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t driver_state_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- int res = 0;
- ssize_t ret;
- char *buf;
-
-#define DRIVER_STATE_BUF_LEN 1024
-
- buf = kmalloc(DRIVER_STATE_BUF_LEN, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- mutex_lock(&wl->mutex);
-
-#define DRIVER_STATE_PRINT(x, fmt) \
- (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\
- #x " = " fmt "\n", wl->x))
-
-#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
-#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d")
-#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s")
-#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
-#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")
-
- DRIVER_STATE_PRINT_INT(tx_blocks_available);
- DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
- DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]);
- DRIVER_STATE_PRINT_INT(tx_allocated_pkts[1]);
- DRIVER_STATE_PRINT_INT(tx_allocated_pkts[2]);
- DRIVER_STATE_PRINT_INT(tx_allocated_pkts[3]);
- DRIVER_STATE_PRINT_INT(tx_frames_cnt);
- DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
- DRIVER_STATE_PRINT_INT(tx_queue_count[0]);
- DRIVER_STATE_PRINT_INT(tx_queue_count[1]);
- DRIVER_STATE_PRINT_INT(tx_queue_count[2]);
- DRIVER_STATE_PRINT_INT(tx_queue_count[3]);
- DRIVER_STATE_PRINT_INT(tx_packets_count);
- DRIVER_STATE_PRINT_INT(tx_results_count);
- DRIVER_STATE_PRINT_LHEX(flags);
- DRIVER_STATE_PRINT_INT(tx_blocks_freed);
- DRIVER_STATE_PRINT_INT(rx_counter);
- DRIVER_STATE_PRINT_INT(state);
- DRIVER_STATE_PRINT_INT(channel);
- DRIVER_STATE_PRINT_INT(band);
- DRIVER_STATE_PRINT_INT(power_level);
- DRIVER_STATE_PRINT_INT(sg_enabled);
- DRIVER_STATE_PRINT_INT(enable_11a);
- DRIVER_STATE_PRINT_INT(noise);
- DRIVER_STATE_PRINT_HEX(ap_fw_ps_map);
- DRIVER_STATE_PRINT_LHEX(ap_ps_map);
- DRIVER_STATE_PRINT_HEX(quirks);
- DRIVER_STATE_PRINT_HEX(irq);
- DRIVER_STATE_PRINT_HEX(ref_clock);
- DRIVER_STATE_PRINT_HEX(tcxo_clock);
- DRIVER_STATE_PRINT_HEX(hw_pg_ver);
- DRIVER_STATE_PRINT_HEX(platform_quirks);
- DRIVER_STATE_PRINT_HEX(chip.id);
- DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
- DRIVER_STATE_PRINT_INT(sched_scanning);
-
-#undef DRIVER_STATE_PRINT_INT
-#undef DRIVER_STATE_PRINT_LONG
-#undef DRIVER_STATE_PRINT_HEX
-#undef DRIVER_STATE_PRINT_LHEX
-#undef DRIVER_STATE_PRINT_STR
-#undef DRIVER_STATE_PRINT
-#undef DRIVER_STATE_BUF_LEN
-
- mutex_unlock(&wl->mutex);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, res);
- kfree(buf);
- return ret;
-}
-
-static const struct file_operations driver_state_ops = {
- .read = driver_state_read,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- struct wl12xx_vif *wlvif;
- int ret, res = 0;
- const int buf_size = 4096;
- char *buf;
- char tmp_buf[64];
-
- buf = kzalloc(buf_size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- mutex_lock(&wl->mutex);
-
-#define VIF_STATE_PRINT(x, fmt) \
- (res += scnprintf(buf + res, buf_size - res, \
- #x " = " fmt "\n", wlvif->x))
-
-#define VIF_STATE_PRINT_LONG(x) VIF_STATE_PRINT(x, "%ld")
-#define VIF_STATE_PRINT_INT(x) VIF_STATE_PRINT(x, "%d")
-#define VIF_STATE_PRINT_STR(x) VIF_STATE_PRINT(x, "%s")
-#define VIF_STATE_PRINT_LHEX(x) VIF_STATE_PRINT(x, "0x%lx")
-#define VIF_STATE_PRINT_LLHEX(x) VIF_STATE_PRINT(x, "0x%llx")
-#define VIF_STATE_PRINT_HEX(x) VIF_STATE_PRINT(x, "0x%x")
-
-#define VIF_STATE_PRINT_NSTR(x, len) \
- do { \
- memset(tmp_buf, 0, sizeof(tmp_buf)); \
- memcpy(tmp_buf, wlvif->x, \
- min_t(u8, len, sizeof(tmp_buf) - 1)); \
- res += scnprintf(buf + res, buf_size - res, \
- #x " = %s\n", tmp_buf); \
- } while (0)
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- VIF_STATE_PRINT_INT(role_id);
- VIF_STATE_PRINT_INT(bss_type);
- VIF_STATE_PRINT_LHEX(flags);
- VIF_STATE_PRINT_INT(p2p);
- VIF_STATE_PRINT_INT(dev_role_id);
- VIF_STATE_PRINT_INT(dev_hlid);
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS) {
- VIF_STATE_PRINT_INT(sta.hlid);
- VIF_STATE_PRINT_INT(sta.ba_rx_bitmap);
- VIF_STATE_PRINT_INT(sta.basic_rate_idx);
- VIF_STATE_PRINT_INT(sta.ap_rate_idx);
- VIF_STATE_PRINT_INT(sta.p2p_rate_idx);
- VIF_STATE_PRINT_INT(sta.qos);
- } else {
- VIF_STATE_PRINT_INT(ap.global_hlid);
- VIF_STATE_PRINT_INT(ap.bcast_hlid);
- VIF_STATE_PRINT_LHEX(ap.sta_hlid_map[0]);
- VIF_STATE_PRINT_INT(ap.mgmt_rate_idx);
- VIF_STATE_PRINT_INT(ap.bcast_rate_idx);
- VIF_STATE_PRINT_INT(ap.ucast_rate_idx[0]);
- VIF_STATE_PRINT_INT(ap.ucast_rate_idx[1]);
- VIF_STATE_PRINT_INT(ap.ucast_rate_idx[2]);
- VIF_STATE_PRINT_INT(ap.ucast_rate_idx[3]);
- }
- VIF_STATE_PRINT_INT(last_tx_hlid);
- VIF_STATE_PRINT_LHEX(links_map[0]);
- VIF_STATE_PRINT_NSTR(ssid, wlvif->ssid_len);
- VIF_STATE_PRINT_INT(band);
- VIF_STATE_PRINT_INT(channel);
- VIF_STATE_PRINT_HEX(bitrate_masks[0]);
- VIF_STATE_PRINT_HEX(bitrate_masks[1]);
- VIF_STATE_PRINT_HEX(basic_rate_set);
- VIF_STATE_PRINT_HEX(basic_rate);
- VIF_STATE_PRINT_HEX(rate_set);
- VIF_STATE_PRINT_INT(beacon_int);
- VIF_STATE_PRINT_INT(default_key);
- VIF_STATE_PRINT_INT(aid);
- VIF_STATE_PRINT_INT(session_counter);
- VIF_STATE_PRINT_INT(psm_entry_retry);
- VIF_STATE_PRINT_INT(power_level);
- VIF_STATE_PRINT_INT(rssi_thold);
- VIF_STATE_PRINT_INT(last_rssi_event);
- VIF_STATE_PRINT_INT(ba_support);
- VIF_STATE_PRINT_INT(ba_allowed);
- VIF_STATE_PRINT_LLHEX(tx_security_seq);
- VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
- }
-
-#undef VIF_STATE_PRINT_INT
-#undef VIF_STATE_PRINT_LONG
-#undef VIF_STATE_PRINT_HEX
-#undef VIF_STATE_PRINT_LHEX
-#undef VIF_STATE_PRINT_LLHEX
-#undef VIF_STATE_PRINT_STR
-#undef VIF_STATE_PRINT_NSTR
-#undef VIF_STATE_PRINT
-
- mutex_unlock(&wl->mutex);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, res);
- kfree(buf);
- return ret;
-}
-
-static const struct file_operations vifs_state_ops = {
- .read = vifs_state_read,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t dtim_interval_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- u8 value;
-
- if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
- wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
- value = wl->conf.conn.listen_interval;
- else
- value = 0;
-
- return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
-}
-
-static ssize_t dtim_interval_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value for dtim_interval");
- return -EINVAL;
- }
-
- if (value < 1 || value > 10) {
- wl1271_warning("dtim value is not in valid range");
- return -ERANGE;
- }
-
- mutex_lock(&wl->mutex);
-
- wl->conf.conn.listen_interval = value;
- /* for some reason there are different event types for 1 and >1 */
- if (value == 1)
- wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
- else
- wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
-
- /*
- * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
- * take effect on the next time we enter psm.
- */
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations dtim_interval_ops = {
- .read = dtim_interval_read,
- .write = dtim_interval_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-
-
-static ssize_t suspend_dtim_interval_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- u8 value;
-
- if (wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
- wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
- value = wl->conf.conn.suspend_listen_interval;
- else
- value = 0;
-
- return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
-}
-
-static ssize_t suspend_dtim_interval_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value for suspend_dtim_interval");
- return -EINVAL;
- }
-
- if (value < 1 || value > 10) {
- wl1271_warning("suspend_dtim value is not in valid range");
- return -ERANGE;
- }
-
- mutex_lock(&wl->mutex);
-
- wl->conf.conn.suspend_listen_interval = value;
- /* for some reason there are different event types for 1 and >1 */
- if (value == 1)
- wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
- else
- wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
-
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-
-static const struct file_operations suspend_dtim_interval_ops = {
- .read = suspend_dtim_interval_read,
- .write = suspend_dtim_interval_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- u8 value;
-
- if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON ||
- wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS)
- value = wl->conf.conn.listen_interval;
- else
- value = 0;
-
- return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
-}
-
-static ssize_t beacon_interval_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value for beacon_interval");
- return -EINVAL;
- }
-
- if (value < 1 || value > 255) {
- wl1271_warning("beacon interval value is not in valid range");
- return -ERANGE;
- }
-
- mutex_lock(&wl->mutex);
-
- wl->conf.conn.listen_interval = value;
- /* for some reason there are different event types for 1 and >1 */
- if (value == 1)
- wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON;
- else
- wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS;
-
- /*
- * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
- * take effect on the next time we enter psm.
- */
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations beacon_interval_ops = {
- .read = beacon_interval_read,
- .write = beacon_interval_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t rx_streaming_interval_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- struct wl12xx_vif *wlvif;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in rx_streaming_interval!");
- return -EINVAL;
- }
-
- /* valid values: 0, 10-100 */
- if (value && (value < 10 || value > 100)) {
- wl1271_warning("value is not in range!");
- return -ERANGE;
- }
-
- mutex_lock(&wl->mutex);
-
- wl->conf.rx_streaming.interval = value;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- wl1271_recalc_rx_streaming(wl, wlvif);
- }
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static ssize_t rx_streaming_interval_read(struct file *file,
- char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- return wl1271_format_buffer(userbuf, count, ppos,
- "%d\n", wl->conf.rx_streaming.interval);
-}
-
-static const struct file_operations rx_streaming_interval_ops = {
- .read = rx_streaming_interval_read,
- .write = rx_streaming_interval_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t rx_streaming_always_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- struct wl12xx_vif *wlvif;
- unsigned long value;
- int ret;
-
- ret = kstrtoul_from_user(user_buf, count, 10, &value);
- if (ret < 0) {
- wl1271_warning("illegal value in rx_streaming_write!");
- return -EINVAL;
- }
-
- /* valid values: 0, 10-100 */
- if (!(value == 0 || value == 1)) {
- wl1271_warning("value is not in valid!");
- return -EINVAL;
- }
-
- mutex_lock(&wl->mutex);
-
- wl->conf.rx_streaming.always = value;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- wl1271_recalc_rx_streaming(wl, wlvif);
- }
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static ssize_t rx_streaming_always_read(struct file *file,
- char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- return wl1271_format_buffer(userbuf, count, ppos,
- "%d\n", wl->conf.rx_streaming.always);
-}
-
-static const struct file_operations rx_streaming_always_ops = {
- .read = rx_streaming_always_read,
- .write = rx_streaming_always_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static ssize_t beacon_filtering_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct wl1271 *wl = file->private_data;
- struct wl12xx_vif *wlvif;
- char buf[10];
- size_t len;
- unsigned long value;
- int ret;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
-
- ret = kstrtoul(buf, 0, &value);
- if (ret < 0) {
- wl1271_warning("illegal value for beacon_filtering!");
- return -EINVAL;
- }
-
- mutex_lock(&wl->mutex);
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value);
- }
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static const struct file_operations beacon_filtering_ops = {
- .write = beacon_filtering_write,
- .open = wl1271_open_file_generic,
- .llseek = default_llseek,
-};
-
-static int wl1271_debugfs_add_files(struct wl1271 *wl,
- struct dentry *rootdir)
-{
- int ret = 0;
- struct dentry *entry, *stats, *streaming;
-
- stats = debugfs_create_dir("fw-statistics", rootdir);
- if (!stats || IS_ERR(stats)) {
- entry = stats;
- goto err;
- }
-
- DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
-
- DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
- DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
- DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
- DEBUGFS_FWSTATS_ADD(rx, dropped);
- DEBUGFS_FWSTATS_ADD(rx, fcs_err);
- DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
- DEBUGFS_FWSTATS_ADD(rx, path_reset);
- DEBUGFS_FWSTATS_ADD(rx, reset_counter);
-
- DEBUGFS_FWSTATS_ADD(dma, rx_requested);
- DEBUGFS_FWSTATS_ADD(dma, rx_errors);
- DEBUGFS_FWSTATS_ADD(dma, tx_requested);
- DEBUGFS_FWSTATS_ADD(dma, tx_errors);
-
- DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
- DEBUGFS_FWSTATS_ADD(isr, fiqs);
- DEBUGFS_FWSTATS_ADD(isr, rx_headers);
- DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
- DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
- DEBUGFS_FWSTATS_ADD(isr, irqs);
- DEBUGFS_FWSTATS_ADD(isr, tx_procs);
- DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
- DEBUGFS_FWSTATS_ADD(isr, dma0_done);
- DEBUGFS_FWSTATS_ADD(isr, dma1_done);
- DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
- DEBUGFS_FWSTATS_ADD(isr, commands);
- DEBUGFS_FWSTATS_ADD(isr, rx_procs);
- DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
- DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
- DEBUGFS_FWSTATS_ADD(isr, pci_pm);
- DEBUGFS_FWSTATS_ADD(isr, wakeups);
- DEBUGFS_FWSTATS_ADD(isr, low_rssi);
-
- DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
- DEBUGFS_FWSTATS_ADD(wep, default_key_count);
- /* skipping wep.reserved */
- DEBUGFS_FWSTATS_ADD(wep, key_not_found);
- DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
- DEBUGFS_FWSTATS_ADD(wep, packets);
- DEBUGFS_FWSTATS_ADD(wep, interrupt);
-
- DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
- DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
- DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
- DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
- DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
- DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
- DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
- DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
- DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
- DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
- DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
- DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
- /* skipping cont_miss_bcns_spread for now */
- DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
-
- DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
- DEBUGFS_FWSTATS_ADD(mic, calc_failure);
-
- DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
- DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
- DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
-
- DEBUGFS_FWSTATS_ADD(event, heart_beat);
- DEBUGFS_FWSTATS_ADD(event, calibration);
- DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
- DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
- DEBUGFS_FWSTATS_ADD(event, rx_pool);
- DEBUGFS_FWSTATS_ADD(event, oom_late);
- DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
- DEBUGFS_FWSTATS_ADD(event, tx_stuck);
-
- DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
- DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
- DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
- DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
- DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
- DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
- DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
-
- DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
- DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
-
- DEBUGFS_ADD(tx_queue_len, rootdir);
- DEBUGFS_ADD(retry_count, rootdir);
- DEBUGFS_ADD(excessive_retries, rootdir);
-
- DEBUGFS_ADD(gpio_power, rootdir);
- DEBUGFS_ADD(start_recovery, rootdir);
- DEBUGFS_ADD(driver_state, rootdir);
- DEBUGFS_ADD(vifs_state, rootdir);
- DEBUGFS_ADD(dtim_interval, rootdir);
- DEBUGFS_ADD(suspend_dtim_interval, rootdir);
- DEBUGFS_ADD(beacon_interval, rootdir);
- DEBUGFS_ADD(beacon_filtering, rootdir);
- DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
- DEBUGFS_ADD(forced_ps, rootdir);
- DEBUGFS_ADD(split_scan_timeout, rootdir);
-
- streaming = debugfs_create_dir("rx_streaming", rootdir);
- if (!streaming || IS_ERR(streaming))
- goto err;
-
- DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming);
- DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming);
-
-
- return 0;
-
-err:
- if (IS_ERR(entry))
- ret = PTR_ERR(entry);
- else
- ret = -ENOMEM;
-
- return ret;
-}
-
-void wl1271_debugfs_reset(struct wl1271 *wl)
-{
- if (!wl->stats.fw_stats)
- return;
-
- memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
- wl->stats.retry_count = 0;
- wl->stats.excessive_retries = 0;
-}
-
-int wl1271_debugfs_init(struct wl1271 *wl)
-{
- int ret;
- struct dentry *rootdir;
-
- rootdir = debugfs_create_dir(KBUILD_MODNAME,
- wl->hw->wiphy->debugfsdir);
-
- if (IS_ERR(rootdir)) {
- ret = PTR_ERR(rootdir);
- goto err;
- }
-
- wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
- GFP_KERNEL);
-
- if (!wl->stats.fw_stats) {
- ret = -ENOMEM;
- goto err_fw;
- }
-
- wl->stats.fw_stats_update = jiffies;
-
- ret = wl1271_debugfs_add_files(wl, rootdir);
-
- if (ret < 0)
- goto err_file;
-
- return 0;
-
-err_file:
- kfree(wl->stats.fw_stats);
- wl->stats.fw_stats = NULL;
-
-err_fw:
- debugfs_remove_recursive(rootdir);
-
-err:
- return ret;
-}
-
-void wl1271_debugfs_exit(struct wl1271 *wl)
-{
- kfree(wl->stats.fw_stats);
- wl->stats.fw_stats = NULL;
-}
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
deleted file mode 100644
index 254c5b292cf6..000000000000
--- a/drivers/net/wireless/wl12xx/debugfs.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __DEBUGFS_H__
-#define __DEBUGFS_H__
-
-#include "wl12xx.h"
-
-int wl1271_debugfs_init(struct wl1271 *wl);
-void wl1271_debugfs_exit(struct wl1271 *wl);
-void wl1271_debugfs_reset(struct wl1271 *wl);
-
-#endif /* WL1271_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
deleted file mode 100644
index 96f06a89c2a9..000000000000
--- a/drivers/net/wireless/wl12xx/event.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "reg.h"
-#include "io.h"
-#include "event.h"
-#include "ps.h"
-#include "scan.h"
-#include "wl12xx_80211.h"
-
-static void wl1271_event_rssi_trigger(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct event_mailbox *mbox)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- enum nl80211_cqm_rssi_threshold_event event;
- s8 metric = mbox->rssi_snr_trigger_metric[0];
-
- wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric);
-
- if (metric <= wlvif->rssi_thold)
- event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
- else
- event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
-
- if (event != wlvif->last_rssi_event)
- ieee80211_cqm_rssi_notify(vif, event, GFP_KERNEL);
- wlvif->last_rssi_event = event;
-}
-
-static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
- if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
- if (!wlvif->sta.ba_rx_bitmap)
- return;
- ieee80211_stop_rx_ba_session(vif, wlvif->sta.ba_rx_bitmap,
- vif->bss_conf.bssid);
- } else {
- u8 hlid;
- struct wl1271_link *lnk;
- for_each_set_bit(hlid, wlvif->ap.sta_hlid_map,
- WL12XX_MAX_LINKS) {
- lnk = &wl->links[hlid];
- if (!lnk->ba_bitmap)
- continue;
-
- ieee80211_stop_rx_ba_session(vif,
- lnk->ba_bitmap,
- lnk->addr);
- }
- }
-}
-
-static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
- u8 enable)
-{
- struct wl12xx_vif *wlvif;
-
- if (enable) {
- set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
- } else {
- clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- wl1271_recalc_rx_streaming(wl, wlvif);
- }
- }
-
-}
-
-static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
-{
- wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
- wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
- wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
-}
-
-static int wl1271_event_process(struct wl1271 *wl)
-{
- struct event_mailbox *mbox = wl->mbox;
- struct ieee80211_vif *vif;
- struct wl12xx_vif *wlvif;
- u32 vector;
- bool beacon_loss = false;
- bool disconnect_sta = false;
- unsigned long sta_bitmap = 0;
-
- wl1271_event_mbox_dump(mbox);
-
- vector = le32_to_cpu(mbox->events_vector);
- vector &= ~(le32_to_cpu(mbox->events_mask));
- wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);
-
- if (vector & SCAN_COMPLETE_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "status: 0x%x",
- mbox->scheduled_scan_status);
-
- wl1271_scan_stm(wl, wl->scan_vif);
- }
-
- if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT "
- "(status 0x%0x)", mbox->scheduled_scan_status);
-
- wl1271_scan_sched_scan_results(wl);
- }
-
- if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
- "(status 0x%0x)", mbox->scheduled_scan_status);
- if (wl->sched_scanning) {
- ieee80211_sched_scan_stopped(wl->hw);
- wl->sched_scanning = false;
- }
- }
-
- if (vector & SOFT_GEMINI_SENSE_EVENT_ID)
- wl12xx_event_soft_gemini_sense(wl,
- mbox->soft_gemini_sense_info);
-
- /*
- * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
- * filtering) is enabled. Without PSM, the stack will receive all
- * beacons and can detect beacon loss by itself.
- *
- * As there's possibility that the driver disables PSM before receiving
- * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
- *
- */
- if (vector & BSS_LOSE_EVENT_ID) {
- /* TODO: check for multi-role */
- wl1271_info("Beacon loss detected.");
-
- /* indicate to the stack, that beacons have been lost */
- beacon_loss = true;
- }
-
- if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
- /* TODO: check actual multi-role support */
- wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- wl1271_event_rssi_trigger(wl, wlvif, mbox);
- }
- }
-
- if (vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) {
- u8 role_id = mbox->role_id;
- wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
- "ba_allowed = 0x%x, role_id=%d",
- mbox->rx_ba_allowed, role_id);
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- if (role_id != 0xff && role_id != wlvif->role_id)
- continue;
-
- wlvif->ba_allowed = !!mbox->rx_ba_allowed;
- if (!wlvif->ba_allowed)
- wl1271_stop_ba_event(wl, wlvif);
- }
- }
-
- if (vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. "
- "status = 0x%x",
- mbox->channel_switch_status);
- /*
- * That event uses for two cases:
- * 1) channel switch complete with status=0
- * 2) channel switch failed status=1
- */
-
- /* TODO: configure only the relevant vif */
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- bool success;
-
- if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
- &wlvif->flags))
- continue;
-
- success = mbox->channel_switch_status ? false : true;
- vif = wl12xx_wlvif_to_vif(wlvif);
-
- ieee80211_chswitch_done(vif, success);
- }
- }
-
- if ((vector & DUMMY_PACKET_EVENT_ID)) {
- wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
- wl1271_tx_dummy_packet(wl);
- }
-
- /*
- * "TX retries exceeded" has a different meaning according to mode.
- * In AP mode the offending station is disconnected.
- */
- if (vector & MAX_TX_RETRY_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID");
- sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded);
- disconnect_sta = true;
- }
-
- if (vector & INACTIVE_STA_EVENT_ID) {
- wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID");
- sta_bitmap |= le16_to_cpu(mbox->sta_aging_status);
- disconnect_sta = true;
- }
-
- if (disconnect_sta) {
- u32 num_packets = wl->conf.tx.max_tx_retries;
- struct ieee80211_sta *sta;
- const u8 *addr;
- int h;
-
- for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) {
- bool found = false;
- /* find the ap vif connected to this sta */
- wl12xx_for_each_wlvif_ap(wl, wlvif) {
- if (!test_bit(h, wlvif->ap.sta_hlid_map))
- continue;
- found = true;
- break;
- }
- if (!found)
- continue;
-
- vif = wl12xx_wlvif_to_vif(wlvif);
- addr = wl->links[h].addr;
-
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, addr);
- if (sta) {
- wl1271_debug(DEBUG_EVENT, "remove sta %d", h);
- ieee80211_report_low_ack(sta, num_packets);
- }
- rcu_read_unlock();
- }
- }
-
- if (beacon_loss)
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- vif = wl12xx_wlvif_to_vif(wlvif);
- ieee80211_connection_loss(vif);
- }
-
- return 0;
-}
-
-int wl1271_event_unmask(struct wl1271 *wl)
-{
- int ret;
-
- ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-void wl1271_event_mbox_config(struct wl1271 *wl)
-{
- wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
- wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
-
- wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
- wl->mbox_ptr[0], wl->mbox_ptr[1]);
-}
-
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
-{
- int ret;
-
- wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
-
- if (mbox_num > 1)
- return -EINVAL;
-
- /* first we read the mbox descriptor */
- wl1271_read(wl, wl->mbox_ptr[mbox_num], wl->mbox,
- sizeof(*wl->mbox), false);
-
- /* process the descriptor */
- ret = wl1271_event_process(wl);
- if (ret < 0)
- return ret;
-
- /* then we let the firmware know it can go on...*/
- wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
-
- return 0;
-}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
deleted file mode 100644
index 8acba0d43976..000000000000
--- a/drivers/net/wireless/wl12xx/event.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __EVENT_H__
-#define __EVENT_H__
-
-/*
- * Mbox events
- *
- * The event mechanism is based on a pair of event buffers (buffers A and
- * B) at fixed locations in the target's memory. The host processes one
- * buffer while the other buffer continues to collect events. If the host
- * is not processing events, an interrupt is issued to signal that a buffer
- * is ready. Once the host is done with processing events from one buffer,
- * it signals the target (with an ACK interrupt) that the event buffer is
- * free.
- */
-
-enum {
- RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0),
- RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1),
- RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2),
- RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3),
- RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4),
- RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5),
- RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6),
- RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7),
- MEASUREMENT_START_EVENT_ID = BIT(8),
- MEASUREMENT_COMPLETE_EVENT_ID = BIT(9),
- SCAN_COMPLETE_EVENT_ID = BIT(10),
- WFD_DISCOVERY_COMPLETE_EVENT_ID = BIT(11),
- AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12),
- RESERVED1 = BIT(13),
- PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14),
- ROLE_STOP_COMPLETE_EVENT_ID = BIT(15),
- RADAR_DETECTED_EVENT_ID = BIT(16),
- CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
- BSS_LOSE_EVENT_ID = BIT(18),
- REGAINED_BSS_EVENT_ID = BIT(19),
- MAX_TX_RETRY_EVENT_ID = BIT(20),
- DUMMY_PACKET_EVENT_ID = BIT(21),
- SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
- CHANGE_AUTO_MODE_TIMEOUT_EVENT_ID = BIT(23),
- SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
- PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25),
- INACTIVE_STA_EVENT_ID = BIT(26),
- PEER_REMOVE_COMPLETE_EVENT_ID = BIT(27),
- PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28),
- PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29),
- BA_SESSION_RX_CONSTRAINT_EVENT_ID = BIT(30),
- REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(31),
- EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
-};
-
-enum {
- EVENT_ENTER_POWER_SAVE_FAIL = 0,
- EVENT_ENTER_POWER_SAVE_SUCCESS,
-};
-
-#define NUM_OF_RSSI_SNR_TRIGGERS 8
-
-struct event_mailbox {
- __le32 events_vector;
- __le32 events_mask;
- __le32 reserved_1;
- __le32 reserved_2;
-
- u8 number_of_scan_results;
- u8 scan_tag;
- u8 completed_scan_status;
- u8 reserved_3;
-
- u8 soft_gemini_sense_info;
- u8 soft_gemini_protective_info;
- s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
- u8 change_auto_mode_timeout;
- u8 scheduled_scan_status;
- u8 reserved4;
- /* tuned channel (roc) */
- u8 roc_channel;
-
- __le16 hlid_removed_bitmap;
-
- /* bitmap of aged stations (by HLID) */
- __le16 sta_aging_status;
-
- /* bitmap of stations (by HLID) which exceeded max tx retries */
- __le16 sta_tx_retry_exceeded;
-
- /* discovery completed results */
- u8 discovery_tag;
- u8 number_of_preq_results;
- u8 number_of_prsp_results;
- u8 reserved_5;
-
- /* rx ba constraint */
- u8 role_id; /* 0xFF means any role. */
- u8 rx_ba_allowed;
- u8 reserved_6[2];
-
- /* Channel switch results */
-
- u8 channel_switch_role_id;
- u8 channel_switch_status;
- u8 reserved_7[2];
-
- u8 ps_poll_delivery_failure_role_ids;
- u8 stopped_role_ids;
- u8 started_role_ids;
-
- u8 reserved_8[9];
-} __packed;
-
-struct wl1271;
-
-int wl1271_event_unmask(struct wl1271 *wl);
-void wl1271_event_mbox_config(struct wl1271 *wl);
-int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/wl12xx/ini.h
deleted file mode 100644
index 4cf9ecc56212..000000000000
--- a/drivers/net/wireless/wl12xx/ini.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __INI_H__
-#define __INI_H__
-
-#define GENERAL_SETTINGS_DRPW_LPD 0xc0
-#define SCRATCH_ENABLE_LPD BIT(25)
-
-#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16
-
-struct wl1271_ini_general_params {
- u8 ref_clock;
- u8 settling_time;
- u8 clk_valid_on_wakeup;
- u8 dc2dc_mode;
- u8 dual_mode_select;
- u8 tx_bip_fem_auto_detect;
- u8 tx_bip_fem_manufacturer;
- u8 general_settings;
- u8 sr_state;
- u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
- u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
- u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
-} __packed;
-
-#define WL128X_INI_MAX_SETTINGS_PARAM 4
-
-struct wl128x_ini_general_params {
- u8 ref_clock;
- u8 settling_time;
- u8 clk_valid_on_wakeup;
- u8 tcxo_ref_clock;
- u8 tcxo_settling_time;
- u8 tcxo_valid_on_wakeup;
- u8 tcxo_ldo_voltage;
- u8 xtal_itrim_val;
- u8 platform_conf;
- u8 dual_mode_select;
- u8 tx_bip_fem_auto_detect;
- u8 tx_bip_fem_manufacturer;
- u8 general_settings[WL128X_INI_MAX_SETTINGS_PARAM];
- u8 sr_state;
- u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
- u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
- u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
-} __packed;
-
-#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15
-
-struct wl1271_ini_band_params_2 {
- u8 rx_trace_insertion_loss;
- u8 tx_trace_loss;
- u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
-} __packed;
-
-#define WL1271_INI_CHANNEL_COUNT_2 14
-
-struct wl128x_ini_band_params_2 {
- u8 rx_trace_insertion_loss;
- u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_2];
- u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
-} __packed;
-
-#define WL1271_INI_RATE_GROUP_COUNT 6
-
-struct wl1271_ini_fem_params_2 {
- __le16 tx_bip_ref_pd_voltage;
- u8 tx_bip_ref_power;
- u8 tx_bip_ref_offset;
- u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
- u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
- u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT];
- u8 rx_fem_insertion_loss;
- u8 degraded_low_to_normal_thr;
- u8 normal_to_degraded_high_thr;
-} __packed;
-
-#define WL128X_INI_RATE_GROUP_COUNT 7
-/* low and high temperatures */
-#define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2
-
-struct wl128x_ini_fem_params_2 {
- __le16 tx_bip_ref_pd_voltage;
- u8 tx_bip_ref_power;
- u8 tx_bip_ref_offset;
- u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
- u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
- u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT + 1];
- u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_2];
- u8 tx_pd_vs_temperature[WL128X_INI_PD_VS_TEMPERATURE_RANGES];
- u8 rx_fem_insertion_loss;
- u8 degraded_low_to_normal_thr;
- u8 normal_to_degraded_high_thr;
-} __packed;
-
-#define WL1271_INI_CHANNEL_COUNT_5 35
-#define WL1271_INI_SUB_BAND_COUNT_5 7
-
-struct wl1271_ini_band_params_5 {
- u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5];
- u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
-} __packed;
-
-struct wl128x_ini_band_params_5 {
- u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_5];
- u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
-} __packed;
-
-struct wl1271_ini_fem_params_5 {
- __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
- u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT];
- u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT];
- u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
- u8 degraded_low_to_normal_thr;
- u8 normal_to_degraded_high_thr;
-} __packed;
-
-struct wl128x_ini_fem_params_5 {
- __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
- u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
- u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT];
- u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_5];
- u8 tx_pd_vs_temperature[WL1271_INI_SUB_BAND_COUNT_5 *
- WL128X_INI_PD_VS_TEMPERATURE_RANGES];
- u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
- u8 degraded_low_to_normal_thr;
- u8 normal_to_degraded_high_thr;
-} __packed;
-
-/* NVS data structure */
-#define WL1271_INI_NVS_SECTION_SIZE 468
-#define WL1271_INI_FEM_MODULE_COUNT 2
-
-#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800
-
-struct wl1271_nvs_file {
- /* NVS section - must be first! */
- u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
-
- /* INI section */
- struct wl1271_ini_general_params general_params;
- u8 padding1;
- struct wl1271_ini_band_params_2 stat_radio_params_2;
- u8 padding2;
- struct {
- struct wl1271_ini_fem_params_2 params;
- u8 padding;
- } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
- struct wl1271_ini_band_params_5 stat_radio_params_5;
- u8 padding3;
- struct {
- struct wl1271_ini_fem_params_5 params;
- u8 padding;
- } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
-} __packed;
-
-struct wl128x_nvs_file {
- /* NVS section - must be first! */
- u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
-
- /* INI section */
- struct wl128x_ini_general_params general_params;
- u8 fem_vendor_and_options;
- struct wl128x_ini_band_params_2 stat_radio_params_2;
- u8 padding2;
- struct {
- struct wl128x_ini_fem_params_2 params;
- u8 padding;
- } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
- struct wl128x_ini_band_params_5 stat_radio_params_5;
- u8 padding3;
- struct {
- struct wl128x_ini_fem_params_5 params;
- u8 padding;
- } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
-} __packed;
-#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
deleted file mode 100644
index 203fbebf09eb..000000000000
--- a/drivers/net/wireless/wl12xx/init.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "debug.h"
-#include "init.h"
-#include "wl12xx_80211.h"
-#include "acx.h"
-#include "cmd.h"
-#include "reg.h"
-#include "tx.h"
-#include "io.h"
-
-int wl1271_init_templates_config(struct wl1271 *wl)
-{
- int ret, i;
- size_t max_size;
-
- /* send empty templates for fw memory reservation */
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
- WL1271_CMD_TEMPL_MAX_SIZE,
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_CFG_PROBE_REQ_5,
- NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
- WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_NULL_DATA, NULL,
- sizeof(struct wl12xx_null_data_template),
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_PS_POLL, NULL,
- sizeof(struct wl12xx_ps_poll_template),
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_QOS_NULL_DATA, NULL,
- sizeof
- (struct ieee80211_qos_hdr),
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_PROBE_RESPONSE, NULL,
- WL1271_CMD_TEMPL_DFLT_SIZE,
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_BEACON, NULL,
- WL1271_CMD_TEMPL_DFLT_SIZE,
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- max_size = sizeof(struct wl12xx_arp_rsp_template) +
- WL1271_EXTRA_SPACE_MAX;
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_ARP_RSP, NULL,
- max_size,
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- /*
- * Put very large empty placeholders for all templates. These
- * reserve memory for later.
- */
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
- WL1271_CMD_TEMPL_MAX_SIZE,
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_AP_BEACON, NULL,
- WL1271_CMD_TEMPL_MAX_SIZE,
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_DEAUTH_AP, NULL,
- sizeof
- (struct wl12xx_disconn_template),
- 0, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
- ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
- CMD_TEMPL_KLV, NULL,
- sizeof(struct ieee80211_qos_hdr),
- i, WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int wl1271_ap_init_deauth_template(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct wl12xx_disconn_template *tmpl;
- int ret;
- u32 rate;
-
- tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
- if (!tmpl) {
- ret = -ENOMEM;
- goto out;
- }
-
- tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_DEAUTH);
-
- rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_DEAUTH_AP,
- tmpl, sizeof(*tmpl), 0, rate);
-
-out:
- kfree(tmpl);
- return ret;
-}
-
-static int wl1271_ap_init_null_template(struct wl1271 *wl,
- struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct ieee80211_hdr_3addr *nullfunc;
- int ret;
- u32 rate;
-
- nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
- if (!nullfunc) {
- ret = -ENOMEM;
- goto out;
- }
-
- nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC |
- IEEE80211_FCTL_FROMDS);
-
- /* nullfunc->addr1 is filled by FW */
-
- memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
- memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);
-
- rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_NULL_DATA, nullfunc,
- sizeof(*nullfunc), 0, rate);
-
-out:
- kfree(nullfunc);
- return ret;
-}
-
-static int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
- struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct ieee80211_qos_hdr *qosnull;
- int ret;
- u32 rate;
-
- qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
- if (!qosnull) {
- ret = -ENOMEM;
- goto out;
- }
-
- qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_QOS_NULLFUNC |
- IEEE80211_FCTL_FROMDS);
-
- /* qosnull->addr1 is filled by FW */
-
- memcpy(qosnull->addr2, vif->addr, ETH_ALEN);
- memcpy(qosnull->addr3, vif->addr, ETH_ALEN);
-
- rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_QOS_NULL_DATA, qosnull,
- sizeof(*qosnull), 0, rate);
-
-out:
- kfree(qosnull);
- return ret;
-}
-
-static int wl12xx_init_rx_config(struct wl1271 *wl)
-{
- int ret;
-
- ret = wl1271_acx_rx_msdu_life_time(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wl12xx_init_phy_vif_config(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret;
-
- ret = wl1271_acx_slot(wl, wlvif, DEFAULT_SLOT_TIME);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_service_period_timeout(wl, wlvif);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_rts_threshold(wl, wlvif, wl->hw->wiphy->rts_threshold);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wl1271_init_sta_beacon_filter(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret;
-
- ret = wl1271_acx_beacon_filter_table(wl, wlvif);
- if (ret < 0)
- return ret;
-
- /* enable beacon filtering */
- ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1271_init_pta(struct wl1271 *wl)
-{
- int ret;
-
- ret = wl12xx_acx_sg_cfg(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1271_init_energy_detection(struct wl1271 *wl)
-{
- int ret;
-
- ret = wl1271_acx_cca_threshold(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wl1271_init_beacon_broadcast(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret;
-
- ret = wl1271_acx_bcn_dtim_options(wl, wlvif);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wl12xx_init_fwlog(struct wl1271 *wl)
-{
- int ret;
-
- if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED)
- return 0;
-
- ret = wl12xx_cmd_config_fwlog(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/* generic sta initialization (non vif-specific) */
-static int wl1271_sta_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- /* PS config */
- ret = wl12xx_acx_config_ps(wl, wlvif);
- if (ret < 0)
- return ret;
-
- /* FM WLAN coexistence */
- ret = wl1271_acx_fm_coex(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl,
- struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret, i;
-
- /* disable all keep-alive templates */
- for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
- ret = wl1271_acx_keep_alive_config(wl, wlvif, i,
- ACX_KEEP_ALIVE_TPL_INVALID);
- if (ret < 0)
- return ret;
- }
-
- /* disable the keep-alive feature */
- ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/* generic ap initialization (non vif-specific) */
-static int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- ret = wl1271_init_ap_rates(wl, wlvif);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret;
-
- ret = wl1271_ap_init_deauth_template(wl, wlvif);
- if (ret < 0)
- return ret;
-
- ret = wl1271_ap_init_null_template(wl, vif);
- if (ret < 0)
- return ret;
-
- ret = wl1271_ap_init_qos_null_template(wl, vif);
- if (ret < 0)
- return ret;
-
- /*
- * when operating as AP we want to receive external beacons for
- * configuring ERP protection.
- */
- ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl,
- struct ieee80211_vif *vif)
-{
- return wl1271_ap_init_templates(wl, vif);
-}
-
-int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int i, ret;
- struct conf_tx_rate_class rc;
- u32 supported_rates;
-
- wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x",
- wlvif->basic_rate_set);
-
- if (wlvif->basic_rate_set == 0)
- return -EINVAL;
-
- rc.enabled_rates = wlvif->basic_rate_set;
- rc.long_retry_limit = 10;
- rc.short_retry_limit = 10;
- rc.aflags = 0;
- ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx);
- if (ret < 0)
- return ret;
-
- /* use the min basic rate for AP broadcast/multicast */
- rc.enabled_rates = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- rc.short_retry_limit = 10;
- rc.long_retry_limit = 10;
- rc.aflags = 0;
- ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx);
- if (ret < 0)
- return ret;
-
- /*
- * If the basic rates contain OFDM rates, use OFDM only
- * rates for unicast TX as well. Else use all supported rates.
- */
- if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
- supported_rates = CONF_TX_OFDM_RATES;
- else
- supported_rates = CONF_TX_AP_ENABLED_RATES;
-
- /* unconditionally enable HT rates */
- supported_rates |= CONF_TX_MCS_RATES;
-
- /* configure unicast TX rate classes */
- for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
- rc.enabled_rates = supported_rates;
- rc.short_retry_limit = 10;
- rc.long_retry_limit = 10;
- rc.aflags = 0;
- ret = wl1271_acx_ap_rate_policy(wl, &rc,
- wlvif->ap.ucast_rate_idx[i]);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- /* Reset the BA RX indicators */
- wlvif->ba_allowed = true;
- wl->ba_rx_session_count = 0;
-
- /* BA is supported in STA/AP modes */
- if (wlvif->bss_type != BSS_TYPE_AP_BSS &&
- wlvif->bss_type != BSS_TYPE_STA_BSS) {
- wlvif->ba_support = false;
- return 0;
- }
-
- wlvif->ba_support = true;
-
- /* 802.11n initiator BA session setting */
- return wl12xx_acx_set_ba_initiator_policy(wl, wlvif);
-}
-
-int wl1271_chip_specific_init(struct wl1271 *wl)
-{
- int ret = 0;
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
-
- if (!(wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT))
- /* Enable SDIO padding */
- host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
-
- /* Must be before wl1271_acx_init_mem_config() */
- ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
- if (ret < 0)
- goto out;
- }
-out:
- return ret;
-}
-
-/* vif-specifc initialization */
-static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0);
- if (ret < 0)
- return ret;
-
- /* Initialize connection monitoring thresholds */
- ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
- if (ret < 0)
- return ret;
-
- /* Beacon filtering */
- ret = wl1271_init_sta_beacon_filter(wl, wlvif);
- if (ret < 0)
- return ret;
-
- /* Beacons and broadcast settings */
- ret = wl1271_init_beacon_broadcast(wl, wlvif);
- if (ret < 0)
- return ret;
-
- /* Configure rssi/snr averaging weights */
- ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/* vif-specific intialization */
-static int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- ret = wl1271_acx_ap_max_tx_retry(wl, wlvif);
- if (ret < 0)
- return ret;
-
- /* initialize Tx power */
- ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct conf_tx_ac_category *conf_ac;
- struct conf_tx_tid *conf_tid;
- bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
- int ret, i;
-
- /*
- * consider all existing roles before configuring psm.
- * TODO: reconfigure on interface removal.
- */
- if (!wl->ap_count) {
- if (is_ap) {
- /* Configure for power always on */
- ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
- if (ret < 0)
- return ret;
- } else if (!wl->sta_count) {
- /* Configure for ELP power saving */
- ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
- if (ret < 0)
- return ret;
- }
- }
-
- /* Mode specific init */
- if (is_ap) {
- ret = wl1271_ap_hw_init(wl, wlvif);
- if (ret < 0)
- return ret;
-
- ret = wl12xx_init_ap_role(wl, wlvif);
- if (ret < 0)
- return ret;
- } else {
- ret = wl1271_sta_hw_init(wl, wlvif);
- if (ret < 0)
- return ret;
-
- ret = wl12xx_init_sta_role(wl, wlvif);
- if (ret < 0)
- return ret;
- }
-
- wl12xx_init_phy_vif_config(wl, wlvif);
-
- /* Default TID/AC configuration */
- BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
- for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
- conf_ac = &wl->conf.tx.ac_conf[i];
- ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac,
- conf_ac->cw_min, conf_ac->cw_max,
- conf_ac->aifsn, conf_ac->tx_op_limit);
- if (ret < 0)
- return ret;
-
- conf_tid = &wl->conf.tx.tid_conf[i];
- ret = wl1271_acx_tid_cfg(wl, wlvif,
- conf_tid->queue_id,
- conf_tid->channel_type,
- conf_tid->tsid,
- conf_tid->ps_scheme,
- conf_tid->ack_policy,
- conf_tid->apsd_conf[0],
- conf_tid->apsd_conf[1]);
- if (ret < 0)
- return ret;
- }
-
- /* Configure HW encryption */
- ret = wl1271_acx_feature_cfg(wl, wlvif);
- if (ret < 0)
- return ret;
-
- /* Mode specific init - post mem init */
- if (is_ap)
- ret = wl1271_ap_hw_init_post_mem(wl, vif);
- else
- ret = wl1271_sta_hw_init_post_mem(wl, vif);
-
- if (ret < 0)
- return ret;
-
- /* Configure initiator BA sessions policies */
- ret = wl1271_set_ba_policies(wl, wlvif);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1271_hw_init(struct wl1271 *wl)
-{
- int ret;
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- ret = wl128x_cmd_general_parms(wl);
- if (ret < 0)
- return ret;
- ret = wl128x_cmd_radio_parms(wl);
- if (ret < 0)
- return ret;
- } else {
- ret = wl1271_cmd_general_parms(wl);
- if (ret < 0)
- return ret;
- ret = wl1271_cmd_radio_parms(wl);
- if (ret < 0)
- return ret;
- ret = wl1271_cmd_ext_radio_parms(wl);
- if (ret < 0)
- return ret;
- }
-
- /* Chip-specific init */
- ret = wl1271_chip_specific_init(wl);
- if (ret < 0)
- return ret;
-
- /* Init templates */
- ret = wl1271_init_templates_config(wl);
- if (ret < 0)
- return ret;
-
- ret = wl12xx_acx_mem_cfg(wl);
- if (ret < 0)
- return ret;
-
- /* Configure the FW logger */
- ret = wl12xx_init_fwlog(wl);
- if (ret < 0)
- return ret;
-
- /* Bluetooth WLAN coexistence */
- ret = wl1271_init_pta(wl);
- if (ret < 0)
- return ret;
-
- /* Default memory configuration */
- ret = wl1271_acx_init_mem_config(wl);
- if (ret < 0)
- return ret;
-
- /* RX config */
- ret = wl12xx_init_rx_config(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- ret = wl1271_acx_dco_itrim_params(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* Configure TX patch complete interrupt behavior */
- ret = wl1271_acx_tx_config_options(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* RX complete interrupt pacing */
- ret = wl1271_acx_init_rx_interrupt(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* Energy detection */
- ret = wl1271_init_energy_detection(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* Default fragmentation threshold */
- ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
- if (ret < 0)
- goto out_free_memmap;
-
- /* Enable data path */
- ret = wl1271_cmd_data_path(wl, 1);
- if (ret < 0)
- goto out_free_memmap;
-
- /* configure PM */
- ret = wl1271_acx_pm_config(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- ret = wl12xx_acx_set_rate_mgmt_params(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* configure hangover */
- ret = wl12xx_acx_config_hangover(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- return 0;
-
- out_free_memmap:
- kfree(wl->target_mem_map);
- wl->target_mem_map = NULL;
-
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
deleted file mode 100644
index 2da0f404ef6e..000000000000
--- a/drivers/net/wireless/wl12xx/init.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __INIT_H__
-#define __INIT_H__
-
-#include "wl12xx.h"
-
-int wl1271_hw_init_power_auth(struct wl1271 *wl);
-int wl1271_init_templates_config(struct wl1271 *wl);
-int wl1271_init_pta(struct wl1271 *wl);
-int wl1271_init_energy_detection(struct wl1271 *wl);
-int wl1271_chip_specific_init(struct wl1271 *wl);
-int wl1271_hw_init(struct wl1271 *wl);
-int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif);
-int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-int wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c
deleted file mode 100644
index c574a3b31e31..000000000000
--- a/drivers/net/wireless/wl12xx/io.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/interrupt.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "wl12xx_80211.h"
-#include "io.h"
-#include "tx.h"
-
-#define OCP_CMD_LOOP 32
-
-#define OCP_CMD_WRITE 0x1
-#define OCP_CMD_READ 0x2
-
-#define OCP_READY_MASK BIT(18)
-#define OCP_STATUS_MASK (BIT(16) | BIT(17))
-
-#define OCP_STATUS_NO_RESP 0x00000
-#define OCP_STATUS_OK 0x10000
-#define OCP_STATUS_REQ_FAILED 0x20000
-#define OCP_STATUS_RESP_ERROR 0x30000
-
-struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN] = {
- [PART_DOWN] = {
- .mem = {
- .start = 0x00000000,
- .size = 0x000177c0
- },
- .reg = {
- .start = REGISTERS_BASE,
- .size = 0x00008800
- },
- .mem2 = {
- .start = 0x00000000,
- .size = 0x00000000
- },
- .mem3 = {
- .start = 0x00000000,
- .size = 0x00000000
- },
- },
-
- [PART_WORK] = {
- .mem = {
- .start = 0x00040000,
- .size = 0x00014fc0
- },
- .reg = {
- .start = REGISTERS_BASE,
- .size = 0x0000a000
- },
- .mem2 = {
- .start = 0x003004f8,
- .size = 0x00000004
- },
- .mem3 = {
- .start = 0x00040404,
- .size = 0x00000000
- },
- },
-
- [PART_DRPW] = {
- .mem = {
- .start = 0x00040000,
- .size = 0x00014fc0
- },
- .reg = {
- .start = DRPW_BASE,
- .size = 0x00006000
- },
- .mem2 = {
- .start = 0x00000000,
- .size = 0x00000000
- },
- .mem3 = {
- .start = 0x00000000,
- .size = 0x00000000
- }
- }
-};
-
-bool wl1271_set_block_size(struct wl1271 *wl)
-{
- if (wl->if_ops->set_block_size) {
- wl->if_ops->set_block_size(wl->dev, WL12XX_BUS_BLOCK_SIZE);
- return true;
- }
-
- return false;
-}
-
-void wl1271_disable_interrupts(struct wl1271 *wl)
-{
- disable_irq(wl->irq);
-}
-
-void wl1271_enable_interrupts(struct wl1271 *wl)
-{
- enable_irq(wl->irq);
-}
-
-/* Set the SPI partitions to access the chip addresses
- *
- * To simplify driver code, a fixed (virtual) memory map is defined for
- * register and memory addresses. Because in the chipset, in different stages
- * of operation, those addresses will move around, an address translation
- * mechanism is required.
- *
- * There are four partitions (three memory and one register partition),
- * which are mapped to two different areas of the hardware memory.
- *
- * Virtual address
- * space
- *
- * | |
- * ...+----+--> mem.start
- * Physical address ... | |
- * space ... | | [PART_0]
- * ... | |
- * 00000000 <--+----+... ...+----+--> mem.start + mem.size
- * | | ... | |
- * |MEM | ... | |
- * | | ... | |
- * mem.size <--+----+... | | {unused area)
- * | | ... | |
- * |REG | ... | |
- * mem.size | | ... | |
- * + <--+----+... ...+----+--> reg.start
- * reg.size | | ... | |
- * |MEM2| ... | | [PART_1]
- * | | ... | |
- * ...+----+--> reg.start + reg.size
- * | |
- *
- */
-int wl1271_set_partition(struct wl1271 *wl,
- struct wl1271_partition_set *p)
-{
- /* copy partition info */
- memcpy(&wl->part, p, sizeof(*p));
-
- wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- p->mem.start, p->mem.size);
- wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
- p->reg.start, p->reg.size);
- wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
- p->mem2.start, p->mem2.size);
- wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
- p->mem3.start, p->mem3.size);
-
- /* write partition info to the chipset */
- wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
- wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
- wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
- wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
- wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
- wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
- wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wl1271_set_partition);
-
-void wl1271_io_reset(struct wl1271 *wl)
-{
- if (wl->if_ops->reset)
- wl->if_ops->reset(wl->dev);
-}
-
-void wl1271_io_init(struct wl1271 *wl)
-{
- if (wl->if_ops->init)
- wl->if_ops->init(wl->dev);
-}
-
-void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
-{
- /* write address >> 1 + 0x30000 to OCP_POR_CTR */
- addr = (addr >> 1) + 0x30000;
- wl1271_write32(wl, OCP_POR_CTR, addr);
-
- /* write value to OCP_POR_WDATA */
- wl1271_write32(wl, OCP_DATA_WRITE, val);
-
- /* write 1 to OCP_CMD */
- wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE);
-}
-
-u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
-{
- u32 val;
- int timeout = OCP_CMD_LOOP;
-
- /* write address >> 1 + 0x30000 to OCP_POR_CTR */
- addr = (addr >> 1) + 0x30000;
- wl1271_write32(wl, OCP_POR_CTR, addr);
-
- /* write 2 to OCP_CMD */
- wl1271_write32(wl, OCP_CMD, OCP_CMD_READ);
-
- /* poll for data ready */
- do {
- val = wl1271_read32(wl, OCP_DATA_READ);
- } while (!(val & OCP_READY_MASK) && --timeout);
-
- if (!timeout) {
- wl1271_warning("Top register access timed out.");
- return 0xffff;
- }
-
- /* check data status and return if OK */
- if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
- return val & 0xffff;
- else {
- wl1271_warning("Top register access returned error.");
- return 0xffff;
- }
-}
-
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h
deleted file mode 100644
index 4fb3dab8c3b2..000000000000
--- a/drivers/net/wireless/wl12xx/io.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __IO_H__
-#define __IO_H__
-
-#include <linux/irqreturn.h>
-#include "reg.h"
-
-#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
-
-#define HW_PARTITION_REGISTERS_ADDR 0x1FFC0
-#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR)
-#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4)
-#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8)
-#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
-#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
-#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
-#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
-
-#define HW_ACCESS_REGISTER_SIZE 4
-
-#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
-
-extern struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN];
-
-struct wl1271;
-
-void wl1271_disable_interrupts(struct wl1271 *wl);
-void wl1271_enable_interrupts(struct wl1271 *wl);
-
-void wl1271_io_reset(struct wl1271 *wl);
-void wl1271_io_init(struct wl1271 *wl);
-
-/* Raw target IO, address is not translated */
-static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
- size_t len, bool fixed)
-{
- wl->if_ops->write(wl->dev, addr, buf, len, fixed);
-}
-
-static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
- size_t len, bool fixed)
-{
- wl->if_ops->read(wl->dev, addr, buf, len, fixed);
-}
-
-static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
-{
- wl1271_raw_read(wl, addr, &wl->buffer_32,
- sizeof(wl->buffer_32), false);
-
- return le32_to_cpu(wl->buffer_32);
-}
-
-static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
-{
- wl->buffer_32 = cpu_to_le32(val);
- wl1271_raw_write(wl, addr, &wl->buffer_32,
- sizeof(wl->buffer_32), false);
-}
-
-/* Translated target IO */
-static inline int wl1271_translate_addr(struct wl1271 *wl, int addr)
-{
- /*
- * To translate, first check to which window of addresses the
- * particular address belongs. Then subtract the starting address
- * of that window from the address. Then, add offset of the
- * translated region.
- *
- * The translated regions occur next to each other in physical device
- * memory, so just add the sizes of the preceding address regions to
- * get the offset to the new region.
- *
- * Currently, only the two first regions are addressed, and the
- * assumption is that all addresses will fall into either of those
- * two.
- */
- if ((addr >= wl->part.reg.start) &&
- (addr < wl->part.reg.start + wl->part.reg.size))
- return addr - wl->part.reg.start + wl->part.mem.size;
- else
- return addr - wl->part.mem.start;
-}
-
-static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf,
- size_t len, bool fixed)
-{
- int physical;
-
- physical = wl1271_translate_addr(wl, addr);
-
- wl1271_raw_read(wl, physical, buf, len, fixed);
-}
-
-static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf,
- size_t len, bool fixed)
-{
- int physical;
-
- physical = wl1271_translate_addr(wl, addr);
-
- wl1271_raw_write(wl, physical, buf, len, fixed);
-}
-
-static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr,
- void *buf, size_t len, bool fixed)
-{
- int physical;
- int addr;
-
- /* Addresses are stored internally as addresses to 32 bytes blocks */
- addr = hwaddr << 5;
-
- physical = wl1271_translate_addr(wl, addr);
-
- wl1271_raw_read(wl, physical, buf, len, fixed);
-}
-
-static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
-{
- return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
-}
-
-static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
-{
- wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
-}
-
-static inline void wl1271_power_off(struct wl1271 *wl)
-{
- wl->if_ops->power(wl->dev, false);
- clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
-}
-
-static inline int wl1271_power_on(struct wl1271 *wl)
-{
- int ret = wl->if_ops->power(wl->dev, true);
- if (ret == 0)
- set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
-
- return ret;
-}
-
-
-/* Top Register IO */
-void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
-u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
-
-int wl1271_set_partition(struct wl1271 *wl,
- struct wl1271_partition_set *p);
-
-bool wl1271_set_block_size(struct wl1271 *wl);
-
-/* Functions from wl1271_main.c */
-
-int wl1271_tx_dummy_packet(struct wl1271 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
deleted file mode 100644
index 96ca25a92b76..000000000000
--- a/drivers/net/wireless/wl12xx/main.c
+++ /dev/null
@@ -1,5633 +0,0 @@
-
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/spi/spi.h>
-#include <linux/crc32.h>
-#include <linux/etherdevice.h>
-#include <linux/vmalloc.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/wl12xx.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "wl12xx_80211.h"
-#include "reg.h"
-#include "io.h"
-#include "event.h"
-#include "tx.h"
-#include "rx.h"
-#include "ps.h"
-#include "init.h"
-#include "debugfs.h"
-#include "cmd.h"
-#include "boot.h"
-#include "testmode.h"
-#include "scan.h"
-
-#define WL1271_BOOT_RETRIES 3
-
-static struct conf_drv_settings default_conf = {
- .sg = {
- .params = {
- [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
- [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
- [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
- [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
- [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
- [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
- [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
- [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
- [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
- [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
- [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
- [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
- [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
- [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
- [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
- [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
- [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
- [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
- [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
- [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
- [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
- [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
- [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
- [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
- [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
- [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
- /* active scan params */
- [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
- [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
- [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
- /* passive scan params */
- [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
- [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
- [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
- /* passive scan in dual antenna params */
- [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
- [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
- [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
- /* general params */
- [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
- [CONF_SG_ANTENNA_CONFIGURATION] = 0,
- [CONF_SG_BEACON_MISS_PERCENT] = 60,
- [CONF_SG_DHCP_TIME] = 5000,
- [CONF_SG_RXT] = 1200,
- [CONF_SG_TXT] = 1000,
- [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
- [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
- [CONF_SG_HV3_MAX_SERVED] = 6,
- [CONF_SG_PS_POLL_TIMEOUT] = 10,
- [CONF_SG_UPSD_TIMEOUT] = 10,
- [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
- [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
- [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
- /* AP params */
- [CONF_AP_BEACON_MISS_TX] = 3,
- [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
- [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
- [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
- [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
- [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
- /* CTS Diluting params */
- [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
- [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
- },
- .state = CONF_SG_PROTECTIVE,
- },
- .rx = {
- .rx_msdu_life_time = 512000,
- .packet_detection_threshold = 0,
- .ps_poll_timeout = 15,
- .upsd_timeout = 15,
- .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
- .rx_cca_threshold = 0,
- .irq_blk_threshold = 0xFFFF,
- .irq_pkt_threshold = 0,
- .irq_timeout = 600,
- .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
- },
- .tx = {
- .tx_energy_detection = 0,
- .sta_rc_conf = {
- .enabled_rates = 0,
- .short_retry_limit = 10,
- .long_retry_limit = 10,
- .aflags = 0,
- },
- .ac_conf_count = 4,
- .ac_conf = {
- [CONF_TX_AC_BE] = {
- .ac = CONF_TX_AC_BE,
- .cw_min = 15,
- .cw_max = 63,
- .aifsn = 3,
- .tx_op_limit = 0,
- },
- [CONF_TX_AC_BK] = {
- .ac = CONF_TX_AC_BK,
- .cw_min = 15,
- .cw_max = 63,
- .aifsn = 7,
- .tx_op_limit = 0,
- },
- [CONF_TX_AC_VI] = {
- .ac = CONF_TX_AC_VI,
- .cw_min = 15,
- .cw_max = 63,
- .aifsn = CONF_TX_AIFS_PIFS,
- .tx_op_limit = 3008,
- },
- [CONF_TX_AC_VO] = {
- .ac = CONF_TX_AC_VO,
- .cw_min = 15,
- .cw_max = 63,
- .aifsn = CONF_TX_AIFS_PIFS,
- .tx_op_limit = 1504,
- },
- },
- .max_tx_retries = 100,
- .ap_aging_period = 300,
- .tid_conf_count = 4,
- .tid_conf = {
- [CONF_TX_AC_BE] = {
- .queue_id = CONF_TX_AC_BE,
- .channel_type = CONF_CHANNEL_TYPE_EDCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [CONF_TX_AC_BK] = {
- .queue_id = CONF_TX_AC_BK,
- .channel_type = CONF_CHANNEL_TYPE_EDCF,
- .tsid = CONF_TX_AC_BK,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [CONF_TX_AC_VI] = {
- .queue_id = CONF_TX_AC_VI,
- .channel_type = CONF_CHANNEL_TYPE_EDCF,
- .tsid = CONF_TX_AC_VI,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [CONF_TX_AC_VO] = {
- .queue_id = CONF_TX_AC_VO,
- .channel_type = CONF_CHANNEL_TYPE_EDCF,
- .tsid = CONF_TX_AC_VO,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- },
- .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
- .tx_compl_timeout = 700,
- .tx_compl_threshold = 4,
- .basic_rate = CONF_HW_BIT_RATE_1MBPS,
- .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
- .tmpl_short_retry_limit = 10,
- .tmpl_long_retry_limit = 10,
- .tx_watchdog_timeout = 5000,
- },
- .conn = {
- .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
- .listen_interval = 1,
- .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
- .suspend_listen_interval = 3,
- .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
- .bcn_filt_ie_count = 2,
- .bcn_filt_ie = {
- [0] = {
- .ie = WLAN_EID_CHANNEL_SWITCH,
- .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
- },
- [1] = {
- .ie = WLAN_EID_HT_OPERATION,
- .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
- },
- },
- .synch_fail_thold = 10,
- .bss_lose_timeout = 100,
- .beacon_rx_timeout = 10000,
- .broadcast_timeout = 20000,
- .rx_broadcast_in_ps = 1,
- .ps_poll_threshold = 10,
- .bet_enable = CONF_BET_MODE_ENABLE,
- .bet_max_consecutive = 50,
- .psm_entry_retries = 8,
- .psm_exit_retries = 16,
- .psm_entry_nullfunc_retries = 3,
- .dynamic_ps_timeout = 200,
- .forced_ps = false,
- .keep_alive_interval = 55000,
- .max_listen_interval = 20,
- },
- .itrim = {
- .enable = false,
- .timeout = 50000,
- },
- .pm_config = {
- .host_clk_settling_time = 5000,
- .host_fast_wakeup_support = false
- },
- .roam_trigger = {
- .trigger_pacing = 1,
- .avg_weight_rssi_beacon = 20,
- .avg_weight_rssi_data = 10,
- .avg_weight_snr_beacon = 20,
- .avg_weight_snr_data = 10,
- },
- .scan = {
- .min_dwell_time_active = 7500,
- .max_dwell_time_active = 30000,
- .min_dwell_time_passive = 100000,
- .max_dwell_time_passive = 100000,
- .num_probe_reqs = 2,
- .split_scan_timeout = 50000,
- },
- .sched_scan = {
- /*
- * Values are in TU/1000 but since sched scan FW command
- * params are in TUs rounding up may occur.
- */
- .base_dwell_time = 7500,
- .max_dwell_time_delta = 22500,
- /* based on 250bits per probe @1Mbps */
- .dwell_time_delta_per_probe = 2000,
- /* based on 250bits per probe @6Mbps (plus a bit more) */
- .dwell_time_delta_per_probe_5 = 350,
- .dwell_time_passive = 100000,
- .dwell_time_dfs = 150000,
- .num_probe_reqs = 2,
- .rssi_threshold = -90,
- .snr_threshold = 0,
- },
- .rf = {
- .tx_per_channel_power_compensation_2 = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- },
- .tx_per_channel_power_compensation_5 = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- },
- },
- .ht = {
- .rx_ba_win_size = 8,
- .tx_ba_win_size = 64,
- .inactivity_timeout = 10000,
- .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
- },
- .mem_wl127x = {
- .num_stations = 1,
- .ssid_profiles = 1,
- .rx_block_num = 70,
- .tx_min_block_num = 40,
- .dynamic_memory = 1,
- .min_req_tx_blocks = 100,
- .min_req_rx_blocks = 22,
- .tx_min = 27,
- },
- .mem_wl128x = {
- .num_stations = 1,
- .ssid_profiles = 1,
- .rx_block_num = 40,
- .tx_min_block_num = 40,
- .dynamic_memory = 1,
- .min_req_tx_blocks = 45,
- .min_req_rx_blocks = 22,
- .tx_min = 27,
- },
- .fm_coex = {
- .enable = true,
- .swallow_period = 5,
- .n_divider_fref_set_1 = 0xff, /* default */
- .n_divider_fref_set_2 = 12,
- .m_divider_fref_set_1 = 148,
- .m_divider_fref_set_2 = 0xffff, /* default */
- .coex_pll_stabilization_time = 0xffffffff, /* default */
- .ldo_stabilization_time = 0xffff, /* default */
- .fm_disturbed_band_margin = 0xff, /* default */
- .swallow_clk_diff = 0xff, /* default */
- },
- .rx_streaming = {
- .duration = 150,
- .queues = 0x1,
- .interval = 20,
- .always = 0,
- },
- .fwlog = {
- .mode = WL12XX_FWLOG_ON_DEMAND,
- .mem_blocks = 2,
- .severity = 0,
- .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
- .output = WL12XX_FWLOG_OUTPUT_HOST,
- .threshold = 0,
- },
- .hci_io_ds = HCI_IO_DS_6MA,
- .rate = {
- .rate_retry_score = 32000,
- .per_add = 8192,
- .per_th1 = 2048,
- .per_th2 = 4096,
- .max_per = 8100,
- .inverse_curiosity_factor = 5,
- .tx_fail_low_th = 4,
- .tx_fail_high_th = 10,
- .per_alpha_shift = 4,
- .per_add_shift = 13,
- .per_beta1_shift = 10,
- .per_beta2_shift = 8,
- .rate_check_up = 2,
- .rate_check_down = 12,
- .rate_retry_policy = {
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- },
- },
- .hangover = {
- .recover_time = 0,
- .hangover_period = 20,
- .dynamic_mode = 1,
- .early_termination_mode = 1,
- .max_period = 20,
- .min_period = 1,
- .increase_delta = 1,
- .decrease_delta = 2,
- .quiet_time = 4,
- .increase_time = 1,
- .window_size = 16,
- },
-};
-
-static char *fwlog_param;
-static bool bug_on_recovery;
-
-static void __wl1271_op_remove_interface(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- bool reset_tx_queues);
-static void wl1271_op_stop(struct ieee80211_hw *hw);
-static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-
-static int wl12xx_set_authorized(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret;
-
- if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
- return -EINVAL;
-
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- return 0;
-
- if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
- return 0;
-
- ret = wl12xx_cmd_set_peer_state(wl, wlvif->sta.hlid);
- if (ret < 0)
- return ret;
-
- wl12xx_croc(wl, wlvif->role_id);
-
- wl1271_info("Association completed.");
- return 0;
-}
-
-static int wl1271_reg_notify(struct wiphy *wiphy,
- struct regulatory_request *request)
-{
- struct ieee80211_supported_band *band;
- struct ieee80211_channel *ch;
- int i;
-
- band = wiphy->bands[IEEE80211_BAND_5GHZ];
- for (i = 0; i < band->n_channels; i++) {
- ch = &band->channels[i];
- if (ch->flags & IEEE80211_CHAN_DISABLED)
- continue;
-
- if (ch->flags & IEEE80211_CHAN_RADAR)
- ch->flags |= IEEE80211_CHAN_NO_IBSS |
- IEEE80211_CHAN_PASSIVE_SCAN;
-
- }
-
- return 0;
-}
-
-static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool enable)
-{
- int ret = 0;
-
- /* we should hold wl->mutex */
- ret = wl1271_acx_ps_rx_streaming(wl, wlvif, enable);
- if (ret < 0)
- goto out;
-
- if (enable)
- set_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags);
- else
- clear_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags);
-out:
- return ret;
-}
-
-/*
- * this function is being called when the rx_streaming interval
- * has beed changed or rx_streaming should be disabled
- */
-int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret = 0;
- int period = wl->conf.rx_streaming.interval;
-
- /* don't reconfigure if rx_streaming is disabled */
- if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
- goto out;
-
- /* reconfigure/disable according to new streaming_period */
- if (period &&
- test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
- (wl->conf.rx_streaming.always ||
- test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
- ret = wl1271_set_rx_streaming(wl, wlvif, true);
- else {
- ret = wl1271_set_rx_streaming(wl, wlvif, false);
- /* don't cancel_work_sync since we might deadlock */
- del_timer_sync(&wlvif->rx_streaming_timer);
- }
-out:
- return ret;
-}
-
-static void wl1271_rx_streaming_enable_work(struct work_struct *work)
-{
- int ret;
- struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
- rx_streaming_enable_work);
- struct wl1271 *wl = wlvif->wl;
-
- mutex_lock(&wl->mutex);
-
- if (test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags) ||
- !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
- (!wl->conf.rx_streaming.always &&
- !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
- goto out;
-
- if (!wl->conf.rx_streaming.interval)
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_set_rx_streaming(wl, wlvif, true);
- if (ret < 0)
- goto out_sleep;
-
- /* stop it after some time of inactivity */
- mod_timer(&wlvif->rx_streaming_timer,
- jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration));
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static void wl1271_rx_streaming_disable_work(struct work_struct *work)
-{
- int ret;
- struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
- rx_streaming_disable_work);
- struct wl1271 *wl = wlvif->wl;
-
- mutex_lock(&wl->mutex);
-
- if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_set_rx_streaming(wl, wlvif, false);
- if (ret)
- goto out_sleep;
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static void wl1271_rx_streaming_timer(unsigned long data)
-{
- struct wl12xx_vif *wlvif = (struct wl12xx_vif *)data;
- struct wl1271 *wl = wlvif->wl;
- ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work);
-}
-
-/* wl->mutex must be taken */
-void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
-{
- /* if the watchdog is not armed, don't do anything */
- if (wl->tx_allocated_blocks == 0)
- return;
-
- cancel_delayed_work(&wl->tx_watchdog_work);
- ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work,
- msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
-}
-
-static void wl12xx_tx_watchdog_work(struct work_struct *work)
-{
- struct delayed_work *dwork;
- struct wl1271 *wl;
-
- dwork = container_of(work, struct delayed_work, work);
- wl = container_of(dwork, struct wl1271, tx_watchdog_work);
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- /* Tx went out in the meantime - everything is ok */
- if (unlikely(wl->tx_allocated_blocks == 0))
- goto out;
-
- /*
- * if a ROC is in progress, we might not have any Tx for a long
- * time (e.g. pending Tx on the non-ROC channels)
- */
- if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
- wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC",
- wl->conf.tx.tx_watchdog_timeout);
- wl12xx_rearm_tx_watchdog_locked(wl);
- goto out;
- }
-
- /*
- * if a scan is in progress, we might not have any Tx for a long
- * time
- */
- if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
- wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan",
- wl->conf.tx.tx_watchdog_timeout);
- wl12xx_rearm_tx_watchdog_locked(wl);
- goto out;
- }
-
- /*
- * AP might cache a frame for a long time for a sleeping station,
- * so rearm the timer if there's an AP interface with stations. If
- * Tx is genuinely stuck we will most hopefully discover it when all
- * stations are removed due to inactivity.
- */
- if (wl->active_sta_count) {
- wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has "
- " %d stations",
- wl->conf.tx.tx_watchdog_timeout,
- wl->active_sta_count);
- wl12xx_rearm_tx_watchdog_locked(wl);
- goto out;
- }
-
- wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery",
- wl->conf.tx.tx_watchdog_timeout);
- wl12xx_queue_recovery_work(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static void wl1271_conf_init(struct wl1271 *wl)
-{
-
- /*
- * This function applies the default configuration to the driver. This
- * function is invoked upon driver load (spi probe.)
- *
- * The configuration is stored in a run-time structure in order to
- * facilitate for run-time adjustment of any of the parameters. Making
- * changes to the configuration structure will apply the new values on
- * the next interface up (wl1271_op_start.)
- */
-
- /* apply driver default configuration */
- memcpy(&wl->conf, &default_conf, sizeof(default_conf));
-
- /* Adjust settings according to optional module parameters */
- if (fwlog_param) {
- if (!strcmp(fwlog_param, "continuous")) {
- wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
- } else if (!strcmp(fwlog_param, "ondemand")) {
- wl->conf.fwlog.mode = WL12XX_FWLOG_ON_DEMAND;
- } else if (!strcmp(fwlog_param, "dbgpins")) {
- wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
- wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_DBG_PINS;
- } else if (!strcmp(fwlog_param, "disable")) {
- wl->conf.fwlog.mem_blocks = 0;
- wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_NONE;
- } else {
- wl1271_error("Unknown fwlog parameter %s", fwlog_param);
- }
- }
-}
-
-static int wl1271_plt_init(struct wl1271 *wl)
-{
- int ret;
-
- if (wl->chip.id == CHIP_ID_1283_PG20)
- ret = wl128x_cmd_general_parms(wl);
- else
- ret = wl1271_cmd_general_parms(wl);
- if (ret < 0)
- return ret;
-
- if (wl->chip.id == CHIP_ID_1283_PG20)
- ret = wl128x_cmd_radio_parms(wl);
- else
- ret = wl1271_cmd_radio_parms(wl);
- if (ret < 0)
- return ret;
-
- if (wl->chip.id != CHIP_ID_1283_PG20) {
- ret = wl1271_cmd_ext_radio_parms(wl);
- if (ret < 0)
- return ret;
- }
-
- /* Chip-specific initializations */
- ret = wl1271_chip_specific_init(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_init_mem_config(wl);
- if (ret < 0)
- return ret;
-
- ret = wl12xx_acx_mem_cfg(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* Enable data path */
- ret = wl1271_cmd_data_path(wl, 1);
- if (ret < 0)
- goto out_free_memmap;
-
- /* Configure for CAM power saving (ie. always active) */
- ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
- if (ret < 0)
- goto out_free_memmap;
-
- /* configure PM */
- ret = wl1271_acx_pm_config(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- return 0;
-
- out_free_memmap:
- kfree(wl->target_mem_map);
- wl->target_mem_map = NULL;
-
- return ret;
-}
-
-static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- u8 hlid, u8 tx_pkts)
-{
- bool fw_ps, single_sta;
-
- fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
- single_sta = (wl->active_sta_count == 1);
-
- /*
- * Wake up from high level PS if the STA is asleep with too little
- * packets in FW or if the STA is awake.
- */
- if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS)
- wl12xx_ps_link_end(wl, wlvif, hlid);
-
- /*
- * Start high-level PS if the STA is asleep with enough blocks in FW.
- * Make an exception if this is the only connected station. In this
- * case FW-memory congestion is not a problem.
- */
- else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
- wl12xx_ps_link_start(wl, wlvif, hlid, true);
-}
-
-static void wl12xx_irq_update_links_status(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct wl12xx_fw_status *status)
-{
- struct wl1271_link *lnk;
- u32 cur_fw_ps_map;
- u8 hlid, cnt;
-
- /* TODO: also use link_fast_bitmap here */
-
- cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
- if (wl->ap_fw_ps_map != cur_fw_ps_map) {
- wl1271_debug(DEBUG_PSM,
- "link ps prev 0x%x cur 0x%x changed 0x%x",
- wl->ap_fw_ps_map, cur_fw_ps_map,
- wl->ap_fw_ps_map ^ cur_fw_ps_map);
-
- wl->ap_fw_ps_map = cur_fw_ps_map;
- }
-
- for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) {
- lnk = &wl->links[hlid];
- cnt = status->tx_lnk_free_pkts[hlid] - lnk->prev_freed_pkts;
-
- lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid];
- lnk->allocated_pkts -= cnt;
-
- wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
- lnk->allocated_pkts);
- }
-}
-
-static void wl12xx_fw_status(struct wl1271 *wl,
- struct wl12xx_fw_status *status)
-{
- struct wl12xx_vif *wlvif;
- struct timespec ts;
- u32 old_tx_blk_count = wl->tx_blocks_available;
- int avail, freed_blocks;
- int i;
-
- wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
-
- wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
- "drv_rx_counter = %d, tx_results_counter = %d)",
- status->intr,
- status->fw_rx_counter,
- status->drv_rx_counter,
- status->tx_results_counter);
-
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- /* prevent wrap-around in freed-packets counter */
- wl->tx_allocated_pkts[i] -=
- (status->tx_released_pkts[i] -
- wl->tx_pkts_freed[i]) & 0xff;
-
- wl->tx_pkts_freed[i] = status->tx_released_pkts[i];
- }
-
- /* prevent wrap-around in total blocks counter */
- if (likely(wl->tx_blocks_freed <=
- le32_to_cpu(status->total_released_blks)))
- freed_blocks = le32_to_cpu(status->total_released_blks) -
- wl->tx_blocks_freed;
- else
- freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
- le32_to_cpu(status->total_released_blks);
-
- wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
-
- wl->tx_allocated_blocks -= freed_blocks;
-
- /*
- * If the FW freed some blocks:
- * If we still have allocated blocks - re-arm the timer, Tx is
- * not stuck. Otherwise, cancel the timer (no Tx currently).
- */
- if (freed_blocks) {
- if (wl->tx_allocated_blocks)
- wl12xx_rearm_tx_watchdog_locked(wl);
- else
- cancel_delayed_work(&wl->tx_watchdog_work);
- }
-
- avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
-
- /*
- * The FW might change the total number of TX memblocks before
- * we get a notification about blocks being released. Thus, the
- * available blocks calculation might yield a temporary result
- * which is lower than the actual available blocks. Keeping in
- * mind that only blocks that were allocated can be moved from
- * TX to RX, tx_blocks_available should never decrease here.
- */
- wl->tx_blocks_available = max((int)wl->tx_blocks_available,
- avail);
-
- /* if more blocks are available now, tx work can be scheduled */
- if (wl->tx_blocks_available > old_tx_blk_count)
- clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
-
- /* for AP update num of allocated TX blocks per link and ps status */
- wl12xx_for_each_wlvif_ap(wl, wlvif) {
- wl12xx_irq_update_links_status(wl, wlvif, status);
- }
-
- /* update the host-chipset time offset */
- getnstimeofday(&ts);
- wl->time_offset = (timespec_to_ns(&ts) >> 10) -
- (s64)le32_to_cpu(status->fw_localtime);
-}
-
-static void wl1271_flush_deferred_work(struct wl1271 *wl)
-{
- struct sk_buff *skb;
-
- /* Pass all received frames to the network stack */
- while ((skb = skb_dequeue(&wl->deferred_rx_queue)))
- ieee80211_rx_ni(wl->hw, skb);
-
- /* Return sent skbs to the network stack */
- while ((skb = skb_dequeue(&wl->deferred_tx_queue)))
- ieee80211_tx_status_ni(wl->hw, skb);
-}
-
-static void wl1271_netstack_work(struct work_struct *work)
-{
- struct wl1271 *wl =
- container_of(work, struct wl1271, netstack_work);
-
- do {
- wl1271_flush_deferred_work(wl);
- } while (skb_queue_len(&wl->deferred_rx_queue));
-}
-
-#define WL1271_IRQ_MAX_LOOPS 256
-
-static irqreturn_t wl1271_irq(int irq, void *cookie)
-{
- int ret;
- u32 intr;
- int loopcount = WL1271_IRQ_MAX_LOOPS;
- struct wl1271 *wl = (struct wl1271 *)cookie;
- bool done = false;
- unsigned int defer_count;
- unsigned long flags;
-
- /* TX might be handled here, avoid redundant work */
- set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
- cancel_work_sync(&wl->tx_work);
-
- /*
- * In case edge triggered interrupt must be used, we cannot iterate
- * more than once without introducing race conditions with the hardirq.
- */
- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
- loopcount = 1;
-
- mutex_lock(&wl->mutex);
-
- wl1271_debug(DEBUG_IRQ, "IRQ work");
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- while (!done && loopcount--) {
- /*
- * In order to avoid a race with the hardirq, clear the flag
- * before acknowledging the chip. Since the mutex is held,
- * wl1271_ps_elp_wakeup cannot be called concurrently.
- */
- clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
- smp_mb__after_clear_bit();
-
- wl12xx_fw_status(wl, wl->fw_status);
- intr = le32_to_cpu(wl->fw_status->intr);
- intr &= WL1271_INTR_MASK;
- if (!intr) {
- done = true;
- continue;
- }
-
- if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
- wl1271_error("watchdog interrupt received! "
- "starting recovery.");
- wl12xx_queue_recovery_work(wl);
-
- /* restarting the chip. ignore any other interrupt. */
- goto out;
- }
-
- if (likely(intr & WL1271_ACX_INTR_DATA)) {
- wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
-
- wl12xx_rx(wl, wl->fw_status);
-
- /* Check if any tx blocks were freed */
- spin_lock_irqsave(&wl->wl_lock, flags);
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
- wl1271_tx_total_queue_count(wl) > 0) {
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- /*
- * In order to avoid starvation of the TX path,
- * call the work function directly.
- */
- wl1271_tx_work_locked(wl);
- } else {
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- }
-
- /* check for tx results */
- if (wl->fw_status->tx_results_counter !=
- (wl->tx_results_count & 0xff))
- wl1271_tx_complete(wl);
-
- /* Make sure the deferred queues don't get too long */
- defer_count = skb_queue_len(&wl->deferred_tx_queue) +
- skb_queue_len(&wl->deferred_rx_queue);
- if (defer_count > WL1271_DEFERRED_QUEUE_LIMIT)
- wl1271_flush_deferred_work(wl);
- }
-
- if (intr & WL1271_ACX_INTR_EVENT_A) {
- wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
- wl1271_event_handle(wl, 0);
- }
-
- if (intr & WL1271_ACX_INTR_EVENT_B) {
- wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
- wl1271_event_handle(wl, 1);
- }
-
- if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
- wl1271_debug(DEBUG_IRQ,
- "WL1271_ACX_INTR_INIT_COMPLETE");
-
- if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
- wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- spin_lock_irqsave(&wl->wl_lock, flags);
- /* In case TX was not handled here, queue TX work */
- clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
- wl1271_tx_total_queue_count(wl) > 0)
- ieee80211_queue_work(wl->hw, &wl->tx_work);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- mutex_unlock(&wl->mutex);
-
- return IRQ_HANDLED;
-}
-
-struct vif_counter_data {
- u8 counter;
-
- struct ieee80211_vif *cur_vif;
- bool cur_vif_running;
-};
-
-static void wl12xx_vif_count_iter(void *data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct vif_counter_data *counter = data;
-
- counter->counter++;
- if (counter->cur_vif == vif)
- counter->cur_vif_running = true;
-}
-
-/* caller must not hold wl->mutex, as it might deadlock */
-static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
- struct ieee80211_vif *cur_vif,
- struct vif_counter_data *data)
-{
- memset(data, 0, sizeof(*data));
- data->cur_vif = cur_vif;
-
- ieee80211_iterate_active_interfaces(hw,
- wl12xx_vif_count_iter, data);
-}
-
-static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
-{
- const struct firmware *fw;
- const char *fw_name;
- enum wl12xx_fw_type fw_type;
- int ret;
-
- if (plt) {
- fw_type = WL12XX_FW_TYPE_PLT;
- if (wl->chip.id == CHIP_ID_1283_PG20)
- fw_name = WL128X_PLT_FW_NAME;
- else
- fw_name = WL127X_PLT_FW_NAME;
- } else {
- /*
- * we can't call wl12xx_get_vif_count() here because
- * wl->mutex is taken, so use the cached last_vif_count value
- */
- if (wl->last_vif_count > 1) {
- fw_type = WL12XX_FW_TYPE_MULTI;
- if (wl->chip.id == CHIP_ID_1283_PG20)
- fw_name = WL128X_FW_NAME_MULTI;
- else
- fw_name = WL127X_FW_NAME_MULTI;
- } else {
- fw_type = WL12XX_FW_TYPE_NORMAL;
- if (wl->chip.id == CHIP_ID_1283_PG20)
- fw_name = WL128X_FW_NAME_SINGLE;
- else
- fw_name = WL127X_FW_NAME_SINGLE;
- }
- }
-
- if (wl->fw_type == fw_type)
- return 0;
-
- wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);
-
- ret = request_firmware(&fw, fw_name, wl->dev);
-
- if (ret < 0) {
- wl1271_error("could not get firmware %s: %d", fw_name, ret);
- return ret;
- }
-
- if (fw->size % 4) {
- wl1271_error("firmware size is not multiple of 32 bits: %zu",
- fw->size);
- ret = -EILSEQ;
- goto out;
- }
-
- vfree(wl->fw);
- wl->fw_type = WL12XX_FW_TYPE_NONE;
- wl->fw_len = fw->size;
- wl->fw = vmalloc(wl->fw_len);
-
- if (!wl->fw) {
- wl1271_error("could not allocate memory for the firmware");
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(wl->fw, fw->data, wl->fw_len);
- ret = 0;
- wl->fw_type = fw_type;
-out:
- release_firmware(fw);
-
- return ret;
-}
-
-static int wl1271_fetch_nvs(struct wl1271 *wl)
-{
- const struct firmware *fw;
- int ret;
-
- ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev);
-
- if (ret < 0) {
- wl1271_error("could not get nvs file %s: %d", WL12XX_NVS_NAME,
- ret);
- return ret;
- }
-
- wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
-
- if (!wl->nvs) {
- wl1271_error("could not allocate memory for the nvs file");
- ret = -ENOMEM;
- goto out;
- }
-
- wl->nvs_len = fw->size;
-
-out:
- release_firmware(fw);
-
- return ret;
-}
-
-void wl12xx_queue_recovery_work(struct wl1271 *wl)
-{
- if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
- ieee80211_queue_work(wl->hw, &wl->recovery_work);
-}
-
-size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
-{
- size_t len = 0;
-
- /* The FW log is a length-value list, find where the log end */
- while (len < maxlen) {
- if (memblock[len] == 0)
- break;
- if (len + memblock[len] + 1 > maxlen)
- break;
- len += memblock[len] + 1;
- }
-
- /* Make sure we have enough room */
- len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size));
-
- /* Fill the FW log file, consumed by the sysfs fwlog entry */
- memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
- wl->fwlog_size += len;
-
- return len;
-}
-
-static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
-{
- u32 addr;
- u32 first_addr;
- u8 *block;
-
- if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
- (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
- (wl->conf.fwlog.mem_blocks == 0))
- return;
-
- wl1271_info("Reading FW panic log");
-
- block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL);
- if (!block)
- return;
-
- /*
- * Make sure the chip is awake and the logger isn't active.
- * This might fail if the firmware hanged.
- */
- if (!wl1271_ps_elp_wakeup(wl))
- wl12xx_cmd_stop_fwlog(wl);
-
- /* Read the first memory block address */
- wl12xx_fw_status(wl, wl->fw_status);
- first_addr = le32_to_cpu(wl->fw_status->log_start_addr);
- if (!first_addr)
- goto out;
-
- /* Traverse the memory blocks linked list */
- addr = first_addr;
- do {
- memset(block, 0, WL12XX_HW_BLOCK_SIZE);
- wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE,
- false);
-
- /*
- * Memory blocks are linked to one another. The first 4 bytes
- * of each memory block hold the hardware address of the next
- * one. The last memory block points to the first one.
- */
- addr = le32_to_cpup((__le32 *)block);
- if (!wl12xx_copy_fwlog(wl, block + sizeof(addr),
- WL12XX_HW_BLOCK_SIZE - sizeof(addr)))
- break;
- } while (addr && (addr != first_addr));
-
- wake_up_interruptible(&wl->fwlog_waitq);
-
-out:
- kfree(block);
-}
-
-static void wl1271_recovery_work(struct work_struct *work)
-{
- struct wl1271 *wl =
- container_of(work, struct wl1271, recovery_work);
- struct wl12xx_vif *wlvif;
- struct ieee80211_vif *vif;
-
- mutex_lock(&wl->mutex);
-
- if (wl->state != WL1271_STATE_ON || wl->plt)
- goto out_unlock;
-
- /* Avoid a recursive recovery */
- set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-
- wl12xx_read_fwlog_panic(wl);
-
- wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
- wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
-
- BUG_ON(bug_on_recovery &&
- !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
-
- /*
- * Advance security sequence number to overcome potential progress
- * in the firmware during recovery. This doens't hurt if the network is
- * not encrypted.
- */
- wl12xx_for_each_wlvif(wl, wlvif) {
- if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
- test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
- wlvif->tx_security_seq +=
- WL1271_TX_SQN_POST_RECOVERY_PADDING;
- }
-
- /* Prevent spurious TX during FW restart */
- ieee80211_stop_queues(wl->hw);
-
- if (wl->sched_scanning) {
- ieee80211_sched_scan_stopped(wl->hw);
- wl->sched_scanning = false;
- }
-
- /* reboot the chipset */
- while (!list_empty(&wl->wlvif_list)) {
- wlvif = list_first_entry(&wl->wlvif_list,
- struct wl12xx_vif, list);
- vif = wl12xx_wlvif_to_vif(wlvif);
- __wl1271_op_remove_interface(wl, vif, false);
- }
- mutex_unlock(&wl->mutex);
- wl1271_op_stop(wl->hw);
-
- clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
-
- ieee80211_restart_hw(wl->hw);
-
- /*
- * Its safe to enable TX now - the queues are stopped after a request
- * to restart the HW.
- */
- ieee80211_wake_queues(wl->hw);
- return;
-out_unlock:
- mutex_unlock(&wl->mutex);
-}
-
-static void wl1271_fw_wakeup(struct wl1271 *wl)
-{
- u32 elp_reg;
-
- elp_reg = ELPCTRL_WAKE_UP;
- wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
-}
-
-static int wl1271_setup(struct wl1271 *wl)
-{
- wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
- if (!wl->fw_status)
- return -ENOMEM;
-
- wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
- if (!wl->tx_res_if) {
- kfree(wl->fw_status);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static int wl12xx_set_power_on(struct wl1271 *wl)
-{
- int ret;
-
- msleep(WL1271_PRE_POWER_ON_SLEEP);
- ret = wl1271_power_on(wl);
- if (ret < 0)
- goto out;
- msleep(WL1271_POWER_ON_SLEEP);
- wl1271_io_reset(wl);
- wl1271_io_init(wl);
-
- wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
-
- /* ELP module wake up */
- wl1271_fw_wakeup(wl);
-
-out:
- return ret;
-}
-
-static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
-{
- int ret = 0;
-
- ret = wl12xx_set_power_on(wl);
- if (ret < 0)
- goto out;
-
- /*
- * For wl127x based devices we could use the default block
- * size (512 bytes), but due to a bug in the sdio driver, we
- * need to set it explicitly after the chip is powered on. To
- * simplify the code and since the performance impact is
- * negligible, we use the same block size for all different
- * chip types.
- */
- if (!wl1271_set_block_size(wl))
- wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
-
- switch (wl->chip.id) {
- case CHIP_ID_1271_PG10:
- wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
- wl->chip.id);
-
- ret = wl1271_setup(wl);
- if (ret < 0)
- goto out;
- wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
- break;
-
- case CHIP_ID_1271_PG20:
- wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
- wl->chip.id);
-
- ret = wl1271_setup(wl);
- if (ret < 0)
- goto out;
- wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
- break;
-
- case CHIP_ID_1283_PG20:
- wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
- wl->chip.id);
-
- ret = wl1271_setup(wl);
- if (ret < 0)
- goto out;
- break;
- case CHIP_ID_1283_PG10:
- default:
- wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
- ret = -ENODEV;
- goto out;
- }
-
- ret = wl12xx_fetch_firmware(wl, plt);
- if (ret < 0)
- goto out;
-
- /* No NVS from netlink, try to get it from the filesystem */
- if (wl->nvs == NULL) {
- ret = wl1271_fetch_nvs(wl);
- if (ret < 0)
- goto out;
- }
-
-out:
- return ret;
-}
-
-int wl1271_plt_start(struct wl1271 *wl)
-{
- int retries = WL1271_BOOT_RETRIES;
- struct wiphy *wiphy = wl->hw->wiphy;
- int ret;
-
- mutex_lock(&wl->mutex);
-
- wl1271_notice("power up");
-
- if (wl->state != WL1271_STATE_OFF) {
- wl1271_error("cannot go into PLT state because not "
- "in off state: %d", wl->state);
- ret = -EBUSY;
- goto out;
- }
-
- while (retries) {
- retries--;
- ret = wl12xx_chip_wakeup(wl, true);
- if (ret < 0)
- goto power_off;
-
- ret = wl1271_boot(wl);
- if (ret < 0)
- goto power_off;
-
- ret = wl1271_plt_init(wl);
- if (ret < 0)
- goto irq_disable;
-
- wl->plt = true;
- wl->state = WL1271_STATE_ON;
- wl1271_notice("firmware booted in PLT mode (%s)",
- wl->chip.fw_ver_str);
-
- /* update hw/fw version info in wiphy struct */
- wiphy->hw_version = wl->chip.id;
- strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
- sizeof(wiphy->fw_version));
-
- goto out;
-
-irq_disable:
- mutex_unlock(&wl->mutex);
- /* Unlocking the mutex in the middle of handling is
- inherently unsafe. In this case we deem it safe to do,
- because we need to let any possibly pending IRQ out of
- the system (and while we are WL1271_STATE_OFF the IRQ
- work function will not do anything.) Also, any other
- possible concurrent operations will fail due to the
- current state, hence the wl1271 struct should be safe. */
- wl1271_disable_interrupts(wl);
- wl1271_flush_deferred_work(wl);
- cancel_work_sync(&wl->netstack_work);
- mutex_lock(&wl->mutex);
-power_off:
- wl1271_power_off(wl);
- }
-
- wl1271_error("firmware boot in PLT mode failed despite %d retries",
- WL1271_BOOT_RETRIES);
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-int wl1271_plt_stop(struct wl1271 *wl)
-{
- int ret = 0;
-
- wl1271_notice("power down");
-
- /*
- * Interrupts must be disabled before setting the state to OFF.
- * Otherwise, the interrupt handler might be called and exit without
- * reading the interrupt status.
- */
- wl1271_disable_interrupts(wl);
- mutex_lock(&wl->mutex);
- if (!wl->plt) {
- mutex_unlock(&wl->mutex);
-
- /*
- * This will not necessarily enable interrupts as interrupts
- * may have been disabled when op_stop was called. It will,
- * however, balance the above call to disable_interrupts().
- */
- wl1271_enable_interrupts(wl);
-
- wl1271_error("cannot power down because not in PLT "
- "state: %d", wl->state);
- ret = -EBUSY;
- goto out;
- }
-
- mutex_unlock(&wl->mutex);
-
- wl1271_flush_deferred_work(wl);
- cancel_work_sync(&wl->netstack_work);
- cancel_work_sync(&wl->recovery_work);
- cancel_delayed_work_sync(&wl->elp_work);
- cancel_delayed_work_sync(&wl->tx_watchdog_work);
-
- mutex_lock(&wl->mutex);
- wl1271_power_off(wl);
- wl->flags = 0;
- wl->state = WL1271_STATE_OFF;
- wl->plt = false;
- wl->rx_counter = 0;
- mutex_unlock(&wl->mutex);
-
-out:
- return ret;
-}
-
-static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct wl1271 *wl = hw->priv;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_vif *vif = info->control.vif;
- struct wl12xx_vif *wlvif = NULL;
- unsigned long flags;
- int q, mapping;
- u8 hlid;
-
- if (vif)
- wlvif = wl12xx_vif_to_data(vif);
-
- mapping = skb_get_queue_mapping(skb);
- q = wl1271_tx_get_queue(mapping);
-
- hlid = wl12xx_tx_get_hlid(wl, wlvif, skb);
-
- spin_lock_irqsave(&wl->wl_lock, flags);
-
- /* queue the packet */
- if (hlid == WL12XX_INVALID_LINK_ID ||
- (wlvif && !test_bit(hlid, wlvif->links_map))) {
- wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q);
- ieee80211_free_txskb(hw, skb);
- goto out;
- }
-
- wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d",
- hlid, q, skb->len);
- skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);
-
- wl->tx_queue_count[q]++;
-
- /*
- * The workqueue is slow to process the tx_queue and we need stop
- * the queue here, otherwise the queue will get too long.
- */
- if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
- wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
- ieee80211_stop_queue(wl->hw, mapping);
- set_bit(q, &wl->stopped_queues_map);
- }
-
- /*
- * The chip specific setup must run before the first TX packet -
- * before that, the tx_work will not be initialized!
- */
-
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
- !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags))
- ieee80211_queue_work(wl->hw, &wl->tx_work);
-
-out:
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-}
-
-int wl1271_tx_dummy_packet(struct wl1271 *wl)
-{
- unsigned long flags;
- int q;
-
- /* no need to queue a new dummy packet if one is already pending */
- if (test_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags))
- return 0;
-
- q = wl1271_tx_get_queue(skb_get_queue_mapping(wl->dummy_packet));
-
- spin_lock_irqsave(&wl->wl_lock, flags);
- set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
- wl->tx_queue_count[q]++;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- /* The FW is low on RX memory blocks, so send the dummy packet asap */
- if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
- wl1271_tx_work_locked(wl);
-
- /*
- * If the FW TX is busy, TX work will be scheduled by the threaded
- * interrupt handler function
- */
- return 0;
-}
-
-/*
- * The size of the dummy packet should be at least 1400 bytes. However, in
- * order to minimize the number of bus transactions, aligning it to 512 bytes
- * boundaries could be beneficial, performance wise
- */
-#define TOTAL_TX_DUMMY_PACKET_SIZE (ALIGN(1400, 512))
-
-static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *hdr;
- unsigned int dummy_packet_size;
-
- dummy_packet_size = TOTAL_TX_DUMMY_PACKET_SIZE -
- sizeof(struct wl1271_tx_hw_descr) - sizeof(*hdr);
-
- skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE);
- if (!skb) {
- wl1271_warning("Failed to allocate a dummy packet skb");
- return NULL;
- }
-
- skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr));
-
- hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr));
- memset(hdr, 0, sizeof(*hdr));
- hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC |
- IEEE80211_FCTL_TODS);
-
- memset(skb_put(skb, dummy_packet_size), 0, dummy_packet_size);
-
- /* Dummy packets require the TID to be management */
- skb->priority = WL1271_TID_MGMT;
-
- /* Initialize all fields that might be used */
- skb_set_queue_mapping(skb, 0);
- memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
-
- return skb;
-}
-
-
-#ifdef CONFIG_PM
-static int wl1271_configure_suspend_sta(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret = 0;
-
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_acx_wake_up_conditions(wl, wlvif,
- wl->conf.conn.suspend_wake_up_event,
- wl->conf.conn.suspend_listen_interval);
-
- if (ret < 0)
- wl1271_error("suspend: set wake up conditions failed: %d", ret);
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- return ret;
-
-}
-
-static int wl1271_configure_suspend_ap(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret = 0;
-
- if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
-
- wl1271_ps_elp_sleep(wl);
-out:
- return ret;
-
-}
-
-static int wl1271_configure_suspend(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- if (wlvif->bss_type == BSS_TYPE_STA_BSS)
- return wl1271_configure_suspend_sta(wl, wlvif);
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- return wl1271_configure_suspend_ap(wl, wlvif);
- return 0;
-}
-
-static void wl1271_configure_resume(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- int ret = 0;
- bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
- bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
-
- if ((!is_ap) && (!is_sta))
- return;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- return;
-
- if (is_sta) {
- ret = wl1271_acx_wake_up_conditions(wl, wlvif,
- wl->conf.conn.wake_up_event,
- wl->conf.conn.listen_interval);
-
- if (ret < 0)
- wl1271_error("resume: wake up conditions failed: %d",
- ret);
-
- } else if (is_ap) {
- ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
- }
-
- wl1271_ps_elp_sleep(wl);
-}
-
-static int wl1271_op_suspend(struct ieee80211_hw *hw,
- struct cfg80211_wowlan *wow)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif;
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
- WARN_ON(!wow || !wow->any);
-
- wl1271_tx_flush(wl);
-
- mutex_lock(&wl->mutex);
- wl->wow_enabled = true;
- wl12xx_for_each_wlvif(wl, wlvif) {
- ret = wl1271_configure_suspend(wl, wlvif);
- if (ret < 0) {
- wl1271_warning("couldn't prepare device to suspend");
- return ret;
- }
- }
- mutex_unlock(&wl->mutex);
- /* flush any remaining work */
- wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
-
- /*
- * disable and re-enable interrupts in order to flush
- * the threaded_irq
- */
- wl1271_disable_interrupts(wl);
-
- /*
- * set suspended flag to avoid triggering a new threaded_irq
- * work. no need for spinlock as interrupts are disabled.
- */
- set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
-
- wl1271_enable_interrupts(wl);
- flush_work(&wl->tx_work);
- flush_delayed_work(&wl->elp_work);
-
- return 0;
-}
-
-static int wl1271_op_resume(struct ieee80211_hw *hw)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif;
- unsigned long flags;
- bool run_irq_work = false;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
- wl->wow_enabled);
- WARN_ON(!wl->wow_enabled);
-
- /*
- * re-enable irq_work enqueuing, and call irq_work directly if
- * there is a pending work.
- */
- spin_lock_irqsave(&wl->wl_lock, flags);
- clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
- if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags))
- run_irq_work = true;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- if (run_irq_work) {
- wl1271_debug(DEBUG_MAC80211,
- "run postponed irq_work directly");
- wl1271_irq(0, wl);
- wl1271_enable_interrupts(wl);
- }
-
- mutex_lock(&wl->mutex);
- wl12xx_for_each_wlvif(wl, wlvif) {
- wl1271_configure_resume(wl, wlvif);
- }
- wl->wow_enabled = false;
- mutex_unlock(&wl->mutex);
-
- return 0;
-}
-#endif
-
-static int wl1271_op_start(struct ieee80211_hw *hw)
-{
- wl1271_debug(DEBUG_MAC80211, "mac80211 start");
-
- /*
- * We have to delay the booting of the hardware because
- * we need to know the local MAC address before downloading and
- * initializing the firmware. The MAC address cannot be changed
- * after boot, and without the proper MAC address, the firmware
- * will not function properly.
- *
- * The MAC address is first known when the corresponding interface
- * is added. That is where we will initialize the hardware.
- */
-
- return 0;
-}
-
-static void wl1271_op_stop(struct ieee80211_hw *hw)
-{
- struct wl1271 *wl = hw->priv;
- int i;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
-
- /*
- * Interrupts must be disabled before setting the state to OFF.
- * Otherwise, the interrupt handler might be called and exit without
- * reading the interrupt status.
- */
- wl1271_disable_interrupts(wl);
- mutex_lock(&wl->mutex);
- if (wl->state == WL1271_STATE_OFF) {
- mutex_unlock(&wl->mutex);
-
- /*
- * This will not necessarily enable interrupts as interrupts
- * may have been disabled when op_stop was called. It will,
- * however, balance the above call to disable_interrupts().
- */
- wl1271_enable_interrupts(wl);
- return;
- }
-
- /*
- * this must be before the cancel_work calls below, so that the work
- * functions don't perform further work.
- */
- wl->state = WL1271_STATE_OFF;
- mutex_unlock(&wl->mutex);
-
- wl1271_flush_deferred_work(wl);
- cancel_delayed_work_sync(&wl->scan_complete_work);
- cancel_work_sync(&wl->netstack_work);
- cancel_work_sync(&wl->tx_work);
- cancel_delayed_work_sync(&wl->elp_work);
- cancel_delayed_work_sync(&wl->tx_watchdog_work);
-
- /* let's notify MAC80211 about the remaining pending TX frames */
- wl12xx_tx_reset(wl, true);
- mutex_lock(&wl->mutex);
-
- wl1271_power_off(wl);
-
- wl->band = IEEE80211_BAND_2GHZ;
-
- wl->rx_counter = 0;
- wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
- wl->tx_blocks_available = 0;
- wl->tx_allocated_blocks = 0;
- wl->tx_results_count = 0;
- wl->tx_packets_count = 0;
- wl->time_offset = 0;
- wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
- wl->ap_fw_ps_map = 0;
- wl->ap_ps_map = 0;
- wl->sched_scanning = false;
- memset(wl->roles_map, 0, sizeof(wl->roles_map));
- memset(wl->links_map, 0, sizeof(wl->links_map));
- memset(wl->roc_map, 0, sizeof(wl->roc_map));
- wl->active_sta_count = 0;
-
- /* The system link is always allocated */
- __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
-
- /*
- * this is performed after the cancel_work calls and the associated
- * mutex_lock, so that wl1271_op_add_interface does not accidentally
- * get executed before all these vars have been reset.
- */
- wl->flags = 0;
-
- wl->tx_blocks_freed = 0;
-
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- wl->tx_pkts_freed[i] = 0;
- wl->tx_allocated_pkts[i] = 0;
- }
-
- wl1271_debugfs_reset(wl);
-
- kfree(wl->fw_status);
- wl->fw_status = NULL;
- kfree(wl->tx_res_if);
- wl->tx_res_if = NULL;
- kfree(wl->target_mem_map);
- wl->target_mem_map = NULL;
-
- mutex_unlock(&wl->mutex);
-}
-
-static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
-{
- u8 policy = find_first_zero_bit(wl->rate_policies_map,
- WL12XX_MAX_RATE_POLICIES);
- if (policy >= WL12XX_MAX_RATE_POLICIES)
- return -EBUSY;
-
- __set_bit(policy, wl->rate_policies_map);
- *idx = policy;
- return 0;
-}
-
-static void wl12xx_free_rate_policy(struct wl1271 *wl, u8 *idx)
-{
- if (WARN_ON(*idx >= WL12XX_MAX_RATE_POLICIES))
- return;
-
- __clear_bit(*idx, wl->rate_policies_map);
- *idx = WL12XX_MAX_RATE_POLICIES;
-}
-
-static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- switch (wlvif->bss_type) {
- case BSS_TYPE_AP_BSS:
- if (wlvif->p2p)
- return WL1271_ROLE_P2P_GO;
- else
- return WL1271_ROLE_AP;
-
- case BSS_TYPE_STA_BSS:
- if (wlvif->p2p)
- return WL1271_ROLE_P2P_CL;
- else
- return WL1271_ROLE_STA;
-
- case BSS_TYPE_IBSS:
- return WL1271_ROLE_IBSS;
-
- default:
- wl1271_error("invalid bss_type: %d", wlvif->bss_type);
- }
- return WL12XX_INVALID_ROLE_TYPE;
-}
-
-static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int i;
-
- /* clear everything but the persistent data */
- memset(wlvif, 0, offsetof(struct wl12xx_vif, persistent));
-
- switch (ieee80211_vif_type_p2p(vif)) {
- case NL80211_IFTYPE_P2P_CLIENT:
- wlvif->p2p = 1;
- /* fall-through */
- case NL80211_IFTYPE_STATION:
- wlvif->bss_type = BSS_TYPE_STA_BSS;
- break;
- case NL80211_IFTYPE_ADHOC:
- wlvif->bss_type = BSS_TYPE_IBSS;
- break;
- case NL80211_IFTYPE_P2P_GO:
- wlvif->p2p = 1;
- /* fall-through */
- case NL80211_IFTYPE_AP:
- wlvif->bss_type = BSS_TYPE_AP_BSS;
- break;
- default:
- wlvif->bss_type = MAX_BSS_TYPE;
- return -EOPNOTSUPP;
- }
-
- wlvif->role_id = WL12XX_INVALID_ROLE_ID;
- wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID;
- wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS) {
- /* init sta/ibss data */
- wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
- wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx);
- wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx);
- wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
- } else {
- /* init ap data */
- wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
- wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
- wl12xx_allocate_rate_policy(wl, &wlvif->ap.mgmt_rate_idx);
- wl12xx_allocate_rate_policy(wl, &wlvif->ap.bcast_rate_idx);
- for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
- wl12xx_allocate_rate_policy(wl,
- &wlvif->ap.ucast_rate_idx[i]);
- }
-
- wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
- wlvif->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5;
- wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
- wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC;
- wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
- wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT;
-
- /*
- * mac80211 configures some values globally, while we treat them
- * per-interface. thus, on init, we have to copy them from wl
- */
- wlvif->band = wl->band;
- wlvif->channel = wl->channel;
- wlvif->power_level = wl->power_level;
-
- INIT_WORK(&wlvif->rx_streaming_enable_work,
- wl1271_rx_streaming_enable_work);
- INIT_WORK(&wlvif->rx_streaming_disable_work,
- wl1271_rx_streaming_disable_work);
- INIT_LIST_HEAD(&wlvif->list);
-
- setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
- (unsigned long) wlvif);
- return 0;
-}
-
-static bool wl12xx_init_fw(struct wl1271 *wl)
-{
- int retries = WL1271_BOOT_RETRIES;
- bool booted = false;
- struct wiphy *wiphy = wl->hw->wiphy;
- int ret;
-
- while (retries) {
- retries--;
- ret = wl12xx_chip_wakeup(wl, false);
- if (ret < 0)
- goto power_off;
-
- ret = wl1271_boot(wl);
- if (ret < 0)
- goto power_off;
-
- ret = wl1271_hw_init(wl);
- if (ret < 0)
- goto irq_disable;
-
- booted = true;
- break;
-
-irq_disable:
- mutex_unlock(&wl->mutex);
- /* Unlocking the mutex in the middle of handling is
- inherently unsafe. In this case we deem it safe to do,
- because we need to let any possibly pending IRQ out of
- the system (and while we are WL1271_STATE_OFF the IRQ
- work function will not do anything.) Also, any other
- possible concurrent operations will fail due to the
- current state, hence the wl1271 struct should be safe. */
- wl1271_disable_interrupts(wl);
- wl1271_flush_deferred_work(wl);
- cancel_work_sync(&wl->netstack_work);
- mutex_lock(&wl->mutex);
-power_off:
- wl1271_power_off(wl);
- }
-
- if (!booted) {
- wl1271_error("firmware boot failed despite %d retries",
- WL1271_BOOT_RETRIES);
- goto out;
- }
-
- wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
-
- /* update hw/fw version info in wiphy struct */
- wiphy->hw_version = wl->chip.id;
- strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
- sizeof(wiphy->fw_version));
-
- /*
- * Now we know if 11a is supported (info from the NVS), so disable
- * 11a channels if not supported
- */
- if (!wl->enable_11a)
- wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels = 0;
-
- wl1271_debug(DEBUG_MAC80211, "11a is %ssupported",
- wl->enable_11a ? "" : "not ");
-
- wl->state = WL1271_STATE_ON;
-out:
- return booted;
-}
-
-static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
-{
- return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID;
-}
-
-/*
- * Check whether a fw switch (i.e. moving from one loaded
- * fw to another) is needed. This function is also responsible
- * for updating wl->last_vif_count, so it must be called before
- * loading a non-plt fw (so the correct fw (single-role/multi-role)
- * will be used).
- */
-static bool wl12xx_need_fw_change(struct wl1271 *wl,
- struct vif_counter_data vif_counter_data,
- bool add)
-{
- enum wl12xx_fw_type current_fw = wl->fw_type;
- u8 vif_count = vif_counter_data.counter;
-
- if (test_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags))
- return false;
-
- /* increase the vif count if this is a new vif */
- if (add && !vif_counter_data.cur_vif_running)
- vif_count++;
-
- wl->last_vif_count = vif_count;
-
- /* no need for fw change if the device is OFF */
- if (wl->state == WL1271_STATE_OFF)
- return false;
-
- if (vif_count > 1 && current_fw == WL12XX_FW_TYPE_NORMAL)
- return true;
- if (vif_count <= 1 && current_fw == WL12XX_FW_TYPE_MULTI)
- return true;
-
- return false;
-}
-
-/*
- * Enter "forced psm". Make sure the sta is in psm against the ap,
- * to make the fw switch a bit more disconnection-persistent.
- */
-static void wl12xx_force_active_psm(struct wl1271 *wl)
-{
- struct wl12xx_vif *wlvif;
-
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE);
- }
-}
-
-static int wl1271_op_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct vif_counter_data vif_count;
- int ret = 0;
- u8 role_type;
- bool booted = false;
-
- vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
- IEEE80211_VIF_SUPPORTS_CQM_RSSI;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
- ieee80211_vif_type_p2p(vif), vif->addr);
-
- wl12xx_get_vif_count(hw, vif, &vif_count);
-
- mutex_lock(&wl->mutex);
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_unlock;
-
- /*
- * in some very corner case HW recovery scenarios its possible to
- * get here before __wl1271_op_remove_interface is complete, so
- * opt out if that is the case.
- */
- if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) ||
- test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) {
- ret = -EBUSY;
- goto out;
- }
-
-
- ret = wl12xx_init_vif_data(wl, vif);
- if (ret < 0)
- goto out;
-
- wlvif->wl = wl;
- role_type = wl12xx_get_role_type(wl, wlvif);
- if (role_type == WL12XX_INVALID_ROLE_TYPE) {
- ret = -EINVAL;
- goto out;
- }
-
- if (wl12xx_need_fw_change(wl, vif_count, true)) {
- wl12xx_force_active_psm(wl);
- set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
- mutex_unlock(&wl->mutex);
- wl1271_recovery_work(&wl->recovery_work);
- return 0;
- }
-
- /*
- * TODO: after the nvs issue will be solved, move this block
- * to start(), and make sure here the driver is ON.
- */
- if (wl->state == WL1271_STATE_OFF) {
- /*
- * we still need this in order to configure the fw
- * while uploading the nvs
- */
- memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN);
-
- booted = wl12xx_init_fw(wl);
- if (!booted) {
- ret = -EINVAL;
- goto out;
- }
- }
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS) {
- /*
- * The device role is a special role used for
- * rx and tx frames prior to association (as
- * the STA role can get packets only from
- * its associated bssid)
- */
- ret = wl12xx_cmd_role_enable(wl, vif->addr,
- WL1271_ROLE_DEVICE,
- &wlvif->dev_role_id);
- if (ret < 0)
- goto out;
- }
-
- ret = wl12xx_cmd_role_enable(wl, vif->addr,
- role_type, &wlvif->role_id);
- if (ret < 0)
- goto out;
-
- ret = wl1271_init_vif_specific(wl, vif);
- if (ret < 0)
- goto out;
-
- list_add(&wlvif->list, &wl->wlvif_list);
- set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags);
-
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- wl->ap_count++;
- else
- wl->sta_count++;
-out:
- wl1271_ps_elp_sleep(wl);
-out_unlock:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static void __wl1271_op_remove_interface(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- bool reset_tx_queues)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int i, ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
-
- if (!test_and_clear_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
- return;
-
- /* because of hardware recovery, we may get here twice */
- if (wl->state != WL1271_STATE_ON)
- return;
-
- wl1271_info("down");
-
- if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
- wl->scan_vif == vif) {
- /*
- * Rearm the tx watchdog just before idling scan. This
- * prevents just-finished scans from triggering the watchdog
- */
- wl12xx_rearm_tx_watchdog_locked(wl);
-
- wl->scan.state = WL1271_SCAN_STATE_IDLE;
- memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
- wl->scan_vif = NULL;
- wl->scan.req = NULL;
- ieee80211_scan_completed(wl->hw, true);
- }
-
- if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
- /* disable active roles */
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto deinit;
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS) {
- if (wl12xx_dev_role_started(wlvif))
- wl12xx_stop_dev(wl, wlvif);
-
- ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
- if (ret < 0)
- goto deinit;
- }
-
- ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
- if (ret < 0)
- goto deinit;
-
- wl1271_ps_elp_sleep(wl);
- }
-deinit:
- /* clear all hlids (except system_hlid) */
- wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
- wlvif->bss_type == BSS_TYPE_IBSS) {
- wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
- wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx);
- wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx);
- wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
- } else {
- wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
- wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
- wl12xx_free_rate_policy(wl, &wlvif->ap.mgmt_rate_idx);
- wl12xx_free_rate_policy(wl, &wlvif->ap.bcast_rate_idx);
- for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
- wl12xx_free_rate_policy(wl,
- &wlvif->ap.ucast_rate_idx[i]);
- wl1271_free_ap_keys(wl, wlvif);
- }
-
- dev_kfree_skb(wlvif->probereq);
- wlvif->probereq = NULL;
- wl12xx_tx_reset_wlvif(wl, wlvif);
- if (wl->last_wlvif == wlvif)
- wl->last_wlvif = NULL;
- list_del(&wlvif->list);
- memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map));
- wlvif->role_id = WL12XX_INVALID_ROLE_ID;
- wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID;
-
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- wl->ap_count--;
- else
- wl->sta_count--;
-
- mutex_unlock(&wl->mutex);
-
- del_timer_sync(&wlvif->rx_streaming_timer);
- cancel_work_sync(&wlvif->rx_streaming_enable_work);
- cancel_work_sync(&wlvif->rx_streaming_disable_work);
-
- mutex_lock(&wl->mutex);
-}
-
-static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct wl12xx_vif *iter;
- struct vif_counter_data vif_count;
- bool cancel_recovery = true;
-
- wl12xx_get_vif_count(hw, vif, &vif_count);
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF ||
- !test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
- goto out;
-
- /*
- * wl->vif can be null here if someone shuts down the interface
- * just when hardware recovery has been started.
- */
- wl12xx_for_each_wlvif(wl, iter) {
- if (iter != wlvif)
- continue;
-
- __wl1271_op_remove_interface(wl, vif, true);
- break;
- }
- WARN_ON(iter != wlvif);
- if (wl12xx_need_fw_change(wl, vif_count, false)) {
- wl12xx_force_active_psm(wl);
- set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
- wl12xx_queue_recovery_work(wl);
- cancel_recovery = false;
- }
-out:
- mutex_unlock(&wl->mutex);
- if (cancel_recovery)
- cancel_work_sync(&wl->recovery_work);
-}
-
-static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum nl80211_iftype new_type, bool p2p)
-{
- struct wl1271 *wl = hw->priv;
- int ret;
-
- set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
- wl1271_op_remove_interface(hw, vif);
-
- vif->type = new_type;
- vif->p2p = p2p;
- ret = wl1271_op_add_interface(hw, vif);
-
- clear_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
- return ret;
-}
-
-static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool set_assoc)
-{
- int ret;
- bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
-
- /*
- * One of the side effects of the JOIN command is that is clears
- * WPA/WPA2 keys from the chipset. Performing a JOIN while associated
- * to a WPA/WPA2 access point will therefore kill the data-path.
- * Currently the only valid scenario for JOIN during association
- * is on roaming, in which case we will also be given new keys.
- * Keep the below message for now, unless it starts bothering
- * users who really like to roam a lot :)
- */
- if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- wl1271_info("JOIN while associated.");
-
- /* clear encryption type */
- wlvif->encryption_type = KEY_NONE;
-
- if (set_assoc)
- set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
-
- if (is_ibss)
- ret = wl12xx_cmd_role_start_ibss(wl, wlvif);
- else
- ret = wl12xx_cmd_role_start_sta(wl, wlvif);
- if (ret < 0)
- goto out;
-
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- goto out;
-
- /*
- * The join command disable the keep-alive mode, shut down its process,
- * and also clear the template config, so we need to reset it all after
- * the join. The acx_aid starts the keep-alive process, and the order
- * of the commands below is relevant.
- */
- ret = wl1271_acx_keep_alive_mode(wl, wlvif, true);
- if (ret < 0)
- goto out;
-
- ret = wl1271_acx_aid(wl, wlvif, wlvif->aid);
- if (ret < 0)
- goto out;
-
- ret = wl12xx_cmd_build_klv_null_data(wl, wlvif);
- if (ret < 0)
- goto out;
-
- ret = wl1271_acx_keep_alive_config(wl, wlvif,
- CMD_TEMPL_KLV_IDX_NULL_DATA,
- ACX_KEEP_ALIVE_TPL_VALID);
- if (ret < 0)
- goto out;
-
-out:
- return ret;
-}
-
-static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int ret;
-
- if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
- wl12xx_cmd_stop_channel_switch(wl);
- ieee80211_chswitch_done(vif, false);
- }
-
- /* to stop listening to a channel, we disconnect */
- ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
- if (ret < 0)
- goto out;
-
- /* reset TX security counters on a clean disconnect */
- wlvif->tx_security_last_seq_lsb = 0;
- wlvif->tx_security_seq = 0;
-
-out:
- return ret;
-}
-
-static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- wlvif->basic_rate_set = wlvif->bitrate_masks[wlvif->band];
- wlvif->rate_set = wlvif->basic_rate_set;
-}
-
-static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- bool idle)
-{
- int ret;
- bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
-
- if (idle == cur_idle)
- return 0;
-
- if (idle) {
- /* no need to croc if we weren't busy (e.g. during boot) */
- if (wl12xx_dev_role_started(wlvif)) {
- ret = wl12xx_stop_dev(wl, wlvif);
- if (ret < 0)
- goto out;
- }
- wlvif->rate_set =
- wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
- if (ret < 0)
- goto out;
- ret = wl1271_acx_keep_alive_config(
- wl, wlvif, CMD_TEMPL_KLV_IDX_NULL_DATA,
- ACX_KEEP_ALIVE_TPL_INVALID);
- if (ret < 0)
- goto out;
- clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
- } else {
- /* The current firmware only supports sched_scan in idle */
- if (wl->sched_scanning) {
- wl1271_scan_sched_scan_stop(wl);
- ieee80211_sched_scan_stopped(wl->hw);
- }
-
- ret = wl12xx_start_dev(wl, wlvif);
- if (ret < 0)
- goto out;
- set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
- }
-
-out:
- return ret;
-}
-
-static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct ieee80211_conf *conf, u32 changed)
-{
- bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
- int channel, ret;
-
- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-
- /* if the channel changes while joined, join again */
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
- ((wlvif->band != conf->channel->band) ||
- (wlvif->channel != channel))) {
- /* send all pending packets */
- wl1271_tx_work_locked(wl);
- wlvif->band = conf->channel->band;
- wlvif->channel = channel;
-
- if (!is_ap) {
- /*
- * FIXME: the mac80211 should really provide a fixed
- * rate to use here. for now, just use the smallest
- * possible rate for the band as a fixed rate for
- * association frames and other control messages.
- */
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- wl1271_set_band_rate(wl, wlvif);
-
- wlvif->basic_rate =
- wl1271_tx_min_rate_get(wl,
- wlvif->basic_rate_set);
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
- if (ret < 0)
- wl1271_warning("rate policy for channel "
- "failed %d", ret);
-
- /*
- * change the ROC channel. do it only if we are
- * not idle. otherwise, CROC will be called
- * anyway.
- */
- if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED,
- &wlvif->flags) &&
- wl12xx_dev_role_started(wlvif) &&
- !(conf->flags & IEEE80211_CONF_IDLE)) {
- ret = wl12xx_stop_dev(wl, wlvif);
- if (ret < 0)
- return ret;
-
- ret = wl12xx_start_dev(wl, wlvif);
- if (ret < 0)
- return ret;
- }
- }
- }
-
- if ((changed & IEEE80211_CONF_CHANGE_PS) && !is_ap) {
-
- if ((conf->flags & IEEE80211_CONF_PS) &&
- test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
- !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
-
- int ps_mode;
- char *ps_mode_str;
-
- if (wl->conf.conn.forced_ps) {
- ps_mode = STATION_POWER_SAVE_MODE;
- ps_mode_str = "forced";
- } else {
- ps_mode = STATION_AUTO_PS_MODE;
- ps_mode_str = "auto";
- }
-
- wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
-
- ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
-
- if (ret < 0)
- wl1271_warning("enter %s ps failed %d",
- ps_mode_str, ret);
-
- } else if (!(conf->flags & IEEE80211_CONF_PS) &&
- test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
-
- wl1271_debug(DEBUG_PSM, "auto ps disabled");
-
- ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_ACTIVE_MODE);
- if (ret < 0)
- wl1271_warning("exit auto ps failed %d", ret);
- }
- }
-
- if (conf->power_level != wlvif->power_level) {
- ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level);
- if (ret < 0)
- return ret;
-
- wlvif->power_level = conf->power_level;
- }
-
- return 0;
-}
-
-static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif;
- struct ieee80211_conf *conf = &hw->conf;
- int channel, ret = 0;
-
- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s"
- " changed 0x%x",
- channel,
- conf->flags & IEEE80211_CONF_PS ? "on" : "off",
- conf->power_level,
- conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use",
- changed);
-
- /*
- * mac80211 will go to idle nearly immediately after transmitting some
- * frames, such as the deauth. To make sure those frames reach the air,
- * wait here until the TX queue is fully flushed.
- */
- if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
- (conf->flags & IEEE80211_CONF_IDLE))
- wl1271_tx_flush(wl);
-
- mutex_lock(&wl->mutex);
-
- /* we support configuring the channel and band even while off */
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- wl->band = conf->channel->band;
- wl->channel = channel;
- }
-
- if (changed & IEEE80211_CONF_CHANGE_POWER)
- wl->power_level = conf->power_level;
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /* configure each interface */
- wl12xx_for_each_wlvif(wl, wlvif) {
- ret = wl12xx_config_vif(wl, wlvif, conf, changed);
- if (ret < 0)
- goto out_sleep;
- }
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-struct wl1271_filter_params {
- bool enabled;
- int mc_list_length;
- u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
-};
-
-static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
- struct netdev_hw_addr_list *mc_list)
-{
- struct wl1271_filter_params *fp;
- struct netdev_hw_addr *ha;
- struct wl1271 *wl = hw->priv;
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- return 0;
-
- fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
- if (!fp) {
- wl1271_error("Out of memory setting filters.");
- return 0;
- }
-
- /* update multicast filtering parameters */
- fp->mc_list_length = 0;
- if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) {
- fp->enabled = false;
- } else {
- fp->enabled = true;
- netdev_hw_addr_list_for_each(ha, mc_list) {
- memcpy(fp->mc_list[fp->mc_list_length],
- ha->addr, ETH_ALEN);
- fp->mc_list_length++;
- }
- }
-
- return (u64)(unsigned long)fp;
-}
-
-#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
- FIF_ALLMULTI | \
- FIF_FCSFAIL | \
- FIF_BCN_PRBRESP_PROMISC | \
- FIF_CONTROL | \
- FIF_OTHER_BSS)
-
-static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed,
- unsigned int *total, u64 multicast)
-{
- struct wl1271_filter_params *fp = (void *)(unsigned long)multicast;
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif;
-
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter changed %x"
- " total %x", changed, *total);
-
- mutex_lock(&wl->mutex);
-
- *total &= WL1271_SUPPORTED_FILTERS;
- changed &= WL1271_SUPPORTED_FILTERS;
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
- if (*total & FIF_ALLMULTI)
- ret = wl1271_acx_group_address_tbl(wl, wlvif,
- false,
- NULL, 0);
- else if (fp)
- ret = wl1271_acx_group_address_tbl(wl, wlvif,
- fp->enabled,
- fp->mc_list,
- fp->mc_list_length);
- if (ret < 0)
- goto out_sleep;
- }
- }
-
- /*
- * the fw doesn't provide an api to configure the filters. instead,
- * the filters configuration is based on the active roles / ROC
- * state.
- */
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
- kfree(fp);
-}
-
-static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 id, u8 key_type, u8 key_size,
- const u8 *key, u8 hlid, u32 tx_seq_32,
- u16 tx_seq_16)
-{
- struct wl1271_ap_key *ap_key;
- int i;
-
- wl1271_debug(DEBUG_CRYPT, "record ap key id %d", (int)id);
-
- if (key_size > MAX_KEY_SIZE)
- return -EINVAL;
-
- /*
- * Find next free entry in ap_keys. Also check we are not replacing
- * an existing key.
- */
- for (i = 0; i < MAX_NUM_KEYS; i++) {
- if (wlvif->ap.recorded_keys[i] == NULL)
- break;
-
- if (wlvif->ap.recorded_keys[i]->id == id) {
- wl1271_warning("trying to record key replacement");
- return -EINVAL;
- }
- }
-
- if (i == MAX_NUM_KEYS)
- return -EBUSY;
-
- ap_key = kzalloc(sizeof(*ap_key), GFP_KERNEL);
- if (!ap_key)
- return -ENOMEM;
-
- ap_key->id = id;
- ap_key->key_type = key_type;
- ap_key->key_size = key_size;
- memcpy(ap_key->key, key, key_size);
- ap_key->hlid = hlid;
- ap_key->tx_seq_32 = tx_seq_32;
- ap_key->tx_seq_16 = tx_seq_16;
-
- wlvif->ap.recorded_keys[i] = ap_key;
- return 0;
-}
-
-static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int i;
-
- for (i = 0; i < MAX_NUM_KEYS; i++) {
- kfree(wlvif->ap.recorded_keys[i]);
- wlvif->ap.recorded_keys[i] = NULL;
- }
-}
-
-static int wl1271_ap_init_hwenc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int i, ret = 0;
- struct wl1271_ap_key *key;
- bool wep_key_added = false;
-
- for (i = 0; i < MAX_NUM_KEYS; i++) {
- u8 hlid;
- if (wlvif->ap.recorded_keys[i] == NULL)
- break;
-
- key = wlvif->ap.recorded_keys[i];
- hlid = key->hlid;
- if (hlid == WL12XX_INVALID_LINK_ID)
- hlid = wlvif->ap.bcast_hlid;
-
- ret = wl1271_cmd_set_ap_key(wl, wlvif, KEY_ADD_OR_REPLACE,
- key->id, key->key_type,
- key->key_size, key->key,
- hlid, key->tx_seq_32,
- key->tx_seq_16);
- if (ret < 0)
- goto out;
-
- if (key->key_type == KEY_WEP)
- wep_key_added = true;
- }
-
- if (wep_key_added) {
- ret = wl12xx_cmd_set_default_wep_key(wl, wlvif->default_key,
- wlvif->ap.bcast_hlid);
- if (ret < 0)
- goto out;
- }
-
-out:
- wl1271_free_ap_keys(wl, wlvif);
- return ret;
-}
-
-static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u16 action, u8 id, u8 key_type,
- u8 key_size, const u8 *key, u32 tx_seq_32,
- u16 tx_seq_16, struct ieee80211_sta *sta)
-{
- int ret;
- bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
-
- if (is_ap) {
- struct wl1271_station *wl_sta;
- u8 hlid;
-
- if (sta) {
- wl_sta = (struct wl1271_station *)sta->drv_priv;
- hlid = wl_sta->hlid;
- } else {
- hlid = wlvif->ap.bcast_hlid;
- }
-
- if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
- /*
- * We do not support removing keys after AP shutdown.
- * Pretend we do to make mac80211 happy.
- */
- if (action != KEY_ADD_OR_REPLACE)
- return 0;
-
- ret = wl1271_record_ap_key(wl, wlvif, id,
- key_type, key_size,
- key, hlid, tx_seq_32,
- tx_seq_16);
- } else {
- ret = wl1271_cmd_set_ap_key(wl, wlvif, action,
- id, key_type, key_size,
- key, hlid, tx_seq_32,
- tx_seq_16);
- }
-
- if (ret < 0)
- return ret;
- } else {
- const u8 *addr;
- static const u8 bcast_addr[ETH_ALEN] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
-
- /*
- * A STA set to GEM cipher requires 2 tx spare blocks.
- * Return to default value when GEM cipher key is removed
- */
- if (key_type == KEY_GEM) {
- if (action == KEY_ADD_OR_REPLACE)
- wl->tx_spare_blocks = 2;
- else if (action == KEY_REMOVE)
- wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
- }
-
- addr = sta ? sta->addr : bcast_addr;
-
- if (is_zero_ether_addr(addr)) {
- /* We dont support TX only encryption */
- return -EOPNOTSUPP;
- }
-
- /* The wl1271 does not allow to remove unicast keys - they
- will be cleared automatically on next CMD_JOIN. Ignore the
- request silently, as we dont want the mac80211 to emit
- an error message. */
- if (action == KEY_REMOVE && !is_broadcast_ether_addr(addr))
- return 0;
-
- /* don't remove key if hlid was already deleted */
- if (action == KEY_REMOVE &&
- wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)
- return 0;
-
- ret = wl1271_cmd_set_sta_key(wl, wlvif, action,
- id, key_type, key_size,
- key, addr, tx_seq_32,
- tx_seq_16);
- if (ret < 0)
- return ret;
-
- /* the default WEP key needs to be configured at least once */
- if (key_type == KEY_WEP) {
- ret = wl12xx_cmd_set_default_wep_key(wl,
- wlvif->default_key,
- wlvif->sta.hlid);
- if (ret < 0)
- return ret;
- }
- }
-
- return 0;
-}
-
-static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key_conf)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret;
- u32 tx_seq_32 = 0;
- u16 tx_seq_16 = 0;
- u8 key_type;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
-
- wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x sta: %p", cmd, sta);
- wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key_conf->cipher, key_conf->keyidx,
- key_conf->keylen, key_conf->flags);
- wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF)) {
- ret = -EAGAIN;
- goto out_unlock;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_unlock;
-
- switch (key_conf->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- key_type = KEY_WEP;
-
- key_conf->hw_key_idx = key_conf->keyidx;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- key_type = KEY_TKIP;
-
- key_conf->hw_key_idx = key_conf->keyidx;
- tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
- tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- key_type = KEY_AES;
-
- key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
- tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
- tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
- break;
- case WL1271_CIPHER_SUITE_GEM:
- key_type = KEY_GEM;
- tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
- tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
- break;
- default:
- wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
-
- ret = -EOPNOTSUPP;
- goto out_sleep;
- }
-
- switch (cmd) {
- case SET_KEY:
- ret = wl1271_set_key(wl, wlvif, KEY_ADD_OR_REPLACE,
- key_conf->keyidx, key_type,
- key_conf->keylen, key_conf->key,
- tx_seq_32, tx_seq_16, sta);
- if (ret < 0) {
- wl1271_error("Could not add or replace key");
- goto out_sleep;
- }
-
- /*
- * reconfiguring arp response if the unicast (or common)
- * encryption key type was changed
- */
- if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
- (sta || key_type == KEY_WEP) &&
- wlvif->encryption_type != key_type) {
- wlvif->encryption_type = key_type;
- ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
- if (ret < 0) {
- wl1271_warning("build arp rsp failed: %d", ret);
- goto out_sleep;
- }
- }
- break;
-
- case DISABLE_KEY:
- ret = wl1271_set_key(wl, wlvif, KEY_REMOVE,
- key_conf->keyidx, key_type,
- key_conf->keylen, key_conf->key,
- 0, 0, sta);
- if (ret < 0) {
- wl1271_error("Could not remove key");
- goto out_sleep;
- }
- break;
-
- default:
- wl1271_error("Unsupported key cmd 0x%x", cmd);
- ret = -EOPNOTSUPP;
- break;
- }
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-
-out_unlock:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
-{
- struct wl1271 *wl = hw->priv;
- int ret;
- u8 *ssid = NULL;
- size_t len = 0;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");
-
- if (req->n_ssids) {
- ssid = req->ssids[0].ssid;
- len = req->ssids[0].ssid_len;
- }
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF) {
- /*
- * We cannot return -EBUSY here because cfg80211 will expect
- * a call to ieee80211_scan_completed if we do - in this case
- * there won't be any call.
- */
- ret = -EAGAIN;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /* fail if there is any role in ROC */
- if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
- /* don't allow scanning right now */
- ret = -EBUSY;
- goto out_sleep;
- }
-
- ret = wl1271_scan(hw->priv, vif, ssid, len, req);
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct wl1271 *wl = hw->priv;
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan");
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF)
- goto out;
-
- if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
- ret = wl1271_scan_stop(wl);
- if (ret < 0)
- goto out_sleep;
- }
-
- /*
- * Rearm the tx watchdog just before idling scan. This
- * prevents just-finished scans from triggering the watchdog
- */
- wl12xx_rearm_tx_watchdog_locked(wl);
-
- wl->scan.state = WL1271_SCAN_STATE_IDLE;
- memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
- wl->scan_vif = NULL;
- wl->scan.req = NULL;
- ieee80211_scan_completed(wl->hw, true);
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-
- cancel_delayed_work_sync(&wl->scan_complete_work);
-}
-
-static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF) {
- ret = -EAGAIN;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_scan_sched_scan_config(wl, wlvif, req, ies);
- if (ret < 0)
- goto out_sleep;
-
- ret = wl1271_scan_sched_scan_start(wl, wlvif);
- if (ret < 0)
- goto out_sleep;
-
- wl->sched_scanning = true;
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
- return ret;
-}
-
-static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct wl1271 *wl = hw->priv;
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF)
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1271_scan_sched_scan_stop(wl);
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
-{
- struct wl1271 *wl = hw->priv;
- int ret = 0;
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF)) {
- ret = -EAGAIN;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_acx_frag_threshold(wl, value);
- if (ret < 0)
- wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif;
- int ret = 0;
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF)) {
- ret = -EAGAIN;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- ret = wl1271_acx_rts_threshold(wl, wlvif, value);
- if (ret < 0)
- wl1271_warning("set rts threshold failed: %d", ret);
- }
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static int wl1271_ssid_set(struct ieee80211_vif *vif, struct sk_buff *skb,
- int offset)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- u8 ssid_len;
- const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
- skb->len - offset);
-
- if (!ptr) {
- wl1271_error("No SSID in IEs!");
- return -ENOENT;
- }
-
- ssid_len = ptr[1];
- if (ssid_len > IEEE80211_MAX_SSID_LEN) {
- wl1271_error("SSID is too long!");
- return -EINVAL;
- }
-
- wlvif->ssid_len = ssid_len;
- memcpy(wlvif->ssid, ptr+2, ssid_len);
- return 0;
-}
-
-static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset)
-{
- int len;
- const u8 *next, *end = skb->data + skb->len;
- u8 *ie = (u8 *)cfg80211_find_ie(eid, skb->data + ieoffset,
- skb->len - ieoffset);
- if (!ie)
- return;
- len = ie[1] + 2;
- next = ie + len;
- memmove(ie, next, end - next);
- skb_trim(skb, skb->len - len);
-}
-
-static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
- unsigned int oui, u8 oui_type,
- int ieoffset)
-{
- int len;
- const u8 *next, *end = skb->data + skb->len;
- u8 *ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
- skb->data + ieoffset,
- skb->len - ieoffset);
- if (!ie)
- return;
- len = ie[1] + 2;
- next = ie + len;
- memmove(ie, next, end - next);
- skb_trim(skb, skb->len - len);
-}
-
-static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
- struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct sk_buff *skb;
- int ret;
-
- skb = ieee80211_proberesp_get(wl->hw, vif);
- if (!skb)
- return -EOPNOTSUPP;
-
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_AP_PROBE_RESPONSE,
- skb->data,
- skb->len, 0,
- rates);
-
- dev_kfree_skb(skb);
- return ret;
-}
-
-static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- u8 *probe_rsp_data,
- size_t probe_rsp_len,
- u32 rates)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE];
- int ssid_ie_offset, ie_offset, templ_len;
- const u8 *ptr;
-
- /* no need to change probe response if the SSID is set correctly */
- if (wlvif->ssid_len > 0)
- return wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_AP_PROBE_RESPONSE,
- probe_rsp_data,
- probe_rsp_len, 0,
- rates);
-
- if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) {
- wl1271_error("probe_rsp template too big");
- return -EINVAL;
- }
-
- /* start searching from IE offset */
- ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-
- ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset,
- probe_rsp_len - ie_offset);
- if (!ptr) {
- wl1271_error("No SSID in beacon!");
- return -EINVAL;
- }
-
- ssid_ie_offset = ptr - probe_rsp_data;
- ptr += (ptr[1] + 2);
-
- memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset);
-
- /* insert SSID from bss_conf */
- probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID;
- probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len;
- memcpy(probe_rsp_templ + ssid_ie_offset + 2,
- bss_conf->ssid, bss_conf->ssid_len);
- templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len;
-
- memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len,
- ptr, probe_rsp_len - (ptr - probe_rsp_data));
- templ_len += probe_rsp_len - (ptr - probe_rsp_data);
-
- return wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_AP_PROBE_RESPONSE,
- probe_rsp_templ,
- templ_len, 0,
- rates);
-}
-
-static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret = 0;
-
- if (changed & BSS_CHANGED_ERP_SLOT) {
- if (bss_conf->use_short_slot)
- ret = wl1271_acx_slot(wl, wlvif, SLOT_TIME_SHORT);
- else
- ret = wl1271_acx_slot(wl, wlvif, SLOT_TIME_LONG);
- if (ret < 0) {
- wl1271_warning("Set slot time failed %d", ret);
- goto out;
- }
- }
-
- if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- if (bss_conf->use_short_preamble)
- wl1271_acx_set_preamble(wl, wlvif, ACX_PREAMBLE_SHORT);
- else
- wl1271_acx_set_preamble(wl, wlvif, ACX_PREAMBLE_LONG);
- }
-
- if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- if (bss_conf->use_cts_prot)
- ret = wl1271_acx_cts_protect(wl, wlvif,
- CTSPROTECT_ENABLE);
- else
- ret = wl1271_acx_cts_protect(wl, wlvif,
- CTSPROTECT_DISABLE);
- if (ret < 0) {
- wl1271_warning("Set ctsprotect failed %d", ret);
- goto out;
- }
- }
-
-out:
- return ret;
-}
-
-static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
- int ret = 0;
-
- if ((changed & BSS_CHANGED_BEACON_INT)) {
- wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d",
- bss_conf->beacon_int);
-
- wlvif->beacon_int = bss_conf->beacon_int;
- }
-
- if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) {
- u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- if (!wl1271_ap_set_probe_resp_tmpl(wl, rate, vif)) {
- wl1271_debug(DEBUG_AP, "probe response updated");
- set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags);
- }
- }
-
- if ((changed & BSS_CHANGED_BEACON)) {
- struct ieee80211_hdr *hdr;
- u32 min_rate;
- int ieoffset = offsetof(struct ieee80211_mgmt,
- u.beacon.variable);
- struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
- u16 tmpl_id;
-
- if (!beacon) {
- ret = -EINVAL;
- goto out;
- }
-
- wl1271_debug(DEBUG_MASTER, "beacon updated");
-
- ret = wl1271_ssid_set(vif, beacon, ieoffset);
- if (ret < 0) {
- dev_kfree_skb(beacon);
- goto out;
- }
- min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
- CMD_TEMPL_BEACON;
- ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
- beacon->data,
- beacon->len, 0,
- min_rate);
- if (ret < 0) {
- dev_kfree_skb(beacon);
- goto out;
- }
-
- /*
- * In case we already have a probe-resp beacon set explicitly
- * by usermode, don't use the beacon data.
- */
- if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags))
- goto end_bcn;
-
- /* remove TIM ie from probe response */
- wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset);
-
- /*
- * remove p2p ie from probe response.
- * the fw reponds to probe requests that don't include
- * the p2p ie. probe requests with p2p ie will be passed,
- * and will be responded by the supplicant (the spec
- * forbids including the p2p ie when responding to probe
- * requests that didn't include it).
- */
- wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA,
- WLAN_OUI_TYPE_WFA_P2P, ieoffset);
-
- hdr = (struct ieee80211_hdr *) beacon->data;
- hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_RESP);
- if (is_ap)
- ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif,
- beacon->data,
- beacon->len,
- min_rate);
- else
- ret = wl1271_cmd_template_set(wl, wlvif->role_id,
- CMD_TEMPL_PROBE_RESPONSE,
- beacon->data,
- beacon->len, 0,
- min_rate);
-end_bcn:
- dev_kfree_skb(beacon);
- if (ret < 0)
- goto out;
- }
-
-out:
- if (ret != 0)
- wl1271_error("beacon info change failed: %d", ret);
- return ret;
-}
-
-/* AP mode changes */
-static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret = 0;
-
- if ((changed & BSS_CHANGED_BASIC_RATES)) {
- u32 rates = bss_conf->basic_rates;
-
- wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
- wlvif->band);
- wlvif->basic_rate = wl1271_tx_min_rate_get(wl,
- wlvif->basic_rate_set);
-
- ret = wl1271_init_ap_rates(wl, wlvif);
- if (ret < 0) {
- wl1271_error("AP rate policy change failed %d", ret);
- goto out;
- }
-
- ret = wl1271_ap_init_templates(wl, vif);
- if (ret < 0)
- goto out;
- }
-
- ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
- if (ret < 0)
- goto out;
-
- if ((changed & BSS_CHANGED_BEACON_ENABLED)) {
- if (bss_conf->enable_beacon) {
- if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
- ret = wl12xx_cmd_role_start_ap(wl, wlvif);
- if (ret < 0)
- goto out;
-
- ret = wl1271_ap_init_hwenc(wl, wlvif);
- if (ret < 0)
- goto out;
-
- set_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
- wl1271_debug(DEBUG_AP, "started AP");
- }
- } else {
- if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
- ret = wl12xx_cmd_role_stop_ap(wl, wlvif);
- if (ret < 0)
- goto out;
-
- clear_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
- clear_bit(WLVIF_FLAG_AP_PROBE_RESP_SET,
- &wlvif->flags);
- wl1271_debug(DEBUG_AP, "stopped AP");
- }
- }
- }
-
- ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
- if (ret < 0)
- goto out;
-
- /* Handle HT information change */
- if ((changed & BSS_CHANGED_HT) &&
- (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
- ret = wl1271_acx_set_ht_information(wl, wlvif,
- bss_conf->ht_operation_mode);
- if (ret < 0) {
- wl1271_warning("Set ht information failed %d", ret);
- goto out;
- }
- }
-
-out:
- return;
-}
-
-/* STA/IBSS mode changes */
-static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- bool do_join = false, set_assoc = false;
- bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
- bool ibss_joined = false;
- u32 sta_rate_set = 0;
- int ret;
- struct ieee80211_sta *sta;
- bool sta_exists = false;
- struct ieee80211_sta_ht_cap sta_ht_cap;
-
- if (is_ibss) {
- ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf,
- changed);
- if (ret < 0)
- goto out;
- }
-
- if (changed & BSS_CHANGED_IBSS) {
- if (bss_conf->ibss_joined) {
- set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
- ibss_joined = true;
- } else {
- if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED,
- &wlvif->flags))
- wl1271_unjoin(wl, wlvif);
- }
- }
-
- if ((changed & BSS_CHANGED_BEACON_INT) && ibss_joined)
- do_join = true;
-
- /* Need to update the SSID (for filtering etc) */
- if ((changed & BSS_CHANGED_BEACON) && ibss_joined)
- do_join = true;
-
- if ((changed & BSS_CHANGED_BEACON_ENABLED) && ibss_joined) {
- wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
- bss_conf->enable_beacon ? "enabled" : "disabled");
-
- do_join = true;
- }
-
- if (changed & BSS_CHANGED_IDLE && !is_ibss) {
- ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
- if (ret < 0)
- wl1271_warning("idle mode change failed %d", ret);
- }
-
- if ((changed & BSS_CHANGED_CQM)) {
- bool enable = false;
- if (bss_conf->cqm_rssi_thold)
- enable = true;
- ret = wl1271_acx_rssi_snr_trigger(wl, wlvif, enable,
- bss_conf->cqm_rssi_thold,
- bss_conf->cqm_rssi_hyst);
- if (ret < 0)
- goto out;
- wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
- }
-
- if (changed & BSS_CHANGED_BSSID)
- if (!is_zero_ether_addr(bss_conf->bssid)) {
- ret = wl12xx_cmd_build_null_data(wl, wlvif);
- if (ret < 0)
- goto out;
-
- ret = wl1271_build_qos_null_data(wl, vif);
- if (ret < 0)
- goto out;
- }
-
- if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, bss_conf->bssid);
- if (!sta)
- goto sta_not_found;
-
- /* save the supp_rates of the ap */
- sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
- if (sta->ht_cap.ht_supported)
- sta_rate_set |=
- (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
- sta_ht_cap = sta->ht_cap;
- sta_exists = true;
-
-sta_not_found:
- rcu_read_unlock();
- }
-
- if ((changed & BSS_CHANGED_ASSOC)) {
- if (bss_conf->assoc) {
- u32 rates;
- int ieoffset;
- wlvif->aid = bss_conf->aid;
- wlvif->beacon_int = bss_conf->beacon_int;
- do_join = true;
- set_assoc = true;
-
- /*
- * use basic rates from AP, and determine lowest rate
- * to use with control frames.
- */
- rates = bss_conf->basic_rates;
- wlvif->basic_rate_set =
- wl1271_tx_enabled_rates_get(wl, rates,
- wlvif->band);
- wlvif->basic_rate =
- wl1271_tx_min_rate_get(wl,
- wlvif->basic_rate_set);
- if (sta_rate_set)
- wlvif->rate_set =
- wl1271_tx_enabled_rates_get(wl,
- sta_rate_set,
- wlvif->band);
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
- if (ret < 0)
- goto out;
-
- /*
- * with wl1271, we don't need to update the
- * beacon_int and dtim_period, because the firmware
- * updates it by itself when the first beacon is
- * received after a join.
- */
- ret = wl1271_cmd_build_ps_poll(wl, wlvif, wlvif->aid);
- if (ret < 0)
- goto out;
-
- /*
- * Get a template for hardware connection maintenance
- */
- dev_kfree_skb(wlvif->probereq);
- wlvif->probereq = wl1271_cmd_build_ap_probe_req(wl,
- wlvif,
- NULL);
- ieoffset = offsetof(struct ieee80211_mgmt,
- u.probe_req.variable);
- wl1271_ssid_set(vif, wlvif->probereq, ieoffset);
-
- /* enable the connection monitoring feature */
- ret = wl1271_acx_conn_monit_params(wl, wlvif, true);
- if (ret < 0)
- goto out;
- } else {
- /* use defaults when not associated */
- bool was_assoc =
- !!test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED,
- &wlvif->flags);
- bool was_ifup =
- !!test_and_clear_bit(WLVIF_FLAG_STA_STATE_SENT,
- &wlvif->flags);
- wlvif->aid = 0;
-
- /* free probe-request template */
- dev_kfree_skb(wlvif->probereq);
- wlvif->probereq = NULL;
-
- /* revert back to minimum rates for the current band */
- wl1271_set_band_rate(wl, wlvif);
- wlvif->basic_rate =
- wl1271_tx_min_rate_get(wl,
- wlvif->basic_rate_set);
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
- if (ret < 0)
- goto out;
-
- /* disable connection monitor features */
- ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
-
- /* Disable the keep-alive feature */
- ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
- if (ret < 0)
- goto out;
-
- /* restore the bssid filter and go to dummy bssid */
- if (was_assoc) {
- /*
- * we might have to disable roc, if there was
- * no IF_OPER_UP notification.
- */
- if (!was_ifup) {
- ret = wl12xx_croc(wl, wlvif->role_id);
- if (ret < 0)
- goto out;
- }
- /*
- * (we also need to disable roc in case of
- * roaming on the same channel. until we will
- * have a better flow...)
- */
- if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
- ret = wl12xx_croc(wl,
- wlvif->dev_role_id);
- if (ret < 0)
- goto out;
- }
-
- wl1271_unjoin(wl, wlvif);
- if (!bss_conf->idle)
- wl12xx_start_dev(wl, wlvif);
- }
- }
- }
-
- if (changed & BSS_CHANGED_IBSS) {
- wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d",
- bss_conf->ibss_joined);
-
- if (bss_conf->ibss_joined) {
- u32 rates = bss_conf->basic_rates;
- wlvif->basic_rate_set =
- wl1271_tx_enabled_rates_get(wl, rates,
- wlvif->band);
- wlvif->basic_rate =
- wl1271_tx_min_rate_get(wl,
- wlvif->basic_rate_set);
-
- /* by default, use 11b + OFDM rates */
- wlvif->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
- if (ret < 0)
- goto out;
- }
- }
-
- ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
- if (ret < 0)
- goto out;
-
- if (do_join) {
- ret = wl1271_join(wl, wlvif, set_assoc);
- if (ret < 0) {
- wl1271_warning("cmd join failed %d", ret);
- goto out;
- }
-
- /* ROC until connected (after EAPOL exchange) */
- if (!is_ibss) {
- ret = wl12xx_roc(wl, wlvif, wlvif->role_id);
- if (ret < 0)
- goto out;
-
- if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
- wl12xx_set_authorized(wl, wlvif);
- }
- /*
- * stop device role if started (we might already be in
- * STA/IBSS role).
- */
- if (wl12xx_dev_role_started(wlvif)) {
- ret = wl12xx_stop_dev(wl, wlvif);
- if (ret < 0)
- goto out;
- }
- }
-
- /* Handle new association with HT. Do this after join. */
- if (sta_exists) {
- if ((changed & BSS_CHANGED_HT) &&
- (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
- ret = wl1271_acx_set_ht_capabilities(wl,
- &sta_ht_cap,
- true,
- wlvif->sta.hlid);
- if (ret < 0) {
- wl1271_warning("Set ht cap true failed %d",
- ret);
- goto out;
- }
- }
- /* handle new association without HT and disassociation */
- else if (changed & BSS_CHANGED_ASSOC) {
- ret = wl1271_acx_set_ht_capabilities(wl,
- &sta_ht_cap,
- false,
- wlvif->sta.hlid);
- if (ret < 0) {
- wl1271_warning("Set ht cap false failed %d",
- ret);
- goto out;
- }
- }
- }
-
- /* Handle HT information change. Done after join. */
- if ((changed & BSS_CHANGED_HT) &&
- (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
- ret = wl1271_acx_set_ht_information(wl, wlvif,
- bss_conf->ht_operation_mode);
- if (ret < 0) {
- wl1271_warning("Set ht information failed %d", ret);
- goto out;
- }
- }
-
- /* Handle arp filtering. Done after join. */
- if ((changed & BSS_CHANGED_ARP_FILTER) ||
- (!is_ibss && (changed & BSS_CHANGED_QOS))) {
- __be32 addr = bss_conf->arp_addr_list[0];
- wlvif->sta.qos = bss_conf->qos;
- WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
-
- if (bss_conf->arp_addr_cnt == 1 &&
- bss_conf->arp_filter_enabled) {
- wlvif->ip_addr = addr;
- /*
- * The template should have been configured only upon
- * association. however, it seems that the correct ip
- * isn't being set (when sending), so we have to
- * reconfigure the template upon every ip change.
- */
- ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
- if (ret < 0) {
- wl1271_warning("build arp rsp failed: %d", ret);
- goto out;
- }
-
- ret = wl1271_acx_arp_ip_filter(wl, wlvif,
- (ACX_ARP_FILTER_ARP_FILTERING |
- ACX_ARP_FILTER_AUTO_ARP),
- addr);
- } else {
- wlvif->ip_addr = 0;
- ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr);
- }
-
- if (ret < 0)
- goto out;
- }
-
-out:
- return;
-}
-
-static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x",
- (int)changed);
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (is_ap)
- wl1271_bss_info_changed_ap(wl, vif, bss_conf, changed);
- else
- wl1271_bss_info_changed_sta(wl, vif, bss_conf, changed);
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- u8 ps_scheme;
- int ret = 0;
-
- mutex_lock(&wl->mutex);
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
-
- if (params->uapsd)
- ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
- else
- ps_scheme = CONF_PS_SCHEME_LEGACY;
-
- if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /*
- * the txop is confed in units of 32us by the mac80211,
- * we need us
- */
- ret = wl1271_acx_ac_cfg(wl, wlvif, wl1271_tx_get_queue(queue),
- params->cw_min, params->cw_max,
- params->aifs, params->txop << 5);
- if (ret < 0)
- goto out_sleep;
-
- ret = wl1271_acx_tid_cfg(wl, wlvif, wl1271_tx_get_queue(queue),
- CONF_CHANNEL_TYPE_EDCF,
- wl1271_tx_get_queue(queue),
- ps_scheme, CONF_ACK_POLICY_LEGACY,
- 0, 0);
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
-
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- u64 mactime = ULLONG_MAX;
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf");
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime);
- if (ret < 0)
- goto out_sleep;
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
- return mactime;
-}
-
-static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
- struct survey_info *survey)
-{
- struct wl1271 *wl = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
-
- if (idx != 0)
- return -ENOENT;
-
- survey->channel = conf->channel;
- survey->filled = SURVEY_INFO_NOISE_DBM;
- survey->noise = wl->noise;
-
- return 0;
-}
-
-static int wl1271_allocate_sta(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct ieee80211_sta *sta)
-{
- struct wl1271_station *wl_sta;
- int ret;
-
-
- if (wl->active_sta_count >= AP_MAX_STATIONS) {
- wl1271_warning("could not allocate HLID - too much stations");
- return -EBUSY;
- }
-
- wl_sta = (struct wl1271_station *)sta->drv_priv;
- ret = wl12xx_allocate_link(wl, wlvif, &wl_sta->hlid);
- if (ret < 0) {
- wl1271_warning("could not allocate HLID - too many links");
- return -EBUSY;
- }
-
- set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
- memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
- wl->active_sta_count++;
- return 0;
-}
-
-void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
-{
- if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
- return;
-
- clear_bit(hlid, wlvif->ap.sta_hlid_map);
- memset(wl->links[hlid].addr, 0, ETH_ALEN);
- wl->links[hlid].ba_bitmap = 0;
- __clear_bit(hlid, &wl->ap_ps_map);
- __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
- wl12xx_free_link(wl, wlvif, &hlid);
- wl->active_sta_count--;
-
- /*
- * rearm the tx watchdog when the last STA is freed - give the FW a
- * chance to return STA-buffered packets before complaining.
- */
- if (wl->active_sta_count == 0)
- wl12xx_rearm_tx_watchdog_locked(wl);
-}
-
-static int wl12xx_sta_add(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct ieee80211_sta *sta)
-{
- struct wl1271_station *wl_sta;
- int ret = 0;
- u8 hlid;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid);
-
- ret = wl1271_allocate_sta(wl, wlvif, sta);
- if (ret < 0)
- return ret;
-
- wl_sta = (struct wl1271_station *)sta->drv_priv;
- hlid = wl_sta->hlid;
-
- ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid);
- if (ret < 0)
- wl1271_free_sta(wl, wlvif, hlid);
-
- return ret;
-}
-
-static int wl12xx_sta_remove(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct ieee80211_sta *sta)
-{
- struct wl1271_station *wl_sta;
- int ret = 0, id;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);
-
- wl_sta = (struct wl1271_station *)sta->drv_priv;
- id = wl_sta->hlid;
- if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
- return -EINVAL;
-
- ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
- if (ret < 0)
- return ret;
-
- wl1271_free_sta(wl, wlvif, wl_sta->hlid);
- return ret;
-}
-
-static int wl12xx_update_sta_state(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct ieee80211_sta *sta,
- enum ieee80211_sta_state old_state,
- enum ieee80211_sta_state new_state)
-{
- struct wl1271_station *wl_sta;
- u8 hlid;
- bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
- bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
- int ret;
-
- wl_sta = (struct wl1271_station *)sta->drv_priv;
- hlid = wl_sta->hlid;
-
- /* Add station (AP mode) */
- if (is_ap &&
- old_state == IEEE80211_STA_NOTEXIST &&
- new_state == IEEE80211_STA_NONE)
- return wl12xx_sta_add(wl, wlvif, sta);
-
- /* Remove station (AP mode) */
- if (is_ap &&
- old_state == IEEE80211_STA_NONE &&
- new_state == IEEE80211_STA_NOTEXIST) {
- /* must not fail */
- wl12xx_sta_remove(wl, wlvif, sta);
- return 0;
- }
-
- /* Authorize station (AP mode) */
- if (is_ap &&
- new_state == IEEE80211_STA_AUTHORIZED) {
- ret = wl12xx_cmd_set_peer_state(wl, hlid);
- if (ret < 0)
- return ret;
-
- ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
- hlid);
- return ret;
- }
-
- /* Authorize station */
- if (is_sta &&
- new_state == IEEE80211_STA_AUTHORIZED) {
- set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
- return wl12xx_set_authorized(wl, wlvif);
- }
-
- if (is_sta &&
- old_state == IEEE80211_STA_AUTHORIZED &&
- new_state == IEEE80211_STA_ASSOC) {
- clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
- return 0;
- }
-
- return 0;
-}
-
-static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- enum ieee80211_sta_state old_state,
- enum ieee80211_sta_state new_state)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d",
- sta->aid, old_state, new_state);
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF)) {
- ret = -EBUSY;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state);
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
- if (new_state < old_state)
- return 0;
- return ret;
-}
-
-static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
- u8 buf_size)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret;
- u8 hlid, *ba_bitmap;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu action %d tid %d", action,
- tid);
-
- /* sanity check - the fields in FW are only 8bits wide */
- if (WARN_ON(tid > 0xFF))
- return -ENOTSUPP;
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF)) {
- ret = -EAGAIN;
- goto out;
- }
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
- hlid = wlvif->sta.hlid;
- ba_bitmap = &wlvif->sta.ba_rx_bitmap;
- } else if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
- struct wl1271_station *wl_sta;
-
- wl_sta = (struct wl1271_station *)sta->drv_priv;
- hlid = wl_sta->hlid;
- ba_bitmap = &wl->links[hlid].ba_bitmap;
- } else {
- ret = -EINVAL;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d",
- tid, action);
-
- switch (action) {
- case IEEE80211_AMPDU_RX_START:
- if (!wlvif->ba_support || !wlvif->ba_allowed) {
- ret = -ENOTSUPP;
- break;
- }
-
- if (wl->ba_rx_session_count >= RX_BA_MAX_SESSIONS) {
- ret = -EBUSY;
- wl1271_error("exceeded max RX BA sessions");
- break;
- }
-
- if (*ba_bitmap & BIT(tid)) {
- ret = -EINVAL;
- wl1271_error("cannot enable RX BA session on active "
- "tid: %d", tid);
- break;
- }
-
- ret = wl12xx_acx_set_ba_receiver_session(wl, tid, *ssn, true,
- hlid);
- if (!ret) {
- *ba_bitmap |= BIT(tid);
- wl->ba_rx_session_count++;
- }
- break;
-
- case IEEE80211_AMPDU_RX_STOP:
- if (!(*ba_bitmap & BIT(tid))) {
- ret = -EINVAL;
- wl1271_error("no active RX BA session on tid: %d",
- tid);
- break;
- }
-
- ret = wl12xx_acx_set_ba_receiver_session(wl, tid, 0, false,
- hlid);
- if (!ret) {
- *ba_bitmap &= ~BIT(tid);
- wl->ba_rx_session_count--;
- }
- break;
-
- /*
- * The BA initiator session management in FW independently.
- * Falling break here on purpose for all TX APDU commands.
- */
- case IEEE80211_AMPDU_TX_START:
- case IEEE80211_AMPDU_TX_STOP:
- case IEEE80211_AMPDU_TX_OPERATIONAL:
- ret = -EINVAL;
- break;
-
- default:
- wl1271_error("Incorrect ampdu action id=%x\n", action);
- ret = -EINVAL;
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- const struct cfg80211_bitrate_mask *mask)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct wl1271 *wl = hw->priv;
- int i, ret = 0;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x",
- mask->control[NL80211_BAND_2GHZ].legacy,
- mask->control[NL80211_BAND_5GHZ].legacy);
-
- mutex_lock(&wl->mutex);
-
- for (i = 0; i < IEEE80211_NUM_BANDS; i++)
- wlvif->bitrate_masks[i] =
- wl1271_tx_enabled_rates_get(wl,
- mask->control[i].legacy,
- i);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
- !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1271_set_band_rate(wl, wlvif);
- wlvif->basic_rate =
- wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
- ret = wl1271_acx_sta_rate_policies(wl, wlvif);
-
- wl1271_ps_elp_sleep(wl);
- }
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
- struct ieee80211_channel_switch *ch_switch)
-{
- struct wl1271 *wl = hw->priv;
- struct wl12xx_vif *wlvif;
- int ret;
-
- wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");
-
- wl1271_tx_flush(wl);
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF)) {
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
- ieee80211_chswitch_done(vif, false);
- }
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /* TODO: change mac80211 to pass vif as param */
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch);
-
- if (!ret)
- set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
- }
-
- wl1271_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
-{
- struct wl1271 *wl = hw->priv;
- bool ret = false;
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- /* packets are considered pending if in the TX queue or the FW */
- ret = (wl1271_tx_total_queue_count(wl) > 0) || (wl->tx_frames_cnt > 0);
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_rate wl1271_rates[] = {
- { .bitrate = 10,
- .hw_value = CONF_HW_BIT_RATE_1MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_1MBPS, },
- { .bitrate = 20,
- .hw_value = CONF_HW_BIT_RATE_2MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
- .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 55,
- .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
- .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 110,
- .hw_value = CONF_HW_BIT_RATE_11MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
- .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 60,
- .hw_value = CONF_HW_BIT_RATE_6MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
- { .bitrate = 90,
- .hw_value = CONF_HW_BIT_RATE_9MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
- { .bitrate = 120,
- .hw_value = CONF_HW_BIT_RATE_12MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
- { .bitrate = 180,
- .hw_value = CONF_HW_BIT_RATE_18MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
- { .bitrate = 240,
- .hw_value = CONF_HW_BIT_RATE_24MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
- { .bitrate = 360,
- .hw_value = CONF_HW_BIT_RATE_36MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
- { .bitrate = 480,
- .hw_value = CONF_HW_BIT_RATE_48MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
- { .bitrate = 540,
- .hw_value = CONF_HW_BIT_RATE_54MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_channel wl1271_channels[] = {
- { .hw_value = 1, .center_freq = 2412, .max_power = 25 },
- { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
- { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
- { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
- { .hw_value = 5, .center_freq = 2432, .max_power = 25 },
- { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
- { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
- { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
- { .hw_value = 9, .center_freq = 2452, .max_power = 25 },
- { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
- { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
- { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
- { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
- { .hw_value = 14, .center_freq = 2484, .max_power = 25 },
-};
-
-/* mapping to indexes for wl1271_rates */
-static const u8 wl1271_rate_to_idx_2ghz[] = {
- /* MCS rates are used only with 11n */
- 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */
- 7, /* CONF_HW_RXTX_RATE_MCS7 */
- 6, /* CONF_HW_RXTX_RATE_MCS6 */
- 5, /* CONF_HW_RXTX_RATE_MCS5 */
- 4, /* CONF_HW_RXTX_RATE_MCS4 */
- 3, /* CONF_HW_RXTX_RATE_MCS3 */
- 2, /* CONF_HW_RXTX_RATE_MCS2 */
- 1, /* CONF_HW_RXTX_RATE_MCS1 */
- 0, /* CONF_HW_RXTX_RATE_MCS0 */
-
- 11, /* CONF_HW_RXTX_RATE_54 */
- 10, /* CONF_HW_RXTX_RATE_48 */
- 9, /* CONF_HW_RXTX_RATE_36 */
- 8, /* CONF_HW_RXTX_RATE_24 */
-
- /* TI-specific rate */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
-
- 7, /* CONF_HW_RXTX_RATE_18 */
- 6, /* CONF_HW_RXTX_RATE_12 */
- 3, /* CONF_HW_RXTX_RATE_11 */
- 5, /* CONF_HW_RXTX_RATE_9 */
- 4, /* CONF_HW_RXTX_RATE_6 */
- 2, /* CONF_HW_RXTX_RATE_5_5 */
- 1, /* CONF_HW_RXTX_RATE_2 */
- 0 /* CONF_HW_RXTX_RATE_1 */
-};
-
-/* 11n STA capabilities */
-#define HW_RX_HIGHEST_RATE 72
-
-#define WL12XX_HT_CAP { \
- .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
- (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
- .ht_supported = true, \
- .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
- .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
- .mcs = { \
- .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
- .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
- .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
- }, \
-}
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_supported_band wl1271_band_2ghz = {
- .channels = wl1271_channels,
- .n_channels = ARRAY_SIZE(wl1271_channels),
- .bitrates = wl1271_rates,
- .n_bitrates = ARRAY_SIZE(wl1271_rates),
- .ht_cap = WL12XX_HT_CAP,
-};
-
-/* 5 GHz data rates for WL1273 */
-static struct ieee80211_rate wl1271_rates_5ghz[] = {
- { .bitrate = 60,
- .hw_value = CONF_HW_BIT_RATE_6MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
- { .bitrate = 90,
- .hw_value = CONF_HW_BIT_RATE_9MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
- { .bitrate = 120,
- .hw_value = CONF_HW_BIT_RATE_12MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
- { .bitrate = 180,
- .hw_value = CONF_HW_BIT_RATE_18MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
- { .bitrate = 240,
- .hw_value = CONF_HW_BIT_RATE_24MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
- { .bitrate = 360,
- .hw_value = CONF_HW_BIT_RATE_36MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
- { .bitrate = 480,
- .hw_value = CONF_HW_BIT_RATE_48MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
- { .bitrate = 540,
- .hw_value = CONF_HW_BIT_RATE_54MBPS,
- .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
-};
-
-/* 5 GHz band channels for WL1273 */
-static struct ieee80211_channel wl1271_channels_5ghz[] = {
- { .hw_value = 7, .center_freq = 5035, .max_power = 25 },
- { .hw_value = 8, .center_freq = 5040, .max_power = 25 },
- { .hw_value = 9, .center_freq = 5045, .max_power = 25 },
- { .hw_value = 11, .center_freq = 5055, .max_power = 25 },
- { .hw_value = 12, .center_freq = 5060, .max_power = 25 },
- { .hw_value = 16, .center_freq = 5080, .max_power = 25 },
- { .hw_value = 34, .center_freq = 5170, .max_power = 25 },
- { .hw_value = 36, .center_freq = 5180, .max_power = 25 },
- { .hw_value = 38, .center_freq = 5190, .max_power = 25 },
- { .hw_value = 40, .center_freq = 5200, .max_power = 25 },
- { .hw_value = 42, .center_freq = 5210, .max_power = 25 },
- { .hw_value = 44, .center_freq = 5220, .max_power = 25 },
- { .hw_value = 46, .center_freq = 5230, .max_power = 25 },
- { .hw_value = 48, .center_freq = 5240, .max_power = 25 },
- { .hw_value = 52, .center_freq = 5260, .max_power = 25 },
- { .hw_value = 56, .center_freq = 5280, .max_power = 25 },
- { .hw_value = 60, .center_freq = 5300, .max_power = 25 },
- { .hw_value = 64, .center_freq = 5320, .max_power = 25 },
- { .hw_value = 100, .center_freq = 5500, .max_power = 25 },
- { .hw_value = 104, .center_freq = 5520, .max_power = 25 },
- { .hw_value = 108, .center_freq = 5540, .max_power = 25 },
- { .hw_value = 112, .center_freq = 5560, .max_power = 25 },
- { .hw_value = 116, .center_freq = 5580, .max_power = 25 },
- { .hw_value = 120, .center_freq = 5600, .max_power = 25 },
- { .hw_value = 124, .center_freq = 5620, .max_power = 25 },
- { .hw_value = 128, .center_freq = 5640, .max_power = 25 },
- { .hw_value = 132, .center_freq = 5660, .max_power = 25 },
- { .hw_value = 136, .center_freq = 5680, .max_power = 25 },
- { .hw_value = 140, .center_freq = 5700, .max_power = 25 },
- { .hw_value = 149, .center_freq = 5745, .max_power = 25 },
- { .hw_value = 153, .center_freq = 5765, .max_power = 25 },
- { .hw_value = 157, .center_freq = 5785, .max_power = 25 },
- { .hw_value = 161, .center_freq = 5805, .max_power = 25 },
- { .hw_value = 165, .center_freq = 5825, .max_power = 25 },
-};
-
-/* mapping to indexes for wl1271_rates_5ghz */
-static const u8 wl1271_rate_to_idx_5ghz[] = {
- /* MCS rates are used only with 11n */
- 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */
- 7, /* CONF_HW_RXTX_RATE_MCS7 */
- 6, /* CONF_HW_RXTX_RATE_MCS6 */
- 5, /* CONF_HW_RXTX_RATE_MCS5 */
- 4, /* CONF_HW_RXTX_RATE_MCS4 */
- 3, /* CONF_HW_RXTX_RATE_MCS3 */
- 2, /* CONF_HW_RXTX_RATE_MCS2 */
- 1, /* CONF_HW_RXTX_RATE_MCS1 */
- 0, /* CONF_HW_RXTX_RATE_MCS0 */
-
- 7, /* CONF_HW_RXTX_RATE_54 */
- 6, /* CONF_HW_RXTX_RATE_48 */
- 5, /* CONF_HW_RXTX_RATE_36 */
- 4, /* CONF_HW_RXTX_RATE_24 */
-
- /* TI-specific rate */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
-
- 3, /* CONF_HW_RXTX_RATE_18 */
- 2, /* CONF_HW_RXTX_RATE_12 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */
- 1, /* CONF_HW_RXTX_RATE_9 */
- 0, /* CONF_HW_RXTX_RATE_6 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */
- CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */
- CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */
-};
-
-static struct ieee80211_supported_band wl1271_band_5ghz = {
- .channels = wl1271_channels_5ghz,
- .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
- .bitrates = wl1271_rates_5ghz,
- .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
- .ht_cap = WL12XX_HT_CAP,
-};
-
-static const u8 *wl1271_band_rate_to_idx[] = {
- [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
- [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
-};
-
-static const struct ieee80211_ops wl1271_ops = {
- .start = wl1271_op_start,
- .stop = wl1271_op_stop,
- .add_interface = wl1271_op_add_interface,
- .remove_interface = wl1271_op_remove_interface,
- .change_interface = wl12xx_op_change_interface,
-#ifdef CONFIG_PM
- .suspend = wl1271_op_suspend,
- .resume = wl1271_op_resume,
-#endif
- .config = wl1271_op_config,
- .prepare_multicast = wl1271_op_prepare_multicast,
- .configure_filter = wl1271_op_configure_filter,
- .tx = wl1271_op_tx,
- .set_key = wl1271_op_set_key,
- .hw_scan = wl1271_op_hw_scan,
- .cancel_hw_scan = wl1271_op_cancel_hw_scan,
- .sched_scan_start = wl1271_op_sched_scan_start,
- .sched_scan_stop = wl1271_op_sched_scan_stop,
- .bss_info_changed = wl1271_op_bss_info_changed,
- .set_frag_threshold = wl1271_op_set_frag_threshold,
- .set_rts_threshold = wl1271_op_set_rts_threshold,
- .conf_tx = wl1271_op_conf_tx,
- .get_tsf = wl1271_op_get_tsf,
- .get_survey = wl1271_op_get_survey,
- .sta_state = wl12xx_op_sta_state,
- .ampdu_action = wl1271_op_ampdu_action,
- .tx_frames_pending = wl1271_tx_frames_pending,
- .set_bitrate_mask = wl12xx_set_bitrate_mask,
- .channel_switch = wl12xx_op_channel_switch,
- CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
-};
-
-
-u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band)
-{
- u8 idx;
-
- BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
-
- if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
- wl1271_error("Illegal RX rate from HW: %d", rate);
- return 0;
- }
-
- idx = wl1271_band_rate_to_idx[band][rate];
- if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
- wl1271_error("Unsupported RX rate from HW: %d", rate);
- return 0;
- }
-
- return idx;
-}
-
-static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct wl1271 *wl = dev_get_drvdata(dev);
- ssize_t len;
-
- len = PAGE_SIZE;
-
- mutex_lock(&wl->mutex);
- len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
- wl->sg_enabled);
- mutex_unlock(&wl->mutex);
-
- return len;
-
-}
-
-static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct wl1271 *wl = dev_get_drvdata(dev);
- unsigned long res;
- int ret;
-
- ret = kstrtoul(buf, 10, &res);
- if (ret < 0) {
- wl1271_warning("incorrect value written to bt_coex_mode");
- return count;
- }
-
- mutex_lock(&wl->mutex);
-
- res = !!res;
-
- if (res == wl->sg_enabled)
- goto out;
-
- wl->sg_enabled = res;
-
- if (wl->state == WL1271_STATE_OFF)
- goto out;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1271_acx_sg_enable(wl, wl->sg_enabled);
- wl1271_ps_elp_sleep(wl);
-
- out:
- mutex_unlock(&wl->mutex);
- return count;
-}
-
-static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
- wl1271_sysfs_show_bt_coex_state,
- wl1271_sysfs_store_bt_coex_state);
-
-static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct wl1271 *wl = dev_get_drvdata(dev);
- ssize_t len;
-
- len = PAGE_SIZE;
-
- mutex_lock(&wl->mutex);
- if (wl->hw_pg_ver >= 0)
- len = snprintf(buf, len, "%d\n", wl->hw_pg_ver);
- else
- len = snprintf(buf, len, "n/a\n");
- mutex_unlock(&wl->mutex);
-
- return len;
-}
-
-static DEVICE_ATTR(hw_pg_ver, S_IRUGO,
- wl1271_sysfs_show_hw_pg_ver, NULL);
-
-static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buffer, loff_t pos, size_t count)
-{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct wl1271 *wl = dev_get_drvdata(dev);
- ssize_t len;
- int ret;
-
- ret = mutex_lock_interruptible(&wl->mutex);
- if (ret < 0)
- return -ERESTARTSYS;
-
- /* Let only one thread read the log at a time, blocking others */
- while (wl->fwlog_size == 0) {
- DEFINE_WAIT(wait);
-
- prepare_to_wait_exclusive(&wl->fwlog_waitq,
- &wait,
- TASK_INTERRUPTIBLE);
-
- if (wl->fwlog_size != 0) {
- finish_wait(&wl->fwlog_waitq, &wait);
- break;
- }
-
- mutex_unlock(&wl->mutex);
-
- schedule();
- finish_wait(&wl->fwlog_waitq, &wait);
-
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- ret = mutex_lock_interruptible(&wl->mutex);
- if (ret < 0)
- return -ERESTARTSYS;
- }
-
- /* Check if the fwlog is still valid */
- if (wl->fwlog_size < 0) {
- mutex_unlock(&wl->mutex);
- return 0;
- }
-
- /* Seeking is not supported - old logs are not kept. Disregard pos. */
- len = min(count, (size_t)wl->fwlog_size);
- wl->fwlog_size -= len;
- memcpy(buffer, wl->fwlog, len);
-
- /* Make room for new messages */
- memmove(wl->fwlog, wl->fwlog + len, wl->fwlog_size);
-
- mutex_unlock(&wl->mutex);
-
- return len;
-}
-
-static struct bin_attribute fwlog_attr = {
- .attr = {.name = "fwlog", .mode = S_IRUSR},
- .read = wl1271_sysfs_read_fwlog,
-};
-
-static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
-{
- bool supported = false;
- u8 major, minor;
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
- minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
-
- /* in wl128x we have the MAC address if the PG is >= (2, 1) */
- if (major > 2 || (major == 2 && minor >= 1))
- supported = true;
- } else {
- major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
- minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
-
- /* in wl127x we have the MAC address if the PG is >= (3, 1) */
- if (major == 3 && minor >= 1)
- supported = true;
- }
-
- wl1271_debug(DEBUG_PROBE,
- "PG Ver major = %d minor = %d, MAC %s present",
- major, minor, supported ? "is" : "is not");
-
- return supported;
-}
-
-static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
- u32 oui, u32 nic, int n)
-{
- int i;
-
- wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x, n %d",
- oui, nic, n);
-
- if (nic + n - 1 > 0xffffff)
- wl1271_warning("NIC part of the MAC address wraps around!");
-
- for (i = 0; i < n; i++) {
- wl->addresses[i].addr[0] = (u8)(oui >> 16);
- wl->addresses[i].addr[1] = (u8)(oui >> 8);
- wl->addresses[i].addr[2] = (u8) oui;
- wl->addresses[i].addr[3] = (u8)(nic >> 16);
- wl->addresses[i].addr[4] = (u8)(nic >> 8);
- wl->addresses[i].addr[5] = (u8) nic;
- nic++;
- }
-
- wl->hw->wiphy->n_addresses = n;
- wl->hw->wiphy->addresses = wl->addresses;
-}
-
-static void wl12xx_get_fuse_mac(struct wl1271 *wl)
-{
- u32 mac1, mac2;
-
- wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
-
- mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
- mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
-
- /* these are the two parts of the BD_ADDR */
- wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
- ((mac1 & 0xff000000) >> 24);
- wl->fuse_nic_addr = mac1 & 0xffffff;
-
- wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
-}
-
-static int wl12xx_get_hw_info(struct wl1271 *wl)
-{
- int ret;
- u32 die_info;
-
- ret = wl12xx_set_power_on(wl);
- if (ret < 0)
- goto out;
-
- wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
-
- if (wl->chip.id == CHIP_ID_1283_PG20)
- die_info = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
- else
- die_info = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
-
- wl->hw_pg_ver = (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
-
- if (!wl12xx_mac_in_fuse(wl)) {
- wl->fuse_oui_addr = 0;
- wl->fuse_nic_addr = 0;
- } else {
- wl12xx_get_fuse_mac(wl);
- }
-
- wl1271_power_off(wl);
-out:
- return ret;
-}
-
-static int wl1271_register_hw(struct wl1271 *wl)
-{
- int ret;
- u32 oui_addr = 0, nic_addr = 0;
-
- if (wl->mac80211_registered)
- return 0;
-
- ret = wl12xx_get_hw_info(wl);
- if (ret < 0) {
- wl1271_error("couldn't get hw info");
- goto out;
- }
-
- ret = wl1271_fetch_nvs(wl);
- if (ret == 0) {
- /* NOTE: The wl->nvs->nvs element must be first, in
- * order to simplify the casting, we assume it is at
- * the beginning of the wl->nvs structure.
- */
- u8 *nvs_ptr = (u8 *)wl->nvs;
-
- oui_addr =
- (nvs_ptr[11] << 16) + (nvs_ptr[10] << 8) + nvs_ptr[6];
- nic_addr =
- (nvs_ptr[5] << 16) + (nvs_ptr[4] << 8) + nvs_ptr[3];
- }
-
- /* if the MAC address is zeroed in the NVS derive from fuse */
- if (oui_addr == 0 && nic_addr == 0) {
- oui_addr = wl->fuse_oui_addr;
- /* fuse has the BD_ADDR, the WLAN addresses are the next two */
- nic_addr = wl->fuse_nic_addr + 1;
- }
-
- wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr, 2);
-
- ret = ieee80211_register_hw(wl->hw);
- if (ret < 0) {
- wl1271_error("unable to register mac80211 hw: %d", ret);
- goto out;
- }
-
- wl->mac80211_registered = true;
-
- wl1271_debugfs_init(wl);
-
- wl1271_notice("loaded");
-
-out:
- return ret;
-}
-
-static void wl1271_unregister_hw(struct wl1271 *wl)
-{
- if (wl->plt)
- wl1271_plt_stop(wl);
-
- ieee80211_unregister_hw(wl->hw);
- wl->mac80211_registered = false;
-
-}
-
-static int wl1271_init_ieee80211(struct wl1271 *wl)
-{
- static const u32 cipher_suites[] = {
- WLAN_CIPHER_SUITE_WEP40,
- WLAN_CIPHER_SUITE_WEP104,
- WLAN_CIPHER_SUITE_TKIP,
- WLAN_CIPHER_SUITE_CCMP,
- WL1271_CIPHER_SUITE_GEM,
- };
-
- /* The tx descriptor buffer and the TKIP space. */
- wl->hw->extra_tx_headroom = WL1271_EXTRA_SPACE_TKIP +
- sizeof(struct wl1271_tx_hw_descr);
-
- /* unit us */
- /* FIXME: find a proper value */
- wl->hw->channel_change_time = 10000;
- wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
-
- wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
- IEEE80211_HW_SUPPORTS_UAPSD |
- IEEE80211_HW_HAS_RATE_CONTROL |
- IEEE80211_HW_CONNECTION_MONITOR |
- IEEE80211_HW_REPORTS_TX_ACK_STATUS |
- IEEE80211_HW_SPECTRUM_MGMT |
- IEEE80211_HW_AP_LINK_PS |
- IEEE80211_HW_AMPDU_AGGREGATION |
- IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
- IEEE80211_HW_SCAN_WHILE_IDLE;
-
- wl->hw->wiphy->cipher_suites = cipher_suites;
- wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-
- wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
- wl->hw->wiphy->max_scan_ssids = 1;
- wl->hw->wiphy->max_sched_scan_ssids = 16;
- wl->hw->wiphy->max_match_sets = 16;
- /*
- * Maximum length of elements in scanning probe request templates
- * should be the maximum length possible for a template, without
- * the IEEE80211 header of the template
- */
- wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
- sizeof(struct ieee80211_header);
-
- wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
- sizeof(struct ieee80211_header);
-
- wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
-
- /* make sure all our channels fit in the scanned_ch bitmask */
- BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) +
- ARRAY_SIZE(wl1271_channels_5ghz) >
- WL1271_MAX_CHANNELS);
- /*
- * We keep local copies of the band structs because we need to
- * modify them on a per-device basis.
- */
- memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz,
- sizeof(wl1271_band_2ghz));
- memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz,
- sizeof(wl1271_band_5ghz));
-
- wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
- &wl->bands[IEEE80211_BAND_2GHZ];
- wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
- &wl->bands[IEEE80211_BAND_5GHZ];
-
- wl->hw->queues = 4;
- wl->hw->max_rates = 1;
-
- wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
-
- /* the FW answers probe-requests in AP-mode */
- wl->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
- wl->hw->wiphy->probe_resp_offload =
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
-
- SET_IEEE80211_DEV(wl->hw, wl->dev);
-
- wl->hw->sta_data_size = sizeof(struct wl1271_station);
- wl->hw->vif_data_size = sizeof(struct wl12xx_vif);
-
- wl->hw->max_rx_aggregation_subframes = 8;
-
- return 0;
-}
-
-#define WL1271_DEFAULT_CHANNEL 0
-
-static struct ieee80211_hw *wl1271_alloc_hw(void)
-{
- struct ieee80211_hw *hw;
- struct wl1271 *wl;
- int i, j, ret;
- unsigned int order;
-
- BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS);
-
- hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
- if (!hw) {
- wl1271_error("could not alloc ieee80211_hw");
- ret = -ENOMEM;
- goto err_hw_alloc;
- }
-
- wl = hw->priv;
- memset(wl, 0, sizeof(*wl));
-
- INIT_LIST_HEAD(&wl->wlvif_list);
-
- wl->hw = hw;
-
- for (i = 0; i < NUM_TX_QUEUES; i++)
- for (j = 0; j < WL12XX_MAX_LINKS; j++)
- skb_queue_head_init(&wl->links[j].tx_queue[i]);
-
- skb_queue_head_init(&wl->deferred_rx_queue);
- skb_queue_head_init(&wl->deferred_tx_queue);
-
- INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
- INIT_WORK(&wl->netstack_work, wl1271_netstack_work);
- INIT_WORK(&wl->tx_work, wl1271_tx_work);
- INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
- INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
- INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
-
- wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
- if (!wl->freezable_wq) {
- ret = -ENOMEM;
- goto err_hw;
- }
-
- wl->channel = WL1271_DEFAULT_CHANNEL;
- wl->rx_counter = 0;
- wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
- wl->band = IEEE80211_BAND_2GHZ;
- wl->flags = 0;
- wl->sg_enabled = true;
- wl->hw_pg_ver = -1;
- wl->ap_ps_map = 0;
- wl->ap_fw_ps_map = 0;
- wl->quirks = 0;
- wl->platform_quirks = 0;
- wl->sched_scanning = false;
- wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
- wl->system_hlid = WL12XX_SYSTEM_HLID;
- wl->active_sta_count = 0;
- wl->fwlog_size = 0;
- init_waitqueue_head(&wl->fwlog_waitq);
-
- /* The system link is always allocated */
- __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
-
- memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
- for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
- wl->tx_frames[i] = NULL;
-
- spin_lock_init(&wl->wl_lock);
-
- wl->state = WL1271_STATE_OFF;
- wl->fw_type = WL12XX_FW_TYPE_NONE;
- mutex_init(&wl->mutex);
-
- /* Apply default driver configuration. */
- wl1271_conf_init(wl);
-
- order = get_order(WL1271_AGGR_BUFFER_SIZE);
- wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
- if (!wl->aggr_buf) {
- ret = -ENOMEM;
- goto err_wq;
- }
-
- wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
- if (!wl->dummy_packet) {
- ret = -ENOMEM;
- goto err_aggr;
- }
-
- /* Allocate one page for the FW log */
- wl->fwlog = (u8 *)get_zeroed_page(GFP_KERNEL);
- if (!wl->fwlog) {
- ret = -ENOMEM;
- goto err_dummy_packet;
- }
-
- wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_DMA);
- if (!wl->mbox) {
- ret = -ENOMEM;
- goto err_fwlog;
- }
-
- return hw;
-
-err_fwlog:
- free_page((unsigned long)wl->fwlog);
-
-err_dummy_packet:
- dev_kfree_skb(wl->dummy_packet);
-
-err_aggr:
- free_pages((unsigned long)wl->aggr_buf, order);
-
-err_wq:
- destroy_workqueue(wl->freezable_wq);
-
-err_hw:
- wl1271_debugfs_exit(wl);
- ieee80211_free_hw(hw);
-
-err_hw_alloc:
-
- return ERR_PTR(ret);
-}
-
-static int wl1271_free_hw(struct wl1271 *wl)
-{
- /* Unblock any fwlog readers */
- mutex_lock(&wl->mutex);
- wl->fwlog_size = -1;
- wake_up_interruptible_all(&wl->fwlog_waitq);
- mutex_unlock(&wl->mutex);
-
- device_remove_bin_file(wl->dev, &fwlog_attr);
-
- device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
-
- device_remove_file(wl->dev, &dev_attr_bt_coex_state);
- free_page((unsigned long)wl->fwlog);
- dev_kfree_skb(wl->dummy_packet);
- free_pages((unsigned long)wl->aggr_buf,
- get_order(WL1271_AGGR_BUFFER_SIZE));
-
- wl1271_debugfs_exit(wl);
-
- vfree(wl->fw);
- wl->fw = NULL;
- wl->fw_type = WL12XX_FW_TYPE_NONE;
- kfree(wl->nvs);
- wl->nvs = NULL;
-
- kfree(wl->fw_status);
- kfree(wl->tx_res_if);
- destroy_workqueue(wl->freezable_wq);
-
- ieee80211_free_hw(wl->hw);
-
- return 0;
-}
-
-static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
-{
- struct wl1271 *wl = cookie;
- unsigned long flags;
-
- wl1271_debug(DEBUG_IRQ, "IRQ");
-
- /* complete the ELP completion */
- spin_lock_irqsave(&wl->wl_lock, flags);
- set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
- if (wl->elp_compl) {
- complete(wl->elp_compl);
- wl->elp_compl = NULL;
- }
-
- if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
- /* don't enqueue a work right now. mark it as pending */
- set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
- wl1271_debug(DEBUG_IRQ, "should not enqueue work");
- disable_irq_nosync(wl->irq);
- pm_wakeup_event(wl->dev, 0);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- return IRQ_HANDLED;
- }
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- return IRQ_WAKE_THREAD;
-}
-
-static int __devinit wl12xx_probe(struct platform_device *pdev)
-{
- struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
- struct ieee80211_hw *hw;
- struct wl1271 *wl;
- unsigned long irqflags;
- int ret = -ENODEV;
-
- hw = wl1271_alloc_hw();
- if (IS_ERR(hw)) {
- wl1271_error("can't allocate hw");
- ret = PTR_ERR(hw);
- goto out;
- }
-
- wl = hw->priv;
- wl->irq = platform_get_irq(pdev, 0);
- wl->ref_clock = pdata->board_ref_clock;
- wl->tcxo_clock = pdata->board_tcxo_clock;
- wl->platform_quirks = pdata->platform_quirks;
- wl->set_power = pdata->set_power;
- wl->dev = &pdev->dev;
- wl->if_ops = pdata->ops;
-
- platform_set_drvdata(pdev, wl);
-
- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
- irqflags = IRQF_TRIGGER_RISING;
- else
- irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
-
- ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wl1271_irq,
- irqflags,
- pdev->name, wl);
- if (ret < 0) {
- wl1271_error("request_irq() failed: %d", ret);
- goto out_free_hw;
- }
-
- ret = enable_irq_wake(wl->irq);
- if (!ret) {
- wl->irq_wake_enabled = true;
- device_init_wakeup(wl->dev, 1);
- if (pdata->pwr_in_suspend)
- hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
-
- }
- disable_irq(wl->irq);
-
- ret = wl1271_init_ieee80211(wl);
- if (ret)
- goto out_irq;
-
- ret = wl1271_register_hw(wl);
- if (ret)
- goto out_irq;
-
- /* Create sysfs file to control bt coex state */
- ret = device_create_file(wl->dev, &dev_attr_bt_coex_state);
- if (ret < 0) {
- wl1271_error("failed to create sysfs file bt_coex_state");
- goto out_irq;
- }
-
- /* Create sysfs file to get HW PG version */
- ret = device_create_file(wl->dev, &dev_attr_hw_pg_ver);
- if (ret < 0) {
- wl1271_error("failed to create sysfs file hw_pg_ver");
- goto out_bt_coex_state;
- }
-
- /* Create sysfs file for the FW log */
- ret = device_create_bin_file(wl->dev, &fwlog_attr);
- if (ret < 0) {
- wl1271_error("failed to create sysfs file fwlog");
- goto out_hw_pg_ver;
- }
-
- return 0;
-
-out_hw_pg_ver:
- device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
-
-out_bt_coex_state:
- device_remove_file(wl->dev, &dev_attr_bt_coex_state);
-
-out_irq:
- free_irq(wl->irq, wl);
-
-out_free_hw:
- wl1271_free_hw(wl);
-
-out:
- return ret;
-}
-
-static int __devexit wl12xx_remove(struct platform_device *pdev)
-{
- struct wl1271 *wl = platform_get_drvdata(pdev);
-
- if (wl->irq_wake_enabled) {
- device_init_wakeup(wl->dev, 0);
- disable_irq_wake(wl->irq);
- }
- wl1271_unregister_hw(wl);
- free_irq(wl->irq, wl);
- wl1271_free_hw(wl);
-
- return 0;
-}
-
-static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
- { "wl12xx", 0 },
- { } /* Terminating Entry */
-};
-MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
-
-static struct platform_driver wl12xx_driver = {
- .probe = wl12xx_probe,
- .remove = __devexit_p(wl12xx_remove),
- .id_table = wl12xx_id_table,
- .driver = {
- .name = "wl12xx_driver",
- .owner = THIS_MODULE,
- }
-};
-
-static int __init wl12xx_init(void)
-{
- return platform_driver_register(&wl12xx_driver);
-}
-module_init(wl12xx_init);
-
-static void __exit wl12xx_exit(void)
-{
- platform_driver_unregister(&wl12xx_driver);
-}
-module_exit(wl12xx_exit);
-
-u32 wl12xx_debug_level = DEBUG_NONE;
-EXPORT_SYMBOL_GPL(wl12xx_debug_level);
-module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR);
-MODULE_PARM_DESC(debug_level, "wl12xx debugging level");
-
-module_param_named(fwlog, fwlog_param, charp, 0);
-MODULE_PARM_DESC(fwlog,
- "FW logger options: continuous, ondemand, dbgpins or disable");
-
-module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR);
-MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
-MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
deleted file mode 100644
index 78f598b4f97b..000000000000
--- a/drivers/net/wireless/wl12xx/ps.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "reg.h"
-#include "ps.h"
-#include "io.h"
-#include "tx.h"
-#include "debug.h"
-
-#define WL1271_WAKEUP_TIMEOUT 500
-
-void wl1271_elp_work(struct work_struct *work)
-{
- struct delayed_work *dwork;
- struct wl1271 *wl;
- struct wl12xx_vif *wlvif;
-
- dwork = container_of(work, struct delayed_work, work);
- wl = container_of(dwork, struct wl1271, elp_work);
-
- wl1271_debug(DEBUG_PSM, "elp work");
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- goto out;
-
- /* our work might have been already cancelled */
- if (unlikely(!test_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
- goto out;
-
- if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
- goto out;
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- goto out;
-
- if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
- test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
- goto out;
- }
-
- wl1271_debug(DEBUG_PSM, "chip to elp");
- wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
- set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-/* Routines to toggle sleep mode while in ELP */
-void wl1271_ps_elp_sleep(struct wl1271 *wl)
-{
- struct wl12xx_vif *wlvif;
-
- /* we shouldn't get consecutive sleep requests */
- if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
- return;
-
- wl12xx_for_each_wlvif(wl, wlvif) {
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- return;
-
- if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
- test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
- return;
- }
-
- ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
- msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout));
-}
-
-int wl1271_ps_elp_wakeup(struct wl1271 *wl)
-{
- DECLARE_COMPLETION_ONSTACK(compl);
- unsigned long flags;
- int ret;
- u32 start_time = jiffies;
- bool pending = false;
-
- /*
- * we might try to wake up even if we didn't go to sleep
- * before (e.g. on boot)
- */
- if (!test_and_clear_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))
- return 0;
-
- /* don't cancel_sync as it might contend for a mutex and deadlock */
- cancel_delayed_work(&wl->elp_work);
-
- if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
- return 0;
-
- wl1271_debug(DEBUG_PSM, "waking up chip from elp");
-
- /*
- * The spinlock is required here to synchronize both the work and
- * the completion variable in one entity.
- */
- spin_lock_irqsave(&wl->wl_lock, flags);
- if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
- pending = true;
- else
- wl->elp_compl = &compl;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
-
- if (!pending) {
- ret = wait_for_completion_timeout(
- &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
- if (ret == 0) {
- wl1271_error("ELP wakeup timeout!");
- wl12xx_queue_recovery_work(wl);
- ret = -ETIMEDOUT;
- goto err;
- } else if (ret < 0) {
- wl1271_error("ELP wakeup completion error.");
- goto err;
- }
- }
-
- clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);
-
- wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
- jiffies_to_msecs(jiffies - start_time));
- goto out;
-
-err:
- spin_lock_irqsave(&wl->wl_lock, flags);
- wl->elp_compl = NULL;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- return ret;
-
-out:
- return 0;
-}
-
-int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum wl1271_cmd_ps_mode mode)
-{
- int ret;
- u16 timeout = wl->conf.conn.dynamic_ps_timeout;
-
- switch (mode) {
- case STATION_AUTO_PS_MODE:
- case STATION_POWER_SAVE_MODE:
- wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)",
- mode, timeout);
-
- ret = wl1271_acx_wake_up_conditions(wl, wlvif,
- wl->conf.conn.wake_up_event,
- wl->conf.conn.listen_interval);
- if (ret < 0) {
- wl1271_error("couldn't set wake up conditions");
- return ret;
- }
-
- ret = wl1271_cmd_ps_mode(wl, wlvif, mode, timeout);
- if (ret < 0)
- return ret;
-
- set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
-
- /* enable beacon early termination. Not relevant for 5GHz */
- if (wlvif->band == IEEE80211_BAND_2GHZ) {
- ret = wl1271_acx_bet_enable(wl, wlvif, true);
- if (ret < 0)
- return ret;
- }
- break;
- case STATION_ACTIVE_MODE:
- wl1271_debug(DEBUG_PSM, "leaving psm");
-
- /* disable beacon early termination */
- if (wlvif->band == IEEE80211_BAND_2GHZ) {
- ret = wl1271_acx_bet_enable(wl, wlvif, false);
- if (ret < 0)
- return ret;
- }
-
- ret = wl1271_cmd_ps_mode(wl, wlvif, mode, 0);
- if (ret < 0)
- return ret;
-
- clear_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
- break;
- default:
- wl1271_warning("trying to set ps to unsupported mode %d", mode);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
-{
- int i;
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
- unsigned long flags;
- int filtered[NUM_TX_QUEUES];
-
- /* filter all frames currently in the low level queues for this hlid */
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- filtered[i] = 0;
- while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) {
- filtered[i]++;
-
- if (WARN_ON(wl12xx_is_dummy_packet(wl, skb)))
- continue;
-
- info = IEEE80211_SKB_CB(skb);
- info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
- info->status.rates[0].idx = -1;
- ieee80211_tx_status_ni(wl->hw, skb);
- }
- }
-
- spin_lock_irqsave(&wl->wl_lock, flags);
- for (i = 0; i < NUM_TX_QUEUES; i++)
- wl->tx_queue_count[i] -= filtered[i];
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- wl1271_handle_tx_low_watermark(wl);
-}
-
-void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 hlid, bool clean_queues)
-{
- struct ieee80211_sta *sta;
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
- if (test_bit(hlid, &wl->ap_ps_map))
- return;
-
- wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d pkts %d "
- "clean_queues %d", hlid, wl->links[hlid].allocated_pkts,
- clean_queues);
-
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
- if (!sta) {
- wl1271_error("could not find sta %pM for starting ps",
- wl->links[hlid].addr);
- rcu_read_unlock();
- return;
- }
-
- ieee80211_sta_ps_transition_ni(sta, true);
- rcu_read_unlock();
-
- /* do we want to filter all frames from this link's queues? */
- if (clean_queues)
- wl1271_ps_filter_frames(wl, hlid);
-
- __set_bit(hlid, &wl->ap_ps_map);
-}
-
-void wl12xx_ps_link_end(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
-{
- struct ieee80211_sta *sta;
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
- if (!test_bit(hlid, &wl->ap_ps_map))
- return;
-
- wl1271_debug(DEBUG_PSM, "end mac80211 PSM on hlid %d", hlid);
-
- __clear_bit(hlid, &wl->ap_ps_map);
-
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
- if (!sta) {
- wl1271_error("could not find sta %pM for ending ps",
- wl->links[hlid].addr);
- goto end;
- }
-
- ieee80211_sta_ps_transition_ni(sta, false);
-end:
- rcu_read_unlock();
-}
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
deleted file mode 100644
index 5f19d4fbbf27..000000000000
--- a/drivers/net/wireless/wl12xx/ps.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __PS_H__
-#define __PS_H__
-
-#include "wl12xx.h"
-#include "acx.h"
-
-int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- enum wl1271_cmd_ps_mode mode);
-void wl1271_ps_elp_sleep(struct wl1271 *wl);
-int wl1271_ps_elp_wakeup(struct wl1271 *wl);
-void wl1271_elp_work(struct work_struct *work);
-void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- u8 hlid, bool clean_queues);
-void wl12xx_ps_link_end(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
-
-#define WL1271_PS_COMPLETE_TIMEOUT 500
-
-#endif /* __WL1271_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
deleted file mode 100644
index 340db324bc26..000000000000
--- a/drivers/net/wireless/wl12xx/reg.h
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __REG_H__
-#define __REG_H__
-
-#include <linux/bitops.h>
-
-#define REGISTERS_BASE 0x00300000
-#define DRPW_BASE 0x00310000
-
-#define REGISTERS_DOWN_SIZE 0x00008800
-#define REGISTERS_WORK_SIZE 0x0000b000
-
-#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
-#define FW_STATUS_ADDR (0x14FC0 + 0xA000)
-
-/* ELP register commands */
-#define ELPCTRL_WAKE_UP 0x1
-#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
-#define ELPCTRL_SLEEP 0x0
-/* ELP WLAN_READY bit */
-#define ELPCTRL_WLAN_READY 0x2
-
-/*===============================================
- Host Software Reset - 32bit RW
- ------------------------------------------
- [31:1] Reserved
- 0 SOFT_RESET Soft Reset - When this bit is set,
- it holds the Wlan hardware in a soft reset state.
- This reset disables all MAC and baseband processor
- clocks except the CardBus/PCI interface clock.
- It also initializes all MAC state machines except
- the host interface. It does not reload the
- contents of the EEPROM. When this bit is cleared
- (not self-clearing), the Wlan hardware
- exits the software reset state.
-===============================================*/
-#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000)
-
-#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008)
-#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c)
-#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018)
-
-#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474)
-#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478)
-
-/*=============================================
- Host Interrupt Mask Register - 32bit (RW)
- ------------------------------------------
- Setting a bit in this register masks the
- corresponding interrupt to the host.
- 0 - RX0 - Rx first dubble buffer Data Interrupt
- 1 - TXD - Tx Data Interrupt
- 2 - TXXFR - Tx Transfer Interrupt
- 3 - RX1 - Rx second dubble buffer Data Interrupt
- 4 - RXXFR - Rx Transfer Interrupt
- 5 - EVENT_A - Event Mailbox interrupt
- 6 - EVENT_B - Event Mailbox interrupt
- 7 - WNONHST - Wake On Host Interrupt
- 8 - TRACE_A - Debug Trace interrupt
- 9 - TRACE_B - Debug Trace interrupt
- 10 - CDCMP - Command Complete Interrupt
- 11 -
- 12 -
- 13 -
- 14 - ICOMP - Initialization Complete Interrupt
- 16 - SG SE - Soft Gemini - Sense enable interrupt
- 17 - SG SD - Soft Gemini - Sense disable interrupt
- 18 - -
- 19 - -
- 20 - -
- 21- -
- Default: 0x0001
-*==============================================*/
-#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC)
-
-/*=============================================
- Host Interrupt Mask Set 16bit, (Write only)
- ------------------------------------------
- Setting a bit in this register sets
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-==============================================*/
-#define ACX_REG_HINT_MASK_SET (REGISTERS_BASE + 0x04E0)
-
-/*=============================================
- Host Interrupt Mask Clear 16bit,(Write only)
- ------------------------------------------
- Setting a bit in this register clears
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-=============================================*/
-#define ACX_REG_HINT_MASK_CLR (REGISTERS_BASE + 0x04E4)
-
-/*=============================================
- Host Interrupt Status Nondestructive Read
- 16bit,(Read only)
- ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register doesn't
- effect its content.
-=============================================*/
-#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8)
-
-/*=============================================
- Host Interrupt Status Clear on Read Register
- 16bit,(Read only)
- ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register clears it,
- thus making all interrupts inactive.
-==============================================*/
-#define ACX_REG_INTERRUPT_CLEAR (REGISTERS_BASE + 0x04F8)
-
-/*=============================================
- Host Interrupt Acknowledge Register
- 16bit,(Write only)
- ------------------------------------------
- The host can set individual bits in this
- register to clear (acknowledge) the corresp.
- interrupt status bits in the HINT_STS_CLR and
- HINT_STS_ND registers, thus making the
- assotiated interrupt inactive. (0-no effect)
-==============================================*/
-#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0)
-
-#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538)
-
-/* Device Configuration registers*/
-#define SOR_CFG (REGISTERS_BASE + 0x0800)
-
-/* Embedded ARM CPU Control */
-
-/*===============================================
- Halt eCPU - 32bit RW
- ------------------------------------------
- 0 HALT_ECPU Halt Embedded CPU - This bit is the
- compliment of bit 1 (MDATA2) in the SOR_CFG register.
- During a hardware reset, this bit holds
- the inverse of MDATA2.
- When downloading firmware from the host,
- set this bit (pull down MDATA2).
- The host clears this bit after downloading the firmware into
- zero-wait-state SSRAM.
- When loading firmware from Flash, clear this bit (pull up MDATA2)
- so that the eCPU can run the bootloader code in Flash
- HALT_ECPU eCPU State
- --------------------
- 1 halt eCPU
- 0 enable eCPU
- ===============================================*/
-#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804)
-
-#define HI_CFG (REGISTERS_BASE + 0x0808)
-
-/*===============================================
- EEPROM Burst Read Start - 32bit RW
- ------------------------------------------
- [31:1] Reserved
- 0 ACX_EE_START - EEPROM Burst Read Start 0
- Setting this bit starts a burst read from
- the external EEPROM.
- If this bit is set (after reset) before an EEPROM read/write,
- the burst read starts at EEPROM address 0.
- Otherwise, it starts at the address
- following the address of the previous access.
- TheWlan hardware hardware clears this bit automatically.
-
- Default: 0x00000000
-*================================================*/
-#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C)
-
-#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4)
-#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8)
-#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC)
-#define OCP_CMD (REGISTERS_BASE + 0x09C0)
-
-#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8)
-
-#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
-
-#define CHIP_ID_1271_PG10 (0x4030101)
-#define CHIP_ID_1271_PG20 (0x4030111)
-#define CHIP_ID_1283_PG10 (0x05030101)
-#define CHIP_ID_1283_PG20 (0x05030111)
-
-#define ENABLE (REGISTERS_BASE + 0x5450)
-
-/* Power Management registers */
-#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
-#define ELP_CMD (REGISTERS_BASE + 0x5808)
-#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
-#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
-#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
-
-#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
-
-/* Scratch Pad registers*/
-#define SCR_PAD0 (REGISTERS_BASE + 0x5608)
-#define SCR_PAD1 (REGISTERS_BASE + 0x560C)
-#define SCR_PAD2 (REGISTERS_BASE + 0x5610)
-#define SCR_PAD3 (REGISTERS_BASE + 0x5614)
-#define SCR_PAD4 (REGISTERS_BASE + 0x5618)
-#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
-#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
-#define SCR_PAD5 (REGISTERS_BASE + 0x5624)
-#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
-#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
-#define SCR_PAD6 (REGISTERS_BASE + 0x5630)
-#define SCR_PAD7 (REGISTERS_BASE + 0x5634)
-#define SCR_PAD8 (REGISTERS_BASE + 0x5638)
-#define SCR_PAD9 (REGISTERS_BASE + 0x563C)
-
-/* Spare registers*/
-#define SPARE_A1 (REGISTERS_BASE + 0x0994)
-#define SPARE_A2 (REGISTERS_BASE + 0x0998)
-#define SPARE_A3 (REGISTERS_BASE + 0x099C)
-#define SPARE_A4 (REGISTERS_BASE + 0x09A0)
-#define SPARE_A5 (REGISTERS_BASE + 0x09A4)
-#define SPARE_A6 (REGISTERS_BASE + 0x09A8)
-#define SPARE_A7 (REGISTERS_BASE + 0x09AC)
-#define SPARE_A8 (REGISTERS_BASE + 0x09B0)
-#define SPARE_B1 (REGISTERS_BASE + 0x5420)
-#define SPARE_B2 (REGISTERS_BASE + 0x5424)
-#define SPARE_B3 (REGISTERS_BASE + 0x5428)
-#define SPARE_B4 (REGISTERS_BASE + 0x542C)
-#define SPARE_B5 (REGISTERS_BASE + 0x5430)
-#define SPARE_B6 (REGISTERS_BASE + 0x5434)
-#define SPARE_B7 (REGISTERS_BASE + 0x5438)
-#define SPARE_B8 (REGISTERS_BASE + 0x543C)
-
-#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040)
-#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008)
-#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100)
-#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C)
-
-
-#define ACX_SLV_SOFT_RESET_BIT BIT(1)
-#define ACX_REG_EEPROM_START_BIT BIT(1)
-
-/* Command/Information Mailbox Pointers */
-
-/*===============================================
- Command Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the command mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to
- find the location of the command mailbox.
- The Wlan hardware initializes the command mailbox
- pointer with the default address of the command mailbox.
- The command mailbox pointer is not valid until after
- the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0)
-
-/*===============================================
- Information Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the information mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to find
- the location of the information mailbox.
- The Wlan hardware initializes the information mailbox pointer
- with the default address of the information mailbox.
- The information mailbox pointer is not valid
- until after the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
-
-/*===============================================
- EEPROM Read/Write Request 32bit RW
- ------------------------------------------
- 1 EE_READ - EEPROM Read Request 1 - Setting this bit
- loads a single byte of data into the EE_DATA
- register from the EEPROM location specified in
- the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
- EE_DATA is valid when this bit is cleared.
-
- 0 EE_WRITE - EEPROM Write Request - Setting this bit
- writes a single byte of data from the EE_DATA register into the
- EEPROM location specified in the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
-*===============================================*/
-#define ACX_EE_CTL_REG EE_CTL
-#define EE_WRITE 0x00000001ul
-#define EE_READ 0x00000002ul
-
-/*===============================================
- EEPROM Address - 32bit RW
- ------------------------------------------
- This register specifies the address
- within the EEPROM from/to which to read/write data.
- ===============================================*/
-#define ACX_EE_ADDR_REG EE_ADDR
-
-/*===============================================
- EEPROM Data - 32bit RW
- ------------------------------------------
- This register either holds the read 8 bits of
- data from the EEPROM or the write data
- to be written to the EEPROM.
- ===============================================*/
-#define ACX_EE_DATA_REG EE_DATA
-
-/*===============================================
- EEPROM Base Address - 32bit RW
- ------------------------------------------
- This register holds the upper nine bits
- [23:15] of the 24-bit Wlan hardware memory
- address for burst reads from EEPROM accesses.
- The EEPROM provides the lower 15 bits of this address.
- The MSB of the address from the EEPROM is ignored.
- ===============================================*/
-#define ACX_EE_CFG EE_CFG
-
-/*===============================================
- GPIO Output Values -32bit, RW
- ------------------------------------------
- [31:16] Reserved
- [15: 0] Specify the output values (at the output driver inputs) for
- GPIO[15:0], respectively.
- ===============================================*/
-#define ACX_GPIO_OUT_REG GPIO_OUT
-#define ACX_MAX_GPIO_LINES 15
-
-/*===============================================
- Contention window -32bit, RW
- ------------------------------------------
- [31:26] Reserved
- [25:16] Max (0x3ff)
- [15:07] Reserved
- [06:00] Current contention window value - default is 0x1F
- ===============================================*/
-#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG
-#define ACX_CONT_WIND_MIN_MASK 0x0000007f
-#define ACX_CONT_WIND_MAX 0x03ff0000
-
-/*===============================================
- HI_CFG Interface Configuration Register Values
- ------------------------------------------
- ===============================================*/
-#define HI_CFG_UART_ENABLE 0x00000004
-#define HI_CFG_RST232_ENABLE 0x00000008
-#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
-#define HI_CFG_HOST_INT_ENABLE 0x00000020
-#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
-#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
-#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
-#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
-#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
-
-#define HI_CFG_DEF_VAL \
- (HI_CFG_UART_ENABLE | \
- HI_CFG_RST232_ENABLE | \
- HI_CFG_CLOCK_REQ_SELECT | \
- HI_CFG_HOST_INT_ENABLE)
-
-#define REF_FREQ_19_2 0
-#define REF_FREQ_26_0 1
-#define REF_FREQ_38_4 2
-#define REF_FREQ_40_0 3
-#define REF_FREQ_33_6 4
-#define REF_FREQ_NUM 5
-
-#define LUT_PARAM_INTEGER_DIVIDER 0
-#define LUT_PARAM_FRACTIONAL_DIVIDER 1
-#define LUT_PARAM_ATTN_BB 2
-#define LUT_PARAM_ALPHA_BB 3
-#define LUT_PARAM_STOP_TIME_BB 4
-#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
-#define LUT_PARAM_NUM 6
-
-#define ACX_EEPROMLESS_IND_REG (SCR_PAD4)
-#define USE_EEPROM 0
-#define SOFT_RESET_MAX_TIME 1000000
-#define SOFT_RESET_STALL_TIME 1000
-#define NVS_DATA_BUNDARY_ALIGNMENT 4
-
-
-/* Firmware image load chunk size */
-#define CHUNK_SIZE 16384
-
-/* Firmware image header size */
-#define FW_HDR_SIZE 8
-
-#define ECPU_CONTROL_HALT 0x00000101
-
-
-/******************************************************************************
-
- CHANNELS, BAND & REG DOMAINS definitions
-
-******************************************************************************/
-
-
-enum {
- RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
- RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
- RADIO_BAND_JAPAN_4_9_GHZ = 2,
- DEFAULT_BAND = RADIO_BAND_2_4GHZ,
- INVALID_BAND = 0xFE,
- MAX_RADIO_BANDS = 0xFF
-};
-
-#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
-#define OFDM_RATE_BIT BIT(6)
-#define PBCC_RATE_BIT BIT(7)
-
-enum {
- CCK_LONG = 0,
- CCK_SHORT = SHORT_PREAMBLE_BIT,
- PBCC_LONG = PBCC_RATE_BIT,
- PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
- OFDM = OFDM_RATE_BIT
-};
-
-/******************************************************************************
-
-Transmit-Descriptor RATE-SET field definitions...
-
-Define a new "Rate-Set" for TX path that incorporates the
-Rate & Modulation info into a single 16-bit field.
-
-TxdRateSet_t:
-b15 - Indicates Preamble type (1=SHORT, 0=LONG).
- Notes:
- Must be LONG (0) for 1Mbps rate.
- Does not apply (set to 0) for RevG-OFDM rates.
-b14 - Indicates PBCC encoding (1=PBCC, 0=not).
- Notes:
- Does not apply (set to 0) for rates 1 and 2 Mbps.
- Does not apply (set to 0) for RevG-OFDM rates.
-b13 - Unused (set to 0).
-b12-b0 - Supported Rate indicator bits as defined below.
-
-******************************************************************************/
-
-
-/*************************************************************************
-
- Interrupt Trigger Register (Host -> WiLink)
-
-**************************************************************************/
-
-/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
-
-/*
- * Host Command Interrupt. Setting this bit masks
- * the interrupt that the host issues to inform
- * the FW that it has sent a command
- * to the Wlan hardware Command Mailbox.
- */
-#define INTR_TRIG_CMD BIT(0)
-
-/*
- * Host Event Acknowlegde Interrupt. The host
- * sets this bit to acknowledge that it received
- * the unsolicited information from the event
- * mailbox.
- */
-#define INTR_TRIG_EVENT_ACK BIT(1)
-
-/*
- * The host sets this bit to inform the Wlan
- * FW that a TX packet is in the XFER
- * Buffer #0.
- */
-#define INTR_TRIG_TX_PROC0 BIT(2)
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #0.
- */
-#define INTR_TRIG_RX_PROC0 BIT(3)
-
-#define INTR_TRIG_DEBUG_ACK BIT(4)
-
-#define INTR_TRIG_STATE_CHANGED BIT(5)
-
-
-/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #1.
- */
-#define INTR_TRIG_RX_PROC1 BIT(17)
-
-/*
- * The host sets this bit to inform the Wlan
- * hardware that a TX packet is in the XFER
- * Buffer #1.
- */
-#define INTR_TRIG_TX_PROC1 BIT(18)
-
-#define WL127X_REG_FUSE_DATA_2_1 0x050a
-#define WL128X_REG_FUSE_DATA_2_1 0x2152
-#define PG_VER_MASK 0x3c
-#define PG_VER_OFFSET 2
-
-#define WL127X_PG_MAJOR_VER_MASK 0x3
-#define WL127X_PG_MAJOR_VER_OFFSET 0x0
-#define WL127X_PG_MINOR_VER_MASK 0xc
-#define WL127X_PG_MINOR_VER_OFFSET 0x2
-
-#define WL128X_PG_MAJOR_VER_MASK 0xc
-#define WL128X_PG_MAJOR_VER_OFFSET 0x2
-#define WL128X_PG_MINOR_VER_MASK 0x3
-#define WL128X_PG_MINOR_VER_OFFSET 0x0
-
-#define WL127X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL127X_PG_MAJOR_VER_MASK) >> \
- WL127X_PG_MAJOR_VER_OFFSET)
-#define WL127X_PG_GET_MINOR(pg_ver) ((pg_ver & WL127X_PG_MINOR_VER_MASK) >> \
- WL127X_PG_MINOR_VER_OFFSET)
-#define WL128X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL128X_PG_MAJOR_VER_MASK) >> \
- WL128X_PG_MAJOR_VER_OFFSET)
-#define WL128X_PG_GET_MINOR(pg_ver) ((pg_ver & WL128X_PG_MINOR_VER_MASK) >> \
- WL128X_PG_MINOR_VER_OFFSET)
-
-#define WL12XX_REG_FUSE_BD_ADDR_1 0x00310eb4
-#define WL12XX_REG_FUSE_BD_ADDR_2 0x00310eb8
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
deleted file mode 100644
index cfa6071704c5..000000000000
--- a/drivers/net/wireless/wl12xx/rx.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/gfp.h>
-#include <linux/sched.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "acx.h"
-#include "reg.h"
-#include "rx.h"
-#include "tx.h"
-#include "io.h"
-
-static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status,
- u32 drv_rx_counter)
-{
- return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
- RX_MEM_BLOCK_MASK;
-}
-
-static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status,
- u32 drv_rx_counter)
-{
- return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
- RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
-}
-
-static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status,
- u32 drv_rx_counter)
-{
- /* Convert the value to bool */
- return !!(le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
- RX_BUF_UNALIGNED_PAYLOAD);
-}
-
-static void wl1271_rx_status(struct wl1271 *wl,
- struct wl1271_rx_descriptor *desc,
- struct ieee80211_rx_status *status,
- u8 beacon)
-{
- memset(status, 0, sizeof(struct ieee80211_rx_status));
-
- if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
- status->band = IEEE80211_BAND_2GHZ;
- else
- status->band = IEEE80211_BAND_5GHZ;
-
- status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band);
-
- /* 11n support */
- if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
- status->flag |= RX_FLAG_HT;
-
- status->signal = desc->rssi;
-
- /*
- * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we
- * need to divide by two for now, but TI has been discussing about
- * changing it. This needs to be rechecked.
- */
- wl->noise = desc->rssi - (desc->snr >> 1);
-
- status->freq = ieee80211_channel_to_frequency(desc->channel,
- status->band);
-
- if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
- u8 desc_err_code = desc->status & WL1271_RX_DESC_STATUS_MASK;
-
- status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED |
- RX_FLAG_DECRYPTED;
-
- if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) {
- status->flag |= RX_FLAG_MMIC_ERROR;
- wl1271_warning("Michael MIC error");
- }
- }
-}
-
-static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
- bool unaligned, u8 *hlid)
-{
- struct wl1271_rx_descriptor *desc;
- struct sk_buff *skb;
- struct ieee80211_hdr *hdr;
- u8 *buf;
- u8 beacon = 0;
- u8 is_data = 0;
- u8 reserved = unaligned ? NET_IP_ALIGN : 0;
- u16 seq_num;
-
- /*
- * In PLT mode we seem to get frames and mac80211 warns about them,
- * workaround this by not retrieving them at all.
- */
- if (unlikely(wl->plt))
- return -EINVAL;
-
- /* the data read starts with the descriptor */
- desc = (struct wl1271_rx_descriptor *) data;
-
- if (desc->packet_class == WL12XX_RX_CLASS_LOGGER) {
- size_t len = length - sizeof(*desc);
- wl12xx_copy_fwlog(wl, data + sizeof(*desc), len);
- wake_up_interruptible(&wl->fwlog_waitq);
- return 0;
- }
-
- switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
- /* discard corrupted packets */
- case WL1271_RX_DESC_DRIVER_RX_Q_FAIL:
- case WL1271_RX_DESC_DECRYPT_FAIL:
- wl1271_warning("corrupted packet in RX with status: 0x%x",
- desc->status & WL1271_RX_DESC_STATUS_MASK);
- return -EINVAL;
- case WL1271_RX_DESC_SUCCESS:
- case WL1271_RX_DESC_MIC_FAIL:
- break;
- default:
- wl1271_error("invalid RX descriptor status: 0x%x",
- desc->status & WL1271_RX_DESC_STATUS_MASK);
- return -EINVAL;
- }
-
- /* skb length not included rx descriptor */
- skb = __dev_alloc_skb(length + reserved - sizeof(*desc), GFP_KERNEL);
- if (!skb) {
- wl1271_error("Couldn't allocate RX frame");
- return -ENOMEM;
- }
-
- /* reserve the unaligned payload(if any) */
- skb_reserve(skb, reserved);
-
- buf = skb_put(skb, length - sizeof(*desc));
-
- /*
- * Copy packets from aggregation buffer to the skbs without rx
- * descriptor and with packet payload aligned care. In case of unaligned
- * packets copy the packets in offset of 2 bytes guarantee IP header
- * payload aligned to 4 bytes.
- */
- memcpy(buf, data + sizeof(*desc), length - sizeof(*desc));
- *hlid = desc->hlid;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- if (ieee80211_is_beacon(hdr->frame_control))
- beacon = 1;
- if (ieee80211_is_data_present(hdr->frame_control))
- is_data = 1;
-
- wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
-
- seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
- wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d hlid %d", skb,
- skb->len - desc->pad_len,
- beacon ? "beacon" : "",
- seq_num, *hlid);
-
- skb_trim(skb, skb->len - desc->pad_len);
-
- skb_queue_tail(&wl->deferred_rx_queue, skb);
- queue_work(wl->freezable_wq, &wl->netstack_work);
-
- return is_data;
-}
-
-void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
-{
- struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
- unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
- u32 buf_size;
- u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
- u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
- u32 rx_counter;
- u32 mem_block;
- u32 pkt_length;
- u32 pkt_offset;
- u8 hlid;
- bool unaligned = false;
-
- while (drv_rx_counter != fw_rx_counter) {
- buf_size = 0;
- rx_counter = drv_rx_counter;
- while (rx_counter != fw_rx_counter) {
- pkt_length = wl12xx_rx_get_buf_size(status, rx_counter);
- if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
- break;
- buf_size += pkt_length;
- rx_counter++;
- rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
- }
-
- if (buf_size == 0) {
- wl1271_warning("received empty data");
- break;
- }
-
- if (wl->chip.id != CHIP_ID_1283_PG20) {
- /*
- * Choose the block we want to read
- * For aggregated packets, only the first memory block
- * should be retrieved. The FW takes care of the rest.
- */
- mem_block = wl12xx_rx_get_mem_block(status,
- drv_rx_counter);
-
- wl->rx_mem_pool_addr.addr = (mem_block << 8) +
- le32_to_cpu(wl_mem_map->packet_memory_pool_start);
-
- wl->rx_mem_pool_addr.addr_extra =
- wl->rx_mem_pool_addr.addr + 4;
-
- wl1271_write(wl, WL1271_SLV_REG_DATA,
- &wl->rx_mem_pool_addr,
- sizeof(wl->rx_mem_pool_addr), false);
- }
-
- /* Read all available packets at once */
- wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
- buf_size, true);
-
- /* Split data into separate packets */
- pkt_offset = 0;
- while (pkt_offset < buf_size) {
- pkt_length = wl12xx_rx_get_buf_size(status,
- drv_rx_counter);
-
- unaligned = wl12xx_rx_get_unaligned(status,
- drv_rx_counter);
-
- /*
- * the handle data call can only fail in memory-outage
- * conditions, in that case the received frame will just
- * be dropped.
- */
- if (wl1271_rx_handle_data(wl,
- wl->aggr_buf + pkt_offset,
- pkt_length, unaligned,
- &hlid) == 1) {
- if (hlid < WL12XX_MAX_LINKS)
- __set_bit(hlid, active_hlids);
- else
- WARN(1,
- "hlid exceeded WL12XX_MAX_LINKS "
- "(%d)\n", hlid);
- }
-
- wl->rx_counter++;
- drv_rx_counter++;
- drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
- pkt_offset += pkt_length;
- }
- }
-
- /*
- * Write the driver's packet counter to the FW. This is only required
- * for older hardware revisions
- */
- if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION)
- wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
-
- wl12xx_rearm_rx_streaming(wl, active_hlids);
-}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
deleted file mode 100644
index 86ba6b1d0cdc..000000000000
--- a/drivers/net/wireless/wl12xx/rx.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __RX_H__
-#define __RX_H__
-
-#include <linux/bitops.h>
-
-#define WL1271_RX_MAX_RSSI -30
-#define WL1271_RX_MIN_RSSI -95
-
-#define SHORT_PREAMBLE_BIT BIT(0)
-#define OFDM_RATE_BIT BIT(6)
-#define PBCC_RATE_BIT BIT(7)
-
-#define PLCP_HEADER_LENGTH 8
-#define RX_DESC_PACKETID_SHIFT 11
-#define RX_MAX_PACKET_ID 3
-
-#define NUM_RX_PKT_DESC_MOD_MASK 7
-
-#define RX_DESC_VALID_FCS 0x0001
-#define RX_DESC_MATCH_RXADDR1 0x0002
-#define RX_DESC_MCAST 0x0004
-#define RX_DESC_STAINTIM 0x0008
-#define RX_DESC_VIRTUAL_BM 0x0010
-#define RX_DESC_BCAST 0x0020
-#define RX_DESC_MATCH_SSID 0x0040
-#define RX_DESC_MATCH_BSSID 0x0080
-#define RX_DESC_ENCRYPTION_MASK 0x0300
-#define RX_DESC_MEASURMENT 0x0400
-#define RX_DESC_SEQNUM_MASK 0x1800
-#define RX_DESC_MIC_FAIL 0x2000
-#define RX_DESC_DECRYPT_FAIL 0x4000
-
-/*
- * RX Descriptor flags:
- *
- * Bits 0-1 - band
- * Bit 2 - STBC
- * Bit 3 - A-MPDU
- * Bit 4 - HT
- * Bits 5-7 - encryption
- */
-#define WL1271_RX_DESC_BAND_MASK 0x03
-#define WL1271_RX_DESC_ENCRYPT_MASK 0xE0
-
-#define WL1271_RX_DESC_BAND_BG 0x00
-#define WL1271_RX_DESC_BAND_J 0x01
-#define WL1271_RX_DESC_BAND_A 0x02
-
-#define WL1271_RX_DESC_STBC BIT(2)
-#define WL1271_RX_DESC_A_MPDU BIT(3)
-#define WL1271_RX_DESC_HT BIT(4)
-
-#define WL1271_RX_DESC_ENCRYPT_WEP 0x20
-#define WL1271_RX_DESC_ENCRYPT_TKIP 0x40
-#define WL1271_RX_DESC_ENCRYPT_AES 0x60
-#define WL1271_RX_DESC_ENCRYPT_GEM 0x80
-
-/*
- * RX Descriptor status
- *
- * Bits 0-2 - error code
- * Bits 3-5 - process_id tag (AP mode FW)
- * Bits 6-7 - reserved
- */
-#define WL1271_RX_DESC_STATUS_MASK 0x03
-
-#define WL1271_RX_DESC_SUCCESS 0x00
-#define WL1271_RX_DESC_DECRYPT_FAIL 0x01
-#define WL1271_RX_DESC_MIC_FAIL 0x02
-#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03
-
-#define RX_MEM_BLOCK_MASK 0xFF
-#define RX_BUF_SIZE_MASK 0xFFF00
-#define RX_BUF_SIZE_SHIFT_DIV 6
-/* If set, the start of IP payload is not 4 bytes aligned */
-#define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
-
-enum {
- WL12XX_RX_CLASS_UNKNOWN,
- WL12XX_RX_CLASS_MANAGEMENT,
- WL12XX_RX_CLASS_DATA,
- WL12XX_RX_CLASS_QOS_DATA,
- WL12XX_RX_CLASS_BCN_PRBRSP,
- WL12XX_RX_CLASS_EAPOL,
- WL12XX_RX_CLASS_BA_EVENT,
- WL12XX_RX_CLASS_AMSDU,
- WL12XX_RX_CLASS_LOGGER,
-};
-
-struct wl1271_rx_descriptor {
- __le16 length;
- u8 status;
- u8 flags;
- u8 rate;
- u8 channel;
- s8 rssi;
- u8 snr;
- __le32 timestamp;
- u8 packet_class;
- u8 hlid;
- u8 pad_len;
- u8 reserved;
-} __packed;
-
-void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status);
-u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
deleted file mode 100644
index a57f333d07f5..000000000000
--- a/drivers/net/wireless/wl12xx/scan.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/ieee80211.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "cmd.h"
-#include "scan.h"
-#include "acx.h"
-#include "ps.h"
-#include "tx.h"
-
-void wl1271_scan_complete_work(struct work_struct *work)
-{
- struct delayed_work *dwork;
- struct wl1271 *wl;
- struct ieee80211_vif *vif;
- struct wl12xx_vif *wlvif;
- int ret;
-
- dwork = container_of(work, struct delayed_work, work);
- wl = container_of(dwork, struct wl1271, scan_complete_work);
-
- wl1271_debug(DEBUG_SCAN, "Scanning complete");
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF)
- goto out;
-
- if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
- goto out;
-
- vif = wl->scan_vif;
- wlvif = wl12xx_vif_to_data(vif);
-
- /*
- * Rearm the tx watchdog just before idling scan. This
- * prevents just-finished scans from triggering the watchdog
- */
- wl12xx_rearm_tx_watchdog_locked(wl);
-
- wl->scan.state = WL1271_SCAN_STATE_IDLE;
- memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
- wl->scan.req = NULL;
- wl->scan_vif = NULL;
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
- /* restore hardware connection monitoring template */
- wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq);
- }
-
- wl1271_ps_elp_sleep(wl);
-
- if (wl->scan.failed) {
- wl1271_info("Scan completed due to error.");
- wl12xx_queue_recovery_work(wl);
- }
-
- ieee80211_scan_completed(wl->hw, false);
-
-out:
- mutex_unlock(&wl->mutex);
-
-}
-
-
-static int wl1271_get_scan_channels(struct wl1271 *wl,
- struct cfg80211_scan_request *req,
- struct basic_scan_channel_params *channels,
- enum ieee80211_band band, bool passive)
-{
- struct conf_scan_settings *c = &wl->conf.scan;
- int i, j;
- u32 flags;
-
- for (i = 0, j = 0;
- i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS;
- i++) {
- flags = req->channels[i]->flags;
-
- if (!test_bit(i, wl->scan.scanned_ch) &&
- !(flags & IEEE80211_CHAN_DISABLED) &&
- (req->channels[i]->band == band) &&
- /*
- * In passive scans, we scan all remaining
- * channels, even if not marked as such.
- * In active scans, we only scan channels not
- * marked as passive.
- */
- (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) {
- wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
- req->channels[i]->band,
- req->channels[i]->center_freq);
- wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
- req->channels[i]->hw_value,
- req->channels[i]->flags);
- wl1271_debug(DEBUG_SCAN,
- "max_antenna_gain %d, max_power %d",
- req->channels[i]->max_antenna_gain,
- req->channels[i]->max_power);
- wl1271_debug(DEBUG_SCAN, "beacon_found %d",
- req->channels[i]->beacon_found);
-
- if (!passive) {
- channels[j].min_duration =
- cpu_to_le32(c->min_dwell_time_active);
- channels[j].max_duration =
- cpu_to_le32(c->max_dwell_time_active);
- } else {
- channels[j].min_duration =
- cpu_to_le32(c->min_dwell_time_passive);
- channels[j].max_duration =
- cpu_to_le32(c->max_dwell_time_passive);
- }
- channels[j].early_termination = 0;
- channels[j].tx_power_att = req->channels[i]->max_power;
- channels[j].channel = req->channels[i]->hw_value;
-
- memset(&channels[j].bssid_lsb, 0xff, 4);
- memset(&channels[j].bssid_msb, 0xff, 2);
-
- /* Mark the channels we already used */
- set_bit(i, wl->scan.scanned_ch);
-
- j++;
- }
- }
-
- return j;
-}
-
-#define WL1271_NOTHING_TO_SCAN 1
-
-static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
- enum ieee80211_band band,
- bool passive, u32 basic_rate)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- struct wl1271_cmd_scan *cmd;
- struct wl1271_cmd_trigger_scan_to *trigger;
- int ret;
- u16 scan_options = 0;
-
- /* skip active scans if we don't have SSIDs */
- if (!passive && wl->scan.req->n_ssids == 0)
- return WL1271_NOTHING_TO_SCAN;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
- if (!cmd || !trigger) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (wl->conf.scan.split_scan_timeout)
- scan_options |= WL1271_SCAN_OPT_SPLIT_SCAN;
-
- if (passive)
- scan_options |= WL1271_SCAN_OPT_PASSIVE;
-
- if (wlvif->bss_type == BSS_TYPE_AP_BSS ||
- test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
- cmd->params.role_id = wlvif->role_id;
- else
- cmd->params.role_id = wlvif->dev_role_id;
-
- if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) {
- ret = -EINVAL;
- goto out;
- }
-
- cmd->params.scan_options = cpu_to_le16(scan_options);
-
- cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
- cmd->channels,
- band, passive);
- if (cmd->params.n_ch == 0) {
- ret = WL1271_NOTHING_TO_SCAN;
- goto out;
- }
-
- cmd->params.tx_rate = cpu_to_le32(basic_rate);
- cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
- cmd->params.tid_trigger = CONF_TX_AC_ANY_TID;
- cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
-
- if (band == IEEE80211_BAND_2GHZ)
- cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ;
- else
- cmd->params.band = WL1271_SCAN_BAND_5_GHZ;
-
- if (wl->scan.ssid_len && wl->scan.ssid) {
- cmd->params.ssid_len = wl->scan.ssid_len;
- memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len);
- }
-
- memcpy(cmd->addr, vif->addr, ETH_ALEN);
-
- ret = wl12xx_cmd_build_probe_req(wl, wlvif,
- cmd->params.role_id, band,
- wl->scan.ssid, wl->scan.ssid_len,
- wl->scan.req->ie,
- wl->scan.req->ie_len);
- if (ret < 0) {
- wl1271_error("PROBE request template failed");
- goto out;
- }
-
- trigger->timeout = cpu_to_le32(wl->conf.scan.split_scan_timeout);
- ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
- sizeof(*trigger), 0);
- if (ret < 0) {
- wl1271_error("trigger scan to failed for hw scan");
- goto out;
- }
-
- wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd));
-
- ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("SCAN failed");
- goto out;
- }
-
-out:
- kfree(cmd);
- kfree(trigger);
- return ret;
-}
-
-void wl1271_scan_stm(struct wl1271 *wl, struct ieee80211_vif *vif)
-{
- struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret = 0;
- enum ieee80211_band band;
- u32 rate, mask;
-
- switch (wl->scan.state) {
- case WL1271_SCAN_STATE_IDLE:
- break;
-
- case WL1271_SCAN_STATE_2GHZ_ACTIVE:
- band = IEEE80211_BAND_2GHZ;
- mask = wlvif->bitrate_masks[band];
- if (wl->scan.req->no_cck) {
- mask &= ~CONF_TX_CCK_RATES;
- if (!mask)
- mask = CONF_TX_RATE_MASK_BASIC_P2P;
- }
- rate = wl1271_tx_min_rate_get(wl, mask);
- ret = wl1271_scan_send(wl, vif, band, false, rate);
- if (ret == WL1271_NOTHING_TO_SCAN) {
- wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
- wl1271_scan_stm(wl, vif);
- }
-
- break;
-
- case WL1271_SCAN_STATE_2GHZ_PASSIVE:
- band = IEEE80211_BAND_2GHZ;
- mask = wlvif->bitrate_masks[band];
- if (wl->scan.req->no_cck) {
- mask &= ~CONF_TX_CCK_RATES;
- if (!mask)
- mask = CONF_TX_RATE_MASK_BASIC_P2P;
- }
- rate = wl1271_tx_min_rate_get(wl, mask);
- ret = wl1271_scan_send(wl, vif, band, true, rate);
- if (ret == WL1271_NOTHING_TO_SCAN) {
- if (wl->enable_11a)
- wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
- else
- wl->scan.state = WL1271_SCAN_STATE_DONE;
- wl1271_scan_stm(wl, vif);
- }
-
- break;
-
- case WL1271_SCAN_STATE_5GHZ_ACTIVE:
- band = IEEE80211_BAND_5GHZ;
- rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
- ret = wl1271_scan_send(wl, vif, band, false, rate);
- if (ret == WL1271_NOTHING_TO_SCAN) {
- wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
- wl1271_scan_stm(wl, vif);
- }
-
- break;
-
- case WL1271_SCAN_STATE_5GHZ_PASSIVE:
- band = IEEE80211_BAND_5GHZ;
- rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
- ret = wl1271_scan_send(wl, vif, band, true, rate);
- if (ret == WL1271_NOTHING_TO_SCAN) {
- wl->scan.state = WL1271_SCAN_STATE_DONE;
- wl1271_scan_stm(wl, vif);
- }
-
- break;
-
- case WL1271_SCAN_STATE_DONE:
- wl->scan.failed = false;
- cancel_delayed_work(&wl->scan_complete_work);
- ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
- msecs_to_jiffies(0));
- break;
-
- default:
- wl1271_error("invalid scan state");
- break;
- }
-
- if (ret < 0) {
- cancel_delayed_work(&wl->scan_complete_work);
- ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
- msecs_to_jiffies(0));
- }
-}
-
-int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
- const u8 *ssid, size_t ssid_len,
- struct cfg80211_scan_request *req)
-{
- /*
- * cfg80211 should guarantee that we don't get more channels
- * than what we have registered.
- */
- BUG_ON(req->n_channels > WL1271_MAX_CHANNELS);
-
- if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
- return -EBUSY;
-
- wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE;
-
- if (ssid_len && ssid) {
- wl->scan.ssid_len = ssid_len;
- memcpy(wl->scan.ssid, ssid, ssid_len);
- } else {
- wl->scan.ssid_len = 0;
- }
-
- wl->scan_vif = vif;
- wl->scan.req = req;
- memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
-
- /* we assume failure so that timeout scenarios are handled correctly */
- wl->scan.failed = true;
- ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
- msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
-
- wl1271_scan_stm(wl, vif);
-
- return 0;
-}
-
-int wl1271_scan_stop(struct wl1271 *wl)
-{
- struct wl1271_cmd_header *cmd = NULL;
- int ret = 0;
-
- if (WARN_ON(wl->scan.state == WL1271_SCAN_STATE_IDLE))
- return -EINVAL;
-
- wl1271_debug(DEBUG_CMD, "cmd scan stop");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1271_cmd_send(wl, CMD_STOP_SCAN, cmd,
- sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("cmd stop_scan failed");
- goto out;
- }
-out:
- kfree(cmd);
- return ret;
-}
-
-static int
-wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
- struct cfg80211_sched_scan_request *req,
- struct conn_scan_ch_params *channels,
- u32 band, bool radar, bool passive,
- int start, int max_channels)
-{
- struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
- int i, j;
- u32 flags;
- bool force_passive = !req->n_ssids;
- u32 min_dwell_time_active, max_dwell_time_active, delta_per_probe;
- u32 dwell_time_passive, dwell_time_dfs;
-
- if (band == IEEE80211_BAND_5GHZ)
- delta_per_probe = c->dwell_time_delta_per_probe_5;
- else
- delta_per_probe = c->dwell_time_delta_per_probe;
-
- min_dwell_time_active = c->base_dwell_time +
- req->n_ssids * c->num_probe_reqs * delta_per_probe;
-
- max_dwell_time_active = min_dwell_time_active + c->max_dwell_time_delta;
-
- min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000);
- max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000);
- dwell_time_passive = DIV_ROUND_UP(c->dwell_time_passive, 1000);
- dwell_time_dfs = DIV_ROUND_UP(c->dwell_time_dfs, 1000);
-
- for (i = 0, j = start;
- i < req->n_channels && j < max_channels;
- i++) {
- flags = req->channels[i]->flags;
-
- if (force_passive)
- flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- if ((req->channels[i]->band == band) &&
- !(flags & IEEE80211_CHAN_DISABLED) &&
- (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
- /* if radar is set, we ignore the passive flag */
- (radar ||
- !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
- wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
- req->channels[i]->band,
- req->channels[i]->center_freq);
- wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
- req->channels[i]->hw_value,
- req->channels[i]->flags);
- wl1271_debug(DEBUG_SCAN, "max_power %d",
- req->channels[i]->max_power);
- wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d",
- min_dwell_time_active,
- max_dwell_time_active);
-
- if (flags & IEEE80211_CHAN_RADAR) {
- channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
-
- channels[j].passive_duration =
- cpu_to_le16(dwell_time_dfs);
- } else {
- channels[j].passive_duration =
- cpu_to_le16(dwell_time_passive);
- }
-
- channels[j].min_duration =
- cpu_to_le16(min_dwell_time_active);
- channels[j].max_duration =
- cpu_to_le16(max_dwell_time_active);
-
- channels[j].tx_power_att = req->channels[i]->max_power;
- channels[j].channel = req->channels[i]->hw_value;
-
- j++;
- }
- }
-
- return j - start;
-}
-
-static bool
-wl1271_scan_sched_scan_channels(struct wl1271 *wl,
- struct cfg80211_sched_scan_request *req,
- struct wl1271_cmd_sched_scan_config *cfg)
-{
- cfg->passive[0] =
- wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2,
- IEEE80211_BAND_2GHZ,
- false, true, 0,
- MAX_CHANNELS_2GHZ);
- cfg->active[0] =
- wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2,
- IEEE80211_BAND_2GHZ,
- false, false,
- cfg->passive[0],
- MAX_CHANNELS_2GHZ);
- cfg->passive[1] =
- wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5,
- IEEE80211_BAND_5GHZ,
- false, true, 0,
- MAX_CHANNELS_5GHZ);
- cfg->dfs =
- wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5,
- IEEE80211_BAND_5GHZ,
- true, true,
- cfg->passive[1],
- MAX_CHANNELS_5GHZ);
- cfg->active[1] =
- wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5,
- IEEE80211_BAND_5GHZ,
- false, false,
- cfg->passive[1] + cfg->dfs,
- MAX_CHANNELS_5GHZ);
- /* 802.11j channels are not supported yet */
- cfg->passive[2] = 0;
- cfg->active[2] = 0;
-
- wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d",
- cfg->active[0], cfg->passive[0]);
- wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d",
- cfg->active[1], cfg->passive[1]);
- wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs);
-
- return cfg->passive[0] || cfg->active[0] ||
- cfg->passive[1] || cfg->active[1] || cfg->dfs ||
- cfg->passive[2] || cfg->active[2];
-}
-
-/* Returns the scan type to be used or a negative value on error */
-static int
-wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
- struct cfg80211_sched_scan_request *req)
-{
- struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL;
- struct cfg80211_match_set *sets = req->match_sets;
- struct cfg80211_ssid *ssids = req->ssids;
- int ret = 0, type, i, j, n_match_ssids = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list");
-
- /* count the match sets that contain SSIDs */
- for (i = 0; i < req->n_match_sets; i++)
- if (sets[i].ssid.ssid_len > 0)
- n_match_ssids++;
-
- /* No filter, no ssids or only bcast ssid */
- if (!n_match_ssids &&
- (!req->n_ssids ||
- (req->n_ssids == 1 && req->ssids[0].ssid_len == 0))) {
- type = SCAN_SSID_FILTER_ANY;
- goto out;
- }
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- if (!n_match_ssids) {
- /* No filter, with ssids */
- type = SCAN_SSID_FILTER_DISABLED;
-
- for (i = 0; i < req->n_ssids; i++) {
- cmd->ssids[cmd->n_ssids].type = (ssids[i].ssid_len) ?
- SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC;
- cmd->ssids[cmd->n_ssids].len = ssids[i].ssid_len;
- memcpy(cmd->ssids[cmd->n_ssids].ssid, ssids[i].ssid,
- ssids[i].ssid_len);
- cmd->n_ssids++;
- }
- } else {
- type = SCAN_SSID_FILTER_LIST;
-
- /* Add all SSIDs from the filters */
- for (i = 0; i < req->n_match_sets; i++) {
- /* ignore sets without SSIDs */
- if (!sets[i].ssid.ssid_len)
- continue;
-
- cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC;
- cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len;
- memcpy(cmd->ssids[cmd->n_ssids].ssid,
- sets[i].ssid.ssid, sets[i].ssid.ssid_len);
- cmd->n_ssids++;
- }
- if ((req->n_ssids > 1) ||
- (req->n_ssids == 1 && req->ssids[0].ssid_len > 0)) {
- /*
- * Mark all the SSIDs passed in the SSID list as HIDDEN,
- * so they're used in probe requests.
- */
- for (i = 0; i < req->n_ssids; i++) {
- if (!req->ssids[i].ssid_len)
- continue;
-
- for (j = 0; j < cmd->n_ssids; j++)
- if (!memcmp(req->ssids[i].ssid,
- cmd->ssids[j].ssid,
- req->ssids[i].ssid_len)) {
- cmd->ssids[j].type =
- SCAN_SSID_TYPE_HIDDEN;
- break;
- }
- /* Fail if SSID isn't present in the filters */
- if (j == cmd->n_ssids) {
- ret = -EINVAL;
- goto out_free;
- }
- }
- }
- }
-
- wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd));
-
- ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd,
- sizeof(*cmd), 0);
- if (ret < 0) {
- wl1271_error("cmd sched scan ssid list failed");
- goto out_free;
- }
-
-out_free:
- kfree(cmd);
-out:
- if (ret < 0)
- return ret;
- return type;
-}
-
-int wl1271_scan_sched_scan_config(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
-{
- struct wl1271_cmd_sched_scan_config *cfg = NULL;
- struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
- int i, ret;
- bool force_passive = !req->n_ssids;
-
- wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
-
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
- if (!cfg)
- return -ENOMEM;
-
- cfg->rssi_threshold = c->rssi_threshold;
- cfg->snr_threshold = c->snr_threshold;
- cfg->n_probe_reqs = c->num_probe_reqs;
- /* cycles set to 0 it means infinite (until manually stopped) */
- cfg->cycles = 0;
- /* report APs when at least 1 is found */
- cfg->report_after = 1;
- /* don't stop scanning automatically when something is found */
- cfg->terminate = 0;
- cfg->tag = WL1271_SCAN_DEFAULT_TAG;
- /* don't filter on BSS type */
- cfg->bss_type = SCAN_BSS_TYPE_ANY;
- /* currently NL80211 supports only a single interval */
- for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
- cfg->intervals[i] = cpu_to_le32(req->interval);
-
- cfg->ssid_len = 0;
- ret = wl12xx_scan_sched_scan_ssid_list(wl, req);
- if (ret < 0)
- goto out;
-
- cfg->filter_type = ret;
-
- wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type);
-
- if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) {
- wl1271_error("scan channel list is empty");
- ret = -EINVAL;
- goto out;
- }
-
- if (!force_passive && cfg->active[0]) {
- u8 band = IEEE80211_BAND_2GHZ;
- ret = wl12xx_cmd_build_probe_req(wl, wlvif,
- wlvif->dev_role_id, band,
- req->ssids[0].ssid,
- req->ssids[0].ssid_len,
- ies->ie[band],
- ies->len[band]);
- if (ret < 0) {
- wl1271_error("2.4GHz PROBE request template failed");
- goto out;
- }
- }
-
- if (!force_passive && cfg->active[1]) {
- u8 band = IEEE80211_BAND_5GHZ;
- ret = wl12xx_cmd_build_probe_req(wl, wlvif,
- wlvif->dev_role_id, band,
- req->ssids[0].ssid,
- req->ssids[0].ssid_len,
- ies->ie[band],
- ies->len[band]);
- if (ret < 0) {
- wl1271_error("5GHz PROBE request template failed");
- goto out;
- }
- }
-
- wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
-
- ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
- sizeof(*cfg), 0);
- if (ret < 0) {
- wl1271_error("SCAN configuration failed");
- goto out;
- }
-out:
- kfree(cfg);
- return ret;
-}
-
-int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- struct wl1271_cmd_sched_scan_start *start;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
-
- if (wlvif->bss_type != BSS_TYPE_STA_BSS)
- return -EOPNOTSUPP;
-
- if (test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
- return -EBUSY;
-
- start = kzalloc(sizeof(*start), GFP_KERNEL);
- if (!start)
- return -ENOMEM;
-
- start->tag = WL1271_SCAN_DEFAULT_TAG;
-
- ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
- sizeof(*start), 0);
- if (ret < 0) {
- wl1271_error("failed to send scan start command");
- goto out_free;
- }
-
-out_free:
- kfree(start);
- return ret;
-}
-
-void wl1271_scan_sched_scan_results(struct wl1271 *wl)
-{
- wl1271_debug(DEBUG_SCAN, "got periodic scan results");
-
- ieee80211_sched_scan_results(wl->hw);
-}
-
-void wl1271_scan_sched_scan_stop(struct wl1271 *wl)
-{
- struct wl1271_cmd_sched_scan_stop *stop;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
-
- /* FIXME: what to do if alloc'ing to stop fails? */
- stop = kzalloc(sizeof(*stop), GFP_KERNEL);
- if (!stop) {
- wl1271_error("failed to alloc memory to send sched scan stop");
- return;
- }
-
- stop->tag = WL1271_SCAN_DEFAULT_TAG;
-
- ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
- sizeof(*stop), 0);
- if (ret < 0) {
- wl1271_error("failed to send sched scan stop command");
- goto out_free;
- }
-
-out_free:
- kfree(stop);
-}
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h
deleted file mode 100644
index 2b300f4d0be9..000000000000
--- a/drivers/net/wireless/wl12xx/scan.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __SCAN_H__
-#define __SCAN_H__
-
-#include "wl12xx.h"
-
-int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
- const u8 *ssid, size_t ssid_len,
- struct cfg80211_scan_request *req);
-int wl1271_scan_stop(struct wl1271 *wl);
-int wl1271_scan_build_probe_req(struct wl1271 *wl,
- const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len, u8 band);
-void wl1271_scan_stm(struct wl1271 *wl, struct ieee80211_vif *vif);
-void wl1271_scan_complete_work(struct work_struct *work);
-int wl1271_scan_sched_scan_config(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
-int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-void wl1271_scan_sched_scan_stop(struct wl1271 *wl);
-void wl1271_scan_sched_scan_results(struct wl1271 *wl);
-
-#define WL1271_SCAN_MAX_CHANNELS 24
-#define WL1271_SCAN_DEFAULT_TAG 1
-#define WL1271_SCAN_CURRENT_TX_PWR 0
-#define WL1271_SCAN_OPT_ACTIVE 0
-#define WL1271_SCAN_OPT_PASSIVE 1
-#define WL1271_SCAN_OPT_SPLIT_SCAN 2
-#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
-/* scan even if we fail to enter psm */
-#define WL1271_SCAN_OPT_FORCE 8
-#define WL1271_SCAN_BAND_2_4_GHZ 0
-#define WL1271_SCAN_BAND_5_GHZ 1
-
-#define WL1271_SCAN_TIMEOUT 30000 /* msec */
-
-enum {
- WL1271_SCAN_STATE_IDLE,
- WL1271_SCAN_STATE_2GHZ_ACTIVE,
- WL1271_SCAN_STATE_2GHZ_PASSIVE,
- WL1271_SCAN_STATE_5GHZ_ACTIVE,
- WL1271_SCAN_STATE_5GHZ_PASSIVE,
- WL1271_SCAN_STATE_DONE
-};
-
-struct basic_scan_params {
- /* Scan option flags (WL1271_SCAN_OPT_*) */
- __le16 scan_options;
- u8 role_id;
- /* Number of scan channels in the list (maximum 30) */
- u8 n_ch;
- /* This field indicates the number of probe requests to send
- per channel for an active scan */
- u8 n_probe_reqs;
- u8 tid_trigger;
- u8 ssid_len;
- u8 use_ssid_list;
-
- /* Rate bit field for sending the probes */
- __le32 tx_rate;
-
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- /* Band to scan */
- u8 band;
-
- u8 scan_tag;
- u8 padding2[2];
-} __packed;
-
-struct basic_scan_channel_params {
- /* Duration in TU to wait for frames on a channel for active scan */
- __le32 min_duration;
- __le32 max_duration;
- __le32 bssid_lsb;
- __le16 bssid_msb;
- u8 early_termination;
- u8 tx_power_att;
- u8 channel;
- /* FW internal use only! */
- u8 dfs_candidate;
- u8 activity_detected;
- u8 pad;
-} __packed;
-
-struct wl1271_cmd_scan {
- struct wl1271_cmd_header header;
-
- struct basic_scan_params params;
- struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS];
-
- /* src mac address */
- u8 addr[ETH_ALEN];
- u8 padding[2];
-} __packed;
-
-struct wl1271_cmd_trigger_scan_to {
- struct wl1271_cmd_header header;
-
- __le32 timeout;
-} __packed;
-
-#define MAX_CHANNELS_2GHZ 14
-#define MAX_CHANNELS_5GHZ 23
-#define MAX_CHANNELS_4GHZ 4
-
-#define SCAN_MAX_CYCLE_INTERVALS 16
-#define SCAN_MAX_BANDS 3
-
-enum {
- SCAN_SSID_FILTER_ANY = 0,
- SCAN_SSID_FILTER_SPECIFIC = 1,
- SCAN_SSID_FILTER_LIST = 2,
- SCAN_SSID_FILTER_DISABLED = 3
-};
-
-enum {
- SCAN_BSS_TYPE_INDEPENDENT,
- SCAN_BSS_TYPE_INFRASTRUCTURE,
- SCAN_BSS_TYPE_ANY,
-};
-
-#define SCAN_CHANNEL_FLAGS_DFS BIT(0)
-#define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1)
-
-struct conn_scan_ch_params {
- __le16 min_duration;
- __le16 max_duration;
- __le16 passive_duration;
-
- u8 channel;
- u8 tx_power_att;
-
- /* bit 0: DFS channel; bit 1: DFS enabled */
- u8 flags;
-
- u8 padding[3];
-} __packed;
-
-struct wl1271_cmd_sched_scan_config {
- struct wl1271_cmd_header header;
-
- __le32 intervals[SCAN_MAX_CYCLE_INTERVALS];
-
- s8 rssi_threshold; /* for filtering (in dBm) */
- s8 snr_threshold; /* for filtering (in dB) */
-
- u8 cycles; /* maximum number of scan cycles */
- u8 report_after; /* report when this number of results are received */
- u8 terminate; /* stop scanning after reporting */
-
- u8 tag;
- u8 bss_type; /* for filtering */
- u8 filter_type;
-
- u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
- u8 ssid[IEEE80211_MAX_SSID_LEN];
-
- u8 n_probe_reqs; /* Number of probes requests per channel */
-
- u8 passive[SCAN_MAX_BANDS];
- u8 active[SCAN_MAX_BANDS];
-
- u8 dfs;
-
- u8 padding[3];
-
- struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ];
- struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ];
- struct conn_scan_ch_params channels_4[MAX_CHANNELS_4GHZ];
-} __packed;
-
-
-#define SCHED_SCAN_MAX_SSIDS 16
-
-enum {
- SCAN_SSID_TYPE_PUBLIC = 0,
- SCAN_SSID_TYPE_HIDDEN = 1,
-};
-
-struct wl1271_ssid {
- u8 type;
- u8 len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- /* u8 padding[2]; */
-} __packed;
-
-struct wl1271_cmd_sched_scan_ssid_list {
- struct wl1271_cmd_header header;
-
- u8 n_ssids;
- struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS];
- u8 padding[3];
-} __packed;
-
-struct wl1271_cmd_sched_scan_start {
- struct wl1271_cmd_header header;
-
- u8 tag;
- u8 padding[3];
-} __packed;
-
-struct wl1271_cmd_sched_scan_stop {
- struct wl1271_cmd_header header;
-
- u8 tag;
- u8 padding[3];
-} __packed;
-
-
-#endif /* __WL1271_SCAN_H__ */
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
deleted file mode 100644
index 4b3c32774bae..000000000000
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-#include <linux/gpio.h>
-#include <linux/wl12xx.h>
-#include <linux/pm_runtime.h>
-
-#include "wl12xx.h"
-#include "wl12xx_80211.h"
-#include "io.h"
-
-#ifndef SDIO_VENDOR_ID_TI
-#define SDIO_VENDOR_ID_TI 0x0097
-#endif
-
-#ifndef SDIO_DEVICE_ID_TI_WL1271
-#define SDIO_DEVICE_ID_TI_WL1271 0x4076
-#endif
-
-struct wl12xx_sdio_glue {
- struct device *dev;
- struct platform_device *core;
-};
-
-static const struct sdio_device_id wl1271_devices[] __devinitconst = {
- { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
- {}
-};
-MODULE_DEVICE_TABLE(sdio, wl1271_devices);
-
-static void wl1271_sdio_set_block_size(struct device *child,
- unsigned int blksz)
-{
- struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
- struct sdio_func *func = dev_to_sdio_func(glue->dev);
-
- sdio_claim_host(func);
- sdio_set_block_size(func, blksz);
- sdio_release_host(func);
-}
-
-static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
- size_t len, bool fixed)
-{
- int ret;
- struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
- struct sdio_func *func = dev_to_sdio_func(glue->dev);
-
- sdio_claim_host(func);
-
- if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
- ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
- dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n",
- addr, ((u8 *)buf)[0]);
- } else {
- if (fixed)
- ret = sdio_readsb(func, buf, addr, len);
- else
- ret = sdio_memcpy_fromio(func, buf, addr, len);
-
- dev_dbg(child->parent, "sdio read 53 addr 0x%x, %zu bytes\n",
- addr, len);
- }
-
- sdio_release_host(func);
-
- if (ret)
- dev_err(child->parent, "sdio read failed (%d)\n", ret);
-}
-
-static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
- size_t len, bool fixed)
-{
- int ret;
- struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
- struct sdio_func *func = dev_to_sdio_func(glue->dev);
-
- sdio_claim_host(func);
-
- if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
- sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
- dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n",
- addr, ((u8 *)buf)[0]);
- } else {
- dev_dbg(child->parent, "sdio write 53 addr 0x%x, %zu bytes\n",
- addr, len);
-
- if (fixed)
- ret = sdio_writesb(func, addr, buf, len);
- else
- ret = sdio_memcpy_toio(func, addr, buf, len);
- }
-
- sdio_release_host(func);
-
- if (ret)
- dev_err(child->parent, "sdio write failed (%d)\n", ret);
-}
-
-static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
-{
- int ret;
- struct sdio_func *func = dev_to_sdio_func(glue->dev);
-
- /* If enabled, tell runtime PM not to power off the card */
- if (pm_runtime_enabled(&func->dev)) {
- ret = pm_runtime_get_sync(&func->dev);
- if (ret < 0)
- goto out;
- } else {
- /* Runtime PM is disabled: power up the card manually */
- ret = mmc_power_restore_host(func->card->host);
- if (ret < 0)
- goto out;
- }
-
- sdio_claim_host(func);
- sdio_enable_func(func);
- sdio_release_host(func);
-
-out:
- return ret;
-}
-
-static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
-{
- int ret;
- struct sdio_func *func = dev_to_sdio_func(glue->dev);
-
- sdio_claim_host(func);
- sdio_disable_func(func);
- sdio_release_host(func);
-
- /* Power off the card manually, even if runtime PM is enabled. */
- ret = mmc_power_save_host(func->card->host);
- if (ret < 0)
- return ret;
-
- /* If enabled, let runtime PM know the card is powered off */
- if (pm_runtime_enabled(&func->dev))
- ret = pm_runtime_put_sync(&func->dev);
-
- return ret;
-}
-
-static int wl12xx_sdio_set_power(struct device *child, bool enable)
-{
- struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent);
-
- if (enable)
- return wl12xx_sdio_power_on(glue);
- else
- return wl12xx_sdio_power_off(glue);
-}
-
-static struct wl1271_if_operations sdio_ops = {
- .read = wl12xx_sdio_raw_read,
- .write = wl12xx_sdio_raw_write,
- .power = wl12xx_sdio_set_power,
- .set_block_size = wl1271_sdio_set_block_size,
-};
-
-static int __devinit wl1271_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- struct wl12xx_platform_data *wlan_data;
- struct wl12xx_sdio_glue *glue;
- struct resource res[1];
- mmc_pm_flag_t mmcflags;
- int ret = -ENOMEM;
-
- /* We are only able to handle the wlan function */
- if (func->num != 0x02)
- return -ENODEV;
-
- glue = kzalloc(sizeof(*glue), GFP_KERNEL);
- if (!glue) {
- dev_err(&func->dev, "can't allocate glue\n");
- goto out;
- }
-
- glue->dev = &func->dev;
-
- /* Grab access to FN0 for ELP reg. */
- func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
-
- /* Use block mode for transferring over one block size of data */
- func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
-
- wlan_data = wl12xx_get_platform_data();
- if (IS_ERR(wlan_data)) {
- ret = PTR_ERR(wlan_data);
- dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
- goto out_free_glue;
- }
-
- /* if sdio can keep power while host is suspended, enable wow */
- mmcflags = sdio_get_host_pm_caps(func);
- dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
-
- if (mmcflags & MMC_PM_KEEP_POWER)
- wlan_data->pwr_in_suspend = true;
-
- wlan_data->ops = &sdio_ops;
-
- sdio_set_drvdata(func, glue);
-
- /* Tell PM core that we don't need the card to be powered now */
- pm_runtime_put_noidle(&func->dev);
-
- glue->core = platform_device_alloc("wl12xx", -1);
- if (!glue->core) {
- dev_err(glue->dev, "can't allocate platform_device");
- ret = -ENOMEM;
- goto out_free_glue;
- }
-
- glue->core->dev.parent = &func->dev;
-
- memset(res, 0x00, sizeof(res));
-
- res[0].start = wlan_data->irq;
- res[0].flags = IORESOURCE_IRQ;
- res[0].name = "irq";
-
- ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
- if (ret) {
- dev_err(glue->dev, "can't add resources\n");
- goto out_dev_put;
- }
-
- ret = platform_device_add_data(glue->core, wlan_data,
- sizeof(*wlan_data));
- if (ret) {
- dev_err(glue->dev, "can't add platform data\n");
- goto out_dev_put;
- }
-
- ret = platform_device_add(glue->core);
- if (ret) {
- dev_err(glue->dev, "can't add platform device\n");
- goto out_dev_put;
- }
- return 0;
-
-out_dev_put:
- platform_device_put(glue->core);
-
-out_free_glue:
- kfree(glue);
-
-out:
- return ret;
-}
-
-static void __devexit wl1271_remove(struct sdio_func *func)
-{
- struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
-
- /* Undo decrement done above in wl1271_probe */
- pm_runtime_get_noresume(&func->dev);
-
- platform_device_del(glue->core);
- platform_device_put(glue->core);
- kfree(glue);
-}
-
-#ifdef CONFIG_PM
-static int wl1271_suspend(struct device *dev)
-{
- /* Tell MMC/SDIO core it's OK to power down the card
- * (if it isn't already), but not to remove it completely */
- struct sdio_func *func = dev_to_sdio_func(dev);
- struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
- struct wl1271 *wl = platform_get_drvdata(glue->core);
- mmc_pm_flag_t sdio_flags;
- int ret = 0;
-
- dev_dbg(dev, "wl1271 suspend. wow_enabled: %d\n",
- wl->wow_enabled);
-
- /* check whether sdio should keep power */
- if (wl->wow_enabled) {
- sdio_flags = sdio_get_host_pm_caps(func);
-
- if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
- dev_err(dev, "can't keep power while host "
- "is suspended\n");
- ret = -EINVAL;
- goto out;
- }
-
- /* keep power while host suspended */
- ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
- if (ret) {
- dev_err(dev, "error while trying to keep power\n");
- goto out;
- }
- }
-out:
- return ret;
-}
-
-static int wl1271_resume(struct device *dev)
-{
- dev_dbg(dev, "wl1271 resume\n");
-
- return 0;
-}
-
-static const struct dev_pm_ops wl1271_sdio_pm_ops = {
- .suspend = wl1271_suspend,
- .resume = wl1271_resume,
-};
-#endif
-
-static struct sdio_driver wl1271_sdio_driver = {
- .name = "wl1271_sdio",
- .id_table = wl1271_devices,
- .probe = wl1271_probe,
- .remove = __devexit_p(wl1271_remove),
-#ifdef CONFIG_PM
- .drv = {
- .pm = &wl1271_sdio_pm_ops,
- },
-#endif
-};
-
-static int __init wl1271_init(void)
-{
- return sdio_register_driver(&wl1271_sdio_driver);
-}
-
-static void __exit wl1271_exit(void)
-{
- sdio_unregister_driver(&wl1271_sdio_driver);
-}
-
-module_init(wl1271_init);
-module_exit(wl1271_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
-MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
-MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
-MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
-MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
-MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
-MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
-MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
deleted file mode 100644
index 2fc18a8dcce8..000000000000
--- a/drivers/net/wireless/wl12xx/spi.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/crc7.h>
-#include <linux/spi/spi.h>
-#include <linux/wl12xx.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "wl12xx.h"
-#include "wl12xx_80211.h"
-#include "io.h"
-
-#include "reg.h"
-
-#define WSPI_CMD_READ 0x40000000
-#define WSPI_CMD_WRITE 0x00000000
-#define WSPI_CMD_FIXED 0x20000000
-#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
-#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
-#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
-
-#define WSPI_INIT_CMD_CRC_LEN 5
-
-#define WSPI_INIT_CMD_START 0x00
-#define WSPI_INIT_CMD_TX 0x40
-/* the extra bypass bit is sampled by the TNET as '1' */
-#define WSPI_INIT_CMD_BYPASS_BIT 0x80
-#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
-#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
-#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
-#define WSPI_INIT_CMD_IOD 0x40
-#define WSPI_INIT_CMD_IP 0x20
-#define WSPI_INIT_CMD_CS 0x10
-#define WSPI_INIT_CMD_WS 0x08
-#define WSPI_INIT_CMD_WSPI 0x01
-#define WSPI_INIT_CMD_END 0x01
-
-#define WSPI_INIT_CMD_LEN 8
-
-#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
- ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
-#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
-
-/* HW limitation: maximum possible chunk size is 4095 bytes */
-#define WSPI_MAX_CHUNK_SIZE 4092
-
-#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
-
-struct wl12xx_spi_glue {
- struct device *dev;
- struct platform_device *core;
-};
-
-static void wl12xx_spi_reset(struct device *child)
-{
- struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
- u8 *cmd;
- struct spi_transfer t;
- struct spi_message m;
-
- cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
- if (!cmd) {
- dev_err(child->parent,
- "could not allocate cmd for spi reset\n");
- return;
- }
-
- memset(&t, 0, sizeof(t));
- spi_message_init(&m);
-
- memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
-
- t.tx_buf = cmd;
- t.len = WSPI_INIT_CMD_LEN;
- spi_message_add_tail(&t, &m);
-
- spi_sync(to_spi_device(glue->dev), &m);
-
- kfree(cmd);
-}
-
-static void wl12xx_spi_init(struct device *child)
-{
- struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
- u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
- struct spi_transfer t;
- struct spi_message m;
-
- cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
- if (!cmd) {
- dev_err(child->parent,
- "could not allocate cmd for spi init\n");
- return;
- }
-
- memset(crc, 0, sizeof(crc));
- memset(&t, 0, sizeof(t));
- spi_message_init(&m);
-
- /*
- * Set WSPI_INIT_COMMAND
- * the data is being send from the MSB to LSB
- */
- cmd[2] = 0xff;
- cmd[3] = 0xff;
- cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
- cmd[0] = 0;
- cmd[7] = 0;
- cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
- cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
-
- if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
- cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
- else
- cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
-
- cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
- | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
-
- crc[0] = cmd[1];
- crc[1] = cmd[0];
- crc[2] = cmd[7];
- crc[3] = cmd[6];
- crc[4] = cmd[5];
-
- cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
- cmd[4] |= WSPI_INIT_CMD_END;
-
- t.tx_buf = cmd;
- t.len = WSPI_INIT_CMD_LEN;
- spi_message_add_tail(&t, &m);
-
- spi_sync(to_spi_device(glue->dev), &m);
- kfree(cmd);
-}
-
-#define WL1271_BUSY_WORD_TIMEOUT 1000
-
-static int wl12xx_spi_read_busy(struct device *child)
-{
- struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
- struct wl1271 *wl = dev_get_drvdata(child);
- struct spi_transfer t[1];
- struct spi_message m;
- u32 *busy_buf;
- int num_busy_bytes = 0;
-
- /*
- * Read further busy words from SPI until a non-busy word is
- * encountered, then read the data itself into the buffer.
- */
-
- num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
- busy_buf = wl->buffer_busyword;
- while (num_busy_bytes) {
- num_busy_bytes--;
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
- t[0].rx_buf = busy_buf;
- t[0].len = sizeof(u32);
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
- spi_sync(to_spi_device(glue->dev), &m);
-
- if (*busy_buf & 0x1)
- return 0;
- }
-
- /* The SPI bus is unresponsive, the read failed. */
- dev_err(child->parent, "SPI read busy-word timeout!\n");
- return -ETIMEDOUT;
-}
-
-static void wl12xx_spi_raw_read(struct device *child, int addr, void *buf,
- size_t len, bool fixed)
-{
- struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
- struct wl1271 *wl = dev_get_drvdata(child);
- struct spi_transfer t[2];
- struct spi_message m;
- u32 *busy_buf;
- u32 *cmd;
- u32 chunk_len;
-
- while (len > 0) {
- chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
-
- cmd = &wl->buffer_cmd;
- busy_buf = wl->buffer_busyword;
-
- *cmd = 0;
- *cmd |= WSPI_CMD_READ;
- *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
- WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
- if (fixed)
- *cmd |= WSPI_CMD_FIXED;
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = cmd;
- t[0].len = 4;
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
-
- /* Busy and non busy words read */
- t[1].rx_buf = busy_buf;
- t[1].len = WL1271_BUSY_WORD_LEN;
- t[1].cs_change = true;
- spi_message_add_tail(&t[1], &m);
-
- spi_sync(to_spi_device(glue->dev), &m);
-
- if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
- wl12xx_spi_read_busy(child)) {
- memset(buf, 0, chunk_len);
- return;
- }
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].rx_buf = buf;
- t[0].len = chunk_len;
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
-
- spi_sync(to_spi_device(glue->dev), &m);
-
- if (!fixed)
- addr += chunk_len;
- buf += chunk_len;
- len -= chunk_len;
- }
-}
-
-static void wl12xx_spi_raw_write(struct device *child, int addr, void *buf,
- size_t len, bool fixed)
-{
- struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
- struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
- struct spi_message m;
- u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
- u32 *cmd;
- u32 chunk_len;
- int i;
-
- WARN_ON(len > WL1271_AGGR_BUFFER_SIZE);
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- cmd = &commands[0];
- i = 0;
- while (len > 0) {
- chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
-
- *cmd = 0;
- *cmd |= WSPI_CMD_WRITE;
- *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
- WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
- if (fixed)
- *cmd |= WSPI_CMD_FIXED;
-
- t[i].tx_buf = cmd;
- t[i].len = sizeof(*cmd);
- spi_message_add_tail(&t[i++], &m);
-
- t[i].tx_buf = buf;
- t[i].len = chunk_len;
- spi_message_add_tail(&t[i++], &m);
-
- if (!fixed)
- addr += chunk_len;
- buf += chunk_len;
- len -= chunk_len;
- cmd++;
- }
-
- spi_sync(to_spi_device(glue->dev), &m);
-}
-
-static struct wl1271_if_operations spi_ops = {
- .read = wl12xx_spi_raw_read,
- .write = wl12xx_spi_raw_write,
- .reset = wl12xx_spi_reset,
- .init = wl12xx_spi_init,
- .set_block_size = NULL,
-};
-
-static int __devinit wl1271_probe(struct spi_device *spi)
-{
- struct wl12xx_spi_glue *glue;
- struct wl12xx_platform_data *pdata;
- struct resource res[1];
- int ret = -ENOMEM;
-
- pdata = spi->dev.platform_data;
- if (!pdata) {
- dev_err(&spi->dev, "no platform data\n");
- return -ENODEV;
- }
-
- pdata->ops = &spi_ops;
-
- glue = kzalloc(sizeof(*glue), GFP_KERNEL);
- if (!glue) {
- dev_err(&spi->dev, "can't allocate glue\n");
- goto out;
- }
-
- glue->dev = &spi->dev;
-
- spi_set_drvdata(spi, glue);
-
- /* This is the only SPI value that we need to set here, the rest
- * comes from the board-peripherals file */
- spi->bits_per_word = 32;
-
- ret = spi_setup(spi);
- if (ret < 0) {
- dev_err(glue->dev, "spi_setup failed\n");
- goto out_free_glue;
- }
-
- glue->core = platform_device_alloc("wl12xx", -1);
- if (!glue->core) {
- dev_err(glue->dev, "can't allocate platform_device\n");
- ret = -ENOMEM;
- goto out_free_glue;
- }
-
- glue->core->dev.parent = &spi->dev;
-
- memset(res, 0x00, sizeof(res));
-
- res[0].start = spi->irq;
- res[0].flags = IORESOURCE_IRQ;
- res[0].name = "irq";
-
- ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
- if (ret) {
- dev_err(glue->dev, "can't add resources\n");
- goto out_dev_put;
- }
-
- ret = platform_device_add_data(glue->core, pdata, sizeof(*pdata));
- if (ret) {
- dev_err(glue->dev, "can't add platform data\n");
- goto out_dev_put;
- }
-
- ret = platform_device_add(glue->core);
- if (ret) {
- dev_err(glue->dev, "can't register platform device\n");
- goto out_dev_put;
- }
-
- return 0;
-
-out_dev_put:
- platform_device_put(glue->core);
-
-out_free_glue:
- kfree(glue);
-out:
- return ret;
-}
-
-static int __devexit wl1271_remove(struct spi_device *spi)
-{
- struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
-
- platform_device_del(glue->core);
- platform_device_put(glue->core);
- kfree(glue);
-
- return 0;
-}
-
-
-static struct spi_driver wl1271_spi_driver = {
- .driver = {
- .name = "wl1271_spi",
- .owner = THIS_MODULE,
- },
-
- .probe = wl1271_probe,
- .remove = __devexit_p(wl1271_remove),
-};
-
-static int __init wl1271_init(void)
-{
- return spi_register_driver(&wl1271_spi_driver);
-}
-
-static void __exit wl1271_exit(void)
-{
- spi_unregister_driver(&wl1271_spi_driver);
-}
-
-module_init(wl1271_init);
-module_exit(wl1271_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
-MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
-MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
-MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
-MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
-MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
-MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
-MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
-MODULE_ALIAS("spi:wl1271");
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c
deleted file mode 100644
index 1e93bb9c0246..000000000000
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#include "testmode.h"
-
-#include <linux/slab.h>
-#include <net/genetlink.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "acx.h"
-#include "reg.h"
-#include "ps.h"
-#include "io.h"
-
-#define WL1271_TM_MAX_DATA_LENGTH 1024
-
-enum wl1271_tm_commands {
- WL1271_TM_CMD_UNSPEC,
- WL1271_TM_CMD_TEST,
- WL1271_TM_CMD_INTERROGATE,
- WL1271_TM_CMD_CONFIGURE,
- WL1271_TM_CMD_NVS_PUSH, /* Not in use. Keep to not break ABI */
- WL1271_TM_CMD_SET_PLT_MODE,
- WL1271_TM_CMD_RECOVER,
- WL1271_TM_CMD_GET_MAC,
-
- __WL1271_TM_CMD_AFTER_LAST
-};
-#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1)
-
-enum wl1271_tm_attrs {
- WL1271_TM_ATTR_UNSPEC,
- WL1271_TM_ATTR_CMD_ID,
- WL1271_TM_ATTR_ANSWER,
- WL1271_TM_ATTR_DATA,
- WL1271_TM_ATTR_IE_ID,
- WL1271_TM_ATTR_PLT_MODE,
-
- __WL1271_TM_ATTR_AFTER_LAST
-};
-#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1)
-
-static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = {
- [WL1271_TM_ATTR_CMD_ID] = { .type = NLA_U32 },
- [WL1271_TM_ATTR_ANSWER] = { .type = NLA_U8 },
- [WL1271_TM_ATTR_DATA] = { .type = NLA_BINARY,
- .len = WL1271_TM_MAX_DATA_LENGTH },
- [WL1271_TM_ATTR_IE_ID] = { .type = NLA_U32 },
- [WL1271_TM_ATTR_PLT_MODE] = { .type = NLA_U32 },
-};
-
-
-static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
-{
- int buf_len, ret, len;
- struct sk_buff *skb;
- void *buf;
- u8 answer = 0;
-
- wl1271_debug(DEBUG_TESTMODE, "testmode cmd test");
-
- if (!tb[WL1271_TM_ATTR_DATA])
- return -EINVAL;
-
- buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
- buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);
-
- if (tb[WL1271_TM_ATTR_ANSWER])
- answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]);
-
- if (buf_len > sizeof(struct wl1271_command))
- return -EMSGSIZE;
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1271_cmd_test(wl, buf, buf_len, answer);
- if (ret < 0) {
- wl1271_warning("testmode cmd test failed: %d", ret);
- goto out_sleep;
- }
-
- if (answer) {
- len = nla_total_size(buf_len);
- skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len);
- if (!skb) {
- ret = -ENOMEM;
- goto out_sleep;
- }
-
- NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);
- ret = cfg80211_testmode_reply(skb);
- if (ret < 0)
- goto out_sleep;
- }
-
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-
-nla_put_failure:
- kfree_skb(skb);
- ret = -EMSGSIZE;
- goto out_sleep;
-}
-
-static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
-{
- int ret;
- struct wl1271_command *cmd;
- struct sk_buff *skb;
- u8 ie_id;
-
- wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate");
-
- if (!tb[WL1271_TM_ATTR_IE_ID])
- return -EINVAL;
-
- ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1271_STATE_OFF) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out_sleep;
- }
-
- ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd));
- if (ret < 0) {
- wl1271_warning("testmode cmd interrogate failed: %d", ret);
- goto out_free;
- }
-
- skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd));
- if (!skb) {
- ret = -ENOMEM;
- goto out_free;
- }
-
- NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);
- ret = cfg80211_testmode_reply(skb);
- if (ret < 0)
- goto out_free;
-
-out_free:
- kfree(cmd);
-out_sleep:
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-
-nla_put_failure:
- kfree_skb(skb);
- ret = -EMSGSIZE;
- goto out_free;
-}
-
-static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])
-{
- int buf_len, ret;
- void *buf;
- u8 ie_id;
-
- wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure");
-
- if (!tb[WL1271_TM_ATTR_DATA])
- return -EINVAL;
- if (!tb[WL1271_TM_ATTR_IE_ID])
- return -EINVAL;
-
- ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
- buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
- buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);
-
- if (buf_len > sizeof(struct wl1271_command))
- return -EMSGSIZE;
-
- mutex_lock(&wl->mutex);
- ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len);
- mutex_unlock(&wl->mutex);
-
- if (ret < 0) {
- wl1271_warning("testmode cmd configure failed: %d", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
-{
- u32 val;
- int ret;
-
- wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode");
-
- if (!tb[WL1271_TM_ATTR_PLT_MODE])
- return -EINVAL;
-
- val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]);
-
- switch (val) {
- case 0:
- ret = wl1271_plt_stop(wl);
- break;
- case 1:
- ret = wl1271_plt_start(wl);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
-{
- wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover");
-
- wl12xx_queue_recovery_work(wl);
-
- return 0;
-}
-
-static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[])
-{
- struct sk_buff *skb;
- u8 mac_addr[ETH_ALEN];
- int ret = 0;
-
- mutex_lock(&wl->mutex);
-
- if (!wl->plt) {
- ret = -EINVAL;
- goto out;
- }
-
- if (wl->fuse_oui_addr == 0 && wl->fuse_nic_addr == 0) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- mac_addr[0] = (u8)(wl->fuse_oui_addr >> 16);
- mac_addr[1] = (u8)(wl->fuse_oui_addr >> 8);
- mac_addr[2] = (u8) wl->fuse_oui_addr;
- mac_addr[3] = (u8)(wl->fuse_nic_addr >> 16);
- mac_addr[4] = (u8)(wl->fuse_nic_addr >> 8);
- mac_addr[5] = (u8) wl->fuse_nic_addr;
-
- skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, ETH_ALEN);
- if (!skb) {
- ret = -ENOMEM;
- goto out;
- }
-
- NLA_PUT(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr);
- ret = cfg80211_testmode_reply(skb);
- if (ret < 0)
- goto out;
-
-out:
- mutex_unlock(&wl->mutex);
- return ret;
-
-nla_put_failure:
- kfree_skb(skb);
- ret = -EMSGSIZE;
- goto out;
-}
-
-int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
-{
- struct wl1271 *wl = hw->priv;
- struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];
- int err;
-
- err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
- if (err)
- return err;
-
- if (!tb[WL1271_TM_ATTR_CMD_ID])
- return -EINVAL;
-
- switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) {
- case WL1271_TM_CMD_TEST:
- return wl1271_tm_cmd_test(wl, tb);
- case WL1271_TM_CMD_INTERROGATE:
- return wl1271_tm_cmd_interrogate(wl, tb);
- case WL1271_TM_CMD_CONFIGURE:
- return wl1271_tm_cmd_configure(wl, tb);
- case WL1271_TM_CMD_SET_PLT_MODE:
- return wl1271_tm_cmd_set_plt_mode(wl, tb);
- case WL1271_TM_CMD_RECOVER:
- return wl1271_tm_cmd_recover(wl, tb);
- case WL1271_TM_CMD_GET_MAC:
- return wl12xx_tm_cmd_get_mac(wl, tb);
- default:
- return -EOPNOTSUPP;
- }
-}
diff --git a/drivers/net/wireless/wl12xx/testmode.h b/drivers/net/wireless/wl12xx/testmode.h
deleted file mode 100644
index 8071654259ea..000000000000
--- a/drivers/net/wireless/wl12xx/testmode.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TESTMODE_H__
-#define __TESTMODE_H__
-
-#include <net/mac80211.h>
-
-int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len);
-
-#endif /* __WL1271_TESTMODE_H__ */
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
deleted file mode 100644
index 43ae49143d68..000000000000
--- a/drivers/net/wireless/wl12xx/tx.c
+++ /dev/null
@@ -1,1079 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-
-#include "wl12xx.h"
-#include "debug.h"
-#include "io.h"
-#include "reg.h"
-#include "ps.h"
-#include "tx.h"
-#include "event.h"
-
-static int wl1271_set_default_wep_key(struct wl1271 *wl,
- struct wl12xx_vif *wlvif, u8 id)
-{
- int ret;
- bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
-
- if (is_ap)
- ret = wl12xx_cmd_set_default_wep_key(wl, id,
- wlvif->ap.bcast_hlid);
- else
- ret = wl12xx_cmd_set_default_wep_key(wl, id, wlvif->sta.hlid);
-
- if (ret < 0)
- return ret;
-
- wl1271_debug(DEBUG_CRYPT, "default wep key idx: %d", (int)id);
- return 0;
-}
-
-static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
-{
- int id;
-
- id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS);
- if (id >= ACX_TX_DESCRIPTORS)
- return -EBUSY;
-
- __set_bit(id, wl->tx_frames_map);
- wl->tx_frames[id] = skb;
- wl->tx_frames_cnt++;
- return id;
-}
-
-static void wl1271_free_tx_id(struct wl1271 *wl, int id)
-{
- if (__test_and_clear_bit(id, wl->tx_frames_map)) {
- if (unlikely(wl->tx_frames_cnt == ACX_TX_DESCRIPTORS))
- clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
-
- wl->tx_frames[id] = NULL;
- wl->tx_frames_cnt--;
- }
-}
-
-static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
- struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
-
- /*
- * add the station to the known list before transmitting the
- * authentication response. this way it won't get de-authed by FW
- * when transmitting too soon.
- */
- hdr = (struct ieee80211_hdr *)(skb->data +
- sizeof(struct wl1271_tx_hw_descr));
- if (ieee80211_is_auth(hdr->frame_control))
- wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
-}
-
-static void wl1271_tx_regulate_link(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- u8 hlid)
-{
- bool fw_ps, single_sta;
- u8 tx_pkts;
-
- if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
- return;
-
- fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
- tx_pkts = wl->links[hlid].allocated_pkts;
- single_sta = (wl->active_sta_count == 1);
-
- /*
- * if in FW PS and there is enough data in FW we can put the link
- * into high-level PS and clean out its TX queues.
- * Make an exception if this is the only connected station. In this
- * case FW-memory congestion is not a problem.
- */
- if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
- wl12xx_ps_link_start(wl, wlvif, hlid, true);
-}
-
-bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb)
-{
- return wl->dummy_packet == skb;
-}
-
-u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb)
-{
- struct ieee80211_tx_info *control = IEEE80211_SKB_CB(skb);
-
- if (control->control.sta) {
- struct wl1271_station *wl_sta;
-
- wl_sta = (struct wl1271_station *)
- control->control.sta->drv_priv;
- return wl_sta->hlid;
- } else {
- struct ieee80211_hdr *hdr;
-
- if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
- return wl->system_hlid;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- if (ieee80211_is_mgmt(hdr->frame_control))
- return wlvif->ap.global_hlid;
- else
- return wlvif->ap.bcast_hlid;
- }
-}
-
-u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
- if (!wlvif || wl12xx_is_dummy_packet(wl, skb))
- return wl->system_hlid;
-
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- return wl12xx_tx_get_hlid_ap(wl, wlvif, skb);
-
- if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
- test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) &&
- !ieee80211_is_auth(hdr->frame_control) &&
- !ieee80211_is_assoc_req(hdr->frame_control))
- return wlvif->sta.hlid;
- else
- return wlvif->dev_hlid;
-}
-
-static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
- unsigned int packet_length)
-{
- if (wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
- return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
- else
- return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
-}
-
-static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb, u32 extra, u32 buf_offset,
- u8 hlid)
-{
- struct wl1271_tx_hw_descr *desc;
- u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
- u32 len;
- u32 total_blocks;
- int id, ret = -EBUSY, ac;
- u32 spare_blocks = wl->tx_spare_blocks;
- bool is_dummy = false;
-
- if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
- return -EAGAIN;
-
- /* allocate free identifier for the packet */
- id = wl1271_alloc_tx_id(wl, skb);
- if (id < 0)
- return id;
-
- /* approximate the number of blocks required for this packet
- in the firmware */
- len = wl12xx_calc_packet_alignment(wl, total_len);
-
- /* in case of a dummy packet, use default amount of spare mem blocks */
- if (unlikely(wl12xx_is_dummy_packet(wl, skb))) {
- is_dummy = true;
- spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
- }
-
- total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
- spare_blocks;
-
- if (total_blocks <= wl->tx_blocks_available) {
- desc = (struct wl1271_tx_hw_descr *)skb_push(
- skb, total_len - skb->len);
-
- /* HW descriptor fields change between wl127x and wl128x */
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- desc->wl128x_mem.total_mem_blocks = total_blocks;
- } else {
- desc->wl127x_mem.extra_blocks = spare_blocks;
- desc->wl127x_mem.total_mem_blocks = total_blocks;
- }
-
- desc->id = id;
-
- wl->tx_blocks_available -= total_blocks;
- wl->tx_allocated_blocks += total_blocks;
-
- /* If the FW was empty before, arm the Tx watchdog */
- if (wl->tx_allocated_blocks == total_blocks)
- wl12xx_rearm_tx_watchdog_locked(wl);
-
- ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- wl->tx_allocated_pkts[ac]++;
-
- if (!is_dummy && wlvif &&
- wlvif->bss_type == BSS_TYPE_AP_BSS &&
- test_bit(hlid, wlvif->ap.sta_hlid_map))
- wl->links[hlid].allocated_pkts++;
-
- ret = 0;
-
- wl1271_debug(DEBUG_TX,
- "tx_allocate: size: %d, blocks: %d, id: %d",
- total_len, total_blocks, id);
- } else {
- wl1271_free_tx_id(wl, id);
- }
-
- return ret;
-}
-
-static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb, u32 extra,
- struct ieee80211_tx_info *control, u8 hlid)
-{
- struct timespec ts;
- struct wl1271_tx_hw_descr *desc;
- int aligned_len, ac, rate_idx;
- s64 hosttime;
- u16 tx_attr = 0;
- __le16 frame_control;
- struct ieee80211_hdr *hdr;
- u8 *frame_start;
- bool is_dummy;
-
- desc = (struct wl1271_tx_hw_descr *) skb->data;
- frame_start = (u8 *)(desc + 1);
- hdr = (struct ieee80211_hdr *)(frame_start + extra);
- frame_control = hdr->frame_control;
-
- /* relocate space for security header */
- if (extra) {
- int hdrlen = ieee80211_hdrlen(frame_control);
- memmove(frame_start, hdr, hdrlen);
- }
-
- /* configure packet life time */
- getnstimeofday(&ts);
- hosttime = (timespec_to_ns(&ts) >> 10);
- desc->start_time = cpu_to_le32(hosttime - wl->time_offset);
-
- is_dummy = wl12xx_is_dummy_packet(wl, skb);
- if (is_dummy || !wlvif || wlvif->bss_type != BSS_TYPE_AP_BSS)
- desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU);
- else
- desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);
-
- /* queue */
- ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- desc->tid = skb->priority;
-
- if (is_dummy) {
- /*
- * FW expects the dummy packet to have an invalid session id -
- * any session id that is different than the one set in the join
- */
- tx_attr = (SESSION_COUNTER_INVALID <<
- TX_HW_ATTR_OFST_SESSION_COUNTER) &
- TX_HW_ATTR_SESSION_COUNTER;
-
- tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
- } else if (wlvif) {
- /* configure the tx attributes */
- tx_attr = wlvif->session_counter <<
- TX_HW_ATTR_OFST_SESSION_COUNTER;
- }
-
- desc->hlid = hlid;
- if (is_dummy || !wlvif)
- rate_idx = 0;
- else if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
- /* if the packets are destined for AP (have a STA entry)
- send them with AP rate policies, otherwise use default
- basic rates */
- if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
- rate_idx = wlvif->sta.p2p_rate_idx;
- else if (control->control.sta)
- rate_idx = wlvif->sta.ap_rate_idx;
- else
- rate_idx = wlvif->sta.basic_rate_idx;
- } else {
- if (hlid == wlvif->ap.global_hlid)
- rate_idx = wlvif->ap.mgmt_rate_idx;
- else if (hlid == wlvif->ap.bcast_hlid)
- rate_idx = wlvif->ap.bcast_rate_idx;
- else
- rate_idx = wlvif->ap.ucast_rate_idx[ac];
- }
-
- tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
- desc->reserved = 0;
-
- aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
-
- if (wl->chip.id == CHIP_ID_1283_PG20) {
- desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
- desc->length = cpu_to_le16(aligned_len >> 2);
-
- wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
- "tx_attr: 0x%x len: %d life: %d mem: %d",
- desc->hlid, tx_attr,
- le16_to_cpu(desc->length),
- le16_to_cpu(desc->life_time),
- desc->wl128x_mem.total_mem_blocks);
- } else {
- int pad;
-
- /* Store the aligned length in terms of words */
- desc->length = cpu_to_le16(aligned_len >> 2);
-
- /* calculate number of padding bytes */
- pad = aligned_len - skb->len;
- tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
-
- wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
- "tx_attr: 0x%x len: %d life: %d mem: %d", pad,
- desc->hlid, tx_attr,
- le16_to_cpu(desc->length),
- le16_to_cpu(desc->life_time),
- desc->wl127x_mem.total_mem_blocks);
- }
-
- /* for WEP shared auth - no fw encryption is needed */
- if (ieee80211_is_auth(frame_control) &&
- ieee80211_has_protected(frame_control))
- tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
-
- desc->tx_attr = cpu_to_le16(tx_attr);
-}
-
-/* caller must hold wl->mutex */
-static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb, u32 buf_offset)
-{
- struct ieee80211_tx_info *info;
- u32 extra = 0;
- int ret = 0;
- u32 total_len;
- u8 hlid;
- bool is_dummy;
-
- if (!skb)
- return -EINVAL;
-
- info = IEEE80211_SKB_CB(skb);
-
- /* TODO: handle dummy packets on multi-vifs */
- is_dummy = wl12xx_is_dummy_packet(wl, skb);
-
- if (info->control.hw_key &&
- info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
- extra = WL1271_EXTRA_SPACE_TKIP;
-
- if (info->control.hw_key) {
- bool is_wep;
- u8 idx = info->control.hw_key->hw_key_idx;
- u32 cipher = info->control.hw_key->cipher;
-
- is_wep = (cipher == WLAN_CIPHER_SUITE_WEP40) ||
- (cipher == WLAN_CIPHER_SUITE_WEP104);
-
- if (unlikely(is_wep && wlvif->default_key != idx)) {
- ret = wl1271_set_default_wep_key(wl, wlvif, idx);
- if (ret < 0)
- return ret;
- wlvif->default_key = idx;
- }
- }
- hlid = wl12xx_tx_get_hlid(wl, wlvif, skb);
- if (hlid == WL12XX_INVALID_LINK_ID) {
- wl1271_error("invalid hlid. dropping skb 0x%p", skb);
- return -EINVAL;
- }
-
- ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid);
- if (ret < 0)
- return ret;
-
- wl1271_tx_fill_hdr(wl, wlvif, skb, extra, info, hlid);
-
- if (!is_dummy && wlvif && wlvif->bss_type == BSS_TYPE_AP_BSS) {
- wl1271_tx_ap_update_inconnection_sta(wl, skb);
- wl1271_tx_regulate_link(wl, wlvif, hlid);
- }
-
- /*
- * The length of each packet is stored in terms of
- * words. Thus, we must pad the skb data to make sure its
- * length is aligned. The number of padding bytes is computed
- * and set in wl1271_tx_fill_hdr.
- * In special cases, we want to align to a specific block size
- * (eg. for wl128x with SDIO we align to 256).
- */
- total_len = wl12xx_calc_packet_alignment(wl, skb->len);
-
- memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
- memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
-
- /* Revert side effects in the dummy packet skb, so it can be reused */
- if (is_dummy)
- skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
-
- return total_len;
-}
-
-u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
- enum ieee80211_band rate_band)
-{
- struct ieee80211_supported_band *band;
- u32 enabled_rates = 0;
- int bit;
-
- band = wl->hw->wiphy->bands[rate_band];
- for (bit = 0; bit < band->n_bitrates; bit++) {
- if (rate_set & 0x1)
- enabled_rates |= band->bitrates[bit].hw_value;
- rate_set >>= 1;
- }
-
- /* MCS rates indication are on bits 16 - 23 */
- rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
-
- for (bit = 0; bit < 8; bit++) {
- if (rate_set & 0x1)
- enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
- rate_set >>= 1;
- }
-
- return enabled_rates;
-}
-
-void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
-{
- unsigned long flags;
- int i;
-
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- if (test_bit(i, &wl->stopped_queues_map) &&
- wl->tx_queue_count[i] <= WL1271_TX_QUEUE_LOW_WATERMARK) {
- /* firmware buffer has space, restart queues */
- spin_lock_irqsave(&wl->wl_lock, flags);
- ieee80211_wake_queue(wl->hw,
- wl1271_tx_get_mac80211_queue(i));
- clear_bit(i, &wl->stopped_queues_map);
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- }
- }
-}
-
-static struct sk_buff_head *wl1271_select_queue(struct wl1271 *wl,
- struct sk_buff_head *queues)
-{
- int i, q = -1, ac;
- u32 min_pkts = 0xffffffff;
-
- /*
- * Find a non-empty ac where:
- * 1. There are packets to transmit
- * 2. The FW has the least allocated blocks
- *
- * We prioritize the ACs according to VO>VI>BE>BK
- */
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- ac = wl1271_tx_get_queue(i);
- if (!skb_queue_empty(&queues[ac]) &&
- (wl->tx_allocated_pkts[ac] < min_pkts)) {
- q = ac;
- min_pkts = wl->tx_allocated_pkts[q];
- }
- }
-
- if (q == -1)
- return NULL;
-
- return &queues[q];
-}
-
-static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl,
- struct wl1271_link *lnk)
-{
- struct sk_buff *skb;
- unsigned long flags;
- struct sk_buff_head *queue;
-
- queue = wl1271_select_queue(wl, lnk->tx_queue);
- if (!queue)
- return NULL;
-
- skb = skb_dequeue(queue);
- if (skb) {
- int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- spin_lock_irqsave(&wl->wl_lock, flags);
- WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
- wl->tx_queue_count[q]--;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- }
-
- return skb;
-}
-
-static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
-{
- struct sk_buff *skb = NULL;
- int i, h, start_hlid;
-
- /* start from the link after the last one */
- start_hlid = (wlvif->last_tx_hlid + 1) % WL12XX_MAX_LINKS;
-
- /* dequeue according to AC, round robin on each link */
- for (i = 0; i < WL12XX_MAX_LINKS; i++) {
- h = (start_hlid + i) % WL12XX_MAX_LINKS;
-
- /* only consider connected stations */
- if (!test_bit(h, wlvif->links_map))
- continue;
-
- skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[h]);
- if (!skb)
- continue;
-
- wlvif->last_tx_hlid = h;
- break;
- }
-
- if (!skb)
- wlvif->last_tx_hlid = 0;
-
- return skb;
-}
-
-static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
-{
- unsigned long flags;
- struct wl12xx_vif *wlvif = wl->last_wlvif;
- struct sk_buff *skb = NULL;
-
- /* continue from last wlvif (round robin) */
- if (wlvif) {
- wl12xx_for_each_wlvif_continue(wl, wlvif) {
- skb = wl12xx_vif_skb_dequeue(wl, wlvif);
- if (skb) {
- wl->last_wlvif = wlvif;
- break;
- }
- }
- }
-
- /* dequeue from the system HLID before the restarting wlvif list */
- if (!skb)
- skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
-
- /* do a new pass over the wlvif list */
- if (!skb) {
- wl12xx_for_each_wlvif(wl, wlvif) {
- skb = wl12xx_vif_skb_dequeue(wl, wlvif);
- if (skb) {
- wl->last_wlvif = wlvif;
- break;
- }
-
- /*
- * No need to continue after last_wlvif. The previous
- * pass should have found it.
- */
- if (wlvif == wl->last_wlvif)
- break;
- }
- }
-
- if (!skb &&
- test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
- int q;
-
- skb = wl->dummy_packet;
- q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- spin_lock_irqsave(&wl->wl_lock, flags);
- WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
- wl->tx_queue_count[q]--;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
- }
-
- return skb;
-}
-
-static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb)
-{
- unsigned long flags;
- int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
-
- if (wl12xx_is_dummy_packet(wl, skb)) {
- set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
- } else {
- u8 hlid = wl12xx_tx_get_hlid(wl, wlvif, skb);
- skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
-
- /* make sure we dequeue the same packet next time */
- wlvif->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) %
- WL12XX_MAX_LINKS;
- }
-
- spin_lock_irqsave(&wl->wl_lock, flags);
- wl->tx_queue_count[q]++;
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-}
-
-static bool wl1271_tx_is_data_present(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
-
- return ieee80211_is_data_present(hdr->frame_control);
-}
-
-void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids)
-{
- struct wl12xx_vif *wlvif;
- u32 timeout;
- u8 hlid;
-
- if (!wl->conf.rx_streaming.interval)
- return;
-
- if (!wl->conf.rx_streaming.always &&
- !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))
- return;
-
- timeout = wl->conf.rx_streaming.duration;
- wl12xx_for_each_wlvif_sta(wl, wlvif) {
- bool found = false;
- for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) {
- if (test_bit(hlid, wlvif->links_map)) {
- found = true;
- break;
- }
- }
-
- if (!found)
- continue;
-
- /* enable rx streaming */
- if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
- ieee80211_queue_work(wl->hw,
- &wlvif->rx_streaming_enable_work);
-
- mod_timer(&wlvif->rx_streaming_timer,
- jiffies + msecs_to_jiffies(timeout));
- }
-}
-
-void wl1271_tx_work_locked(struct wl1271 *wl)
-{
- struct wl12xx_vif *wlvif;
- struct sk_buff *skb;
- struct wl1271_tx_hw_descr *desc;
- u32 buf_offset = 0;
- bool sent_packets = false;
- unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
- int ret;
-
- if (unlikely(wl->state == WL1271_STATE_OFF))
- return;
-
- while ((skb = wl1271_skb_dequeue(wl))) {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- bool has_data = false;
-
- wlvif = NULL;
- if (!wl12xx_is_dummy_packet(wl, skb) && info->control.vif)
- wlvif = wl12xx_vif_to_data(info->control.vif);
-
- has_data = wlvif && wl1271_tx_is_data_present(skb);
- ret = wl1271_prepare_tx_frame(wl, wlvif, skb, buf_offset);
- if (ret == -EAGAIN) {
- /*
- * Aggregation buffer is full.
- * Flush buffer and try again.
- */
- wl1271_skb_queue_head(wl, wlvif, skb);
- wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
- buf_offset, true);
- sent_packets = true;
- buf_offset = 0;
- continue;
- } else if (ret == -EBUSY) {
- /*
- * Firmware buffer is full.
- * Queue back last skb, and stop aggregating.
- */
- wl1271_skb_queue_head(wl, wlvif, skb);
- /* No work left, avoid scheduling redundant tx work */
- set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
- goto out_ack;
- } else if (ret < 0) {
- if (wl12xx_is_dummy_packet(wl, skb))
- /*
- * fw still expects dummy packet,
- * so re-enqueue it
- */
- wl1271_skb_queue_head(wl, wlvif, skb);
- else
- ieee80211_free_txskb(wl->hw, skb);
- goto out_ack;
- }
- buf_offset += ret;
- wl->tx_packets_count++;
- if (has_data) {
- desc = (struct wl1271_tx_hw_descr *) skb->data;
- __set_bit(desc->hlid, active_hlids);
- }
- }
-
-out_ack:
- if (buf_offset) {
- wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
- buf_offset, true);
- sent_packets = true;
- }
- if (sent_packets) {
- /*
- * Interrupt the firmware with the new packets. This is only
- * required for older hardware revisions
- */
- if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION)
- wl1271_write32(wl, WL1271_HOST_WR_ACCESS,
- wl->tx_packets_count);
-
- wl1271_handle_tx_low_watermark(wl);
- }
- wl12xx_rearm_rx_streaming(wl, active_hlids);
-}
-
-void wl1271_tx_work(struct work_struct *work)
-{
- struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
- int ret;
-
- mutex_lock(&wl->mutex);
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1271_tx_work_locked(wl);
-
- wl1271_ps_elp_sleep(wl);
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static u8 wl1271_tx_get_rate_flags(u8 rate_class_index)
-{
- u8 flags = 0;
-
- if (rate_class_index >= CONF_HW_RXTX_RATE_MCS_MIN &&
- rate_class_index <= CONF_HW_RXTX_RATE_MCS_MAX)
- flags |= IEEE80211_TX_RC_MCS;
- if (rate_class_index == CONF_HW_RXTX_RATE_MCS7_SGI)
- flags |= IEEE80211_TX_RC_SHORT_GI;
- return flags;
-}
-
-static void wl1271_tx_complete_packet(struct wl1271 *wl,
- struct wl1271_tx_hw_res_descr *result)
-{
- struct ieee80211_tx_info *info;
- struct ieee80211_vif *vif;
- struct wl12xx_vif *wlvif;
- struct sk_buff *skb;
- int id = result->id;
- int rate = -1;
- u8 rate_flags = 0;
- u8 retries = 0;
-
- /* check for id legality */
- if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) {
- wl1271_warning("TX result illegal id: %d", id);
- return;
- }
-
- skb = wl->tx_frames[id];
- info = IEEE80211_SKB_CB(skb);
-
- if (wl12xx_is_dummy_packet(wl, skb)) {
- wl1271_free_tx_id(wl, id);
- return;
- }
-
- /* info->control is valid as long as we don't update info->status */
- vif = info->control.vif;
- wlvif = wl12xx_vif_to_data(vif);
-
- /* update the TX status info */
- if (result->status == TX_SUCCESS) {
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
- info->flags |= IEEE80211_TX_STAT_ACK;
- rate = wl1271_rate_to_idx(result->rate_class_index,
- wlvif->band);
- rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index);
- retries = result->ack_failures;
- } else if (result->status == TX_RETRY_EXCEEDED) {
- wl->stats.excessive_retries++;
- retries = result->ack_failures;
- }
-
- info->status.rates[0].idx = rate;
- info->status.rates[0].count = retries;
- info->status.rates[0].flags = rate_flags;
- info->status.ack_signal = -1;
-
- wl->stats.retry_count += result->ack_failures;
-
- /*
- * update sequence number only when relevant, i.e. only in
- * sessions of TKIP, AES and GEM (not in open or WEP sessions)
- */
- if (info->control.hw_key &&
- (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP ||
- info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP ||
- info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) {
- u8 fw_lsb = result->tx_security_sequence_number_lsb;
- u8 cur_lsb = wlvif->tx_security_last_seq_lsb;
-
- /*
- * update security sequence number, taking care of potential
- * wrap-around
- */
- wlvif->tx_security_seq += (fw_lsb - cur_lsb) & 0xff;
- wlvif->tx_security_last_seq_lsb = fw_lsb;
- }
-
- /* remove private header from packet */
- skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
-
- /* remove TKIP header space if present */
- if (info->control.hw_key &&
- info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
- int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data,
- hdrlen);
- skb_pull(skb, WL1271_EXTRA_SPACE_TKIP);
- }
-
- wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
- " status 0x%x",
- result->id, skb, result->ack_failures,
- result->rate_class_index, result->status);
-
- /* return the packet to the stack */
- skb_queue_tail(&wl->deferred_tx_queue, skb);
- queue_work(wl->freezable_wq, &wl->netstack_work);
- wl1271_free_tx_id(wl, result->id);
-}
-
-/* Called upon reception of a TX complete interrupt */
-void wl1271_tx_complete(struct wl1271 *wl)
-{
- struct wl1271_acx_mem_map *memmap =
- (struct wl1271_acx_mem_map *)wl->target_mem_map;
- u32 count, fw_counter;
- u32 i;
-
- /* read the tx results from the chipset */
- wl1271_read(wl, le32_to_cpu(memmap->tx_result),
- wl->tx_res_if, sizeof(*wl->tx_res_if), false);
- fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter);
-
- /* write host counter to chipset (to ack) */
- wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +
- offsetof(struct wl1271_tx_hw_res_if,
- tx_result_host_counter), fw_counter);
-
- count = fw_counter - wl->tx_results_count;
- wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
-
- /* verify that the result buffer is not getting overrun */
- if (unlikely(count > TX_HW_RESULT_QUEUE_LEN))
- wl1271_warning("TX result overflow from chipset: %d", count);
-
- /* process the results */
- for (i = 0; i < count; i++) {
- struct wl1271_tx_hw_res_descr *result;
- u8 offset = wl->tx_results_count & TX_HW_RESULT_QUEUE_LEN_MASK;
-
- /* process the packet */
- result = &(wl->tx_res_if->tx_results_queue[offset]);
- wl1271_tx_complete_packet(wl, result);
-
- wl->tx_results_count++;
- }
-}
-
-void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
-{
- struct sk_buff *skb;
- int i;
- unsigned long flags;
- struct ieee80211_tx_info *info;
- int total[NUM_TX_QUEUES];
-
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- total[i] = 0;
- while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) {
- wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb);
-
- if (!wl12xx_is_dummy_packet(wl, skb)) {
- info = IEEE80211_SKB_CB(skb);
- info->status.rates[0].idx = -1;
- info->status.rates[0].count = 0;
- ieee80211_tx_status_ni(wl->hw, skb);
- }
-
- total[i]++;
- }
- }
-
- spin_lock_irqsave(&wl->wl_lock, flags);
- for (i = 0; i < NUM_TX_QUEUES; i++)
- wl->tx_queue_count[i] -= total[i];
- spin_unlock_irqrestore(&wl->wl_lock, flags);
-
- wl1271_handle_tx_low_watermark(wl);
-}
-
-/* caller must hold wl->mutex and TX must be stopped */
-void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
-{
- int i;
-
- /* TX failure */
- for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) {
- if (wlvif->bss_type == BSS_TYPE_AP_BSS)
- wl1271_free_sta(wl, wlvif, i);
- else
- wlvif->sta.ba_rx_bitmap = 0;
-
- wl->links[i].allocated_pkts = 0;
- wl->links[i].prev_freed_pkts = 0;
- }
- wlvif->last_tx_hlid = 0;
-
-}
-/* caller must hold wl->mutex and TX must be stopped */
-void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
-{
- int i;
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
-
- /* only reset the queues if something bad happened */
- if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) {
- for (i = 0; i < WL12XX_MAX_LINKS; i++)
- wl1271_tx_reset_link_queues(wl, i);
-
- for (i = 0; i < NUM_TX_QUEUES; i++)
- wl->tx_queue_count[i] = 0;
- }
-
- wl->stopped_queues_map = 0;
-
- /*
- * Make sure the driver is at a consistent state, in case this
- * function is called from a context other than interface removal.
- * This call will always wake the TX queues.
- */
- if (reset_tx_queues)
- wl1271_handle_tx_low_watermark(wl);
-
- for (i = 0; i < ACX_TX_DESCRIPTORS; i++) {
- if (wl->tx_frames[i] == NULL)
- continue;
-
- skb = wl->tx_frames[i];
- wl1271_free_tx_id(wl, i);
- wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
-
- if (!wl12xx_is_dummy_packet(wl, skb)) {
- /*
- * Remove private headers before passing the skb to
- * mac80211
- */
- info = IEEE80211_SKB_CB(skb);
- skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
- if (info->control.hw_key &&
- info->control.hw_key->cipher ==
- WLAN_CIPHER_SUITE_TKIP) {
- int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- memmove(skb->data + WL1271_EXTRA_SPACE_TKIP,
- skb->data, hdrlen);
- skb_pull(skb, WL1271_EXTRA_SPACE_TKIP);
- }
-
- info->status.rates[0].idx = -1;
- info->status.rates[0].count = 0;
-
- ieee80211_tx_status_ni(wl->hw, skb);
- }
- }
-}
-
-#define WL1271_TX_FLUSH_TIMEOUT 500000
-
-/* caller must *NOT* hold wl->mutex */
-void wl1271_tx_flush(struct wl1271 *wl)
-{
- unsigned long timeout;
- int i;
- timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT);
-
- while (!time_after(jiffies, timeout)) {
- mutex_lock(&wl->mutex);
- wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d",
- wl->tx_frames_cnt,
- wl1271_tx_total_queue_count(wl));
- if ((wl->tx_frames_cnt == 0) &&
- (wl1271_tx_total_queue_count(wl) == 0)) {
- mutex_unlock(&wl->mutex);
- return;
- }
- mutex_unlock(&wl->mutex);
- msleep(1);
- }
-
- wl1271_warning("Unable to flush all TX buffers, timed out.");
-
- /* forcibly flush all Tx buffers on our queues */
- mutex_lock(&wl->mutex);
- for (i = 0; i < WL12XX_MAX_LINKS; i++)
- wl1271_tx_reset_link_queues(wl, i);
- mutex_unlock(&wl->mutex);
-}
-
-u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
-{
- if (WARN_ON(!rate_set))
- return 0;
-
- return BIT(__ffs(rate_set));
-}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
deleted file mode 100644
index 5cf8c32d40d1..000000000000
--- a/drivers/net/wireless/wl12xx/tx.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TX_H__
-#define __TX_H__
-
-#define TX_HW_BLOCK_SPARE_DEFAULT 1
-#define TX_HW_BLOCK_SIZE 252
-
-#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
-#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
-
-#define TX_HW_ATTR_SAVE_RETRIES BIT(0)
-#define TX_HW_ATTR_HEADER_PAD BIT(1)
-#define TX_HW_ATTR_SESSION_COUNTER (BIT(2) | BIT(3) | BIT(4))
-#define TX_HW_ATTR_RATE_POLICY (BIT(5) | BIT(6) | BIT(7) | \
- BIT(8) | BIT(9))
-#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11))
-#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
-#define TX_HW_ATTR_TX_DUMMY_REQ BIT(13)
-#define TX_HW_ATTR_HOST_ENCRYPT BIT(14)
-
-#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
-#define TX_HW_ATTR_OFST_HEADER_PAD 1
-#define TX_HW_ATTR_OFST_SESSION_COUNTER 2
-#define TX_HW_ATTR_OFST_RATE_POLICY 5
-#define TX_HW_ATTR_OFST_LAST_WORD_PAD 10
-#define TX_HW_ATTR_OFST_TX_CMPLT_REQ 12
-
-#define TX_HW_RESULT_QUEUE_LEN 16
-#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf
-
-#define WL1271_TX_ALIGN_TO 4
-#define WL1271_EXTRA_SPACE_TKIP 4
-#define WL1271_EXTRA_SPACE_AES 8
-#define WL1271_EXTRA_SPACE_MAX 8
-
-/* Used for management frames and dummy packets */
-#define WL1271_TID_MGMT 7
-
-struct wl127x_tx_mem {
- /*
- * Number of extra memory blocks to allocate for this packet
- * in addition to the number of blocks derived from the packet
- * length.
- */
- u8 extra_blocks;
- /*
- * Total number of memory blocks allocated by the host for
- * this packet. Must be equal or greater than the actual
- * blocks number allocated by HW.
- */
- u8 total_mem_blocks;
-} __packed;
-
-struct wl128x_tx_mem {
- /*
- * Total number of memory blocks allocated by the host for
- * this packet.
- */
- u8 total_mem_blocks;
- /*
- * Number of extra bytes, at the end of the frame. the host
- * uses this padding to complete each frame to integer number
- * of SDIO blocks.
- */
- u8 extra_bytes;
-} __packed;
-
-/*
- * On wl128x based devices, when TX packets are aggregated, each packet
- * size must be aligned to the SDIO block size. The maximum block size
- * is bounded by the type of the padded bytes field that is sent to the
- * FW. Currently the type is u8, so the maximum block size is 256 bytes.
- */
-#define WL12XX_BUS_BLOCK_SIZE min(512u, \
- (1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
-
-struct wl1271_tx_hw_descr {
- /* Length of packet in words, including descriptor+header+data */
- __le16 length;
- union {
- struct wl127x_tx_mem wl127x_mem;
- struct wl128x_tx_mem wl128x_mem;
- } __packed;
- /* Device time (in us) when the packet arrived to the driver */
- __le32 start_time;
- /*
- * Max delay in TUs until transmission. The last device time the
- * packet can be transmitted is: start_time + (1024 * life_time)
- */
- __le16 life_time;
- /* Bitwise fields - see TX_ATTR... definitions above. */
- __le16 tx_attr;
- /* Packet identifier used also in the Tx-Result. */
- u8 id;
- /* The packet TID value (as User-Priority) */
- u8 tid;
- /* host link ID (HLID) */
- u8 hlid;
- u8 reserved;
-} __packed;
-
-enum wl1271_tx_hw_res_status {
- TX_SUCCESS = 0,
- TX_HW_ERROR = 1,
- TX_DISABLED = 2,
- TX_RETRY_EXCEEDED = 3,
- TX_TIMEOUT = 4,
- TX_KEY_NOT_FOUND = 5,
- TX_PEER_NOT_FOUND = 6,
- TX_SESSION_MISMATCH = 7,
- TX_LINK_NOT_VALID = 8,
-};
-
-struct wl1271_tx_hw_res_descr {
- /* Packet Identifier - same value used in the Tx descriptor.*/
- u8 id;
- /* The status of the transmission, indicating success or one of
- several possible reasons for failure. */
- u8 status;
- /* Total air access duration including all retrys and overheads.*/
- __le16 medium_usage;
- /* The time passed from host xfer to Tx-complete.*/
- __le32 fw_handling_time;
- /* Total media delay
- (from 1st EDCA AIFS counter until TX Complete). */
- __le32 medium_delay;
- /* LS-byte of last TKIP seq-num (saved per AC for recovery). */
- u8 tx_security_sequence_number_lsb;
- /* Retry count - number of transmissions without successful ACK.*/
- u8 ack_failures;
- /* The rate that succeeded getting ACK
- (Valid only if status=SUCCESS). */
- u8 rate_class_index;
- /* for 4-byte alignment. */
- u8 spare;
-} __packed;
-
-struct wl1271_tx_hw_res_if {
- __le32 tx_result_fw_counter;
- __le32 tx_result_host_counter;
- struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
-} __packed;
-
-static inline int wl1271_tx_get_queue(int queue)
-{
- switch (queue) {
- case 0:
- return CONF_TX_AC_VO;
- case 1:
- return CONF_TX_AC_VI;
- case 2:
- return CONF_TX_AC_BE;
- case 3:
- return CONF_TX_AC_BK;
- default:
- return CONF_TX_AC_BE;
- }
-}
-
-static inline int wl1271_tx_get_mac80211_queue(int queue)
-{
- switch (queue) {
- case CONF_TX_AC_VO:
- return 0;
- case CONF_TX_AC_VI:
- return 1;
- case CONF_TX_AC_BE:
- return 2;
- case CONF_TX_AC_BK:
- return 3;
- default:
- return 2;
- }
-}
-
-static inline int wl1271_tx_total_queue_count(struct wl1271 *wl)
-{
- int i, count = 0;
-
- for (i = 0; i < NUM_TX_QUEUES; i++)
- count += wl->tx_queue_count[i];
-
- return count;
-}
-
-void wl1271_tx_work(struct work_struct *work);
-void wl1271_tx_work_locked(struct wl1271 *wl);
-void wl1271_tx_complete(struct wl1271 *wl);
-void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
-void wl1271_tx_flush(struct wl1271 *wl);
-u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
-u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
- enum ieee80211_band rate_band);
-u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
-u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb);
-u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
- struct sk_buff *skb);
-void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
-void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
-bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
-void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
-
-/* from main.c */
-void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
-void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
deleted file mode 100644
index 82802d1c0782..000000000000
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- * This file is part of wl1271
- *
- * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL12XX_H__
-#define __WL12XX_H__
-
-#include <linux/mutex.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/bitops.h>
-#include <net/mac80211.h>
-
-#include "conf.h"
-#include "ini.h"
-#include "event.h"
-
-#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
-#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
-
-#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
-#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
-
-#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
-#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
-
-/*
- * wl127x and wl128x are using the same NVS file name. However, the
- * ini parameters between them are different. The driver validates
- * the correct NVS size in wl1271_boot_upload_nvs().
- */
-#define WL12XX_NVS_NAME "ti-connectivity/wl1271-nvs.bin"
-
-#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
-#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
-#define WL1271_TX_SQN_POST_RECOVERY_PADDING 0xff
-
-#define WL1271_CIPHER_SUITE_GEM 0x00147201
-
-#define WL1271_BUSY_WORD_CNT 1
-#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
-
-#define WL1271_ELP_HW_STATE_ASLEEP 0
-#define WL1271_ELP_HW_STATE_IRQ 1
-
-#define WL1271_DEFAULT_BEACON_INT 100
-#define WL1271_DEFAULT_DTIM_PERIOD 1
-
-#define WL12XX_MAX_ROLES 4
-#define WL12XX_MAX_LINKS 12
-#define WL12XX_INVALID_ROLE_ID 0xff
-#define WL12XX_INVALID_LINK_ID 0xff
-
-#define WL12XX_MAX_RATE_POLICIES 16
-
-/* Defined by FW as 0. Will not be freed or allocated. */
-#define WL12XX_SYSTEM_HLID 0
-
-/*
- * When in AP-mode, we allow (at least) this number of packets
- * to be transmitted to FW for a STA in PS-mode. Only when packets are
- * present in the FW buffers it will wake the sleeping STA. We want to put
- * enough packets for the driver to transmit all of its buffered data before
- * the STA goes to sleep again. But we don't want to take too much memory
- * as it might hurt the throughput of active STAs.
- */
-#define WL1271_PS_STA_MAX_PACKETS 2
-
-#define WL1271_AP_BSS_INDEX 0
-#define WL1271_AP_DEF_BEACON_EXP 20
-
-#define ACX_TX_DESCRIPTORS 16
-
-#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
-
-enum wl1271_state {
- WL1271_STATE_OFF,
- WL1271_STATE_ON,
-};
-
-enum wl12xx_fw_type {
- WL12XX_FW_TYPE_NONE,
- WL12XX_FW_TYPE_NORMAL,
- WL12XX_FW_TYPE_MULTI,
- WL12XX_FW_TYPE_PLT,
-};
-
-enum wl1271_partition_type {
- PART_DOWN,
- PART_WORK,
- PART_DRPW,
-
- PART_TABLE_LEN
-};
-
-struct wl1271_partition {
- u32 size;
- u32 start;
-};
-
-struct wl1271_partition_set {
- struct wl1271_partition mem;
- struct wl1271_partition reg;
- struct wl1271_partition mem2;
- struct wl1271_partition mem3;
-};
-
-struct wl1271;
-
-enum {
- FW_VER_CHIP,
- FW_VER_IF_TYPE,
- FW_VER_MAJOR,
- FW_VER_SUBTYPE,
- FW_VER_MINOR,
-
- NUM_FW_VER
-};
-
-#define FW_VER_CHIP_WL127X 6
-#define FW_VER_CHIP_WL128X 7
-
-#define FW_VER_IF_TYPE_STA 1
-#define FW_VER_IF_TYPE_AP 2
-
-#define FW_VER_MINOR_1_SPARE_STA_MIN 58
-#define FW_VER_MINOR_1_SPARE_AP_MIN 47
-
-#define FW_VER_MINOR_FWLOG_STA_MIN 70
-
-struct wl1271_chip {
- u32 id;
- char fw_ver_str[ETHTOOL_BUSINFO_LEN];
- unsigned int fw_ver[NUM_FW_VER];
-};
-
-struct wl1271_stats {
- struct acx_statistics *fw_stats;
- unsigned long fw_stats_update;
-
- unsigned int retry_count;
- unsigned int excessive_retries;
-};
-
-#define NUM_TX_QUEUES 4
-#define NUM_RX_PKT_DESC 8
-
-#define AP_MAX_STATIONS 8
-
-/* FW status registers */
-struct wl12xx_fw_status {
- __le32 intr;
- u8 fw_rx_counter;
- u8 drv_rx_counter;
- u8 reserved;
- u8 tx_results_counter;
- __le32 rx_pkt_descs[NUM_RX_PKT_DESC];
- __le32 fw_localtime;
-
- /*
- * A bitmap (where each bit represents a single HLID)
- * to indicate if the station is in PS mode.
- */
- __le32 link_ps_bitmap;
-
- /*
- * A bitmap (where each bit represents a single HLID) to indicate
- * if the station is in Fast mode
- */
- __le32 link_fast_bitmap;
-
- /* Cumulative counter of total released mem blocks since FW-reset */
- __le32 total_released_blks;
-
- /* Size (in Memory Blocks) of TX pool */
- __le32 tx_total;
-
- /* Cumulative counter of released packets per AC */
- u8 tx_released_pkts[NUM_TX_QUEUES];
-
- /* Cumulative counter of freed packets per HLID */
- u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
-
- /* Cumulative counter of released Voice memory blocks */
- u8 tx_voice_released_blks;
- u8 padding_1[3];
- __le32 log_start_addr;
-} __packed;
-
-struct wl1271_rx_mem_pool_addr {
- u32 addr;
- u32 addr_extra;
-};
-
-#define WL1271_MAX_CHANNELS 64
-struct wl1271_scan {
- struct cfg80211_scan_request *req;
- unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)];
- bool failed;
- u8 state;
- u8 ssid[IEEE80211_MAX_SSID_LEN+1];
- size_t ssid_len;
-};
-
-struct wl1271_if_operations {
- void (*read)(struct device *child, int addr, void *buf, size_t len,
- bool fixed);
- void (*write)(struct device *child, int addr, void *buf, size_t len,
- bool fixed);
- void (*reset)(struct device *child);
- void (*init)(struct device *child);
- int (*power)(struct device *child, bool enable);
- void (*set_block_size) (struct device *child, unsigned int blksz);
-};
-
-#define MAX_NUM_KEYS 14
-#define MAX_KEY_SIZE 32
-
-struct wl1271_ap_key {
- u8 id;
- u8 key_type;
- u8 key_size;
- u8 key[MAX_KEY_SIZE];
- u8 hlid;
- u32 tx_seq_32;
- u16 tx_seq_16;
-};
-
-enum wl12xx_flags {
- WL1271_FLAG_GPIO_POWER,
- WL1271_FLAG_TX_QUEUE_STOPPED,
- WL1271_FLAG_TX_PENDING,
- WL1271_FLAG_IN_ELP,
- WL1271_FLAG_ELP_REQUESTED,
- WL1271_FLAG_IRQ_RUNNING,
- WL1271_FLAG_FW_TX_BUSY,
- WL1271_FLAG_DUMMY_PACKET_PENDING,
- WL1271_FLAG_SUSPENDED,
- WL1271_FLAG_PENDING_WORK,
- WL1271_FLAG_SOFT_GEMINI,
- WL1271_FLAG_RECOVERY_IN_PROGRESS,
- WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
- WL1271_FLAG_INTENDED_FW_RECOVERY,
-};
-
-enum wl12xx_vif_flags {
- WLVIF_FLAG_INITIALIZED,
- WLVIF_FLAG_STA_ASSOCIATED,
- WLVIF_FLAG_STA_AUTHORIZED,
- WLVIF_FLAG_IBSS_JOINED,
- WLVIF_FLAG_AP_STARTED,
- WLVIF_FLAG_IN_PS,
- WLVIF_FLAG_STA_STATE_SENT,
- WLVIF_FLAG_RX_STREAMING_STARTED,
- WLVIF_FLAG_PSPOLL_FAILURE,
- WLVIF_FLAG_CS_PROGRESS,
- WLVIF_FLAG_AP_PROBE_RESP_SET,
- WLVIF_FLAG_IN_USE,
-};
-
-struct wl1271_link {
- /* AP-mode - TX queue per AC in link */
- struct sk_buff_head tx_queue[NUM_TX_QUEUES];
-
- /* accounting for allocated / freed packets in FW */
- u8 allocated_pkts;
- u8 prev_freed_pkts;
-
- u8 addr[ETH_ALEN];
-
- /* bitmap of TIDs where RX BA sessions are active for this link */
- u8 ba_bitmap;
-};
-
-struct wl1271 {
- struct ieee80211_hw *hw;
- bool mac80211_registered;
-
- struct device *dev;
-
- void *if_priv;
-
- struct wl1271_if_operations *if_ops;
-
- void (*set_power)(bool enable);
- int irq;
- int ref_clock;
-
- spinlock_t wl_lock;
-
- enum wl1271_state state;
- enum wl12xx_fw_type fw_type;
- bool plt;
- u8 last_vif_count;
- struct mutex mutex;
-
- unsigned long flags;
-
- struct wl1271_partition_set part;
-
- struct wl1271_chip chip;
-
- int cmd_box_addr;
- int event_box_addr;
-
- u8 *fw;
- size_t fw_len;
- void *nvs;
- size_t nvs_len;
-
- s8 hw_pg_ver;
-
- /* address read from the fuse ROM */
- u32 fuse_oui_addr;
- u32 fuse_nic_addr;
-
- /* we have up to 2 MAC addresses */
- struct mac_address addresses[2];
- int channel;
- u8 system_hlid;
-
- unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
- unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
- unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
- unsigned long rate_policies_map[
- BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
-
- struct list_head wlvif_list;
-
- u8 sta_count;
- u8 ap_count;
-
- struct wl1271_acx_mem_map *target_mem_map;
-
- /* Accounting for allocated / available TX blocks on HW */
- u32 tx_blocks_freed;
- u32 tx_blocks_available;
- u32 tx_allocated_blocks;
- u32 tx_results_count;
-
- /* amount of spare TX blocks to use */
- u32 tx_spare_blocks;
-
- /* Accounting for allocated / available Tx packets in HW */
- u32 tx_pkts_freed[NUM_TX_QUEUES];
- u32 tx_allocated_pkts[NUM_TX_QUEUES];
-
- /* Transmitted TX packets counter for chipset interface */
- u32 tx_packets_count;
-
- /* Time-offset between host and chipset clocks */
- s64 time_offset;
-
- /* Frames scheduled for transmission, not handled yet */
- int tx_queue_count[NUM_TX_QUEUES];
- long stopped_queues_map;
-
- /* Frames received, not handled yet by mac80211 */
- struct sk_buff_head deferred_rx_queue;
-
- /* Frames sent, not returned yet to mac80211 */
- struct sk_buff_head deferred_tx_queue;
-
- struct work_struct tx_work;
- struct workqueue_struct *freezable_wq;
-
- /* Pending TX frames */
- unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
- struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
- int tx_frames_cnt;
-
- /* FW Rx counter */
- u32 rx_counter;
-
- /* Rx memory pool address */
- struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
-
- /* Intermediate buffer, used for packet aggregation */
- u8 *aggr_buf;
-
- /* Reusable dummy packet template */
- struct sk_buff *dummy_packet;
-
- /* Network stack work */
- struct work_struct netstack_work;
-
- /* FW log buffer */
- u8 *fwlog;
-
- /* Number of valid bytes in the FW log buffer */
- ssize_t fwlog_size;
-
- /* Sysfs FW log entry readers wait queue */
- wait_queue_head_t fwlog_waitq;
-
- /* Hardware recovery work */
- struct work_struct recovery_work;
-
- struct event_mailbox *mbox;
-
- /* The mbox event mask */
- u32 event_mask;
-
- /* Mailbox pointers */
- u32 mbox_ptr[2];
-
- /* Are we currently scanning */
- struct ieee80211_vif *scan_vif;
- struct wl1271_scan scan;
- struct delayed_work scan_complete_work;
-
- bool sched_scanning;
-
- /* The current band */
- enum ieee80211_band band;
-
- struct completion *elp_compl;
- struct delayed_work elp_work;
-
- /* in dBm */
- int power_level;
-
- struct wl1271_stats stats;
-
- __le32 buffer_32;
- u32 buffer_cmd;
- u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
-
- struct wl12xx_fw_status *fw_status;
- struct wl1271_tx_hw_res_if *tx_res_if;
-
- /* Current chipset configuration */
- struct conf_drv_settings conf;
-
- bool sg_enabled;
-
- bool enable_11a;
-
- /* Most recently reported noise in dBm */
- s8 noise;
-
- /* bands supported by this instance of wl12xx */
- struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-
- int tcxo_clock;
-
- /*
- * wowlan trigger was configured during suspend.
- * (currently, only "ANY" trigger is supported)
- */
- bool wow_enabled;
- bool irq_wake_enabled;
-
- /*
- * AP-mode - links indexed by HLID. The global and broadcast links
- * are always active.
- */
- struct wl1271_link links[WL12XX_MAX_LINKS];
-
- /* AP-mode - a bitmap of links currently in PS mode according to FW */
- u32 ap_fw_ps_map;
-
- /* AP-mode - a bitmap of links currently in PS mode in mac80211 */
- unsigned long ap_ps_map;
-
- /* Quirks of specific hardware revisions */
- unsigned int quirks;
-
- /* Platform limitations */
- unsigned int platform_quirks;
-
- /* number of currently active RX BA sessions */
- int ba_rx_session_count;
-
- /* AP-mode - number of currently connected stations */
- int active_sta_count;
-
- /* last wlvif we transmitted from */
- struct wl12xx_vif *last_wlvif;
-
- /* work to fire when Tx is stuck */
- struct delayed_work tx_watchdog_work;
-};
-
-struct wl1271_station {
- u8 hlid;
-};
-
-struct wl12xx_vif {
- struct wl1271 *wl;
- struct list_head list;
- unsigned long flags;
- u8 bss_type;
- u8 p2p; /* we are using p2p role */
- u8 role_id;
-
- /* sta/ibss specific */
- u8 dev_role_id;
- u8 dev_hlid;
-
- union {
- struct {
- u8 hlid;
- u8 ba_rx_bitmap;
-
- u8 basic_rate_idx;
- u8 ap_rate_idx;
- u8 p2p_rate_idx;
-
- bool qos;
- } sta;
- struct {
- u8 global_hlid;
- u8 bcast_hlid;
-
- /* HLIDs bitmap of associated stations */
- unsigned long sta_hlid_map[BITS_TO_LONGS(
- WL12XX_MAX_LINKS)];
-
- /* recoreded keys - set here before AP startup */
- struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS];
-
- u8 mgmt_rate_idx;
- u8 bcast_rate_idx;
- u8 ucast_rate_idx[CONF_TX_MAX_AC_COUNT];
- } ap;
- };
-
- /* the hlid of the last transmitted skb */
- int last_tx_hlid;
-
- unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
-
- u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
- u8 ssid_len;
-
- /* The current band */
- enum ieee80211_band band;
- int channel;
-
- u32 bitrate_masks[IEEE80211_NUM_BANDS];
- u32 basic_rate_set;
-
- /*
- * currently configured rate set:
- * bits 0-15 - 802.11abg rates
- * bits 16-23 - 802.11n MCS index mask
- * support only 1 stream, thus only 8 bits for the MCS rates (0-7).
- */
- u32 basic_rate;
- u32 rate_set;
-
- /* probe-req template for the current AP */
- struct sk_buff *probereq;
-
- /* Beaconing interval (needed for ad-hoc) */
- u32 beacon_int;
-
- /* Default key (for WEP) */
- u32 default_key;
-
- /* Our association ID */
- u16 aid;
-
- /* Session counter for the chipset */
- int session_counter;
-
- /* retry counter for PSM entries */
- u8 psm_entry_retry;
-
- /* in dBm */
- int power_level;
-
- int rssi_thold;
- int last_rssi_event;
-
- /* save the current encryption type for auto-arp config */
- u8 encryption_type;
- __be32 ip_addr;
-
- /* RX BA constraint value */
- bool ba_support;
- bool ba_allowed;
-
- /* Rx Streaming */
- struct work_struct rx_streaming_enable_work;
- struct work_struct rx_streaming_disable_work;
- struct timer_list rx_streaming_timer;
-
- /*
- * This struct must be last!
- * data that has to be saved acrossed reconfigs (e.g. recovery)
- * should be declared in this struct.
- */
- struct {
- u8 persistent[0];
- /*
- * Security sequence number
- * bits 0-15: lower 16 bits part of sequence number
- * bits 16-47: higher 32 bits part of sequence number
- * bits 48-63: not in use
- */
- u64 tx_security_seq;
-
- /* 8 bits of the last sequence number in use */
- u8 tx_security_last_seq_lsb;
- };
-};
-
-static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif)
-{
- return (struct wl12xx_vif *)vif->drv_priv;
-}
-
-static inline
-struct ieee80211_vif *wl12xx_wlvif_to_vif(struct wl12xx_vif *wlvif)
-{
- return container_of((void *)wlvif, struct ieee80211_vif, drv_priv);
-}
-
-#define wl12xx_for_each_wlvif(wl, wlvif) \
- list_for_each_entry(wlvif, &wl->wlvif_list, list)
-
-#define wl12xx_for_each_wlvif_continue(wl, wlvif) \
- list_for_each_entry_continue(wlvif, &wl->wlvif_list, list)
-
-#define wl12xx_for_each_wlvif_bss_type(wl, wlvif, _bss_type) \
- wl12xx_for_each_wlvif(wl, wlvif) \
- if (wlvif->bss_type == _bss_type)
-
-#define wl12xx_for_each_wlvif_sta(wl, wlvif) \
- wl12xx_for_each_wlvif_bss_type(wl, wlvif, BSS_TYPE_STA_BSS)
-
-#define wl12xx_for_each_wlvif_ap(wl, wlvif) \
- wl12xx_for_each_wlvif_bss_type(wl, wlvif, BSS_TYPE_AP_BSS)
-
-int wl1271_plt_start(struct wl1271 *wl);
-int wl1271_plt_stop(struct wl1271 *wl);
-int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif);
-void wl12xx_queue_recovery_work(struct wl1271 *wl);
-size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
-
-#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
-
-#define SESSION_COUNTER_MAX 6 /* maximum value for the session counter */
-#define SESSION_COUNTER_INVALID 7 /* used with dummy_packet */
-
-#define WL1271_DEFAULT_POWER_LEVEL 0
-
-#define WL1271_TX_QUEUE_LOW_WATERMARK 32
-#define WL1271_TX_QUEUE_HIGH_WATERMARK 256
-
-#define WL1271_DEFERRED_QUEUE_LIMIT 64
-
-/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
- on in case is has been shut down shortly before */
-#define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */
-#define WL1271_POWER_ON_SLEEP 200 /* in milliseconds */
-
-/* Macros to handle wl1271.sta_rate_set */
-#define HW_BG_RATES_MASK 0xffff
-#define HW_HT_RATES_OFFSET 16
-
-/* Quirks */
-
-/* Each RX/TX transaction requires an end-of-transaction transfer */
-#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
-
-/* wl127x and SPI don't support SDIO block size alignment */
-#define WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2)
-
-/* Older firmwares did not implement the FW logger over bus feature */
-#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
-
-#define WL12XX_HW_BLOCK_SIZE 256
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
deleted file mode 100644
index 22b0bc98d7b5..000000000000
--- a/drivers/net/wireless/wl12xx/wl12xx_80211.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#ifndef __WL12XX_80211_H__
-#define __WL12XX_80211_H__
-
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/if_arp.h>
-
-/* RATES */
-#define IEEE80211_CCK_RATE_1MB 0x02
-#define IEEE80211_CCK_RATE_2MB 0x04
-#define IEEE80211_CCK_RATE_5MB 0x0B
-#define IEEE80211_CCK_RATE_11MB 0x16
-#define IEEE80211_OFDM_RATE_6MB 0x0C
-#define IEEE80211_OFDM_RATE_9MB 0x12
-#define IEEE80211_OFDM_RATE_12MB 0x18
-#define IEEE80211_OFDM_RATE_18MB 0x24
-#define IEEE80211_OFDM_RATE_24MB 0x30
-#define IEEE80211_OFDM_RATE_36MB 0x48
-#define IEEE80211_OFDM_RATE_48MB 0x60
-#define IEEE80211_OFDM_RATE_54MB 0x6C
-#define IEEE80211_BASIC_RATE_MASK 0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
-
-#define IEEE80211_CCK_RATES_MASK 0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
- IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
- IEEE80211_CCK_RATE_5MB_MASK | \
- IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
- IEEE80211_OFDM_RATE_12MB_MASK | \
- IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
- IEEE80211_OFDM_RATE_9MB_MASK | \
- IEEE80211_OFDM_RATE_18MB_MASK | \
- IEEE80211_OFDM_RATE_36MB_MASK | \
- IEEE80211_OFDM_RATE_48MB_MASK | \
- IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
- IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-
-/* This really should be 8, but not for our firmware */
-#define MAX_SUPPORTED_RATES 32
-#define MAX_COUNTRY_TRIPLETS 32
-
-/* Headers */
-struct ieee80211_header {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 da[ETH_ALEN];
- u8 sa[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- __le16 seq_ctl;
- u8 payload[0];
-} __packed;
-
-struct wl12xx_ie_header {
- u8 id;
- u8 len;
-} __packed;
-
-/* IEs */
-
-struct wl12xx_ie_ssid {
- struct wl12xx_ie_header header;
- char ssid[IEEE80211_MAX_SSID_LEN];
-} __packed;
-
-struct wl12xx_ie_rates {
- struct wl12xx_ie_header header;
- u8 rates[MAX_SUPPORTED_RATES];
-} __packed;
-
-struct wl12xx_ie_ds_params {
- struct wl12xx_ie_header header;
- u8 channel;
-} __packed;
-
-struct country_triplet {
- u8 channel;
- u8 num_channels;
- u8 max_tx_power;
-} __packed;
-
-struct wl12xx_ie_country {
- struct wl12xx_ie_header header;
- u8 country_string[IEEE80211_COUNTRY_STRING_LEN];
- struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
-} __packed;
-
-
-/* Templates */
-
-struct wl12xx_null_data_template {
- struct ieee80211_header header;
-} __packed;
-
-struct wl12xx_ps_poll_template {
- __le16 fc;
- __le16 aid;
- u8 bssid[ETH_ALEN];
- u8 ta[ETH_ALEN];
-} __packed;
-
-struct wl12xx_arp_rsp_template {
- /* not including ieee80211 header */
-
- u8 llc_hdr[sizeof(rfc1042_header)];
- __be16 llc_type;
-
- struct arphdr arp_hdr;
- u8 sender_hw[ETH_ALEN];
- __be32 sender_ip;
- u8 target_hw[ETH_ALEN];
- __be32 target_ip;
-} __packed;
-
-struct wl12xx_disconn_template {
- struct ieee80211_header header;
- __le16 disconn_reason;
-} __packed;
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
deleted file mode 100644
index 998e95895f9d..000000000000
--- a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2010-2011 Texas Instruments, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/wl12xx.h>
-
-static struct wl12xx_platform_data *platform_data;
-
-int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
-{
- if (platform_data)
- return -EBUSY;
- if (!data)
- return -EINVAL;
-
- platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
- if (!platform_data)
- return -ENOMEM;
-
- return 0;
-}
-
-struct wl12xx_platform_data *wl12xx_get_platform_data(void)
-{
- if (!platform_data)
- return ERR_PTR(-ENODEV);
-
- return platform_data;
-}
-EXPORT_SYMBOL(wl12xx_get_platform_data);