summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-03-25 03:53:42 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-03-25 03:53:42 -0300
commit03dd4cb26d967f9588437b0fc9cc0e8353322bb7 (patch)
treefa581f6dc1c0596391690d1f67eceef3af8246dc /drivers/net/wireless/libertas
parentd4e493caf788ef44982e131ff9c786546904d934 (diff)
Linux-libre 4.5-gnu
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/Kconfig45
-rw-r--r--drivers/net/wireless/libertas/LICENSE16
-rw-r--r--drivers/net/wireless/libertas/Makefile21
-rw-r--r--drivers/net/wireless/libertas/README239
-rw-r--r--drivers/net/wireless/libertas/cfg.c2215
-rw-r--r--drivers/net/wireless/libertas/cfg.h21
-rw-r--r--drivers/net/wireless/libertas/cmd.c1725
-rw-r--r--drivers/net/wireless/libertas/cmd.h141
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c353
-rw-r--r--drivers/net/wireless/libertas/debugfs.c989
-rw-r--r--drivers/net/wireless/libertas/debugfs.h10
-rw-r--r--drivers/net/wireless/libertas/decl.h82
-rw-r--r--drivers/net/wireless/libertas/defs.h394
-rw-r--r--drivers/net/wireless/libertas/dev.h211
-rw-r--r--drivers/net/wireless/libertas/ethtool.c120
-rw-r--r--drivers/net/wireless/libertas/firmware.c227
-rw-r--r--drivers/net/wireless/libertas/host.h978
-rw-r--r--drivers/net/wireless/libertas/if_cs.c1000
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c1440
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h52
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1310
-rw-r--r--drivers/net/wireless/libertas/if_spi.h206
-rw-r--r--drivers/net/wireless/libertas/if_usb.c1014
-rw-r--r--drivers/net/wireless/libertas/if_usb.h106
-rw-r--r--drivers/net/wireless/libertas/main.c1225
-rw-r--r--drivers/net/wireless/libertas/mesh.c1187
-rw-r--r--drivers/net/wireless/libertas/mesh.h77
-rw-r--r--drivers/net/wireless/libertas/radiotap.h44
-rw-r--r--drivers/net/wireless/libertas/rx.c286
-rw-r--r--drivers/net/wireless/libertas/tx.c207
-rw-r--r--drivers/net/wireless/libertas/types.h268
31 files changed, 0 insertions, 16209 deletions
diff --git a/drivers/net/wireless/libertas/Kconfig b/drivers/net/wireless/libertas/Kconfig
deleted file mode 100644
index e6268ceac..000000000
--- a/drivers/net/wireless/libertas/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-config LIBERTAS
- tristate "Marvell 8xxx Libertas WLAN driver support"
- depends on CFG80211
- select WIRELESS_EXT
- select WEXT_SPY
- select LIB80211
- select FW_LOADER
- ---help---
- A library for Marvell Libertas 8xxx devices.
-
-config LIBERTAS_USB
- tristate "Marvell Libertas 8388 USB 802.11b/g cards"
- depends on LIBERTAS && USB
- ---help---
- A driver for Marvell Libertas 8388 USB devices.
-
-config LIBERTAS_CS
- tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
- depends on LIBERTAS && PCMCIA && HAS_IOPORT_MAP
- ---help---
- A driver for Marvell Libertas 8385 CompactFlash devices.
-
-config LIBERTAS_SDIO
- tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
- depends on LIBERTAS && MMC
- ---help---
- A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
-
-config LIBERTAS_SPI
- tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
- depends on LIBERTAS && SPI
- ---help---
- A driver for Marvell Libertas 8686 SPI devices.
-
-config LIBERTAS_DEBUG
- bool "Enable full debugging output in the Libertas module."
- depends on LIBERTAS
- ---help---
- Debugging support.
-
-config LIBERTAS_MESH
- bool "Enable mesh support"
- depends on LIBERTAS
- help
- This enables Libertas' MESH support, used by e.g. the OLPC people.
diff --git a/drivers/net/wireless/libertas/LICENSE b/drivers/net/wireless/libertas/LICENSE
deleted file mode 100644
index 886274221..000000000
--- a/drivers/net/wireless/libertas/LICENSE
+++ /dev/null
@@ -1,16 +0,0 @@
- Copyright (c) 2003-2006, Marvell International Ltd.
- All Rights Reserved
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
deleted file mode 100644
index eac72f7bd..000000000
--- a/drivers/net/wireless/libertas/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-libertas-y += cfg.o
-libertas-y += cmd.o
-libertas-y += cmdresp.o
-libertas-y += debugfs.o
-libertas-y += ethtool.o
-libertas-y += main.o
-libertas-y += rx.o
-libertas-y += tx.o
-libertas-y += firmware.o
-libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
-
-usb8xxx-objs += if_usb.o
-libertas_cs-objs += if_cs.o
-libertas_sdio-objs += if_sdio.o
-libertas_spi-objs += if_spi.o
-
-obj-$(CONFIG_LIBERTAS) += libertas.o
-obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
-obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o
-obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o
-obj-$(CONFIG_LIBERTAS_SPI) += libertas_spi.o
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
deleted file mode 100644
index 2dc0bf4bd..000000000
--- a/drivers/net/wireless/libertas/README
+++ /dev/null
@@ -1,239 +0,0 @@
-================================================================================
- README for Libertas
-
- (c) Copyright © 2003-2006, Marvell International Ltd.
- All Rights Reserved
-
- This software file (the "File") is distributed by Marvell International
- Ltd. under the terms of the GNU General Public License Version 2, June 1991
- (the "License"). You may use, redistribute and/or modify this File in
- accordance with the terms and conditions of the License, a copy of which
- is available along with the File in the license.txt file or on the worldwide
- web at http://www.gnu.org/licenses/gpl.txt.
-
- THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
- IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
- ARE EXPRESSLY DISCLAIMED. The License provides additional details about
- this warranty disclaimer.
-================================================================================
-
-=====================
-DRIVER LOADING
-=====================
-
- /*(DEBLOBBED)*/
-
- o. Load driver by using the following command:
-
- insmod usb8388.ko /*(DEBLOBBED)*/
-
-=========================
-ETHTOOL
-=========================
-
-
-Use the -i option to retrieve version information from the driver.
-
-# ethtool -i eth0
-driver: libertas
-version: COMM-USB8388-318.p4
-firmware-version: 5.110.7
-bus-info:
-
-Use the -e option to read the EEPROM contents of the card.
-
- Usage:
- ethtool -e ethX [raw on|off] [offset N] [length N]
-
- -e retrieves and prints an EEPROM dump for the specified ethernet
- device. When raw is enabled, then it dumps the raw EEPROM data
- to stdout. The length and offset parameters allow dumping cer-
- tain portions of the EEPROM. Default is to dump the entire EEP-
- ROM.
-
-# ethtool -e eth0 offset 0 length 16
-Offset Values
------- ------
-0x0000 38 33 30 58 00 00 34 f4 00 00 10 00 00 c4 17 00
-
-========================
-DEBUGFS COMMANDS
-========================
-
-those commands are used via debugfs interface
-
-===========
-rdmac
-rdbbp
-rdrf
- These commands are used to read the MAC, BBP and RF registers from the
- card. These commands take one parameter that specifies the offset
- location that is to be read. This parameter must be specified in
- hexadecimal (its possible to precede preceding the number with a "0x").
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/registers/
-
- Usage:
- echo "0xa123" > rdmac ; cat rdmac
- echo "0xa123" > rdbbp ; cat rdbbp
- echo "0xa123" > rdrf ; cat rdrf
-wrmac
-wrbbp
-wrrf
- These commands are used to write the MAC, BBP and RF registers in the
- card. These commands take two parameters that specify the offset
- location and the value that is to be written. This parameters must
- be specified in hexadecimal (its possible to precede the number
- with a "0x").
-
- Usage:
- echo "0xa123 0xaa" > wrmac
- echo "0xa123 0xaa" > wrbbp
- echo "0xa123 0xaa" > wrrf
-
-sleepparams
- This command is used to set the sleepclock configurations
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/
-
- Usage:
- cat sleepparams: reads the current sleepclock configuration
-
- echo "p1 p2 p3 p4 p5 p6" > sleepparams: writes the sleepclock configuration.
-
- where:
- p1 is Sleep clock error in ppm (0-65535)
- p2 is Wakeup offset in usec (0-65535)
- p3 is Clock stabilization time in usec (0-65535)
- p4 is Control periodic calibration (0-2)
- p5 is Control the use of external sleep clock (0-2)
- p6 is reserved for debug (0-65535)
-
-subscribed_events
-
- The subscribed_events directory contains the interface for the
- subscribed events API.
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/subscribed_events/
-
- Each event is represented by a filename. Each filename consists of the
- following three fields:
- Value Frequency Subscribed
-
- To read the current values for a given event, do:
- cat event
- To set the current values, do:
- echo "60 2 1" > event
-
- Frequency field specifies the reporting frequency for this event.
- If it is set to 0, then the event is reported only once, and then
- automatically unsubscribed. If it is set to 1, then the event is
- reported every time it occurs. If it is set to N, then the event is
- reported every Nth time it occurs.
-
- beacon_missed
- Value field specifies the number of consecutive missing beacons which
- triggers the LINK_LOSS event. This event is generated only once after
- which the firmware resets its state. At initialization, the LINK_LOSS
- event is subscribed by default. The default value of MissedBeacons is
- 60.
-
- failure_count
- Value field specifies the consecutive failure count threshold which
- triggers the generation of the MAX_FAIL event. Once this event is
- generated, the consecutive failure count is reset to 0.
- At initialization, the MAX_FAIL event is NOT subscribed by
- default.
-
- high_rssi
- This event is generated when the average received RSSI in beacons goes
- above a threshold, specified by Value.
-
- low_rssi
- This event is generated when the average received RSSI in beacons goes
- below a threshold, specified by Value.
-
- high_snr
- This event is generated when the average received SNR in beacons goes
- above a threshold, specified by Value.
-
- low_snr
- This event is generated when the average received SNR in beacons goes
- below a threshold, specified by Value.
-
-extscan
- This command is used to do a specific scan.
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/
-
- Usage: echo "SSID" > extscan
-
- Example:
- echo "LINKSYS-AP" > extscan
-
- To see the results of use getscantable command.
-
-getscantable
-
- Display the current contents of the driver scan table (ie. get the
- scan results).
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/
-
- Usage:
- cat getscantable
-
-setuserscan
- Initiate a customized scan and retrieve the results
-
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/
-
- Usage:
- echo "[ARGS]" > setuserscan
-
- where [ARGS]:
-
- bssid=xx:xx:xx:xx:xx:xx specify a BSSID filter for the scan
- ssid="[SSID]" specify a SSID filter for the scan
- keep=[0 or 1] keep the previous scan results (1), discard (0)
- dur=[scan time] time to scan for each channel in milliseconds
- type=[1,2,3] BSS type: 1 (Infra), 2(Adhoc), 3(Any)
-
- Any combination of the above arguments can be supplied on the command
- line. If dur tokens are absent, the driver default setting will be used.
- The bssid and ssid fields, if blank, will produce an unfiltered scan.
- The type field will default to 3 (Any) and the keep field will default
- to 0 (Discard).
-
- Examples:
- 1) Perform a passive scan on all channels for 20 ms per channel:
- echo "dur=20" > setuserscan
-
- 2) Perform an active scan for a specific SSID:
- echo "ssid="TestAP"" > setuserscan
-
- 3) Scan all available channels (B/G, A bands) for a specific BSSID, keep
- the current scan table intact, update existing or append new scan data:
- echo "bssid=00:50:43:20:12:82 keep=1" > setuserscan
-
- 4) Scan for all infrastructure networks.
- Keep the previous scan table intact. Update any duplicate BSSID/SSID
- matches with the new scan data:
- echo "type=1 keep=1" > setuserscan
-
- All entries in the scan table (not just the new scan data when keep=1)
- will be displayed upon completion by use of the getscantable ioctl.
-
-hostsleep
- This command is used to enable/disable host sleep.
- Note: Host sleep parameters should be configured using
- "ethtool -s ethX wol X" command before enabling host sleep.
-
- Path: /sys/kernel/debug/libertas_wireless/ethX/
-
- Usage:
- cat hostsleep: reads the current hostsleep state
- echo "1" > hostsleep : enable host sleep.
- echo "0" > hostsleep : disable host sleep
-
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
deleted file mode 100644
index 8317afd06..000000000
--- a/drivers/net/wireless/libertas/cfg.c
+++ /dev/null
@@ -1,2215 +0,0 @@
-/*
- * Implement cfg80211 ("iw") support.
- *
- * Copyright (C) 2009 M&N Solutions GmbH, 61191 Rosbach, Germany
- * Holger Schurig <hs4233@mail.mn-solutions.de>
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/hardirq.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/ieee80211.h>
-#include <net/cfg80211.h>
-#include <asm/unaligned.h>
-
-#include "decl.h"
-#include "cfg.h"
-#include "cmd.h"
-#include "mesh.h"
-
-
-#define CHAN2G(_channel, _freq, _flags) { \
- .band = IEEE80211_BAND_2GHZ, \
- .center_freq = (_freq), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-static struct ieee80211_channel lbs_2ghz_channels[] = {
- CHAN2G(1, 2412, 0),
- CHAN2G(2, 2417, 0),
- CHAN2G(3, 2422, 0),
- CHAN2G(4, 2427, 0),
- CHAN2G(5, 2432, 0),
- CHAN2G(6, 2437, 0),
- CHAN2G(7, 2442, 0),
- CHAN2G(8, 2447, 0),
- CHAN2G(9, 2452, 0),
- CHAN2G(10, 2457, 0),
- CHAN2G(11, 2462, 0),
- CHAN2G(12, 2467, 0),
- CHAN2G(13, 2472, 0),
- CHAN2G(14, 2484, 0),
-};
-
-#define RATETAB_ENT(_rate, _hw_value, _flags) { \
- .bitrate = (_rate), \
- .hw_value = (_hw_value), \
- .flags = (_flags), \
-}
-
-
-/* Table 6 in section 3.2.1.1 */
-static struct ieee80211_rate lbs_rates[] = {
- RATETAB_ENT(10, 0, 0),
- RATETAB_ENT(20, 1, 0),
- RATETAB_ENT(55, 2, 0),
- RATETAB_ENT(110, 3, 0),
- RATETAB_ENT(60, 9, 0),
- RATETAB_ENT(90, 6, 0),
- RATETAB_ENT(120, 7, 0),
- RATETAB_ENT(180, 8, 0),
- RATETAB_ENT(240, 9, 0),
- RATETAB_ENT(360, 10, 0),
- RATETAB_ENT(480, 11, 0),
- RATETAB_ENT(540, 12, 0),
-};
-
-static struct ieee80211_supported_band lbs_band_2ghz = {
- .channels = lbs_2ghz_channels,
- .n_channels = ARRAY_SIZE(lbs_2ghz_channels),
- .bitrates = lbs_rates,
- .n_bitrates = ARRAY_SIZE(lbs_rates),
-};
-
-
-static const u32 cipher_suites[] = {
- WLAN_CIPHER_SUITE_WEP40,
- WLAN_CIPHER_SUITE_WEP104,
- WLAN_CIPHER_SUITE_TKIP,
- WLAN_CIPHER_SUITE_CCMP,
-};
-
-/* Time to stay on the channel */
-#define LBS_DWELL_PASSIVE 100
-#define LBS_DWELL_ACTIVE 40
-
-
-/***************************************************************************
- * Misc utility functions
- *
- * TLVs are Marvell specific. They are very similar to IEs, they have the
- * same structure: type, length, data*. The only difference: for IEs, the
- * type and length are u8, but for TLVs they're __le16.
- */
-
-/*
- * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1
- * in the firmware spec
- */
-static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
-{
- int ret = -ENOTSUPP;
-
- switch (auth_type) {
- case NL80211_AUTHTYPE_OPEN_SYSTEM:
- case NL80211_AUTHTYPE_SHARED_KEY:
- ret = auth_type;
- break;
- case NL80211_AUTHTYPE_AUTOMATIC:
- ret = NL80211_AUTHTYPE_OPEN_SYSTEM;
- break;
- case NL80211_AUTHTYPE_NETWORK_EAP:
- ret = 0x80;
- break;
- default:
- /* silence compiler */
- break;
- }
- return ret;
-}
-
-
-/*
- * Various firmware commands need the list of supported rates, but with
- * the hight-bit set for basic rates
- */
-static int lbs_add_rates(u8 *rates)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
- u8 rate = lbs_rates[i].bitrate / 5;
- if (rate == 0x02 || rate == 0x04 ||
- rate == 0x0b || rate == 0x16)
- rate |= 0x80;
- rates[i] = rate;
- }
- return ARRAY_SIZE(lbs_rates);
-}
-
-
-/***************************************************************************
- * TLV utility functions
- *
- * TLVs are Marvell specific. They are very similar to IEs, they have the
- * same structure: type, length, data*. The only difference: for IEs, the
- * type and length are u8, but for TLVs they're __le16.
- */
-
-
-/*
- * Add ssid TLV
- */
-#define LBS_MAX_SSID_TLV_SIZE \
- (sizeof(struct mrvl_ie_header) \
- + IEEE80211_MAX_SSID_LEN)
-
-static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len)
-{
- struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
-
- /*
- * TLV-ID SSID 00 00
- * length 06 00
- * ssid 4d 4e 54 45 53 54
- */
- ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
- ssid_tlv->header.len = cpu_to_le16(ssid_len);
- memcpy(ssid_tlv->ssid, ssid, ssid_len);
- return sizeof(ssid_tlv->header) + ssid_len;
-}
-
-
-/*
- * Add channel list TLV (section 8.4.2)
- *
- * Actual channel data comes from priv->wdev->wiphy->channels.
- */
-#define LBS_MAX_CHANNEL_LIST_TLV_SIZE \
- (sizeof(struct mrvl_ie_header) \
- + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset)))
-
-static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv,
- int last_channel, int active_scan)
-{
- int chanscanparamsize = sizeof(struct chanscanparamset) *
- (last_channel - priv->scan_channel);
-
- struct mrvl_ie_header *header = (void *) tlv;
-
- /*
- * TLV-ID CHANLIST 01 01
- * length 0e 00
- * channel 00 01 00 00 00 64 00
- * radio type 00
- * channel 01
- * scan type 00
- * min scan time 00 00
- * max scan time 64 00
- * channel 2 00 02 00 00 00 64 00
- *
- */
-
- header->type = cpu_to_le16(TLV_TYPE_CHANLIST);
- header->len = cpu_to_le16(chanscanparamsize);
- tlv += sizeof(struct mrvl_ie_header);
-
- /* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel,
- last_channel); */
- memset(tlv, 0, chanscanparamsize);
-
- while (priv->scan_channel < last_channel) {
- struct chanscanparamset *param = (void *) tlv;
-
- param->radiotype = CMD_SCAN_RADIO_TYPE_BG;
- param->channumber =
- priv->scan_req->channels[priv->scan_channel]->hw_value;
- if (active_scan) {
- param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE);
- } else {
- param->chanscanmode.passivescan = 1;
- param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE);
- }
- tlv += sizeof(struct chanscanparamset);
- priv->scan_channel++;
- }
- return sizeof(struct mrvl_ie_header) + chanscanparamsize;
-}
-
-
-/*
- * Add rates TLV
- *
- * The rates are in lbs_bg_rates[], but for the 802.11b
- * rates the high bit is set. We add this TLV only because
- * there's a firmware which otherwise doesn't report all
- * APs in range.
- */
-#define LBS_MAX_RATES_TLV_SIZE \
- (sizeof(struct mrvl_ie_header) \
- + (ARRAY_SIZE(lbs_rates)))
-
-/* Adds a TLV with all rates the hardware supports */
-static int lbs_add_supported_rates_tlv(u8 *tlv)
-{
- size_t i;
- struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
-
- /*
- * TLV-ID RATES 01 00
- * length 0e 00
- * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c
- */
- rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
- tlv += sizeof(rate_tlv->header);
- i = lbs_add_rates(tlv);
- tlv += i;
- rate_tlv->header.len = cpu_to_le16(i);
- return sizeof(rate_tlv->header) + i;
-}
-
-/* Add common rates from a TLV and return the new end of the TLV */
-static u8 *
-add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
-{
- int hw, ap, ap_max = ie[1];
- u8 hw_rate;
-
- /* Advance past IE header */
- ie += 2;
-
- lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
-
- for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
- hw_rate = lbs_rates[hw].bitrate / 5;
- for (ap = 0; ap < ap_max; ap++) {
- if (hw_rate == (ie[ap] & 0x7f)) {
- *tlv++ = ie[ap];
- *nrates = *nrates + 1;
- }
- }
- }
- return tlv;
-}
-
-/*
- * Adds a TLV with all rates the hardware *and* BSS supports.
- */
-static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
-{
- struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
- const u8 *rates_eid, *ext_rates_eid;
- int n = 0;
-
- rcu_read_lock();
- rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
- ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
-
- /*
- * 01 00 TLV_TYPE_RATES
- * 04 00 len
- * 82 84 8b 96 rates
- */
- rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
- tlv += sizeof(rate_tlv->header);
-
- /* Add basic rates */
- if (rates_eid) {
- tlv = add_ie_rates(tlv, rates_eid, &n);
-
- /* Add extended rates, if any */
- if (ext_rates_eid)
- tlv = add_ie_rates(tlv, ext_rates_eid, &n);
- } else {
- lbs_deb_assoc("assoc: bss had no basic rate IE\n");
- /* Fallback: add basic 802.11b rates */
- *tlv++ = 0x82;
- *tlv++ = 0x84;
- *tlv++ = 0x8b;
- *tlv++ = 0x96;
- n = 4;
- }
- rcu_read_unlock();
-
- rate_tlv->header.len = cpu_to_le16(n);
- return sizeof(rate_tlv->header) + n;
-}
-
-
-/*
- * Add auth type TLV.
- *
- * This is only needed for newer firmware (V9 and up).
- */
-#define LBS_MAX_AUTH_TYPE_TLV_SIZE \
- sizeof(struct mrvl_ie_auth_type)
-
-static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type)
-{
- struct mrvl_ie_auth_type *auth = (void *) tlv;
-
- /*
- * 1f 01 TLV_TYPE_AUTH_TYPE
- * 01 00 len
- * 01 auth type
- */
- auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
- auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header));
- auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type));
- return sizeof(*auth);
-}
-
-
-/*
- * Add channel (phy ds) TLV
- */
-#define LBS_MAX_CHANNEL_TLV_SIZE \
- sizeof(struct mrvl_ie_header)
-
-static int lbs_add_channel_tlv(u8 *tlv, u8 channel)
-{
- struct mrvl_ie_ds_param_set *ds = (void *) tlv;
-
- /*
- * 03 00 TLV_TYPE_PHY_DS
- * 01 00 len
- * 06 channel
- */
- ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
- ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header));
- ds->channel = channel;
- return sizeof(*ds);
-}
-
-
-/*
- * Add (empty) CF param TLV of the form:
- */
-#define LBS_MAX_CF_PARAM_TLV_SIZE \
- sizeof(struct mrvl_ie_header)
-
-static int lbs_add_cf_param_tlv(u8 *tlv)
-{
- struct mrvl_ie_cf_param_set *cf = (void *)tlv;
-
- /*
- * 04 00 TLV_TYPE_CF
- * 06 00 len
- * 00 cfpcnt
- * 00 cfpperiod
- * 00 00 cfpmaxduration
- * 00 00 cfpdurationremaining
- */
- cf->header.type = cpu_to_le16(TLV_TYPE_CF);
- cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header));
- return sizeof(*cf);
-}
-
-/*
- * Add WPA TLV
- */
-#define LBS_MAX_WPA_TLV_SIZE \
- (sizeof(struct mrvl_ie_header) \
- + 128 /* TODO: I guessed the size */)
-
-static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
-{
- size_t tlv_len;
-
- /*
- * We need just convert an IE to an TLV. IEs use u8 for the header,
- * u8 type
- * u8 len
- * u8[] data
- * but TLVs use __le16 instead:
- * __le16 type
- * __le16 len
- * u8[] data
- */
- *tlv++ = *ie++;
- *tlv++ = 0;
- tlv_len = *tlv++ = *ie++;
- *tlv++ = 0;
- while (tlv_len--)
- *tlv++ = *ie++;
- /* the TLV is two bytes larger than the IE */
- return ie_len + 2;
-}
-
-/*
- * Set Channel
- */
-
-static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
- struct cfg80211_chan_def *chandef)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- int ret = -ENOTSUPP;
-
- lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
- chandef->chan->center_freq,
- cfg80211_get_chandef_type(chandef));
-
- if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
- goto out;
-
- ret = lbs_set_channel(priv, chandef->chan->hw_value);
-
- out:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy,
- struct net_device *netdev,
- struct ieee80211_channel *channel)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- int ret = -ENOTSUPP;
-
- lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d",
- netdev_name(netdev), channel->center_freq);
-
- if (netdev != priv->mesh_dev)
- goto out;
-
- ret = lbs_mesh_set_channel(priv, channel->hw_value);
-
- out:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-
-/*
- * Scanning
- */
-
-/*
- * When scanning, the firmware doesn't send a nul packet with the power-safe
- * bit to the AP. So we cannot stay away from our current channel too long,
- * otherwise we loose data. So take a "nap" while scanning every other
- * while.
- */
-#define LBS_SCAN_BEFORE_NAP 4
-
-
-/*
- * When the firmware reports back a scan-result, it gives us an "u8 rssi",
- * which isn't really an RSSI, as it becomes larger when moving away from
- * the AP. Anyway, we need to convert that into mBm.
- */
-#define LBS_SCAN_RSSI_TO_MBM(rssi) \
- ((-(int)rssi + 3)*100)
-
-static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
- struct cmd_header *resp)
-{
- struct cfg80211_bss *bss;
- struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
- int bsssize;
- const u8 *pos;
- const u8 *tsfdesc;
- int tsfsize;
- int i;
- int ret = -EILSEQ;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
-
- lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
- scanresp->nr_sets, bsssize, le16_to_cpu(resp->size));
-
- if (scanresp->nr_sets == 0) {
- ret = 0;
- goto done;
- }
-
- /*
- * The general layout of the scan response is described in chapter
- * 5.7.1. Basically we have a common part, then any number of BSS
- * descriptor sections. Finally we have section with the same number
- * of TSFs.
- *
- * cmd_ds_802_11_scan_rsp
- * cmd_header
- * pos_size
- * nr_sets
- * bssdesc 1
- * bssid
- * rssi
- * timestamp
- * intvl
- * capa
- * IEs
- * bssdesc 2
- * bssdesc n
- * MrvlIEtypes_TsfFimestamp_t
- * TSF for BSS 1
- * TSF for BSS 2
- * TSF for BSS n
- */
-
- pos = scanresp->bssdesc_and_tlvbuffer;
-
- lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
- scanresp->bssdescriptsize);
-
- tsfdesc = pos + bsssize;
- tsfsize = 4 + 8 * scanresp->nr_sets;
- lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
-
- /* Validity check: we expect a Marvell-Local TLV */
- i = get_unaligned_le16(tsfdesc);
- tsfdesc += 2;
- if (i != TLV_TYPE_TSFTIMESTAMP) {
- lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
- goto done;
- }
-
- /*
- * Validity check: the TLV holds TSF values with 8 bytes each, so
- * the size in the TLV must match the nr_sets value
- */
- i = get_unaligned_le16(tsfdesc);
- tsfdesc += 2;
- if (i / 8 != scanresp->nr_sets) {
- lbs_deb_scan("scan response: invalid number of TSF timestamp "
- "sets (expected %d got %d)\n", scanresp->nr_sets,
- i / 8);
- goto done;
- }
-
- for (i = 0; i < scanresp->nr_sets; i++) {
- const u8 *bssid;
- const u8 *ie;
- int left;
- int ielen;
- int rssi;
- u16 intvl;
- u16 capa;
- int chan_no = -1;
- const u8 *ssid = NULL;
- u8 ssid_len = 0;
-
- int len = get_unaligned_le16(pos);
- pos += 2;
-
- /* BSSID */
- bssid = pos;
- pos += ETH_ALEN;
- /* RSSI */
- rssi = *pos++;
- /* Packet time stamp */
- pos += 8;
- /* Beacon interval */
- intvl = get_unaligned_le16(pos);
- pos += 2;
- /* Capabilities */
- capa = get_unaligned_le16(pos);
- pos += 2;
-
- /* To find out the channel, we must parse the IEs */
- ie = pos;
- /*
- * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
- * interval, capabilities
- */
- ielen = left = len - (6 + 1 + 8 + 2 + 2);
- while (left >= 2) {
- u8 id, elen;
- id = *pos++;
- elen = *pos++;
- left -= 2;
- if (elen > left) {
- lbs_deb_scan("scan response: invalid IE fmt\n");
- goto done;
- }
-
- if (id == WLAN_EID_DS_PARAMS)
- chan_no = *pos;
- if (id == WLAN_EID_SSID) {
- ssid = pos;
- ssid_len = elen;
- }
- left -= elen;
- pos += elen;
- }
-
- /* No channel, no luck */
- if (chan_no != -1) {
- struct wiphy *wiphy = priv->wdev->wiphy;
- int freq = ieee80211_channel_to_frequency(chan_no,
- IEEE80211_BAND_2GHZ);
- struct ieee80211_channel *channel =
- ieee80211_get_channel(wiphy, freq);
-
- lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %*pE, %d dBm\n",
- bssid, capa, chan_no, ssid_len, ssid,
- LBS_SCAN_RSSI_TO_MBM(rssi)/100);
-
- if (channel &&
- !(channel->flags & IEEE80211_CHAN_DISABLED)) {
- bss = cfg80211_inform_bss(wiphy, channel,
- CFG80211_BSS_FTYPE_UNKNOWN,
- bssid, get_unaligned_le64(tsfdesc),
- capa, intvl, ie, ielen,
- LBS_SCAN_RSSI_TO_MBM(rssi),
- GFP_KERNEL);
- cfg80211_put_bss(wiphy, bss);
- }
- } else
- lbs_deb_scan("scan response: missing BSS channel IE\n");
-
- tsfdesc += 8;
- }
- ret = 0;
-
- done:
- lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
- return ret;
-}
-
-
-/*
- * Our scan command contains a TLV, consting of a SSID TLV, a channel list
- * TLV and a rates TLV. Determine the maximum size of them:
- */
-#define LBS_SCAN_MAX_CMD_SIZE \
- (sizeof(struct cmd_ds_802_11_scan) \
- + LBS_MAX_SSID_TLV_SIZE \
- + LBS_MAX_CHANNEL_LIST_TLV_SIZE \
- + LBS_MAX_RATES_TLV_SIZE)
-
-/*
- * Assumes priv->scan_req is initialized and valid
- * Assumes priv->scan_channel is initialized
- */
-static void lbs_scan_worker(struct work_struct *work)
-{
- struct lbs_private *priv =
- container_of(work, struct lbs_private, scan_work.work);
- struct cmd_ds_802_11_scan *scan_cmd;
- u8 *tlv; /* pointer into our current, growing TLV storage area */
- int last_channel;
- int running, carrier;
-
- lbs_deb_enter(LBS_DEB_SCAN);
-
- scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
- if (scan_cmd == NULL)
- goto out_no_scan_cmd;
-
- /* prepare fixed part of scan command */
- scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
-
- /* stop network while we're away from our main channel */
- running = !netif_queue_stopped(priv->dev);
- carrier = netif_carrier_ok(priv->dev);
- if (running)
- netif_stop_queue(priv->dev);
- if (carrier)
- netif_carrier_off(priv->dev);
-
- /* prepare fixed part of scan command */
- tlv = scan_cmd->tlvbuffer;
-
- /* add SSID TLV */
- if (priv->scan_req->n_ssids && priv->scan_req->ssids[0].ssid_len > 0)
- tlv += lbs_add_ssid_tlv(tlv,
- priv->scan_req->ssids[0].ssid,
- priv->scan_req->ssids[0].ssid_len);
-
- /* add channel TLVs */
- last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP;
- if (last_channel > priv->scan_req->n_channels)
- last_channel = priv->scan_req->n_channels;
- tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel,
- priv->scan_req->n_ssids);
-
- /* add rates TLV */
- tlv += lbs_add_supported_rates_tlv(tlv);
-
- if (priv->scan_channel < priv->scan_req->n_channels) {
- cancel_delayed_work(&priv->scan_work);
- if (netif_running(priv->dev))
- queue_delayed_work(priv->work_thread, &priv->scan_work,
- msecs_to_jiffies(300));
- }
-
- /* This is the final data we are about to send */
- scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd);
- lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
- sizeof(*scan_cmd));
- lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
- tlv - scan_cmd->tlvbuffer);
-
- __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
- le16_to_cpu(scan_cmd->hdr.size),
- lbs_ret_scan, 0);
-
- if (priv->scan_channel >= priv->scan_req->n_channels) {
- /* Mark scan done */
- cancel_delayed_work(&priv->scan_work);
- lbs_scan_done(priv);
- }
-
- /* Restart network */
- if (carrier)
- netif_carrier_on(priv->dev);
- if (running && !priv->tx_pending_len)
- netif_wake_queue(priv->dev);
-
- kfree(scan_cmd);
-
- /* Wake up anything waiting on scan completion */
- if (priv->scan_req == NULL) {
- lbs_deb_scan("scan: waking up waiters\n");
- wake_up_all(&priv->scan_q);
- }
-
- out_no_scan_cmd:
- lbs_deb_leave(LBS_DEB_SCAN);
-}
-
-static void _internal_start_scan(struct lbs_private *priv, bool internal,
- struct cfg80211_scan_request *request)
-{
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
- request->n_ssids, request->n_channels, request->ie_len);
-
- priv->scan_channel = 0;
- priv->scan_req = request;
- priv->internal_scan = internal;
-
- queue_delayed_work(priv->work_thread, &priv->scan_work,
- msecs_to_jiffies(50));
-
- lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
-/*
- * Clean up priv->scan_req. Should be used to handle the allocation details.
- */
-void lbs_scan_done(struct lbs_private *priv)
-{
- WARN_ON(!priv->scan_req);
-
- if (priv->internal_scan)
- kfree(priv->scan_req);
- else
- cfg80211_scan_done(priv->scan_req, false);
-
- priv->scan_req = NULL;
-}
-
-static int lbs_cfg_scan(struct wiphy *wiphy,
- struct cfg80211_scan_request *request)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (priv->scan_req || delayed_work_pending(&priv->scan_work)) {
- /* old scan request not yet processed */
- ret = -EAGAIN;
- goto out;
- }
-
- _internal_start_scan(priv, false, request);
-
- if (priv->surpriseremoved)
- ret = -EIO;
-
- out:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-
-
-/*
- * Events
- */
-
-void lbs_send_disconnect_notification(struct lbs_private *priv,
- bool locally_generated)
-{
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- cfg80211_disconnected(priv->dev, 0, NULL, 0, locally_generated,
- GFP_KERNEL);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
-void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
-{
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- cfg80211_michael_mic_failure(priv->dev,
- priv->assoc_bss,
- event == MACREG_INT_CODE_MIC_ERR_MULTICAST ?
- NL80211_KEYTYPE_GROUP :
- NL80211_KEYTYPE_PAIRWISE,
- -1,
- NULL,
- GFP_KERNEL);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
-
-
-
-/*
- * Connect/disconnect
- */
-
-
-/*
- * This removes all WEP keys
- */
-static int lbs_remove_wep_keys(struct lbs_private *priv)
-{
- struct cmd_ds_802_11_set_wep cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
- cmd.action = cpu_to_le16(CMD_ACT_REMOVE);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
- return ret;
-}
-
-/*
- * Set WEP keys
- */
-static int lbs_set_wep_keys(struct lbs_private *priv)
-{
- struct cmd_ds_802_11_set_wep cmd;
- int i;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- /*
- * command 13 00
- * size 50 00
- * sequence xx xx
- * result 00 00
- * action 02 00 ACT_ADD
- * transmit key 00 00
- * type for key 1 01 WEP40
- * type for key 2 00
- * type for key 3 00
- * type for key 4 00
- * key 1 39 39 39 39 39 00 00 00
- * 00 00 00 00 00 00 00 00
- * key 2 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * key 3 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * key 4 00 00 00 00 00 00 00 00
- */
- if (priv->wep_key_len[0] || priv->wep_key_len[1] ||
- priv->wep_key_len[2] || priv->wep_key_len[3]) {
- /* Only set wep keys if we have at least one of them */
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
- cmd.action = cpu_to_le16(CMD_ACT_ADD);
-
- for (i = 0; i < 4; i++) {
- switch (priv->wep_key_len[i]) {
- case WLAN_KEY_LEN_WEP40:
- cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
- break;
- case WLAN_KEY_LEN_WEP104:
- cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
- break;
- default:
- cmd.keytype[i] = 0;
- break;
- }
- memcpy(cmd.keymaterial[i], priv->wep_key[i],
- priv->wep_key_len[i]);
- }
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
- } else {
- /* Otherwise remove all wep keys */
- ret = lbs_remove_wep_keys(priv);
- }
-
- lbs_deb_leave(LBS_DEB_CFG80211);
- return ret;
-}
-
-
-/*
- * Enable/Disable RSN status
- */
-static int lbs_enable_rsn(struct lbs_private *priv, int enable)
-{
- struct cmd_ds_802_11_enable_rsn cmd;
- int ret;
-
- lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", enable);
-
- /*
- * cmd 2f 00
- * size 0c 00
- * sequence xx xx
- * result 00 00
- * action 01 00 ACT_SET
- * enable 01 00
- */
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.enable = cpu_to_le16(enable);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
- return ret;
-}
-
-
-/*
- * Set WPA/WPA key material
- */
-
-/*
- * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
- * get rid of WEXT, this should go into host.h
- */
-
-struct cmd_key_material {
- struct cmd_header hdr;
-
- __le16 action;
- struct MrvlIEtype_keyParamSet param;
-} __packed;
-
-static int lbs_set_key_material(struct lbs_private *priv,
- int key_type, int key_info,
- const u8 *key, u16 key_len)
-{
- struct cmd_key_material cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- /*
- * Example for WPA (TKIP):
- *
- * cmd 5e 00
- * size 34 00
- * sequence xx xx
- * result 00 00
- * action 01 00
- * TLV type 00 01 key param
- * length 00 26
- * key type 01 00 TKIP
- * key info 06 00 UNICAST | ENABLED
- * key len 20 00
- * key 32 bytes
- */
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
- cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4);
- cmd.param.keytypeid = cpu_to_le16(key_type);
- cmd.param.keyinfo = cpu_to_le16(key_info);
- cmd.param.keylen = cpu_to_le16(key_len);
- if (key && key_len)
- memcpy(cmd.param.key, key, key_len);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
- return ret;
-}
-
-
-/*
- * Sets the auth type (open, shared, etc) in the firmware. That
- * we use CMD_802_11_AUTHENTICATE is misleading, this firmware
- * command doesn't send an authentication frame at all, it just
- * stores the auth_type.
- */
-static int lbs_set_authtype(struct lbs_private *priv,
- struct cfg80211_connect_params *sme)
-{
- struct cmd_ds_802_11_authenticate cmd;
- int ret;
-
- lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type);
-
- /*
- * cmd 11 00
- * size 19 00
- * sequence xx xx
- * result 00 00
- * BSS id 00 13 19 80 da 30
- * auth type 00
- * reserved 00 00 00 00 00 00 00 00 00 00
- */
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- if (sme->bssid)
- memcpy(cmd.bssid, sme->bssid, ETH_ALEN);
- /* convert auth_type */
- ret = lbs_auth_to_authtype(sme->auth_type);
- if (ret < 0)
- goto done;
-
- cmd.authtype = ret;
- ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
-
- done:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-/*
- * Create association request
- */
-#define LBS_ASSOC_MAX_CMD_SIZE \
- (sizeof(struct cmd_ds_802_11_associate) \
- - 512 /* cmd_ds_802_11_associate.iebuf */ \
- + LBS_MAX_SSID_TLV_SIZE \
- + LBS_MAX_CHANNEL_TLV_SIZE \
- + LBS_MAX_CF_PARAM_TLV_SIZE \
- + LBS_MAX_AUTH_TYPE_TLV_SIZE \
- + LBS_MAX_WPA_TLV_SIZE)
-
-static int lbs_associate(struct lbs_private *priv,
- struct cfg80211_bss *bss,
- struct cfg80211_connect_params *sme)
-{
- struct cmd_ds_802_11_associate_response *resp;
- struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE,
- GFP_KERNEL);
- const u8 *ssid_eid;
- size_t len, resp_ie_len;
- int status;
- int ret;
- u8 *pos = &(cmd->iebuf[0]);
- u8 *tmp;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (!cmd) {
- ret = -ENOMEM;
- goto done;
- }
-
- /*
- * cmd 50 00
- * length 34 00
- * sequence xx xx
- * result 00 00
- * BSS id 00 13 19 80 da 30
- * capabilities 11 00
- * listen interval 0a 00
- * beacon interval 00 00
- * DTIM period 00
- * TLVs xx (up to 512 bytes)
- */
- cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE);
-
- /* Fill in static fields */
- memcpy(cmd->bssid, bss->bssid, ETH_ALEN);
- cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
- cmd->capability = cpu_to_le16(bss->capability);
-
- /* add SSID TLV */
- rcu_read_lock();
- ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
- if (ssid_eid)
- pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
- else
- lbs_deb_assoc("no SSID\n");
- rcu_read_unlock();
-
- /* add DS param TLV */
- if (bss->channel)
- pos += lbs_add_channel_tlv(pos, bss->channel->hw_value);
- else
- lbs_deb_assoc("no channel\n");
-
- /* add (empty) CF param TLV */
- pos += lbs_add_cf_param_tlv(pos);
-
- /* add rates TLV */
- tmp = pos + 4; /* skip Marvell IE header */
- pos += lbs_add_common_rates_tlv(pos, bss);
- lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
-
- /* add auth type TLV */
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
- pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
-
- /* add WPA/WPA2 TLV */
- if (sme->ie && sme->ie_len)
- pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len);
-
- len = (sizeof(*cmd) - sizeof(cmd->iebuf)) +
- (u16)(pos - (u8 *) &cmd->iebuf);
- cmd->hdr.size = cpu_to_le16(len);
-
- lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
- le16_to_cpu(cmd->hdr.size));
-
- /* store for later use */
- memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd);
- if (ret)
- goto done;
-
- /* generate connect message to cfg80211 */
-
- resp = (void *) cmd; /* recast for easier field access */
- status = le16_to_cpu(resp->statuscode);
-
- /* Older FW versions map the IEEE 802.11 Status Code in the association
- * response to the following values returned in resp->statuscode:
- *
- * IEEE Status Code Marvell Status Code
- * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
- * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
- * others -> 0x0003 ASSOC_RESULT_REFUSED
- *
- * Other response codes:
- * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
- * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
- * association response from the AP)
- */
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
- switch (status) {
- case 0:
- break;
- case 1:
- lbs_deb_assoc("invalid association parameters\n");
- status = WLAN_STATUS_CAPS_UNSUPPORTED;
- break;
- case 2:
- lbs_deb_assoc("timer expired while waiting for AP\n");
- status = WLAN_STATUS_AUTH_TIMEOUT;
- break;
- case 3:
- lbs_deb_assoc("association refused by AP\n");
- status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
- break;
- case 4:
- lbs_deb_assoc("authentication refused by AP\n");
- status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
- break;
- default:
- lbs_deb_assoc("association failure %d\n", status);
- /* v5 OLPC firmware does return the AP status code if
- * it's not one of the values above. Let that through.
- */
- break;
- }
- }
-
- lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
- "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
- le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
-
- resp_ie_len = le16_to_cpu(resp->hdr.size)
- - sizeof(resp->hdr)
- - 6;
- cfg80211_connect_result(priv->dev,
- priv->assoc_bss,
- sme->ie, sme->ie_len,
- resp->iebuf, resp_ie_len,
- status,
- GFP_KERNEL);
-
- if (status == 0) {
- /* TODO: get rid of priv->connect_status */
- priv->connect_status = LBS_CONNECTED;
- netif_carrier_on(priv->dev);
- if (!priv->tx_pending_len)
- netif_tx_wake_all_queues(priv->dev);
- }
-
- kfree(cmd);
-done:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-static struct cfg80211_scan_request *
-_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
-{
- struct cfg80211_scan_request *creq = NULL;
- int i, n_channels = ieee80211_get_num_supported_channels(wiphy);
- enum ieee80211_band band;
-
- creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
- n_channels * sizeof(void *),
- GFP_ATOMIC);
- if (!creq)
- return NULL;
-
- /* SSIDs come after channels */
- creq->ssids = (void *)&creq->channels[n_channels];
- creq->n_channels = n_channels;
- creq->n_ssids = 1;
-
- /* Scan all available channels */
- i = 0;
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
- int j;
-
- if (!wiphy->bands[band])
- continue;
-
- for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
- /* ignore disabled channels */
- if (wiphy->bands[band]->channels[j].flags &
- IEEE80211_CHAN_DISABLED)
- continue;
-
- creq->channels[i] = &wiphy->bands[band]->channels[j];
- i++;
- }
- }
- if (i) {
- /* Set real number of channels specified in creq->channels[] */
- creq->n_channels = i;
-
- /* Scan for the SSID we're going to connect to */
- memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len);
- creq->ssids[0].ssid_len = sme->ssid_len;
- } else {
- /* No channels found... */
- kfree(creq);
- creq = NULL;
- }
-
- return creq;
-}
-
-static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_connect_params *sme)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- struct cfg80211_bss *bss = NULL;
- int ret = 0;
- u8 preamble = RADIO_PREAMBLE_SHORT;
-
- if (dev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (!sme->bssid) {
- struct cfg80211_scan_request *creq;
-
- /*
- * Scan for the requested network after waiting for existing
- * scans to finish.
- */
- lbs_deb_assoc("assoc: waiting for existing scans\n");
- wait_event_interruptible_timeout(priv->scan_q,
- (priv->scan_req == NULL),
- (15 * HZ));
-
- creq = _new_connect_scan_req(wiphy, sme);
- if (!creq) {
- ret = -EINVAL;
- goto done;
- }
-
- lbs_deb_assoc("assoc: scanning for compatible AP\n");
- _internal_start_scan(priv, true, creq);
-
- lbs_deb_assoc("assoc: waiting for scan to complete\n");
- wait_event_interruptible_timeout(priv->scan_q,
- (priv->scan_req == NULL),
- (15 * HZ));
- lbs_deb_assoc("assoc: scanning completed\n");
- }
-
- /* Find the BSS we want using available scan results */
- bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
- sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS,
- IEEE80211_PRIVACY_ANY);
- if (!bss) {
- wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
- sme->bssid);
- ret = -ENOENT;
- goto done;
- }
- lbs_deb_assoc("trying %pM\n", bss->bssid);
- lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
- sme->crypto.cipher_group,
- sme->key_idx, sme->key_len);
-
- /* As this is a new connection, clear locally stored WEP keys */
- priv->wep_tx_key = 0;
- memset(priv->wep_key, 0, sizeof(priv->wep_key));
- memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
-
- /* set/remove WEP keys */
- switch (sme->crypto.cipher_group) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- /* Store provided WEP keys in priv-> */
- priv->wep_tx_key = sme->key_idx;
- priv->wep_key_len[sme->key_idx] = sme->key_len;
- memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len);
- /* Set WEP keys and WEP mode */
- lbs_set_wep_keys(priv);
- priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
- lbs_set_mac_control(priv);
- /* No RSN mode for WEP */
- lbs_enable_rsn(priv, 0);
- break;
- case 0: /* there's no WLAN_CIPHER_SUITE_NONE definition */
- /*
- * If we don't have no WEP, no WPA and no WPA2,
- * we remove all keys like in the WPA/WPA2 setup,
- * we just don't set RSN.
- *
- * Therefore: fall-through
- */
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- /* Remove WEP keys and WEP mode */
- lbs_remove_wep_keys(priv);
- priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
- lbs_set_mac_control(priv);
-
- /* clear the WPA/WPA2 keys */
- lbs_set_key_material(priv,
- KEY_TYPE_ID_WEP, /* doesn't matter */
- KEY_INFO_WPA_UNICAST,
- NULL, 0);
- lbs_set_key_material(priv,
- KEY_TYPE_ID_WEP, /* doesn't matter */
- KEY_INFO_WPA_MCAST,
- NULL, 0);
- /* RSN mode for WPA/WPA2 */
- lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
- break;
- default:
- wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
- sme->crypto.cipher_group);
- ret = -ENOTSUPP;
- goto done;
- }
-
- ret = lbs_set_authtype(priv, sme);
- if (ret == -ENOTSUPP) {
- wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type);
- goto done;
- }
-
- lbs_set_radio(priv, preamble, 1);
-
- /* Do the actual association */
- ret = lbs_associate(priv, bss, sme);
-
- done:
- if (bss)
- cfg80211_put_bss(wiphy, bss);
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-int lbs_disconnect(struct lbs_private *priv, u16 reason)
-{
- struct cmd_ds_802_11_deauthenticate cmd;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- /* Mildly ugly to use a locally store my own BSSID ... */
- memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
- cmd.reasoncode = cpu_to_le16(reason);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
- if (ret)
- return ret;
-
- cfg80211_disconnected(priv->dev,
- reason,
- NULL, 0, true,
- GFP_KERNEL);
- priv->connect_status = LBS_DISCONNECTED;
-
- return 0;
-}
-
-static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
- u16 reason_code)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
-
- if (dev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
-
- /* store for lbs_cfg_ret_disconnect() */
- priv->disassoc_reason = reason_code;
-
- return lbs_disconnect(priv, reason_code);
-}
-
-static int lbs_cfg_set_default_key(struct wiphy *wiphy,
- struct net_device *netdev,
- u8 key_index, bool unicast,
- bool multicast)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
-
- if (netdev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (key_index != priv->wep_tx_key) {
- lbs_deb_assoc("set_default_key: to %d\n", key_index);
- priv->wep_tx_key = key_index;
- lbs_set_wep_keys(priv);
- }
-
- return 0;
-}
-
-
-static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 idx, bool pairwise, const u8 *mac_addr,
- struct key_params *params)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- u16 key_info;
- u16 key_type;
- int ret = 0;
-
- if (netdev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
- params->cipher, mac_addr);
- lbs_deb_assoc("add_key: key index %d, key len %d\n",
- idx, params->key_len);
- if (params->key_len)
- lbs_deb_hex(LBS_DEB_CFG80211, "KEY",
- params->key, params->key_len);
-
- lbs_deb_assoc("add_key: seq len %d\n", params->seq_len);
- if (params->seq_len)
- lbs_deb_hex(LBS_DEB_CFG80211, "SEQ",
- params->seq, params->seq_len);
-
- switch (params->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- /* actually compare if something has changed ... */
- if ((priv->wep_key_len[idx] != params->key_len) ||
- memcmp(priv->wep_key[idx],
- params->key, params->key_len) != 0) {
- priv->wep_key_len[idx] = params->key_len;
- memcpy(priv->wep_key[idx],
- params->key, params->key_len);
- lbs_set_wep_keys(priv);
- }
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- key_info = KEY_INFO_WPA_ENABLED | ((idx == 0)
- ? KEY_INFO_WPA_UNICAST
- : KEY_INFO_WPA_MCAST);
- key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP)
- ? KEY_TYPE_ID_TKIP
- : KEY_TYPE_ID_AES;
- lbs_set_key_material(priv,
- key_type,
- key_info,
- params->key, params->key_len);
- break;
- default:
- wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
- ret = -ENOTSUPP;
- break;
- }
-
- return ret;
-}
-
-
-static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
- u8 key_index, bool pairwise, const u8 *mac_addr)
-{
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n",
- key_index, mac_addr);
-
-#ifdef TODO
- struct lbs_private *priv = wiphy_priv(wiphy);
- /*
- * I think can keep this a NO-OP, because:
-
- * - we clear all keys whenever we do lbs_cfg_connect() anyway
- * - neither "iw" nor "wpa_supplicant" won't call this during
- * an ongoing connection
- * - TODO: but I have to check if this is still true when
- * I set the AP to periodic re-keying
- * - we've not kzallec() something when we've added a key at
- * lbs_cfg_connect() or lbs_cfg_add_key().
- *
- * This causes lbs_cfg_del_key() only called at disconnect time,
- * where we'd just waste time deleting a key that is not going
- * to be used anyway.
- */
- if (key_index < 3 && priv->wep_key_len[key_index]) {
- priv->wep_key_len[key_index] = 0;
- lbs_set_wep_keys(priv);
- }
-#endif
-
- return 0;
-}
-
-
-/*
- * Get station
- */
-
-static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
- const u8 *mac, struct station_info *sinfo)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- s8 signal, noise;
- int ret;
- size_t i;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES) |
- BIT(NL80211_STA_INFO_TX_PACKETS) |
- BIT(NL80211_STA_INFO_RX_BYTES) |
- BIT(NL80211_STA_INFO_RX_PACKETS);
- sinfo->tx_bytes = priv->dev->stats.tx_bytes;
- sinfo->tx_packets = priv->dev->stats.tx_packets;
- sinfo->rx_bytes = priv->dev->stats.rx_bytes;
- sinfo->rx_packets = priv->dev->stats.rx_packets;
-
- /* Get current RSSI */
- ret = lbs_get_rssi(priv, &signal, &noise);
- if (ret == 0) {
- sinfo->signal = signal;
- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
- }
-
- /* Convert priv->cur_rate from hw_value to NL80211 value */
- for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
- if (priv->cur_rate == lbs_rates[i].hw_value) {
- sinfo->txrate.legacy = lbs_rates[i].bitrate;
- sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
- break;
- }
- }
-
- return 0;
-}
-
-
-
-
-/*
- * Change interface
- */
-
-static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- int ret = 0;
-
- if (dev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- switch (type) {
- case NL80211_IFTYPE_MONITOR:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_ADHOC:
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (priv->iface_running)
- ret = lbs_set_iface_type(priv, type);
-
- if (!ret)
- priv->wdev->iftype = type;
-
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-
-/*
- * IBSS (Ad-Hoc)
- */
-
-/*
- * The firmware needs the following bits masked out of the beacon-derived
- * capability field when associating/joining to a BSS:
- * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
- */
-#define CAPINFO_MASK (~(0xda00))
-
-
-static void lbs_join_post(struct lbs_private *priv,
- struct cfg80211_ibss_params *params,
- u8 *bssid, u16 capability)
-{
- u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN + /* ssid */
- 2 + 4 + /* basic rates */
- 2 + 1 + /* DS parameter */
- 2 + 2 + /* atim */
- 2 + 8]; /* extended rates */
- u8 *fake = fake_ie;
- struct cfg80211_bss *bss;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- /*
- * For cfg80211_inform_bss, we'll need a fake IE, as we can't get
- * the real IE from the firmware. So we fabricate a fake IE based on
- * what the firmware actually sends (sniffed with wireshark).
- */
- /* Fake SSID IE */
- *fake++ = WLAN_EID_SSID;
- *fake++ = params->ssid_len;
- memcpy(fake, params->ssid, params->ssid_len);
- fake += params->ssid_len;
- /* Fake supported basic rates IE */
- *fake++ = WLAN_EID_SUPP_RATES;
- *fake++ = 4;
- *fake++ = 0x82;
- *fake++ = 0x84;
- *fake++ = 0x8b;
- *fake++ = 0x96;
- /* Fake DS channel IE */
- *fake++ = WLAN_EID_DS_PARAMS;
- *fake++ = 1;
- *fake++ = params->chandef.chan->hw_value;
- /* Fake IBSS params IE */
- *fake++ = WLAN_EID_IBSS_PARAMS;
- *fake++ = 2;
- *fake++ = 0; /* ATIM=0 */
- *fake++ = 0;
- /* Fake extended rates IE, TODO: don't add this for 802.11b only,
- * but I don't know how this could be checked */
- *fake++ = WLAN_EID_EXT_SUPP_RATES;
- *fake++ = 8;
- *fake++ = 0x0c;
- *fake++ = 0x12;
- *fake++ = 0x18;
- *fake++ = 0x24;
- *fake++ = 0x30;
- *fake++ = 0x48;
- *fake++ = 0x60;
- *fake++ = 0x6c;
- lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
-
- bss = cfg80211_inform_bss(priv->wdev->wiphy,
- params->chandef.chan,
- CFG80211_BSS_FTYPE_UNKNOWN,
- bssid,
- 0,
- capability,
- params->beacon_interval,
- fake_ie, fake - fake_ie,
- 0, GFP_KERNEL);
- cfg80211_put_bss(priv->wdev->wiphy, bss);
-
- memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
- priv->wdev->ssid_len = params->ssid_len;
-
- cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
- GFP_KERNEL);
-
- /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
- priv->connect_status = LBS_CONNECTED;
- netif_carrier_on(priv->dev);
- if (!priv->tx_pending_len)
- netif_wake_queue(priv->dev);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
-static int lbs_ibss_join_existing(struct lbs_private *priv,
- struct cfg80211_ibss_params *params,
- struct cfg80211_bss *bss)
-{
- const u8 *rates_eid;
- struct cmd_ds_802_11_ad_hoc_join cmd;
- u8 preamble = RADIO_PREAMBLE_SHORT;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- /* TODO: set preamble based on scan result */
- ret = lbs_set_radio(priv, preamble, 1);
- if (ret)
- goto out;
-
- /*
- * Example CMD_802_11_AD_HOC_JOIN command:
- *
- * command 2c 00 CMD_802_11_AD_HOC_JOIN
- * size 65 00
- * sequence xx xx
- * result 00 00
- * bssid 02 27 27 97 2f 96
- * ssid 49 42 53 53 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * type 02 CMD_BSS_TYPE_IBSS
- * beacon period 64 00
- * dtim period 00
- * timestamp 00 00 00 00 00 00 00 00
- * localtime 00 00 00 00 00 00 00 00
- * IE DS 03
- * IE DS len 01
- * IE DS channel 01
- * reserveed 00 00 00 00
- * IE IBSS 06
- * IE IBSS len 02
- * IE IBSS atim 00 00
- * reserved 00 00 00 00
- * capability 02 00
- * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c 00
- * fail timeout ff 00
- * probe delay 00 00
- */
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
- memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN);
- memcpy(cmd.bss.ssid, params->ssid, params->ssid_len);
- cmd.bss.type = CMD_BSS_TYPE_IBSS;
- cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
- cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
- cmd.bss.ds.header.len = 1;
- cmd.bss.ds.channel = params->chandef.chan->hw_value;
- cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
- cmd.bss.ibss.header.len = 2;
- cmd.bss.ibss.atimwindow = 0;
- cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
-
- /* set rates to the intersection of our rates and the rates in the
- bss */
- rcu_read_lock();
- rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
- if (!rates_eid) {
- lbs_add_rates(cmd.bss.rates);
- } else {
- int hw, i;
- u8 rates_max = rates_eid[1];
- u8 *rates = cmd.bss.rates;
- for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
- u8 hw_rate = lbs_rates[hw].bitrate / 5;
- for (i = 0; i < rates_max; i++) {
- if (hw_rate == (rates_eid[i+2] & 0x7f)) {
- u8 rate = rates_eid[i+2];
- if (rate == 0x02 || rate == 0x04 ||
- rate == 0x0b || rate == 0x16)
- rate |= 0x80;
- *rates++ = rate;
- }
- }
- }
- }
- rcu_read_unlock();
-
- /* Only v8 and below support setting this */
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
- cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
- cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
- }
- ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
- if (ret)
- goto out;
-
- /*
- * This is a sample response to CMD_802_11_AD_HOC_JOIN:
- *
- * response 2c 80
- * size 09 00
- * sequence xx xx
- * result 00 00
- * reserved 00
- */
- lbs_join_post(priv, params, bss->bssid, bss->capability);
-
- out:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-
-static int lbs_ibss_start_new(struct lbs_private *priv,
- struct cfg80211_ibss_params *params)
-{
- struct cmd_ds_802_11_ad_hoc_start cmd;
- struct cmd_ds_802_11_ad_hoc_result *resp =
- (struct cmd_ds_802_11_ad_hoc_result *) &cmd;
- u8 preamble = RADIO_PREAMBLE_SHORT;
- int ret = 0;
- u16 capability;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- ret = lbs_set_radio(priv, preamble, 1);
- if (ret)
- goto out;
-
- /*
- * Example CMD_802_11_AD_HOC_START command:
- *
- * command 2b 00 CMD_802_11_AD_HOC_START
- * size b1 00
- * sequence xx xx
- * result 00 00
- * ssid 54 45 53 54 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * 00 00 00 00 00 00 00 00
- * bss type 02
- * beacon period 64 00
- * dtim period 00
- * IE IBSS 06
- * IE IBSS len 02
- * IE IBSS atim 00 00
- * reserved 00 00 00 00
- * IE DS 03
- * IE DS len 01
- * IE DS channel 01
- * reserved 00 00 00 00
- * probe delay 00 00
- * capability 02 00
- * rates 82 84 8b 96 (basic rates with have bit 7 set)
- * 0c 12 18 24 30 48 60 6c
- * padding 100 bytes
- */
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- memcpy(cmd.ssid, params->ssid, params->ssid_len);
- cmd.bsstype = CMD_BSS_TYPE_IBSS;
- cmd.beaconperiod = cpu_to_le16(params->beacon_interval);
- cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
- cmd.ibss.header.len = 2;
- cmd.ibss.atimwindow = 0;
- cmd.ds.header.id = WLAN_EID_DS_PARAMS;
- cmd.ds.header.len = 1;
- cmd.ds.channel = params->chandef.chan->hw_value;
- /* Only v8 and below support setting probe delay */
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
- cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
- /* TODO: mix in WLAN_CAPABILITY_PRIVACY */
- capability = WLAN_CAPABILITY_IBSS;
- cmd.capability = cpu_to_le16(capability);
- lbs_add_rates(cmd.rates);
-
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
- if (ret)
- goto out;
-
- /*
- * This is a sample response to CMD_802_11_AD_HOC_JOIN:
- *
- * response 2b 80
- * size 14 00
- * sequence xx xx
- * result 00 00
- * reserved 00
- * bssid 02 2b 7b 0f 86 0e
- */
- lbs_join_post(priv, params, resp->bssid, capability);
-
- out:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_ibss_params *params)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- int ret = 0;
- struct cfg80211_bss *bss;
-
- if (dev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (!params->chandef.chan) {
- ret = -ENOTSUPP;
- goto out;
- }
-
- ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
- if (ret)
- goto out;
-
- /* Search if someone is beaconing. This assumes that the
- * bss list is populated already */
- bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
- params->ssid, params->ssid_len,
- IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY);
-
- if (bss) {
- ret = lbs_ibss_join_existing(priv, params, bss);
- cfg80211_put_bss(wiphy, bss);
- } else
- ret = lbs_ibss_start_new(priv, params);
-
-
- out:
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
- struct cmd_ds_802_11_ad_hoc_stop cmd;
- int ret = 0;
-
- if (dev == priv->mesh_dev)
- return -EOPNOTSUPP;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
-
- /* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */
- lbs_mac_event_disconnected(priv, true);
-
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-
-
-
-/*
- * Initialization
- */
-
-static struct cfg80211_ops lbs_cfg80211_ops = {
- .set_monitor_channel = lbs_cfg_set_monitor_channel,
- .libertas_set_mesh_channel = lbs_cfg_set_mesh_channel,
- .scan = lbs_cfg_scan,
- .connect = lbs_cfg_connect,
- .disconnect = lbs_cfg_disconnect,
- .add_key = lbs_cfg_add_key,
- .del_key = lbs_cfg_del_key,
- .set_default_key = lbs_cfg_set_default_key,
- .get_station = lbs_cfg_get_station,
- .change_virtual_intf = lbs_change_intf,
- .join_ibss = lbs_join_ibss,
- .leave_ibss = lbs_leave_ibss,
-};
-
-
-/*
- * At this time lbs_private *priv doesn't even exist, so we just allocate
- * memory and don't initialize the wiphy further. This is postponed until we
- * can talk to the firmware and happens at registration time in
- * lbs_cfg_wiphy_register().
- */
-struct wireless_dev *lbs_cfg_alloc(struct device *dev)
-{
- int ret = 0;
- struct wireless_dev *wdev;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!wdev)
- return ERR_PTR(-ENOMEM);
-
- wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private));
- if (!wdev->wiphy) {
- dev_err(dev, "cannot allocate wiphy\n");
- ret = -ENOMEM;
- goto err_wiphy_new;
- }
-
- lbs_deb_leave(LBS_DEB_CFG80211);
- return wdev;
-
- err_wiphy_new:
- kfree(wdev);
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ERR_PTR(ret);
-}
-
-
-static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
-{
- struct region_code_mapping {
- const char *cn;
- int code;
- };
-
- /* Section 5.17.2 */
- static const struct region_code_mapping regmap[] = {
- {"US ", 0x10}, /* US FCC */
- {"CA ", 0x20}, /* Canada */
- {"EU ", 0x30}, /* ETSI */
- {"ES ", 0x31}, /* Spain */
- {"FR ", 0x32}, /* France */
- {"JP ", 0x40}, /* Japan */
- };
- size_t i;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- for (i = 0; i < ARRAY_SIZE(regmap); i++)
- if (regmap[i].code == priv->regioncode) {
- regulatory_hint(priv->wdev->wiphy, regmap[i].cn);
- break;
- }
-
- lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
-static void lbs_reg_notifier(struct wiphy *wiphy,
- struct regulatory_request *request)
-{
- struct lbs_private *priv = wiphy_priv(wiphy);
-
- lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
- "callback for domain %c%c\n", request->alpha2[0],
- request->alpha2[1]);
-
- memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
- if (lbs_iface_active(priv))
- lbs_set_11d_domain_info(priv);
-
- lbs_deb_leave(LBS_DEB_CFG80211);
-}
-
-/*
- * This function get's called after lbs_setup_firmware() determined the
- * firmware capabities. So we can setup the wiphy according to our
- * hardware/firmware.
- */
-int lbs_cfg_register(struct lbs_private *priv)
-{
- struct wireless_dev *wdev = priv->wdev;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- wdev->wiphy->max_scan_ssids = 1;
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
- wdev->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
- if (lbs_rtap_supported(priv))
- wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
- if (lbs_mesh_activated(priv))
- wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT);
-
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
-
- /*
- * We could check priv->fwcapinfo && FW_CAPINFO_WPA, but I have
- * never seen a firmware without WPA
- */
- wdev->wiphy->cipher_suites = cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
- wdev->wiphy->reg_notifier = lbs_reg_notifier;
-
- ret = wiphy_register(wdev->wiphy);
- if (ret < 0)
- pr_err("cannot register wiphy device\n");
-
- priv->wiphy_registered = true;
-
- ret = register_netdev(priv->dev);
- if (ret)
- pr_err("cannot register network device\n");
-
- INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
-
- lbs_cfg_set_regulatory_hint(priv);
-
- lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
- return ret;
-}
-
-void lbs_scan_deinit(struct lbs_private *priv)
-{
- lbs_deb_enter(LBS_DEB_CFG80211);
- cancel_delayed_work_sync(&priv->scan_work);
-}
-
-
-void lbs_cfg_free(struct lbs_private *priv)
-{
- struct wireless_dev *wdev = priv->wdev;
-
- lbs_deb_enter(LBS_DEB_CFG80211);
-
- if (!wdev)
- return;
-
- if (priv->wiphy_registered)
- wiphy_unregister(wdev->wiphy);
-
- if (wdev->wiphy)
- wiphy_free(wdev->wiphy);
-
- kfree(wdev);
-}
diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h
deleted file mode 100644
index acccc2922..000000000
--- a/drivers/net/wireless/libertas/cfg.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __LBS_CFG80211_H__
-#define __LBS_CFG80211_H__
-
-struct device;
-struct lbs_private;
-struct regulatory_request;
-struct wiphy;
-
-struct wireless_dev *lbs_cfg_alloc(struct device *dev);
-int lbs_cfg_register(struct lbs_private *priv);
-void lbs_cfg_free(struct lbs_private *priv);
-
-void lbs_send_disconnect_notification(struct lbs_private *priv,
- bool locally_generated);
-void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
-
-void lbs_scan_done(struct lbs_private *priv);
-void lbs_scan_deinit(struct lbs_private *priv);
-int lbs_disconnect(struct lbs_private *priv, u16 reason);
-
-#endif
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
deleted file mode 100644
index 0387a5b38..000000000
--- a/drivers/net/wireless/libertas/cmd.c
+++ /dev/null
@@ -1,1725 +0,0 @@
-/*
- * This file contains the handling of command.
- * It prepares command and sends it to firmware when it is ready.
- */
-
-#include <linux/hardirq.h>
-#include <linux/kfifo.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/if_arp.h>
-#include <linux/export.h>
-
-#include "decl.h"
-#include "cfg.h"
-#include "cmd.h"
-
-#define CAL_NF(nf) ((s32)(-(s32)(nf)))
-#define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
-
-/**
- * lbs_cmd_copyback - Simple callback that copies response back into command
- *
- * @priv: A pointer to &struct lbs_private structure
- * @extra: A pointer to the original command structure for which
- * 'resp' is a response
- * @resp: A pointer to the command response
- *
- * returns: 0 on success, error on failure
- */
-int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
- struct cmd_header *resp)
-{
- struct cmd_header *buf = (void *)extra;
- uint16_t copy_len;
-
- copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
- memcpy(buf, resp, copy_len);
- return 0;
-}
-EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
-
-/**
- * lbs_cmd_async_callback - Simple callback that ignores the result.
- * Use this if you just want to send a command to the hardware, but don't
- * care for the result.
- *
- * @priv: ignored
- * @extra: ignored
- * @resp: ignored
- *
- * returns: 0 for success
- */
-static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
- struct cmd_header *resp)
-{
- return 0;
-}
-
-
-/**
- * is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
- *
- * @cmd: the command ID
- *
- * returns: 1 if allowed, 0 if not allowed
- */
-static u8 is_command_allowed_in_ps(u16 cmd)
-{
- switch (cmd) {
- case CMD_802_11_RSSI:
- return 1;
- case CMD_802_11_HOST_SLEEP_CFG:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-/**
- * lbs_update_hw_spec - Updates the hardware details like MAC address
- * and regulatory region
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: 0 on success, error on failure
- */
-int lbs_update_hw_spec(struct lbs_private *priv)
-{
- struct cmd_ds_get_hw_spec cmd;
- int ret = -1;
- u32 i;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
- ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
- if (ret)
- goto out;
-
- priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
-
- /* The firmware release is in an interesting format: the patch
- * level is in the most significant nibble ... so fix that: */
- priv->fwrelease = le32_to_cpu(cmd.fwrelease);
- priv->fwrelease = (priv->fwrelease << 8) |
- (priv->fwrelease >> 24 & 0xff);
-
- /* Some firmware capabilities:
- * CF card firmware 5.0.16p0: cap 0x00000303
- * USB dongle firmware 5.110.17p2: cap 0x00000303
- */
- netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
- cmd.permanentaddr,
- priv->fwrelease >> 24 & 0xff,
- priv->fwrelease >> 16 & 0xff,
- priv->fwrelease >> 8 & 0xff,
- priv->fwrelease & 0xff,
- priv->fwcapinfo);
- lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
- cmd.hwifversion, cmd.version);
-
- /* Clamp region code to 8-bit since FW spec indicates that it should
- * only ever be 8-bit, even though the field size is 16-bit. Some firmware
- * returns non-zero high 8 bits here.
- *
- * Firmware version 4.0.102 used in CF8381 has region code shifted. We
- * need to check for this problem and handle it properly.
- */
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4)
- priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF;
- else
- priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
-
- for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
- /* use the region code to search for the index */
- if (priv->regioncode == lbs_region_code_to_index[i])
- break;
- }
-
- /* if it's unidentified region code, use the default (USA) */
- if (i >= MRVDRV_MAX_REGION_CODE) {
- priv->regioncode = 0x10;
- netdev_info(priv->dev,
- "unidentified region code; using the default (USA)\n");
- }
-
- if (priv->current_addr[0] == 0xff)
- memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
-
- if (!priv->copied_hwaddr) {
- memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
- if (priv->mesh_dev)
- memcpy(priv->mesh_dev->dev_addr,
- priv->current_addr, ETH_ALEN);
- priv->copied_hwaddr = 1;
- }
-
-out:
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
- struct cmd_header *resp)
-{
- lbs_deb_enter(LBS_DEB_CMD);
- if (priv->is_host_sleep_activated) {
- priv->is_host_sleep_configured = 0;
- if (priv->psstate == PS_STATE_FULL_POWER) {
- priv->is_host_sleep_activated = 0;
- wake_up_interruptible(&priv->host_sleep_q);
- }
- } else {
- priv->is_host_sleep_configured = 1;
- }
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
- struct wol_config *p_wol_config)
-{
- struct cmd_ds_host_sleep cmd_config;
- int ret;
-
- /*
- * Certain firmware versions do not support EHS_REMOVE_WAKEUP command
- * and the card will return a failure. Since we need to be
- * able to reset the mask, in those cases we set a 0 mask instead.
- */
- if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported)
- criteria = 0;
-
- cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
- cmd_config.criteria = cpu_to_le32(criteria);
- cmd_config.gpio = priv->wol_gpio;
- cmd_config.gap = priv->wol_gap;
-
- if (p_wol_config != NULL)
- memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
- sizeof(struct wol_config));
- else
- cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
-
- ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
- le16_to_cpu(cmd_config.hdr.size),
- lbs_ret_host_sleep_cfg, 0);
- if (!ret) {
- if (p_wol_config)
- memcpy((uint8_t *) p_wol_config,
- (uint8_t *)&cmd_config.wol_conf,
- sizeof(struct wol_config));
- } else {
- netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
-
-/**
- * lbs_set_ps_mode - Sets the Power Save mode
- *
- * @priv: A pointer to &struct lbs_private structure
- * @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or
- * PS_MODE_ACTION_EXIT_PS)
- * @block: Whether to block on a response or not
- *
- * returns: 0 on success, error on failure
- */
-int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
-{
- struct cmd_ds_802_11_ps_mode cmd;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(cmd_action);
-
- if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
- lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
- cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */
- } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
- lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
- } else {
- /* We don't handle CONFIRM_SLEEP here because it needs to
- * be fastpathed to the firmware.
- */
- lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- if (block)
- ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
- else
- lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
- struct sleep_params *sp)
-{
- struct cmd_ds_802_11_sleep_params cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- if (cmd_action == CMD_ACT_GET) {
- memset(&cmd, 0, sizeof(cmd));
- } else {
- cmd.error = cpu_to_le16(sp->sp_error);
- cmd.offset = cpu_to_le16(sp->sp_offset);
- cmd.stabletime = cpu_to_le16(sp->sp_stabletime);
- cmd.calcontrol = sp->sp_calcontrol;
- cmd.externalsleepclk = sp->sp_extsleepclk;
- cmd.reserved = cpu_to_le16(sp->sp_reserved);
- }
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(cmd_action);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SLEEP_PARAMS, &cmd);
-
- if (!ret) {
- lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, "
- "calcontrol 0x%x extsleepclk 0x%x\n",
- le16_to_cpu(cmd.error), le16_to_cpu(cmd.offset),
- le16_to_cpu(cmd.stabletime), cmd.calcontrol,
- cmd.externalsleepclk);
-
- sp->sp_error = le16_to_cpu(cmd.error);
- sp->sp_offset = le16_to_cpu(cmd.offset);
- sp->sp_stabletime = le16_to_cpu(cmd.stabletime);
- sp->sp_calcontrol = cmd.calcontrol;
- sp->sp_extsleepclk = cmd.externalsleepclk;
- sp->sp_reserved = le16_to_cpu(cmd.reserved);
- }
-
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return 0;
-}
-
-static int lbs_wait_for_ds_awake(struct lbs_private *priv)
-{
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- if (priv->is_deep_sleep) {
- if (!wait_event_interruptible_timeout(priv->ds_awake_q,
- !priv->is_deep_sleep, (10 * HZ))) {
- netdev_err(priv->dev, "ds_awake_q: timer expired\n");
- ret = -1;
- }
- }
-
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
-{
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- if (deep_sleep) {
- if (priv->is_deep_sleep != 1) {
- lbs_deb_cmd("deep sleep: sleep\n");
- BUG_ON(!priv->enter_deep_sleep);
- ret = priv->enter_deep_sleep(priv);
- if (!ret) {
- netif_stop_queue(priv->dev);
- netif_carrier_off(priv->dev);
- }
- } else {
- netdev_err(priv->dev, "deep sleep: already enabled\n");
- }
- } else {
- if (priv->is_deep_sleep) {
- lbs_deb_cmd("deep sleep: wakeup\n");
- BUG_ON(!priv->exit_deep_sleep);
- ret = priv->exit_deep_sleep(priv);
- if (!ret) {
- ret = lbs_wait_for_ds_awake(priv);
- if (ret)
- netdev_err(priv->dev,
- "deep sleep: wakeup failed\n");
- }
- }
- }
-
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
- unsigned long dummy,
- struct cmd_header *cmd)
-{
- lbs_deb_enter(LBS_DEB_FW);
- priv->is_host_sleep_activated = 1;
- wake_up_interruptible(&priv->host_sleep_q);
- lbs_deb_leave(LBS_DEB_FW);
- return 0;
-}
-
-int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
-{
- struct cmd_header cmd;
- int ret = 0;
- uint32_t criteria = EHS_REMOVE_WAKEUP;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- if (host_sleep) {
- if (priv->is_host_sleep_activated != 1) {
- memset(&cmd, 0, sizeof(cmd));
- ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
- (struct wol_config *)NULL);
- if (ret) {
- netdev_info(priv->dev,
- "Host sleep configuration failed: %d\n",
- ret);
- return ret;
- }
- if (priv->psstate == PS_STATE_FULL_POWER) {
- ret = __lbs_cmd(priv,
- CMD_802_11_HOST_SLEEP_ACTIVATE,
- &cmd,
- sizeof(cmd),
- lbs_ret_host_sleep_activate, 0);
- if (ret)
- netdev_info(priv->dev,
- "HOST_SLEEP_ACTIVATE failed: %d\n",
- ret);
- }
-
- if (!wait_event_interruptible_timeout(
- priv->host_sleep_q,
- priv->is_host_sleep_activated,
- (10 * HZ))) {
- netdev_err(priv->dev,
- "host_sleep_q: timer expired\n");
- ret = -1;
- }
- } else {
- netdev_err(priv->dev, "host sleep: already enabled\n");
- }
- } else {
- if (priv->is_host_sleep_activated)
- ret = lbs_host_sleep_cfg(priv, criteria,
- (struct wol_config *)NULL);
- }
-
- return ret;
-}
-
-/**
- * lbs_set_snmp_mib - Set an SNMP MIB value
- *
- * @priv: A pointer to &struct lbs_private structure
- * @oid: The OID to set in the firmware
- * @val: Value to set the OID to
- *
- * returns: 0 on success, error on failure
- */
-int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
-{
- struct cmd_ds_802_11_snmp_mib cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof (cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.oid = cpu_to_le16((u16) oid);
-
- switch (oid) {
- case SNMP_MIB_OID_BSS_TYPE:
- cmd.bufsize = cpu_to_le16(sizeof(u8));
- cmd.value[0] = val;
- break;
- case SNMP_MIB_OID_11D_ENABLE:
- case SNMP_MIB_OID_FRAG_THRESHOLD:
- case SNMP_MIB_OID_RTS_THRESHOLD:
- case SNMP_MIB_OID_SHORT_RETRY_LIMIT:
- case SNMP_MIB_OID_LONG_RETRY_LIMIT:
- cmd.bufsize = cpu_to_le16(sizeof(u16));
- *((__le16 *)(&cmd.value)) = cpu_to_le16(val);
- break;
- default:
- lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
- ret = -EINVAL;
- goto out;
- }
-
- lbs_deb_cmd("SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n",
- le16_to_cpu(cmd.oid), le16_to_cpu(cmd.bufsize), val);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_get_snmp_mib - Get an SNMP MIB value
- *
- * @priv: A pointer to &struct lbs_private structure
- * @oid: The OID to retrieve from the firmware
- * @out_val: Location for the returned value
- *
- * returns: 0 on success, error on failure
- */
-int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
-{
- struct cmd_ds_802_11_snmp_mib cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof (cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_GET);
- cmd.oid = cpu_to_le16(oid);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
- if (ret)
- goto out;
-
- switch (le16_to_cpu(cmd.bufsize)) {
- case sizeof(u8):
- *out_val = cmd.value[0];
- break;
- case sizeof(u16):
- *out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
- break;
- default:
- lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
- oid, le16_to_cpu(cmd.bufsize));
- break;
- }
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_get_tx_power - Get the min, max, and current TX power
- *
- * @priv: A pointer to &struct lbs_private structure
- * @curlevel: Current power level in dBm
- * @minlevel: Minimum supported power level in dBm (optional)
- * @maxlevel: Maximum supported power level in dBm (optional)
- *
- * returns: 0 on success, error on failure
- */
-int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
- s16 *maxlevel)
-{
- struct cmd_ds_802_11_rf_tx_power cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_GET);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
- if (ret == 0) {
- *curlevel = le16_to_cpu(cmd.curlevel);
- if (minlevel)
- *minlevel = cmd.minlevel;
- if (maxlevel)
- *maxlevel = cmd.maxlevel;
- }
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-/**
- * lbs_set_tx_power - Set the TX power
- *
- * @priv: A pointer to &struct lbs_private structure
- * @dbm: The desired power level in dBm
- *
- * returns: 0 on success, error on failure
- */
-int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
-{
- struct cmd_ds_802_11_rf_tx_power cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.curlevel = cpu_to_le16(dbm);
-
- lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-/**
- * lbs_set_monitor_mode - Enable or disable monitor mode
- * (only implemented on OLPC usb8388 FW)
- *
- * @priv: A pointer to &struct lbs_private structure
- * @enable: 1 to enable monitor mode, 0 to disable
- *
- * returns: 0 on success, error on failure
- */
-int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
-{
- struct cmd_ds_802_11_monitor_mode cmd;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- if (enable)
- cmd.mode = cpu_to_le16(0x1);
-
- lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
- if (ret == 0) {
- priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
- ARPHRD_ETHER;
- }
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-/**
- * lbs_get_channel - Get the radio channel
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: The channel on success, error on failure
- */
-static int lbs_get_channel(struct lbs_private *priv)
-{
- struct cmd_ds_802_11_rf_channel cmd;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
- if (ret)
- goto out;
-
- ret = le16_to_cpu(cmd.channel);
- lbs_deb_cmd("current radio channel is %d\n", ret);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-int lbs_update_channel(struct lbs_private *priv)
-{
- int ret;
-
- /* the channel in f/w could be out of sync; get the current channel */
- lbs_deb_enter(LBS_DEB_ASSOC);
-
- ret = lbs_get_channel(priv);
- if (ret > 0) {
- priv->channel = ret;
- ret = 0;
- }
- lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_set_channel - Set the radio channel
- *
- * @priv: A pointer to &struct lbs_private structure
- * @channel: The desired channel, or 0 to clear a locked channel
- *
- * returns: 0 on success, error on failure
- */
-int lbs_set_channel(struct lbs_private *priv, u8 channel)
-{
- struct cmd_ds_802_11_rf_channel cmd;
-#ifdef DEBUG
- u8 old_channel = priv->channel;
-#endif
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
- cmd.channel = cpu_to_le16(channel);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
- if (ret)
- goto out;
-
- priv->channel = (uint8_t) le16_to_cpu(cmd.channel);
- lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
- priv->channel);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_get_rssi - Get current RSSI and noise floor
- *
- * @priv: A pointer to &struct lbs_private structure
- * @rssi: On successful return, signal level in mBm
- * @nf: On successful return, Noise floor
- *
- * returns: The channel on success, error on failure
- */
-int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
-{
- struct cmd_ds_802_11_rssi cmd;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- BUG_ON(rssi == NULL);
- BUG_ON(nf == NULL);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- /* Average SNR over last 8 beacons */
- cmd.n_or_snr = cpu_to_le16(8);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
- if (ret == 0) {
- *nf = CAL_NF(le16_to_cpu(cmd.nf));
- *rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf));
- }
-
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
- * to the firmware
- *
- * @priv: pointer to &struct lbs_private
- *
- * returns: 0 on success, error code on failure
-*/
-int lbs_set_11d_domain_info(struct lbs_private *priv)
-{
- struct wiphy *wiphy = priv->wdev->wiphy;
- struct ieee80211_supported_band **bands = wiphy->bands;
- struct cmd_ds_802_11d_domain_info cmd;
- struct mrvl_ie_domain_param_set *domain = &cmd.domain;
- struct ieee80211_country_ie_triplet *t;
- enum ieee80211_band band;
- struct ieee80211_channel *ch;
- u8 num_triplet = 0;
- u8 num_parsed_chan = 0;
- u8 first_channel = 0, next_chan = 0, max_pwr = 0;
- u8 i, flag = 0;
- size_t triplet_size;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_11D);
- if (!priv->country_code[0])
- goto out;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
-
- lbs_deb_11d("Setting country code '%c%c'\n",
- priv->country_code[0], priv->country_code[1]);
-
- domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
-
- /* Set country code */
- domain->country_code[0] = priv->country_code[0];
- domain->country_code[1] = priv->country_code[1];
- domain->country_code[2] = ' ';
-
- /* Now set up the channel triplets; firmware is somewhat picky here
- * and doesn't validate channel numbers and spans; hence it would
- * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since
- * the last 3 aren't valid channels, the driver is responsible for
- * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
- * etc.
- */
- for (band = 0;
- (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
- band++) {
-
- if (!bands[band])
- continue;
-
- for (i = 0;
- (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
- i++) {
- ch = &bands[band]->channels[i];
- if (ch->flags & IEEE80211_CHAN_DISABLED)
- continue;
-
- if (!flag) {
- flag = 1;
- next_chan = first_channel = (u32) ch->hw_value;
- max_pwr = ch->max_power;
- num_parsed_chan = 1;
- continue;
- }
-
- if ((ch->hw_value == next_chan + 1) &&
- (ch->max_power == max_pwr)) {
- /* Consolidate adjacent channels */
- next_chan++;
- num_parsed_chan++;
- } else {
- /* Add this triplet */
- lbs_deb_11d("11D triplet (%d, %d, %d)\n",
- first_channel, num_parsed_chan,
- max_pwr);
- t = &domain->triplet[num_triplet];
- t->chans.first_channel = first_channel;
- t->chans.num_channels = num_parsed_chan;
- t->chans.max_power = max_pwr;
- num_triplet++;
- flag = 0;
- }
- }
-
- if (flag) {
- /* Add last triplet */
- lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
- num_parsed_chan, max_pwr);
- t = &domain->triplet[num_triplet];
- t->chans.first_channel = first_channel;
- t->chans.num_channels = num_parsed_chan;
- t->chans.max_power = max_pwr;
- num_triplet++;
- }
- }
-
- lbs_deb_11d("# triplets %d\n", num_triplet);
-
- /* Set command header sizes */
- triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
- domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
- triplet_size);
-
- lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
- (u8 *) &cmd.domain.country_code,
- le16_to_cpu(domain->header.len));
-
- cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
- sizeof(cmd.action) +
- sizeof(cmd.domain.header) +
- sizeof(cmd.domain.country_code) +
- triplet_size);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
-
-out:
- lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_get_reg - Read a MAC, Baseband, or RF register
- *
- * @priv: pointer to &struct lbs_private
- * @reg: register command, one of CMD_MAC_REG_ACCESS,
- * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
- * @offset: byte offset of the register to get
- * @value: on success, the value of the register at 'offset'
- *
- * returns: 0 on success, error code on failure
-*/
-int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
-{
- struct cmd_ds_reg_access cmd;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- BUG_ON(value == NULL);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_GET);
- cmd.offset = cpu_to_le16(offset);
-
- if (reg != CMD_MAC_REG_ACCESS &&
- reg != CMD_BBP_REG_ACCESS &&
- reg != CMD_RF_REG_ACCESS) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = lbs_cmd_with_response(priv, reg, &cmd);
- if (!ret) {
- if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
- *value = cmd.value.bbp_rf;
- else if (reg == CMD_MAC_REG_ACCESS)
- *value = le32_to_cpu(cmd.value.mac);
- }
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_set_reg - Write a MAC, Baseband, or RF register
- *
- * @priv: pointer to &struct lbs_private
- * @reg: register command, one of CMD_MAC_REG_ACCESS,
- * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
- * @offset: byte offset of the register to set
- * @value: the value to write to the register at 'offset'
- *
- * returns: 0 on success, error code on failure
-*/
-int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
-{
- struct cmd_ds_reg_access cmd;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.offset = cpu_to_le16(offset);
-
- if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
- cmd.value.bbp_rf = (u8) (value & 0xFF);
- else if (reg == CMD_MAC_REG_ACCESS)
- cmd.value.mac = cpu_to_le32(value);
- else {
- ret = -EINVAL;
- goto out;
- }
-
- ret = lbs_cmd_with_response(priv, reg, &cmd);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-static void lbs_queue_cmd(struct lbs_private *priv,
- struct cmd_ctrl_node *cmdnode)
-{
- unsigned long flags;
- int addtail = 1;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- if (!cmdnode) {
- lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
- goto done;
- }
- if (!cmdnode->cmdbuf->size) {
- lbs_deb_host("DNLD_CMD: cmd size is zero\n");
- goto done;
- }
- cmdnode->result = 0;
-
- /* Exit_PS command needs to be queued in the header always. */
- if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
- struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf;
-
- if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
- if (priv->psstate != PS_STATE_FULL_POWER)
- addtail = 0;
- }
- }
-
- if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
- addtail = 0;
-
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (addtail)
- list_add_tail(&cmdnode->list, &priv->cmdpendingq);
- else
- list_add(&cmdnode->list, &priv->cmdpendingq);
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
- le16_to_cpu(cmdnode->cmdbuf->command));
-
-done:
- lbs_deb_leave(LBS_DEB_HOST);
-}
-
-static void lbs_submit_command(struct lbs_private *priv,
- struct cmd_ctrl_node *cmdnode)
-{
- unsigned long flags;
- struct cmd_header *cmd;
- uint16_t cmdsize;
- uint16_t command;
- int timeo = 3 * HZ;
- int ret;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- cmd = cmdnode->cmdbuf;
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- priv->seqnum++;
- cmd->seqnum = cpu_to_le16(priv->seqnum);
- priv->cur_cmd = cmdnode;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- cmdsize = le16_to_cpu(cmd->size);
- command = le16_to_cpu(cmd->command);
-
- /* These commands take longer */
- if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
- timeo = 5 * HZ;
-
- lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
- command, le16_to_cpu(cmd->seqnum), cmdsize);
- lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
-
- ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
-
- if (ret) {
- netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n",
- ret);
- /* Reset dnld state machine, report failure */
- priv->dnld_sent = DNLD_RES_RECEIVED;
- lbs_complete_command(priv, cmdnode, ret);
- }
-
- if (command == CMD_802_11_DEEP_SLEEP) {
- if (priv->is_auto_deep_sleep_enabled) {
- priv->wakeup_dev_required = 1;
- priv->dnld_sent = 0;
- }
- priv->is_deep_sleep = 1;
- lbs_complete_command(priv, cmdnode, 0);
- } else {
- /* Setup the timer after transmit command */
- mod_timer(&priv->command_timer, jiffies + timeo);
- }
-
- lbs_deb_leave(LBS_DEB_HOST);
-}
-
-/*
- * This function inserts command node to cmdfreeq
- * after cleans it. Requires priv->driver_lock held.
- */
-static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
- struct cmd_ctrl_node *cmdnode)
-{
- lbs_deb_enter(LBS_DEB_HOST);
-
- if (!cmdnode)
- goto out;
-
- cmdnode->callback = NULL;
- cmdnode->callback_arg = 0;
-
- memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
-
- list_add_tail(&cmdnode->list, &priv->cmdfreeq);
- out:
- lbs_deb_leave(LBS_DEB_HOST);
-}
-
-static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
- struct cmd_ctrl_node *ptempcmd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-}
-
-void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
- int result)
-{
- /*
- * Normally, commands are removed from cmdpendingq before being
- * submitted. However, we can arrive here on alternative codepaths
- * where the command is still pending. Make sure the command really
- * isn't part of a list at this point.
- */
- list_del_init(&cmd->list);
-
- cmd->result = result;
- cmd->cmdwaitqwoken = 1;
- wake_up(&cmd->cmdwait_q);
-
- if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
- __lbs_cleanup_and_insert_cmd(priv, cmd);
- priv->cur_cmd = NULL;
- wake_up(&priv->waitq);
-}
-
-void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
- int result)
-{
- unsigned long flags;
- spin_lock_irqsave(&priv->driver_lock, flags);
- __lbs_complete_command(priv, cmd, result);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-}
-
-int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
-{
- struct cmd_ds_802_11_radio_control cmd;
- int ret = -EINVAL;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.control = 0;
-
- /* Only v8 and below support setting the preamble */
- if (priv->fwrelease < 0x09000000) {
- switch (preamble) {
- case RADIO_PREAMBLE_SHORT:
- case RADIO_PREAMBLE_AUTO:
- case RADIO_PREAMBLE_LONG:
- cmd.control = cpu_to_le16(preamble);
- break;
- default:
- goto out;
- }
- }
-
- if (radio_on)
- cmd.control |= cpu_to_le16(0x1);
- else {
- cmd.control &= cpu_to_le16(~0x1);
- priv->txpower_cur = 0;
- }
-
- lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
- radio_on ? "ON" : "OFF", preamble);
-
- priv->radio_on = radio_on;
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
-
-void lbs_set_mac_control(struct lbs_private *priv)
-{
- struct cmd_ds_mac_control cmd;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(priv->mac_control);
- cmd.reserved = 0;
-
- lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
-
- lbs_deb_leave(LBS_DEB_CMD);
-}
-
-int lbs_set_mac_control_sync(struct lbs_private *priv)
-{
- struct cmd_ds_mac_control cmd;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(priv->mac_control);
- cmd.reserved = 0;
- ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-/**
- * lbs_allocate_cmd_buffer - allocates the command buffer and links
- * it to command free queue
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: 0 for success or -1 on error
- */
-int lbs_allocate_cmd_buffer(struct lbs_private *priv)
-{
- int ret = 0;
- u32 bufsize;
- u32 i;
- struct cmd_ctrl_node *cmdarray;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- /* Allocate and initialize the command array */
- bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
- if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
- lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
- ret = -1;
- goto done;
- }
- priv->cmd_array = cmdarray;
-
- /* Allocate and initialize each command buffer in the command array */
- for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
- cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
- if (!cmdarray[i].cmdbuf) {
- lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
- ret = -1;
- goto done;
- }
- }
-
- for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
- init_waitqueue_head(&cmdarray[i].cmdwait_q);
- lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
- }
- ret = 0;
-
-done:
- lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_free_cmd_buffer - free the command buffer
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: 0 for success
- */
-int lbs_free_cmd_buffer(struct lbs_private *priv)
-{
- struct cmd_ctrl_node *cmdarray;
- unsigned int i;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- /* need to check if cmd array is allocated or not */
- if (priv->cmd_array == NULL) {
- lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
- goto done;
- }
-
- cmdarray = priv->cmd_array;
-
- /* Release shared memory buffers */
- for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
- if (cmdarray[i].cmdbuf) {
- kfree(cmdarray[i].cmdbuf);
- cmdarray[i].cmdbuf = NULL;
- }
- }
-
- /* Release cmd_ctrl_node */
- if (priv->cmd_array) {
- kfree(priv->cmd_array);
- priv->cmd_array = NULL;
- }
-
-done:
- lbs_deb_leave(LBS_DEB_HOST);
- return 0;
-}
-
-/**
- * lbs_get_free_cmd_node - gets a free command node if available in
- * command free queue
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: A pointer to &cmd_ctrl_node structure on success
- * or %NULL on error
- */
-static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
-{
- struct cmd_ctrl_node *tempnode;
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- if (!priv)
- return NULL;
-
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (!list_empty(&priv->cmdfreeq)) {
- tempnode = list_first_entry(&priv->cmdfreeq,
- struct cmd_ctrl_node, list);
- list_del_init(&tempnode->list);
- } else {
- lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
- tempnode = NULL;
- }
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- lbs_deb_leave(LBS_DEB_HOST);
- return tempnode;
-}
-
-/**
- * lbs_execute_next_command - execute next command in command
- * pending queue. Will put firmware back to PS mode if applicable.
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: 0 on success or -1 on error
- */
-int lbs_execute_next_command(struct lbs_private *priv)
-{
- struct cmd_ctrl_node *cmdnode = NULL;
- struct cmd_header *cmd;
- unsigned long flags;
- int ret = 0;
-
- /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
- * only caller to us is lbs_thread() and we get even when a
- * data packet is received */
- lbs_deb_enter(LBS_DEB_THREAD);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (priv->cur_cmd) {
- netdev_alert(priv->dev,
- "EXEC_NEXT_CMD: already processing command!\n");
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- ret = -1;
- goto done;
- }
-
- if (!list_empty(&priv->cmdpendingq)) {
- cmdnode = list_first_entry(&priv->cmdpendingq,
- struct cmd_ctrl_node, list);
- }
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- if (cmdnode) {
- cmd = cmdnode->cmdbuf;
-
- if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
- if ((priv->psstate == PS_STATE_SLEEP) ||
- (priv->psstate == PS_STATE_PRE_SLEEP)) {
- lbs_deb_host(
- "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
- le16_to_cpu(cmd->command),
- priv->psstate);
- ret = -1;
- goto done;
- }
- lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
- "0x%04x in psstate %d\n",
- le16_to_cpu(cmd->command), priv->psstate);
- } else if (priv->psstate != PS_STATE_FULL_POWER) {
- /*
- * 1. Non-PS command:
- * Queue it. set needtowakeup to TRUE if current state
- * is SLEEP, otherwise call send EXIT_PS.
- * 2. PS command but not EXIT_PS:
- * Ignore it.
- * 3. PS command EXIT_PS:
- * Set needtowakeup to TRUE if current state is SLEEP,
- * otherwise send this command down to firmware
- * immediately.
- */
- if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
- /* Prepare to send Exit PS,
- * this non PS command will be sent later */
- if ((priv->psstate == PS_STATE_SLEEP)
- || (priv->psstate == PS_STATE_PRE_SLEEP)
- ) {
- /* w/ new scheme, it will not reach here.
- since it is blocked in main_thread. */
- priv->needtowakeup = 1;
- } else {
- lbs_set_ps_mode(priv,
- PS_MODE_ACTION_EXIT_PS,
- false);
- }
-
- ret = 0;
- goto done;
- } else {
- /*
- * PS command. Ignore it if it is not Exit_PS.
- * otherwise send it down immediately.
- */
- struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
-
- lbs_deb_host(
- "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
- psm->action);
- if (psm->action !=
- cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
- lbs_deb_host(
- "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
- lbs_complete_command(priv, cmdnode, 0);
-
- ret = 0;
- goto done;
- }
-
- if ((priv->psstate == PS_STATE_SLEEP) ||
- (priv->psstate == PS_STATE_PRE_SLEEP)) {
- lbs_deb_host(
- "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
- lbs_complete_command(priv, cmdnode, 0);
- priv->needtowakeup = 1;
-
- ret = 0;
- goto done;
- }
-
- lbs_deb_host(
- "EXEC_NEXT_CMD: sending EXIT_PS\n");
- }
- }
- spin_lock_irqsave(&priv->driver_lock, flags);
- list_del_init(&cmdnode->list);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
- le16_to_cpu(cmd->command));
- lbs_submit_command(priv, cmdnode);
- } else {
- /*
- * check if in power save mode, if yes, put the device back
- * to PS mode
- */
-#ifdef TODO
- /*
- * This was the old code for libertas+wext. Someone that
- * understands this beast should re-code it in a sane way.
- *
- * I actually don't understand why this is related to WPA
- * and to connection status, shouldn't powering should be
- * independ of such things?
- */
- if ((priv->psmode != LBS802_11POWERMODECAM) &&
- (priv->psstate == PS_STATE_FULL_POWER) &&
- ((priv->connect_status == LBS_CONNECTED) ||
- lbs_mesh_connected(priv))) {
- if (priv->secinfo.WPAenabled ||
- priv->secinfo.WPA2enabled) {
- /* check for valid WPA group keys */
- if (priv->wpa_mcast_key.len ||
- priv->wpa_unicast_key.len) {
- lbs_deb_host(
- "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
- " go back to PS_SLEEP");
- lbs_set_ps_mode(priv,
- PS_MODE_ACTION_ENTER_PS,
- false);
- }
- } else {
- lbs_deb_host(
- "EXEC_NEXT_CMD: cmdpendingq empty, "
- "go back to PS_SLEEP");
- lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
- false);
- }
- }
-#endif
- }
-
- ret = 0;
-done:
- lbs_deb_leave(LBS_DEB_THREAD);
- return ret;
-}
-
-static void lbs_send_confirmsleep(struct lbs_private *priv)
-{
- unsigned long flags;
- int ret;
-
- lbs_deb_enter(LBS_DEB_HOST);
- lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep,
- sizeof(confirm_sleep));
-
- ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
- sizeof(confirm_sleep));
- if (ret) {
- netdev_alert(priv->dev, "confirm_sleep failed\n");
- goto out;
- }
-
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- /* We don't get a response on the sleep-confirmation */
- priv->dnld_sent = DNLD_RES_RECEIVED;
-
- if (priv->is_host_sleep_configured) {
- priv->is_host_sleep_activated = 1;
- wake_up_interruptible(&priv->host_sleep_q);
- }
-
- /* If nothing to do, go back to sleep (?) */
- if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
- priv->psstate = PS_STATE_SLEEP;
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-out:
- lbs_deb_leave(LBS_DEB_HOST);
-}
-
-/**
- * lbs_ps_confirm_sleep - checks condition and prepares to
- * send sleep confirm command to firmware if ok
- *
- * @priv: A pointer to &struct lbs_private structure
- *
- * returns: n/a
- */
-void lbs_ps_confirm_sleep(struct lbs_private *priv)
-{
- unsigned long flags =0;
- int allowed = 1;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- if (priv->dnld_sent) {
- allowed = 0;
- lbs_deb_host("dnld_sent was set\n");
- }
-
- /* In-progress command? */
- if (priv->cur_cmd) {
- allowed = 0;
- lbs_deb_host("cur_cmd was set\n");
- }
-
- /* Pending events or command responses? */
- if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
- allowed = 0;
- lbs_deb_host("pending events or command responses\n");
- }
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- if (allowed) {
- lbs_deb_host("sending lbs_ps_confirm_sleep\n");
- lbs_send_confirmsleep(priv);
- } else {
- lbs_deb_host("sleep confirm has been delayed\n");
- }
-
- lbs_deb_leave(LBS_DEB_HOST);
-}
-
-
-/**
- * lbs_set_tpc_cfg - Configures the transmission power control functionality
- *
- * @priv: A pointer to &struct lbs_private structure
- * @enable: Transmission power control enable
- * @p0: Power level when link quality is good (dBm).
- * @p1: Power level when link quality is fair (dBm).
- * @p2: Power level when link quality is poor (dBm).
- * @usesnr: Use Signal to Noise Ratio in TPC
- *
- * returns: 0 on success
- */
-int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
- int8_t p2, int usesnr)
-{
- struct cmd_ds_802_11_tpc_cfg cmd;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.enable = !!enable;
- cmd.usesnr = !!usesnr;
- cmd.P0 = p0;
- cmd.P1 = p1;
- cmd.P2 = p2;
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
-
- return ret;
-}
-
-/**
- * lbs_set_power_adapt_cfg - Configures the power adaptation settings
- *
- * @priv: A pointer to &struct lbs_private structure
- * @enable: Power adaptation enable
- * @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm).
- * @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
- * @p2: Power level for 48 and 54 Mbps (dBm).
- *
- * returns: 0 on Success
- */
-
-int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
- int8_t p1, int8_t p2)
-{
- struct cmd_ds_802_11_pa_cfg cmd;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- cmd.enable = !!enable;
- cmd.P0 = p0;
- cmd.P1 = p1;
- cmd.P2 = p2;
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
-
- return ret;
-}
-
-
-struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
- uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
- int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
- unsigned long callback_arg)
-{
- struct cmd_ctrl_node *cmdnode;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- if (priv->surpriseremoved) {
- lbs_deb_host("PREP_CMD: card removed\n");
- cmdnode = ERR_PTR(-ENOENT);
- goto done;
- }
-
- /* No commands are allowed in Deep Sleep until we toggle the GPIO
- * to wake up the card and it has signaled that it's ready.
- */
- if (!priv->is_auto_deep_sleep_enabled) {
- if (priv->is_deep_sleep) {
- lbs_deb_cmd("command not allowed in deep sleep\n");
- cmdnode = ERR_PTR(-EBUSY);
- goto done;
- }
- }
-
- cmdnode = lbs_get_free_cmd_node(priv);
- if (cmdnode == NULL) {
- lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
-
- /* Wake up main thread to execute next command */
- wake_up(&priv->waitq);
- cmdnode = ERR_PTR(-ENOBUFS);
- goto done;
- }
-
- cmdnode->callback = callback;
- cmdnode->callback_arg = callback_arg;
-
- /* Copy the incoming command to the buffer */
- memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
-
- /* Set command, clean result, move to buffer */
- cmdnode->cmdbuf->command = cpu_to_le16(command);
- cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size);
- cmdnode->cmdbuf->result = 0;
-
- lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
-
- cmdnode->cmdwaitqwoken = 0;
- lbs_queue_cmd(priv, cmdnode);
- wake_up(&priv->waitq);
-
- done:
- lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
- return cmdnode;
-}
-
-void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
- struct cmd_header *in_cmd, int in_cmd_size)
-{
- lbs_deb_enter(LBS_DEB_CMD);
- __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
- lbs_cmd_async_callback, 0);
- lbs_deb_leave(LBS_DEB_CMD);
-}
-
-int __lbs_cmd(struct lbs_private *priv, uint16_t command,
- struct cmd_header *in_cmd, int in_cmd_size,
- int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
- unsigned long callback_arg)
-{
- struct cmd_ctrl_node *cmdnode;
- unsigned long flags;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
- callback, callback_arg);
- if (IS_ERR(cmdnode)) {
- ret = PTR_ERR(cmdnode);
- goto done;
- }
-
- might_sleep();
-
- /*
- * Be careful with signals here. A signal may be received as the system
- * goes into suspend or resume. We do not want this to interrupt the
- * command, so we perform an uninterruptible sleep.
- */
- wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- ret = cmdnode->result;
- if (ret)
- netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
- command, ret);
-
- __lbs_cleanup_and_insert_cmd(priv, cmdnode);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-done:
- lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(__lbs_cmd);
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
deleted file mode 100644
index 0c5444b02..000000000
--- a/drivers/net/wireless/libertas/cmd.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright (C) 2007, Red Hat, Inc. */
-
-#ifndef _LBS_CMD_H_
-#define _LBS_CMD_H_
-
-#include <net/cfg80211.h>
-
-#include "host.h"
-#include "dev.h"
-
-
-/* Command & response transfer between host and card */
-
-struct cmd_ctrl_node {
- struct list_head list;
- int result;
- /* command response */
- int (*callback)(struct lbs_private *,
- unsigned long,
- struct cmd_header *);
- unsigned long callback_arg;
- /* command data */
- struct cmd_header *cmdbuf;
- /* wait queue */
- u16 cmdwaitqwoken;
- wait_queue_head_t cmdwait_q;
-};
-
-
-/* lbs_cmd() infers the size of the buffer to copy data back into, from
- the size of the target of the pointer. Since the command to be sent
- may often be smaller, that size is set in cmd->size by the caller.*/
-#define lbs_cmd(priv, cmdnr, cmd, cb, cb_arg) ({ \
- uint16_t __sz = le16_to_cpu((cmd)->hdr.size); \
- (cmd)->hdr.size = cpu_to_le16(sizeof(*(cmd))); \
- __lbs_cmd(priv, cmdnr, &(cmd)->hdr, __sz, cb, cb_arg); \
-})
-
-#define lbs_cmd_with_response(priv, cmdnr, cmd) \
- lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
-
-void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
- struct cmd_header *in_cmd, int in_cmd_size);
-
-int __lbs_cmd(struct lbs_private *priv, uint16_t command,
- struct cmd_header *in_cmd, int in_cmd_size,
- int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
- unsigned long callback_arg);
-
-struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
- uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
- int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
- unsigned long callback_arg);
-
-int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
- struct cmd_header *resp);
-
-int lbs_allocate_cmd_buffer(struct lbs_private *priv);
-int lbs_free_cmd_buffer(struct lbs_private *priv);
-
-int lbs_execute_next_command(struct lbs_private *priv);
-void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
- int result);
-void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
- int result);
-int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);
-
-
-/* From cmdresp.c */
-
-void lbs_mac_event_disconnected(struct lbs_private *priv,
- bool locally_generated);
-
-
-
-/* Events */
-
-int lbs_process_event(struct lbs_private *priv, u32 event);
-
-
-/* Actual commands */
-
-int lbs_update_hw_spec(struct lbs_private *priv);
-
-int lbs_set_channel(struct lbs_private *priv, u8 channel);
-
-int lbs_update_channel(struct lbs_private *priv);
-
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
- struct wol_config *p_wol_config);
-
-int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
- struct sleep_params *sp);
-
-void lbs_ps_confirm_sleep(struct lbs_private *priv);
-
-int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
-
-void lbs_set_mac_control(struct lbs_private *priv);
-int lbs_set_mac_control_sync(struct lbs_private *priv);
-
-int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
- s16 *maxlevel);
-
-int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val);
-
-int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val);
-
-
-/* Commands only used in wext.c, assoc. and scan.c */
-
-int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
- int8_t p1, int8_t p2);
-
-int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
- int8_t p2, int usesnr);
-
-int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
-
-int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
- uint16_t cmd_action);
-
-int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);
-
-int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
-
-int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep);
-
-int lbs_set_monitor_mode(struct lbs_private *priv, int enable);
-
-int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf);
-
-int lbs_set_11d_domain_info(struct lbs_private *priv);
-
-int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value);
-
-int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value);
-
-int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block);
-
-#endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
deleted file mode 100644
index e5442e895..000000000
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * This file contains the handling of command
- * responses as well as events generated by firmware.
- */
-
-#include <linux/hardirq.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <asm/unaligned.h>
-#include <net/cfg80211.h>
-
-#include "cfg.h"
-#include "cmd.h"
-
-/**
- * lbs_mac_event_disconnected - handles disconnect event. It
- * reports disconnect to upper layer, clean tx/rx packets,
- * reset link state etc.
- *
- * @priv: A pointer to struct lbs_private structure
- * @locally_generated: indicates disconnect was requested locally
- * (usually by userspace)
- *
- * returns: n/a
- */
-void lbs_mac_event_disconnected(struct lbs_private *priv,
- bool locally_generated)
-{
- if (priv->connect_status != LBS_CONNECTED)
- return;
-
- lbs_deb_enter(LBS_DEB_ASSOC);
-
- /*
- * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
- * It causes problem in the Supplicant
- */
- msleep_interruptible(1000);
-
- if (priv->wdev->iftype == NL80211_IFTYPE_STATION)
- lbs_send_disconnect_notification(priv, locally_generated);
-
- /* report disconnect to upper layer */
- netif_stop_queue(priv->dev);
- netif_carrier_off(priv->dev);
-
- /* Free Tx and Rx packets */
- kfree_skb(priv->currenttxskb);
- priv->currenttxskb = NULL;
- priv->tx_pending_len = 0;
-
- priv->connect_status = LBS_DISCONNECTED;
-
- if (priv->psstate != PS_STATE_FULL_POWER) {
- /* make firmware to exit PS mode */
- lbs_deb_cmd("disconnected, so exit PS mode\n");
- lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
- }
- lbs_deb_leave(LBS_DEB_ASSOC);
-}
-
-int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
-{
- uint16_t respcmd, curcmd;
- struct cmd_header *resp;
- int ret = 0;
- unsigned long flags;
- uint16_t result;
-
- lbs_deb_enter(LBS_DEB_HOST);
-
- mutex_lock(&priv->lock);
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (!priv->cur_cmd) {
- lbs_deb_host("CMD_RESP: cur_cmd is NULL\n");
- ret = -1;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- goto done;
- }
-
- resp = (void *)data;
- curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command);
- respcmd = le16_to_cpu(resp->command);
- result = le16_to_cpu(resp->result);
-
- lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d\n",
- respcmd, le16_to_cpu(resp->seqnum), len);
- lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);
-
- if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
- netdev_info(priv->dev,
- "Received CMD_RESP with invalid sequence %d (expected %d)\n",
- le16_to_cpu(resp->seqnum),
- le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- ret = -1;
- goto done;
- }
- if (respcmd != CMD_RET(curcmd) &&
- respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
- netdev_info(priv->dev, "Invalid CMD_RESP %x to command %x!\n",
- respcmd, curcmd);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- ret = -1;
- goto done;
- }
-
- if (resp->result == cpu_to_le16(0x0004)) {
- /* 0x0004 means -EAGAIN. Drop the response, let it time out
- and be resubmitted */
- netdev_info(priv->dev,
- "Firmware returns DEFER to command %x. Will let it time out...\n",
- le16_to_cpu(resp->command));
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- ret = -1;
- goto done;
- }
-
- /* Now we got response from FW, cancel the command timer */
- del_timer(&priv->command_timer);
- priv->cmd_timed_out = 0;
-
- if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
- struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
- u16 action = le16_to_cpu(psmode->action);
-
- lbs_deb_host(
- "CMD_RESP: PS_MODE cmd reply result 0x%x, action 0x%x\n",
- result, action);
-
- if (result) {
- lbs_deb_host("CMD_RESP: PS command failed with 0x%x\n",
- result);
- /*
- * We should not re-try enter-ps command in
- * ad-hoc mode. It takes place in
- * lbs_execute_next_command().
- */
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
- action == PS_MODE_ACTION_ENTER_PS)
- priv->psmode = LBS802_11POWERMODECAM;
- } else if (action == PS_MODE_ACTION_ENTER_PS) {
- priv->needtowakeup = 0;
- priv->psstate = PS_STATE_AWAKE;
-
- lbs_deb_host("CMD_RESP: ENTER_PS command response\n");
- if (priv->connect_status != LBS_CONNECTED) {
- /*
- * When Deauth Event received before Enter_PS command
- * response, We need to wake up the firmware.
- */
- lbs_deb_host(
- "disconnected, invoking lbs_ps_wakeup\n");
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- mutex_unlock(&priv->lock);
- lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS,
- false);
- mutex_lock(&priv->lock);
- spin_lock_irqsave(&priv->driver_lock, flags);
- }
- } else if (action == PS_MODE_ACTION_EXIT_PS) {
- priv->needtowakeup = 0;
- priv->psstate = PS_STATE_FULL_POWER;
- lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
- } else {
- lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
- }
-
- __lbs_complete_command(priv, priv->cur_cmd, result);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- ret = 0;
- goto done;
- }
-
- /* If the command is not successful, cleanup and return failure */
- if ((result != 0 || !(respcmd & 0x8000))) {
- lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
- result, respcmd);
- /*
- * Handling errors here
- */
- switch (respcmd) {
- case CMD_RET(CMD_GET_HW_SPEC):
- case CMD_RET(CMD_802_11_RESET):
- lbs_deb_host("CMD_RESP: reset failed\n");
- break;
-
- }
- __lbs_complete_command(priv, priv->cur_cmd, result);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- ret = -1;
- goto done;
- }
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- if (priv->cur_cmd && priv->cur_cmd->callback) {
- ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
- resp);
- }
-
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (priv->cur_cmd) {
- /* Clean up and Put current command back to cmdfreeq */
- __lbs_complete_command(priv, priv->cur_cmd, result);
- }
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-done:
- mutex_unlock(&priv->lock);
- lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
- return ret;
-}
-
-int lbs_process_event(struct lbs_private *priv, u32 event)
-{
- int ret = 0;
- struct cmd_header cmd;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- switch (event) {
- case MACREG_INT_CODE_LINK_SENSED:
- lbs_deb_cmd("EVENT: link sensed\n");
- break;
-
- case MACREG_INT_CODE_DEAUTHENTICATED:
- lbs_deb_cmd("EVENT: deauthenticated\n");
- lbs_mac_event_disconnected(priv, false);
- break;
-
- case MACREG_INT_CODE_DISASSOCIATED:
- lbs_deb_cmd("EVENT: disassociated\n");
- lbs_mac_event_disconnected(priv, false);
- break;
-
- case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
- lbs_deb_cmd("EVENT: link lost\n");
- lbs_mac_event_disconnected(priv, true);
- break;
-
- case MACREG_INT_CODE_PS_SLEEP:
- lbs_deb_cmd("EVENT: ps sleep\n");
-
- /* handle unexpected PS SLEEP event */
- if (priv->psstate == PS_STATE_FULL_POWER) {
- lbs_deb_cmd(
- "EVENT: in FULL POWER mode, ignoring PS_SLEEP\n");
- break;
- }
- priv->psstate = PS_STATE_PRE_SLEEP;
-
- lbs_ps_confirm_sleep(priv);
-
- break;
-
- case MACREG_INT_CODE_HOST_AWAKE:
- lbs_deb_cmd("EVENT: host awake\n");
- if (priv->reset_deep_sleep_wakeup)
- priv->reset_deep_sleep_wakeup(priv);
- priv->is_deep_sleep = 0;
- lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
- sizeof(cmd));
- priv->is_host_sleep_activated = 0;
- wake_up_interruptible(&priv->host_sleep_q);
- break;
-
- case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
- if (priv->reset_deep_sleep_wakeup)
- priv->reset_deep_sleep_wakeup(priv);
- lbs_deb_cmd("EVENT: ds awake\n");
- priv->is_deep_sleep = 0;
- priv->wakeup_dev_required = 0;
- wake_up_interruptible(&priv->ds_awake_q);
- break;
-
- case MACREG_INT_CODE_PS_AWAKE:
- lbs_deb_cmd("EVENT: ps awake\n");
- /* handle unexpected PS AWAKE event */
- if (priv->psstate == PS_STATE_FULL_POWER) {
- lbs_deb_cmd(
- "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
- break;
- }
-
- priv->psstate = PS_STATE_AWAKE;
-
- if (priv->needtowakeup) {
- /*
- * wait for the command processing to finish
- * before resuming sending
- * priv->needtowakeup will be set to FALSE
- * in lbs_ps_wakeup()
- */
- lbs_deb_cmd("waking up ...\n");
- lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
- }
- break;
-
- case MACREG_INT_CODE_MIC_ERR_UNICAST:
- lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
- lbs_send_mic_failureevent(priv, event);
- break;
-
- case MACREG_INT_CODE_MIC_ERR_MULTICAST:
- lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
- lbs_send_mic_failureevent(priv, event);
- break;
-
- case MACREG_INT_CODE_MIB_CHANGED:
- lbs_deb_cmd("EVENT: MIB CHANGED\n");
- break;
- case MACREG_INT_CODE_INIT_DONE:
- lbs_deb_cmd("EVENT: INIT DONE\n");
- break;
- case MACREG_INT_CODE_ADHOC_BCN_LOST:
- lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
- break;
- case MACREG_INT_CODE_RSSI_LOW:
- netdev_alert(priv->dev, "EVENT: rssi low\n");
- break;
- case MACREG_INT_CODE_SNR_LOW:
- netdev_alert(priv->dev, "EVENT: snr low\n");
- break;
- case MACREG_INT_CODE_MAX_FAIL:
- netdev_alert(priv->dev, "EVENT: max fail\n");
- break;
- case MACREG_INT_CODE_RSSI_HIGH:
- netdev_alert(priv->dev, "EVENT: rssi high\n");
- break;
- case MACREG_INT_CODE_SNR_HIGH:
- netdev_alert(priv->dev, "EVENT: snr high\n");
- break;
-
- case MACREG_INT_CODE_MESH_AUTO_STARTED:
- /* Ignore spurious autostart events */
- netdev_info(priv->dev, "EVENT: MESH_AUTO_STARTED (ignoring)\n");
- break;
-
- default:
- netdev_alert(priv->dev, "EVENT: unknown event id %d\n", event);
- break;
- }
-
- lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
- return ret;
-}
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
deleted file mode 100644
index 26cbf1dcc..000000000
--- a/drivers/net/wireless/libertas/debugfs.c
+++ /dev/null
@@ -1,989 +0,0 @@
-#include <linux/dcache.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/hardirq.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-
-#include "decl.h"
-#include "cmd.h"
-#include "debugfs.h"
-
-static struct dentry *lbs_dir;
-static char *szStates[] = {
- "Connected",
- "Disconnected"
-};
-
-#ifdef PROC_DEBUG
-static void lbs_debug_init(struct lbs_private *priv);
-#endif
-
-static ssize_t write_file_dummy(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- return -EINVAL;
-}
-
-static const size_t len = PAGE_SIZE;
-
-static ssize_t lbs_dev_info(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- size_t pos = 0;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- ssize_t res;
- if (!buf)
- return -ENOMEM;
-
- pos += snprintf(buf+pos, len-pos, "state = %s\n",
- szStates[priv->connect_status]);
- pos += snprintf(buf+pos, len-pos, "region_code = %02x\n",
- (u32) priv->regioncode);
-
- res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-
- free_page(addr);
- return res;
-}
-
-static ssize_t lbs_sleepparams_write(struct file *file,
- const char __user *user_buf, size_t count,
- loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t buf_size, ret;
- struct sleep_params sp;
- int p1, p2, p3, p4, p5, p6;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, user_buf, buf_size)) {
- ret = -EFAULT;
- goto out_unlock;
- }
- ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
- if (ret != 6) {
- ret = -EINVAL;
- goto out_unlock;
- }
- sp.sp_error = p1;
- sp.sp_offset = p2;
- sp.sp_stabletime = p3;
- sp.sp_calcontrol = p4;
- sp.sp_extsleepclk = p5;
- sp.sp_reserved = p6;
-
- ret = lbs_cmd_802_11_sleep_params(priv, CMD_ACT_SET, &sp);
- if (!ret)
- ret = count;
- else if (ret > 0)
- ret = -EINVAL;
-
-out_unlock:
- free_page(addr);
- return ret;
-}
-
-static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t ret;
- size_t pos = 0;
- struct sleep_params sp;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- ret = lbs_cmd_802_11_sleep_params(priv, CMD_ACT_GET, &sp);
- if (ret)
- goto out_unlock;
-
- pos += snprintf(buf, len, "%d %d %d %d %d %d\n", sp.sp_error,
- sp.sp_offset, sp.sp_stabletime,
- sp.sp_calcontrol, sp.sp_extsleepclk,
- sp.sp_reserved);
-
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-
-out_unlock:
- free_page(addr);
- return ret;
-}
-
-static ssize_t lbs_host_sleep_write(struct file *file,
- const char __user *user_buf, size_t count,
- loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t buf_size, ret;
- int host_sleep;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, user_buf, buf_size)) {
- ret = -EFAULT;
- goto out_unlock;
- }
- ret = sscanf(buf, "%d", &host_sleep);
- if (ret != 1) {
- ret = -EINVAL;
- goto out_unlock;
- }
-
- if (host_sleep == 0)
- ret = lbs_set_host_sleep(priv, 0);
- else if (host_sleep == 1) {
- if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
- netdev_info(priv->dev,
- "wake parameters not configured\n");
- ret = -EINVAL;
- goto out_unlock;
- }
- ret = lbs_set_host_sleep(priv, 1);
- } else {
- netdev_err(priv->dev, "invalid option\n");
- ret = -EINVAL;
- }
-
- if (!ret)
- ret = count;
-
-out_unlock:
- free_page(addr);
- return ret;
-}
-
-static ssize_t lbs_host_sleep_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t ret;
- size_t pos = 0;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- pos += snprintf(buf, len, "%d\n", priv->is_host_sleep_activated);
-
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-
- free_page(addr);
- return ret;
-}
-
-/*
- * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might
- * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the
- * firmware. Here's an example:
- * 04 01 02 00 00 00 05 01 02 00 00 00 06 01 02 00
- * 00 00 07 01 02 00 3c 00 00 00 00 00 00 00 03 03
- * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- *
- * The 04 01 is the TLV type (here TLV_TYPE_RSSI_LOW), 02 00 is the length,
- * 00 00 are the data bytes of this TLV. For this TLV, their meaning is
- * defined in mrvlietypes_thresholds
- *
- * This function searches in this TLV data chunk for a given TLV type
- * and returns a pointer to the first data byte of the TLV, or to NULL
- * if the TLV hasn't been found.
- */
-static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
-{
- struct mrvl_ie_header *tlv_h;
- uint16_t length;
- ssize_t pos = 0;
-
- while (pos < size) {
- tlv_h = (struct mrvl_ie_header *) tlv;
- if (!tlv_h->len)
- return NULL;
- if (tlv_h->type == cpu_to_le16(tlv_type))
- return tlv_h;
- length = le16_to_cpu(tlv_h->len) + sizeof(*tlv_h);
- pos += length;
- tlv += length;
- }
- return NULL;
-}
-
-
-static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
- struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct cmd_ds_802_11_subscribe_event *subscribed;
- struct mrvl_ie_thresholds *got;
- struct lbs_private *priv = file->private_data;
- ssize_t ret = 0;
- size_t pos = 0;
- char *buf;
- u8 value;
- u8 freq;
- int events = 0;
-
- buf = (char *)get_zeroed_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- subscribed = kzalloc(sizeof(*subscribed), GFP_KERNEL);
- if (!subscribed) {
- ret = -ENOMEM;
- goto out_page;
- }
-
- subscribed->hdr.size = cpu_to_le16(sizeof(*subscribed));
- subscribed->action = cpu_to_le16(CMD_ACT_GET);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, subscribed);
- if (ret)
- goto out_cmd;
-
- got = lbs_tlv_find(tlv_type, subscribed->tlv, sizeof(subscribed->tlv));
- if (got) {
- value = got->value;
- freq = got->freq;
- events = le16_to_cpu(subscribed->events);
-
- pos += snprintf(buf, len, "%d %d %d\n", value, freq,
- !!(events & event_mask));
- }
-
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-
- out_cmd:
- kfree(subscribed);
-
- out_page:
- free_page((unsigned long)buf);
- return ret;
-}
-
-
-static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
- struct file *file,
- const char __user *userbuf, size_t count,
- loff_t *ppos)
-{
- struct cmd_ds_802_11_subscribe_event *events;
- struct mrvl_ie_thresholds *tlv;
- struct lbs_private *priv = file->private_data;
- ssize_t buf_size;
- int value, freq, new_mask;
- uint16_t curr_mask;
- char *buf;
- int ret;
-
- buf = (char *)get_zeroed_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- ret = -EFAULT;
- goto out_page;
- }
- ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask);
- if (ret != 3) {
- ret = -EINVAL;
- goto out_page;
- }
- events = kzalloc(sizeof(*events), GFP_KERNEL);
- if (!events) {
- ret = -ENOMEM;
- goto out_page;
- }
-
- events->hdr.size = cpu_to_le16(sizeof(*events));
- events->action = cpu_to_le16(CMD_ACT_GET);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events);
- if (ret)
- goto out_events;
-
- curr_mask = le16_to_cpu(events->events);
-
- if (new_mask)
- new_mask = curr_mask | event_mask;
- else
- new_mask = curr_mask & ~event_mask;
-
- /* Now everything is set and we can send stuff down to the firmware */
-
- tlv = (void *)events->tlv;
-
- events->action = cpu_to_le16(CMD_ACT_SET);
- events->events = cpu_to_le16(new_mask);
- tlv->header.type = cpu_to_le16(tlv_type);
- tlv->header.len = cpu_to_le16(sizeof(*tlv) - sizeof(tlv->header));
- tlv->value = value;
- if (tlv_type != TLV_TYPE_BCNMISS)
- tlv->freq = freq;
-
- /* The command header, the action, the event mask, and one TLV */
- events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 4 + sizeof(*tlv));
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events);
-
- if (!ret)
- ret = count;
- out_events:
- kfree(events);
- out_page:
- free_page((unsigned long)buf);
- return ret;
-}
-
-
-static ssize_t lbs_lowrssi_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_read(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_lowrssi_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_write(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_lowsnr_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_read(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_lowsnr_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_write(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_failcount_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_read(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_failcount_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_write(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_highrssi_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_read(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_highrssi_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_write(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_highsnr_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_read(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_highsnr_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_write(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
- file, userbuf, count, ppos);
-}
-
-static ssize_t lbs_bcnmiss_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_read(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- return lbs_threshold_write(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
- file, userbuf, count, ppos);
-}
-
-
-static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t pos = 0;
- int ret;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- u32 val = 0;
-
- if (!buf)
- return -ENOMEM;
-
- ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val);
- mdelay(10);
- if (!ret) {
- pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n",
- priv->mac_offset, val);
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
- }
- free_page(addr);
- return ret;
-}
-
-static ssize_t lbs_rdmac_write(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
- priv->mac_offset = simple_strtoul(buf, NULL, 16);
- res = count;
-out_unlock:
- free_page(addr);
- return res;
-}
-
-static ssize_t lbs_wrmac_write(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
-
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- u32 offset, value;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
- res = sscanf(buf, "%x %x", &offset, &value);
- if (res != 2) {
- res = -EFAULT;
- goto out_unlock;
- }
-
- res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value);
- mdelay(10);
-
- if (!res)
- res = count;
-out_unlock:
- free_page(addr);
- return res;
-}
-
-static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t pos = 0;
- int ret;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- u32 val;
-
- if (!buf)
- return -ENOMEM;
-
- ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val);
- mdelay(10);
- if (!ret) {
- pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n",
- priv->bbp_offset, val);
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
- }
- free_page(addr);
-
- return ret;
-}
-
-static ssize_t lbs_rdbbp_write(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
- priv->bbp_offset = simple_strtoul(buf, NULL, 16);
- res = count;
-out_unlock:
- free_page(addr);
- return res;
-}
-
-static ssize_t lbs_wrbbp_write(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
-
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- u32 offset, value;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
- res = sscanf(buf, "%x %x", &offset, &value);
- if (res != 2) {
- res = -EFAULT;
- goto out_unlock;
- }
-
- res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value);
- mdelay(10);
-
- if (!res)
- res = count;
-out_unlock:
- free_page(addr);
- return res;
-}
-
-static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t pos = 0;
- int ret;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- u32 val;
-
- if (!buf)
- return -ENOMEM;
-
- ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val);
- mdelay(10);
- if (!ret) {
- pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n",
- priv->rf_offset, val);
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
- }
- free_page(addr);
-
- return ret;
-}
-
-static ssize_t lbs_rdrf_write(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
- priv->rf_offset = simple_strtoul(buf, NULL, 16);
- res = count;
-out_unlock:
- free_page(addr);
- return res;
-}
-
-static ssize_t lbs_wrrf_write(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
-
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- u32 offset, value;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
- res = sscanf(buf, "%x %x", &offset, &value);
- if (res != 2) {
- res = -EFAULT;
- goto out_unlock;
- }
-
- res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value);
- mdelay(10);
-
- if (!res)
- res = count;
-out_unlock:
- free_page(addr);
- return res;
-}
-
-#define FOPS(fread, fwrite) { \
- .owner = THIS_MODULE, \
- .open = simple_open, \
- .read = (fread), \
- .write = (fwrite), \
- .llseek = generic_file_llseek, \
-}
-
-struct lbs_debugfs_files {
- const char *name;
- umode_t perm;
- struct file_operations fops;
-};
-
-static const struct lbs_debugfs_files debugfs_files[] = {
- { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
- { "sleepparams", 0644, FOPS(lbs_sleepparams_read,
- lbs_sleepparams_write), },
- { "hostsleep", 0644, FOPS(lbs_host_sleep_read,
- lbs_host_sleep_write), },
-};
-
-static const struct lbs_debugfs_files debugfs_events_files[] = {
- {"low_rssi", 0644, FOPS(lbs_lowrssi_read,
- lbs_lowrssi_write), },
- {"low_snr", 0644, FOPS(lbs_lowsnr_read,
- lbs_lowsnr_write), },
- {"failure_count", 0644, FOPS(lbs_failcount_read,
- lbs_failcount_write), },
- {"beacon_missed", 0644, FOPS(lbs_bcnmiss_read,
- lbs_bcnmiss_write), },
- {"high_rssi", 0644, FOPS(lbs_highrssi_read,
- lbs_highrssi_write), },
- {"high_snr", 0644, FOPS(lbs_highsnr_read,
- lbs_highsnr_write), },
-};
-
-static const struct lbs_debugfs_files debugfs_regs_files[] = {
- {"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), },
- {"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), },
- {"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), },
- {"wrbbp", 0600, FOPS(NULL, lbs_wrbbp_write), },
- {"rdrf", 0644, FOPS(lbs_rdrf_read, lbs_rdrf_write), },
- {"wrrf", 0600, FOPS(NULL, lbs_wrrf_write), },
-};
-
-void lbs_debugfs_init(void)
-{
- if (!lbs_dir)
- lbs_dir = debugfs_create_dir("lbs_wireless", NULL);
-}
-
-void lbs_debugfs_remove(void)
-{
- debugfs_remove(lbs_dir);
-}
-
-void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
-{
- int i;
- const struct lbs_debugfs_files *files;
- if (!lbs_dir)
- goto exit;
-
- priv->debugfs_dir = debugfs_create_dir(dev->name, lbs_dir);
- if (!priv->debugfs_dir)
- goto exit;
-
- for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
- files = &debugfs_files[i];
- priv->debugfs_files[i] = debugfs_create_file(files->name,
- files->perm,
- priv->debugfs_dir,
- priv,
- &files->fops);
- }
-
- priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
- if (!priv->events_dir)
- goto exit;
-
- for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
- files = &debugfs_events_files[i];
- priv->debugfs_events_files[i] = debugfs_create_file(files->name,
- files->perm,
- priv->events_dir,
- priv,
- &files->fops);
- }
-
- priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
- if (!priv->regs_dir)
- goto exit;
-
- for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
- files = &debugfs_regs_files[i];
- priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
- files->perm,
- priv->regs_dir,
- priv,
- &files->fops);
- }
-
-#ifdef PROC_DEBUG
- lbs_debug_init(priv);
-#endif
-exit:
- return;
-}
-
-void lbs_debugfs_remove_one(struct lbs_private *priv)
-{
- int i;
-
- for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
- debugfs_remove(priv->debugfs_regs_files[i]);
-
- debugfs_remove(priv->regs_dir);
-
- for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
- debugfs_remove(priv->debugfs_events_files[i]);
-
- debugfs_remove(priv->events_dir);
-#ifdef PROC_DEBUG
- debugfs_remove(priv->debugfs_debug);
-#endif
- for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
- debugfs_remove(priv->debugfs_files[i]);
- debugfs_remove(priv->debugfs_dir);
-}
-
-
-
-/* debug entry */
-
-#ifdef PROC_DEBUG
-
-#define item_size(n) (FIELD_SIZEOF(struct lbs_private, n))
-#define item_addr(n) (offsetof(struct lbs_private, n))
-
-
-struct debug_data {
- char name[32];
- u32 size;
- size_t addr;
-};
-
-/* To debug any member of struct lbs_private, simply add one line here.
- */
-static struct debug_data items[] = {
- {"psmode", item_size(psmode), item_addr(psmode)},
- {"psstate", item_size(psstate), item_addr(psstate)},
-};
-
-static int num_of_items = ARRAY_SIZE(items);
-
-/**
- * lbs_debugfs_read - proc read function
- *
- * @file: file to read
- * @userbuf: pointer to buffer
- * @count: number of bytes to read
- * @ppos: read data starting position
- *
- * returns: amount of data read or negative error code
- */
-static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- int val = 0;
- size_t pos = 0;
- ssize_t res;
- char *p;
- int i;
- struct debug_data *d;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
- if (!buf)
- return -ENOMEM;
-
- p = buf;
-
- d = file->private_data;
-
- for (i = 0; i < num_of_items; i++) {
- if (d[i].size == 1)
- val = *((u8 *) d[i].addr);
- else if (d[i].size == 2)
- val = *((u16 *) d[i].addr);
- else if (d[i].size == 4)
- val = *((u32 *) d[i].addr);
- else if (d[i].size == 8)
- val = *((u64 *) d[i].addr);
-
- pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
- }
-
- res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
-
- free_page(addr);
- return res;
-}
-
-/**
- * lbs_debugfs_write - proc write function
- *
- * @f: file pointer
- * @buf: pointer to data buffer
- * @cnt: data number to write
- * @ppos: file position
- *
- * returns: amount of data written
- */
-static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
- size_t cnt, loff_t *ppos)
-{
- int r, i;
- char *pdata;
- char *p;
- char *p0;
- char *p1;
- char *p2;
- struct debug_data *d = f->private_data;
-
- if (cnt == 0)
- return 0;
-
- pdata = kmalloc(cnt + 1, GFP_KERNEL);
- if (pdata == NULL)
- return 0;
-
- if (copy_from_user(pdata, buf, cnt)) {
- lbs_deb_debugfs("Copy from user failed\n");
- kfree(pdata);
- return 0;
- }
- pdata[cnt] = '\0';
-
- p0 = pdata;
- for (i = 0; i < num_of_items; i++) {
- do {
- p = strstr(p0, d[i].name);
- if (p == NULL)
- break;
- p1 = strchr(p, '\n');
- if (p1 == NULL)
- break;
- p0 = p1++;
- p2 = strchr(p, '=');
- if (!p2)
- break;
- p2++;
- r = simple_strtoul(p2, NULL, 0);
- if (d[i].size == 1)
- *((u8 *) d[i].addr) = (u8) r;
- else if (d[i].size == 2)
- *((u16 *) d[i].addr) = (u16) r;
- else if (d[i].size == 4)
- *((u32 *) d[i].addr) = (u32) r;
- else if (d[i].size == 8)
- *((u64 *) d[i].addr) = (u64) r;
- break;
- } while (1);
- }
- kfree(pdata);
-
- return (ssize_t)cnt;
-}
-
-static const struct file_operations lbs_debug_fops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .write = lbs_debugfs_write,
- .read = lbs_debugfs_read,
- .llseek = default_llseek,
-};
-
-/**
- * lbs_debug_init - create debug proc file
- *
- * @priv: pointer to &struct lbs_private
- *
- * returns: N/A
- */
-static void lbs_debug_init(struct lbs_private *priv)
-{
- int i;
-
- if (!priv->debugfs_dir)
- return;
-
- for (i = 0; i < num_of_items; i++)
- items[i].addr += (size_t) priv;
-
- priv->debugfs_debug = debugfs_create_file("debug", 0644,
- priv->debugfs_dir, &items[0],
- &lbs_debug_fops);
-}
-#endif
diff --git a/drivers/net/wireless/libertas/debugfs.h b/drivers/net/wireless/libertas/debugfs.h
deleted file mode 100644
index f2b9c7ffe..000000000
--- a/drivers/net/wireless/libertas/debugfs.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _LBS_DEBUGFS_H_
-#define _LBS_DEBUGFS_H_
-
-void lbs_debugfs_init(void);
-void lbs_debugfs_remove(void);
-
-void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev);
-void lbs_debugfs_remove_one(struct lbs_private *priv);
-
-#endif
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
deleted file mode 100644
index 84a3aa7ac..000000000
--- a/drivers/net/wireless/libertas/decl.h
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * This file contains declaration referring to
- * functions defined in other source files
- */
-
-#ifndef _LBS_DECL_H_
-#define _LBS_DECL_H_
-
-#include <linux/netdevice.h>
-#include <linux/firmware.h>
-#include <linux/nl80211.h>
-
-/* Should be terminated by a NULL entry */
-struct lbs_fw_table {
- int model;
- const char *helper;
- const char *fwname;
-};
-
-struct lbs_private;
-typedef void (*lbs_fw_cb)(struct lbs_private *priv, int ret,
- const struct firmware *helper, const struct firmware *mainfw);
-
-struct lbs_private;
-struct sk_buff;
-struct net_device;
-struct cmd_ds_command;
-
-
-/* ethtool.c */
-extern const struct ethtool_ops lbs_ethtool_ops;
-
-
-/* tx.c */
-void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count);
-netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb,
- struct net_device *dev);
-
-/* rx.c */
-int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *);
-
-
-/* main.c */
-struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
-void lbs_remove_card(struct lbs_private *priv);
-int lbs_start_card(struct lbs_private *priv);
-void lbs_stop_card(struct lbs_private *priv);
-void lbs_host_to_card_done(struct lbs_private *priv);
-
-int lbs_start_iface(struct lbs_private *priv);
-int lbs_stop_iface(struct lbs_private *priv);
-int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type);
-
-int lbs_rtap_supported(struct lbs_private *priv);
-
-int lbs_set_mac_address(struct net_device *dev, void *addr);
-void lbs_set_multicast_list(struct net_device *dev);
-void lbs_update_mcast(struct lbs_private *priv);
-
-int lbs_suspend(struct lbs_private *priv);
-int lbs_resume(struct lbs_private *priv);
-
-void lbs_queue_event(struct lbs_private *priv, u32 event);
-void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
-
-int lbs_enter_auto_deep_sleep(struct lbs_private *priv);
-int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
-
-u32 lbs_fw_index_to_data_rate(u8 index);
-u8 lbs_data_rate_to_fw_index(u32 rate);
-
-int lbs_get_firmware(struct device *dev, u32 card_model,
- const struct lbs_fw_table *fw_table,
- const struct firmware **helper,
- const struct firmware **mainfw);
-int lbs_get_firmware_async(struct lbs_private *priv, struct device *device,
- u32 card_model, const struct lbs_fw_table *fw_table,
- lbs_fw_cb callback);
-void lbs_wait_for_firmware_load(struct lbs_private *priv);
-
-#endif
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
deleted file mode 100644
index 407784aca..000000000
--- a/drivers/net/wireless/libertas/defs.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * This header file contains global constant/enum definitions,
- * global variable declaration.
- */
-#ifndef _LBS_DEFS_H_
-#define _LBS_DEFS_H_
-
-#include <linux/spinlock.h>
-
-#ifdef CONFIG_LIBERTAS_DEBUG
-#define DEBUG
-#define PROC_DEBUG
-#endif
-
-#ifndef DRV_NAME
-#define DRV_NAME "libertas"
-#endif
-
-
-#define LBS_DEB_ENTER 0x00000001
-#define LBS_DEB_LEAVE 0x00000002
-#define LBS_DEB_MAIN 0x00000004
-#define LBS_DEB_NET 0x00000008
-#define LBS_DEB_MESH 0x00000010
-#define LBS_DEB_WEXT 0x00000020
-#define LBS_DEB_IOCTL 0x00000040
-#define LBS_DEB_SCAN 0x00000080
-#define LBS_DEB_ASSOC 0x00000100
-#define LBS_DEB_JOIN 0x00000200
-#define LBS_DEB_11D 0x00000400
-#define LBS_DEB_DEBUGFS 0x00000800
-#define LBS_DEB_ETHTOOL 0x00001000
-#define LBS_DEB_HOST 0x00002000
-#define LBS_DEB_CMD 0x00004000
-#define LBS_DEB_RX 0x00008000
-#define LBS_DEB_TX 0x00010000
-#define LBS_DEB_USB 0x00020000
-#define LBS_DEB_CS 0x00040000
-#define LBS_DEB_FW 0x00080000
-#define LBS_DEB_THREAD 0x00100000
-#define LBS_DEB_HEX 0x00200000
-#define LBS_DEB_SDIO 0x00400000
-#define LBS_DEB_SYSFS 0x00800000
-#define LBS_DEB_SPI 0x01000000
-#define LBS_DEB_CFG80211 0x02000000
-
-extern unsigned int lbs_debug;
-
-#ifdef DEBUG
-#define LBS_DEB_LL(grp, grpnam, fmt, args...) \
-do { if ((lbs_debug & (grp)) == (grp)) \
- printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \
- in_interrupt() ? " (INT)" : "", ## args); } while (0)
-#else
-#define LBS_DEB_LL(grp, grpnam, fmt, args...) do {} while (0)
-#endif
-
-#define lbs_deb_enter(grp) \
- LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s()\n", __func__);
-#define lbs_deb_enter_args(grp, fmt, args...) \
- LBS_DEB_LL(grp | LBS_DEB_ENTER, " enter", "%s(" fmt ")\n", __func__, ## args);
-#define lbs_deb_leave(grp) \
- LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s()\n", __func__);
-#define lbs_deb_leave_args(grp, fmt, args...) \
- LBS_DEB_LL(grp | LBS_DEB_LEAVE, " leave", "%s(), " fmt "\n", \
- __func__, ##args);
-#define lbs_deb_main(fmt, args...) LBS_DEB_LL(LBS_DEB_MAIN, " main", fmt, ##args)
-#define lbs_deb_net(fmt, args...) LBS_DEB_LL(LBS_DEB_NET, " net", fmt, ##args)
-#define lbs_deb_mesh(fmt, args...) LBS_DEB_LL(LBS_DEB_MESH, " mesh", fmt, ##args)
-#define lbs_deb_wext(fmt, args...) LBS_DEB_LL(LBS_DEB_WEXT, " wext", fmt, ##args)
-#define lbs_deb_ioctl(fmt, args...) LBS_DEB_LL(LBS_DEB_IOCTL, " ioctl", fmt, ##args)
-#define lbs_deb_scan(fmt, args...) LBS_DEB_LL(LBS_DEB_SCAN, " scan", fmt, ##args)
-#define lbs_deb_assoc(fmt, args...) LBS_DEB_LL(LBS_DEB_ASSOC, " assoc", fmt, ##args)
-#define lbs_deb_join(fmt, args...) LBS_DEB_LL(LBS_DEB_JOIN, " join", fmt, ##args)
-#define lbs_deb_11d(fmt, args...) LBS_DEB_LL(LBS_DEB_11D, " 11d", fmt, ##args)
-#define lbs_deb_debugfs(fmt, args...) LBS_DEB_LL(LBS_DEB_DEBUGFS, " debugfs", fmt, ##args)
-#define lbs_deb_ethtool(fmt, args...) LBS_DEB_LL(LBS_DEB_ETHTOOL, " ethtool", fmt, ##args)
-#define lbs_deb_host(fmt, args...) LBS_DEB_LL(LBS_DEB_HOST, " host", fmt, ##args)
-#define lbs_deb_cmd(fmt, args...) LBS_DEB_LL(LBS_DEB_CMD, " cmd", fmt, ##args)
-#define lbs_deb_rx(fmt, args...) LBS_DEB_LL(LBS_DEB_RX, " rx", fmt, ##args)
-#define lbs_deb_tx(fmt, args...) LBS_DEB_LL(LBS_DEB_TX, " tx", fmt, ##args)
-#define lbs_deb_fw(fmt, args...) LBS_DEB_LL(LBS_DEB_FW, " fw", fmt, ##args)
-#define lbs_deb_usb(fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usb", fmt, ##args)
-#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, dev_name(dev), ##args)
-#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args)
-#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
-#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
-#define lbs_deb_sysfs(fmt, args...) LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args)
-#define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
-#define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args)
-
-#ifdef DEBUG
-static inline void lbs_deb_hex(unsigned int grp, const char *prompt,
- const u8 *buf, int len)
-{
- int i = 0;
-
- if (len &&
- (lbs_debug & LBS_DEB_HEX) &&
- (lbs_debug & grp))
- {
- for (i = 1; i <= len; i++) {
- if ((i & 0xf) == 1) {
- if (i != 1)
- printk("\n");
- printk(DRV_NAME " %s: ", prompt);
- }
- printk("%02x ", (u8) * buf);
- buf++;
- }
- printk("\n");
- }
-}
-#else
-#define lbs_deb_hex(grp,prompt,buf,len) do {} while (0)
-#endif
-
-
-
-/* Buffer Constants */
-
-/* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
- * addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
- * driver has more local TxPDs. Each TxPD on the host memory is associated
- * with a Tx control node. The driver maintains 8 RxPD descriptors for
- * station firmware to store Rx packet information.
- *
- * Current version of MAC has a 32x6 multicast address buffer.
- *
- * 802.11b can have up to 14 channels, the driver keeps the
- * BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
- */
-
-#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
-#define LBS_NUM_CMD_BUFFERS 10
-#define LBS_CMD_BUFFER_SIZE (2 * 1024)
-#define MRVDRV_MAX_CHANNEL_SIZE 14
-#define MRVDRV_ASSOCIATION_TIME_OUT 255
-#define MRVDRV_SNAP_HEADER_LEN 8
-
-#define LBS_UPLD_SIZE 2312
-#define DEV_NAME_LEN 32
-
-/* Wake criteria for HOST_SLEEP_CFG command */
-#define EHS_WAKE_ON_BROADCAST_DATA 0x0001
-#define EHS_WAKE_ON_UNICAST_DATA 0x0002
-#define EHS_WAKE_ON_MAC_EVENT 0x0004
-#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
-#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
-/* Wake rules for Host_Sleep_CFG command */
-#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS 0x00
-#define WOL_RULE_NET_TYPE_MESH 0x10
-#define WOL_RULE_ADDR_TYPE_BCAST 0x01
-#define WOL_RULE_ADDR_TYPE_MCAST 0x08
-#define WOL_RULE_ADDR_TYPE_UCAST 0x02
-#define WOL_RULE_OP_AND 0x01
-#define WOL_RULE_OP_OR 0x02
-#define WOL_RULE_OP_INVALID 0xFF
-#define WOL_RESULT_VALID_CMD 0
-#define WOL_RESULT_NOSPC_ERR 1
-#define WOL_RESULT_EEXIST_ERR 2
-
-/* Misc constants */
-/* This section defines 802.11 specific contants */
-
-#define MRVDRV_MAX_BSS_DESCRIPTS 16
-#define MRVDRV_MAX_REGION_CODE 6
-
-#define MRVDRV_DEFAULT_LISTEN_INTERVAL 10
-
-#define MRVDRV_CHANNELS_PER_SCAN 4
-#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
-
-#define MRVDRV_MIN_BEACON_INTERVAL 20
-#define MRVDRV_MAX_BEACON_INTERVAL 1000
-#define MRVDRV_BEACON_INTERVAL 100
-
-#define MARVELL_MESH_IE_LENGTH 9
-
-/*
- * Values used to populate the struct mrvl_mesh_ie. The only time you need this
- * is when enabling the mesh using CMD_MESH_CONFIG.
- */
-#define MARVELL_MESH_IE_TYPE 4
-#define MARVELL_MESH_IE_SUBTYPE 0
-#define MARVELL_MESH_IE_VERSION 0
-#define MARVELL_MESH_PROTO_ID_HWMP 0
-#define MARVELL_MESH_METRIC_ID 0
-#define MARVELL_MESH_CAPABILITY 0
-
-/* INT status Bit Definition */
-#define MRVDRV_TX_DNLD_RDY 0x0001
-#define MRVDRV_RX_UPLD_RDY 0x0002
-#define MRVDRV_CMD_DNLD_RDY 0x0004
-#define MRVDRV_CMD_UPLD_RDY 0x0008
-#define MRVDRV_CARDEVENT 0x0010
-
-/* Automatic TX control default levels */
-#define POW_ADAPT_DEFAULT_P0 13
-#define POW_ADAPT_DEFAULT_P1 15
-#define POW_ADAPT_DEFAULT_P2 18
-#define TPC_DEFAULT_P0 5
-#define TPC_DEFAULT_P1 10
-#define TPC_DEFAULT_P2 13
-
-/* TxPD status */
-
-/*
- * Station firmware use TxPD status field to report final Tx transmit
- * result, Bit masks are used to present combined situations.
- */
-
-#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
-#define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
-
-/* Tx mesh flag */
-/*
- * Currently we are using normal WDS flag as mesh flag.
- * TODO: change to proper mesh flag when MAC understands it.
- */
-#define TxPD_CONTROL_WDS_FRAME (1<<17)
-#define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
-
-/* Mesh interface ID */
-#define MESH_IFACE_ID 0x0001
-/* Mesh id should be in bits 14-13-12 */
-#define MESH_IFACE_BIT_OFFSET 0x000c
-/* Mesh enable bit in FW capability */
-#define MESH_CAPINFO_ENABLE_MASK (1<<16)
-
-/* FW definition from Marvell v4 */
-#define MRVL_FW_V4 (0x04)
-/* FW definition from Marvell v5 */
-#define MRVL_FW_V5 (0x05)
-/* FW definition from Marvell v10 */
-#define MRVL_FW_V10 (0x0a)
-/* FW major revision definition */
-#define MRVL_FW_MAJOR_REV(x) ((x)>>24)
-
-/* RxPD status */
-
-#define MRVDRV_RXPD_STATUS_OK 0x0001
-
-/* RxPD status - Received packet types */
-/* Rx mesh flag */
-/*
- * Currently we are using normal WDS flag as mesh flag.
- * TODO: change to proper mesh flag when MAC understands it.
- */
-#define RxPD_CONTROL_WDS_FRAME (0x40)
-#define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME
-
-/* RSSI-related defines */
-/*
- * RSSI constants are used to implement 802.11 RSSI threshold
- * indication. if the Rx packet signal got too weak for 5 consecutive
- * times, miniport driver (driver) will report this event to wrapper
- */
-
-#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96)
-
-/* RTS/FRAG related defines */
-#define MRVDRV_RTS_MIN_VALUE 0
-#define MRVDRV_RTS_MAX_VALUE 2347
-#define MRVDRV_FRAG_MIN_VALUE 256
-#define MRVDRV_FRAG_MAX_VALUE 2346
-
-/* This is for firmware specific length */
-#define EXTRA_LEN 36
-
-#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
- (ETH_FRAME_LEN + sizeof(struct txpd) + EXTRA_LEN)
-
-#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
- (ETH_FRAME_LEN + sizeof(struct rxpd) \
- + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
-
-#define CMD_F_HOSTCMD (1 << 0)
-#define FW_CAPINFO_WPA (1 << 0)
-#define FW_CAPINFO_PS (1 << 1)
-#define FW_CAPINFO_FIRMWARE_UPGRADE (1 << 13)
-#define FW_CAPINFO_BOOT2_UPGRADE (1<<14)
-#define FW_CAPINFO_PERSISTENT_CONFIG (1<<15)
-
-#define KEY_LEN_WPA_AES 16
-#define KEY_LEN_WPA_TKIP 32
-#define KEY_LEN_WEP_104 13
-#define KEY_LEN_WEP_40 5
-
-#define RF_ANTENNA_1 0x1
-#define RF_ANTENNA_2 0x2
-#define RF_ANTENNA_AUTO 0xFFFF
-
-#define BAND_B (0x01)
-#define BAND_G (0x02)
-#define ALL_802_11_BANDS (BAND_B | BAND_G)
-
-#define MAX_RATES 14
-
-#define MAX_LEDS 8
-
-/* Global Variable Declaration */
-extern const char lbs_driver_version[];
-extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
-
-
-/* ENUM definition */
-/* SNRNF_TYPE */
-enum SNRNF_TYPE {
- TYPE_BEACON = 0,
- TYPE_RXPD,
- MAX_TYPE_B
-};
-
-/* SNRNF_DATA */
-enum SNRNF_DATA {
- TYPE_NOAVG = 0,
- TYPE_AVG,
- MAX_TYPE_AVG
-};
-
-/* LBS_802_11_POWER_MODE */
-enum LBS_802_11_POWER_MODE {
- LBS802_11POWERMODECAM,
- LBS802_11POWERMODEMAX_PSP,
- LBS802_11POWERMODEFAST_PSP,
- /* not a real mode, defined as an upper bound */
- LBS802_11POWEMODEMAX
-};
-
-/* PS_STATE */
-enum PS_STATE {
- PS_STATE_FULL_POWER,
- PS_STATE_AWAKE,
- PS_STATE_PRE_SLEEP,
- PS_STATE_SLEEP
-};
-
-/* DNLD_STATE */
-enum DNLD_STATE {
- DNLD_RES_RECEIVED,
- DNLD_DATA_SENT,
- DNLD_CMD_SENT,
- DNLD_BOOTCMD_SENT,
-};
-
-/* LBS_MEDIA_STATE */
-enum LBS_MEDIA_STATE {
- LBS_CONNECTED,
- LBS_DISCONNECTED
-};
-
-/* LBS_802_11_PRIVACY_FILTER */
-enum LBS_802_11_PRIVACY_FILTER {
- LBS802_11PRIVFILTERACCEPTALL,
- LBS802_11PRIVFILTER8021XWEP
-};
-
-/* mv_ms_type */
-enum mv_ms_type {
- MVMS_DAT = 0,
- MVMS_CMD = 1,
- MVMS_TXDONE = 2,
- MVMS_EVENT
-};
-
-/* KEY_TYPE_ID */
-enum KEY_TYPE_ID {
- KEY_TYPE_ID_WEP = 0,
- KEY_TYPE_ID_TKIP,
- KEY_TYPE_ID_AES
-};
-
-/* KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
-enum KEY_INFO_WPA {
- KEY_INFO_WPA_MCAST = 0x01,
- KEY_INFO_WPA_UNICAST = 0x02,
- KEY_INFO_WPA_ENABLED = 0x04
-};
-
-/* Default values for fwt commands. */
-#define FWT_DEFAULT_METRIC 0
-#define FWT_DEFAULT_DIR 1
-/* Default Rate, 11Mbps */
-#define FWT_DEFAULT_RATE 3
-#define FWT_DEFAULT_SSN 0xffffffff
-#define FWT_DEFAULT_DSN 0
-#define FWT_DEFAULT_HOPCOUNT 0
-#define FWT_DEFAULT_TTL 0
-#define FWT_DEFAULT_EXPIRATION 0
-#define FWT_DEFAULT_SLEEPMODE 0
-#define FWT_DEFAULT_SNR 0
-
-#endif
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
deleted file mode 100644
index 6bd160899..000000000
--- a/drivers/net/wireless/libertas/dev.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * This file contains definitions and data structures specific
- * to Marvell 802.11 NIC. It contains the Device Information
- * structure struct lbs_private..
- */
-#ifndef _LBS_DEV_H_
-#define _LBS_DEV_H_
-
-#include "defs.h"
-#include "decl.h"
-#include "host.h"
-
-#include <linux/kfifo.h>
-
-/* sleep_params */
-struct sleep_params {
- uint16_t sp_error;
- uint16_t sp_offset;
- uint16_t sp_stabletime;
- uint8_t sp_calcontrol;
- uint8_t sp_extsleepclk;
- uint16_t sp_reserved;
-};
-
-/* Mesh statistics */
-struct lbs_mesh_stats {
- u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
- u32 fwd_unicast_cnt; /* Fwd: Unicast counter */
- u32 fwd_drop_ttl; /* Fwd: TTL zero */
- u32 fwd_drop_rbt; /* Fwd: Recently Broadcasted */
- u32 fwd_drop_noroute; /* Fwd: No route to Destination */
- u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
- u32 drop_blind; /* Rx: Dropped by blinding table */
- u32 tx_failed_cnt; /* Tx: Failed transmissions */
-};
-
-/* Private structure for the MV device */
-struct lbs_private {
-
- /* Basic networking */
- struct net_device *dev;
- u32 connect_status;
- struct work_struct mcast_work;
- u32 nr_of_multicastmacaddr;
- u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
-
- /* CFG80211 */
- struct wireless_dev *wdev;
- bool wiphy_registered;
- struct cfg80211_scan_request *scan_req;
- u8 assoc_bss[ETH_ALEN];
- u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
- u8 disassoc_reason;
-
- /* Mesh */
- struct net_device *mesh_dev; /* Virtual device */
-#ifdef CONFIG_LIBERTAS_MESH
- struct lbs_mesh_stats mstats;
- uint16_t mesh_tlv;
- u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
- u8 mesh_ssid_len;
- u8 mesh_channel;
-#endif
-
- /* Debugfs */
- struct dentry *debugfs_dir;
- struct dentry *debugfs_debug;
- struct dentry *debugfs_files[6];
- struct dentry *events_dir;
- struct dentry *debugfs_events_files[6];
- struct dentry *regs_dir;
- struct dentry *debugfs_regs_files[6];
-
- /* Hardware debugging */
- u32 mac_offset;
- u32 bbp_offset;
- u32 rf_offset;
-
- /* Power management */
- u16 psmode;
- u32 psstate;
- u8 needtowakeup;
-
- /* Deep sleep */
- int is_deep_sleep;
- int deep_sleep_required;
- int is_auto_deep_sleep_enabled;
- int wakeup_dev_required;
- int is_activity_detected;
- int auto_deep_sleep_timeout; /* in ms */
- wait_queue_head_t ds_awake_q;
- struct timer_list auto_deepsleep_timer;
-
- /* Host sleep*/
- int is_host_sleep_configured;
- int is_host_sleep_activated;
- wait_queue_head_t host_sleep_q;
-
- /* Hardware access */
- void *card;
- bool iface_running;
- u8 fw_ready;
- u8 surpriseremoved;
- u8 setup_fw_on_resume;
- int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
- void (*reset_card) (struct lbs_private *priv);
- int (*power_save) (struct lbs_private *priv);
- int (*power_restore) (struct lbs_private *priv);
- int (*enter_deep_sleep) (struct lbs_private *priv);
- int (*exit_deep_sleep) (struct lbs_private *priv);
- int (*reset_deep_sleep_wakeup) (struct lbs_private *priv);
-
- /* Adapter info (from EEPROM) */
- u32 fwrelease;
- u32 fwcapinfo;
- u16 regioncode;
- u8 current_addr[ETH_ALEN];
- u8 copied_hwaddr;
-
- /* Command download */
- u8 dnld_sent;
- /* bit0 1/0=data_sent/data_tx_done,
- bit1 1/0=cmd_sent/cmd_tx_done,
- all other bits reserved 0 */
- u16 seqnum;
- struct cmd_ctrl_node *cmd_array;
- struct cmd_ctrl_node *cur_cmd;
- struct list_head cmdfreeq; /* free command buffers */
- struct list_head cmdpendingq; /* pending command buffers */
- struct timer_list command_timer;
- int cmd_timed_out;
-
- /* Command responses sent from the hardware to the driver */
- u8 resp_idx;
- u8 resp_buf[2][LBS_UPLD_SIZE];
- u32 resp_len[2];
-
- /* Events sent from hardware to driver */
- struct kfifo event_fifo;
-
- /* thread to service interrupts */
- struct task_struct *main_thread;
- wait_queue_head_t waitq;
- struct workqueue_struct *work_thread;
-
- /* Encryption stuff */
- u8 authtype_auto;
- u8 wep_tx_key;
- u8 wep_key[4][WLAN_KEY_LEN_WEP104];
- u8 wep_key_len[4];
-
- /* Wake On LAN */
- uint32_t wol_criteria;
- uint8_t wol_gpio;
- uint8_t wol_gap;
- bool ehs_remove_supported;
-
- /* Transmitting */
- int tx_pending_len; /* -1 while building packet */
- u8 tx_pending_buf[LBS_UPLD_SIZE];
- /* protected by hard_start_xmit serialization */
- u8 txretrycount;
- struct sk_buff *currenttxskb;
- struct timer_list tx_lockup_timer;
-
- /* Locks */
- struct mutex lock;
- spinlock_t driver_lock;
-
- /* NIC/link operation characteristics */
- u16 mac_control;
- u8 radio_on;
- u8 cur_rate;
- u8 channel;
- s16 txpower_cur;
- s16 txpower_min;
- s16 txpower_max;
-
- /* Scanning */
- struct delayed_work scan_work;
- int scan_channel;
- /* Queue of things waiting for scan completion */
- wait_queue_head_t scan_q;
- /* Whether the scan was initiated internally and not by cfg80211 */
- bool internal_scan;
-
- /* Firmware load */
- u32 fw_model;
- wait_queue_head_t fw_waitq;
- struct device *fw_device;
- const struct firmware *helper_fw;
- const struct lbs_fw_table *fw_table;
- const struct lbs_fw_table *fw_iter;
- lbs_fw_cb fw_callback;
-};
-
-extern struct cmd_confirm_sleep confirm_sleep;
-
-/* Check if there is an interface active. */
-static inline int lbs_iface_active(struct lbs_private *priv)
-{
- int r;
-
- r = netif_running(priv->dev);
- if (priv->mesh_dev)
- r |= netif_running(priv->mesh_dev);
-
- return r;
-}
-
-#endif
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
deleted file mode 100644
index f955b2d66..000000000
--- a/drivers/net/wireless/libertas/ethtool.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#include <linux/hardirq.h>
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-
-#include "decl.h"
-#include "cmd.h"
-#include "mesh.h"
-
-
-static void lbs_ethtool_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- snprintf(info->fw_version, sizeof(info->fw_version),
- "%u.%u.%u.p%u",
- priv->fwrelease >> 24 & 0xff,
- priv->fwrelease >> 16 & 0xff,
- priv->fwrelease >> 8 & 0xff,
- priv->fwrelease & 0xff);
- strlcpy(info->driver, "libertas", sizeof(info->driver));
- strlcpy(info->version, lbs_driver_version, sizeof(info->version));
-}
-
-/*
- * All 8388 parts have 16KiB EEPROM size at the time of writing.
- * In case that changes this needs fixing.
- */
-#define LBS_EEPROM_LEN 16384
-
-static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
-{
- return LBS_EEPROM_LEN;
-}
-
-static int lbs_ethtool_get_eeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom, u8 * bytes)
-{
- struct lbs_private *priv = dev->ml_priv;
- struct cmd_ds_802_11_eeprom_access cmd;
- int ret;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-
- if (eeprom->offset + eeprom->len > LBS_EEPROM_LEN ||
- eeprom->len > LBS_EEPROM_READ_LEN) {
- ret = -EINVAL;
- goto out;
- }
-
- cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) -
- LBS_EEPROM_READ_LEN + eeprom->len);
- cmd.action = cpu_to_le16(CMD_ACT_GET);
- cmd.offset = cpu_to_le16(eeprom->offset);
- cmd.len = cpu_to_le16(eeprom->len);
- ret = lbs_cmd_with_response(priv, CMD_802_11_EEPROM_ACCESS, &cmd);
- if (!ret)
- memcpy(bytes, cmd.value, eeprom->len);
-
-out:
- lbs_deb_leave_args(LBS_DEB_ETHTOOL, "ret %d", ret);
- return ret;
-}
-
-static void lbs_ethtool_get_wol(struct net_device *dev,
- struct ethtool_wolinfo *wol)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
-
- if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
- return;
-
- if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA)
- wol->wolopts |= WAKE_UCAST;
- if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA)
- wol->wolopts |= WAKE_MCAST;
- if (priv->wol_criteria & EHS_WAKE_ON_BROADCAST_DATA)
- wol->wolopts |= WAKE_BCAST;
- if (priv->wol_criteria & EHS_WAKE_ON_MAC_EVENT)
- wol->wolopts |= WAKE_PHY;
-}
-
-static int lbs_ethtool_set_wol(struct net_device *dev,
- struct ethtool_wolinfo *wol)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
- return -EOPNOTSUPP;
-
- priv->wol_criteria = 0;
- if (wol->wolopts & WAKE_UCAST)
- priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA;
- if (wol->wolopts & WAKE_MCAST)
- priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA;
- if (wol->wolopts & WAKE_BCAST)
- priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA;
- if (wol->wolopts & WAKE_PHY)
- priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT;
- if (wol->wolopts == 0)
- priv->wol_criteria |= EHS_REMOVE_WAKEUP;
- return 0;
-}
-
-const struct ethtool_ops lbs_ethtool_ops = {
- .get_drvinfo = lbs_ethtool_get_drvinfo,
- .get_eeprom = lbs_ethtool_get_eeprom,
- .get_eeprom_len = lbs_ethtool_get_eeprom_len,
-#ifdef CONFIG_LIBERTAS_MESH
- .get_sset_count = lbs_mesh_ethtool_get_sset_count,
- .get_ethtool_stats = lbs_mesh_ethtool_get_stats,
- .get_strings = lbs_mesh_ethtool_get_strings,
-#endif
- .get_wol = lbs_ethtool_get_wol,
- .set_wol = lbs_ethtool_set_wol,
-};
-
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c
deleted file mode 100644
index d1aa2f299..000000000
--- a/drivers/net/wireless/libertas/firmware.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Firmware loading and handling functions.
- */
-
-#include <linux/sched.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-
-#include "dev.h"
-#include "decl.h"
-
-static void load_next_firmware_from_table(struct lbs_private *private);
-
-static void lbs_fw_loaded(struct lbs_private *priv, int ret,
- const struct firmware *helper, const struct firmware *mainfw)
-{
- unsigned long flags;
-
- lbs_deb_fw("firmware load complete, code %d\n", ret);
-
- /* User must free helper/mainfw */
- priv->fw_callback(priv, ret, helper, mainfw);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- priv->fw_callback = NULL;
- wake_up(&priv->fw_waitq);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-}
-
-static void do_load_firmware(struct lbs_private *priv, const char *name,
- void (*cb)(const struct firmware *fw, void *context))
-{
- int ret;
-
- lbs_deb_fw("Requesting %s\n", name);
- ret = reject_firmware_nowait(THIS_MODULE, true, name,
- priv->fw_device, GFP_KERNEL, priv, cb);
- if (ret) {
- lbs_deb_fw("request_firmware_nowait error %d\n", ret);
- lbs_fw_loaded(priv, ret, NULL, NULL);
- }
-}
-
-static void main_firmware_cb(const struct firmware *firmware, void *context)
-{
- struct lbs_private *priv = context;
-
- if (!firmware) {
- /* Failed to find firmware: try next table entry */
- load_next_firmware_from_table(priv);
- return;
- }
-
- /* Firmware found! */
- lbs_fw_loaded(priv, 0, priv->helper_fw, firmware);
- if (priv->helper_fw) {
- release_firmware (priv->helper_fw);
- priv->helper_fw = NULL;
- }
- release_firmware (firmware);
-}
-
-static void helper_firmware_cb(const struct firmware *firmware, void *context)
-{
- struct lbs_private *priv = context;
-
- if (!firmware) {
- /* Failed to find firmware: try next table entry */
- load_next_firmware_from_table(priv);
- return;
- }
-
- /* Firmware found! */
- if (priv->fw_iter->fwname) {
- priv->helper_fw = firmware;
- do_load_firmware(priv, priv->fw_iter->fwname, main_firmware_cb);
- } else {
- /* No main firmware needed for this helper --> success! */
- lbs_fw_loaded(priv, 0, firmware, NULL);
- }
-}
-
-static void load_next_firmware_from_table(struct lbs_private *priv)
-{
- const struct lbs_fw_table *iter;
-
- if (!priv->fw_iter)
- iter = priv->fw_table;
- else
- iter = ++priv->fw_iter;
-
- if (priv->helper_fw) {
- release_firmware(priv->helper_fw);
- priv->helper_fw = NULL;
- }
-
-next:
- if (!iter->helper) {
- /* End of table hit. */
- lbs_fw_loaded(priv, -ENOENT, NULL, NULL);
- return;
- }
-
- if (iter->model != priv->fw_model) {
- iter++;
- goto next;
- }
-
- priv->fw_iter = iter;
- do_load_firmware(priv, iter->helper, helper_firmware_cb);
-}
-
-void lbs_wait_for_firmware_load(struct lbs_private *priv)
-{
- wait_event(priv->fw_waitq, priv->fw_callback == NULL);
-}
-
-/**
- * lbs_get_firmware_async - Retrieves firmware asynchronously. Can load
- * either a helper firmware and a main firmware (2-stage), or just the helper.
- *
- * @priv: Pointer to lbs_private instance
- * @dev: A pointer to &device structure
- * @card_model: Bus-specific card model ID used to filter firmware table
- * elements
- * @fw_table: Table of firmware file names and device model numbers
- * terminated by an entry with a NULL helper name
- * @callback: User callback to invoke when firmware load succeeds or fails.
- */
-int lbs_get_firmware_async(struct lbs_private *priv, struct device *device,
- u32 card_model, const struct lbs_fw_table *fw_table,
- lbs_fw_cb callback)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- if (priv->fw_callback) {
- lbs_deb_fw("firmware load already in progress\n");
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- return -EBUSY;
- }
-
- priv->fw_device = device;
- priv->fw_callback = callback;
- priv->fw_table = fw_table;
- priv->fw_iter = NULL;
- priv->fw_model = card_model;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- lbs_deb_fw("Starting async firmware load\n");
- load_next_firmware_from_table(priv);
- return 0;
-}
-EXPORT_SYMBOL_GPL(lbs_get_firmware_async);
-
-/**
- * lbs_get_firmware - Retrieves two-stage firmware
- *
- * @dev: A pointer to &device structure
- * @card_model: Bus-specific card model ID used to filter firmware table
- * elements
- * @fw_table: Table of firmware file names and device model numbers
- * terminated by an entry with a NULL helper name
- * @helper: On success, the helper firmware; caller must free
- * @mainfw: On success, the main firmware; caller must free
- *
- * Deprecated: use lbs_get_firmware_async() instead.
- *
- * returns: 0 on success, non-zero on failure
- */
-int lbs_get_firmware(struct device *dev, u32 card_model,
- const struct lbs_fw_table *fw_table,
- const struct firmware **helper,
- const struct firmware **mainfw)
-{
- const struct lbs_fw_table *iter;
- int ret;
-
- BUG_ON(helper == NULL);
- BUG_ON(mainfw == NULL);
-
- /* Search for firmware to use from the table. */
- iter = fw_table;
- while (iter && iter->helper) {
- if (iter->model != card_model)
- goto next;
-
- if (*helper == NULL) {
- ret = reject_firmware(helper, iter->helper, dev);
- if (ret)
- goto next;
-
- /* If the device has one-stage firmware (ie cf8305) and
- * we've got it then we don't need to bother with the
- * main firmware.
- */
- if (iter->fwname == NULL)
- return 0;
- }
-
- if (*mainfw == NULL) {
- ret = reject_firmware(mainfw, iter->fwname, dev);
- if (ret) {
- /* Clear the helper to ensure we don't have
- * mismatched firmware pairs.
- */
- release_firmware(*helper);
- *helper = NULL;
- }
- }
-
- if (*helper && *mainfw)
- return 0;
-
- next:
- iter++;
- }
-
- /* Failed */
- release_firmware(*helper);
- *helper = NULL;
- release_firmware(*mainfw);
- *mainfw = NULL;
-
- return -ENOENT;
-}
-EXPORT_SYMBOL_GPL(lbs_get_firmware);
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
deleted file mode 100644
index 96726f79a..000000000
--- a/drivers/net/wireless/libertas/host.h
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * This file function prototypes, data structure
- * and definitions for all the host/station commands
- */
-
-#ifndef _LBS_HOST_H_
-#define _LBS_HOST_H_
-
-#include "types.h"
-#include "defs.h"
-
-#define DEFAULT_AD_HOC_CHANNEL 6
-
-#define CMD_OPTION_WAITFORRSP 0x0002
-
-/* Host command IDs */
-
-/*
- * Return command are almost always the same as the host command, but with
- * bit 15 set high. There are a few exceptions, though...
- */
-#define CMD_RET(cmd) (0x8000 | cmd)
-
-/* Return command convention exceptions: */
-#define CMD_RET_802_11_ASSOCIATE 0x8012
-
-/* Command codes */
-#define CMD_GET_HW_SPEC 0x0003
-#define CMD_EEPROM_UPDATE 0x0004
-#define CMD_802_11_RESET 0x0005
-#define CMD_802_11_SCAN 0x0006
-#define CMD_802_11_GET_LOG 0x000b
-#define CMD_MAC_MULTICAST_ADR 0x0010
-#define CMD_802_11_AUTHENTICATE 0x0011
-#define CMD_802_11_EEPROM_ACCESS 0x0059
-#define CMD_802_11_ASSOCIATE 0x0050
-#define CMD_802_11_SET_WEP 0x0013
-#define CMD_802_11_GET_STAT 0x0014
-#define CMD_802_3_GET_STAT 0x0015
-#define CMD_802_11_SNMP_MIB 0x0016
-#define CMD_MAC_REG_MAP 0x0017
-#define CMD_BBP_REG_MAP 0x0018
-#define CMD_MAC_REG_ACCESS 0x0019
-#define CMD_BBP_REG_ACCESS 0x001a
-#define CMD_RF_REG_ACCESS 0x001b
-#define CMD_802_11_RADIO_CONTROL 0x001c
-#define CMD_802_11_RF_CHANNEL 0x001d
-#define CMD_802_11_RF_TX_POWER 0x001e
-#define CMD_802_11_RSSI 0x001f
-#define CMD_802_11_RF_ANTENNA 0x0020
-#define CMD_802_11_PS_MODE 0x0021
-#define CMD_802_11_DATA_RATE 0x0022
-#define CMD_RF_REG_MAP 0x0023
-#define CMD_802_11_DEAUTHENTICATE 0x0024
-#define CMD_802_11_REASSOCIATE 0x0025
-#define CMD_MAC_CONTROL 0x0028
-#define CMD_802_11_AD_HOC_START 0x002b
-#define CMD_802_11_AD_HOC_JOIN 0x002c
-#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS 0x002e
-#define CMD_802_11_ENABLE_RSN 0x002f
-#define CMD_802_11_SET_AFC 0x003c
-#define CMD_802_11_GET_AFC 0x003d
-#define CMD_802_11_DEEP_SLEEP 0x003e
-#define CMD_802_11_AD_HOC_STOP 0x0040
-#define CMD_802_11_HOST_SLEEP_CFG 0x0043
-#define CMD_802_11_WAKEUP_CONFIRM 0x0044
-#define CMD_802_11_HOST_SLEEP_ACTIVATE 0x0045
-#define CMD_802_11_BEACON_STOP 0x0049
-#define CMD_802_11_MAC_ADDRESS 0x004d
-#define CMD_802_11_LED_GPIO_CTRL 0x004e
-#define CMD_802_11_BAND_CONFIG 0x0058
-#define CMD_GSPI_BUS_CONFIG 0x005a
-#define CMD_802_11D_DOMAIN_INFO 0x005b
-#define CMD_802_11_KEY_MATERIAL 0x005e
-#define CMD_802_11_SLEEP_PARAMS 0x0066
-#define CMD_802_11_INACTIVITY_TIMEOUT 0x0067
-#define CMD_802_11_SLEEP_PERIOD 0x0068
-#define CMD_802_11_TPC_CFG 0x0072
-#define CMD_802_11_PA_CFG 0x0073
-#define CMD_802_11_FW_WAKE_METHOD 0x0074
-#define CMD_802_11_SUBSCRIBE_EVENT 0x0075
-#define CMD_802_11_RATE_ADAPT_RATESET 0x0076
-#define CMD_802_11_TX_RATE_QUERY 0x007f
-#define CMD_GET_TSF 0x0080
-#define CMD_BT_ACCESS 0x0087
-#define CMD_FWT_ACCESS 0x0095
-#define CMD_802_11_MONITOR_MODE 0x0098
-#define CMD_MESH_ACCESS 0x009b
-#define CMD_MESH_CONFIG_OLD 0x00a3
-#define CMD_MESH_CONFIG 0x00ac
-#define CMD_SET_BOOT2_VER 0x00a5
-#define CMD_FUNC_INIT 0x00a9
-#define CMD_FUNC_SHUTDOWN 0x00aa
-#define CMD_802_11_BEACON_CTRL 0x00b0
-
-/* For the IEEE Power Save */
-#define PS_MODE_ACTION_ENTER_PS 0x0030
-#define PS_MODE_ACTION_EXIT_PS 0x0031
-#define PS_MODE_ACTION_SLEEP_CONFIRMED 0x0034
-
-#define CMD_ENABLE_RSN 0x0001
-#define CMD_DISABLE_RSN 0x0000
-
-#define CMD_ACT_GET 0x0000
-#define CMD_ACT_SET 0x0001
-
-/* Define action or option for CMD_802_11_SET_WEP */
-#define CMD_ACT_ADD 0x0002
-#define CMD_ACT_REMOVE 0x0004
-
-#define CMD_TYPE_WEP_40_BIT 0x01
-#define CMD_TYPE_WEP_104_BIT 0x02
-
-#define CMD_NUM_OF_WEP_KEYS 4
-
-#define CMD_WEP_KEY_INDEX_MASK 0x3fff
-
-/* Define action or option for CMD_802_11_SCAN */
-#define CMD_BSS_TYPE_BSS 0x0001
-#define CMD_BSS_TYPE_IBSS 0x0002
-#define CMD_BSS_TYPE_ANY 0x0003
-
-/* Define action or option for CMD_802_11_SCAN */
-#define CMD_SCAN_TYPE_ACTIVE 0x0000
-#define CMD_SCAN_TYPE_PASSIVE 0x0001
-
-#define CMD_SCAN_RADIO_TYPE_BG 0
-
-#define CMD_SCAN_PROBE_DELAY_TIME 0
-
-/* Define action or option for CMD_MAC_CONTROL */
-#define CMD_ACT_MAC_RX_ON 0x0001
-#define CMD_ACT_MAC_TX_ON 0x0002
-#define CMD_ACT_MAC_LOOPBACK_ON 0x0004
-#define CMD_ACT_MAC_WEP_ENABLE 0x0008
-#define CMD_ACT_MAC_INT_ENABLE 0x0010
-#define CMD_ACT_MAC_MULTICAST_ENABLE 0x0020
-#define CMD_ACT_MAC_BROADCAST_ENABLE 0x0040
-#define CMD_ACT_MAC_PROMISCUOUS_ENABLE 0x0080
-#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100
-#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400
-
-/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
-#define CMD_SUBSCRIBE_RSSI_LOW 0x0001
-#define CMD_SUBSCRIBE_SNR_LOW 0x0002
-#define CMD_SUBSCRIBE_FAILCOUNT 0x0004
-#define CMD_SUBSCRIBE_BCNMISS 0x0008
-#define CMD_SUBSCRIBE_RSSI_HIGH 0x0010
-#define CMD_SUBSCRIBE_SNR_HIGH 0x0020
-
-#define RADIO_PREAMBLE_LONG 0x00
-#define RADIO_PREAMBLE_SHORT 0x02
-#define RADIO_PREAMBLE_AUTO 0x04
-
-/* Define action or option for CMD_802_11_RF_CHANNEL */
-#define CMD_OPT_802_11_RF_CHANNEL_GET 0x00
-#define CMD_OPT_802_11_RF_CHANNEL_SET 0x01
-
-/* Define action or option for CMD_802_11_DATA_RATE */
-#define CMD_ACT_SET_TX_AUTO 0x0000
-#define CMD_ACT_SET_TX_FIX_RATE 0x0001
-#define CMD_ACT_GET_TX_RATE 0x0002
-
-/* Options for CMD_802_11_FW_WAKE_METHOD */
-#define CMD_WAKE_METHOD_UNCHANGED 0x0000
-#define CMD_WAKE_METHOD_COMMAND_INT 0x0001
-#define CMD_WAKE_METHOD_GPIO 0x0002
-
-/* Object IDs for CMD_802_11_SNMP_MIB */
-#define SNMP_MIB_OID_BSS_TYPE 0x0000
-#define SNMP_MIB_OID_OP_RATE_SET 0x0001
-#define SNMP_MIB_OID_BEACON_PERIOD 0x0002 /* Reserved on v9+ */
-#define SNMP_MIB_OID_DTIM_PERIOD 0x0003 /* Reserved on v9+ */
-#define SNMP_MIB_OID_ASSOC_TIMEOUT 0x0004 /* Reserved on v9+ */
-#define SNMP_MIB_OID_RTS_THRESHOLD 0x0005
-#define SNMP_MIB_OID_SHORT_RETRY_LIMIT 0x0006
-#define SNMP_MIB_OID_LONG_RETRY_LIMIT 0x0007
-#define SNMP_MIB_OID_FRAG_THRESHOLD 0x0008
-#define SNMP_MIB_OID_11D_ENABLE 0x0009
-#define SNMP_MIB_OID_11H_ENABLE 0x000A
-
-/* Define action or option for CMD_BT_ACCESS */
-enum cmd_bt_access_opts {
- /* The bt commands start at 5 instead of 1 because the old dft commands
- * are mapped to 1-4. These old commands are no longer maintained and
- * should not be called.
- */
- CMD_ACT_BT_ACCESS_ADD = 5,
- CMD_ACT_BT_ACCESS_DEL,
- CMD_ACT_BT_ACCESS_LIST,
- CMD_ACT_BT_ACCESS_RESET,
- CMD_ACT_BT_ACCESS_SET_INVERT,
- CMD_ACT_BT_ACCESS_GET_INVERT
-};
-
-/* Define action or option for CMD_FWT_ACCESS */
-enum cmd_fwt_access_opts {
- CMD_ACT_FWT_ACCESS_ADD = 1,
- CMD_ACT_FWT_ACCESS_DEL,
- CMD_ACT_FWT_ACCESS_LOOKUP,
- CMD_ACT_FWT_ACCESS_LIST,
- CMD_ACT_FWT_ACCESS_LIST_ROUTE,
- CMD_ACT_FWT_ACCESS_LIST_NEIGHBOR,
- CMD_ACT_FWT_ACCESS_RESET,
- CMD_ACT_FWT_ACCESS_CLEANUP,
- CMD_ACT_FWT_ACCESS_TIME,
-};
-
-/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
-enum cmd_wol_cfg_opts {
- CMD_ACT_ACTION_NONE = 0,
- CMD_ACT_SET_WOL_RULE,
- CMD_ACT_GET_WOL_RULE,
- CMD_ACT_RESET_WOL_RULE,
-};
-
-/* Define action or option for CMD_MESH_ACCESS */
-enum cmd_mesh_access_opts {
- CMD_ACT_MESH_GET_TTL = 1,
- CMD_ACT_MESH_SET_TTL,
- CMD_ACT_MESH_GET_STATS,
- CMD_ACT_MESH_GET_ANYCAST,
- CMD_ACT_MESH_SET_ANYCAST,
- CMD_ACT_MESH_SET_LINK_COSTS,
- CMD_ACT_MESH_GET_LINK_COSTS,
- CMD_ACT_MESH_SET_BCAST_RATE,
- CMD_ACT_MESH_GET_BCAST_RATE,
- CMD_ACT_MESH_SET_RREQ_DELAY,
- CMD_ACT_MESH_GET_RREQ_DELAY,
- CMD_ACT_MESH_SET_ROUTE_EXP,
- CMD_ACT_MESH_GET_ROUTE_EXP,
- CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
- CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
- CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT = 17,
-};
-
-/* Define actions and types for CMD_MESH_CONFIG */
-enum cmd_mesh_config_actions {
- CMD_ACT_MESH_CONFIG_STOP = 0,
- CMD_ACT_MESH_CONFIG_START,
- CMD_ACT_MESH_CONFIG_SET,
- CMD_ACT_MESH_CONFIG_GET,
-};
-
-enum cmd_mesh_config_types {
- CMD_TYPE_MESH_SET_BOOTFLAG = 1,
- CMD_TYPE_MESH_SET_BOOTTIME,
- CMD_TYPE_MESH_SET_DEF_CHANNEL,
- CMD_TYPE_MESH_SET_MESH_IE,
- CMD_TYPE_MESH_GET_DEFAULTS,
- CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */
-};
-
-/* Card Event definition */
-#define MACREG_INT_CODE_TX_PPA_FREE 0
-#define MACREG_INT_CODE_TX_DMA_DONE 1
-#define MACREG_INT_CODE_LINK_LOST_W_SCAN 2
-#define MACREG_INT_CODE_LINK_LOST_NO_SCAN 3
-#define MACREG_INT_CODE_LINK_SENSED 4
-#define MACREG_INT_CODE_CMD_FINISHED 5
-#define MACREG_INT_CODE_MIB_CHANGED 6
-#define MACREG_INT_CODE_INIT_DONE 7
-#define MACREG_INT_CODE_DEAUTHENTICATED 8
-#define MACREG_INT_CODE_DISASSOCIATED 9
-#define MACREG_INT_CODE_PS_AWAKE 10
-#define MACREG_INT_CODE_PS_SLEEP 11
-#define MACREG_INT_CODE_MIC_ERR_MULTICAST 13
-#define MACREG_INT_CODE_MIC_ERR_UNICAST 14
-#define MACREG_INT_CODE_WM_AWAKE 15
-#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE 16
-#define MACREG_INT_CODE_ADHOC_BCN_LOST 17
-#define MACREG_INT_CODE_HOST_AWAKE 18
-#define MACREG_INT_CODE_STOP_TX 19
-#define MACREG_INT_CODE_START_TX 20
-#define MACREG_INT_CODE_CHANNEL_SWITCH 21
-#define MACREG_INT_CODE_MEASUREMENT_RDY 22
-#define MACREG_INT_CODE_WMM_CHANGE 23
-#define MACREG_INT_CODE_BG_SCAN_REPORT 24
-#define MACREG_INT_CODE_RSSI_LOW 25
-#define MACREG_INT_CODE_SNR_LOW 26
-#define MACREG_INT_CODE_MAX_FAIL 27
-#define MACREG_INT_CODE_RSSI_HIGH 28
-#define MACREG_INT_CODE_SNR_HIGH 29
-#define MACREG_INT_CODE_MESH_AUTO_STARTED 35
-#define MACREG_INT_CODE_FIRMWARE_READY 48
-
-
-/* 802.11-related definitions */
-
-/* TxPD descriptor */
-struct txpd {
- /* union to cope up with later FW revisions */
- union {
- /* Current Tx packet status */
- __le32 tx_status;
- struct {
- /* BSS type: client, AP, etc. */
- u8 bss_type;
- /* BSS number */
- u8 bss_num;
- /* Reserved */
- __le16 reserved;
- } bss;
- } u;
- /* Tx control */
- __le32 tx_control;
- __le32 tx_packet_location;
- /* Tx packet length */
- __le16 tx_packet_length;
- /* First 2 byte of destination MAC address */
- u8 tx_dest_addr_high[2];
- /* Last 4 byte of destination MAC address */
- u8 tx_dest_addr_low[4];
- /* Pkt Priority */
- u8 priority;
- /* Pkt Trasnit Power control */
- u8 powermgmt;
- /* Amount of time the packet has been queued (units = 2ms) */
- u8 pktdelay_2ms;
- /* reserved */
- u8 reserved1;
-} __packed;
-
-/* RxPD Descriptor */
-struct rxpd {
- /* union to cope up with later FW revisions */
- union {
- /* Current Rx packet status */
- __le16 status;
- struct {
- /* BSS type: client, AP, etc. */
- u8 bss_type;
- /* BSS number */
- u8 bss_num;
- } __packed bss;
- } __packed u;
-
- /* SNR */
- u8 snr;
-
- /* Tx control */
- u8 rx_control;
-
- /* Pkt length */
- __le16 pkt_len;
-
- /* Noise Floor */
- u8 nf;
-
- /* Rx Packet Rate */
- u8 rx_rate;
-
- /* Pkt addr */
- __le32 pkt_ptr;
-
- /* Next Rx RxPD addr */
- __le32 next_rxpd_ptr;
-
- /* Pkt Priority */
- u8 priority;
- u8 reserved[3];
-} __packed;
-
-struct cmd_header {
- __le16 command;
- __le16 size;
- __le16 seqnum;
- __le16 result;
-} __packed;
-
-/* Generic structure to hold all key types. */
-struct enc_key {
- u16 len;
- u16 flags; /* KEY_INFO_* from defs.h */
- u16 type; /* KEY_TYPE_* from defs.h */
- u8 key[32];
-};
-
-/* lbs_offset_value */
-struct lbs_offset_value {
- u32 offset;
- u32 value;
-} __packed;
-
-#define MAX_11D_TRIPLETS 83
-
-struct mrvl_ie_domain_param_set {
- struct mrvl_ie_header header;
-
- u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
- struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS];
-} __packed;
-
-struct cmd_ds_802_11d_domain_info {
- struct cmd_header hdr;
-
- __le16 action;
- struct mrvl_ie_domain_param_set domain;
-} __packed;
-
-/*
- * Define data structure for CMD_GET_HW_SPEC
- * This structure defines the response for the GET_HW_SPEC command
- */
-struct cmd_ds_get_hw_spec {
- struct cmd_header hdr;
-
- /* HW Interface version number */
- __le16 hwifversion;
- /* HW version number */
- __le16 version;
- /* Max number of TxPD FW can handle */
- __le16 nr_txpd;
- /* Max no of Multicast address */
- __le16 nr_mcast_adr;
- /* MAC address */
- u8 permanentaddr[6];
-
- /* region Code */
- __le16 regioncode;
-
- /* Number of antenna used */
- __le16 nr_antenna;
-
- /* FW release number, example 0x01030304 = 2.3.4p1 */
- __le32 fwrelease;
-
- /* Base Address of TxPD queue */
- __le32 wcb_base;
- /* Read Pointer of RxPd queue */
- __le32 rxpd_rdptr;
-
- /* Write Pointer of RxPd queue */
- __le32 rxpd_wrptr;
-
- /*FW/HW capability */
- __le32 fwcapinfo;
-} __packed;
-
-struct cmd_ds_802_11_subscribe_event {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 events;
-
- /* A TLV to the CMD_802_11_SUBSCRIBE_EVENT command can contain a
- * number of TLVs. From the v5.1 manual, those TLVs would add up to
- * 40 bytes. However, future firmware might add additional TLVs, so I
- * bump this up a bit.
- */
- uint8_t tlv[128];
-} __packed;
-
-/*
- * This scan handle Country Information IE(802.11d compliant)
- * Define data structure for CMD_802_11_SCAN
- */
-struct cmd_ds_802_11_scan {
- struct cmd_header hdr;
-
- uint8_t bsstype;
- uint8_t bssid[ETH_ALEN];
- uint8_t tlvbuffer[0];
-} __packed;
-
-struct cmd_ds_802_11_scan_rsp {
- struct cmd_header hdr;
-
- __le16 bssdescriptsize;
- uint8_t nr_sets;
- uint8_t bssdesc_and_tlvbuffer[0];
-} __packed;
-
-struct cmd_ds_802_11_get_log {
- struct cmd_header hdr;
-
- __le32 mcasttxframe;
- __le32 failed;
- __le32 retry;
- __le32 multiretry;
- __le32 framedup;
- __le32 rtssuccess;
- __le32 rtsfailure;
- __le32 ackfailure;
- __le32 rxfrag;
- __le32 mcastrxframe;
- __le32 fcserror;
- __le32 txframe;
- __le32 wepundecryptable;
-} __packed;
-
-struct cmd_ds_mac_control {
- struct cmd_header hdr;
- __le16 action;
- u16 reserved;
-} __packed;
-
-struct cmd_ds_mac_multicast_adr {
- struct cmd_header hdr;
- __le16 action;
- __le16 nr_of_adrs;
- u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
-} __packed;
-
-struct cmd_ds_802_11_authenticate {
- struct cmd_header hdr;
-
- u8 bssid[ETH_ALEN];
- u8 authtype;
- u8 reserved[10];
-} __packed;
-
-struct cmd_ds_802_11_deauthenticate {
- struct cmd_header hdr;
-
- u8 macaddr[ETH_ALEN];
- __le16 reasoncode;
-} __packed;
-
-struct cmd_ds_802_11_associate {
- struct cmd_header hdr;
-
- u8 bssid[6];
- __le16 capability;
- __le16 listeninterval;
- __le16 bcnperiod;
- u8 dtimperiod;
- u8 iebuf[512]; /* Enough for required and most optional IEs */
-} __packed;
-
-struct cmd_ds_802_11_associate_response {
- struct cmd_header hdr;
-
- __le16 capability;
- __le16 statuscode;
- __le16 aid;
- u8 iebuf[512];
-} __packed;
-
-struct cmd_ds_802_11_set_wep {
- struct cmd_header hdr;
-
- /* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
- __le16 action;
-
- /* key Index selected for Tx */
- __le16 keyindex;
-
- /* 40, 128bit or TXWEP */
- uint8_t keytype[4];
- uint8_t keymaterial[4][16];
-} __packed;
-
-struct cmd_ds_802_11_snmp_mib {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 oid;
- __le16 bufsize;
- u8 value[128];
-} __packed;
-
-struct cmd_ds_reg_access {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 offset;
- union {
- u8 bbp_rf; /* for BBP and RF registers */
- __le32 mac; /* for MAC registers */
- } value;
-} __packed;
-
-struct cmd_ds_802_11_radio_control {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 control;
-} __packed;
-
-struct cmd_ds_802_11_beacon_control {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 beacon_enable;
- __le16 beacon_period;
-} __packed;
-
-struct cmd_ds_802_11_sleep_params {
- struct cmd_header hdr;
-
- /* ACT_GET/ACT_SET */
- __le16 action;
-
- /* Sleep clock error in ppm */
- __le16 error;
-
- /* Wakeup offset in usec */
- __le16 offset;
-
- /* Clock stabilization time in usec */
- __le16 stabletime;
-
- /* control periodic calibration */
- uint8_t calcontrol;
-
- /* control the use of external sleep clock */
- uint8_t externalsleepclk;
-
- /* reserved field, should be set to zero */
- __le16 reserved;
-} __packed;
-
-struct cmd_ds_802_11_rf_channel {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 channel;
- __le16 rftype; /* unused */
- __le16 reserved; /* unused */
- u8 channellist[32]; /* unused */
-} __packed;
-
-struct cmd_ds_802_11_rssi {
- struct cmd_header hdr;
-
- /*
- * request: number of beacons (N) to average the SNR and NF over
- * response: SNR of most recent beacon
- */
- __le16 n_or_snr;
-
- /*
- * The following fields are only set in the response.
- * In the request these are reserved and should be set to 0.
- */
- __le16 nf; /* most recent beacon noise floor */
- __le16 avg_snr; /* average SNR weighted by N from request */
- __le16 avg_nf; /* average noise floor weighted by N from request */
-} __packed;
-
-struct cmd_ds_802_11_mac_address {
- struct cmd_header hdr;
-
- __le16 action;
- u8 macadd[ETH_ALEN];
-} __packed;
-
-struct cmd_ds_802_11_rf_tx_power {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 curlevel;
- s8 maxlevel;
- s8 minlevel;
-} __packed;
-
-/* MONITOR_MODE only exists in OLPC v5 firmware */
-struct cmd_ds_802_11_monitor_mode {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 mode;
-} __packed;
-
-struct cmd_ds_set_boot2_ver {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 version;
-} __packed;
-
-struct cmd_ds_802_11_fw_wake_method {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 method;
-} __packed;
-
-struct cmd_ds_802_11_ps_mode {
- struct cmd_header hdr;
-
- __le16 action;
-
- /*
- * Interval for keepalive in PS mode:
- * 0x0000 = don't change
- * 0x001E = firmware default
- * 0xFFFF = disable
- */
- __le16 nullpktinterval;
-
- /*
- * Number of DTIM intervals to wake up for:
- * 0 = don't change
- * 1 = firmware default
- * 5 = max
- */
- __le16 multipledtim;
-
- __le16 reserved;
- __le16 locallisteninterval;
-
- /*
- * AdHoc awake period (FW v9+ only):
- * 0 = don't change
- * 1 = always awake (IEEE standard behavior)
- * 2 - 31 = sleep for (n - 1) periods and awake for 1 period
- * 32 - 254 = invalid
- * 255 = sleep at each ATIM
- */
- __le16 adhoc_awake_period;
-} __packed;
-
-struct cmd_confirm_sleep {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 nullpktinterval;
- __le16 multipledtim;
- __le16 reserved;
- __le16 locallisteninterval;
-} __packed;
-
-struct cmd_ds_802_11_data_rate {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 reserved;
- u8 rates[MAX_RATES];
-} __packed;
-
-struct cmd_ds_802_11_rate_adapt_rateset {
- struct cmd_header hdr;
- __le16 action;
- __le16 enablehwauto;
- __le16 bitmap;
-} __packed;
-
-struct cmd_ds_802_11_ad_hoc_start {
- struct cmd_header hdr;
-
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- u8 bsstype;
- __le16 beaconperiod;
- u8 dtimperiod; /* Reserved on v9 and later */
- struct ieee_ie_ibss_param_set ibss;
- u8 reserved1[4];
- struct ieee_ie_ds_param_set ds;
- u8 reserved2[4];
- __le16 probedelay; /* Reserved on v9 and later */
- __le16 capability;
- u8 rates[MAX_RATES];
- u8 tlv_memory_size_pad[100];
-} __packed;
-
-struct cmd_ds_802_11_ad_hoc_result {
- struct cmd_header hdr;
-
- u8 pad[3];
- u8 bssid[ETH_ALEN];
-} __packed;
-
-struct adhoc_bssdesc {
- u8 bssid[ETH_ALEN];
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- u8 type;
- __le16 beaconperiod;
- u8 dtimperiod;
- __le64 timestamp;
- __le64 localtime;
- struct ieee_ie_ds_param_set ds;
- u8 reserved1[4];
- struct ieee_ie_ibss_param_set ibss;
- u8 reserved2[4];
- __le16 capability;
- u8 rates[MAX_RATES];
-
- /*
- * DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
- * Adhoc join command and will cause a binary layout mismatch with
- * the firmware
- */
-} __packed;
-
-struct cmd_ds_802_11_ad_hoc_join {
- struct cmd_header hdr;
-
- struct adhoc_bssdesc bss;
- __le16 failtimeout; /* Reserved on v9 and later */
- __le16 probedelay; /* Reserved on v9 and later */
-} __packed;
-
-struct cmd_ds_802_11_ad_hoc_stop {
- struct cmd_header hdr;
-} __packed;
-
-struct cmd_ds_802_11_enable_rsn {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 enable;
-} __packed;
-
-struct MrvlIEtype_keyParamSet {
- /* type ID */
- __le16 type;
-
- /* length of Payload */
- __le16 length;
-
- /* type of key: WEP=0, TKIP=1, AES=2 */
- __le16 keytypeid;
-
- /* key control Info specific to a keytypeid */
- __le16 keyinfo;
-
- /* length of key */
- __le16 keylen;
-
- /* key material of size keylen */
- u8 key[32];
-} __packed;
-
-#define MAX_WOL_RULES 16
-
-struct host_wol_rule {
- uint8_t rule_no;
- uint8_t rule_ops;
- __le16 sig_offset;
- __le16 sig_length;
- __le16 reserve;
- __be32 sig_mask;
- __be32 signature;
-} __packed;
-
-struct wol_config {
- uint8_t action;
- uint8_t pattern;
- uint8_t no_rules_in_cmd;
- uint8_t result;
- struct host_wol_rule rule[MAX_WOL_RULES];
-} __packed;
-
-struct cmd_ds_host_sleep {
- struct cmd_header hdr;
- __le32 criteria;
- uint8_t gpio;
- uint16_t gap;
- struct wol_config wol_conf;
-} __packed;
-
-
-
-struct cmd_ds_802_11_key_material {
- struct cmd_header hdr;
-
- __le16 action;
- struct MrvlIEtype_keyParamSet keyParamSet[2];
-} __packed;
-
-struct cmd_ds_802_11_eeprom_access {
- struct cmd_header hdr;
- __le16 action;
- __le16 offset;
- __le16 len;
- /* firmware says it returns a maximum of 20 bytes */
-#define LBS_EEPROM_READ_LEN 20
- u8 value[LBS_EEPROM_READ_LEN];
-} __packed;
-
-struct cmd_ds_802_11_tpc_cfg {
- struct cmd_header hdr;
-
- __le16 action;
- uint8_t enable;
- int8_t P0;
- int8_t P1;
- int8_t P2;
- uint8_t usesnr;
-} __packed;
-
-
-struct cmd_ds_802_11_pa_cfg {
- struct cmd_header hdr;
-
- __le16 action;
- uint8_t enable;
- int8_t P0;
- int8_t P1;
- int8_t P2;
-} __packed;
-
-
-struct cmd_ds_802_11_led_ctrl {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 numled;
- u8 data[256];
-} __packed;
-
-/* Automatic Frequency Control */
-struct cmd_ds_802_11_afc {
- struct cmd_header hdr;
-
- __le16 afc_auto;
- union {
- struct {
- __le16 threshold;
- __le16 period;
- };
- struct {
- __le16 timing_offset; /* signed */
- __le16 carrier_offset; /* signed */
- };
- };
-} __packed;
-
-struct cmd_tx_rate_query {
- __le16 txrate;
-} __packed;
-
-struct cmd_ds_get_tsf {
- __le64 tsfvalue;
-} __packed;
-
-struct cmd_ds_bt_access {
- struct cmd_header hdr;
-
- __le16 action;
- __le32 id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
-} __packed;
-
-struct cmd_ds_fwt_access {
- struct cmd_header hdr;
-
- __le16 action;
- __le32 id;
- u8 valid;
- u8 da[ETH_ALEN];
- u8 dir;
- u8 ra[ETH_ALEN];
- __le32 ssn;
- __le32 dsn;
- __le32 metric;
- u8 rate;
- u8 hopcount;
- u8 ttl;
- __le32 expiration;
- u8 sleepmode;
- __le32 snr;
- __le32 references;
- u8 prec[ETH_ALEN];
-} __packed;
-
-struct cmd_ds_mesh_config {
- struct cmd_header hdr;
-
- __le16 action;
- __le16 channel;
- __le16 type;
- __le16 length;
- u8 data[128]; /* last position reserved */
-} __packed;
-
-struct cmd_ds_mesh_access {
- struct cmd_header hdr;
-
- __le16 action;
- __le32 data[32]; /* last position reserved */
-} __packed;
-
-/* Number of stats counters returned by the firmware */
-#define MESH_STATS_NUM 8
-#endif
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
deleted file mode 100644
index f722e1a49..000000000
--- a/drivers/net/wireless/libertas/if_cs.c
+++ /dev/null
@@ -1,1000 +0,0 @@
-/*
-
- Driver for the Marvell 8385 based compact flash WLAN cards.
-
- (C) 2007 by Holger Schurig <hs4233@mail.mn-solutions.de>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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; see the file COPYING. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/moduleparam.h>
-#include <linux/firmware.h>
-#include <linux/netdevice.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include <linux/io.h>
-
-#define DRV_NAME "libertas_cs"
-
-#include "decl.h"
-#include "defs.h"
-#include "dev.h"
-
-
-/********************************************************************/
-/* Module stuff */
-/********************************************************************/
-
-MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
-MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
-MODULE_LICENSE("GPL");
-
-
-
-/********************************************************************/
-/* Data structures */
-/********************************************************************/
-
-struct if_cs_card {
- struct pcmcia_device *p_dev;
- struct lbs_private *priv;
- void __iomem *iobase;
- bool align_regs;
- u32 model;
-};
-
-
-enum {
- MODEL_UNKNOWN = 0x00,
- MODEL_8305 = 0x01,
- MODEL_8381 = 0x02,
- MODEL_8385 = 0x03
-};
-
-static const struct lbs_fw_table fw_table[] = {
- { MODEL_8305, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8305, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8381, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8381, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8385, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8385, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { 0, NULL, NULL }
-};
-/*(DEBLOBBED)*/
-
-
-/********************************************************************/
-/* Hardware access */
-/********************************************************************/
-
-/* This define enables wrapper functions which allow you
- to dump all register accesses. You normally won't this,
- except for development */
-/* #define DEBUG_IO */
-
-#ifdef DEBUG_IO
-static int debug_output = 0;
-#else
-/* This way the compiler optimizes the printk's away */
-#define debug_output 0
-#endif
-
-static inline unsigned int if_cs_read8(struct if_cs_card *card, uint reg)
-{
- unsigned int val = ioread8(card->iobase + reg);
- if (debug_output)
- printk(KERN_INFO "inb %08x<%02x\n", reg, val);
- return val;
-}
-static inline unsigned int if_cs_read16(struct if_cs_card *card, uint reg)
-{
- unsigned int val = ioread16(card->iobase + reg);
- if (debug_output)
- printk(KERN_INFO "inw %08x<%04x\n", reg, val);
- return val;
-}
-static inline void if_cs_read16_rep(
- struct if_cs_card *card,
- uint reg,
- void *buf,
- unsigned long count)
-{
- if (debug_output)
- printk(KERN_INFO "insw %08x<(0x%lx words)\n",
- reg, count);
- ioread16_rep(card->iobase + reg, buf, count);
-}
-
-static inline void if_cs_write8(struct if_cs_card *card, uint reg, u8 val)
-{
- if (debug_output)
- printk(KERN_INFO "outb %08x>%02x\n", reg, val);
- iowrite8(val, card->iobase + reg);
-}
-
-static inline void if_cs_write16(struct if_cs_card *card, uint reg, u16 val)
-{
- if (debug_output)
- printk(KERN_INFO "outw %08x>%04x\n", reg, val);
- iowrite16(val, card->iobase + reg);
-}
-
-static inline void if_cs_write16_rep(
- struct if_cs_card *card,
- uint reg,
- const void *buf,
- unsigned long count)
-{
- if (debug_output)
- printk(KERN_INFO "outsw %08x>(0x%lx words)\n",
- reg, count);
- iowrite16_rep(card->iobase + reg, buf, count);
-}
-
-
-/*
- * I know that polling/delaying is frowned upon. However, this procedure
- * with polling is needed while downloading the firmware. At this stage,
- * the hardware does unfortunately not create any interrupts.
- *
- * Fortunately, this function is never used once the firmware is in
- * the card. :-)
- *
- * As a reference, see the "Firmware Specification v5.1", page 18
- * and 19. I did not follow their suggested timing to the word,
- * but this works nice & fast anyway.
- */
-static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 reg)
-{
- int i;
-
- for (i = 0; i < 100000; i++) {
- u8 val = if_cs_read8(card, addr);
- if (val == reg)
- return 0;
- udelay(5);
- }
- return -ETIME;
-}
-
-
-
-/*
- * First the bitmasks for the host/card interrupt/status registers:
- */
-#define IF_CS_BIT_TX 0x0001
-#define IF_CS_BIT_RX 0x0002
-#define IF_CS_BIT_COMMAND 0x0004
-#define IF_CS_BIT_RESP 0x0008
-#define IF_CS_BIT_EVENT 0x0010
-#define IF_CS_BIT_MASK 0x001f
-
-
-
-/*
- * It's not really clear to me what the host status register is for. It
- * needs to be set almost in union with "host int cause". The following
- * bits from above are used:
- *
- * IF_CS_BIT_TX driver downloaded a data packet
- * IF_CS_BIT_RX driver got a data packet
- * IF_CS_BIT_COMMAND driver downloaded a command
- * IF_CS_BIT_RESP not used (has some meaning with powerdown)
- * IF_CS_BIT_EVENT driver read a host event
- */
-#define IF_CS_HOST_STATUS 0x00000000
-
-/*
- * With the host int cause register can the host (that is, Linux) cause
- * an interrupt in the firmware, to tell the firmware about those events:
- *
- * IF_CS_BIT_TX a data packet has been downloaded
- * IF_CS_BIT_RX a received data packet has retrieved
- * IF_CS_BIT_COMMAND a firmware block or a command has been downloaded
- * IF_CS_BIT_RESP not used (has some meaning with powerdown)
- * IF_CS_BIT_EVENT a host event (link lost etc) has been retrieved
- */
-#define IF_CS_HOST_INT_CAUSE 0x00000002
-
-/*
- * The host int mask register is used to enable/disable interrupt. However,
- * I have the suspicion that disabled interrupts are lost.
- */
-#define IF_CS_HOST_INT_MASK 0x00000004
-
-/*
- * Used to send or receive data packets:
- */
-#define IF_CS_WRITE 0x00000016
-#define IF_CS_WRITE_LEN 0x00000014
-#define IF_CS_READ 0x00000010
-#define IF_CS_READ_LEN 0x00000024
-
-/*
- * Used to send commands (and to send firmware block) and to
- * receive command responses:
- */
-#define IF_CS_CMD 0x0000001A
-#define IF_CS_CMD_LEN 0x00000018
-#define IF_CS_RESP 0x00000012
-#define IF_CS_RESP_LEN 0x00000030
-
-/*
- * The card status registers shows what the card/firmware actually
- * accepts:
- *
- * IF_CS_BIT_TX you may send a data packet
- * IF_CS_BIT_RX you may retrieve a data packet
- * IF_CS_BIT_COMMAND you may send a command
- * IF_CS_BIT_RESP you may retrieve a command response
- * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc)
- *
- * When reading this register several times, you will get back the same
- * results --- with one exception: the IF_CS_BIT_EVENT clear itself
- * automatically.
- *
- * Not that we don't rely on BIT_RX,_BIT_RESP or BIT_EVENT because
- * we handle this via the card int cause register.
- */
-#define IF_CS_CARD_STATUS 0x00000020
-#define IF_CS_CARD_STATUS_MASK 0x7f00
-
-/*
- * The card int cause register is used by the card/firmware to notify us
- * about the following events:
- *
- * IF_CS_BIT_TX a data packet has successfully been sentx
- * IF_CS_BIT_RX a data packet has been received and can be retrieved
- * IF_CS_BIT_COMMAND not used
- * IF_CS_BIT_RESP the firmware has a command response for us
- * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc)
- */
-#define IF_CS_CARD_INT_CAUSE 0x00000022
-
-/*
- * This is used to for handshaking with the card's bootloader/helper image
- * to synchronize downloading of firmware blocks.
- */
-#define IF_CS_SQ_READ_LOW 0x00000028
-#define IF_CS_SQ_HELPER_OK 0x10
-
-/*
- * The scratch register tells us ...
- *
- * IF_CS_SCRATCH_BOOT_OK the bootloader runs
- * IF_CS_SCRATCH_HELPER_OK the helper firmware already runs
- */
-#define IF_CS_SCRATCH 0x0000003F
-#define IF_CS_SCRATCH_BOOT_OK 0x00
-#define IF_CS_SCRATCH_HELPER_OK 0x5a
-
-/*
- * Used to detect ancient chips:
- */
-#define IF_CS_PRODUCT_ID 0x0000001C
-#define IF_CS_CF8385_B1_REV 0x12
-#define IF_CS_CF8381_B3_REV 0x04
-#define IF_CS_CF8305_B1_REV 0x03
-
-/*
- * Used to detect other cards than CF8385 since their revisions of silicon
- * doesn't match those from CF8385, eg. CF8381 B3 works with this driver.
- */
-#define CF8305_MANFID 0x02db
-#define CF8305_CARDID 0x8103
-#define CF8381_MANFID 0x02db
-#define CF8381_CARDID 0x6064
-#define CF8385_MANFID 0x02df
-#define CF8385_CARDID 0x8103
-
-/*
- * FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
- * that gets fixed. Currently there's no way to access it from the probe hook.
- */
-static inline u32 get_model(u16 manf_id, u16 card_id)
-{
- /* NOTE: keep in sync with if_cs_ids */
- if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID)
- return MODEL_8305;
- else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID)
- return MODEL_8381;
- else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID)
- return MODEL_8385;
- return MODEL_UNKNOWN;
-}
-
-/********************************************************************/
-/* I/O and interrupt handling */
-/********************************************************************/
-
-static inline void if_cs_enable_ints(struct if_cs_card *card)
-{
- lbs_deb_enter(LBS_DEB_CS);
- if_cs_write16(card, IF_CS_HOST_INT_MASK, 0);
-}
-
-static inline void if_cs_disable_ints(struct if_cs_card *card)
-{
- lbs_deb_enter(LBS_DEB_CS);
- if_cs_write16(card, IF_CS_HOST_INT_MASK, IF_CS_BIT_MASK);
-}
-
-/*
- * Called from if_cs_host_to_card to send a command to the hardware
- */
-static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
-{
- struct if_cs_card *card = (struct if_cs_card *)priv->card;
- int ret = -1;
- int loops = 0;
-
- lbs_deb_enter(LBS_DEB_CS);
- if_cs_disable_ints(card);
-
- /* Is hardware ready? */
- while (1) {
- u16 status = if_cs_read16(card, IF_CS_CARD_STATUS);
- if (status & IF_CS_BIT_COMMAND)
- break;
- if (++loops > 100) {
- netdev_err(priv->dev, "card not ready for commands\n");
- goto done;
- }
- mdelay(1);
- }
-
- if_cs_write16(card, IF_CS_CMD_LEN, nb);
-
- if_cs_write16_rep(card, IF_CS_CMD, buf, nb / 2);
- /* Are we supposed to transfer an odd amount of bytes? */
- if (nb & 1)
- if_cs_write8(card, IF_CS_CMD, buf[nb-1]);
-
- /* "Assert the download over interrupt command in the Host
- * status register" */
- if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
-
- /* "Assert the download over interrupt command in the Card
- * interrupt case register" */
- if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
- ret = 0;
-
-done:
- if_cs_enable_ints(card);
- lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
- return ret;
-}
-
-/*
- * Called from if_cs_host_to_card to send a data to the hardware
- */
-static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb)
-{
- struct if_cs_card *card = (struct if_cs_card *)priv->card;
- u16 status;
-
- lbs_deb_enter(LBS_DEB_CS);
- if_cs_disable_ints(card);
-
- status = if_cs_read16(card, IF_CS_CARD_STATUS);
- BUG_ON((status & IF_CS_BIT_TX) == 0);
-
- if_cs_write16(card, IF_CS_WRITE_LEN, nb);
-
- /* write even number of bytes, then odd byte if necessary */
- if_cs_write16_rep(card, IF_CS_WRITE, buf, nb / 2);
- if (nb & 1)
- if_cs_write8(card, IF_CS_WRITE, buf[nb-1]);
-
- if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX);
- if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX);
- if_cs_enable_ints(card);
-
- lbs_deb_leave(LBS_DEB_CS);
-}
-
-/*
- * Get the command result out of the card.
- */
-static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
-{
- unsigned long flags;
- int ret = -1;
- u16 status;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- /* is hardware ready? */
- status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
- if ((status & IF_CS_BIT_RESP) == 0) {
- netdev_err(priv->dev, "no cmd response in card\n");
- *len = 0;
- goto out;
- }
-
- *len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
- if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
- netdev_err(priv->dev,
- "card cmd buffer has invalid # of bytes (%d)\n",
- *len);
- goto out;
- }
-
- /* read even number of bytes, then odd byte if necessary */
- if_cs_read16_rep(priv->card, IF_CS_RESP, data, *len/sizeof(u16));
- if (*len & 1)
- data[*len-1] = if_cs_read8(priv->card, IF_CS_RESP);
-
- /* This is a workaround for a firmware that reports too much
- * bytes */
- *len -= 8;
- ret = 0;
-
- /* Clear this flag again */
- spin_lock_irqsave(&priv->driver_lock, flags);
- priv->dnld_sent = DNLD_RES_RECEIVED;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len);
- return ret;
-}
-
-static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
-{
- struct sk_buff *skb = NULL;
- u16 len;
- u8 *data;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- len = if_cs_read16(priv->card, IF_CS_READ_LEN);
- if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
- netdev_err(priv->dev,
- "card data buffer has invalid # of bytes (%d)\n",
- len);
- priv->dev->stats.rx_dropped++;
- goto dat_err;
- }
-
- skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + 2);
- if (!skb)
- goto out;
- skb_put(skb, len);
- skb_reserve(skb, 2);/* 16 byte align */
- data = skb->data;
-
- /* read even number of bytes, then odd byte if necessary */
- if_cs_read16_rep(priv->card, IF_CS_READ, data, len/sizeof(u16));
- if (len & 1)
- data[len-1] = if_cs_read8(priv->card, IF_CS_READ);
-
-dat_err:
- if_cs_write16(priv->card, IF_CS_HOST_STATUS, IF_CS_BIT_RX);
- if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_RX);
-
-out:
- lbs_deb_leave_args(LBS_DEB_CS, "ret %p", skb);
- return skb;
-}
-
-static irqreturn_t if_cs_interrupt(int irq, void *data)
-{
- struct if_cs_card *card = data;
- struct lbs_private *priv = card->priv;
- u16 cause;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- /* Ask card interrupt cause register if there is something for us */
- cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE);
- lbs_deb_cs("cause 0x%04x\n", cause);
-
- if (cause == 0) {
- /* Not for us */
- return IRQ_NONE;
- }
-
- if (cause == 0xffff) {
- /* Read in junk, the card has probably been removed */
- card->priv->surpriseremoved = 1;
- return IRQ_HANDLED;
- }
-
- if (cause & IF_CS_BIT_RX) {
- struct sk_buff *skb;
- lbs_deb_cs("rx packet\n");
- skb = if_cs_receive_data(priv);
- if (skb)
- lbs_process_rxed_packet(priv, skb);
- }
-
- if (cause & IF_CS_BIT_TX) {
- lbs_deb_cs("tx done\n");
- lbs_host_to_card_done(priv);
- }
-
- if (cause & IF_CS_BIT_RESP) {
- unsigned long flags;
- u8 i;
-
- lbs_deb_cs("cmd resp\n");
- spin_lock_irqsave(&priv->driver_lock, flags);
- i = (priv->resp_idx == 0) ? 1 : 0;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- BUG_ON(priv->resp_len[i]);
- if_cs_receive_cmdres(priv, priv->resp_buf[i],
- &priv->resp_len[i]);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- lbs_notify_command_response(priv, i);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- }
-
- if (cause & IF_CS_BIT_EVENT) {
- u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
- if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE,
- IF_CS_BIT_EVENT);
- lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8);
- }
-
- /* Clear interrupt cause */
- if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK);
-
- lbs_deb_leave(LBS_DEB_CS);
- return IRQ_HANDLED;
-}
-
-
-
-
-/********************************************************************/
-/* Firmware */
-/********************************************************************/
-
-/*
- * Tries to program the helper firmware.
- *
- * Return 0 on success
- */
-static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
-{
- int ret = 0;
- int sent = 0;
- u8 scratch;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- /*
- * This is the only place where an unaligned register access happens on
- * the CF8305 card, therefore for the sake of speed of the driver, we do
- * the alignment correction here.
- */
- if (card->align_regs)
- scratch = if_cs_read16(card, IF_CS_SCRATCH) >> 8;
- else
- scratch = if_cs_read8(card, IF_CS_SCRATCH);
-
- /* "If the value is 0x5a, the firmware is already
- * downloaded successfully"
- */
- if (scratch == IF_CS_SCRATCH_HELPER_OK)
- goto done;
-
- /* "If the value is != 00, it is invalid value of register */
- if (scratch != IF_CS_SCRATCH_BOOT_OK) {
- ret = -ENODEV;
- goto done;
- }
-
- lbs_deb_cs("helper size %td\n", fw->size);
-
- /* "Set the 5 bytes of the helper image to 0" */
- /* Not needed, this contains an ARM branch instruction */
-
- for (;;) {
- /* "the number of bytes to send is 256" */
- int count = 256;
- int remain = fw->size - sent;
-
- if (remain < count)
- count = remain;
-
- /*
- * "write the number of bytes to be sent to the I/O Command
- * write length register"
- */
- if_cs_write16(card, IF_CS_CMD_LEN, count);
-
- /* "write this to I/O Command port register as 16 bit writes */
- if (count)
- if_cs_write16_rep(card, IF_CS_CMD,
- &fw->data[sent],
- count >> 1);
-
- /*
- * "Assert the download over interrupt command in the Host
- * status register"
- */
- if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
-
- /*
- * "Assert the download over interrupt command in the Card
- * interrupt case register"
- */
- if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
-
- /*
- * "The host polls the Card Status register ... for 50 ms before
- * declaring a failure"
- */
- ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
- IF_CS_BIT_COMMAND);
- if (ret < 0) {
- pr_err("can't download helper at 0x%x, ret %d\n",
- sent, ret);
- goto done;
- }
-
- if (count == 0)
- break;
-
- sent += count;
- }
-
-done:
- lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
- return ret;
-}
-
-
-static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
-{
- int ret = 0;
- int retry = 0;
- int len = 0;
- int sent;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- lbs_deb_cs("fw size %td\n", fw->size);
-
- ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
- IF_CS_SQ_HELPER_OK);
- if (ret < 0) {
- pr_err("helper firmware doesn't answer\n");
- goto done;
- }
-
- for (sent = 0; sent < fw->size; sent += len) {
- len = if_cs_read16(card, IF_CS_SQ_READ_LOW);
- if (len & 1) {
- retry++;
- pr_info("odd, need to retry this firmware block\n");
- } else {
- retry = 0;
- }
-
- if (retry > 20) {
- pr_err("could not download firmware\n");
- ret = -ENODEV;
- goto done;
- }
- if (retry) {
- sent -= len;
- }
-
-
- if_cs_write16(card, IF_CS_CMD_LEN, len);
-
- if_cs_write16_rep(card, IF_CS_CMD,
- &fw->data[sent],
- (len+1) >> 1);
- if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
- if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
-
- ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
- IF_CS_BIT_COMMAND);
- if (ret < 0) {
- pr_err("can't download firmware at 0x%x\n", sent);
- goto done;
- }
- }
-
- ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
- if (ret < 0)
- pr_err("firmware download failed\n");
-
-done:
- lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
- return ret;
-}
-
-static void if_cs_prog_firmware(struct lbs_private *priv, int ret,
- const struct firmware *helper,
- const struct firmware *mainfw)
-{
- struct if_cs_card *card = priv->card;
-
- if (ret) {
- pr_err("failed to find firmware (%d)\n", ret);
- return;
- }
-
- /* Load the firmware */
- ret = if_cs_prog_helper(card, helper);
- if (ret == 0 && (card->model != MODEL_8305))
- ret = if_cs_prog_real(card, mainfw);
- if (ret)
- return;
-
- /* Now actually get the IRQ */
- ret = request_irq(card->p_dev->irq, if_cs_interrupt,
- IRQF_SHARED, DRV_NAME, card);
- if (ret) {
- pr_err("error in request_irq\n");
- return;
- }
-
- /*
- * Clear any interrupt cause that happened while sending
- * firmware/initializing card
- */
- if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
- if_cs_enable_ints(card);
-
- /* And finally bring the card up */
- priv->fw_ready = 1;
- if (lbs_start_card(priv) != 0) {
- pr_err("could not activate card\n");
- free_irq(card->p_dev->irq, card);
- }
-}
-
-
-/********************************************************************/
-/* Callback functions for libertas.ko */
-/********************************************************************/
-
-/* Send commands or data packets to the card */
-static int if_cs_host_to_card(struct lbs_private *priv,
- u8 type,
- u8 *buf,
- u16 nb)
-{
- int ret = -1;
-
- lbs_deb_enter_args(LBS_DEB_CS, "type %d, bytes %d", type, nb);
-
- switch (type) {
- case MVMS_DAT:
- priv->dnld_sent = DNLD_DATA_SENT;
- if_cs_send_data(priv, buf, nb);
- ret = 0;
- break;
- case MVMS_CMD:
- priv->dnld_sent = DNLD_CMD_SENT;
- ret = if_cs_send_cmd(priv, buf, nb);
- break;
- default:
- netdev_err(priv->dev, "%s: unsupported type %d\n",
- __func__, type);
- }
-
- lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
- return ret;
-}
-
-
-static void if_cs_release(struct pcmcia_device *p_dev)
-{
- struct if_cs_card *card = p_dev->priv;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- free_irq(p_dev->irq, card);
- pcmcia_disable_device(p_dev);
- if (card->iobase)
- ioport_unmap(card->iobase);
-
- lbs_deb_leave(LBS_DEB_CS);
-}
-
-
-static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
-{
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
-
- if (p_dev->resource[1]->end) {
- pr_err("wrong CIS (check number of IO windows)\n");
- return -ENODEV;
- }
-
- /* This reserves IO space but doesn't actually enable it */
- return pcmcia_request_io(p_dev);
-}
-
-static int if_cs_probe(struct pcmcia_device *p_dev)
-{
- int ret = -ENOMEM;
- unsigned int prod_id;
- struct lbs_private *priv;
- struct if_cs_card *card;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
- if (!card)
- goto out;
-
- card->p_dev = p_dev;
- p_dev->priv = card;
-
- p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-
- if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
- pr_err("error in pcmcia_loop_config\n");
- goto out1;
- }
-
- /*
- * Allocate an interrupt line. Note that this does not assign
- * a handler to the interrupt, unless the 'Handler' member of
- * the irq structure is initialized.
- */
- if (!p_dev->irq)
- goto out1;
-
- /* Initialize io access */
- card->iobase = ioport_map(p_dev->resource[0]->start,
- resource_size(p_dev->resource[0]));
- if (!card->iobase) {
- pr_err("error in ioport_map\n");
- ret = -EIO;
- goto out1;
- }
-
- ret = pcmcia_enable_device(p_dev);
- if (ret) {
- pr_err("error in pcmcia_enable_device\n");
- goto out2;
- }
-
- /* Finally, report what we've done */
- lbs_deb_cs("irq %d, io %pR", p_dev->irq, p_dev->resource[0]);
-
- /*
- * Most of the libertas cards can do unaligned register access, but some
- * weird ones cannot. That's especially true for the CF8305 card.
- */
- card->align_regs = false;
-
- card->model = get_model(p_dev->manf_id, p_dev->card_id);
- if (card->model == MODEL_UNKNOWN) {
- pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
- p_dev->manf_id, p_dev->card_id);
- ret = -ENODEV;
- goto out2;
- }
-
- /* Check if we have a current silicon */
- prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
- if (card->model == MODEL_8305) {
- card->align_regs = true;
- if (prod_id < IF_CS_CF8305_B1_REV) {
- pr_err("8305 rev B0 and older are not supported\n");
- ret = -ENODEV;
- goto out2;
- }
- }
-
- if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
- pr_err("8381 rev B2 and older are not supported\n");
- ret = -ENODEV;
- goto out2;
- }
-
- if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
- pr_err("8385 rev B0 and older are not supported\n");
- ret = -ENODEV;
- goto out2;
- }
-
- /* Make this card known to the libertas driver */
- priv = lbs_add_card(card, &p_dev->dev);
- if (!priv) {
- ret = -ENOMEM;
- goto out2;
- }
-
- /* Set up fields in lbs_private */
- card->priv = priv;
- priv->card = card;
- priv->hw_host_to_card = if_cs_host_to_card;
- priv->enter_deep_sleep = NULL;
- priv->exit_deep_sleep = NULL;
- priv->reset_deep_sleep_wakeup = NULL;
-
- /* Get firmware */
- ret = lbs_get_firmware_async(priv, &p_dev->dev, card->model, fw_table,
- if_cs_prog_firmware);
- if (ret) {
- pr_err("failed to find firmware (%d)\n", ret);
- goto out3;
- }
-
- goto out;
-
-out3:
- lbs_remove_card(priv);
-out2:
- ioport_unmap(card->iobase);
-out1:
- pcmcia_disable_device(p_dev);
-out:
- lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
- return ret;
-}
-
-
-static void if_cs_detach(struct pcmcia_device *p_dev)
-{
- struct if_cs_card *card = p_dev->priv;
-
- lbs_deb_enter(LBS_DEB_CS);
-
- lbs_stop_card(card->priv);
- lbs_remove_card(card->priv);
- if_cs_disable_ints(card);
- if_cs_release(p_dev);
- kfree(card);
-
- lbs_deb_leave(LBS_DEB_CS);
-}
-
-
-
-/********************************************************************/
-/* Module initialization */
-/********************************************************************/
-
-static const struct pcmcia_device_id if_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
- PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
- PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
- /* NOTE: keep in sync with get_model() */
- PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
-
-static struct pcmcia_driver lbs_driver = {
- .owner = THIS_MODULE,
- .name = DRV_NAME,
- .probe = if_cs_probe,
- .remove = if_cs_detach,
- .id_table = if_cs_ids,
-};
-module_pcmcia_driver(lbs_driver);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
deleted file mode 100644
index 42d80538a..000000000
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ /dev/null
@@ -1,1440 +0,0 @@
-/*
- * linux/drivers/net/wireless/libertas/if_sdio.c
- *
- * Copyright 2007-2008 Pierre Ossman
- *
- * Inspired by if_cs.c, Copyright 2007 Holger Schurig
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This hardware has more or less no CMD53 support, so all registers
- * must be accessed using sdio_readb()/sdio_writeb().
- *
- * Transfers must be in one transaction or the firmware goes bonkers.
- * This means that the transfer must either be small enough to do a
- * byte based transfer or it must be padded to a multiple of the
- * current block size.
- *
- * As SDIO is still new to the kernel, it is unfortunately common with
- * bugs in the host controllers related to that. One such bug is that
- * controllers cannot do transfers that aren't a multiple of 4 bytes.
- * If you don't have time to fix the host controller driver, you can
- * work around the problem by modifying if_sdio_host_to_card() and
- * if_sdio_card_to_host() to pad the data.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/firmware.h>
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/host.h>
-#include <linux/pm_runtime.h>
-
-#include "host.h"
-#include "decl.h"
-#include "defs.h"
-#include "dev.h"
-#include "cmd.h"
-#include "if_sdio.h"
-
-static void if_sdio_interrupt(struct sdio_func *func);
-
-/* The if_sdio_remove() callback function is called when
- * user removes this module from kernel space or ejects
- * the card from the slot. The driver handles these 2 cases
- * differently for SD8688 combo chip.
- * If the user is removing the module, the FUNC_SHUTDOWN
- * command for SD8688 is sent to the firmware.
- * If the card is removed, there is no need to send this command.
- *
- * The variable 'user_rmmod' is used to distinguish these two
- * scenarios. This flag is initialized as FALSE in case the card
- * is removed, and will be set to TRUE for module removal when
- * module_exit function is called.
- */
-static u8 user_rmmod;
-
-static const struct sdio_device_id if_sdio_ids[] = {
- { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
- SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
- { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
- SDIO_DEVICE_ID_MARVELL_8688WLAN) },
- { /* end: all zeroes */ },
-};
-
-MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
-
-#define MODEL_8385 0x04
-#define MODEL_8686 0x0b
-#define MODEL_8688 0x10
-
-static const struct lbs_fw_table fw_table[] = {
- { MODEL_8385, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8385, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8686, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8686, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8686, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8688, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8688, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { 0, NULL, NULL }
-};
-/*(DEBLOBBED)*/
-
-struct if_sdio_packet {
- struct if_sdio_packet *next;
- u16 nb;
- u8 buffer[0] __attribute__((aligned(4)));
-};
-
-struct if_sdio_card {
- struct sdio_func *func;
- struct lbs_private *priv;
-
- int model;
- unsigned long ioport;
- unsigned int scratch_reg;
- bool started;
- wait_queue_head_t pwron_waitq;
-
- u8 buffer[65536] __attribute__((aligned(4)));
-
- spinlock_t lock;
- struct if_sdio_packet *packets;
-
- struct workqueue_struct *workqueue;
- struct work_struct packet_worker;
-
- u8 rx_unit;
-};
-
-static void if_sdio_finish_power_on(struct if_sdio_card *card);
-static int if_sdio_power_off(struct if_sdio_card *card);
-
-/********************************************************************/
-/* I/O */
-/********************************************************************/
-
-/*
- * For SD8385/SD8686, this function reads firmware status after
- * the image is downloaded, or reads RX packet length when
- * interrupt (with IF_SDIO_H_INT_UPLD bit set) is received.
- * For SD8688, this function reads firmware status only.
- */
-static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
-{
- int ret;
- u16 scratch;
-
- scratch = sdio_readb(card->func, card->scratch_reg, &ret);
- if (!ret)
- scratch |= sdio_readb(card->func, card->scratch_reg + 1,
- &ret) << 8;
-
- if (err)
- *err = ret;
-
- if (ret)
- return 0xffff;
-
- return scratch;
-}
-
-static u8 if_sdio_read_rx_unit(struct if_sdio_card *card)
-{
- int ret;
- u8 rx_unit;
-
- rx_unit = sdio_readb(card->func, IF_SDIO_RX_UNIT, &ret);
-
- if (ret)
- rx_unit = 0;
-
- return rx_unit;
-}
-
-static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
-{
- int ret;
- u16 rx_len;
-
- switch (card->model) {
- case MODEL_8385:
- case MODEL_8686:
- rx_len = if_sdio_read_scratch(card, &ret);
- break;
- case MODEL_8688:
- default: /* for newer chipsets */
- rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
- if (!ret)
- rx_len <<= card->rx_unit;
- else
- rx_len = 0xffff; /* invalid length */
-
- break;
- }
-
- if (err)
- *err = ret;
-
- return rx_len;
-}
-
-static int if_sdio_handle_cmd(struct if_sdio_card *card,
- u8 *buffer, unsigned size)
-{
- struct lbs_private *priv = card->priv;
- int ret;
- unsigned long flags;
- u8 i;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- if (size > LBS_CMD_BUFFER_SIZE) {
- lbs_deb_sdio("response packet too large (%d bytes)\n",
- (int)size);
- ret = -E2BIG;
- goto out;
- }
-
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- i = (priv->resp_idx == 0) ? 1 : 0;
- BUG_ON(priv->resp_len[i]);
- priv->resp_len[i] = size;
- memcpy(priv->resp_buf[i], buffer, size);
- lbs_notify_command_response(priv, i);
-
- spin_unlock_irqrestore(&card->priv->driver_lock, flags);
-
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
- return ret;
-}
-
-static int if_sdio_handle_data(struct if_sdio_card *card,
- u8 *buffer, unsigned size)
-{
- int ret;
- struct sk_buff *skb;
- char *data;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- if (size > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
- lbs_deb_sdio("response packet too large (%d bytes)\n",
- (int)size);
- ret = -E2BIG;
- goto out;
- }
-
- skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + NET_IP_ALIGN);
- if (!skb) {
- ret = -ENOMEM;
- goto out;
- }
-
- skb_reserve(skb, NET_IP_ALIGN);
-
- data = skb_put(skb, size);
-
- memcpy(data, buffer, size);
-
- lbs_process_rxed_packet(card->priv, skb);
-
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
- return ret;
-}
-
-static int if_sdio_handle_event(struct if_sdio_card *card,
- u8 *buffer, unsigned size)
-{
- int ret;
- u32 event;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- if (card->model == MODEL_8385) {
- event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
- if (ret)
- goto out;
-
- /* right shift 3 bits to get the event id */
- event >>= 3;
- } else {
- if (size < 4) {
- lbs_deb_sdio("event packet too small (%d bytes)\n",
- (int)size);
- ret = -EINVAL;
- goto out;
- }
- event = buffer[3] << 24;
- event |= buffer[2] << 16;
- event |= buffer[1] << 8;
- event |= buffer[0] << 0;
- }
-
- lbs_queue_event(card->priv, event & 0xFF);
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
- return ret;
-}
-
-static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
-{
- u8 status;
- unsigned long timeout;
- int ret = 0;
-
- timeout = jiffies + HZ;
- while (1) {
- status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
- if (ret)
- return ret;
- if ((status & condition) == condition)
- break;
- if (time_after(jiffies, timeout))
- return -ETIMEDOUT;
- mdelay(1);
- }
- return ret;
-}
-
-static int if_sdio_card_to_host(struct if_sdio_card *card)
-{
- int ret;
- u16 size, type, chunk;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- size = if_sdio_read_rx_len(card, &ret);
- if (ret)
- goto out;
-
- if (size < 4) {
- lbs_deb_sdio("invalid packet size (%d bytes) from firmware\n",
- (int)size);
- ret = -EINVAL;
- goto out;
- }
-
- ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
- if (ret)
- goto out;
-
- /*
- * The transfer must be in one transaction or the firmware
- * goes suicidal. There's no way to guarantee that for all
- * controllers, but we can at least try.
- */
- chunk = sdio_align_size(card->func, size);
-
- ret = sdio_readsb(card->func, card->buffer, card->ioport, chunk);
- if (ret)
- goto out;
-
- chunk = card->buffer[0] | (card->buffer[1] << 8);
- type = card->buffer[2] | (card->buffer[3] << 8);
-
- lbs_deb_sdio("packet of type %d and size %d bytes\n",
- (int)type, (int)chunk);
-
- if (chunk > size) {
- lbs_deb_sdio("packet fragment (%d > %d)\n",
- (int)chunk, (int)size);
- ret = -EINVAL;
- goto out;
- }
-
- if (chunk < size) {
- lbs_deb_sdio("packet fragment (%d < %d)\n",
- (int)chunk, (int)size);
- }
-
- switch (type) {
- case MVMS_CMD:
- ret = if_sdio_handle_cmd(card, card->buffer + 4, chunk - 4);
- if (ret)
- goto out;
- break;
- case MVMS_DAT:
- ret = if_sdio_handle_data(card, card->buffer + 4, chunk - 4);
- if (ret)
- goto out;
- break;
- case MVMS_EVENT:
- ret = if_sdio_handle_event(card, card->buffer + 4, chunk - 4);
- if (ret)
- goto out;
- break;
- default:
- lbs_deb_sdio("invalid type (%d) from firmware\n",
- (int)type);
- ret = -EINVAL;
- goto out;
- }
-
-out:
- if (ret)
- pr_err("problem fetching packet from firmware\n");
-
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
- return ret;
-}
-
-static void if_sdio_host_to_card_worker(struct work_struct *work)
-{
- struct if_sdio_card *card;
- struct if_sdio_packet *packet;
- int ret;
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- card = container_of(work, struct if_sdio_card, packet_worker);
-
- while (1) {
- spin_lock_irqsave(&card->lock, flags);
- packet = card->packets;
- if (packet)
- card->packets = packet->next;
- spin_unlock_irqrestore(&card->lock, flags);
-
- if (!packet)
- break;
-
- sdio_claim_host(card->func);
-
- ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
- if (ret == 0) {
- ret = sdio_writesb(card->func, card->ioport,
- packet->buffer, packet->nb);
- }
-
- if (ret)
- pr_err("error %d sending packet to firmware\n", ret);
-
- sdio_release_host(card->func);
-
- kfree(packet);
- }
-
- lbs_deb_leave(LBS_DEB_SDIO);
-}
-
-/********************************************************************/
-/* Firmware */
-/********************************************************************/
-
-#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
-
-static int if_sdio_prog_helper(struct if_sdio_card *card,
- const struct firmware *fw)
-{
- int ret;
- unsigned long timeout;
- u8 *chunk_buffer;
- u32 chunk_size;
- const u8 *firmware;
- size_t size;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- chunk_buffer = kzalloc(64, GFP_KERNEL);
- if (!chunk_buffer) {
- ret = -ENOMEM;
- goto out;
- }
-
- sdio_claim_host(card->func);
-
- ret = sdio_set_block_size(card->func, 32);
- if (ret)
- goto release;
-
- firmware = fw->data;
- size = fw->size;
-
- while (size) {
- ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
- if (ret)
- goto release;
-
- /* On some platforms (like Davinci) the chip needs more time
- * between helper blocks.
- */
- mdelay(2);
-
- chunk_size = min_t(size_t, size, 60);
-
- *((__le32*)chunk_buffer) = cpu_to_le32(chunk_size);
- memcpy(chunk_buffer + 4, firmware, chunk_size);
-/*
- lbs_deb_sdio("sending %d bytes chunk\n", chunk_size);
-*/
- ret = sdio_writesb(card->func, card->ioport,
- chunk_buffer, 64);
- if (ret)
- goto release;
-
- firmware += chunk_size;
- size -= chunk_size;
- }
-
- /* an empty block marks the end of the transfer */
- memset(chunk_buffer, 0, 4);
- ret = sdio_writesb(card->func, card->ioport, chunk_buffer, 64);
- if (ret)
- goto release;
-
- lbs_deb_sdio("waiting for helper to boot...\n");
-
- /* wait for the helper to boot by looking at the size register */
- timeout = jiffies + HZ;
- while (1) {
- u16 req_size;
-
- req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
- if (ret)
- goto release;
-
- req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8;
- if (ret)
- goto release;
-
- if (req_size != 0)
- break;
-
- if (time_after(jiffies, timeout)) {
- ret = -ETIMEDOUT;
- goto release;
- }
-
- msleep(10);
- }
-
- ret = 0;
-
-release:
- sdio_release_host(card->func);
- kfree(chunk_buffer);
-
-out:
- if (ret)
- pr_err("failed to load helper firmware\n");
-
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
- return ret;
-}
-
-static int if_sdio_prog_real(struct if_sdio_card *card,
- const struct firmware *fw)
-{
- int ret;
- unsigned long timeout;
- u8 *chunk_buffer;
- u32 chunk_size;
- const u8 *firmware;
- size_t size, req_size;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- chunk_buffer = kzalloc(512, GFP_KERNEL);
- if (!chunk_buffer) {
- ret = -ENOMEM;
- goto out;
- }
-
- sdio_claim_host(card->func);
-
- ret = sdio_set_block_size(card->func, 32);
- if (ret)
- goto release;
-
- firmware = fw->data;
- size = fw->size;
-
- while (size) {
- timeout = jiffies + HZ;
- while (1) {
- ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
- if (ret)
- goto release;
-
- req_size = sdio_readb(card->func, IF_SDIO_RD_BASE,
- &ret);
- if (ret)
- goto release;
-
- req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1,
- &ret) << 8;
- if (ret)
- goto release;
-
- /*
- * For SD8688 wait until the length is not 0, 1 or 2
- * before downloading the first FW block,
- * since BOOT code writes the register to indicate the
- * helper/FW download winner,
- * the value could be 1 or 2 (Func1 or Func2).
- */
- if ((size != fw->size) || (req_size > 2))
- break;
- if (time_after(jiffies, timeout)) {
- ret = -ETIMEDOUT;
- goto release;
- }
- mdelay(1);
- }
-
-/*
- lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size);
-*/
- if (req_size == 0) {
- lbs_deb_sdio("firmware helper gave up early\n");
- ret = -EIO;
- goto release;
- }
-
- if (req_size & 0x01) {
- lbs_deb_sdio("firmware helper signalled error\n");
- ret = -EIO;
- goto release;
- }
-
- if (req_size > size)
- req_size = size;
-
- while (req_size) {
- chunk_size = min_t(size_t, req_size, 512);
-
- memcpy(chunk_buffer, firmware, chunk_size);
-/*
- lbs_deb_sdio("sending %d bytes (%d bytes) chunk\n",
- chunk_size, (chunk_size + 31) / 32 * 32);
-*/
- ret = sdio_writesb(card->func, card->ioport,
- chunk_buffer, roundup(chunk_size, 32));
- if (ret)
- goto release;
-
- firmware += chunk_size;
- size -= chunk_size;
- req_size -= chunk_size;
- }
- }
-
- ret = 0;
-
- lbs_deb_sdio("waiting for firmware to boot...\n");
-
- /* wait for the firmware to boot */
- timeout = jiffies + HZ;
- while (1) {
- u16 scratch;
-
- scratch = if_sdio_read_scratch(card, &ret);
- if (ret)
- goto release;
-
- if (scratch == IF_SDIO_FIRMWARE_OK)
- break;
-
- if (time_after(jiffies, timeout)) {
- ret = -ETIMEDOUT;
- goto release;
- }
-
- msleep(10);
- }
-
- ret = 0;
-
-release:
- sdio_release_host(card->func);
- kfree(chunk_buffer);
-
-out:
- if (ret)
- pr_err("failed to load firmware\n");
-
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
- return ret;
-}
-
-static void if_sdio_do_prog_firmware(struct lbs_private *priv, int ret,
- const struct firmware *helper,
- const struct firmware *mainfw)
-{
- struct if_sdio_card *card = priv->card;
-
- if (ret) {
- pr_err("failed to find firmware (%d)\n", ret);
- return;
- }
-
- ret = if_sdio_prog_helper(card, helper);
- if (ret)
- return;
-
- lbs_deb_sdio("Helper firmware loaded\n");
-
- ret = if_sdio_prog_real(card, mainfw);
- if (ret)
- return;
-
- lbs_deb_sdio("Firmware loaded\n");
- if_sdio_finish_power_on(card);
-}
-
-static int if_sdio_prog_firmware(struct if_sdio_card *card)
-{
- int ret;
- u16 scratch;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- /*
- * Disable interrupts
- */
- sdio_claim_host(card->func);
- sdio_writeb(card->func, 0x00, IF_SDIO_H_INT_MASK, &ret);
- sdio_release_host(card->func);
-
- sdio_claim_host(card->func);
- scratch = if_sdio_read_scratch(card, &ret);
- sdio_release_host(card->func);
-
- lbs_deb_sdio("firmware status = %#x\n", scratch);
- lbs_deb_sdio("scratch ret = %d\n", ret);
-
- if (ret)
- goto out;
-
-
- /*
- * The manual clearly describes that FEDC is the right code to use
- * to detect firmware presence, but for SD8686 it is not that simple.
- * Scratch is also used to store the RX packet length, so we lose
- * the FEDC value early on. So we use a non-zero check in order
- * to validate firmware presence.
- * Additionally, the SD8686 in the Gumstix always has the high scratch
- * bit set, even when the firmware is not loaded. So we have to
- * exclude that from the test.
- */
- if (scratch == IF_SDIO_FIRMWARE_OK) {
- lbs_deb_sdio("firmware already loaded\n");
- if_sdio_finish_power_on(card);
- return 0;
- } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) {
- lbs_deb_sdio("firmware may be running\n");
- if_sdio_finish_power_on(card);
- return 0;
- }
-
- ret = lbs_get_firmware_async(card->priv, &card->func->dev, card->model,
- fw_table, if_sdio_do_prog_firmware);
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
- return ret;
-}
-
-/********************************************************************/
-/* Power management */
-/********************************************************************/
-
-/* Finish power on sequence (after firmware is loaded) */
-static void if_sdio_finish_power_on(struct if_sdio_card *card)
-{
- struct sdio_func *func = card->func;
- struct lbs_private *priv = card->priv;
- int ret;
-
- sdio_claim_host(func);
- sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
-
- /*
- * Get rx_unit if the chip is SD8688 or newer.
- * SD8385 & SD8686 do not have rx_unit.
- */
- if ((card->model != MODEL_8385)
- && (card->model != MODEL_8686))
- card->rx_unit = if_sdio_read_rx_unit(card);
- else
- card->rx_unit = 0;
-
- /*
- * Set up the interrupt handler late.
- *
- * If we set it up earlier, the (buggy) hardware generates a spurious
- * interrupt, even before the interrupt has been enabled, with
- * CCCR_INTx = 0.
- *
- * We register the interrupt handler late so that we can handle any
- * spurious interrupts, and also to avoid generation of that known
- * spurious interrupt in the first place.
- */
- ret = sdio_claim_irq(func, if_sdio_interrupt);
- if (ret)
- goto release;
-
- /*
- * Enable interrupts now that everything is set up
- */
- sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
- if (ret)
- goto release_irq;
-
- sdio_release_host(func);
-
- /* Set fw_ready before queuing any commands so that
- * lbs_thread won't block from sending them to firmware.
- */
- priv->fw_ready = 1;
-
- /*
- * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
- */
- if (card->model == MODEL_8688) {
- struct cmd_header cmd;
-
- memset(&cmd, 0, sizeof(cmd));
-
- lbs_deb_sdio("send function INIT command\n");
- if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
- lbs_cmd_copyback, (unsigned long) &cmd))
- netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
- }
-
- wake_up(&card->pwron_waitq);
-
- if (!card->started) {
- ret = lbs_start_card(priv);
- if_sdio_power_off(card);
- if (ret == 0) {
- card->started = true;
- /* Tell PM core that we don't need the card to be
- * powered now */
- pm_runtime_put(&func->dev);
- }
- }
-
- return;
-
-release_irq:
- sdio_release_irq(func);
-release:
- sdio_release_host(func);
-}
-
-static int if_sdio_power_on(struct if_sdio_card *card)
-{
- struct sdio_func *func = card->func;
- struct mmc_host *host = func->card->host;
- int ret;
-
- sdio_claim_host(func);
-
- ret = sdio_enable_func(func);
- if (ret)
- goto release;
-
- /* For 1-bit transfers to the 8686 model, we need to enable the
- * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
- * bit to allow access to non-vendor registers. */
- if ((card->model == MODEL_8686) &&
- (host->caps & MMC_CAP_SDIO_IRQ) &&
- (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
- u8 reg;
-
- func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
- reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
- if (ret)
- goto disable;
-
- reg |= SDIO_BUS_ECSI;
- sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
- if (ret)
- goto disable;
- }
-
- card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
- if (ret)
- goto disable;
-
- card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
- if (ret)
- goto disable;
-
- card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
- if (ret)
- goto disable;
-
- sdio_release_host(func);
- ret = if_sdio_prog_firmware(card);
- if (ret) {
- sdio_claim_host(func);
- goto disable;
- }
-
- return 0;
-
-disable:
- sdio_disable_func(func);
-release:
- sdio_release_host(func);
- return ret;
-}
-
-static int if_sdio_power_off(struct if_sdio_card *card)
-{
- struct sdio_func *func = card->func;
- struct lbs_private *priv = card->priv;
-
- priv->fw_ready = 0;
-
- sdio_claim_host(func);
- sdio_release_irq(func);
- sdio_disable_func(func);
- sdio_release_host(func);
- return 0;
-}
-
-
-/*******************************************************************/
-/* Libertas callbacks */
-/*******************************************************************/
-
-static int if_sdio_host_to_card(struct lbs_private *priv,
- u8 type, u8 *buf, u16 nb)
-{
- int ret;
- struct if_sdio_card *card;
- struct if_sdio_packet *packet, *cur;
- u16 size;
- unsigned long flags;
-
- lbs_deb_enter_args(LBS_DEB_SDIO, "type %d, bytes %d", type, nb);
-
- card = priv->card;
-
- if (nb > (65536 - sizeof(struct if_sdio_packet) - 4)) {
- ret = -EINVAL;
- goto out;
- }
-
- /*
- * The transfer must be in one transaction or the firmware
- * goes suicidal. There's no way to guarantee that for all
- * controllers, but we can at least try.
- */
- size = sdio_align_size(card->func, nb + 4);
-
- packet = kzalloc(sizeof(struct if_sdio_packet) + size,
- GFP_ATOMIC);
- if (!packet) {
- ret = -ENOMEM;
- goto out;
- }
-
- packet->next = NULL;
- packet->nb = size;
-
- /*
- * SDIO specific header.
- */
- packet->buffer[0] = (nb + 4) & 0xff;
- packet->buffer[1] = ((nb + 4) >> 8) & 0xff;
- packet->buffer[2] = type;
- packet->buffer[3] = 0;
-
- memcpy(packet->buffer + 4, buf, nb);
-
- spin_lock_irqsave(&card->lock, flags);
-
- if (!card->packets)
- card->packets = packet;
- else {
- cur = card->packets;
- while (cur->next)
- cur = cur->next;
- cur->next = packet;
- }
-
- switch (type) {
- case MVMS_CMD:
- priv->dnld_sent = DNLD_CMD_SENT;
- break;
- case MVMS_DAT:
- priv->dnld_sent = DNLD_DATA_SENT;
- break;
- default:
- lbs_deb_sdio("unknown packet type %d\n", (int)type);
- }
-
- spin_unlock_irqrestore(&card->lock, flags);
-
- queue_work(card->workqueue, &card->packet_worker);
-
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
- return ret;
-}
-
-static int if_sdio_enter_deep_sleep(struct lbs_private *priv)
-{
- int ret = -1;
- struct cmd_header cmd;
-
- memset(&cmd, 0, sizeof(cmd));
-
- lbs_deb_sdio("send DEEP_SLEEP command\n");
- ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
- lbs_cmd_copyback, (unsigned long) &cmd);
- if (ret)
- netdev_err(priv->dev, "DEEP_SLEEP cmd failed\n");
-
- mdelay(200);
- return ret;
-}
-
-static int if_sdio_exit_deep_sleep(struct lbs_private *priv)
-{
- struct if_sdio_card *card = priv->card;
- int ret = -1;
-
- lbs_deb_enter(LBS_DEB_SDIO);
- sdio_claim_host(card->func);
-
- sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
- if (ret)
- netdev_err(priv->dev, "sdio_writeb failed!\n");
-
- sdio_release_host(card->func);
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
- return ret;
-}
-
-static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv)
-{
- struct if_sdio_card *card = priv->card;
- int ret = -1;
-
- lbs_deb_enter(LBS_DEB_SDIO);
- sdio_claim_host(card->func);
-
- sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
- if (ret)
- netdev_err(priv->dev, "sdio_writeb failed!\n");
-
- sdio_release_host(card->func);
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
- return ret;
-
-}
-
-static struct mmc_host *reset_host;
-
-static void if_sdio_reset_card_worker(struct work_struct *work)
-{
- /*
- * The actual reset operation must be run outside of lbs_thread. This
- * is because mmc_remove_host() will cause the device to be instantly
- * destroyed, and the libertas driver then needs to end lbs_thread,
- * leading to a deadlock.
- *
- * We run it in a workqueue totally independent from the if_sdio_card
- * instance for that reason.
- */
-
- pr_info("Resetting card...");
- mmc_remove_host(reset_host);
- mmc_add_host(reset_host);
-}
-static DECLARE_WORK(card_reset_work, if_sdio_reset_card_worker);
-
-static void if_sdio_reset_card(struct lbs_private *priv)
-{
- struct if_sdio_card *card = priv->card;
-
- if (work_pending(&card_reset_work))
- return;
-
- reset_host = card->func->card->host;
- schedule_work(&card_reset_work);
-}
-
-static int if_sdio_power_save(struct lbs_private *priv)
-{
- struct if_sdio_card *card = priv->card;
- int ret;
-
- flush_workqueue(card->workqueue);
-
- ret = if_sdio_power_off(card);
-
- /* Let runtime PM know the card is powered off */
- pm_runtime_put_sync(&card->func->dev);
-
- return ret;
-}
-
-static int if_sdio_power_restore(struct lbs_private *priv)
-{
- struct if_sdio_card *card = priv->card;
- int r;
-
- /* Make sure the card will not be powered off by runtime PM */
- pm_runtime_get_sync(&card->func->dev);
-
- r = if_sdio_power_on(card);
- if (r)
- return r;
-
- wait_event(card->pwron_waitq, priv->fw_ready);
- return 0;
-}
-
-
-/*******************************************************************/
-/* SDIO callbacks */
-/*******************************************************************/
-
-static void if_sdio_interrupt(struct sdio_func *func)
-{
- int ret;
- struct if_sdio_card *card;
- u8 cause;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- card = sdio_get_drvdata(func);
-
- cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
- if (ret || !cause)
- goto out;
-
- lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
-
- sdio_writeb(card->func, ~cause, IF_SDIO_H_INT_STATUS, &ret);
- if (ret)
- goto out;
-
- /*
- * Ignore the define name, this really means the card has
- * successfully received the command.
- */
- card->priv->is_activity_detected = 1;
- if (cause & IF_SDIO_H_INT_DNLD)
- lbs_host_to_card_done(card->priv);
-
-
- if (cause & IF_SDIO_H_INT_UPLD) {
- ret = if_sdio_card_to_host(card);
- if (ret)
- goto out;
- }
-
- ret = 0;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-}
-
-static int if_sdio_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- struct if_sdio_card *card;
- struct lbs_private *priv;
- int ret, i;
- unsigned int model;
- struct if_sdio_packet *packet;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- for (i = 0;i < func->card->num_info;i++) {
- if (sscanf(func->card->info[i],
- "802.11 SDIO ID: %x", &model) == 1)
- break;
- if (sscanf(func->card->info[i],
- "ID: %x", &model) == 1)
- break;
- if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
- model = MODEL_8385;
- break;
- }
- }
-
- if (i == func->card->num_info) {
- pr_err("unable to identify card model\n");
- return -ENODEV;
- }
-
- card = kzalloc(sizeof(struct if_sdio_card), GFP_KERNEL);
- if (!card)
- return -ENOMEM;
-
- card->func = func;
- card->model = model;
-
- switch (card->model) {
- case MODEL_8385:
- card->scratch_reg = IF_SDIO_SCRATCH_OLD;
- break;
- case MODEL_8686:
- card->scratch_reg = IF_SDIO_SCRATCH;
- break;
- case MODEL_8688:
- default: /* for newer chipsets */
- card->scratch_reg = IF_SDIO_FW_STATUS;
- break;
- }
-
- spin_lock_init(&card->lock);
- card->workqueue = create_workqueue("libertas_sdio");
- INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
- init_waitqueue_head(&card->pwron_waitq);
-
- /* Check if we support this card */
- for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
- if (card->model == fw_table[i].model)
- break;
- }
- if (i == ARRAY_SIZE(fw_table)) {
- pr_err("unknown card model 0x%x\n", card->model);
- ret = -ENODEV;
- goto free;
- }
-
- sdio_set_drvdata(func, card);
-
- lbs_deb_sdio("class = 0x%X, vendor = 0x%X, "
- "device = 0x%X, model = 0x%X, ioport = 0x%X\n",
- func->class, func->vendor, func->device,
- model, (unsigned)card->ioport);
-
-
- priv = lbs_add_card(card, &func->dev);
- if (!priv) {
- ret = -ENOMEM;
- goto free;
- }
-
- card->priv = priv;
-
- priv->card = card;
- priv->hw_host_to_card = if_sdio_host_to_card;
- priv->enter_deep_sleep = if_sdio_enter_deep_sleep;
- priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
- priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
- priv->reset_card = if_sdio_reset_card;
- priv->power_save = if_sdio_power_save;
- priv->power_restore = if_sdio_power_restore;
-
- ret = if_sdio_power_on(card);
- if (ret)
- goto err_activate_card;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
- return ret;
-
-err_activate_card:
- flush_workqueue(card->workqueue);
- lbs_remove_card(priv);
-free:
- destroy_workqueue(card->workqueue);
- while (card->packets) {
- packet = card->packets;
- card->packets = card->packets->next;
- kfree(packet);
- }
-
- kfree(card);
-
- goto out;
-}
-
-static void if_sdio_remove(struct sdio_func *func)
-{
- struct if_sdio_card *card;
- struct if_sdio_packet *packet;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- card = sdio_get_drvdata(func);
-
- /* Undo decrement done above in if_sdio_probe */
- pm_runtime_get_noresume(&func->dev);
-
- if (user_rmmod && (card->model == MODEL_8688)) {
- /*
- * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
- * multiple functions
- */
- struct cmd_header cmd;
-
- memset(&cmd, 0, sizeof(cmd));
-
- lbs_deb_sdio("send function SHUTDOWN command\n");
- if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
- &cmd, sizeof(cmd), lbs_cmd_copyback,
- (unsigned long) &cmd))
- pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
- }
-
-
- lbs_deb_sdio("call remove card\n");
- lbs_stop_card(card->priv);
- lbs_remove_card(card->priv);
-
- flush_workqueue(card->workqueue);
- destroy_workqueue(card->workqueue);
-
- while (card->packets) {
- packet = card->packets;
- card->packets = card->packets->next;
- kfree(packet);
- }
-
- kfree(card);
- lbs_deb_leave(LBS_DEB_SDIO);
-}
-
-static int if_sdio_suspend(struct device *dev)
-{
- struct sdio_func *func = dev_to_sdio_func(dev);
- int ret;
- struct if_sdio_card *card = sdio_get_drvdata(func);
-
- mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
-
- /* If we're powered off anyway, just let the mmc layer remove the
- * card. */
- if (!lbs_iface_active(card->priv))
- return -ENOSYS;
-
- dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
- sdio_func_id(func), flags);
-
- /* If we aren't being asked to wake on anything, we should bail out
- * and let the SD stack power down the card.
- */
- if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
- dev_info(dev, "Suspend without wake params -- powering down card\n");
- return -ENOSYS;
- }
-
- if (!(flags & MMC_PM_KEEP_POWER)) {
- dev_err(dev, "%s: cannot remain alive while host is suspended\n",
- sdio_func_id(func));
- return -ENOSYS;
- }
-
- ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
- if (ret)
- return ret;
-
- ret = lbs_suspend(card->priv);
- if (ret)
- return ret;
-
- return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
-}
-
-static int if_sdio_resume(struct device *dev)
-{
- struct sdio_func *func = dev_to_sdio_func(dev);
- struct if_sdio_card *card = sdio_get_drvdata(func);
- int ret;
-
- dev_info(dev, "%s: resume: we're back\n", sdio_func_id(func));
-
- ret = lbs_resume(card->priv);
-
- return ret;
-}
-
-static const struct dev_pm_ops if_sdio_pm_ops = {
- .suspend = if_sdio_suspend,
- .resume = if_sdio_resume,
-};
-
-static struct sdio_driver if_sdio_driver = {
- .name = "libertas_sdio",
- .id_table = if_sdio_ids,
- .probe = if_sdio_probe,
- .remove = if_sdio_remove,
- .drv = {
- .pm = &if_sdio_pm_ops,
- },
-};
-
-/*******************************************************************/
-/* Module functions */
-/*******************************************************************/
-
-static int __init if_sdio_init_module(void)
-{
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_SDIO);
-
- printk(KERN_INFO "libertas_sdio: Libertas SDIO driver\n");
- printk(KERN_INFO "libertas_sdio: Copyright Pierre Ossman\n");
-
- ret = sdio_register_driver(&if_sdio_driver);
-
- /* Clear the flag in case user removes the card. */
- user_rmmod = 0;
-
- lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
-
- return ret;
-}
-
-static void __exit if_sdio_exit_module(void)
-{
- lbs_deb_enter(LBS_DEB_SDIO);
-
- /* Set the flag as user is removing this module. */
- user_rmmod = 1;
-
- cancel_work_sync(&card_reset_work);
-
- sdio_unregister_driver(&if_sdio_driver);
-
- lbs_deb_leave(LBS_DEB_SDIO);
-}
-
-module_init(if_sdio_init_module);
-module_exit(if_sdio_exit_module);
-
-MODULE_DESCRIPTION("Libertas SDIO WLAN Driver");
-MODULE_AUTHOR("Pierre Ossman");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
deleted file mode 100644
index 62fda3592..000000000
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * linux/drivers/net/wireless/libertas/if_sdio.h
- *
- * Copyright 2007 Pierre Ossman
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef _LBS_IF_SDIO_H
-#define _LBS_IF_SDIO_H
-
-#define IF_SDIO_IOPORT 0x00
-
-#define IF_SDIO_H_INT_MASK 0x04
-#define IF_SDIO_H_INT_OFLOW 0x08
-#define IF_SDIO_H_INT_UFLOW 0x04
-#define IF_SDIO_H_INT_DNLD 0x02
-#define IF_SDIO_H_INT_UPLD 0x01
-
-#define IF_SDIO_H_INT_STATUS 0x05
-#define IF_SDIO_H_INT_RSR 0x06
-#define IF_SDIO_H_INT_STATUS2 0x07
-
-#define IF_SDIO_RD_BASE 0x10
-
-#define IF_SDIO_STATUS 0x20
-#define IF_SDIO_IO_RDY 0x08
-#define IF_SDIO_CIS_RDY 0x04
-#define IF_SDIO_UL_RDY 0x02
-#define IF_SDIO_DL_RDY 0x01
-
-#define IF_SDIO_C_INT_MASK 0x24
-#define IF_SDIO_C_INT_STATUS 0x28
-#define IF_SDIO_C_INT_RSR 0x2C
-
-#define IF_SDIO_SCRATCH 0x34
-#define IF_SDIO_SCRATCH_OLD 0x80fe
-#define IF_SDIO_FW_STATUS 0x40
-#define IF_SDIO_FIRMWARE_OK 0xfedc
-
-#define IF_SDIO_RX_LEN 0x42
-#define IF_SDIO_RX_UNIT 0x43
-
-#define IF_SDIO_EVENT 0x80fc
-
-#define IF_SDIO_BLOCK_SIZE 256
-#define CONFIGURATION_REG 0x03
-#define HOST_POWER_UP (0x1U << 1)
-#endif
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
deleted file mode 100644
index d51293895..000000000
--- a/drivers/net/wireless/libertas/if_spi.c
+++ /dev/null
@@ -1,1310 +0,0 @@
-/*
- * linux/drivers/net/wireless/libertas/if_spi.c
- *
- * Driver for Marvell SPI WLAN cards.
- *
- * Copyright 2008 Analog Devices Inc.
- *
- * Authors:
- * Andrey Yurovsky <andrey@cozybit.com>
- * Colin McCabe <colin@cozybit.com>
- *
- * Inspired by if_sdio.c, Copyright 2007-2008 Pierre Ossman
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/hardirq.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/spi/libertas_spi.h>
-#include <linux/spi/spi.h>
-
-#include "host.h"
-#include "decl.h"
-#include "defs.h"
-#include "dev.h"
-#include "if_spi.h"
-
-struct if_spi_packet {
- struct list_head list;
- u16 blen;
- u8 buffer[0] __attribute__((aligned(4)));
-};
-
-struct if_spi_card {
- struct spi_device *spi;
- struct lbs_private *priv;
- struct libertas_spi_platform_data *pdata;
-
- /* The card ID and card revision, as reported by the hardware. */
- u16 card_id;
- u8 card_rev;
-
- /* The last time that we initiated an SPU operation */
- unsigned long prev_xfer_time;
-
- int use_dummy_writes;
- unsigned long spu_port_delay;
- unsigned long spu_reg_delay;
-
- /* Handles all SPI communication (except for FW load) */
- struct workqueue_struct *workqueue;
- struct work_struct packet_work;
- struct work_struct resume_work;
-
- u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE];
-
- /* A buffer of incoming packets from libertas core.
- * Since we can't sleep in hw_host_to_card, we have to buffer
- * them. */
- struct list_head cmd_packet_list;
- struct list_head data_packet_list;
-
- /* Protects cmd_packet_list and data_packet_list */
- spinlock_t buffer_lock;
-
- /* True is card suspended */
- u8 suspended;
-};
-
-static void free_if_spi_card(struct if_spi_card *card)
-{
- struct list_head *cursor, *next;
- struct if_spi_packet *packet;
-
- list_for_each_safe(cursor, next, &card->cmd_packet_list) {
- packet = container_of(cursor, struct if_spi_packet, list);
- list_del(&packet->list);
- kfree(packet);
- }
- list_for_each_safe(cursor, next, &card->data_packet_list) {
- packet = container_of(cursor, struct if_spi_packet, list);
- list_del(&packet->list);
- kfree(packet);
- }
- kfree(card);
-}
-
-#define MODEL_8385 0x04
-#define MODEL_8686 0x0b
-#define MODEL_8688 0x10
-
-static const struct lbs_fw_table fw_table[] = {
- { MODEL_8385, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8385, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8686, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8686, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { MODEL_8688, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" },
- { 0, NULL, NULL }
-};
-/*(DEBLOBBED)*/
-
-
-/*
- * SPI Interface Unit Routines
- *
- * The SPU sits between the host and the WLAN module.
- * All communication with the firmware is through SPU transactions.
- *
- * First we have to put a SPU register name on the bus. Then we can
- * either read from or write to that register.
- *
- */
-
-static void spu_transaction_init(struct if_spi_card *card)
-{
- if (!time_after(jiffies, card->prev_xfer_time + 1)) {
- /* Unfortunately, the SPU requires a delay between successive
- * transactions. If our last transaction was more than a jiffy
- * ago, we have obviously already delayed enough.
- * If not, we have to busy-wait to be on the safe side. */
- ndelay(400);
- }
-}
-
-static void spu_transaction_finish(struct if_spi_card *card)
-{
- card->prev_xfer_time = jiffies;
-}
-
-/*
- * Write out a byte buffer to an SPI register,
- * using a series of 16-bit transfers.
- */
-static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
-{
- int err = 0;
- __le16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
- struct spi_message m;
- struct spi_transfer reg_trans;
- struct spi_transfer data_trans;
-
- spi_message_init(&m);
- memset(&reg_trans, 0, sizeof(reg_trans));
- memset(&data_trans, 0, sizeof(data_trans));
-
- /* You must give an even number of bytes to the SPU, even if it
- * doesn't care about the last one. */
- BUG_ON(len & 0x1);
-
- spu_transaction_init(card);
-
- /* write SPU register index */
- reg_trans.tx_buf = &reg_out;
- reg_trans.len = sizeof(reg_out);
-
- data_trans.tx_buf = buf;
- data_trans.len = len;
-
- spi_message_add_tail(&reg_trans, &m);
- spi_message_add_tail(&data_trans, &m);
-
- err = spi_sync(card->spi, &m);
- spu_transaction_finish(card);
- return err;
-}
-
-static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
-{
- __le16 buff;
-
- buff = cpu_to_le16(val);
- return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
-}
-
-static inline int spu_reg_is_port_reg(u16 reg)
-{
- switch (reg) {
- case IF_SPI_IO_RDWRPORT_REG:
- case IF_SPI_CMD_RDWRPORT_REG:
- case IF_SPI_DATA_RDWRPORT_REG:
- return 1;
- default:
- return 0;
- }
-}
-
-static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
-{
- unsigned int delay;
- int err = 0;
- __le16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
- struct spi_message m;
- struct spi_transfer reg_trans;
- struct spi_transfer dummy_trans;
- struct spi_transfer data_trans;
-
- /*
- * You must take an even number of bytes from the SPU, even if you
- * don't care about the last one.
- */
- BUG_ON(len & 0x1);
-
- spu_transaction_init(card);
-
- spi_message_init(&m);
- memset(&reg_trans, 0, sizeof(reg_trans));
- memset(&dummy_trans, 0, sizeof(dummy_trans));
- memset(&data_trans, 0, sizeof(data_trans));
-
- /* write SPU register index */
- reg_trans.tx_buf = &reg_out;
- reg_trans.len = sizeof(reg_out);
- spi_message_add_tail(&reg_trans, &m);
-
- delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay :
- card->spu_reg_delay;
- if (card->use_dummy_writes) {
- /* Clock in dummy cycles while the SPU fills the FIFO */
- dummy_trans.len = delay / 8;
- spi_message_add_tail(&dummy_trans, &m);
- } else {
- /* Busy-wait while the SPU fills the FIFO */
- reg_trans.delay_usecs =
- DIV_ROUND_UP((100 + (delay * 10)), 1000);
- }
-
- /* read in data */
- data_trans.rx_buf = buf;
- data_trans.len = len;
- spi_message_add_tail(&data_trans, &m);
-
- err = spi_sync(card->spi, &m);
- spu_transaction_finish(card);
- return err;
-}
-
-/* Read 16 bits from an SPI register */
-static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
-{
- __le16 buf;
- int ret;
-
- ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
- if (ret == 0)
- *val = le16_to_cpup(&buf);
- return ret;
-}
-
-/*
- * Read 32 bits from an SPI register.
- * The low 16 bits are read first.
- */
-static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
-{
- __le32 buf;
- int err;
-
- err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
- if (!err)
- *val = le32_to_cpup(&buf);
- return err;
-}
-
-/*
- * Keep reading 16 bits from an SPI register until you get the correct result.
- *
- * If mask = 0, the correct result is any non-zero number.
- * If mask != 0, the correct result is any number where
- * number & target_mask == target
- *
- * Returns -ETIMEDOUT if a second passes without the correct result.
- */
-static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
- u16 target_mask, u16 target)
-{
- int err;
- unsigned long timeout = jiffies + 5*HZ;
- while (1) {
- u16 val;
- err = spu_read_u16(card, reg, &val);
- if (err)
- return err;
- if (target_mask) {
- if ((val & target_mask) == target)
- return 0;
- } else {
- if (val)
- return 0;
- }
- udelay(100);
- if (time_after(jiffies, timeout)) {
- pr_err("%s: timeout with val=%02x, target_mask=%02x, target=%02x\n",
- __func__, val, target_mask, target);
- return -ETIMEDOUT;
- }
- }
-}
-
-/*
- * Read 16 bits from an SPI register until you receive a specific value.
- * Returns -ETIMEDOUT if a 4 tries pass without success.
- */
-static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
-{
- int err, try;
- for (try = 0; try < 4; ++try) {
- u32 val = 0;
- err = spu_read_u32(card, reg, &val);
- if (err)
- return err;
- if (val == target)
- return 0;
- mdelay(100);
- }
- return -ETIMEDOUT;
-}
-
-static int spu_set_interrupt_mode(struct if_spi_card *card,
- int suppress_host_int,
- int auto_int)
-{
- int err = 0;
-
- /*
- * We can suppress a host interrupt by clearing the appropriate
- * bit in the "host interrupt status mask" register
- */
- if (suppress_host_int) {
- err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
- if (err)
- return err;
- } else {
- err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG,
- IF_SPI_HISM_TX_DOWNLOAD_RDY |
- IF_SPI_HISM_RX_UPLOAD_RDY |
- IF_SPI_HISM_CMD_DOWNLOAD_RDY |
- IF_SPI_HISM_CARDEVENT |
- IF_SPI_HISM_CMD_UPLOAD_RDY);
- if (err)
- return err;
- }
-
- /*
- * If auto-interrupts are on, the completion of certain transactions
- * will trigger an interrupt automatically. If auto-interrupts
- * are off, we need to set the "Card Interrupt Cause" register to
- * trigger a card interrupt.
- */
- if (auto_int) {
- err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
- IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
- IF_SPI_HICT_RX_UPLOAD_OVER_AUTO |
- IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO |
- IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO);
- if (err)
- return err;
- } else {
- err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
- if (err)
- return err;
- }
- return err;
-}
-
-static int spu_get_chip_revision(struct if_spi_card *card,
- u16 *card_id, u8 *card_rev)
-{
- int err = 0;
- u32 dev_ctrl;
- err = spu_read_u32(card, IF_SPI_DEVICEID_CTRL_REG, &dev_ctrl);
- if (err)
- return err;
- *card_id = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dev_ctrl);
- *card_rev = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dev_ctrl);
- return err;
-}
-
-static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
-{
- int err = 0;
- u16 rval;
- /* set bus mode */
- err = spu_write_u16(card, IF_SPI_SPU_BUS_MODE_REG, mode);
- if (err)
- return err;
- /* Check that we were able to read back what we just wrote. */
- err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval);
- if (err)
- return err;
- if ((rval & 0xF) != mode) {
- pr_err("Can't read bus mode register\n");
- return -EIO;
- }
- return 0;
-}
-
-static int spu_init(struct if_spi_card *card, int use_dummy_writes)
-{
- int err = 0;
- u32 delay;
-
- /*
- * We have to start up in timed delay mode so that we can safely
- * read the Delay Read Register.
- */
- card->use_dummy_writes = 0;
- err = spu_set_bus_mode(card,
- IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
- IF_SPI_BUS_MODE_DELAY_METHOD_TIMED |
- IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
- if (err)
- return err;
- card->spu_port_delay = 1000;
- card->spu_reg_delay = 1000;
- err = spu_read_u32(card, IF_SPI_DELAY_READ_REG, &delay);
- if (err)
- return err;
- card->spu_port_delay = delay & 0x0000ffff;
- card->spu_reg_delay = (delay & 0xffff0000) >> 16;
-
- /* If dummy clock delay mode has been requested, switch to it now */
- if (use_dummy_writes) {
- card->use_dummy_writes = 1;
- err = spu_set_bus_mode(card,
- IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
- IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK |
- IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
- if (err)
- return err;
- }
-
- lbs_deb_spi("Initialized SPU unit. "
- "spu_port_delay=0x%04lx, spu_reg_delay=0x%04lx\n",
- card->spu_port_delay, card->spu_reg_delay);
- return err;
-}
-
-/*
- * Firmware Loading
- */
-
-static int if_spi_prog_helper_firmware(struct if_spi_card *card,
- const struct firmware *firmware)
-{
- int err = 0;
- int bytes_remaining;
- const u8 *fw;
- u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- err = spu_set_interrupt_mode(card, 1, 0);
- if (err)
- goto out;
-
- bytes_remaining = firmware->size;
- fw = firmware->data;
-
- /* Load helper firmware image */
- while (bytes_remaining > 0) {
- /*
- * Scratch pad 1 should contain the number of bytes we
- * want to download to the firmware
- */
- err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
- HELPER_FW_LOAD_CHUNK_SZ);
- if (err)
- goto out;
-
- err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
- IF_SPI_HIST_CMD_DOWNLOAD_RDY,
- IF_SPI_HIST_CMD_DOWNLOAD_RDY);
- if (err)
- goto out;
-
- /*
- * Feed the data into the command read/write port reg
- * in chunks of 64 bytes
- */
- memset(temp, 0, sizeof(temp));
- memcpy(temp, fw,
- min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
- mdelay(10);
- err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
- temp, HELPER_FW_LOAD_CHUNK_SZ);
- if (err)
- goto out;
-
- /* Interrupt the boot code */
- err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
- if (err)
- goto out;
- err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
- IF_SPI_CIC_CMD_DOWNLOAD_OVER);
- if (err)
- goto out;
- bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
- fw += HELPER_FW_LOAD_CHUNK_SZ;
- }
-
- /*
- * Once the helper / single stage firmware download is complete,
- * write 0 to scratch pad 1 and interrupt the
- * bootloader. This completes the helper download.
- */
- err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
- if (err)
- goto out;
- err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
- if (err)
- goto out;
- err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
- IF_SPI_CIC_CMD_DOWNLOAD_OVER);
-out:
- if (err)
- pr_err("failed to load helper firmware (err=%d)\n", err);
- lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
- return err;
-}
-
-/*
- * Returns the length of the next packet the firmware expects us to send.
- * Sets crc_err if the previous transfer had a CRC error.
- */
-static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
- int *crc_err)
-{
- u16 len;
- int err = 0;
-
- /*
- * wait until the host interrupt status register indicates
- * that we are ready to download
- */
- err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
- IF_SPI_HIST_CMD_DOWNLOAD_RDY,
- IF_SPI_HIST_CMD_DOWNLOAD_RDY);
- if (err) {
- pr_err("timed out waiting for host_int_status\n");
- return err;
- }
-
- /* Ask the device how many bytes of firmware it wants. */
- err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
- if (err)
- return err;
-
- if (len > IF_SPI_CMD_BUF_SIZE) {
- pr_err("firmware load device requested a larger transfer than we are prepared to handle (len = %d)\n",
- len);
- return -EIO;
- }
- if (len & 0x1) {
- lbs_deb_spi("%s: crc error\n", __func__);
- len &= ~0x1;
- *crc_err = 1;
- } else
- *crc_err = 0;
-
- return len;
-}
-
-static int if_spi_prog_main_firmware(struct if_spi_card *card,
- const struct firmware *firmware)
-{
- struct lbs_private *priv = card->priv;
- int len, prev_len;
- int bytes, crc_err = 0, err = 0;
- const u8 *fw;
- u16 num_crc_errs;
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- err = spu_set_interrupt_mode(card, 1, 0);
- if (err)
- goto out;
-
- err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
- if (err) {
- netdev_err(priv->dev,
- "%s: timed out waiting for initial scratch reg = 0\n",
- __func__);
- goto out;
- }
-
- num_crc_errs = 0;
- prev_len = 0;
- bytes = firmware->size;
- fw = firmware->data;
- while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
- if (len < 0) {
- err = len;
- goto out;
- }
- if (bytes < 0) {
- /*
- * If there are no more bytes left, we would normally
- * expect to have terminated with len = 0
- */
- netdev_err(priv->dev,
- "Firmware load wants more bytes than we have to offer.\n");
- break;
- }
- if (crc_err) {
- /* Previous transfer failed. */
- if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
- pr_err("Too many CRC errors encountered in firmware load.\n");
- err = -EIO;
- goto out;
- }
- } else {
- /* Previous transfer succeeded. Advance counters. */
- bytes -= prev_len;
- fw += prev_len;
- }
- if (bytes < len) {
- memset(card->cmd_buffer, 0, len);
- memcpy(card->cmd_buffer, fw, bytes);
- } else
- memcpy(card->cmd_buffer, fw, len);
-
- err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
- if (err)
- goto out;
- err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
- card->cmd_buffer, len);
- if (err)
- goto out;
- err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
- IF_SPI_CIC_CMD_DOWNLOAD_OVER);
- if (err)
- goto out;
- prev_len = len;
- }
- if (bytes > prev_len) {
- pr_err("firmware load wants fewer bytes than we have to offer\n");
- }
-
- /* Confirm firmware download */
- err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
- SUCCESSFUL_FW_DOWNLOAD_MAGIC);
- if (err) {
- pr_err("failed to confirm the firmware download\n");
- goto out;
- }
-
-out:
- if (err)
- pr_err("failed to load firmware (err=%d)\n", err);
- lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
- return err;
-}
-
-/*
- * SPI Transfer Thread
- *
- * The SPI worker handles all SPI transfers, so there is no need for a lock.
- */
-
-/* Move a command from the card to the host */
-static int if_spi_c2h_cmd(struct if_spi_card *card)
-{
- struct lbs_private *priv = card->priv;
- unsigned long flags;
- int err = 0;
- u16 len;
- u8 i;
-
- /*
- * We need a buffer big enough to handle whatever people send to
- * hw_host_to_card
- */
- BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
- BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
-
- /*
- * It's just annoying if the buffer size isn't a multiple of 4, because
- * then we might have len < IF_SPI_CMD_BUF_SIZE but
- * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE
- */
- BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- /* How many bytes are there to read? */
- err = spu_read_u16(card, IF_SPI_SCRATCH_2_REG, &len);
- if (err)
- goto out;
- if (!len) {
- netdev_err(priv->dev, "%s: error: card has no data for host\n",
- __func__);
- err = -EINVAL;
- goto out;
- } else if (len > IF_SPI_CMD_BUF_SIZE) {
- netdev_err(priv->dev,
- "%s: error: response packet too large: %d bytes, but maximum is %d\n",
- __func__, len, IF_SPI_CMD_BUF_SIZE);
- err = -EINVAL;
- goto out;
- }
-
- /* Read the data from the WLAN module into our command buffer */
- err = spu_read(card, IF_SPI_CMD_RDWRPORT_REG,
- card->cmd_buffer, ALIGN(len, 4));
- if (err)
- goto out;
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- i = (priv->resp_idx == 0) ? 1 : 0;
- BUG_ON(priv->resp_len[i]);
- priv->resp_len[i] = len;
- memcpy(priv->resp_buf[i], card->cmd_buffer, len);
- lbs_notify_command_response(priv, i);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
-out:
- if (err)
- netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
- lbs_deb_leave(LBS_DEB_SPI);
- return err;
-}
-
-/* Move data from the card to the host */
-static int if_spi_c2h_data(struct if_spi_card *card)
-{
- struct lbs_private *priv = card->priv;
- struct sk_buff *skb;
- char *data;
- u16 len;
- int err = 0;
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- /* How many bytes are there to read? */
- err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
- if (err)
- goto out;
- if (!len) {
- netdev_err(priv->dev, "%s: error: card has no data for host\n",
- __func__);
- err = -EINVAL;
- goto out;
- } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
- netdev_err(priv->dev,
- "%s: error: card has %d bytes of data, but our maximum skb size is %zu\n",
- __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
- err = -EINVAL;
- goto out;
- }
-
- /* TODO: should we allocate a smaller skb if we have less data? */
- skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
- if (!skb) {
- err = -ENOBUFS;
- goto out;
- }
- skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
- data = skb_put(skb, len);
-
- /* Read the data from the WLAN module into our skb... */
- err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
- if (err)
- goto free_skb;
-
- /* pass the SKB to libertas */
- err = lbs_process_rxed_packet(card->priv, skb);
- if (err)
- goto free_skb;
-
- /* success */
- goto out;
-
-free_skb:
- dev_kfree_skb(skb);
-out:
- if (err)
- netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
- lbs_deb_leave(LBS_DEB_SPI);
- return err;
-}
-
-/* Move data or a command from the host to the card. */
-static void if_spi_h2c(struct if_spi_card *card,
- struct if_spi_packet *packet, int type)
-{
- struct lbs_private *priv = card->priv;
- int err = 0;
- u16 int_type, port_reg;
-
- switch (type) {
- case MVMS_DAT:
- int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
- port_reg = IF_SPI_DATA_RDWRPORT_REG;
- break;
- case MVMS_CMD:
- int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
- port_reg = IF_SPI_CMD_RDWRPORT_REG;
- break;
- default:
- netdev_err(priv->dev, "can't transfer buffer of type %d\n",
- type);
- err = -EINVAL;
- goto out;
- }
-
- /* Write the data to the card */
- err = spu_write(card, port_reg, packet->buffer, packet->blen);
- if (err)
- goto out;
-
-out:
- kfree(packet);
-
- if (err)
- netdev_err(priv->dev, "%s: error %d\n", __func__, err);
-}
-
-/* Inform the host about a card event */
-static void if_spi_e2h(struct if_spi_card *card)
-{
- int err = 0;
- u32 cause;
- struct lbs_private *priv = card->priv;
-
- err = spu_read_u32(card, IF_SPI_SCRATCH_3_REG, &cause);
- if (err)
- goto out;
-
- /* re-enable the card event interrupt */
- spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG,
- ~IF_SPI_HICU_CARD_EVENT);
-
- /* generate a card interrupt */
- spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT);
-
- lbs_queue_event(priv, cause & 0xff);
-out:
- if (err)
- netdev_err(priv->dev, "%s: error %d\n", __func__, err);
-}
-
-static void if_spi_host_to_card_worker(struct work_struct *work)
-{
- int err;
- struct if_spi_card *card;
- u16 hiStatus;
- unsigned long flags;
- struct if_spi_packet *packet;
- struct lbs_private *priv;
-
- card = container_of(work, struct if_spi_card, packet_work);
- priv = card->priv;
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- /*
- * Read the host interrupt status register to see what we
- * can do.
- */
- err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
- &hiStatus);
- if (err) {
- netdev_err(priv->dev, "I/O error\n");
- goto err;
- }
-
- if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) {
- err = if_spi_c2h_cmd(card);
- if (err)
- goto err;
- }
- if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) {
- err = if_spi_c2h_data(card);
- if (err)
- goto err;
- }
-
- /*
- * workaround: in PS mode, the card does not set the Command
- * Download Ready bit, but it sets TX Download Ready.
- */
- if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
- (card->priv->psstate != PS_STATE_FULL_POWER &&
- (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
- /*
- * This means two things. First of all,
- * if there was a previous command sent, the card has
- * successfully received it.
- * Secondly, it is now ready to download another
- * command.
- */
- lbs_host_to_card_done(card->priv);
-
- /* Do we have any command packets from the host to send? */
- packet = NULL;
- spin_lock_irqsave(&card->buffer_lock, flags);
- if (!list_empty(&card->cmd_packet_list)) {
- packet = (struct if_spi_packet *)(card->
- cmd_packet_list.next);
- list_del(&packet->list);
- }
- spin_unlock_irqrestore(&card->buffer_lock, flags);
-
- if (packet)
- if_spi_h2c(card, packet, MVMS_CMD);
- }
- if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
- /* Do we have any data packets from the host to send? */
- packet = NULL;
- spin_lock_irqsave(&card->buffer_lock, flags);
- if (!list_empty(&card->data_packet_list)) {
- packet = (struct if_spi_packet *)(card->
- data_packet_list.next);
- list_del(&packet->list);
- }
- spin_unlock_irqrestore(&card->buffer_lock, flags);
-
- if (packet)
- if_spi_h2c(card, packet, MVMS_DAT);
- }
- if (hiStatus & IF_SPI_HIST_CARD_EVENT)
- if_spi_e2h(card);
-
-err:
- if (err)
- netdev_err(priv->dev, "%s: got error %d\n", __func__, err);
-
- lbs_deb_leave(LBS_DEB_SPI);
-}
-
-/*
- * Host to Card
- *
- * Called from Libertas to transfer some data to the WLAN device
- * We can't sleep here.
- */
-static int if_spi_host_to_card(struct lbs_private *priv,
- u8 type, u8 *buf, u16 nb)
-{
- int err = 0;
- unsigned long flags;
- struct if_spi_card *card = priv->card;
- struct if_spi_packet *packet;
- u16 blen;
-
- lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
-
- if (nb == 0) {
- netdev_err(priv->dev, "%s: invalid size requested: %d\n",
- __func__, nb);
- err = -EINVAL;
- goto out;
- }
- blen = ALIGN(nb, 4);
- packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC);
- if (!packet) {
- err = -ENOMEM;
- goto out;
- }
- packet->blen = blen;
- memcpy(packet->buffer, buf, nb);
- memset(packet->buffer + nb, 0, blen - nb);
-
- switch (type) {
- case MVMS_CMD:
- priv->dnld_sent = DNLD_CMD_SENT;
- spin_lock_irqsave(&card->buffer_lock, flags);
- list_add_tail(&packet->list, &card->cmd_packet_list);
- spin_unlock_irqrestore(&card->buffer_lock, flags);
- break;
- case MVMS_DAT:
- priv->dnld_sent = DNLD_DATA_SENT;
- spin_lock_irqsave(&card->buffer_lock, flags);
- list_add_tail(&packet->list, &card->data_packet_list);
- spin_unlock_irqrestore(&card->buffer_lock, flags);
- break;
- default:
- kfree(packet);
- netdev_err(priv->dev, "can't transfer buffer of type %d\n",
- type);
- err = -EINVAL;
- break;
- }
-
- /* Queue spi xfer work */
- queue_work(card->workqueue, &card->packet_work);
-out:
- lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err);
- return err;
-}
-
-/*
- * Host Interrupts
- *
- * Service incoming interrupts from the WLAN device. We can't sleep here, so
- * don't try to talk on the SPI bus, just queue the SPI xfer work.
- */
-static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
-{
- struct if_spi_card *card = dev_id;
-
- queue_work(card->workqueue, &card->packet_work);
-
- return IRQ_HANDLED;
-}
-
-/*
- * SPI callbacks
- */
-
-static int if_spi_init_card(struct if_spi_card *card)
-{
- struct lbs_private *priv = card->priv;
- int err, i;
- u32 scratch;
- const struct firmware *helper = NULL;
- const struct firmware *mainfw = NULL;
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- err = spu_init(card, card->pdata->use_dummy_writes);
- if (err)
- goto out;
- err = spu_get_chip_revision(card, &card->card_id, &card->card_rev);
- if (err)
- goto out;
-
- err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch);
- if (err)
- goto out;
- if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC)
- lbs_deb_spi("Firmware is already loaded for "
- "Marvell WLAN 802.11 adapter\n");
- else {
- /* Check if we support this card */
- for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
- if (card->card_id == fw_table[i].model)
- break;
- }
- if (i == ARRAY_SIZE(fw_table)) {
- netdev_err(priv->dev, "Unsupported chip_id: 0x%02x\n",
- card->card_id);
- err = -ENODEV;
- goto out;
- }
-
- err = lbs_get_firmware(&card->spi->dev, card->card_id,
- &fw_table[0], &helper, &mainfw);
- if (err) {
- netdev_err(priv->dev, "failed to find firmware (%d)\n",
- err);
- goto out;
- }
-
- lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
- "(chip_id = 0x%04x, chip_rev = 0x%02x) "
- "attached to SPI bus_num %d, chip_select %d. "
- "spi->max_speed_hz=%d\n",
- card->card_id, card->card_rev,
- card->spi->master->bus_num,
- card->spi->chip_select,
- card->spi->max_speed_hz);
- err = if_spi_prog_helper_firmware(card, helper);
- if (err)
- goto out;
- err = if_spi_prog_main_firmware(card, mainfw);
- if (err)
- goto out;
- lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
- }
-
- err = spu_set_interrupt_mode(card, 0, 1);
- if (err)
- goto out;
-
-out:
- lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
- return err;
-}
-
-static void if_spi_resume_worker(struct work_struct *work)
-{
- struct if_spi_card *card;
-
- card = container_of(work, struct if_spi_card, resume_work);
-
- if (card->suspended) {
- if (card->pdata->setup)
- card->pdata->setup(card->spi);
-
- /* Init card ... */
- if_spi_init_card(card);
-
- enable_irq(card->spi->irq);
-
- /* And resume it ... */
- lbs_resume(card->priv);
-
- card->suspended = 0;
- }
-}
-
-static int if_spi_probe(struct spi_device *spi)
-{
- struct if_spi_card *card;
- struct lbs_private *priv = NULL;
- struct libertas_spi_platform_data *pdata = dev_get_platdata(&spi->dev);
- int err = 0;
-
- lbs_deb_enter(LBS_DEB_SPI);
-
- if (!pdata) {
- err = -EINVAL;
- goto out;
- }
-
- if (pdata->setup) {
- err = pdata->setup(spi);
- if (err)
- goto out;
- }
-
- /* Allocate card structure to represent this specific device */
- card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL);
- if (!card) {
- err = -ENOMEM;
- goto teardown;
- }
- spi_set_drvdata(spi, card);
- card->pdata = pdata;
- card->spi = spi;
- card->prev_xfer_time = jiffies;
-
- INIT_LIST_HEAD(&card->cmd_packet_list);
- INIT_LIST_HEAD(&card->data_packet_list);
- spin_lock_init(&card->buffer_lock);
-
- /* Initialize the SPI Interface Unit */
-
- /* Firmware load */
- err = if_spi_init_card(card);
- if (err)
- goto free_card;
-
- /*
- * Register our card with libertas.
- * This will call alloc_etherdev.
- */
- priv = lbs_add_card(card, &spi->dev);
- if (!priv) {
- err = -ENOMEM;
- goto free_card;
- }
- card->priv = priv;
- priv->setup_fw_on_resume = 1;
- priv->card = card;
- priv->hw_host_to_card = if_spi_host_to_card;
- priv->enter_deep_sleep = NULL;
- priv->exit_deep_sleep = NULL;
- priv->reset_deep_sleep_wakeup = NULL;
- priv->fw_ready = 1;
-
- /* Initialize interrupt handling stuff. */
- card->workqueue = create_workqueue("libertas_spi");
- INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
- INIT_WORK(&card->resume_work, if_spi_resume_worker);
-
- err = request_irq(spi->irq, if_spi_host_interrupt,
- IRQF_TRIGGER_FALLING, "libertas_spi", card);
- if (err) {
- pr_err("can't get host irq line-- request_irq failed\n");
- goto terminate_workqueue;
- }
-
- /*
- * Start the card.
- * This will call register_netdev, and we'll start
- * getting interrupts...
- */
- err = lbs_start_card(priv);
- if (err)
- goto release_irq;
-
- lbs_deb_spi("Finished initializing WLAN module.\n");
-
- /* successful exit */
- goto out;
-
-release_irq:
- free_irq(spi->irq, card);
-terminate_workqueue:
- flush_workqueue(card->workqueue);
- destroy_workqueue(card->workqueue);
- lbs_remove_card(priv); /* will call free_netdev */
-free_card:
- free_if_spi_card(card);
-teardown:
- if (pdata->teardown)
- pdata->teardown(spi);
-out:
- lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
- return err;
-}
-
-static int libertas_spi_remove(struct spi_device *spi)
-{
- struct if_spi_card *card = spi_get_drvdata(spi);
- struct lbs_private *priv = card->priv;
-
- lbs_deb_spi("libertas_spi_remove\n");
- lbs_deb_enter(LBS_DEB_SPI);
-
- cancel_work_sync(&card->resume_work);
-
- lbs_stop_card(priv);
- lbs_remove_card(priv); /* will call free_netdev */
-
- free_irq(spi->irq, card);
- flush_workqueue(card->workqueue);
- destroy_workqueue(card->workqueue);
- if (card->pdata->teardown)
- card->pdata->teardown(spi);
- free_if_spi_card(card);
- lbs_deb_leave(LBS_DEB_SPI);
- return 0;
-}
-
-static int if_spi_suspend(struct device *dev)
-{
- struct spi_device *spi = to_spi_device(dev);
- struct if_spi_card *card = spi_get_drvdata(spi);
-
- if (!card->suspended) {
- lbs_suspend(card->priv);
- flush_workqueue(card->workqueue);
- disable_irq(spi->irq);
-
- if (card->pdata->teardown)
- card->pdata->teardown(spi);
- card->suspended = 1;
- }
-
- return 0;
-}
-
-static int if_spi_resume(struct device *dev)
-{
- struct spi_device *spi = to_spi_device(dev);
- struct if_spi_card *card = spi_get_drvdata(spi);
-
- /* Schedule delayed work */
- schedule_work(&card->resume_work);
-
- return 0;
-}
-
-static const struct dev_pm_ops if_spi_pm_ops = {
- .suspend = if_spi_suspend,
- .resume = if_spi_resume,
-};
-
-static struct spi_driver libertas_spi_driver = {
- .probe = if_spi_probe,
- .remove = libertas_spi_remove,
- .driver = {
- .name = "libertas_spi",
- .pm = &if_spi_pm_ops,
- },
-};
-
-/*
- * Module functions
- */
-
-static int __init if_spi_init_module(void)
-{
- int ret = 0;
- lbs_deb_enter(LBS_DEB_SPI);
- printk(KERN_INFO "libertas_spi: Libertas SPI driver\n");
- ret = spi_register_driver(&libertas_spi_driver);
- lbs_deb_leave(LBS_DEB_SPI);
- return ret;
-}
-
-static void __exit if_spi_exit_module(void)
-{
- lbs_deb_enter(LBS_DEB_SPI);
- spi_unregister_driver(&libertas_spi_driver);
- lbs_deb_leave(LBS_DEB_SPI);
-}
-
-module_init(if_spi_init_module);
-module_exit(if_spi_exit_module);
-
-MODULE_DESCRIPTION("Libertas SPI WLAN Driver");
-MODULE_AUTHOR("Andrey Yurovsky <andrey@cozybit.com>, "
- "Colin McCabe <colin@cozybit.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:libertas_spi");
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
deleted file mode 100644
index e450e31fd..000000000
--- a/drivers/net/wireless/libertas/if_spi.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * linux/drivers/net/wireless/libertas/if_spi.c
- *
- * Driver for Marvell SPI WLAN cards.
- *
- * Copyright 2008 Analog Devices Inc.
- *
- * Authors:
- * Andrey Yurovsky <andrey@cozybit.com>
- * Colin McCabe <colin@cozybit.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef _LBS_IF_SPI_H_
-#define _LBS_IF_SPI_H_
-
-#define IPFIELD_ALIGN_OFFSET 2
-#define IF_SPI_CMD_BUF_SIZE 2400
-
-/***************** Firmware *****************/
-
-#define IF_SPI_FW_NAME_MAX 30
-
-#define MAX_MAIN_FW_LOAD_CRC_ERR 10
-
-/* Chunk size when loading the helper firmware */
-#define HELPER_FW_LOAD_CHUNK_SZ 64
-
-/* Value to write to indicate end of helper firmware dnld */
-#define FIRMWARE_DNLD_OK 0x0000
-
-/* Value to check once the main firmware is downloaded */
-#define SUCCESSFUL_FW_DOWNLOAD_MAGIC 0x88888888
-
-/***************** SPI Interface Unit *****************/
-/* Masks used in SPI register read/write operations */
-#define IF_SPI_READ_OPERATION_MASK 0x0
-#define IF_SPI_WRITE_OPERATION_MASK 0x8000
-
-/* SPI register offsets. 4-byte aligned. */
-#define IF_SPI_DEVICEID_CTRL_REG 0x00 /* DeviceID controller reg */
-#define IF_SPI_IO_READBASE_REG 0x04 /* Read I/O base reg */
-#define IF_SPI_IO_WRITEBASE_REG 0x08 /* Write I/O base reg */
-#define IF_SPI_IO_RDWRPORT_REG 0x0C /* Read/Write I/O port reg */
-
-#define IF_SPI_CMD_READBASE_REG 0x10 /* Read command base reg */
-#define IF_SPI_CMD_WRITEBASE_REG 0x14 /* Write command base reg */
-#define IF_SPI_CMD_RDWRPORT_REG 0x18 /* Read/Write command port reg */
-
-#define IF_SPI_DATA_READBASE_REG 0x1C /* Read data base reg */
-#define IF_SPI_DATA_WRITEBASE_REG 0x20 /* Write data base reg */
-#define IF_SPI_DATA_RDWRPORT_REG 0x24 /* Read/Write data port reg */
-
-#define IF_SPI_SCRATCH_1_REG 0x28 /* Scratch reg 1 */
-#define IF_SPI_SCRATCH_2_REG 0x2C /* Scratch reg 2 */
-#define IF_SPI_SCRATCH_3_REG 0x30 /* Scratch reg 3 */
-#define IF_SPI_SCRATCH_4_REG 0x34 /* Scratch reg 4 */
-
-#define IF_SPI_TX_FRAME_SEQ_NUM_REG 0x38 /* Tx frame sequence number reg */
-#define IF_SPI_TX_FRAME_STATUS_REG 0x3C /* Tx frame status reg */
-
-#define IF_SPI_HOST_INT_CTRL_REG 0x40 /* Host interrupt controller reg */
-
-#define IF_SPI_CARD_INT_CAUSE_REG 0x44 /* Card interrupt cause reg */
-#define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interrupt status reg */
-#define IF_SPI_CARD_INT_EVENT_MASK_REG 0x4C /* Card interrupt event mask */
-#define IF_SPI_CARD_INT_STATUS_MASK_REG 0x50 /* Card interrupt status mask */
-
-#define IF_SPI_CARD_INT_RESET_SELECT_REG 0x54 /* Card interrupt reset select */
-
-#define IF_SPI_HOST_INT_CAUSE_REG 0x58 /* Host interrupt cause reg */
-#define IF_SPI_HOST_INT_STATUS_REG 0x5C /* Host interrupt status reg */
-#define IF_SPI_HOST_INT_EVENT_MASK_REG 0x60 /* Host interrupt event mask */
-#define IF_SPI_HOST_INT_STATUS_MASK_REG 0x64 /* Host interrupt status mask */
-#define IF_SPI_HOST_INT_RESET_SELECT_REG 0x68 /* Host interrupt reset select */
-
-#define IF_SPI_DELAY_READ_REG 0x6C /* Delay read reg */
-#define IF_SPI_SPU_BUS_MODE_REG 0x70 /* SPU BUS mode reg */
-
-/***************** IF_SPI_DEVICEID_CTRL_REG *****************/
-#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dc) ((dc & 0xffff0000)>>16)
-#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
-
-/***************** IF_SPI_HOST_INT_CTRL_REG *****************/
-/* Host Interrupt Control bit : Wake up */
-#define IF_SPI_HICT_WAKE_UP (1<<0)
-/* Host Interrupt Control bit : WLAN ready */
-#define IF_SPI_HICT_WLAN_READY (1<<1)
-/*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */
-/*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */
-/*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */
-/* Host Interrupt Control bit : Tx auto download */
-#define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5)
-/* Host Interrupt Control bit : Rx auto upload */
-#define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6)
-/* Host Interrupt Control bit : Command auto download */
-#define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7)
-/* Host Interrupt Control bit : Command auto upload */
-#define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8)
-
-/***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
-/* Card Interrupt Case bit : Tx download over */
-#define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0)
-/* Card Interrupt Case bit : Rx upload over */
-#define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1)
-/* Card Interrupt Case bit : Command download over */
-#define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2)
-/* Card Interrupt Case bit : Host event */
-#define IF_SPI_CIC_HOST_EVENT (1<<3)
-/* Card Interrupt Case bit : Command upload over */
-#define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4)
-/* Card Interrupt Case bit : Power down */
-#define IF_SPI_CIC_POWER_DOWN (1<<5)
-
-/***************** IF_SPI_CARD_INT_STATUS_REG *****************/
-#define IF_SPI_CIS_TX_DOWNLOAD_OVER (1<<0)
-#define IF_SPI_CIS_RX_UPLOAD_OVER (1<<1)
-#define IF_SPI_CIS_CMD_DOWNLOAD_OVER (1<<2)
-#define IF_SPI_CIS_HOST_EVENT (1<<3)
-#define IF_SPI_CIS_CMD_UPLOAD_OVER (1<<4)
-#define IF_SPI_CIS_POWER_DOWN (1<<5)
-
-/***************** IF_SPI_HOST_INT_CAUSE_REG *****************/
-#define IF_SPI_HICU_TX_DOWNLOAD_RDY (1<<0)
-#define IF_SPI_HICU_RX_UPLOAD_RDY (1<<1)
-#define IF_SPI_HICU_CMD_DOWNLOAD_RDY (1<<2)
-#define IF_SPI_HICU_CARD_EVENT (1<<3)
-#define IF_SPI_HICU_CMD_UPLOAD_RDY (1<<4)
-#define IF_SPI_HICU_IO_WR_FIFO_OVERFLOW (1<<5)
-#define IF_SPI_HICU_IO_RD_FIFO_UNDERFLOW (1<<6)
-#define IF_SPI_HICU_DATA_WR_FIFO_OVERFLOW (1<<7)
-#define IF_SPI_HICU_DATA_RD_FIFO_UNDERFLOW (1<<8)
-#define IF_SPI_HICU_CMD_WR_FIFO_OVERFLOW (1<<9)
-#define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10)
-
-/***************** IF_SPI_HOST_INT_STATUS_REG *****************/
-/* Host Interrupt Status bit : Tx download ready */
-#define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0)
-/* Host Interrupt Status bit : Rx upload ready */
-#define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1)
-/* Host Interrupt Status bit : Command download ready */
-#define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2)
-/* Host Interrupt Status bit : Card event */
-#define IF_SPI_HIST_CARD_EVENT (1<<3)
-/* Host Interrupt Status bit : Command upload ready */
-#define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4)
-/* Host Interrupt Status bit : I/O write FIFO overflow */
-#define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5)
-/* Host Interrupt Status bit : I/O read FIFO underflow */
-#define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6)
-/* Host Interrupt Status bit : Data write FIFO overflow */
-#define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7)
-/* Host Interrupt Status bit : Data read FIFO underflow */
-#define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8)
-/* Host Interrupt Status bit : Command write FIFO overflow */
-#define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9)
-/* Host Interrupt Status bit : Command read FIFO underflow */
-#define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10)
-
-/***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
-/* Host Interrupt Status Mask bit : Tx download ready */
-#define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0)
-/* Host Interrupt Status Mask bit : Rx upload ready */
-#define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1)
-/* Host Interrupt Status Mask bit : Command download ready */
-#define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2)
-/* Host Interrupt Status Mask bit : Card event */
-#define IF_SPI_HISM_CARDEVENT (1<<3)
-/* Host Interrupt Status Mask bit : Command upload ready */
-#define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4)
-/* Host Interrupt Status Mask bit : I/O write FIFO overflow */
-#define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5)
-/* Host Interrupt Status Mask bit : I/O read FIFO underflow */
-#define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6)
-/* Host Interrupt Status Mask bit : Data write FIFO overflow */
-#define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7)
-/* Host Interrupt Status Mask bit : Data write FIFO underflow */
-#define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8)
-/* Host Interrupt Status Mask bit : Command write FIFO overflow */
-#define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9)
-/* Host Interrupt Status Mask bit : Command write FIFO underflow */
-#define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10)
-
-/***************** IF_SPI_SPU_BUS_MODE_REG *****************/
-/* SCK edge on which the WLAN module outputs data on MISO */
-#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_FALLING 0x8
-#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING 0x0
-
-/* In a SPU read operation, there is a delay between writing the SPU
- * register name and getting back data from the WLAN module.
- * This can be specified in terms of nanoseconds or in terms of dummy
- * clock cycles which the master must output before receiving a response. */
-#define IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK 0x4
-#define IF_SPI_BUS_MODE_DELAY_METHOD_TIMED 0x0
-
-/* Some different modes of SPI operation */
-#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_16_BIT_DATA 0x00
-#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_32_BIT_DATA 0x01
-#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA 0x02
-#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_32_BIT_DATA 0x03
-
-#endif
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
deleted file mode 100644
index 23b0afda6..000000000
--- a/drivers/net/wireless/libertas/if_usb.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * This file contains functions used in USB interface module.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/firmware.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/olpc-ec.h>
-
-#ifdef CONFIG_OLPC
-#include <asm/olpc.h>
-#endif
-
-#define DRV_NAME "usb8xxx"
-
-#include "host.h"
-#include "decl.h"
-#include "defs.h"
-#include "dev.h"
-#include "cmd.h"
-#include "if_usb.h"
-
-#define INSANEDEBUG 0
-#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
-
-#define MESSAGE_HEADER_LEN 4
-
-/*(DEBLOBBED)*/
-
-enum {
- MODEL_UNKNOWN = 0x0,
- MODEL_8388 = 0x1,
- MODEL_8682 = 0x2
-};
-
-/* table of firmware file names */
-static const struct lbs_fw_table fw_table[] = {
- { MODEL_8388, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8388, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8388, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8388, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8388, "/*(DEBLOBBED)*/", NULL },
- { MODEL_8682, "/*(DEBLOBBED)*/", NULL }
-};
-
-static struct usb_device_id if_usb_table[] = {
- /* Enter the device signature inside */
- { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
- { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, if_usb_table);
-
-static void if_usb_receive(struct urb *urb);
-static void if_usb_receive_fwload(struct urb *urb);
-static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
- const struct firmware *fw,
- const struct firmware *unused);
-static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
- uint8_t *payload, uint16_t nb);
-static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
- uint16_t nb);
-static void if_usb_free(struct if_usb_card *cardp);
-static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
-static int if_usb_reset_device(struct if_usb_card *cardp);
-
-/**
- * if_usb_write_bulk_callback - callback function to handle the status
- * of the URB
- * @urb: pointer to &urb structure
- * returns: N/A
- */
-static void if_usb_write_bulk_callback(struct urb *urb)
-{
- struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
-
- /* handle the transmission complete validations */
-
- if (urb->status == 0) {
- struct lbs_private *priv = cardp->priv;
-
- lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
- lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
- urb->actual_length);
-
- /* Boot commands such as UPDATE_FW and UPDATE_BOOT2 are not
- * passed up to the lbs level.
- */
- if (priv && priv->dnld_sent != DNLD_BOOTCMD_SENT)
- lbs_host_to_card_done(priv);
- } else {
- /* print the failure status number for debug */
- pr_info("URB in failure status: %d\n", urb->status);
- }
-}
-
-/**
- * if_usb_free - free tx/rx urb, skb and rx buffer
- * @cardp: pointer to &if_usb_card
- * returns: N/A
- */
-static void if_usb_free(struct if_usb_card *cardp)
-{
- lbs_deb_enter(LBS_DEB_USB);
-
- /* Unlink tx & rx urb */
- usb_kill_urb(cardp->tx_urb);
- usb_kill_urb(cardp->rx_urb);
-
- usb_free_urb(cardp->tx_urb);
- cardp->tx_urb = NULL;
-
- usb_free_urb(cardp->rx_urb);
- cardp->rx_urb = NULL;
-
- kfree(cardp->ep_out_buf);
- cardp->ep_out_buf = NULL;
-
- lbs_deb_leave(LBS_DEB_USB);
-}
-
-static void if_usb_setup_firmware(struct lbs_private *priv)
-{
- struct if_usb_card *cardp = priv->card;
- struct cmd_ds_set_boot2_ver b2_cmd;
- struct cmd_ds_802_11_fw_wake_method wake_method;
-
- b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
- b2_cmd.action = 0;
- b2_cmd.version = cardp->boot2_version;
-
- if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
- lbs_deb_usb("Setting boot2 version failed\n");
-
- priv->wol_gpio = 2; /* Wake via GPIO2... */
- priv->wol_gap = 20; /* ... after 20ms */
- lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
- (struct wol_config *) NULL);
-
- wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
- wake_method.action = cpu_to_le16(CMD_ACT_GET);
- if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
- netdev_info(priv->dev, "Firmware does not seem to support PS mode\n");
- priv->fwcapinfo &= ~FW_CAPINFO_PS;
- } else {
- if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
- lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
- } else {
- /* The versions which boot up this way don't seem to
- work even if we set it to the command interrupt */
- priv->fwcapinfo &= ~FW_CAPINFO_PS;
- netdev_info(priv->dev,
- "Firmware doesn't wake via command interrupt; disabling PS mode\n");
- }
- }
-}
-
-static void if_usb_fw_timeo(unsigned long priv)
-{
- struct if_usb_card *cardp = (void *)priv;
-
- if (cardp->fwdnldover) {
- lbs_deb_usb("Download complete, no event. Assuming success\n");
- } else {
- pr_err("Download timed out\n");
- cardp->surprise_removed = 1;
- }
- wake_up(&cardp->fw_wq);
-}
-
-#ifdef CONFIG_OLPC
-static void if_usb_reset_olpc_card(struct lbs_private *priv)
-{
- printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
- olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
-}
-#endif
-
-/**
- * if_usb_probe - sets the configuration values
- * @intf: &usb_interface pointer
- * @id: pointer to usb_device_id
- * returns: 0 on success, error code on failure
- */
-static int if_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- struct lbs_private *priv;
- struct if_usb_card *cardp;
- int r = -ENOMEM;
- int i;
-
- udev = interface_to_usbdev(intf);
-
- cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
- if (!cardp)
- goto error;
-
- setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
- init_waitqueue_head(&cardp->fw_wq);
-
- cardp->udev = udev;
- cardp->model = (uint32_t) id->driver_info;
- iface_desc = intf->cur_altsetting;
-
- lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
- " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
- le16_to_cpu(udev->descriptor.bcdUSB),
- udev->descriptor.bDeviceClass,
- udev->descriptor.bDeviceSubClass,
- udev->descriptor.bDeviceProtocol);
-
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (usb_endpoint_is_bulk_in(endpoint)) {
- cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
- cardp->ep_in = usb_endpoint_num(endpoint);
-
- lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
- lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
-
- } else if (usb_endpoint_is_bulk_out(endpoint)) {
- cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
- cardp->ep_out = usb_endpoint_num(endpoint);
-
- lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
- lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
- }
- }
- if (!cardp->ep_out_size || !cardp->ep_in_size) {
- lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
- goto dealloc;
- }
- if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
- lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
- goto dealloc;
- }
- if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
- lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
- goto dealloc;
- }
- cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
- if (!cardp->ep_out_buf) {
- lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
- goto dealloc;
- }
-
- if (!(priv = lbs_add_card(cardp, &intf->dev)))
- goto err_add_card;
-
- cardp->priv = priv;
-
- priv->hw_host_to_card = if_usb_host_to_card;
- priv->enter_deep_sleep = NULL;
- priv->exit_deep_sleep = NULL;
- priv->reset_deep_sleep_wakeup = NULL;
-#ifdef CONFIG_OLPC
- if (machine_is_olpc())
- priv->reset_card = if_usb_reset_olpc_card;
-#endif
-
- cardp->boot2_version = udev->descriptor.bcdDevice;
-
- usb_get_dev(udev);
- usb_set_intfdata(intf, cardp);
-
- r = lbs_get_firmware_async(priv, &udev->dev, cardp->model,
- fw_table, if_usb_prog_firmware);
- if (r)
- goto err_get_fw;
-
- return 0;
-
-err_get_fw:
- lbs_remove_card(priv);
-err_add_card:
- if_usb_reset_device(cardp);
-dealloc:
- if_usb_free(cardp);
-
-error:
- return r;
-}
-
-/**
- * if_usb_disconnect - free resource and cleanup
- * @intf: USB interface structure
- * returns: N/A
- */
-static void if_usb_disconnect(struct usb_interface *intf)
-{
- struct if_usb_card *cardp = usb_get_intfdata(intf);
- struct lbs_private *priv = cardp->priv;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- cardp->surprise_removed = 1;
-
- if (priv) {
- lbs_stop_card(priv);
- lbs_remove_card(priv);
- }
-
- /* Unlink and free urb */
- if_usb_free(cardp);
-
- usb_set_intfdata(intf, NULL);
- usb_put_dev(interface_to_usbdev(intf));
-
- lbs_deb_leave(LBS_DEB_MAIN);
-}
-
-/**
- * if_usb_send_fw_pkt - download FW
- * @cardp: pointer to &struct if_usb_card
- * returns: 0
- */
-static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
-{
- struct fwdata *fwdata = cardp->ep_out_buf;
- const uint8_t *firmware = cardp->fw->data;
-
- /* If we got a CRC failure on the last block, back
- up and retry it */
- if (!cardp->CRC_OK) {
- cardp->totalbytes = cardp->fwlastblksent;
- cardp->fwseqnum--;
- }
-
- lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
- cardp->totalbytes);
-
- /* struct fwdata (which we sent to the card) has an
- extra __le32 field in between the header and the data,
- which is not in the struct fwheader in the actual
- firmware binary. Insert the seqnum in the middle... */
- memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
- sizeof(struct fwheader));
-
- cardp->fwlastblksent = cardp->totalbytes;
- cardp->totalbytes += sizeof(struct fwheader);
-
- memcpy(fwdata->data, &firmware[cardp->totalbytes],
- le32_to_cpu(fwdata->hdr.datalength));
-
- lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
- le32_to_cpu(fwdata->hdr.datalength));
-
- fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
- cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
-
- usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
- le32_to_cpu(fwdata->hdr.datalength));
-
- if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
- lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
- lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
- cardp->fwseqnum, cardp->totalbytes);
- } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
- lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
- lbs_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
-
- cardp->fwfinalblk = 1;
- }
-
- lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
- cardp->totalbytes);
-
- return 0;
-}
-
-static int if_usb_reset_device(struct if_usb_card *cardp)
-{
- struct cmd_header *cmd = cardp->ep_out_buf + 4;
- int ret;
-
- lbs_deb_enter(LBS_DEB_USB);
-
- *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
-
- cmd->command = cpu_to_le16(CMD_802_11_RESET);
- cmd->size = cpu_to_le16(sizeof(cmd));
- cmd->result = cpu_to_le16(0);
- cmd->seqnum = cpu_to_le16(0x5a5a);
- usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header));
-
- msleep(100);
- ret = usb_reset_device(cardp->udev);
- msleep(100);
-
-#ifdef CONFIG_OLPC
- if (ret && machine_is_olpc())
- if_usb_reset_olpc_card(NULL);
-#endif
-
- lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
-
- return ret;
-}
-
-/**
- * usb_tx_block - transfer the data to the device
- * @cardp: pointer to &struct if_usb_card
- * @payload: pointer to payload data
- * @nb: data length
- * returns: 0 for success or negative error code
- */
-static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
-{
- int ret;
-
- /* check if device is removed */
- if (cardp->surprise_removed) {
- lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
- ret = -ENODEV;
- goto tx_ret;
- }
-
- usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
- usb_sndbulkpipe(cardp->udev,
- cardp->ep_out),
- payload, nb, if_usb_write_bulk_callback, cardp);
-
- cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
-
- if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
- lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
- } else {
- lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
- ret = 0;
- }
-
-tx_ret:
- return ret;
-}
-
-static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
- void (*callbackfn)(struct urb *urb))
-{
- struct sk_buff *skb;
- int ret = -1;
-
- if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
- pr_err("No free skb\n");
- goto rx_ret;
- }
-
- cardp->rx_skb = skb;
-
- /* Fill the receive configuration URB and initialise the Rx call back */
- usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
- usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
- skb->data + IPFIELD_ALIGN_OFFSET,
- MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
- cardp);
-
- cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
-
- lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
- if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
- lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
- kfree_skb(skb);
- cardp->rx_skb = NULL;
- ret = -1;
- } else {
- lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
- ret = 0;
- }
-
-rx_ret:
- return ret;
-}
-
-static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
-{
- return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
-}
-
-static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
-{
- return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
-}
-
-static void if_usb_receive_fwload(struct urb *urb)
-{
- struct if_usb_card *cardp = urb->context;
- struct sk_buff *skb = cardp->rx_skb;
- struct fwsyncheader *syncfwheader;
- struct bootcmdresp bootcmdresp;
-
- if (urb->status) {
- lbs_deb_usbd(&cardp->udev->dev,
- "URB status is failed during fw load\n");
- kfree_skb(skb);
- return;
- }
-
- if (cardp->fwdnldover) {
- __le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
-
- if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
- tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
- pr_info("Firmware ready event received\n");
- wake_up(&cardp->fw_wq);
- } else {
- lbs_deb_usb("Waiting for confirmation; got %x %x\n",
- le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
- if_usb_submit_rx_urb_fwload(cardp);
- }
- kfree_skb(skb);
- return;
- }
- if (cardp->bootcmdresp <= 0) {
- memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
- sizeof(bootcmdresp));
-
- if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
- kfree_skb(skb);
- if_usb_submit_rx_urb_fwload(cardp);
- cardp->bootcmdresp = BOOT_CMD_RESP_OK;
- lbs_deb_usbd(&cardp->udev->dev,
- "Received valid boot command response\n");
- return;
- }
- if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
- if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
- bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
- bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
- if (!cardp->bootcmdresp)
- pr_info("Firmware already seems alive; resetting\n");
- cardp->bootcmdresp = -1;
- } else {
- pr_info("boot cmd response wrong magic number (0x%x)\n",
- le32_to_cpu(bootcmdresp.magic));
- }
- } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
- (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
- (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
- pr_info("boot cmd response cmd_tag error (%d)\n",
- bootcmdresp.cmd);
- } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
- pr_info("boot cmd response result error (%d)\n",
- bootcmdresp.result);
- } else {
- cardp->bootcmdresp = 1;
- lbs_deb_usbd(&cardp->udev->dev,
- "Received valid boot command response\n");
- }
- kfree_skb(skb);
- if_usb_submit_rx_urb_fwload(cardp);
- return;
- }
-
- syncfwheader = kmemdup(skb->data + IPFIELD_ALIGN_OFFSET,
- sizeof(struct fwsyncheader), GFP_ATOMIC);
- if (!syncfwheader) {
- lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
- kfree_skb(skb);
- return;
- }
-
- if (!syncfwheader->cmd) {
- lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
- lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
- le32_to_cpu(syncfwheader->seqnum));
- cardp->CRC_OK = 1;
- } else {
- lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
- cardp->CRC_OK = 0;
- }
-
- kfree_skb(skb);
-
- /* Give device 5s to either write firmware to its RAM or eeprom */
- mod_timer(&cardp->fw_timeout, jiffies + (HZ*5));
-
- if (cardp->fwfinalblk) {
- cardp->fwdnldover = 1;
- goto exit;
- }
-
- if_usb_send_fw_pkt(cardp);
-
- exit:
- if_usb_submit_rx_urb_fwload(cardp);
-
- kfree(syncfwheader);
-}
-
-#define MRVDRV_MIN_PKT_LEN 30
-
-static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
- struct if_usb_card *cardp,
- struct lbs_private *priv)
-{
- if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
- || recvlength < MRVDRV_MIN_PKT_LEN) {
- lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
- kfree_skb(skb);
- return;
- }
-
- skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
- skb_put(skb, recvlength);
- skb_pull(skb, MESSAGE_HEADER_LEN);
-
- lbs_process_rxed_packet(priv, skb);
-}
-
-static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
- struct sk_buff *skb,
- struct if_usb_card *cardp,
- struct lbs_private *priv)
-{
- u8 i;
-
- if (recvlength > LBS_CMD_BUFFER_SIZE) {
- lbs_deb_usbd(&cardp->udev->dev,
- "The receive buffer is too large\n");
- kfree_skb(skb);
- return;
- }
-
- BUG_ON(!in_interrupt());
-
- spin_lock(&priv->driver_lock);
-
- i = (priv->resp_idx == 0) ? 1 : 0;
- BUG_ON(priv->resp_len[i]);
- priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN);
- memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN,
- priv->resp_len[i]);
- kfree_skb(skb);
- lbs_notify_command_response(priv, i);
-
- spin_unlock(&priv->driver_lock);
-
- lbs_deb_usbd(&cardp->udev->dev,
- "Wake up main thread to handle cmd response\n");
-}
-
-/**
- * if_usb_receive - read the packet into the upload buffer,
- * wake up the main thread and initialise the Rx callack
- *
- * @urb: pointer to &struct urb
- * returns: N/A
- */
-static void if_usb_receive(struct urb *urb)
-{
- struct if_usb_card *cardp = urb->context;
- struct sk_buff *skb = cardp->rx_skb;
- struct lbs_private *priv = cardp->priv;
- int recvlength = urb->actual_length;
- uint8_t *recvbuff = NULL;
- uint32_t recvtype = 0;
- __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
- uint32_t event;
-
- lbs_deb_enter(LBS_DEB_USB);
-
- if (recvlength) {
- if (urb->status) {
- lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
- urb->status);
- kfree_skb(skb);
- goto setup_for_next;
- }
-
- recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
- recvtype = le32_to_cpu(pkt[0]);
- lbs_deb_usbd(&cardp->udev->dev,
- "Recv length = 0x%x, Recv type = 0x%X\n",
- recvlength, recvtype);
- } else if (urb->status) {
- kfree_skb(skb);
- goto rx_exit;
- }
-
- switch (recvtype) {
- case CMD_TYPE_DATA:
- process_cmdtypedata(recvlength, skb, cardp, priv);
- break;
-
- case CMD_TYPE_REQUEST:
- process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
- break;
-
- case CMD_TYPE_INDICATION:
- /* Event handling */
- event = le32_to_cpu(pkt[1]);
- lbs_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event);
- kfree_skb(skb);
-
- /* Icky undocumented magic special case */
- if (event & 0xffff0000) {
- u32 trycount = (event & 0xffff0000) >> 16;
-
- lbs_send_tx_feedback(priv, trycount);
- } else
- lbs_queue_event(priv, event & 0xFF);
- break;
-
- default:
- lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
- recvtype);
- kfree_skb(skb);
- break;
- }
-
-setup_for_next:
- if_usb_submit_rx_urb(cardp);
-rx_exit:
- lbs_deb_leave(LBS_DEB_USB);
-}
-
-/**
- * if_usb_host_to_card - downloads data to FW
- * @priv: pointer to &struct lbs_private structure
- * @type: type of data
- * @payload: pointer to data buffer
- * @nb: number of bytes
- * returns: 0 for success or negative error code
- */
-static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
- uint8_t *payload, uint16_t nb)
-{
- struct if_usb_card *cardp = priv->card;
-
- lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
- lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
-
- if (type == MVMS_CMD) {
- *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
- priv->dnld_sent = DNLD_CMD_SENT;
- } else {
- *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
- priv->dnld_sent = DNLD_DATA_SENT;
- }
-
- memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
-
- return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
-}
-
-/**
- * if_usb_issue_boot_command - issues Boot command to the Boot2 code
- * @cardp: pointer to &if_usb_card
- * @ivalue: 1:Boot from FW by USB-Download
- * 2:Boot from FW in EEPROM
- * returns: 0 for success or negative error code
- */
-static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
-{
- struct bootcmd *bootcmd = cardp->ep_out_buf;
-
- /* Prepare command */
- bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
- bootcmd->cmd = ivalue;
- memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
-
- /* Issue command */
- usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
-
- return 0;
-}
-
-
-/**
- * check_fwfile_format - check the validity of Boot2/FW image
- *
- * @data: pointer to image
- * @totlen: image length
- * returns: 0 (good) or 1 (failure)
- */
-static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
-{
- uint32_t bincmd, exit;
- uint32_t blksize, offset, len;
- int ret;
-
- ret = 1;
- exit = len = 0;
-
- do {
- struct fwheader *fwh = (void *)data;
-
- bincmd = le32_to_cpu(fwh->dnldcmd);
- blksize = le32_to_cpu(fwh->datalength);
- switch (bincmd) {
- case FW_HAS_DATA_TO_RECV:
- offset = sizeof(struct fwheader) + blksize;
- data += offset;
- len += offset;
- if (len >= totlen)
- exit = 1;
- break;
- case FW_HAS_LAST_BLOCK:
- exit = 1;
- ret = 0;
- break;
- default:
- exit = 1;
- break;
- }
- } while (!exit);
-
- if (ret)
- pr_err("firmware file format check FAIL\n");
- else
- lbs_deb_fw("firmware file format check PASS\n");
-
- return ret;
-}
-
-static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
- const struct firmware *fw,
- const struct firmware *unused)
-{
- struct if_usb_card *cardp = priv->card;
- int i = 0;
- static int reset_count = 10;
-
- lbs_deb_enter(LBS_DEB_USB);
-
- if (ret) {
- pr_err("failed to find firmware (%d)\n", ret);
- goto done;
- }
-
- cardp->fw = fw;
- if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
- ret = -EINVAL;
- goto done;
- }
-
- /* Cancel any pending usb business */
- usb_kill_urb(cardp->rx_urb);
- usb_kill_urb(cardp->tx_urb);
-
- cardp->fwlastblksent = 0;
- cardp->fwdnldover = 0;
- cardp->totalbytes = 0;
- cardp->fwfinalblk = 0;
- cardp->bootcmdresp = 0;
-
-restart:
- if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
- lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
- ret = -EIO;
- goto done;
- }
-
- cardp->bootcmdresp = 0;
- do {
- int j = 0;
- i++;
- if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
- /* wait for command response */
- do {
- j++;
- msleep_interruptible(100);
- } while (cardp->bootcmdresp == 0 && j < 10);
- } while (cardp->bootcmdresp == 0 && i < 5);
-
- if (cardp->bootcmdresp == BOOT_CMD_RESP_NOT_SUPPORTED) {
- /* Return to normal operation */
- ret = -EOPNOTSUPP;
- usb_kill_urb(cardp->rx_urb);
- usb_kill_urb(cardp->tx_urb);
- if (if_usb_submit_rx_urb(cardp) < 0)
- ret = -EIO;
- goto done;
- } else if (cardp->bootcmdresp <= 0) {
- if (--reset_count >= 0) {
- if_usb_reset_device(cardp);
- goto restart;
- }
- ret = -EIO;
- goto done;
- }
-
- i = 0;
-
- cardp->totalbytes = 0;
- cardp->fwlastblksent = 0;
- cardp->CRC_OK = 1;
- cardp->fwdnldover = 0;
- cardp->fwseqnum = -1;
- cardp->totalbytes = 0;
- cardp->fwfinalblk = 0;
-
- /* Send the first firmware packet... */
- if_usb_send_fw_pkt(cardp);
-
- /* ... and wait for the process to complete */
- wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
-
- del_timer_sync(&cardp->fw_timeout);
- usb_kill_urb(cardp->rx_urb);
-
- if (!cardp->fwdnldover) {
- pr_info("failed to load fw, resetting device!\n");
- if (--reset_count >= 0) {
- if_usb_reset_device(cardp);
- goto restart;
- }
-
- pr_info("FW download failure, time = %d ms\n", i * 100);
- ret = -EIO;
- goto done;
- }
-
- cardp->priv->fw_ready = 1;
- if_usb_submit_rx_urb(cardp);
-
- if (lbs_start_card(priv))
- goto done;
-
- if_usb_setup_firmware(priv);
-
- /*
- * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
- */
- priv->wol_criteria = EHS_REMOVE_WAKEUP;
- if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
- priv->ehs_remove_supported = false;
-
- done:
- cardp->fw = NULL;
- lbs_deb_leave(LBS_DEB_USB);
-}
-
-
-#ifdef CONFIG_PM
-static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct if_usb_card *cardp = usb_get_intfdata(intf);
- struct lbs_private *priv = cardp->priv;
- int ret;
-
- lbs_deb_enter(LBS_DEB_USB);
-
- if (priv->psstate != PS_STATE_FULL_POWER) {
- ret = -1;
- goto out;
- }
-
-#ifdef CONFIG_OLPC
- if (machine_is_olpc()) {
- if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
- olpc_ec_wakeup_clear(EC_SCI_SRC_WLAN);
- else
- olpc_ec_wakeup_set(EC_SCI_SRC_WLAN);
- }
-#endif
-
- ret = lbs_suspend(priv);
- if (ret)
- goto out;
-
- /* Unlink tx & rx urb */
- usb_kill_urb(cardp->tx_urb);
- usb_kill_urb(cardp->rx_urb);
-
- out:
- lbs_deb_leave(LBS_DEB_USB);
- return ret;
-}
-
-static int if_usb_resume(struct usb_interface *intf)
-{
- struct if_usb_card *cardp = usb_get_intfdata(intf);
- struct lbs_private *priv = cardp->priv;
-
- lbs_deb_enter(LBS_DEB_USB);
-
- if_usb_submit_rx_urb(cardp);
-
- lbs_resume(priv);
-
- lbs_deb_leave(LBS_DEB_USB);
- return 0;
-}
-#else
-#define if_usb_suspend NULL
-#define if_usb_resume NULL
-#endif
-
-static struct usb_driver if_usb_driver = {
- .name = DRV_NAME,
- .probe = if_usb_probe,
- .disconnect = if_usb_disconnect,
- .id_table = if_usb_table,
- .suspend = if_usb_suspend,
- .resume = if_usb_resume,
- .reset_resume = if_usb_resume,
- .disable_hub_initiated_lpm = 1,
-};
-
-module_usb_driver(if_usb_driver);
-
-MODULE_DESCRIPTION("8388 USB WLAN Driver");
-MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
deleted file mode 100644
index 6e42eac33..000000000
--- a/drivers/net/wireless/libertas/if_usb.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef _LBS_IF_USB_H
-#define _LBS_IF_USB_H
-
-#include <linux/wait.h>
-#include <linux/timer.h>
-
-struct lbs_private;
-
-/*
- * This file contains definition for USB interface.
- */
-#define CMD_TYPE_REQUEST 0xF00DFACE
-#define CMD_TYPE_DATA 0xBEADC0DE
-#define CMD_TYPE_INDICATION 0xBEEFFACE
-
-#define IPFIELD_ALIGN_OFFSET 2
-
-#define BOOT_CMD_FW_BY_USB 0x01
-#define BOOT_CMD_FW_IN_EEPROM 0x02
-#define BOOT_CMD_UPDATE_BOOT2 0x03
-#define BOOT_CMD_UPDATE_FW 0x04
-#define BOOT_CMD_MAGIC_NUMBER 0x4C56524D /* LVRM */
-
-struct bootcmd
-{
- __le32 magic;
- uint8_t cmd;
- uint8_t pad[11];
-};
-
-#define BOOT_CMD_RESP_OK 0x0001
-#define BOOT_CMD_RESP_FAIL 0x0000
-#define BOOT_CMD_RESP_NOT_SUPPORTED 0x0002
-
-struct bootcmdresp
-{
- __le32 magic;
- uint8_t cmd;
- uint8_t result;
- uint8_t pad[2];
-};
-
-/* USB card description structure*/
-struct if_usb_card {
- struct usb_device *udev;
- uint32_t model; /* MODEL_* */
- struct urb *rx_urb, *tx_urb;
- struct lbs_private *priv;
-
- struct sk_buff *rx_skb;
-
- uint8_t ep_in;
- uint8_t ep_out;
-
- /* bootcmdresp == 0 means command is pending
- * bootcmdresp < 0 means error
- * bootcmdresp > 0 is a BOOT_CMD_RESP_* from firmware
- */
- int8_t bootcmdresp;
-
- int ep_in_size;
-
- void *ep_out_buf;
- int ep_out_size;
-
- const struct firmware *fw;
- struct timer_list fw_timeout;
- wait_queue_head_t fw_wq;
- uint32_t fwseqnum;
- uint32_t totalbytes;
- uint32_t fwlastblksent;
- uint8_t CRC_OK;
- uint8_t fwdnldover;
- uint8_t fwfinalblk;
- uint8_t surprise_removed;
-
- __le16 boot2_version;
-};
-
-/* fwheader */
-struct fwheader {
- __le32 dnldcmd;
- __le32 baseaddr;
- __le32 datalength;
- __le32 CRC;
-};
-
-#define FW_MAX_DATA_BLK_SIZE 600
-/* FWData */
-struct fwdata {
- struct fwheader hdr;
- __le32 seqnum;
- uint8_t data[0];
-};
-
-/* fwsyncheader */
-struct fwsyncheader {
- __le32 cmd;
- __le32 seqnum;
-};
-
-#define FW_HAS_DATA_TO_RECV 0x00000001
-#define FW_HAS_LAST_BLOCK 0x00000004
-
-
-#endif
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
deleted file mode 100644
index 8079560f4..000000000
--- a/drivers/net/wireless/libertas/main.c
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * This file contains the major functions in WLAN
- * driver. It includes init, exit, open, close and main
- * thread etc..
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/etherdevice.h>
-#include <linux/hardirq.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/kthread.h>
-#include <linux/kfifo.h>
-#include <linux/slab.h>
-#include <net/cfg80211.h>
-
-#include "host.h"
-#include "decl.h"
-#include "dev.h"
-#include "cfg.h"
-#include "debugfs.h"
-#include "cmd.h"
-#include "mesh.h"
-
-#define DRIVER_RELEASE_VERSION "323.p0"
-const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
-#ifdef DEBUG
- "-dbg"
-#endif
- "";
-
-
-/* Module parameters */
-unsigned int lbs_debug;
-EXPORT_SYMBOL_GPL(lbs_debug);
-module_param_named(libertas_debug, lbs_debug, int, 0644);
-
-unsigned int lbs_disablemesh;
-EXPORT_SYMBOL_GPL(lbs_disablemesh);
-module_param_named(libertas_disablemesh, lbs_disablemesh, int, 0644);
-
-
-/*
- * This global structure is used to send the confirm_sleep command as
- * fast as possible down to the firmware.
- */
-struct cmd_confirm_sleep confirm_sleep;
-
-
-/*
- * the table to keep region code
- */
-u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
- { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
-
-/*
- * FW rate table. FW refers to rates by their index in this table, not by the
- * rate value itself. Values of 0x00 are
- * reserved positions.
- */
-static u8 fw_data_rates[MAX_RATES] =
- { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
- 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
-};
-
-/**
- * lbs_fw_index_to_data_rate - use index to get the data rate
- *
- * @idx: The index of data rate
- * returns: data rate or 0
- */
-u32 lbs_fw_index_to_data_rate(u8 idx)
-{
- if (idx >= sizeof(fw_data_rates))
- idx = 0;
- return fw_data_rates[idx];
-}
-
-/**
- * lbs_data_rate_to_fw_index - use rate to get the index
- *
- * @rate: data rate
- * returns: index or 0
- */
-u8 lbs_data_rate_to_fw_index(u32 rate)
-{
- u8 i;
-
- if (!rate)
- return 0;
-
- for (i = 0; i < sizeof(fw_data_rates); i++) {
- if (rate == fw_data_rates[i])
- return i;
- }
- return 0;
-}
-
-int lbs_set_iface_type(struct lbs_private *priv, enum nl80211_iftype type)
-{
- int ret = 0;
-
- switch (type) {
- case NL80211_IFTYPE_MONITOR:
- ret = lbs_set_monitor_mode(priv, 1);
- break;
- case NL80211_IFTYPE_STATION:
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
- ret = lbs_set_monitor_mode(priv, 0);
- if (!ret)
- ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
- break;
- case NL80211_IFTYPE_ADHOC:
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
- ret = lbs_set_monitor_mode(priv, 0);
- if (!ret)
- ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
- break;
- default:
- ret = -ENOTSUPP;
- }
- return ret;
-}
-
-int lbs_start_iface(struct lbs_private *priv)
-{
- struct cmd_ds_802_11_mac_address cmd;
- int ret;
-
- if (priv->power_restore) {
- ret = priv->power_restore(priv);
- if (ret)
- return ret;
- }
-
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_SET);
- memcpy(cmd.macadd, priv->current_addr, ETH_ALEN);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_MAC_ADDRESS, &cmd);
- if (ret) {
- lbs_deb_net("set MAC address failed\n");
- goto err;
- }
-
- ret = lbs_set_iface_type(priv, priv->wdev->iftype);
- if (ret) {
- lbs_deb_net("set iface type failed\n");
- goto err;
- }
-
- ret = lbs_set_11d_domain_info(priv);
- if (ret) {
- lbs_deb_net("set 11d domain info failed\n");
- goto err;
- }
-
- lbs_update_channel(priv);
-
- priv->iface_running = true;
- return 0;
-
-err:
- if (priv->power_save)
- priv->power_save(priv);
- return ret;
-}
-
-/**
- * lbs_dev_open - open the ethX interface
- *
- * @dev: A pointer to &net_device structure
- * returns: 0 or -EBUSY if monitor mode active
- */
-static int lbs_dev_open(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_NET);
- if (!priv->iface_running) {
- ret = lbs_start_iface(priv);
- if (ret)
- goto out;
- }
-
- spin_lock_irq(&priv->driver_lock);
-
- netif_carrier_off(dev);
-
- if (!priv->tx_pending_len)
- netif_wake_queue(dev);
-
- spin_unlock_irq(&priv->driver_lock);
-
-out:
- lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
- return ret;
-}
-
-static bool lbs_command_queue_empty(struct lbs_private *priv)
-{
- unsigned long flags;
- bool ret;
- spin_lock_irqsave(&priv->driver_lock, flags);
- ret = priv->cur_cmd == NULL && list_empty(&priv->cmdpendingq);
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- return ret;
-}
-
-int lbs_stop_iface(struct lbs_private *priv)
-{
- unsigned long flags;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- priv->iface_running = false;
- kfree_skb(priv->currenttxskb);
- priv->currenttxskb = NULL;
- priv->tx_pending_len = 0;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- cancel_work_sync(&priv->mcast_work);
- del_timer_sync(&priv->tx_lockup_timer);
-
- /* Disable command processing, and wait for all commands to complete */
- lbs_deb_main("waiting for commands to complete\n");
- wait_event(priv->waitq, lbs_command_queue_empty(priv));
- lbs_deb_main("all commands completed\n");
-
- if (priv->power_save)
- ret = priv->power_save(priv);
-
- lbs_deb_leave(LBS_DEB_MAIN);
- return ret;
-}
-
-/**
- * lbs_eth_stop - close the ethX interface
- *
- * @dev: A pointer to &net_device structure
- * returns: 0
- */
-static int lbs_eth_stop(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_NET);
-
- if (priv->connect_status == LBS_CONNECTED)
- lbs_disconnect(priv, WLAN_REASON_DEAUTH_LEAVING);
-
- spin_lock_irq(&priv->driver_lock);
- netif_stop_queue(dev);
- spin_unlock_irq(&priv->driver_lock);
-
- lbs_update_mcast(priv);
- cancel_delayed_work_sync(&priv->scan_work);
- if (priv->scan_req)
- lbs_scan_done(priv);
-
- netif_carrier_off(priv->dev);
-
- if (!lbs_iface_active(priv))
- lbs_stop_iface(priv);
-
- lbs_deb_leave(LBS_DEB_NET);
- return 0;
-}
-
-void lbs_host_to_card_done(struct lbs_private *priv)
-{
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_THREAD);
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- del_timer(&priv->tx_lockup_timer);
-
- priv->dnld_sent = DNLD_RES_RECEIVED;
-
- /* Wake main thread if commands are pending */
- if (!priv->cur_cmd || priv->tx_pending_len > 0) {
- if (!priv->wakeup_dev_required)
- wake_up(&priv->waitq);
- }
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- lbs_deb_leave(LBS_DEB_THREAD);
-}
-EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
-
-int lbs_set_mac_address(struct net_device *dev, void *addr)
-{
- int ret = 0;
- struct lbs_private *priv = dev->ml_priv;
- struct sockaddr *phwaddr = addr;
-
- lbs_deb_enter(LBS_DEB_NET);
-
- /*
- * Can only set MAC address when all interfaces are down, to be written
- * to the hardware when one of them is brought up.
- */
- if (lbs_iface_active(priv))
- return -EBUSY;
-
- /* In case it was called from the mesh device */
- dev = priv->dev;
-
- memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
- memcpy(dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
- if (priv->mesh_dev)
- memcpy(priv->mesh_dev->dev_addr, phwaddr->sa_data, ETH_ALEN);
-
- lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
- return ret;
-}
-
-
-static inline int mac_in_list(unsigned char *list, int list_len,
- unsigned char *mac)
-{
- while (list_len) {
- if (!memcmp(list, mac, ETH_ALEN))
- return 1;
- list += ETH_ALEN;
- list_len--;
- }
- return 0;
-}
-
-
-static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
- struct net_device *dev, int nr_addrs)
-{
- int i = nr_addrs;
- struct netdev_hw_addr *ha;
- int cnt;
-
- if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
- return nr_addrs;
-
- netif_addr_lock_bh(dev);
- cnt = netdev_mc_count(dev);
- netdev_for_each_mc_addr(ha, dev) {
- if (mac_in_list(cmd->maclist, nr_addrs, ha->addr)) {
- lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
- ha->addr);
- cnt--;
- continue;
- }
-
- if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
- break;
- memcpy(&cmd->maclist[6*i], ha->addr, ETH_ALEN);
- lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
- ha->addr);
- i++;
- cnt--;
- }
- netif_addr_unlock_bh(dev);
- if (cnt)
- return -EOVERFLOW;
-
- return i;
-}
-
-void lbs_update_mcast(struct lbs_private *priv)
-{
- struct cmd_ds_mac_multicast_adr mcast_cmd;
- int dev_flags = 0;
- int nr_addrs;
- int old_mac_control = priv->mac_control;
-
- lbs_deb_enter(LBS_DEB_NET);
-
- if (netif_running(priv->dev))
- dev_flags |= priv->dev->flags;
- if (priv->mesh_dev && netif_running(priv->mesh_dev))
- dev_flags |= priv->mesh_dev->flags;
-
- if (dev_flags & IFF_PROMISC) {
- priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE;
- priv->mac_control &= ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
- CMD_ACT_MAC_MULTICAST_ENABLE);
- goto out_set_mac_control;
- } else if (dev_flags & IFF_ALLMULTI) {
- do_allmulti:
- priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
- priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
- CMD_ACT_MAC_MULTICAST_ENABLE);
- goto out_set_mac_control;
- }
-
- /* Once for priv->dev, again for priv->mesh_dev if it exists */
- nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->dev, 0);
- if (nr_addrs >= 0 && priv->mesh_dev)
- nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->mesh_dev, nr_addrs);
- if (nr_addrs < 0)
- goto do_allmulti;
-
- if (nr_addrs) {
- int size = offsetof(struct cmd_ds_mac_multicast_adr,
- maclist[6*nr_addrs]);
-
- mcast_cmd.action = cpu_to_le16(CMD_ACT_SET);
- mcast_cmd.hdr.size = cpu_to_le16(size);
- mcast_cmd.nr_of_adrs = cpu_to_le16(nr_addrs);
-
- lbs_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &mcast_cmd.hdr, size);
-
- priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
- } else
- priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
-
- priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
- CMD_ACT_MAC_ALL_MULTICAST_ENABLE);
- out_set_mac_control:
- if (priv->mac_control != old_mac_control)
- lbs_set_mac_control(priv);
-
- lbs_deb_leave(LBS_DEB_NET);
-}
-
-static void lbs_set_mcast_worker(struct work_struct *work)
-{
- struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
- lbs_update_mcast(priv);
-}
-
-void lbs_set_multicast_list(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- schedule_work(&priv->mcast_work);
-}
-
-/**
- * lbs_thread - handles the major jobs in the LBS driver.
- * It handles all events generated by firmware, RX data received
- * from firmware and TX data sent from kernel.
- *
- * @data: A pointer to &lbs_thread structure
- * returns: 0
- */
-static int lbs_thread(void *data)
-{
- struct net_device *dev = data;
- struct lbs_private *priv = dev->ml_priv;
- wait_queue_t wait;
-
- lbs_deb_enter(LBS_DEB_THREAD);
-
- init_waitqueue_entry(&wait, current);
-
- for (;;) {
- int shouldsleep;
- u8 resp_idx;
-
- lbs_deb_thread("1: currenttxskb %p, dnld_sent %d\n",
- priv->currenttxskb, priv->dnld_sent);
-
- add_wait_queue(&priv->waitq, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irq(&priv->driver_lock);
-
- if (kthread_should_stop())
- shouldsleep = 0; /* Bye */
- else if (priv->surpriseremoved)
- shouldsleep = 1; /* We need to wait until we're _told_ to die */
- else if (priv->psstate == PS_STATE_SLEEP)
- shouldsleep = 1; /* Sleep mode. Nothing we can do till it wakes */
- else if (priv->cmd_timed_out)
- shouldsleep = 0; /* Command timed out. Recover */
- else if (!priv->fw_ready)
- shouldsleep = 1; /* Firmware not ready. We're waiting for it */
- else if (priv->dnld_sent)
- shouldsleep = 1; /* Something is en route to the device already */
- else if (priv->tx_pending_len > 0)
- shouldsleep = 0; /* We've a packet to send */
- else if (priv->resp_len[priv->resp_idx])
- shouldsleep = 0; /* We have a command response */
- else if (priv->cur_cmd)
- shouldsleep = 1; /* Can't send a command; one already running */
- else if (!list_empty(&priv->cmdpendingq) &&
- !(priv->wakeup_dev_required))
- shouldsleep = 0; /* We have a command to send */
- else if (kfifo_len(&priv->event_fifo))
- shouldsleep = 0; /* We have an event to process */
- else
- shouldsleep = 1; /* No command */
-
- if (shouldsleep) {
- lbs_deb_thread("sleeping, connect_status %d, "
- "psmode %d, psstate %d\n",
- priv->connect_status,
- priv->psmode, priv->psstate);
- spin_unlock_irq(&priv->driver_lock);
- schedule();
- } else
- spin_unlock_irq(&priv->driver_lock);
-
- lbs_deb_thread("2: currenttxskb %p, dnld_send %d\n",
- priv->currenttxskb, priv->dnld_sent);
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&priv->waitq, &wait);
-
- lbs_deb_thread("3: currenttxskb %p, dnld_sent %d\n",
- priv->currenttxskb, priv->dnld_sent);
-
- if (kthread_should_stop()) {
- lbs_deb_thread("break from main thread\n");
- break;
- }
-
- if (priv->surpriseremoved) {
- lbs_deb_thread("adapter removed; waiting to die...\n");
- continue;
- }
-
- lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n",
- priv->currenttxskb, priv->dnld_sent);
-
- /* Process any pending command response */
- spin_lock_irq(&priv->driver_lock);
- resp_idx = priv->resp_idx;
- if (priv->resp_len[resp_idx]) {
- spin_unlock_irq(&priv->driver_lock);
- lbs_process_command_response(priv,
- priv->resp_buf[resp_idx],
- priv->resp_len[resp_idx]);
- spin_lock_irq(&priv->driver_lock);
- priv->resp_len[resp_idx] = 0;
- }
- spin_unlock_irq(&priv->driver_lock);
-
- /* Process hardware events, e.g. card removed, link lost */
- spin_lock_irq(&priv->driver_lock);
- while (kfifo_len(&priv->event_fifo)) {
- u32 event;
-
- if (kfifo_out(&priv->event_fifo,
- (unsigned char *) &event, sizeof(event)) !=
- sizeof(event))
- break;
- spin_unlock_irq(&priv->driver_lock);
- lbs_process_event(priv, event);
- spin_lock_irq(&priv->driver_lock);
- }
- spin_unlock_irq(&priv->driver_lock);
-
- if (priv->wakeup_dev_required) {
- lbs_deb_thread("Waking up device...\n");
- /* Wake up device */
- if (priv->exit_deep_sleep(priv))
- lbs_deb_thread("Wakeup device failed\n");
- continue;
- }
-
- /* command timeout stuff */
- if (priv->cmd_timed_out && priv->cur_cmd) {
- struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
-
- netdev_info(dev, "Timeout submitting command 0x%04x\n",
- le16_to_cpu(cmdnode->cmdbuf->command));
- lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
-
- /* Reset card, but only when it isn't in the process
- * of being shutdown anyway. */
- if (!dev->dismantle && priv->reset_card)
- priv->reset_card(priv);
- }
- priv->cmd_timed_out = 0;
-
- if (!priv->fw_ready)
- continue;
-
- /* Check if we need to confirm Sleep Request received previously */
- if (priv->psstate == PS_STATE_PRE_SLEEP &&
- !priv->dnld_sent && !priv->cur_cmd) {
- if (priv->connect_status == LBS_CONNECTED) {
- lbs_deb_thread("pre-sleep, currenttxskb %p, "
- "dnld_sent %d, cur_cmd %p\n",
- priv->currenttxskb, priv->dnld_sent,
- priv->cur_cmd);
-
- lbs_ps_confirm_sleep(priv);
- } else {
- /* workaround for firmware sending
- * deauth/linkloss event immediately
- * after sleep request; remove this
- * after firmware fixes it
- */
- priv->psstate = PS_STATE_AWAKE;
- netdev_alert(dev,
- "ignore PS_SleepConfirm in non-connected state\n");
- }
- }
-
- /* The PS state is changed during processing of Sleep Request
- * event above
- */
- if ((priv->psstate == PS_STATE_SLEEP) ||
- (priv->psstate == PS_STATE_PRE_SLEEP))
- continue;
-
- if (priv->is_deep_sleep)
- continue;
-
- /* Execute the next command */
- if (!priv->dnld_sent && !priv->cur_cmd)
- lbs_execute_next_command(priv);
-
- spin_lock_irq(&priv->driver_lock);
- if (!priv->dnld_sent && priv->tx_pending_len > 0) {
- int ret = priv->hw_host_to_card(priv, MVMS_DAT,
- priv->tx_pending_buf,
- priv->tx_pending_len);
- if (ret) {
- lbs_deb_tx("host_to_card failed %d\n", ret);
- priv->dnld_sent = DNLD_RES_RECEIVED;
- } else {
- mod_timer(&priv->tx_lockup_timer,
- jiffies + (HZ * 5));
- }
- priv->tx_pending_len = 0;
- if (!priv->currenttxskb) {
- /* We can wake the queues immediately if we aren't
- waiting for TX feedback */
- if (priv->connect_status == LBS_CONNECTED)
- netif_wake_queue(priv->dev);
- if (priv->mesh_dev &&
- netif_running(priv->mesh_dev))
- netif_wake_queue(priv->mesh_dev);
- }
- }
- spin_unlock_irq(&priv->driver_lock);
- }
-
- del_timer(&priv->command_timer);
- del_timer(&priv->tx_lockup_timer);
- del_timer(&priv->auto_deepsleep_timer);
-
- lbs_deb_leave(LBS_DEB_THREAD);
- return 0;
-}
-
-/**
- * lbs_setup_firmware - gets the HW spec from the firmware and sets
- * some basic parameters
- *
- * @priv: A pointer to &struct lbs_private structure
- * returns: 0 or -1
- */
-static int lbs_setup_firmware(struct lbs_private *priv)
-{
- int ret = -1;
- s16 curlevel = 0, minlevel = 0, maxlevel = 0;
-
- lbs_deb_enter(LBS_DEB_FW);
-
- /* Read MAC address from firmware */
- eth_broadcast_addr(priv->current_addr);
- ret = lbs_update_hw_spec(priv);
- if (ret)
- goto done;
-
- /* Read power levels if available */
- ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
- if (ret == 0) {
- priv->txpower_cur = curlevel;
- priv->txpower_min = minlevel;
- priv->txpower_max = maxlevel;
- }
-
- /* Send cmd to FW to enable 11D function */
- ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
- if (ret)
- goto done;
-
- ret = lbs_set_mac_control_sync(priv);
-done:
- lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
- return ret;
-}
-
-int lbs_suspend(struct lbs_private *priv)
-{
- int ret;
-
- lbs_deb_enter(LBS_DEB_FW);
-
- if (priv->is_deep_sleep) {
- ret = lbs_set_deep_sleep(priv, 0);
- if (ret) {
- netdev_err(priv->dev,
- "deep sleep cancellation failed: %d\n", ret);
- return ret;
- }
- priv->deep_sleep_required = 1;
- }
-
- ret = lbs_set_host_sleep(priv, 1);
-
- netif_device_detach(priv->dev);
- if (priv->mesh_dev)
- netif_device_detach(priv->mesh_dev);
-
- lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_suspend);
-
-int lbs_resume(struct lbs_private *priv)
-{
- int ret;
-
- lbs_deb_enter(LBS_DEB_FW);
-
- ret = lbs_set_host_sleep(priv, 0);
-
- netif_device_attach(priv->dev);
- if (priv->mesh_dev)
- netif_device_attach(priv->mesh_dev);
-
- if (priv->deep_sleep_required) {
- priv->deep_sleep_required = 0;
- ret = lbs_set_deep_sleep(priv, 1);
- if (ret)
- netdev_err(priv->dev,
- "deep sleep activation failed: %d\n", ret);
- }
-
- if (priv->setup_fw_on_resume)
- ret = lbs_setup_firmware(priv);
-
- lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_resume);
-
-/**
- * lbs_cmd_timeout_handler - handles the timeout of command sending.
- * It will re-send the same command again.
- *
- * @data: &struct lbs_private pointer
- */
-static void lbs_cmd_timeout_handler(unsigned long data)
-{
- struct lbs_private *priv = (struct lbs_private *)data;
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_CMD);
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (!priv->cur_cmd)
- goto out;
-
- netdev_info(priv->dev, "command 0x%04x timed out\n",
- le16_to_cpu(priv->cur_cmd->cmdbuf->command));
-
- priv->cmd_timed_out = 1;
-
- /*
- * If the device didn't even acknowledge the command, reset the state
- * so that we don't block all future commands due to this one timeout.
- */
- if (priv->dnld_sent == DNLD_CMD_SENT)
- priv->dnld_sent = DNLD_RES_RECEIVED;
-
- wake_up(&priv->waitq);
-out:
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- lbs_deb_leave(LBS_DEB_CMD);
-}
-
-/**
- * lbs_tx_lockup_handler - handles the timeout of the passing of TX frames
- * to the hardware. This is known to frequently happen with SD8686 when
- * waking up after a Wake-on-WLAN-triggered resume.
- *
- * @data: &struct lbs_private pointer
- */
-static void lbs_tx_lockup_handler(unsigned long data)
-{
- struct lbs_private *priv = (struct lbs_private *)data;
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_TX);
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- netdev_info(priv->dev, "TX lockup detected\n");
- if (priv->reset_card)
- priv->reset_card(priv);
-
- priv->dnld_sent = DNLD_RES_RECEIVED;
- wake_up_interruptible(&priv->waitq);
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- lbs_deb_leave(LBS_DEB_TX);
-}
-
-/**
- * auto_deepsleep_timer_fn - put the device back to deep sleep mode when
- * timer expires and no activity (command, event, data etc.) is detected.
- * @data: &struct lbs_private pointer
- * returns: N/A
- */
-static void auto_deepsleep_timer_fn(unsigned long data)
-{
- struct lbs_private *priv = (struct lbs_private *)data;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- if (priv->is_activity_detected) {
- priv->is_activity_detected = 0;
- } else {
- if (priv->is_auto_deep_sleep_enabled &&
- (!priv->wakeup_dev_required) &&
- (priv->connect_status != LBS_CONNECTED)) {
- struct cmd_header cmd;
-
- lbs_deb_main("Entering auto deep sleep mode...\n");
- memset(&cmd, 0, sizeof(cmd));
- cmd.size = cpu_to_le16(sizeof(cmd));
- lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd,
- sizeof(cmd));
- }
- }
- mod_timer(&priv->auto_deepsleep_timer , jiffies +
- (priv->auto_deep_sleep_timeout * HZ)/1000);
- lbs_deb_leave(LBS_DEB_CMD);
-}
-
-int lbs_enter_auto_deep_sleep(struct lbs_private *priv)
-{
- lbs_deb_enter(LBS_DEB_SDIO);
-
- priv->is_auto_deep_sleep_enabled = 1;
- if (priv->is_deep_sleep)
- priv->wakeup_dev_required = 1;
- mod_timer(&priv->auto_deepsleep_timer ,
- jiffies + (priv->auto_deep_sleep_timeout * HZ)/1000);
-
- lbs_deb_leave(LBS_DEB_SDIO);
- return 0;
-}
-
-int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
-{
- lbs_deb_enter(LBS_DEB_SDIO);
-
- priv->is_auto_deep_sleep_enabled = 0;
- priv->auto_deep_sleep_timeout = 0;
- del_timer(&priv->auto_deepsleep_timer);
-
- lbs_deb_leave(LBS_DEB_SDIO);
- return 0;
-}
-
-static int lbs_init_adapter(struct lbs_private *priv)
-{
- int ret;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- eth_broadcast_addr(priv->current_addr);
-
- priv->connect_status = LBS_DISCONNECTED;
- priv->channel = DEFAULT_AD_HOC_CHANNEL;
- priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
- priv->radio_on = 1;
- priv->psmode = LBS802_11POWERMODECAM;
- priv->psstate = PS_STATE_FULL_POWER;
- priv->is_deep_sleep = 0;
- priv->is_auto_deep_sleep_enabled = 0;
- priv->deep_sleep_required = 0;
- priv->wakeup_dev_required = 0;
- init_waitqueue_head(&priv->ds_awake_q);
- init_waitqueue_head(&priv->scan_q);
- priv->authtype_auto = 1;
- priv->is_host_sleep_configured = 0;
- priv->is_host_sleep_activated = 0;
- init_waitqueue_head(&priv->host_sleep_q);
- init_waitqueue_head(&priv->fw_waitq);
- mutex_init(&priv->lock);
-
- setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
- (unsigned long)priv);
- setup_timer(&priv->tx_lockup_timer, lbs_tx_lockup_handler,
- (unsigned long)priv);
- setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
- (unsigned long)priv);
-
- INIT_LIST_HEAD(&priv->cmdfreeq);
- INIT_LIST_HEAD(&priv->cmdpendingq);
-
- spin_lock_init(&priv->driver_lock);
-
- /* Allocate the command buffers */
- if (lbs_allocate_cmd_buffer(priv)) {
- pr_err("Out of memory allocating command buffers\n");
- ret = -ENOMEM;
- goto out;
- }
- priv->resp_idx = 0;
- priv->resp_len[0] = priv->resp_len[1] = 0;
-
- /* Create the event FIFO */
- ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
- if (ret) {
- pr_err("Out of memory allocating event FIFO buffer\n");
- goto out;
- }
-
-out:
- lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
-
- return ret;
-}
-
-static void lbs_free_adapter(struct lbs_private *priv)
-{
- lbs_deb_enter(LBS_DEB_MAIN);
-
- lbs_free_cmd_buffer(priv);
- kfifo_free(&priv->event_fifo);
- del_timer(&priv->command_timer);
- del_timer(&priv->tx_lockup_timer);
- del_timer(&priv->auto_deepsleep_timer);
-
- lbs_deb_leave(LBS_DEB_MAIN);
-}
-
-static const struct net_device_ops lbs_netdev_ops = {
- .ndo_open = lbs_dev_open,
- .ndo_stop = lbs_eth_stop,
- .ndo_start_xmit = lbs_hard_start_xmit,
- .ndo_set_mac_address = lbs_set_mac_address,
- .ndo_set_rx_mode = lbs_set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/**
- * lbs_add_card - adds the card. It will probe the
- * card, allocate the lbs_priv and initialize the device.
- *
- * @card: A pointer to card
- * @dmdev: A pointer to &struct device
- * returns: A pointer to &struct lbs_private structure
- */
-struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
-{
- struct net_device *dev;
- struct wireless_dev *wdev;
- struct lbs_private *priv = NULL;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- /* Allocate an Ethernet device and register it */
- wdev = lbs_cfg_alloc(dmdev);
- if (IS_ERR(wdev)) {
- pr_err("cfg80211 init failed\n");
- goto done;
- }
-
- wdev->iftype = NL80211_IFTYPE_STATION;
- priv = wdev_priv(wdev);
- priv->wdev = wdev;
-
- if (lbs_init_adapter(priv)) {
- pr_err("failed to initialize adapter structure\n");
- goto err_wdev;
- }
-
- dev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup);
- if (!dev) {
- dev_err(dmdev, "no memory for network device instance\n");
- goto err_adapter;
- }
-
- dev->ieee80211_ptr = wdev;
- dev->ml_priv = priv;
- SET_NETDEV_DEV(dev, dmdev);
- wdev->netdev = dev;
- priv->dev = dev;
-
- dev->netdev_ops = &lbs_netdev_ops;
- dev->watchdog_timeo = 5 * HZ;
- dev->ethtool_ops = &lbs_ethtool_ops;
- dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-
- priv->card = card;
-
- strcpy(dev->name, "wlan%d");
-
- lbs_deb_thread("Starting main thread...\n");
- init_waitqueue_head(&priv->waitq);
- priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
- if (IS_ERR(priv->main_thread)) {
- lbs_deb_thread("Error creating main thread.\n");
- goto err_ndev;
- }
-
- priv->work_thread = create_singlethread_workqueue("lbs_worker");
- INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
-
- priv->wol_criteria = EHS_REMOVE_WAKEUP;
- priv->wol_gpio = 0xff;
- priv->wol_gap = 20;
- priv->ehs_remove_supported = true;
-
- goto done;
-
- err_ndev:
- free_netdev(dev);
-
- err_adapter:
- lbs_free_adapter(priv);
-
- err_wdev:
- lbs_cfg_free(priv);
-
- priv = NULL;
-
-done:
- lbs_deb_leave_args(LBS_DEB_MAIN, "priv %p", priv);
- return priv;
-}
-EXPORT_SYMBOL_GPL(lbs_add_card);
-
-
-void lbs_remove_card(struct lbs_private *priv)
-{
- struct net_device *dev = priv->dev;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- lbs_remove_mesh(priv);
-
- if (priv->wiphy_registered)
- lbs_scan_deinit(priv);
-
- lbs_wait_for_firmware_load(priv);
-
- /* worker thread destruction blocks on the in-flight command which
- * should have been cleared already in lbs_stop_card().
- */
- lbs_deb_main("destroying worker thread\n");
- destroy_workqueue(priv->work_thread);
- lbs_deb_main("done destroying worker thread\n");
-
- if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
- priv->psmode = LBS802_11POWERMODECAM;
- lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true);
- }
-
- if (priv->is_deep_sleep) {
- priv->is_deep_sleep = 0;
- wake_up_interruptible(&priv->ds_awake_q);
- }
-
- priv->is_host_sleep_configured = 0;
- priv->is_host_sleep_activated = 0;
- wake_up_interruptible(&priv->host_sleep_q);
-
- /* Stop the thread servicing the interrupts */
- priv->surpriseremoved = 1;
- kthread_stop(priv->main_thread);
-
- lbs_free_adapter(priv);
- lbs_cfg_free(priv);
- free_netdev(dev);
-
- lbs_deb_leave(LBS_DEB_MAIN);
-}
-EXPORT_SYMBOL_GPL(lbs_remove_card);
-
-
-int lbs_rtap_supported(struct lbs_private *priv)
-{
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
- return 1;
-
- /* newer firmware use a capability mask */
- return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
- (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK));
-}
-
-
-int lbs_start_card(struct lbs_private *priv)
-{
- struct net_device *dev = priv->dev;
- int ret = -1;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- /* poke the firmware */
- ret = lbs_setup_firmware(priv);
- if (ret)
- goto done;
-
- if (!lbs_disablemesh)
- lbs_init_mesh(priv);
- else
- pr_info("%s: mesh disabled\n", dev->name);
-
- if (lbs_cfg_register(priv)) {
- pr_err("cannot register device\n");
- goto done;
- }
-
- if (lbs_mesh_activated(priv))
- lbs_start_mesh(priv);
-
- lbs_debugfs_init_one(priv, dev);
-
- netdev_info(dev, "Marvell WLAN 802.11 adapter\n");
-
- ret = 0;
-
-done:
- lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_start_card);
-
-
-void lbs_stop_card(struct lbs_private *priv)
-{
- struct net_device *dev;
-
- lbs_deb_enter(LBS_DEB_MAIN);
-
- if (!priv)
- goto out;
- dev = priv->dev;
-
- /* If the netdev isn't registered, it means that lbs_start_card() was
- * never called so we have nothing to do here. */
- if (dev->reg_state != NETREG_REGISTERED)
- goto out;
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
-
- lbs_debugfs_remove_one(priv);
- lbs_deinit_mesh(priv);
- unregister_netdev(dev);
-
-out:
- lbs_deb_leave(LBS_DEB_MAIN);
-}
-EXPORT_SYMBOL_GPL(lbs_stop_card);
-
-
-void lbs_queue_event(struct lbs_private *priv, u32 event)
-{
- unsigned long flags;
-
- lbs_deb_enter(LBS_DEB_THREAD);
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (priv->psstate == PS_STATE_SLEEP)
- priv->psstate = PS_STATE_AWAKE;
-
- kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
-
- wake_up(&priv->waitq);
-
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- lbs_deb_leave(LBS_DEB_THREAD);
-}
-EXPORT_SYMBOL_GPL(lbs_queue_event);
-
-void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
-{
- lbs_deb_enter(LBS_DEB_THREAD);
-
- if (priv->psstate == PS_STATE_SLEEP)
- priv->psstate = PS_STATE_AWAKE;
-
- /* Swap buffers by flipping the response index */
- BUG_ON(resp_idx > 1);
- priv->resp_idx = resp_idx;
-
- wake_up(&priv->waitq);
-
- lbs_deb_leave(LBS_DEB_THREAD);
-}
-EXPORT_SYMBOL_GPL(lbs_notify_command_response);
-
-static int __init lbs_init_module(void)
-{
- lbs_deb_enter(LBS_DEB_MAIN);
- memset(&confirm_sleep, 0, sizeof(confirm_sleep));
- confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE);
- confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep));
- confirm_sleep.action = cpu_to_le16(PS_MODE_ACTION_SLEEP_CONFIRMED);
- lbs_debugfs_init();
- lbs_deb_leave(LBS_DEB_MAIN);
- return 0;
-}
-
-static void __exit lbs_exit_module(void)
-{
- lbs_deb_enter(LBS_DEB_MAIN);
- lbs_debugfs_remove();
- lbs_deb_leave(LBS_DEB_MAIN);
-}
-
-module_init(lbs_init_module);
-module_exit(lbs_exit_module);
-
-MODULE_DESCRIPTION("Libertas WLAN Driver Library");
-MODULE_AUTHOR("Marvell International Ltd.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
deleted file mode 100644
index d0c881dd5..000000000
--- a/drivers/net/wireless/libertas/mesh.c
+++ /dev/null
@@ -1,1187 +0,0 @@
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/delay.h>
-#include <linux/etherdevice.h>
-#include <linux/hardirq.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/kthread.h>
-#include <linux/kfifo.h>
-#include <net/cfg80211.h>
-
-#include "mesh.h"
-#include "decl.h"
-#include "cmd.h"
-
-
-static int lbs_add_mesh(struct lbs_private *priv);
-
-/***************************************************************************
- * Mesh command handling
- */
-
-static int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
- struct cmd_ds_mesh_access *cmd)
-{
- int ret;
-
- lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
- cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
- cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
- cmd->hdr.result = 0;
-
- cmd->action = cpu_to_le16(cmd_action);
-
- ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-static int __lbs_mesh_config_send(struct lbs_private *priv,
- struct cmd_ds_mesh_config *cmd,
- uint16_t action, uint16_t type)
-{
- int ret;
- u16 command = CMD_MESH_CONFIG_OLD;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- /*
- * Command id is 0xac for v10 FW along with mesh interface
- * id in bits 14-13-12.
- */
- if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
- command = CMD_MESH_CONFIG |
- (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
-
- cmd->hdr.command = cpu_to_le16(command);
- cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
- cmd->hdr.result = 0;
-
- cmd->type = cpu_to_le16(type);
- cmd->action = cpu_to_le16(action);
-
- ret = lbs_cmd_with_response(priv, command, cmd);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return ret;
-}
-
-static int lbs_mesh_config_send(struct lbs_private *priv,
- struct cmd_ds_mesh_config *cmd,
- uint16_t action, uint16_t type)
-{
- int ret;
-
- if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
- return -EOPNOTSUPP;
-
- ret = __lbs_mesh_config_send(priv, cmd, action, type);
- return ret;
-}
-
-/* This function is the CMD_MESH_CONFIG legacy function. It only handles the
- * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG
- * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
- * lbs_mesh_config_send.
- */
-static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
- uint16_t chan)
-{
- struct cmd_ds_mesh_config cmd;
- struct mrvl_meshie *ie;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.channel = cpu_to_le16(chan);
- ie = (struct mrvl_meshie *)cmd.data;
-
- switch (action) {
- case CMD_ACT_MESH_CONFIG_START:
- ie->id = WLAN_EID_VENDOR_SPECIFIC;
- ie->val.oui[0] = 0x00;
- ie->val.oui[1] = 0x50;
- ie->val.oui[2] = 0x43;
- ie->val.type = MARVELL_MESH_IE_TYPE;
- ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
- ie->val.version = MARVELL_MESH_IE_VERSION;
- ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
- ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
- ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
- ie->val.mesh_id_len = priv->mesh_ssid_len;
- memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
- ie->len = sizeof(struct mrvl_meshie_val) -
- IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
- cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
- break;
- case CMD_ACT_MESH_CONFIG_STOP:
- break;
- default:
- return -1;
- }
- lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n",
- action, priv->mesh_tlv, chan, priv->mesh_ssid_len,
- priv->mesh_ssid);
-
- return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
-}
-
-int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel)
-{
- priv->mesh_channel = channel;
- return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel);
-}
-
-static uint16_t lbs_mesh_get_channel(struct lbs_private *priv)
-{
- return priv->mesh_channel ?: 1;
-}
-
-/***************************************************************************
- * Mesh sysfs support
- */
-
-/*
- * Attributes exported through sysfs
- */
-
-/**
- * lbs_anycast_get - Get function for sysfs attribute anycast_mask
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t lbs_anycast_get(struct device *dev,
- struct device_attribute *attr, char * buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
- if (ret)
- return ret;
-
- return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
-}
-
-/**
- * lbs_anycast_set - Set function for sysfs attribute anycast_mask
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t lbs_anycast_set(struct device *dev,
- struct device_attribute *attr, const char * buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- uint32_t datum;
- int ret;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- sscanf(buf, "%x", &datum);
- mesh_access.data[0] = cpu_to_le32(datum);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * lbs_prb_rsp_limit_get - Get function for sysfs attribute prb_rsp_limit
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
- u32 retry_limit;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
- &mesh_access);
- if (ret)
- return ret;
-
- retry_limit = le32_to_cpu(mesh_access.data[1]);
- return snprintf(buf, 10, "%d\n", retry_limit);
-}
-
-/**
- * lbs_prb_rsp_limit_set - Set function for sysfs attribute prb_rsp_limit
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
- unsigned long retry_limit;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
-
- if (!kstrtoul(buf, 10, &retry_limit))
- return -ENOTSUPP;
- if (retry_limit > 15)
- return -ENOTSUPP;
-
- mesh_access.data[1] = cpu_to_le32(retry_limit);
-
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
- &mesh_access);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * lbs_mesh_get - Get function for sysfs attribute mesh
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t lbs_mesh_get(struct device *dev,
- struct device_attribute *attr, char * buf)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
-}
-
-/**
- * lbs_mesh_set - Set function for sysfs attribute mesh
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t lbs_mesh_set(struct device *dev,
- struct device_attribute *attr, const char * buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- int enable;
-
- sscanf(buf, "%x", &enable);
- enable = !!enable;
- if (enable == !!priv->mesh_dev)
- return count;
-
- if (enable)
- lbs_add_mesh(priv);
- else
- lbs_remove_mesh(priv);
-
- return count;
-}
-
-/*
- * lbs_mesh attribute to be exported per ethX interface
- * through sysfs (/sys/class/net/ethX/lbs_mesh)
- */
-static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
-
-/*
- * anycast_mask attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/anycast_mask)
- */
-static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
-
-/*
- * prb_rsp_limit attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
- */
-static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
- lbs_prb_rsp_limit_set);
-
-static struct attribute *lbs_mesh_sysfs_entries[] = {
- &dev_attr_anycast_mask.attr,
- &dev_attr_prb_rsp_limit.attr,
- NULL,
-};
-
-static const struct attribute_group lbs_mesh_attr_group = {
- .attrs = lbs_mesh_sysfs_entries,
-};
-
-
-/***************************************************************************
- * Persistent configuration support
- */
-
-static int mesh_get_default_parameters(struct device *dev,
- struct mrvl_mesh_defaults *defs)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- int ret;
-
- memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
- CMD_TYPE_MESH_GET_DEFAULTS);
-
- if (ret)
- return -EOPNOTSUPP;
-
- memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
-
- return 0;
-}
-
-/**
- * bootflag_get - Get function for sysfs attribute bootflag
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t bootflag_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));
-}
-
-/**
- * bootflag_set - Set function for sysfs attribute bootflag
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- uint32_t datum;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 1))
- return -EINVAL;
-
- *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
- cmd.length = cpu_to_le16(sizeof(uint32_t));
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_BOOTFLAG);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * boottime_get - Get function for sysfs attribute boottime
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t boottime_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- return snprintf(buf, 12, "%d\n", defs.boottime);
-}
-
-/**
- * boottime_set - Set function for sysfs attribute boottime
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t boottime_set(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- uint32_t datum;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- return -EINVAL;
-
- /* A too small boot time will result in the device booting into
- * standalone (no-host) mode before the host can take control of it,
- * so the change will be hard to revert. This may be a desired
- * feature (e.g to configure a very fast boot time for devices that
- * will not be attached to a host), but dangerous. So I'm enforcing a
- * lower limit of 20 seconds: remove and recompile the driver if this
- * does not work for you.
- */
- datum = (datum < 20) ? 20 : datum;
- cmd.data[0] = datum;
- cmd.length = cpu_to_le16(sizeof(uint8_t));
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_BOOTTIME);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * channel_get - Get function for sysfs attribute channel
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t channel_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel));
-}
-
-/**
- * channel_set - Set function for sysfs attribute channel
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- struct cmd_ds_mesh_config cmd;
- uint32_t datum;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if (ret != 1 || datum < 1 || datum > 11)
- return -EINVAL;
-
- *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
- cmd.length = cpu_to_le16(sizeof(uint16_t));
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_DEF_CHANNEL);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * mesh_id_get - Get function for sysfs attribute mesh_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
- dev_err(dev, "inconsistent mesh ID length\n");
- defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
- }
-
- memcpy(buf, defs.meshie.val.mesh_id, defs.meshie.val.mesh_id_len);
- buf[defs.meshie.val.mesh_id_len] = '\n';
- buf[defs.meshie.val.mesh_id_len + 1] = '\0';
-
- return defs.meshie.val.mesh_id_len + 1;
-}
-
-/**
- * mesh_id_set - Set function for sysfs attribute mesh_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cmd_ds_mesh_config cmd;
- struct mrvl_mesh_defaults defs;
- struct mrvl_meshie *ie;
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- int len;
- int ret;
-
- if (count < 2 || count > IEEE80211_MAX_SSID_LEN + 1)
- return -EINVAL;
-
- memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
- ie = (struct mrvl_meshie *) &cmd.data[0];
-
- /* fetch all other Information Element parameters */
- ret = mesh_get_default_parameters(dev, &defs);
-
- cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
- /* transfer IE elements */
- memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-
- len = count - 1;
- memcpy(ie->val.mesh_id, buf, len);
- /* SSID len */
- ie->val.mesh_id_len = len;
- /* IE len */
- ie->len = sizeof(struct mrvl_meshie_val) - IEEE80211_MAX_SSID_LEN + len;
-
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_MESH_IE);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * protocol_id_get - Get function for sysfs attribute protocol_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t protocol_id_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
-}
-
-/**
- * protocol_id_set - Set function for sysfs attribute protocol_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t protocol_id_set(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct cmd_ds_mesh_config cmd;
- struct mrvl_mesh_defaults defs;
- struct mrvl_meshie *ie;
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- uint32_t datum;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- return -EINVAL;
-
- /* fetch all other Information Element parameters */
- ret = mesh_get_default_parameters(dev, &defs);
-
- cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
- /* transfer IE elements */
- ie = (struct mrvl_meshie *) &cmd.data[0];
- memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
- /* update protocol id */
- ie->val.active_protocol_id = datum;
-
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_MESH_IE);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * metric_id_get - Get function for sysfs attribute metric_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t metric_id_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
-}
-
-/**
- * metric_id_set - Set function for sysfs attribute metric_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cmd_ds_mesh_config cmd;
- struct mrvl_mesh_defaults defs;
- struct mrvl_meshie *ie;
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- uint32_t datum;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- return -EINVAL;
-
- /* fetch all other Information Element parameters */
- ret = mesh_get_default_parameters(dev, &defs);
-
- cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
- /* transfer IE elements */
- ie = (struct mrvl_meshie *) &cmd.data[0];
- memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
- /* update metric id */
- ie->val.active_metric_id = datum;
-
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_MESH_IE);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-/**
- * capability_get - Get function for sysfs attribute capability
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t capability_get(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct mrvl_mesh_defaults defs;
- int ret;
-
- ret = mesh_get_default_parameters(dev, &defs);
-
- if (ret)
- return ret;
-
- return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
-}
-
-/**
- * capability_set - Set function for sysfs attribute capability
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct cmd_ds_mesh_config cmd;
- struct mrvl_mesh_defaults defs;
- struct mrvl_meshie *ie;
- struct lbs_private *priv = to_net_dev(dev)->ml_priv;
- uint32_t datum;
- int ret;
-
- memset(&cmd, 0, sizeof(cmd));
- ret = sscanf(buf, "%d", &datum);
- if ((ret != 1) || (datum > 255))
- return -EINVAL;
-
- /* fetch all other Information Element parameters */
- ret = mesh_get_default_parameters(dev, &defs);
-
- cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
-
- /* transfer IE elements */
- ie = (struct mrvl_meshie *) &cmd.data[0];
- memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
- /* update value */
- ie->val.mesh_capability = datum;
-
- ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
- CMD_TYPE_MESH_SET_MESH_IE);
- if (ret)
- return ret;
-
- return strlen(buf);
-}
-
-
-static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
-static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
-static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
-static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
-static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
-static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
-static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
-
-static struct attribute *boot_opts_attrs[] = {
- &dev_attr_bootflag.attr,
- &dev_attr_boottime.attr,
- &dev_attr_channel.attr,
- NULL
-};
-
-static const struct attribute_group boot_opts_group = {
- .name = "boot_options",
- .attrs = boot_opts_attrs,
-};
-
-static struct attribute *mesh_ie_attrs[] = {
- &dev_attr_mesh_id.attr,
- &dev_attr_protocol_id.attr,
- &dev_attr_metric_id.attr,
- &dev_attr_capability.attr,
- NULL
-};
-
-static const struct attribute_group mesh_ie_group = {
- .name = "mesh_ie",
- .attrs = mesh_ie_attrs,
-};
-
-static void lbs_persist_config_init(struct net_device *dev)
-{
- int ret;
- ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
- ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
-}
-
-static void lbs_persist_config_remove(struct net_device *dev)
-{
- sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
- sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
-}
-
-
-/***************************************************************************
- * Initializing and starting, stopping mesh
- */
-
-/*
- * Check mesh FW version and appropriately send the mesh start
- * command
- */
-int lbs_init_mesh(struct lbs_private *priv)
-{
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_MESH);
-
- /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
- /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
- /* 5.110.22 have mesh command with 0xa3 command id */
- /* 10.0.0.p0 FW brings in mesh config command with different id */
- /* Check FW version MSB and initialize mesh_fw_ver */
- if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
- /* Enable mesh, if supported, and work out which TLV it uses.
- 0x100 + 291 is an unofficial value used in 5.110.20.pXX
- 0x100 + 37 is the official value used in 5.110.21.pXX
- but we check them in that order because 20.pXX doesn't
- give an error -- it just silently fails. */
-
- /* 5.110.20.pXX firmware will fail the command if the channel
- doesn't match the existing channel. But only if the TLV
- is correct. If the channel is wrong, _BOTH_ versions will
- give an error to 0x100+291, and allow 0x100+37 to succeed.
- It's just that 5.110.20.pXX will not have done anything
- useful */
-
- priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) {
- priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
- priv->mesh_tlv = 0;
- }
- } else
- if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
- (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
- /* 10.0.0.pXX new firmwares should succeed with TLV
- * 0x100+37; Do not invoke command with old TLV.
- */
- priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
- priv->mesh_tlv = 0;
- }
-
- /* Stop meshing until interface is brought up */
- lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
-
- if (priv->mesh_tlv) {
- sprintf(priv->mesh_ssid, "mesh");
- priv->mesh_ssid_len = 4;
- ret = 1;
- }
-
- lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
- return ret;
-}
-
-void lbs_start_mesh(struct lbs_private *priv)
-{
- lbs_add_mesh(priv);
-
- if (device_create_file(&priv->dev->dev, &dev_attr_lbs_mesh))
- netdev_err(priv->dev, "cannot register lbs_mesh attribute\n");
-}
-
-int lbs_deinit_mesh(struct lbs_private *priv)
-{
- struct net_device *dev = priv->dev;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_MESH);
-
- if (priv->mesh_tlv) {
- device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
- ret = 1;
- }
-
- lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
- return ret;
-}
-
-
-/**
- * lbs_mesh_stop - close the mshX interface
- *
- * @dev: A pointer to &net_device structure
- * returns: 0
- */
-static int lbs_mesh_stop(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_MESH);
- lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
- lbs_mesh_get_channel(priv));
-
- spin_lock_irq(&priv->driver_lock);
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
-
- spin_unlock_irq(&priv->driver_lock);
-
- lbs_update_mcast(priv);
- if (!lbs_iface_active(priv))
- lbs_stop_iface(priv);
-
- lbs_deb_leave(LBS_DEB_MESH);
- return 0;
-}
-
-/**
- * lbs_mesh_dev_open - open the mshX interface
- *
- * @dev: A pointer to &net_device structure
- * returns: 0 or -EBUSY if monitor mode active
- */
-static int lbs_mesh_dev_open(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_NET);
- if (!priv->iface_running) {
- ret = lbs_start_iface(priv);
- if (ret)
- goto out;
- }
-
- spin_lock_irq(&priv->driver_lock);
-
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
- ret = -EBUSY;
- spin_unlock_irq(&priv->driver_lock);
- goto out;
- }
-
- netif_carrier_on(dev);
-
- if (!priv->tx_pending_len)
- netif_wake_queue(dev);
-
- spin_unlock_irq(&priv->driver_lock);
-
- ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- lbs_mesh_get_channel(priv));
-
-out:
- lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
- return ret;
-}
-
-static const struct net_device_ops mesh_netdev_ops = {
- .ndo_open = lbs_mesh_dev_open,
- .ndo_stop = lbs_mesh_stop,
- .ndo_start_xmit = lbs_hard_start_xmit,
- .ndo_set_mac_address = lbs_set_mac_address,
- .ndo_set_rx_mode = lbs_set_multicast_list,
-};
-
-/**
- * lbs_add_mesh - add mshX interface
- *
- * @priv: A pointer to the &struct lbs_private structure
- * returns: 0 if successful, -X otherwise
- */
-static int lbs_add_mesh(struct lbs_private *priv)
-{
- struct net_device *mesh_dev = NULL;
- struct wireless_dev *mesh_wdev;
- int ret = 0;
-
- lbs_deb_enter(LBS_DEB_MESH);
-
- /* Allocate a virtual mesh device */
- mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!mesh_wdev) {
- lbs_deb_mesh("init mshX wireless device failed\n");
- ret = -ENOMEM;
- goto done;
- }
-
- mesh_dev = alloc_netdev(0, "msh%d", NET_NAME_UNKNOWN, ether_setup);
- if (!mesh_dev) {
- lbs_deb_mesh("init mshX device failed\n");
- ret = -ENOMEM;
- goto err_free_wdev;
- }
-
- mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT;
- mesh_wdev->wiphy = priv->wdev->wiphy;
- mesh_wdev->netdev = mesh_dev;
-
- mesh_dev->ml_priv = priv;
- mesh_dev->ieee80211_ptr = mesh_wdev;
- priv->mesh_dev = mesh_dev;
-
- mesh_dev->netdev_ops = &mesh_netdev_ops;
- mesh_dev->ethtool_ops = &lbs_ethtool_ops;
- eth_hw_addr_inherit(mesh_dev, priv->dev);
-
- SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
-
- mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- /* Register virtual mesh interface */
- ret = register_netdev(mesh_dev);
- if (ret) {
- pr_err("cannot register mshX virtual interface\n");
- goto err_free_netdev;
- }
-
- ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- if (ret)
- goto err_unregister;
-
- lbs_persist_config_init(mesh_dev);
-
- /* Everything successful */
- ret = 0;
- goto done;
-
-err_unregister:
- unregister_netdev(mesh_dev);
-
-err_free_netdev:
- free_netdev(mesh_dev);
-
-err_free_wdev:
- kfree(mesh_wdev);
-
-done:
- lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
- return ret;
-}
-
-void lbs_remove_mesh(struct lbs_private *priv)
-{
- struct net_device *mesh_dev;
-
- mesh_dev = priv->mesh_dev;
- if (!mesh_dev)
- return;
-
- lbs_deb_enter(LBS_DEB_MESH);
- netif_stop_queue(mesh_dev);
- netif_carrier_off(mesh_dev);
- sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- lbs_persist_config_remove(mesh_dev);
- unregister_netdev(mesh_dev);
- priv->mesh_dev = NULL;
- kfree(mesh_dev->ieee80211_ptr);
- free_netdev(mesh_dev);
- lbs_deb_leave(LBS_DEB_MESH);
-}
-
-
-/***************************************************************************
- * Sending and receiving
- */
-struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
- struct net_device *dev, struct rxpd *rxpd)
-{
- if (priv->mesh_dev) {
- if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
- if (rxpd->rx_control & RxPD_MESH_FRAME)
- dev = priv->mesh_dev;
- } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
- if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
- dev = priv->mesh_dev;
- }
- }
- return dev;
-}
-
-
-void lbs_mesh_set_txpd(struct lbs_private *priv,
- struct net_device *dev, struct txpd *txpd)
-{
- if (dev == priv->mesh_dev) {
- if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
- txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
- else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
- txpd->u.bss.bss_num = MESH_IFACE_ID;
- }
-}
-
-
-/***************************************************************************
- * Ethtool related
- */
-
-static const char * const mesh_stat_strings[] = {
- "drop_duplicate_bcast",
- "drop_ttl_zero",
- "drop_no_fwd_route",
- "drop_no_buffers",
- "fwded_unicast_cnt",
- "fwded_bcast_cnt",
- "drop_blind_table",
- "tx_failed_cnt"
-};
-
-void lbs_mesh_ethtool_get_stats(struct net_device *dev,
- struct ethtool_stats *stats, uint64_t *data)
-{
- struct lbs_private *priv = dev->ml_priv;
- struct cmd_ds_mesh_access mesh_access;
- int ret;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-
- /* Get Mesh Statistics */
- ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
-
- if (ret) {
- memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
- return;
- }
-
- priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
- priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
- priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
- priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
- priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
- priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
- priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
- priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
-
- data[0] = priv->mstats.fwd_drop_rbt;
- data[1] = priv->mstats.fwd_drop_ttl;
- data[2] = priv->mstats.fwd_drop_noroute;
- data[3] = priv->mstats.fwd_drop_nobuf;
- data[4] = priv->mstats.fwd_unicast_cnt;
- data[5] = priv->mstats.fwd_bcast_cnt;
- data[6] = priv->mstats.drop_blind;
- data[7] = priv->mstats.tx_failed_cnt;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-}
-
-int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
- return MESH_STATS_NUM;
-
- return -EOPNOTSUPP;
-}
-
-void lbs_mesh_ethtool_get_strings(struct net_device *dev,
- uint32_t stringset, uint8_t *s)
-{
- int i;
-
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-
- switch (stringset) {
- case ETH_SS_STATS:
- for (i = 0; i < MESH_STATS_NUM; i++) {
- memcpy(s + i * ETH_GSTRING_LEN,
- mesh_stat_strings[i],
- ETH_GSTRING_LEN);
- }
- break;
- }
- lbs_deb_enter(LBS_DEB_ETHTOOL);
-}
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h
deleted file mode 100644
index 6603f341c..000000000
--- a/drivers/net/wireless/libertas/mesh.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Contains all definitions needed for the Libertas' MESH implementation.
- */
-#ifndef _LBS_MESH_H_
-#define _LBS_MESH_H_
-
-
-#include <net/iw_handler.h>
-#include <net/lib80211.h>
-
-#include "host.h"
-#include "dev.h"
-
-#ifdef CONFIG_LIBERTAS_MESH
-
-struct net_device;
-
-int lbs_init_mesh(struct lbs_private *priv);
-void lbs_start_mesh(struct lbs_private *priv);
-int lbs_deinit_mesh(struct lbs_private *priv);
-
-void lbs_remove_mesh(struct lbs_private *priv);
-
-static inline bool lbs_mesh_activated(struct lbs_private *priv)
-{
- /* Mesh SSID is only programmed after successful init */
- return priv->mesh_ssid_len != 0;
-}
-
-int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel);
-
-/* Sending / Receiving */
-
-struct rxpd;
-struct txpd;
-
-struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
- struct net_device *dev, struct rxpd *rxpd);
-void lbs_mesh_set_txpd(struct lbs_private *priv,
- struct net_device *dev, struct txpd *txpd);
-
-
-/* Command handling */
-
-struct cmd_ds_command;
-struct cmd_ds_mesh_access;
-struct cmd_ds_mesh_config;
-
-
-/* Ethtool statistics */
-
-struct ethtool_stats;
-
-void lbs_mesh_ethtool_get_stats(struct net_device *dev,
- struct ethtool_stats *stats, uint64_t *data);
-int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset);
-void lbs_mesh_ethtool_get_strings(struct net_device *dev,
- uint32_t stringset, uint8_t *s);
-
-
-#else
-
-#define lbs_init_mesh(priv)
-#define lbs_deinit_mesh(priv)
-#define lbs_start_mesh(priv)
-#define lbs_add_mesh(priv)
-#define lbs_remove_mesh(priv)
-#define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
-#define lbs_mesh_set_txpd(priv, dev, txpd)
-#define lbs_mesh_set_channel(priv, channel) (0)
-#define lbs_mesh_activated(priv) (false)
-
-#endif
-
-
-
-#endif
diff --git a/drivers/net/wireless/libertas/radiotap.h b/drivers/net/wireless/libertas/radiotap.h
deleted file mode 100644
index b3c8ea6d6..000000000
--- a/drivers/net/wireless/libertas/radiotap.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <net/ieee80211_radiotap.h>
-
-struct tx_radiotap_hdr {
- struct ieee80211_radiotap_header hdr;
- u8 rate;
- u8 txpower;
- u8 rts_retries;
- u8 data_retries;
-} __packed;
-
-#define TX_RADIOTAP_PRESENT ( \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
- (1 << IEEE80211_RADIOTAP_RTS_RETRIES) | \
- (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | \
- 0)
-
-#define IEEE80211_FC_VERSION_MASK 0x0003
-#define IEEE80211_FC_TYPE_MASK 0x000c
-#define IEEE80211_FC_TYPE_MGT 0x0000
-#define IEEE80211_FC_TYPE_CTL 0x0004
-#define IEEE80211_FC_TYPE_DATA 0x0008
-#define IEEE80211_FC_SUBTYPE_MASK 0x00f0
-#define IEEE80211_FC_TOFROMDS_MASK 0x0300
-#define IEEE80211_FC_TODS_MASK 0x0100
-#define IEEE80211_FC_FROMDS_MASK 0x0200
-#define IEEE80211_FC_NODS 0x0000
-#define IEEE80211_FC_TODS 0x0100
-#define IEEE80211_FC_FROMDS 0x0200
-#define IEEE80211_FC_DSTODS 0x0300
-
-struct rx_radiotap_hdr {
- struct ieee80211_radiotap_header hdr;
- u8 flags;
- u8 rate;
- u8 antsignal;
-} __packed;
-
-#define RX_RADIOTAP_PRESENT ( \
- (1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |\
- 0)
-
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
deleted file mode 100644
index e446fed7b..000000000
--- a/drivers/net/wireless/libertas/rx.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * This file contains the handling of RX in wlan driver.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/etherdevice.h>
-#include <linux/hardirq.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/export.h>
-#include <net/cfg80211.h>
-
-#include "defs.h"
-#include "host.h"
-#include "radiotap.h"
-#include "decl.h"
-#include "dev.h"
-#include "mesh.h"
-
-struct eth803hdr {
- u8 dest_addr[6];
- u8 src_addr[6];
- u16 h803_len;
-} __packed;
-
-struct rfc1042hdr {
- u8 llc_dsap;
- u8 llc_ssap;
- u8 llc_ctrl;
- u8 snap_oui[3];
- u16 snap_type;
-} __packed;
-
-struct rxpackethdr {
- struct eth803hdr eth803_hdr;
- struct rfc1042hdr rfc1042_hdr;
-} __packed;
-
-struct rx80211packethdr {
- struct rxpd rx_pd;
- void *eth80211_hdr;
-} __packed;
-
-static int process_rxed_802_11_packet(struct lbs_private *priv,
- struct sk_buff *skb);
-
-/**
- * lbs_process_rxed_packet - processes received packet and forwards it
- * to kernel/upper layer
- *
- * @priv: A pointer to &struct lbs_private
- * @skb: A pointer to skb which includes the received packet
- * returns: 0 or -1
- */
-int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
-{
- int ret = 0;
- struct net_device *dev = priv->dev;
- struct rxpackethdr *p_rx_pkt;
- struct rxpd *p_rx_pd;
- int hdrchop;
- struct ethhdr *p_ethhdr;
- static const u8 rfc1042_eth_hdr[] = {
- 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
- };
-
- lbs_deb_enter(LBS_DEB_RX);
-
- BUG_ON(!skb);
-
- skb->ip_summed = CHECKSUM_NONE;
-
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
- ret = process_rxed_802_11_packet(priv, skb);
- goto done;
- }
-
- p_rx_pd = (struct rxpd *) skb->data;
- p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
- le32_to_cpu(p_rx_pd->pkt_ptr));
-
- dev = lbs_mesh_set_dev(priv, dev, p_rx_pd);
-
- lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
- min_t(unsigned int, skb->len, 100));
-
- if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
- lbs_deb_rx("rx err: frame received with bad length\n");
- dev->stats.rx_length_errors++;
- ret = -EINVAL;
- dev_kfree_skb(skb);
- goto done;
- }
-
- lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n",
- skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr),
- skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr));
-
- lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
- sizeof(p_rx_pkt->eth803_hdr.dest_addr));
- lbs_deb_hex(LBS_DEB_RX, "RX Data: Src", p_rx_pkt->eth803_hdr.src_addr,
- sizeof(p_rx_pkt->eth803_hdr.src_addr));
-
- if (memcmp(&p_rx_pkt->rfc1042_hdr,
- rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
- /*
- * Replace the 803 header and rfc1042 header (llc/snap) with an
- * EthernetII header, keep the src/dst and snap_type (ethertype)
- *
- * The firmware only passes up SNAP frames converting
- * all RX Data from 802.11 to 802.2/LLC/SNAP frames.
- *
- * To create the Ethernet II, just move the src, dst address right
- * before the snap_type.
- */
- p_ethhdr = (struct ethhdr *)
- ((u8 *) &p_rx_pkt->eth803_hdr
- + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr)
- - sizeof(p_rx_pkt->eth803_hdr.dest_addr)
- - sizeof(p_rx_pkt->eth803_hdr.src_addr)
- - sizeof(p_rx_pkt->rfc1042_hdr.snap_type));
-
- memcpy(p_ethhdr->h_source, p_rx_pkt->eth803_hdr.src_addr,
- sizeof(p_ethhdr->h_source));
- memcpy(p_ethhdr->h_dest, p_rx_pkt->eth803_hdr.dest_addr,
- sizeof(p_ethhdr->h_dest));
-
- /* Chop off the rxpd + the excess memory from the 802.2/llc/snap header
- * that was removed
- */
- hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
- } else {
- lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
- (u8 *) &p_rx_pkt->rfc1042_hdr,
- sizeof(p_rx_pkt->rfc1042_hdr));
-
- /* Chop off the rxpd */
- hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd;
- }
-
- /* Chop off the leading header bytes so the skb points to the start of
- * either the reconstructed EthII frame or the 802.2/llc/snap frame
- */
- skb_pull(skb, hdrchop);
-
- priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
-
- lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
- dev->stats.rx_bytes += skb->len;
- dev->stats.rx_packets++;
-
- skb->protocol = eth_type_trans(skb, dev);
- if (in_interrupt())
- netif_rx(skb);
- else
- netif_rx_ni(skb);
-
- ret = 0;
-done:
- lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
-
-/**
- * convert_mv_rate_to_radiotap - converts Tx/Rx rates from Marvell WLAN format
- * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
- *
- * @rate: Input rate
- * returns: Output Rate (0 if invalid)
- */
-static u8 convert_mv_rate_to_radiotap(u8 rate)
-{
- switch (rate) {
- case 0: /* 1 Mbps */
- return 2;
- case 1: /* 2 Mbps */
- return 4;
- case 2: /* 5.5 Mbps */
- return 11;
- case 3: /* 11 Mbps */
- return 22;
- /* case 4: reserved */
- case 5: /* 6 Mbps */
- return 12;
- case 6: /* 9 Mbps */
- return 18;
- case 7: /* 12 Mbps */
- return 24;
- case 8: /* 18 Mbps */
- return 36;
- case 9: /* 24 Mbps */
- return 48;
- case 10: /* 36 Mbps */
- return 72;
- case 11: /* 48 Mbps */
- return 96;
- case 12: /* 54 Mbps */
- return 108;
- }
- pr_alert("Invalid Marvell WLAN rate %i\n", rate);
- return 0;
-}
-
-/**
- * process_rxed_802_11_packet - processes a received 802.11 packet and forwards
- * it to kernel/upper layer
- *
- * @priv: A pointer to &struct lbs_private
- * @skb: A pointer to skb which includes the received packet
- * returns: 0 or -1
- */
-static int process_rxed_802_11_packet(struct lbs_private *priv,
- struct sk_buff *skb)
-{
- int ret = 0;
- struct net_device *dev = priv->dev;
- struct rx80211packethdr *p_rx_pkt;
- struct rxpd *prxpd;
- struct rx_radiotap_hdr radiotap_hdr;
- struct rx_radiotap_hdr *pradiotap_hdr;
-
- lbs_deb_enter(LBS_DEB_RX);
-
- p_rx_pkt = (struct rx80211packethdr *) skb->data;
- prxpd = &p_rx_pkt->rx_pd;
-
- /* lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); */
-
- if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
- lbs_deb_rx("rx err: frame received with bad length\n");
- dev->stats.rx_length_errors++;
- ret = -EINVAL;
- kfree_skb(skb);
- goto done;
- }
-
- lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
- skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
-
- /* create the exported radio header */
-
- /* radiotap header */
- memset(&radiotap_hdr, 0, sizeof(radiotap_hdr));
- /* XXX must check radiotap_hdr.hdr.it_pad for pad */
- radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
- radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
- radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
- /* XXX must check no carryout */
- radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
-
- /* chop the rxpd */
- skb_pull(skb, sizeof(struct rxpd));
-
- /* add space for the new radio header */
- if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
- pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
- netdev_alert(dev, "%s: couldn't pskb_expand_head\n", __func__);
- ret = -ENOMEM;
- kfree_skb(skb);
- goto done;
- }
-
- pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
- memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr));
-
- priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
-
- lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
- dev->stats.rx_bytes += skb->len;
- dev->stats.rx_packets++;
-
- skb->protocol = eth_type_trans(skb, priv->dev);
-
- if (in_interrupt())
- netif_rx(skb);
- else
- netif_rx_ni(skb);
-
- ret = 0;
-
-done:
- lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
- return ret;
-}
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
deleted file mode 100644
index c025f9c18..000000000
--- a/drivers/net/wireless/libertas/tx.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file contains the handling of TX in wlan driver.
- */
-#include <linux/hardirq.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/sched.h>
-#include <linux/export.h>
-#include <net/cfg80211.h>
-
-#include "host.h"
-#include "radiotap.h"
-#include "decl.h"
-#include "defs.h"
-#include "dev.h"
-#include "mesh.h"
-
-/**
- * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
- * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
- *
- * @rate: Input rate
- * returns: Output Rate (0 if invalid)
- */
-static u32 convert_radiotap_rate_to_mv(u8 rate)
-{
- switch (rate) {
- case 2: /* 1 Mbps */
- return 0 | (1 << 4);
- case 4: /* 2 Mbps */
- return 1 | (1 << 4);
- case 11: /* 5.5 Mbps */
- return 2 | (1 << 4);
- case 22: /* 11 Mbps */
- return 3 | (1 << 4);
- case 12: /* 6 Mbps */
- return 4 | (1 << 4);
- case 18: /* 9 Mbps */
- return 5 | (1 << 4);
- case 24: /* 12 Mbps */
- return 6 | (1 << 4);
- case 36: /* 18 Mbps */
- return 7 | (1 << 4);
- case 48: /* 24 Mbps */
- return 8 | (1 << 4);
- case 72: /* 36 Mbps */
- return 9 | (1 << 4);
- case 96: /* 48 Mbps */
- return 10 | (1 << 4);
- case 108: /* 54 Mbps */
- return 11 | (1 << 4);
- }
- return 0;
-}
-
-/**
- * lbs_hard_start_xmit - checks the conditions and sends packet to IF
- * layer if everything is ok
- *
- * @skb: A pointer to skb which includes TX packet
- * @dev: A pointer to the &struct net_device
- * returns: 0 or -1
- */
-netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- struct lbs_private *priv = dev->ml_priv;
- struct txpd *txpd;
- char *p802x_hdr;
- uint16_t pkt_len;
- netdev_tx_t ret = NETDEV_TX_OK;
-
- lbs_deb_enter(LBS_DEB_TX);
-
- /* We need to protect against the queues being restarted before
- we get round to stopping them */
- spin_lock_irqsave(&priv->driver_lock, flags);
-
- if (priv->surpriseremoved)
- goto free;
-
- if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
- lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
- skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
- /* We'll never manage to send this one; drop it and return 'OK' */
-
- dev->stats.tx_dropped++;
- dev->stats.tx_errors++;
- goto free;
- }
-
-
- netif_stop_queue(priv->dev);
- if (priv->mesh_dev)
- netif_stop_queue(priv->mesh_dev);
-
- if (priv->tx_pending_len) {
- /* This can happen if packets come in on the mesh and eth
- device simultaneously -- there's no mutual exclusion on
- hard_start_xmit() calls between devices. */
- lbs_deb_tx("Packet on %s while busy\n", dev->name);
- ret = NETDEV_TX_BUSY;
- goto unlock;
- }
-
- priv->tx_pending_len = -1;
- spin_unlock_irqrestore(&priv->driver_lock, flags);
-
- lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
-
- txpd = (void *)priv->tx_pending_buf;
- memset(txpd, 0, sizeof(struct txpd));
-
- p802x_hdr = skb->data;
- pkt_len = skb->len;
-
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
- struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
-
- /* set txpd fields from the radiotap header */
- txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate));
-
- /* skip the radiotap header */
- p802x_hdr += sizeof(*rtap_hdr);
- pkt_len -= sizeof(*rtap_hdr);
-
- /* copy destination address from 802.11 header */
- memcpy(txpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
- } else {
- /* copy destination address from 802.3 header */
- memcpy(txpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
- }
-
- txpd->tx_packet_length = cpu_to_le16(pkt_len);
- txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
-
- lbs_mesh_set_txpd(priv, dev, txpd);
-
- lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
-
- lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, le16_to_cpu(txpd->tx_packet_length));
-
- memcpy(&txpd[1], p802x_hdr, le16_to_cpu(txpd->tx_packet_length));
-
- spin_lock_irqsave(&priv->driver_lock, flags);
- priv->tx_pending_len = pkt_len + sizeof(struct txpd);
-
- lbs_deb_tx("%s lined up packet\n", __func__);
-
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
-
- if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
- /* Keep the skb to echo it back once Tx feedback is
- received from FW */
- skb_orphan(skb);
-
- /* Keep the skb around for when we get feedback */
- priv->currenttxskb = skb;
- } else {
- free:
- dev_kfree_skb_any(skb);
- }
-
- unlock:
- spin_unlock_irqrestore(&priv->driver_lock, flags);
- wake_up(&priv->waitq);
-
- lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
- return ret;
-}
-
-/**
- * lbs_send_tx_feedback - sends to the host the last transmitted packet,
- * filling the radiotap headers with transmission information.
- *
- * @priv: A pointer to &struct lbs_private structure
- * @try_count: A 32-bit value containing transmission retry status.
- *
- * returns: void
- */
-void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
-{
- struct tx_radiotap_hdr *radiotap_hdr;
-
- if (priv->wdev->iftype != NL80211_IFTYPE_MONITOR ||
- priv->currenttxskb == NULL)
- return;
-
- radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data;
-
- radiotap_hdr->data_retries = try_count ?
- (1 + priv->txretrycount - try_count) : 0;
-
- priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb,
- priv->dev);
- netif_rx(priv->currenttxskb);
-
- priv->currenttxskb = NULL;
-
- if (priv->connect_status == LBS_CONNECTED)
- netif_wake_queue(priv->dev);
-
- if (priv->mesh_dev && netif_running(priv->mesh_dev))
- netif_wake_queue(priv->mesh_dev);
-}
-EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
deleted file mode 100644
index cf1d9b047..000000000
--- a/drivers/net/wireless/libertas/types.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * This header file contains definition for global types
- */
-#ifndef _LBS_TYPES_H_
-#define _LBS_TYPES_H_
-
-#include <linux/if_ether.h>
-#include <linux/ieee80211.h>
-#include <asm/byteorder.h>
-
-struct ieee_ie_header {
- u8 id;
- u8 len;
-} __packed;
-
-struct ieee_ie_cf_param_set {
- struct ieee_ie_header header;
-
- u8 cfpcnt;
- u8 cfpperiod;
- __le16 cfpmaxduration;
- __le16 cfpdurationremaining;
-} __packed;
-
-
-struct ieee_ie_ibss_param_set {
- struct ieee_ie_header header;
-
- __le16 atimwindow;
-} __packed;
-
-union ieee_ss_param_set {
- struct ieee_ie_cf_param_set cf;
- struct ieee_ie_ibss_param_set ibss;
-} __packed;
-
-struct ieee_ie_fh_param_set {
- struct ieee_ie_header header;
-
- __le16 dwelltime;
- u8 hopset;
- u8 hoppattern;
- u8 hopindex;
-} __packed;
-
-struct ieee_ie_ds_param_set {
- struct ieee_ie_header header;
-
- u8 channel;
-} __packed;
-
-union ieee_phy_param_set {
- struct ieee_ie_fh_param_set fh;
- struct ieee_ie_ds_param_set ds;
-} __packed;
-
-/* TLV type ID definition */
-#define PROPRIETARY_TLV_BASE_ID 0x0100
-
-/* Terminating TLV type */
-#define MRVL_TERMINATE_TLV_ID 0xffff
-
-#define TLV_TYPE_SSID 0x0000
-#define TLV_TYPE_RATES 0x0001
-#define TLV_TYPE_PHY_FH 0x0002
-#define TLV_TYPE_PHY_DS 0x0003
-#define TLV_TYPE_CF 0x0004
-#define TLV_TYPE_IBSS 0x0006
-
-#define TLV_TYPE_DOMAIN 0x0007
-
-#define TLV_TYPE_POWER_CAPABILITY 0x0021
-
-#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
-#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1)
-#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2)
-#define TLV_TYPE_RSSI_LOW (PROPRIETARY_TLV_BASE_ID + 4)
-#define TLV_TYPE_SNR_LOW (PROPRIETARY_TLV_BASE_ID + 5)
-#define TLV_TYPE_FAILCOUNT (PROPRIETARY_TLV_BASE_ID + 6)
-#define TLV_TYPE_BCNMISS (PROPRIETARY_TLV_BASE_ID + 7)
-#define TLV_TYPE_LED_GPIO (PROPRIETARY_TLV_BASE_ID + 8)
-#define TLV_TYPE_LEDBEHAVIOR (PROPRIETARY_TLV_BASE_ID + 9)
-#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10)
-#define TLV_TYPE_REASSOCAP (PROPRIETARY_TLV_BASE_ID + 11)
-#define TLV_TYPE_POWER_TBL_2_4GHZ (PROPRIETARY_TLV_BASE_ID + 12)
-#define TLV_TYPE_POWER_TBL_5GHZ (PROPRIETARY_TLV_BASE_ID + 13)
-#define TLV_TYPE_BCASTPROBE (PROPRIETARY_TLV_BASE_ID + 14)
-#define TLV_TYPE_NUMSSID_PROBE (PROPRIETARY_TLV_BASE_ID + 15)
-#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16)
-#define TLV_TYPE_CRYPTO_DATA (PROPRIETARY_TLV_BASE_ID + 17)
-#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18)
-#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
-#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
-#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
-#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
-#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
-#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
-
-/* TLV related data structures */
-struct mrvl_ie_header {
- __le16 type;
- __le16 len;
-} __packed;
-
-struct mrvl_ie_data {
- struct mrvl_ie_header header;
- u8 Data[1];
-} __packed;
-
-struct mrvl_ie_rates_param_set {
- struct mrvl_ie_header header;
- u8 rates[1];
-} __packed;
-
-struct mrvl_ie_ssid_param_set {
- struct mrvl_ie_header header;
- u8 ssid[1];
-} __packed;
-
-struct mrvl_ie_wildcard_ssid_param_set {
- struct mrvl_ie_header header;
- u8 MaxSsidlength;
- u8 ssid[1];
-} __packed;
-
-struct chanscanmode {
-#ifdef __BIG_ENDIAN_BITFIELD
- u8 reserved_2_7:6;
- u8 disablechanfilt:1;
- u8 passivescan:1;
-#else
- u8 passivescan:1;
- u8 disablechanfilt:1;
- u8 reserved_2_7:6;
-#endif
-} __packed;
-
-struct chanscanparamset {
- u8 radiotype;
- u8 channumber;
- struct chanscanmode chanscanmode;
- __le16 minscantime;
- __le16 maxscantime;
-} __packed;
-
-struct mrvl_ie_chanlist_param_set {
- struct mrvl_ie_header header;
- struct chanscanparamset chanscanparam[1];
-} __packed;
-
-struct mrvl_ie_cf_param_set {
- struct mrvl_ie_header header;
- u8 cfpcnt;
- u8 cfpperiod;
- __le16 cfpmaxduration;
- __le16 cfpdurationremaining;
-} __packed;
-
-struct mrvl_ie_ds_param_set {
- struct mrvl_ie_header header;
- u8 channel;
-} __packed;
-
-struct mrvl_ie_rsn_param_set {
- struct mrvl_ie_header header;
- u8 rsnie[1];
-} __packed;
-
-struct mrvl_ie_tsf_timestamp {
- struct mrvl_ie_header header;
- __le64 tsftable[1];
-} __packed;
-
-/* v9 and later firmware only */
-struct mrvl_ie_auth_type {
- struct mrvl_ie_header header;
- __le16 auth;
-} __packed;
-
-/* Local Power capability */
-struct mrvl_ie_power_capability {
- struct mrvl_ie_header header;
- s8 minpower;
- s8 maxpower;
-} __packed;
-
-/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
-struct mrvl_ie_thresholds {
- struct mrvl_ie_header header;
- u8 value;
- u8 freq;
-} __packed;
-
-struct mrvl_ie_beacons_missed {
- struct mrvl_ie_header header;
- u8 beaconmissed;
- u8 reserved;
-} __packed;
-
-struct mrvl_ie_num_probes {
- struct mrvl_ie_header header;
- __le16 numprobes;
-} __packed;
-
-struct mrvl_ie_bcast_probe {
- struct mrvl_ie_header header;
- __le16 bcastprobe;
-} __packed;
-
-struct mrvl_ie_num_ssid_probe {
- struct mrvl_ie_header header;
- __le16 numssidprobe;
-} __packed;
-
-struct led_pin {
- u8 led;
- u8 pin;
-} __packed;
-
-struct mrvl_ie_ledgpio {
- struct mrvl_ie_header header;
- struct led_pin ledpin[1];
-} __packed;
-
-struct led_bhv {
- uint8_t firmwarestate;
- uint8_t led;
- uint8_t ledstate;
- uint8_t ledarg;
-} __packed;
-
-
-struct mrvl_ie_ledbhv {
- struct mrvl_ie_header header;
- struct led_bhv ledbhv[1];
-} __packed;
-
-/*
- * Meant to be packed as the value member of a struct ieee80211_info_element.
- * Note that the len member of the ieee80211_info_element varies depending on
- * the mesh_id_len
- */
-struct mrvl_meshie_val {
- uint8_t oui[3];
- uint8_t type;
- uint8_t subtype;
- uint8_t version;
- uint8_t active_protocol_id;
- uint8_t active_metric_id;
- uint8_t mesh_capability;
- uint8_t mesh_id_len;
- uint8_t mesh_id[IEEE80211_MAX_SSID_LEN];
-} __packed;
-
-struct mrvl_meshie {
- u8 id, len;
- struct mrvl_meshie_val val;
-} __packed;
-
-struct mrvl_mesh_defaults {
- __le32 bootflag;
- uint8_t boottime;
- uint8_t reserved;
- __le16 channel;
- struct mrvl_meshie meshie;
-} __packed;
-
-#endif