aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:18:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:18:44 -0400
commit252f4bf400df1712408fe83ba199a66a1b57ab1d (patch)
treee07fa00abdd55b31e22567786c78635f32c6a66c /drivers/net
parent6ba1037c3d871ab70e342631516dbf841c35b086 (diff)
parentb37e3b6d64358604960b35e8ecbb7aed22e0926e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/ath/ar9170/main.c drivers/net/wireless/ath/ar9170/phy.c drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath/Kconfig1
-rw-r--r--drivers/net/wireless/ath/Makefile1
-rw-r--r--drivers/net/wireless/ath/ar9170/Kconfig20
-rw-r--r--drivers/net/wireless/ath/ar9170/Makefile3
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h258
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.c127
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.h92
-rw-r--r--drivers/net/wireless/ath/ar9170/eeprom.h179
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h430
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c181
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c519
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c2190
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c1719
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c1008
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.h82
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c98
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h925
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c207
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c94
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c33
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c206
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h66
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c53
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c113
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c175
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c29
-rw-r--r--drivers/net/wireless/ath/key.c32
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c142
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c122
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c529
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h647
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c114
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h191
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c274
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h491
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h342
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c68
-rw-r--r--drivers/net/wireless/libertas/if_spi.c65
-rw-r--r--drivers/net/wireless/mwifiex/11n.c809
-rw-r--r--drivers/net/wireless/mwifiex/11n.h176
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c423
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.h32
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c637
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h67
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig21
-rw-r--r--drivers/net/wireless/mwifiex/Makefile41
-rw-r--r--drivers/net/wireless/mwifiex/README204
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c1456
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h31
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c367
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1459
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c773
-rw-r--r--drivers/net/wireless/mwifiex/decl.h153
-rw-r--r--drivers/net/wireless/mwifiex/fw.h1229
-rw-r--r--drivers/net/wireless/mwifiex/init.c662
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h411
-rw-r--r--drivers/net/wireless/mwifiex/join.c1462
-rw-r--r--drivers/net/wireless/mwifiex/main.c1102
-rw-r--r--drivers/net/wireless/mwifiex/main.h1058
-rw-r--r--drivers/net/wireless/mwifiex/scan.c3097
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c1770
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h305
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c1226
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c983
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c405
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c2360
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c182
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c202
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c202
-rw-r--r--drivers/net/wireless/mwifiex/util.c252
-rw-r--r--drivers/net/wireless/mwifiex/util.h32
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c1237
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h112
-rw-r--r--drivers/net/wireless/mwl8k.c749
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h106
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c198
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c28
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c49
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/wireless/rtlwifi/base.c5
-rw-r--r--drivers/net/wireless/rtlwifi/core.c8
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c106
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c53
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h4
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h18
-rw-r--r--drivers/net/wireless/wl1251/cmd.h4
-rw-r--r--drivers/net/wireless/wl1251/event.c6
-rw-r--r--drivers/net/wireless/wl1251/main.c22
-rw-r--r--drivers/net/wireless/wl1251/ps.c23
-rw-r--r--drivers/net/wireless/wl1251/ps.h2
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h9
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c262
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h533
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c198
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c240
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c78
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c86
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h2
182 files changed, 28444 insertions, 12306 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 7aeb113cbb90..f354bd4e121e 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -284,5 +284,6 @@ source "drivers/net/wireless/rtlwifi/Kconfig"
284source "drivers/net/wireless/wl1251/Kconfig" 284source "drivers/net/wireless/wl1251/Kconfig"
285source "drivers/net/wireless/wl12xx/Kconfig" 285source "drivers/net/wireless/wl12xx/Kconfig"
286source "drivers/net/wireless/zd1211rw/Kconfig" 286source "drivers/net/wireless/zd1211rw/Kconfig"
287source "drivers/net/wireless/mwifiex/Kconfig"
287 288
288endif # WLAN 289endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index ddd3fb6ba1d3..7bba6a82b875 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -56,3 +56,5 @@ obj-$(CONFIG_WL12XX) += wl12xx/
56obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ 56obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
57 57
58obj-$(CONFIG_IWM) += iwmc3200wifi/ 58obj-$(CONFIG_IWM) += iwmc3200wifi/
59
60obj-$(CONFIG_MWIFIEX) += mwifiex/
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 92c216263ee9..d1b23067619f 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -24,7 +24,6 @@ config ATH_DEBUG
24 24
25source "drivers/net/wireless/ath/ath5k/Kconfig" 25source "drivers/net/wireless/ath/ath5k/Kconfig"
26source "drivers/net/wireless/ath/ath9k/Kconfig" 26source "drivers/net/wireless/ath/ath9k/Kconfig"
27source "drivers/net/wireless/ath/ar9170/Kconfig"
28source "drivers/net/wireless/ath/carl9170/Kconfig" 27source "drivers/net/wireless/ath/carl9170/Kconfig"
29 28
30endif 29endif
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 6d711ec97ec2..0e8f528c81c0 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -1,6 +1,5 @@
1obj-$(CONFIG_ATH5K) += ath5k/ 1obj-$(CONFIG_ATH5K) += ath5k/
2obj-$(CONFIG_ATH9K_HW) += ath9k/ 2obj-$(CONFIG_ATH9K_HW) += ath9k/
3obj-$(CONFIG_AR9170_USB) += ar9170/
4obj-$(CONFIG_CARL9170) += carl9170/ 3obj-$(CONFIG_CARL9170) += carl9170/
5 4
6obj-$(CONFIG_ATH_COMMON) += ath.o 5obj-$(CONFIG_ATH_COMMON) += ath.o
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
deleted file mode 100644
index 7b9672b0d090..000000000000
--- a/drivers/net/wireless/ath/ar9170/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
1config AR9170_USB
2 tristate "Atheros AR9170 802.11n USB support (OBSOLETE)"
3 depends on USB && MAC80211
4 select FW_LOADER
5 help
6 This driver is going to get replaced by carl9170.
7
8 This is a driver for the Atheros "otus" 802.11n USB devices.
9
10 These devices require additional firmware (2 files).
11 For now, these files can be downloaded from here:
12
13 http://wireless.kernel.org/en/users/Drivers/ar9170
14
15 If you choose to build a module, it'll be called ar9170usb.
16
17config AR9170_LEDS
18 bool
19 depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
20 default y
diff --git a/drivers/net/wireless/ath/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile
deleted file mode 100644
index 8d91c7ee3215..000000000000
--- a/drivers/net/wireless/ath/ar9170/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
2
3obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
deleted file mode 100644
index 371e4ce49528..000000000000
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ /dev/null
@@ -1,258 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Driver specific definitions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __AR9170_H
39#define __AR9170_H
40
41#include <linux/completion.h>
42#include <linux/spinlock.h>
43#include <net/cfg80211.h>
44#include <net/mac80211.h>
45#ifdef CONFIG_AR9170_LEDS
46#include <linux/leds.h>
47#endif /* CONFIG_AR9170_LEDS */
48#include "eeprom.h"
49#include "hw.h"
50
51#include "../regd.h"
52
53#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
54
55enum ar9170_bw {
56 AR9170_BW_20,
57 AR9170_BW_40_BELOW,
58 AR9170_BW_40_ABOVE,
59
60 __AR9170_NUM_BW,
61};
62
63static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
64{
65 switch (type) {
66 case NL80211_CHAN_NO_HT:
67 case NL80211_CHAN_HT20:
68 return AR9170_BW_20;
69 case NL80211_CHAN_HT40MINUS:
70 return AR9170_BW_40_BELOW;
71 case NL80211_CHAN_HT40PLUS:
72 return AR9170_BW_40_ABOVE;
73 default:
74 BUG();
75 }
76}
77
78enum ar9170_rf_init_mode {
79 AR9170_RFI_NONE,
80 AR9170_RFI_WARM,
81 AR9170_RFI_COLD,
82};
83
84#define AR9170_MAX_RX_BUFFER_SIZE 8192
85
86#ifdef CONFIG_AR9170_LEDS
87struct ar9170;
88
89struct ar9170_led {
90 struct ar9170 *ar;
91 struct led_classdev l;
92 char name[32];
93 unsigned int toggled;
94 bool last_state;
95 bool registered;
96};
97
98#endif /* CONFIG_AR9170_LEDS */
99
100enum ar9170_device_state {
101 AR9170_UNKNOWN_STATE,
102 AR9170_STOPPED,
103 AR9170_IDLE,
104 AR9170_STARTED,
105};
106
107struct ar9170_rxstream_mpdu_merge {
108 struct ar9170_rx_head plcp;
109 bool has_plcp;
110};
111
112struct ar9170_tx_queue_stats {
113 unsigned int len;
114 unsigned int limit;
115 unsigned int count;
116};
117
118#define AR9170_QUEUE_TIMEOUT 64
119#define AR9170_TX_TIMEOUT 8
120#define AR9170_JANITOR_DELAY 128
121#define AR9170_TX_INVALID_RATE 0xffffffff
122
123#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH
124#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10)
125
126struct ar9170 {
127 struct ieee80211_hw *hw;
128 struct ath_common common;
129 struct mutex mutex;
130 enum ar9170_device_state state;
131 bool registered;
132 unsigned long bad_hw_nagger;
133
134 int (*open)(struct ar9170 *);
135 void (*stop)(struct ar9170 *);
136 int (*tx)(struct ar9170 *, struct sk_buff *);
137 int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
138 void *, u32 , void *);
139 void (*callback_cmd)(struct ar9170 *, u32 , void *);
140 int (*flush)(struct ar9170 *);
141
142 /* interface mode settings */
143 struct ieee80211_vif *vif;
144
145 /* beaconing */
146 struct sk_buff *beacon;
147 struct work_struct beacon_work;
148 bool enable_beacon;
149
150 /* cryptographic engine */
151 u64 usedkeys;
152 bool rx_software_decryption;
153 bool disable_offload;
154
155 /* filter settings */
156 u64 cur_mc_hash;
157 u32 cur_filter;
158 unsigned int filter_state;
159 bool sniffer_enabled;
160
161 /* PHY */
162 struct ieee80211_channel *channel;
163 int noise[4];
164
165 /* power calibration data */
166 u8 power_5G_leg[4];
167 u8 power_2G_cck[4];
168 u8 power_2G_ofdm[4];
169 u8 power_5G_ht20[8];
170 u8 power_5G_ht40[8];
171 u8 power_2G_ht20[8];
172 u8 power_2G_ht40[8];
173
174 u8 phy_heavy_clip;
175
176#ifdef CONFIG_AR9170_LEDS
177 struct delayed_work led_work;
178 struct ar9170_led leds[AR9170_NUM_LEDS];
179#endif /* CONFIG_AR9170_LEDS */
180
181 /* qos queue settings */
182 spinlock_t tx_stats_lock;
183 struct ar9170_tx_queue_stats tx_stats[5];
184 struct ieee80211_tx_queue_params edcf[5];
185
186 spinlock_t cmdlock;
187 __le32 cmdbuf[PAYLOAD_MAX + 1];
188
189 /* MAC statistics */
190 struct ieee80211_low_level_stats stats;
191
192 /* EEPROM */
193 struct ar9170_eeprom eeprom;
194
195 /* tx queues - as seen by hw - */
196 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
197 struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
198 struct delayed_work tx_janitor;
199
200 /* rxstream mpdu merge */
201 struct ar9170_rxstream_mpdu_merge rx_mpdu;
202 struct sk_buff *rx_failover;
203 int rx_failover_missing;
204
205 /* (cached) HW A-MPDU settings */
206 u8 global_ampdu_density;
207 u8 global_ampdu_factor;
208};
209
210struct ar9170_tx_info {
211 unsigned long timeout;
212};
213
214#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED)
215#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE)
216
217/* exported interface */
218void *ar9170_alloc(size_t priv_size);
219int ar9170_register(struct ar9170 *ar, struct device *pdev);
220void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
221void ar9170_unregister(struct ar9170 *ar);
222void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
223void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
224int ar9170_nag_limiter(struct ar9170 *ar);
225
226/* MAC */
227void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
228int ar9170_init_mac(struct ar9170 *ar);
229int ar9170_set_qos(struct ar9170 *ar);
230int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
231int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
232int ar9170_set_operating_mode(struct ar9170 *ar);
233int ar9170_set_beacon_timers(struct ar9170 *ar);
234int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
235int ar9170_set_slot_time(struct ar9170 *ar);
236int ar9170_set_basic_rates(struct ar9170 *ar);
237int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
238int ar9170_update_beacon(struct ar9170 *ar);
239void ar9170_new_beacon(struct work_struct *work);
240int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
241 u8 keyidx, u8 *keydata, int keylen);
242int ar9170_disable_key(struct ar9170 *ar, u8 id);
243
244/* LEDs */
245#ifdef CONFIG_AR9170_LEDS
246int ar9170_register_leds(struct ar9170 *ar);
247void ar9170_unregister_leds(struct ar9170 *ar);
248#endif /* CONFIG_AR9170_LEDS */
249int ar9170_init_leds(struct ar9170 *ar);
250int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
251
252/* PHY / RF */
253int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
254int ar9170_init_rf(struct ar9170 *ar);
255int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
256 enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
257
258#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
deleted file mode 100644
index 6452c5055a63..000000000000
--- a/drivers/net/wireless/ath/ar9170/cmd.c
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Basic HW register/memory/command access functions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include "ar9170.h"
40#include "cmd.h"
41
42int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
43{
44 int err;
45
46 if (unlikely(!IS_ACCEPTING_CMD(ar)))
47 return 0;
48
49 err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
50 if (err)
51 wiphy_debug(ar->hw->wiphy, "writing memory failed\n");
52 return err;
53}
54
55int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
56{
57 const __le32 buf[2] = {
58 cpu_to_le32(reg),
59 cpu_to_le32(val),
60 };
61 int err;
62
63 if (unlikely(!IS_ACCEPTING_CMD(ar)))
64 return 0;
65
66 err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
67 (u8 *) buf, 0, NULL);
68 if (err)
69 wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n",
70 reg, val);
71 return err;
72}
73
74int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out)
75{
76 int i, err;
77 __le32 *offs, *res;
78
79 if (unlikely(!IS_ACCEPTING_CMD(ar)))
80 return 0;
81
82 /* abuse "out" for the register offsets, must be same length */
83 offs = (__le32 *)out;
84 for (i = 0; i < nregs; i++)
85 offs[i] = cpu_to_le32(regs[i]);
86
87 /* also use the same buffer for the input */
88 res = (__le32 *)out;
89
90 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
91 4 * nregs, (u8 *)offs,
92 4 * nregs, (u8 *)res);
93 if (err)
94 return err;
95
96 /* convert result to cpu endian */
97 for (i = 0; i < nregs; i++)
98 out[i] = le32_to_cpu(res[i]);
99
100 return 0;
101}
102
103int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
104{
105 return ar9170_read_mreg(ar, 1, &reg, val);
106}
107
108int ar9170_echo_test(struct ar9170 *ar, u32 v)
109{
110 __le32 echobuf = cpu_to_le32(v);
111 __le32 echores;
112 int err;
113
114 if (unlikely(!IS_ACCEPTING_CMD(ar)))
115 return -ENODEV;
116
117 err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
118 4, (u8 *)&echobuf,
119 4, (u8 *)&echores);
120 if (err)
121 return err;
122
123 if (echobuf != echores)
124 return -EINVAL;
125
126 return 0;
127}
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
deleted file mode 100644
index ec8134b4b949..000000000000
--- a/drivers/net/wireless/ath/ar9170/cmd.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Basic HW register/memory/command access functions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __CMD_H
39#define __CMD_H
40
41#include "ar9170.h"
42
43/* basic HW access */
44int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
45int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
46int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
47int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out);
48int ar9170_echo_test(struct ar9170 *ar, u32 v);
49
50/*
51 * Macros to facilitate writing multiple registers in a single
52 * write-combining USB command. Note that when the first group
53 * fails the whole thing will fail without any others attempted,
54 * but you won't know which write in the group failed.
55 */
56#define ar9170_regwrite_begin(ar) \
57do { \
58 int __nreg = 0, __err = 0; \
59 struct ar9170 *__ar = ar;
60
61#define ar9170_regwrite(r, v) do { \
62 __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r); \
63 __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v); \
64 __nreg++; \
65 if ((__nreg >= PAYLOAD_MAX/2)) { \
66 if (IS_ACCEPTING_CMD(__ar)) \
67 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
68 8 * __nreg, \
69 (u8 *) &__ar->cmdbuf[1], \
70 0, NULL); \
71 __nreg = 0; \
72 if (__err) \
73 goto __regwrite_out; \
74 } \
75} while (0)
76
77#define ar9170_regwrite_finish() \
78__regwrite_out : \
79 if (__nreg) { \
80 if (IS_ACCEPTING_CMD(__ar)) \
81 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
82 8 * __nreg, \
83 (u8 *) &__ar->cmdbuf[1], \
84 0, NULL); \
85 __nreg = 0; \
86 }
87
88#define ar9170_regwrite_result() \
89 __err; \
90} while (0);
91
92#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
deleted file mode 100644
index 6c4663883423..000000000000
--- a/drivers/net/wireless/ath/ar9170/eeprom.h
+++ /dev/null
@@ -1,179 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * EEPROM layout
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __AR9170_EEPROM_H
39#define __AR9170_EEPROM_H
40
41#define AR5416_MAX_CHAINS 2
42#define AR5416_MODAL_SPURS 5
43
44struct ar9170_eeprom_modal {
45 __le32 antCtrlChain[AR5416_MAX_CHAINS];
46 __le32 antCtrlCommon;
47 s8 antennaGainCh[AR5416_MAX_CHAINS];
48 u8 switchSettling;
49 u8 txRxAttenCh[AR5416_MAX_CHAINS];
50 u8 rxTxMarginCh[AR5416_MAX_CHAINS];
51 s8 adcDesiredSize;
52 s8 pgaDesiredSize;
53 u8 xlnaGainCh[AR5416_MAX_CHAINS];
54 u8 txEndToXpaOff;
55 u8 txEndToRxOn;
56 u8 txFrameToXpaOn;
57 u8 thresh62;
58 s8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
59 u8 xpdGain;
60 u8 xpd;
61 s8 iqCalICh[AR5416_MAX_CHAINS];
62 s8 iqCalQCh[AR5416_MAX_CHAINS];
63 u8 pdGainOverlap;
64 u8 ob;
65 u8 db;
66 u8 xpaBiasLvl;
67 u8 pwrDecreaseFor2Chain;
68 u8 pwrDecreaseFor3Chain;
69 u8 txFrameToDataStart;
70 u8 txFrameToPaOn;
71 u8 ht40PowerIncForPdadc;
72 u8 bswAtten[AR5416_MAX_CHAINS];
73 u8 bswMargin[AR5416_MAX_CHAINS];
74 u8 swSettleHt40;
75 u8 reserved[22];
76 struct spur_channel {
77 __le16 spurChan;
78 u8 spurRangeLow;
79 u8 spurRangeHigh;
80 } __packed spur_channels[AR5416_MODAL_SPURS];
81} __packed;
82
83#define AR5416_NUM_PD_GAINS 4
84#define AR5416_PD_GAIN_ICEPTS 5
85
86struct ar9170_calibration_data_per_freq {
87 u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
88 u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
89} __packed;
90
91#define AR5416_NUM_5G_CAL_PIERS 8
92#define AR5416_NUM_2G_CAL_PIERS 4
93
94#define AR5416_NUM_5G_TARGET_PWRS 8
95#define AR5416_NUM_2G_CCK_TARGET_PWRS 3
96#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
97#define AR5416_MAX_NUM_TGT_PWRS 8
98
99struct ar9170_calibration_target_power_legacy {
100 u8 freq;
101 u8 power[4];
102} __packed;
103
104struct ar9170_calibration_target_power_ht {
105 u8 freq;
106 u8 power[8];
107} __packed;
108
109#define AR5416_NUM_CTLS 24
110
111struct ar9170_calctl_edges {
112 u8 channel;
113#define AR9170_CALCTL_EDGE_FLAGS 0xC0
114 u8 power_flags;
115} __packed;
116
117#define AR5416_NUM_BAND_EDGES 8
118
119struct ar9170_calctl_data {
120 struct ar9170_calctl_edges
121 control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
122} __packed;
123
124
125struct ar9170_eeprom {
126 __le16 length;
127 __le16 checksum;
128 __le16 version;
129 u8 operating_flags;
130#define AR9170_OPFLAG_5GHZ 1
131#define AR9170_OPFLAG_2GHZ 2
132 u8 misc;
133 __le16 reg_domain[2];
134 u8 mac_address[6];
135 u8 rx_mask;
136 u8 tx_mask;
137 __le16 rf_silent;
138 __le16 bluetooth_options;
139 __le16 device_capabilities;
140 __le32 build_number;
141 u8 deviceType;
142 u8 reserved[33];
143
144 u8 customer_data[64];
145
146 struct ar9170_eeprom_modal
147 modal_header[2];
148
149 u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
150 u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
151
152 struct ar9170_calibration_data_per_freq
153 cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
154 cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
155
156 /* power calibration data */
157 struct ar9170_calibration_target_power_legacy
158 cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
159 struct ar9170_calibration_target_power_ht
160 cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
161 cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
162
163 struct ar9170_calibration_target_power_legacy
164 cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
165 cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
166 struct ar9170_calibration_target_power_ht
167 cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
168 cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
169
170 /* conformance testing limits */
171 u8 ctl_index[AR5416_NUM_CTLS];
172 struct ar9170_calctl_data
173 ctl_data[AR5416_NUM_CTLS];
174
175 u8 pad;
176 __le16 subsystem_id;
177} __packed;
178
179#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
deleted file mode 100644
index 06f1f3c951a4..000000000000
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ /dev/null
@@ -1,430 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * Hardware-specific definitions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38#ifndef __AR9170_HW_H
39#define __AR9170_HW_H
40
41#define AR9170_MAX_CMD_LEN 64
42
43enum ar9170_cmd {
44 AR9170_CMD_RREG = 0x00,
45 AR9170_CMD_WREG = 0x01,
46 AR9170_CMD_RMEM = 0x02,
47 AR9170_CMD_WMEM = 0x03,
48 AR9170_CMD_BITAND = 0x04,
49 AR9170_CMD_BITOR = 0x05,
50 AR9170_CMD_EKEY = 0x28,
51 AR9170_CMD_DKEY = 0x29,
52 AR9170_CMD_FREQUENCY = 0x30,
53 AR9170_CMD_RF_INIT = 0x31,
54 AR9170_CMD_SYNTH = 0x32,
55 AR9170_CMD_FREQ_START = 0x33,
56 AR9170_CMD_ECHO = 0x80,
57 AR9170_CMD_TALLY = 0x81,
58 AR9170_CMD_TALLY_APD = 0x82,
59 AR9170_CMD_CONFIG = 0x83,
60 AR9170_CMD_RESET = 0x90,
61 AR9170_CMD_DKRESET = 0x91,
62 AR9170_CMD_DKTX_STATUS = 0x92,
63 AR9170_CMD_FDC = 0xA0,
64 AR9170_CMD_WREEPROM = 0xB0,
65 AR9170_CMD_WFLASH = 0xB0,
66 AR9170_CMD_FLASH_ERASE = 0xB1,
67 AR9170_CMD_FLASH_PROG = 0xB2,
68 AR9170_CMD_FLASH_CHKSUM = 0xB3,
69 AR9170_CMD_FLASH_READ = 0xB4,
70 AR9170_CMD_FW_DL_INIT = 0xB5,
71 AR9170_CMD_MEM_WREEPROM = 0xBB,
72};
73
74/* endpoints */
75#define AR9170_EP_TX 1
76#define AR9170_EP_RX 2
77#define AR9170_EP_IRQ 3
78#define AR9170_EP_CMD 4
79
80#define AR9170_EEPROM_START 0x1600
81
82#define AR9170_GPIO_REG_BASE 0x1d0100
83#define AR9170_GPIO_REG_PORT_TYPE AR9170_GPIO_REG_BASE
84#define AR9170_GPIO_REG_DATA (AR9170_GPIO_REG_BASE + 4)
85#define AR9170_NUM_LEDS 2
86
87
88#define AR9170_USB_REG_BASE 0x1e1000
89#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108)
90#define AR9170_DMA_CTL_ENABLE_TO_DEVICE 0x1
91#define AR9170_DMA_CTL_ENABLE_FROM_DEVICE 0x2
92#define AR9170_DMA_CTL_HIGH_SPEED 0x4
93#define AR9170_DMA_CTL_PACKET_MODE 0x8
94
95#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110)
96#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114)
97
98
99
100#define AR9170_MAC_REG_BASE 0x1c3000
101
102#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514)
103#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518)
104
105#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51C)
106#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520)
107#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524)
108
109#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610)
110#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614)
111#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618)
112#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c)
113
114#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624)
115#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628)
116
117#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62C)
118
119#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630)
120#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634)
121#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638)
122#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c)
123#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640)
124#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64C)
125
126#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658)
127#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674)
128#define AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC BIT(0)
129#define AR9170_MAC_REG_SNIFFER_DEFAULTS 0x02000000
130#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
131#define AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE BIT(3)
132#define AR9170_MAC_REG_ENCRYPTION_DEFAULTS 0x70
133
134#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680)
135#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688)
136
137#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c)
138#define AR9170_MAC_REG_FTF_ASSOC_REQ BIT(0)
139#define AR9170_MAC_REG_FTF_ASSOC_RESP BIT(1)
140#define AR9170_MAC_REG_FTF_REASSOC_REQ BIT(2)
141#define AR9170_MAC_REG_FTF_REASSOC_RESP BIT(3)
142#define AR9170_MAC_REG_FTF_PRB_REQ BIT(4)
143#define AR9170_MAC_REG_FTF_PRB_RESP BIT(5)
144#define AR9170_MAC_REG_FTF_BIT6 BIT(6)
145#define AR9170_MAC_REG_FTF_BIT7 BIT(7)
146#define AR9170_MAC_REG_FTF_BEACON BIT(8)
147#define AR9170_MAC_REG_FTF_ATIM BIT(9)
148#define AR9170_MAC_REG_FTF_DEASSOC BIT(10)
149#define AR9170_MAC_REG_FTF_AUTH BIT(11)
150#define AR9170_MAC_REG_FTF_DEAUTH BIT(12)
151#define AR9170_MAC_REG_FTF_BIT13 BIT(13)
152#define AR9170_MAC_REG_FTF_BIT14 BIT(14)
153#define AR9170_MAC_REG_FTF_BIT15 BIT(15)
154#define AR9170_MAC_REG_FTF_BAR BIT(24)
155#define AR9170_MAC_REG_FTF_BA BIT(25)
156#define AR9170_MAC_REG_FTF_PSPOLL BIT(26)
157#define AR9170_MAC_REG_FTF_RTS BIT(27)
158#define AR9170_MAC_REG_FTF_CTS BIT(28)
159#define AR9170_MAC_REG_FTF_ACK BIT(29)
160#define AR9170_MAC_REG_FTF_CFE BIT(30)
161#define AR9170_MAC_REG_FTF_CFE_ACK BIT(31)
162#define AR9170_MAC_REG_FTF_DEFAULTS 0x0700ffff
163#define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff
164
165#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0)
166#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6A4)
167#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6A8)
168#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6AC)
169#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6B0)
170#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6BC)
171#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6CC)
172#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6F4)
173
174
175#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690)
176#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698)
177
178#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6F0)
179
180#define AR9170_MAC_REG_POWERMANAGEMENT (AR9170_MAC_REG_BASE + 0x700)
181#define AR9170_MAC_REG_POWERMGT_IBSS 0xe0
182#define AR9170_MAC_REG_POWERMGT_AP 0xa1
183#define AR9170_MAC_REG_POWERMGT_STA 0x2
184#define AR9170_MAC_REG_POWERMGT_AP_WDS 0x3
185#define AR9170_MAC_REG_POWERMGT_DEFAULTS (0xf << 24)
186
187#define AR9170_MAC_REG_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704)
188#define AR9170_MAC_REG_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708)
189
190#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xB00)
191#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xB04)
192#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xB08)
193#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xB0C)
194#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xB10)
195#define AR9170_MAC_REG_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xB14)
196#define AR9170_MAC_REG_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xB18)
197
198#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xB28)
199
200#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xBB0)
201#define AR9170_MAC_FCS_SWFCS 0x1
202#define AR9170_MAC_FCS_FIFO_PROT 0x4
203
204
205#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xB30)
206
207#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
208#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
209
210#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C)
211#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0)
212
213#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
214#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
215
216#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xD7C)
217#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
218#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0
219#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
220#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000
221
222#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xD84)
223#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xD88)
224#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xD90)
225#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xD94)
226#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xDA0)
227#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xDA4)
228
229
230#define AR9170_PWR_REG_BASE 0x1D4000
231
232#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008)
233#define AR9170_PWR_CLK_AHB_40MHZ 0
234#define AR9170_PWR_CLK_AHB_20_22MHZ 1
235#define AR9170_PWR_CLK_AHB_40_44MHZ 2
236#define AR9170_PWR_CLK_AHB_80_88MHZ 3
237#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70
238
239
240/* put beacon here in memory */
241#define AR9170_BEACON_BUFFER_ADDRESS 0x117900
242
243
244struct ar9170_tx_control {
245 __le16 length;
246 __le16 mac_control;
247 __le32 phy_control;
248 u8 frame_data[0];
249} __packed;
250
251/* these are either-or */
252#define AR9170_TX_MAC_PROT_RTS 0x0001
253#define AR9170_TX_MAC_PROT_CTS 0x0002
254
255#define AR9170_TX_MAC_NO_ACK 0x0004
256/* if unset, MAC will only do SIFS space before frame */
257#define AR9170_TX_MAC_BACKOFF 0x0008
258#define AR9170_TX_MAC_BURST 0x0010
259#define AR9170_TX_MAC_AGGR 0x0020
260
261/* encryption is a two-bit field */
262#define AR9170_TX_MAC_ENCR_NONE 0x0000
263#define AR9170_TX_MAC_ENCR_RC4 0x0040
264#define AR9170_TX_MAC_ENCR_CENC 0x0080
265#define AR9170_TX_MAC_ENCR_AES 0x00c0
266
267#define AR9170_TX_MAC_MMIC 0x0100
268#define AR9170_TX_MAC_HW_DURATION 0x0200
269#define AR9170_TX_MAC_QOS_SHIFT 10
270#define AR9170_TX_MAC_QOS_MASK (3 << AR9170_TX_MAC_QOS_SHIFT)
271#define AR9170_TX_MAC_AGGR_QOS_BIT1 0x0400
272#define AR9170_TX_MAC_AGGR_QOS_BIT2 0x0800
273#define AR9170_TX_MAC_DISABLE_TXOP 0x1000
274#define AR9170_TX_MAC_TXOP_RIFS 0x2000
275#define AR9170_TX_MAC_IMM_AMPDU 0x4000
276#define AR9170_TX_MAC_RATE_PROBE 0x8000
277
278/* either-or */
279#define AR9170_TX_PHY_MOD_MASK 0x00000003
280#define AR9170_TX_PHY_MOD_CCK 0x00000000
281#define AR9170_TX_PHY_MOD_OFDM 0x00000001
282#define AR9170_TX_PHY_MOD_HT 0x00000002
283
284/* depends on modulation */
285#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004
286#define AR9170_TX_PHY_GREENFIELD 0x00000004
287
288#define AR9170_TX_PHY_BW_SHIFT 3
289#define AR9170_TX_PHY_BW_MASK (3 << AR9170_TX_PHY_BW_SHIFT)
290#define AR9170_TX_PHY_BW_20MHZ 0
291#define AR9170_TX_PHY_BW_40MHZ 2
292#define AR9170_TX_PHY_BW_40MHZ_DUP 3
293
294#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT 6
295#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
296
297#define AR9170_TX_PHY_TX_PWR_SHIFT 9
298#define AR9170_TX_PHY_TX_PWR_MASK (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
299
300/* not part of the hw-spec */
301#define AR9170_TX_PHY_QOS_SHIFT 25
302#define AR9170_TX_PHY_QOS_MASK (3 << AR9170_TX_PHY_QOS_SHIFT)
303
304#define AR9170_TX_PHY_TXCHAIN_SHIFT 15
305#define AR9170_TX_PHY_TXCHAIN_MASK (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
306#define AR9170_TX_PHY_TXCHAIN_1 1
307/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
308#define AR9170_TX_PHY_TXCHAIN_2 5
309
310#define AR9170_TX_PHY_MCS_SHIFT 18
311#define AR9170_TX_PHY_MCS_MASK (0x7f << AR9170_TX_PHY_MCS_SHIFT)
312
313#define AR9170_TX_PHY_SHORT_GI 0x80000000
314
315#define AR5416_MAX_RATE_POWER 63
316
317struct ar9170_rx_head {
318 u8 plcp[12];
319} __packed;
320
321struct ar9170_rx_phystatus {
322 union {
323 struct {
324 u8 rssi_ant0, rssi_ant1, rssi_ant2,
325 rssi_ant0x, rssi_ant1x, rssi_ant2x,
326 rssi_combined;
327 } __packed;
328 u8 rssi[7];
329 } __packed;
330
331 u8 evm_stream0[6], evm_stream1[6];
332 u8 phy_err;
333} __packed;
334
335struct ar9170_rx_macstatus {
336 u8 SAidx, DAidx;
337 u8 error;
338 u8 status;
339} __packed;
340
341#define AR9170_ENC_ALG_NONE 0x0
342#define AR9170_ENC_ALG_WEP64 0x1
343#define AR9170_ENC_ALG_TKIP 0x2
344#define AR9170_ENC_ALG_AESCCMP 0x4
345#define AR9170_ENC_ALG_WEP128 0x5
346#define AR9170_ENC_ALG_WEP256 0x6
347#define AR9170_ENC_ALG_CENC 0x7
348
349#define AR9170_RX_ENC_SOFTWARE 0x8
350
351static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
352{
353 return (t->SAidx & 0xc0) >> 4 |
354 (t->DAidx & 0xc0) >> 6;
355}
356
357#define AR9170_RX_STATUS_MODULATION_MASK 0x03
358#define AR9170_RX_STATUS_MODULATION_CCK 0x00
359#define AR9170_RX_STATUS_MODULATION_OFDM 0x01
360#define AR9170_RX_STATUS_MODULATION_HT 0x02
361#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03
362
363/* depends on modulation */
364#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08
365#define AR9170_RX_STATUS_GREENFIELD 0x08
366
367#define AR9170_RX_STATUS_MPDU_MASK 0x30
368#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
369#define AR9170_RX_STATUS_MPDU_FIRST 0x20
370#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
371#define AR9170_RX_STATUS_MPDU_LAST 0x10
372
373#define AR9170_RX_ERROR_RXTO 0x01
374#define AR9170_RX_ERROR_OVERRUN 0x02
375#define AR9170_RX_ERROR_DECRYPT 0x04
376#define AR9170_RX_ERROR_FCS 0x08
377#define AR9170_RX_ERROR_WRONG_RA 0x10
378#define AR9170_RX_ERROR_PLCP 0x20
379#define AR9170_RX_ERROR_MMIC 0x40
380#define AR9170_RX_ERROR_FATAL 0x80
381
382struct ar9170_cmd_tx_status {
383 u8 dst[ETH_ALEN];
384 __le32 rate;
385 __le16 status;
386} __packed;
387
388#define AR9170_TX_STATUS_COMPLETE 0x00
389#define AR9170_TX_STATUS_RETRY 0x01
390#define AR9170_TX_STATUS_FAILED 0x02
391
392struct ar9170_cmd_ba_failed_count {
393 __le16 failed;
394 __le16 rate;
395} __packed;
396
397struct ar9170_cmd_response {
398 u8 flag;
399 u8 type;
400 __le16 padding;
401
402 union {
403 struct ar9170_cmd_tx_status tx_status;
404 struct ar9170_cmd_ba_failed_count ba_fail_cnt;
405 u8 data[0];
406 };
407} __packed;
408
409/* QoS */
410
411/* mac80211 queue to HW/FW map */
412static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
413
414/* HW/FW queue to mac80211 map */
415static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
416
417enum ar9170_txq {
418 AR9170_TXQ_BE,
419 AR9170_TXQ_BK,
420 AR9170_TXQ_VI,
421 AR9170_TXQ_VO,
422
423 __AR9170_NUM_TXQ,
424};
425
426#define AR9170_TXQ_DEPTH 32
427#define AR9170_TX_MAX_PENDING 128
428#define AR9170_RX_STREAM_MAX_SIZE 65535
429
430#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
deleted file mode 100644
index 832d90087f8a..000000000000
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ /dev/null
@@ -1,181 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * LED handling
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include "ar9170.h"
40#include "cmd.h"
41
42int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
43{
44 return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
45}
46
47int ar9170_init_leds(struct ar9170 *ar)
48{
49 int err;
50
51 /* disable LEDs */
52 /* GPIO [0/1 mode: output, 2/3: input] */
53 err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
54 if (err)
55 goto out;
56
57 /* GPIO 0/1 value: off */
58 err = ar9170_set_leds_state(ar, 0);
59
60out:
61 return err;
62}
63
64#ifdef CONFIG_AR9170_LEDS
65static void ar9170_update_leds(struct work_struct *work)
66{
67 struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
68 int i, tmp, blink_delay = 1000;
69 u32 led_val = 0;
70 bool rerun = false;
71
72 if (unlikely(!IS_ACCEPTING_CMD(ar)))
73 return ;
74
75 mutex_lock(&ar->mutex);
76 for (i = 0; i < AR9170_NUM_LEDS; i++)
77 if (ar->leds[i].registered && ar->leds[i].toggled) {
78 led_val |= 1 << i;
79
80 tmp = 70 + 200 / (ar->leds[i].toggled);
81 if (tmp < blink_delay)
82 blink_delay = tmp;
83
84 if (ar->leds[i].toggled > 1)
85 ar->leds[i].toggled = 0;
86
87 rerun = true;
88 }
89
90 ar9170_set_leds_state(ar, led_val);
91 mutex_unlock(&ar->mutex);
92
93 if (!rerun)
94 return;
95
96 ieee80211_queue_delayed_work(ar->hw,
97 &ar->led_work,
98 msecs_to_jiffies(blink_delay));
99}
100
101static void ar9170_led_brightness_set(struct led_classdev *led,
102 enum led_brightness brightness)
103{
104 struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
105 struct ar9170 *ar = arl->ar;
106
107 if (unlikely(!arl->registered))
108 return ;
109
110 if (arl->last_state != !!brightness) {
111 arl->toggled++;
112 arl->last_state = !!brightness;
113 }
114
115 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
116 ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
117}
118
119static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
120 char *trigger)
121{
122 int err;
123
124 snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
125 "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
126
127 ar->leds[i].ar = ar;
128 ar->leds[i].l.name = ar->leds[i].name;
129 ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
130 ar->leds[i].l.brightness = 0;
131 ar->leds[i].l.default_trigger = trigger;
132
133 err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
134 &ar->leds[i].l);
135 if (err)
136 wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
137 ar->leds[i].name, err);
138 else
139 ar->leds[i].registered = true;
140
141 return err;
142}
143
144void ar9170_unregister_leds(struct ar9170 *ar)
145{
146 int i;
147
148 for (i = 0; i < AR9170_NUM_LEDS; i++)
149 if (ar->leds[i].registered) {
150 led_classdev_unregister(&ar->leds[i].l);
151 ar->leds[i].registered = false;
152 ar->leds[i].toggled = 0;
153 }
154
155 cancel_delayed_work_sync(&ar->led_work);
156}
157
158int ar9170_register_leds(struct ar9170 *ar)
159{
160 int err;
161
162 INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
163
164 err = ar9170_register_led(ar, 0, "tx",
165 ieee80211_get_tx_led_name(ar->hw));
166 if (err)
167 goto fail;
168
169 err = ar9170_register_led(ar, 1, "assoc",
170 ieee80211_get_assoc_led_name(ar->hw));
171 if (err)
172 goto fail;
173
174 return 0;
175
176fail:
177 ar9170_unregister_leds(ar);
178 return err;
179}
180
181#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
deleted file mode 100644
index 857e86104295..000000000000
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ /dev/null
@@ -1,519 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * MAC programming
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include <asm/unaligned.h>
40
41#include "ar9170.h"
42#include "cmd.h"
43
44int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
45{
46 u32 val;
47
48 if (conf_is_ht40(&ar->hw->conf))
49 val = 0x010a;
50 else {
51 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
52 val = 0x105;
53 else
54 val = 0x104;
55 }
56
57 return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
58}
59
60int ar9170_set_slot_time(struct ar9170 *ar)
61{
62 u32 slottime = 20;
63
64 if (!ar->vif)
65 return 0;
66
67 if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
68 ar->vif->bss_conf.use_short_slot)
69 slottime = 9;
70
71 return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
72}
73
74int ar9170_set_basic_rates(struct ar9170 *ar)
75{
76 u8 cck, ofdm;
77
78 if (!ar->vif)
79 return 0;
80
81 ofdm = ar->vif->bss_conf.basic_rates >> 4;
82
83 /* FIXME: is still necessary? */
84 if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
85 cck = 0;
86 else
87 cck = ar->vif->bss_conf.basic_rates & 0xf;
88
89 return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
90 ofdm << 8 | cck);
91}
92
93int ar9170_set_qos(struct ar9170 *ar)
94{
95 ar9170_regwrite_begin(ar);
96
97 ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
98 (ar->edcf[0].cw_max << 16));
99 ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
100 (ar->edcf[1].cw_max << 16));
101 ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
102 (ar->edcf[2].cw_max << 16));
103 ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
104 (ar->edcf[3].cw_max << 16));
105 ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
106 (ar->edcf[4].cw_max << 16));
107
108 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
109 ((ar->edcf[0].aifs * 9 + 10)) |
110 ((ar->edcf[1].aifs * 9 + 10) << 12) |
111 ((ar->edcf[2].aifs * 9 + 10) << 24));
112 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
113 ((ar->edcf[2].aifs * 9 + 10) >> 8) |
114 ((ar->edcf[3].aifs * 9 + 10) << 4) |
115 ((ar->edcf[4].aifs * 9 + 10) << 16));
116
117 ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
118 ar->edcf[0].txop | ar->edcf[1].txop << 16);
119 ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
120 ar->edcf[2].txop | ar->edcf[3].txop << 16);
121
122 ar9170_regwrite_finish();
123
124 return ar9170_regwrite_result();
125}
126
127static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
128{
129 u32 val;
130
131 /* don't allow AMPDU density > 8us */
132 if (mpdudensity > 6)
133 return -EINVAL;
134
135 /* Watch out! Otus uses slightly different density values. */
136 val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
137
138 ar9170_regwrite_begin(ar);
139 ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
140 ar9170_regwrite_finish();
141
142 return ar9170_regwrite_result();
143}
144
145int ar9170_init_mac(struct ar9170 *ar)
146{
147 ar9170_regwrite_begin(ar);
148
149 ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
150
151 ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
152
153 /* enable MMIC */
154 ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
155 AR9170_MAC_REG_SNIFFER_DEFAULTS);
156
157 ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
158
159 ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
160 ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
161 ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
162
163 /* CF-END mode */
164 ar9170_regwrite(0x1c3b2c, 0x19000000);
165
166 /* NAV protects ACK only (in TXOP) */
167 ar9170_regwrite(0x1c3b38, 0x201);
168
169 /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
170 /* OTUS set AM to 0x1 */
171 ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
172
173 ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
174
175 /* AGG test code*/
176 /* Aggregation MAX number and timeout */
177 ar9170_regwrite(0x1c3b9c, 0x10000a);
178
179 ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
180 AR9170_MAC_REG_FTF_DEFAULTS);
181
182 /* Enable deaggregator, response in sniffer mode */
183 ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
184
185 /* rate sets */
186 ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
187 ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
188 ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
189
190 /* MIMO response control */
191 ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */
192
193 /* switch MAC to OTUS interface */
194 ar9170_regwrite(0x1c3600, 0x3);
195
196 ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
197
198 /* set PHY register read timeout (??) */
199 ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
200
201 /* Disable Rx TimeOut, workaround for BB. */
202 ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
203
204 /* Set CPU clock frequency to 88/80MHz */
205 ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
206 AR9170_PWR_CLK_AHB_80_88MHZ |
207 AR9170_PWR_CLK_DAC_160_INV_DLY);
208
209 /* Set WLAN DMA interrupt mode: generate int per packet */
210 ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
211
212 ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
213 AR9170_MAC_FCS_FIFO_PROT);
214
215 /* Disables the CF_END frame, undocumented register */
216 ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
217 0x141E0F48);
218
219 ar9170_regwrite_finish();
220
221 return ar9170_regwrite_result();
222}
223
224static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
225{
226 static const u8 zero[ETH_ALEN] = { 0 };
227
228 if (!mac)
229 mac = zero;
230
231 ar9170_regwrite_begin(ar);
232
233 ar9170_regwrite(reg, get_unaligned_le32(mac));
234 ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
235
236 ar9170_regwrite_finish();
237
238 return ar9170_regwrite_result();
239}
240
241int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
242{
243 int err;
244
245 ar9170_regwrite_begin(ar);
246 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
247 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
248 ar9170_regwrite_finish();
249 err = ar9170_regwrite_result();
250 if (err)
251 return err;
252
253 ar->cur_mc_hash = mc_hash;
254 return 0;
255}
256
257int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
258{
259 int err;
260
261 err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
262 if (err)
263 return err;
264
265 ar->cur_filter = filter;
266 return 0;
267}
268
269static int ar9170_set_promiscouous(struct ar9170 *ar)
270{
271 u32 encr_mode, sniffer;
272 int err;
273
274 err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
275 if (err)
276 return err;
277
278 err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
279 if (err)
280 return err;
281
282 if (ar->sniffer_enabled) {
283 sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
284
285 /*
286 * Rx decryption works in place.
287 *
288 * If we don't disable it, the hardware will render all
289 * encrypted frames which are encrypted with an unknown
290 * key useless.
291 */
292
293 encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
294 ar->sniffer_enabled = true;
295 } else {
296 sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
297
298 if (ar->rx_software_decryption)
299 encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
300 else
301 encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
302 }
303
304 ar9170_regwrite_begin(ar);
305 ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
306 ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
307 ar9170_regwrite_finish();
308
309 return ar9170_regwrite_result();
310}
311
312int ar9170_set_operating_mode(struct ar9170 *ar)
313{
314 struct ath_common *common = &ar->common;
315 u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
316 u8 *mac_addr, *bssid;
317 int err;
318
319 if (ar->vif) {
320 mac_addr = common->macaddr;
321 bssid = common->curbssid;
322
323 switch (ar->vif->type) {
324 case NL80211_IFTYPE_MESH_POINT:
325 case NL80211_IFTYPE_ADHOC:
326 pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
327 break;
328 case NL80211_IFTYPE_AP:
329 pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
330 break;
331 case NL80211_IFTYPE_WDS:
332 pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
333 break;
334 case NL80211_IFTYPE_MONITOR:
335 ar->sniffer_enabled = true;
336 ar->rx_software_decryption = true;
337 break;
338 default:
339 pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
340 break;
341 }
342 } else {
343 mac_addr = NULL;
344 bssid = NULL;
345 }
346
347 err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
348 if (err)
349 return err;
350
351 err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
352 if (err)
353 return err;
354
355 err = ar9170_set_promiscouous(ar);
356 if (err)
357 return err;
358
359 /* set AMPDU density to 8us. */
360 err = ar9170_set_ampdu_density(ar, 6);
361 if (err)
362 return err;
363
364 ar9170_regwrite_begin(ar);
365
366 ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
367 ar9170_regwrite_finish();
368
369 return ar9170_regwrite_result();
370}
371
372int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
373{
374 u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
375
376 return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
377}
378
379int ar9170_set_beacon_timers(struct ar9170 *ar)
380{
381 u32 v = 0;
382 u32 pretbtt = 0;
383
384 if (ar->vif) {
385 v |= ar->vif->bss_conf.beacon_int;
386
387 if (ar->enable_beacon) {
388 switch (ar->vif->type) {
389 case NL80211_IFTYPE_MESH_POINT:
390 case NL80211_IFTYPE_ADHOC:
391 v |= BIT(25);
392 break;
393 case NL80211_IFTYPE_AP:
394 v |= BIT(24);
395 pretbtt = (ar->vif->bss_conf.beacon_int - 6) <<
396 16;
397 break;
398 default:
399 break;
400 }
401 }
402
403 v |= ar->vif->bss_conf.dtim_period << 16;
404 }
405
406 ar9170_regwrite_begin(ar);
407 ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
408 ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
409 ar9170_regwrite_finish();
410 return ar9170_regwrite_result();
411}
412
413int ar9170_update_beacon(struct ar9170 *ar)
414{
415 struct sk_buff *skb;
416 __le32 *data, *old = NULL;
417 u32 word;
418 int i;
419
420 skb = ieee80211_beacon_get(ar->hw, ar->vif);
421 if (!skb)
422 return -ENOMEM;
423
424 data = (__le32 *)skb->data;
425 if (ar->beacon)
426 old = (__le32 *)ar->beacon->data;
427
428 ar9170_regwrite_begin(ar);
429 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
430 /*
431 * XXX: This accesses beyond skb data for up
432 * to the last 3 bytes!!
433 */
434
435 if (old && (data[i] == old[i]))
436 continue;
437
438 word = le32_to_cpu(data[i]);
439 ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
440 }
441
442 /* XXX: use skb->cb info */
443 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
444 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
445 ((skb->len + 4) << (3 + 16)) + 0x0400);
446 else
447 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
448 ((skb->len + 4) << 16) + 0x001b);
449
450 ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
451 ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
452 ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
453
454 ar9170_regwrite_finish();
455
456 dev_kfree_skb(ar->beacon);
457 ar->beacon = skb;
458
459 return ar9170_regwrite_result();
460}
461
462void ar9170_new_beacon(struct work_struct *work)
463{
464 struct ar9170 *ar = container_of(work, struct ar9170,
465 beacon_work);
466 struct sk_buff *skb;
467
468 if (unlikely(!IS_STARTED(ar)))
469 return ;
470
471 mutex_lock(&ar->mutex);
472
473 if (!ar->vif)
474 goto out;
475
476 ar9170_update_beacon(ar);
477
478 rcu_read_lock();
479 while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
480 ar9170_op_tx(ar->hw, skb);
481
482 rcu_read_unlock();
483
484 out:
485 mutex_unlock(&ar->mutex);
486}
487
488int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
489 u8 keyidx, u8 *keydata, int keylen)
490{
491 __le32 vals[7];
492 static const u8 bcast[ETH_ALEN] =
493 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
494 u8 dummy;
495
496 mac = mac ? : bcast;
497
498 vals[0] = cpu_to_le32((keyidx << 16) + id);
499 vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
500 vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
501 mac[3] << 8 | mac[2]);
502 memset(&vals[3], 0, 16);
503 if (keydata)
504 memcpy(&vals[3], keydata, keylen);
505
506 return ar->exec_cmd(ar, AR9170_CMD_EKEY,
507 sizeof(vals), (u8 *)vals,
508 1, &dummy);
509}
510
511int ar9170_disable_key(struct ar9170 *ar, u8 id)
512{
513 __le32 val = cpu_to_le32(id);
514 u8 dummy;
515
516 return ar->exec_cmd(ar, AR9170_CMD_EKEY,
517 sizeof(val), (u8 *)&val,
518 1, &dummy);
519}
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
deleted file mode 100644
index ccc2edaaeda0..000000000000
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ /dev/null
@@ -1,2190 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * mac80211 interaction code
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; see the file COPYING. If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 * Copyright (c) 2007-2008 Atheros Communications, Inc.
26 *
27 * Permission to use, copy, modify, and/or distribute this software for any
28 * purpose with or without fee is hereby granted, provided that the above
29 * copyright notice and this permission notice appear in all copies.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39
40#include <linux/init.h>
41#include <linux/slab.h>
42#include <linux/module.h>
43#include <linux/etherdevice.h>
44#include <net/mac80211.h>
45#include "ar9170.h"
46#include "hw.h"
47#include "cmd.h"
48
49static int modparam_nohwcrypt;
50module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
51MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
52
53#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
54 .bitrate = (_bitrate), \
55 .flags = (_flags), \
56 .hw_value = (_hw_rate) | (_txpidx) << 4, \
57}
58
59static struct ieee80211_rate __ar9170_ratetable[] = {
60 RATE(10, 0, 0, 0),
61 RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
62 RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
63 RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
64 RATE(60, 0xb, 0, 0),
65 RATE(90, 0xf, 0, 0),
66 RATE(120, 0xa, 0, 0),
67 RATE(180, 0xe, 0, 0),
68 RATE(240, 0x9, 0, 0),
69 RATE(360, 0xd, 1, 0),
70 RATE(480, 0x8, 2, 0),
71 RATE(540, 0xc, 3, 0),
72};
73#undef RATE
74
75#define ar9170_g_ratetable (__ar9170_ratetable + 0)
76#define ar9170_g_ratetable_size 12
77#define ar9170_a_ratetable (__ar9170_ratetable + 4)
78#define ar9170_a_ratetable_size 8
79
80/*
81 * NB: The hw_value is used as an index into the ar9170_phy_freq_params
82 * array in phy.c so that we don't have to do frequency lookups!
83 */
84#define CHAN(_freq, _idx) { \
85 .center_freq = (_freq), \
86 .hw_value = (_idx), \
87 .max_power = 18, /* XXX */ \
88}
89
90static struct ieee80211_channel ar9170_2ghz_chantable[] = {
91 CHAN(2412, 0),
92 CHAN(2417, 1),
93 CHAN(2422, 2),
94 CHAN(2427, 3),
95 CHAN(2432, 4),
96 CHAN(2437, 5),
97 CHAN(2442, 6),
98 CHAN(2447, 7),
99 CHAN(2452, 8),
100 CHAN(2457, 9),
101 CHAN(2462, 10),
102 CHAN(2467, 11),
103 CHAN(2472, 12),
104 CHAN(2484, 13),
105};
106
107static struct ieee80211_channel ar9170_5ghz_chantable[] = {
108 CHAN(4920, 14),
109 CHAN(4940, 15),
110 CHAN(4960, 16),
111 CHAN(4980, 17),
112 CHAN(5040, 18),
113 CHAN(5060, 19),
114 CHAN(5080, 20),
115 CHAN(5180, 21),
116 CHAN(5200, 22),
117 CHAN(5220, 23),
118 CHAN(5240, 24),
119 CHAN(5260, 25),
120 CHAN(5280, 26),
121 CHAN(5300, 27),
122 CHAN(5320, 28),
123 CHAN(5500, 29),
124 CHAN(5520, 30),
125 CHAN(5540, 31),
126 CHAN(5560, 32),
127 CHAN(5580, 33),
128 CHAN(5600, 34),
129 CHAN(5620, 35),
130 CHAN(5640, 36),
131 CHAN(5660, 37),
132 CHAN(5680, 38),
133 CHAN(5700, 39),
134 CHAN(5745, 40),
135 CHAN(5765, 41),
136 CHAN(5785, 42),
137 CHAN(5805, 43),
138 CHAN(5825, 44),
139 CHAN(5170, 45),
140 CHAN(5190, 46),
141 CHAN(5210, 47),
142 CHAN(5230, 48),
143};
144#undef CHAN
145
146#define AR9170_HT_CAP \
147{ \
148 .ht_supported = true, \
149 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
150 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
151 IEEE80211_HT_CAP_SGI_40 | \
152 IEEE80211_HT_CAP_GRN_FLD | \
153 IEEE80211_HT_CAP_DSSSCCK40 | \
154 IEEE80211_HT_CAP_SM_PS, \
155 .ampdu_factor = 3, \
156 .ampdu_density = 6, \
157 .mcs = { \
158 .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
159 .rx_highest = cpu_to_le16(300), \
160 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
161 }, \
162}
163
164static struct ieee80211_supported_band ar9170_band_2GHz = {
165 .channels = ar9170_2ghz_chantable,
166 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
167 .bitrates = ar9170_g_ratetable,
168 .n_bitrates = ar9170_g_ratetable_size,
169 .ht_cap = AR9170_HT_CAP,
170};
171
172static struct ieee80211_supported_band ar9170_band_5GHz = {
173 .channels = ar9170_5ghz_chantable,
174 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
175 .bitrates = ar9170_a_ratetable,
176 .n_bitrates = ar9170_a_ratetable_size,
177 .ht_cap = AR9170_HT_CAP,
178};
179
180static void ar9170_tx(struct ar9170 *ar);
181
182static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
183{
184 return le16_to_cpu(hdr->seq_ctrl) >> 4;
185}
186
187static inline u16 ar9170_get_seq(struct sk_buff *skb)
188{
189 struct ar9170_tx_control *txc = (void *) skb->data;
190 return ar9170_get_seq_h((void *) txc->frame_data);
191}
192
193#ifdef AR9170_QUEUE_DEBUG
194static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
195{
196 struct ar9170_tx_control *txc = (void *) skb->data;
197 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
198 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
199 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
200
201 wiphy_debug(ar->hw->wiphy,
202 "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
203 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
204 skb, skb_get_queue_mapping(skb),
205 ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
206 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
207 jiffies_to_msecs(arinfo->timeout - jiffies));
208}
209
210static void __ar9170_dump_txqueue(struct ar9170 *ar,
211 struct sk_buff_head *queue)
212{
213 struct sk_buff *skb;
214 int i = 0;
215
216 printk(KERN_DEBUG "---[ cut here ]---\n");
217 wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n",
218 skb_queue_len(queue));
219
220 skb_queue_walk(queue, skb) {
221 printk(KERN_DEBUG "index:%d =>\n", i++);
222 ar9170_print_txheader(ar, skb);
223 }
224 if (i != skb_queue_len(queue))
225 printk(KERN_DEBUG "WARNING: queue frame counter "
226 "mismatch %d != %d\n", skb_queue_len(queue), i);
227 printk(KERN_DEBUG "---[ end ]---\n");
228}
229#endif /* AR9170_QUEUE_DEBUG */
230
231#ifdef AR9170_QUEUE_DEBUG
232static void ar9170_dump_txqueue(struct ar9170 *ar,
233 struct sk_buff_head *queue)
234{
235 unsigned long flags;
236
237 spin_lock_irqsave(&queue->lock, flags);
238 __ar9170_dump_txqueue(ar, queue);
239 spin_unlock_irqrestore(&queue->lock, flags);
240}
241#endif /* AR9170_QUEUE_DEBUG */
242
243#ifdef AR9170_QUEUE_STOP_DEBUG
244static void __ar9170_dump_txstats(struct ar9170 *ar)
245{
246 int i;
247
248 wiphy_debug(ar->hw->wiphy, "QoS queue stats\n");
249
250 for (i = 0; i < __AR9170_NUM_TXQ; i++)
251 wiphy_debug(ar->hw->wiphy,
252 "queue:%d limit:%d len:%d waitack:%d stopped:%d\n",
253 i, ar->tx_stats[i].limit, ar->tx_stats[i].len,
254 skb_queue_len(&ar->tx_status[i]),
255 ieee80211_queue_stopped(ar->hw, i));
256}
257#endif /* AR9170_QUEUE_STOP_DEBUG */
258
259/* caller must guarantee exclusive access for _bin_ queue. */
260static void ar9170_recycle_expired(struct ar9170 *ar,
261 struct sk_buff_head *queue,
262 struct sk_buff_head *bin)
263{
264 struct sk_buff *skb, *old = NULL;
265 unsigned long flags;
266
267 spin_lock_irqsave(&queue->lock, flags);
268 while ((skb = skb_peek(queue))) {
269 struct ieee80211_tx_info *txinfo;
270 struct ar9170_tx_info *arinfo;
271
272 txinfo = IEEE80211_SKB_CB(skb);
273 arinfo = (void *) txinfo->rate_driver_data;
274
275 if (time_is_before_jiffies(arinfo->timeout)) {
276#ifdef AR9170_QUEUE_DEBUG
277 wiphy_debug(ar->hw->wiphy,
278 "[%ld > %ld] frame expired => recycle\n",
279 jiffies, arinfo->timeout);
280 ar9170_print_txheader(ar, skb);
281#endif /* AR9170_QUEUE_DEBUG */
282 __skb_unlink(skb, queue);
283 __skb_queue_tail(bin, skb);
284 } else {
285 break;
286 }
287
288 if (unlikely(old == skb)) {
289 /* bail out - queue is shot. */
290
291 WARN_ON(1);
292 break;
293 }
294 old = skb;
295 }
296 spin_unlock_irqrestore(&queue->lock, flags);
297}
298
299static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
300 u16 tx_status)
301{
302 struct ieee80211_tx_info *txinfo;
303 unsigned int retries = 0;
304
305 txinfo = IEEE80211_SKB_CB(skb);
306 ieee80211_tx_info_clear_status(txinfo);
307
308 switch (tx_status) {
309 case AR9170_TX_STATUS_RETRY:
310 retries = 2;
311 case AR9170_TX_STATUS_COMPLETE:
312 txinfo->flags |= IEEE80211_TX_STAT_ACK;
313 break;
314
315 case AR9170_TX_STATUS_FAILED:
316 retries = ar->hw->conf.long_frame_max_tx_count;
317 break;
318
319 default:
320 wiphy_err(ar->hw->wiphy,
321 "invalid tx_status response (%x)\n", tx_status);
322 break;
323 }
324
325 txinfo->status.rates[0].count = retries + 1;
326 skb_pull(skb, sizeof(struct ar9170_tx_control));
327 ieee80211_tx_status_irqsafe(ar->hw, skb);
328}
329
330void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
331{
332 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
333 struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
334 unsigned int queue = skb_get_queue_mapping(skb);
335 unsigned long flags;
336
337 spin_lock_irqsave(&ar->tx_stats_lock, flags);
338 ar->tx_stats[queue].len--;
339
340 if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
341#ifdef AR9170_QUEUE_STOP_DEBUG
342 wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue);
343 __ar9170_dump_txstats(ar);
344#endif /* AR9170_QUEUE_STOP_DEBUG */
345 ieee80211_wake_queue(ar->hw, queue);
346 }
347 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
348
349 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
350 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
351 } else {
352 arinfo->timeout = jiffies +
353 msecs_to_jiffies(AR9170_TX_TIMEOUT);
354
355 skb_queue_tail(&ar->tx_status[queue], skb);
356 }
357
358 if (!ar->tx_stats[queue].len &&
359 !skb_queue_empty(&ar->tx_pending[queue])) {
360 ar9170_tx(ar);
361 }
362}
363
364static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
365 const u8 *mac,
366 struct sk_buff_head *queue,
367 const u32 rate)
368{
369 unsigned long flags;
370 struct sk_buff *skb;
371
372 /*
373 * Unfortunately, the firmware does not tell to which (queued) frame
374 * this transmission status report belongs to.
375 *
376 * So we have to make risky guesses - with the scarce information
377 * the firmware provided (-> destination MAC, and phy_control) -
378 * and hope that we picked the right one...
379 */
380
381 spin_lock_irqsave(&queue->lock, flags);
382 skb_queue_walk(queue, skb) {
383 struct ar9170_tx_control *txc = (void *) skb->data;
384 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
385 u32 r;
386
387 if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
388#ifdef AR9170_QUEUE_DEBUG
389 wiphy_debug(ar->hw->wiphy,
390 "skip frame => DA %pM != %pM\n",
391 mac, ieee80211_get_DA(hdr));
392 ar9170_print_txheader(ar, skb);
393#endif /* AR9170_QUEUE_DEBUG */
394 continue;
395 }
396
397 r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
398 AR9170_TX_PHY_MCS_SHIFT;
399
400 if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
401#ifdef AR9170_QUEUE_DEBUG
402 wiphy_debug(ar->hw->wiphy,
403 "skip frame => rate %d != %d\n", rate, r);
404 ar9170_print_txheader(ar, skb);
405#endif /* AR9170_QUEUE_DEBUG */
406 continue;
407 }
408
409 __skb_unlink(skb, queue);
410 spin_unlock_irqrestore(&queue->lock, flags);
411 return skb;
412 }
413
414#ifdef AR9170_QUEUE_DEBUG
415 wiphy_err(ar->hw->wiphy,
416 "ESS:[%pM] does not have any outstanding frames in queue.\n",
417 mac);
418 __ar9170_dump_txqueue(ar, queue);
419#endif /* AR9170_QUEUE_DEBUG */
420 spin_unlock_irqrestore(&queue->lock, flags);
421
422 return NULL;
423}
424
425/*
426 * This worker tries to keeps an maintain tx_status queues.
427 * So we can guarantee that incoming tx_status reports are
428 * actually for a pending frame.
429 */
430
431static void ar9170_tx_janitor(struct work_struct *work)
432{
433 struct ar9170 *ar = container_of(work, struct ar9170,
434 tx_janitor.work);
435 struct sk_buff_head waste;
436 unsigned int i;
437 bool resched = false;
438
439 if (unlikely(!IS_STARTED(ar)))
440 return ;
441
442 skb_queue_head_init(&waste);
443
444 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
445#ifdef AR9170_QUEUE_DEBUG
446 wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n",
447 i);
448 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
449 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
450#endif /* AR9170_QUEUE_DEBUG */
451
452 ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
453 ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
454 skb_queue_purge(&waste);
455
456 if (!skb_queue_empty(&ar->tx_status[i]) ||
457 !skb_queue_empty(&ar->tx_pending[i]))
458 resched = true;
459 }
460
461 if (!resched)
462 return;
463
464 ieee80211_queue_delayed_work(ar->hw,
465 &ar->tx_janitor,
466 msecs_to_jiffies(AR9170_JANITOR_DELAY));
467}
468
469void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
470{
471 struct ar9170_cmd_response *cmd = (void *) buf;
472
473 if ((cmd->type & 0xc0) != 0xc0) {
474 ar->callback_cmd(ar, len, buf);
475 return;
476 }
477
478 /* hardware event handlers */
479 switch (cmd->type) {
480 case 0xc1: {
481 /*
482 * TX status notification:
483 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
484 *
485 * XX always 81
486 * YY always 00
487 * M1-M6 is the MAC address
488 * R1-R4 is the transmit rate
489 * S1-S2 is the transmit status
490 */
491
492 struct sk_buff *skb;
493 u32 phy = le32_to_cpu(cmd->tx_status.rate);
494 u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
495 AR9170_TX_PHY_QOS_SHIFT;
496#ifdef AR9170_QUEUE_DEBUG
497 wiphy_debug(ar->hw->wiphy,
498 "recv tx_status for %pm, p:%08x, q:%d\n",
499 cmd->tx_status.dst, phy, q);
500#endif /* AR9170_QUEUE_DEBUG */
501
502 skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
503 &ar->tx_status[q],
504 AR9170_TX_INVALID_RATE);
505 if (unlikely(!skb))
506 return ;
507
508 ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
509 break;
510 }
511
512 case 0xc0:
513 /*
514 * pre-TBTT event
515 */
516 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
517 ieee80211_queue_work(ar->hw, &ar->beacon_work);
518 break;
519
520 case 0xc2:
521 /*
522 * (IBSS) beacon send notification
523 * bytes: 04 c2 XX YY B4 B3 B2 B1
524 *
525 * XX always 80
526 * YY always 00
527 * B1-B4 "should" be the number of send out beacons.
528 */
529 break;
530
531 case 0xc3:
532 /* End of Atim Window */
533 break;
534
535 case 0xc4:
536 /* BlockACK bitmap */
537 break;
538
539 case 0xc5:
540 /* BlockACK events */
541 break;
542
543 case 0xc6:
544 /* Watchdog Interrupt */
545 break;
546
547 case 0xc9:
548 /* retransmission issue / SIFS/EIFS collision ?! */
549 break;
550
551 /* firmware debug */
552 case 0xca:
553 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
554 (char *)buf + 4);
555 break;
556 case 0xcb:
557 len -= 4;
558
559 switch (len) {
560 case 1:
561 printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
562 *((char *)buf + 4));
563 break;
564 case 2:
565 printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
566 le16_to_cpup((__le16 *)((char *)buf + 4)));
567 break;
568 case 4:
569 printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
570 le32_to_cpup((__le32 *)((char *)buf + 4)));
571 break;
572 case 8:
573 printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
574 (unsigned long)le64_to_cpup(
575 (__le64 *)((char *)buf + 4)));
576 break;
577 }
578 break;
579 case 0xcc:
580 print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
581 (char *)buf + 4, len - 4);
582 break;
583
584 default:
585 pr_info("received unhandled event %x\n", cmd->type);
586 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
587 break;
588 }
589}
590
591static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
592{
593 memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
594 ar->rx_mpdu.has_plcp = false;
595}
596
597int ar9170_nag_limiter(struct ar9170 *ar)
598{
599 bool print_message;
600
601 /*
602 * we expect all sorts of errors in promiscuous mode.
603 * don't bother with it, it's OK!
604 */
605 if (ar->sniffer_enabled)
606 return false;
607
608 /*
609 * only go for frequent errors! The hardware tends to
610 * do some stupid thing once in a while under load, in
611 * noisy environments or just for fun!
612 */
613 if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
614 print_message = true;
615 else
616 print_message = false;
617
618 /* reset threshold for "once in a while" */
619 ar->bad_hw_nagger = jiffies + HZ / 4;
620 return print_message;
621}
622
623static int ar9170_rx_mac_status(struct ar9170 *ar,
624 struct ar9170_rx_head *head,
625 struct ar9170_rx_macstatus *mac,
626 struct ieee80211_rx_status *status)
627{
628 u8 error, decrypt;
629
630 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
631 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
632
633 error = mac->error;
634 if (error & AR9170_RX_ERROR_MMIC) {
635 status->flag |= RX_FLAG_MMIC_ERROR;
636 error &= ~AR9170_RX_ERROR_MMIC;
637 }
638
639 if (error & AR9170_RX_ERROR_PLCP) {
640 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
641 error &= ~AR9170_RX_ERROR_PLCP;
642
643 if (!(ar->filter_state & FIF_PLCPFAIL))
644 return -EINVAL;
645 }
646
647 if (error & AR9170_RX_ERROR_FCS) {
648 status->flag |= RX_FLAG_FAILED_FCS_CRC;
649 error &= ~AR9170_RX_ERROR_FCS;
650
651 if (!(ar->filter_state & FIF_FCSFAIL))
652 return -EINVAL;
653 }
654
655 decrypt = ar9170_get_decrypt_type(mac);
656 if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
657 decrypt != AR9170_ENC_ALG_NONE)
658 status->flag |= RX_FLAG_DECRYPTED;
659
660 /* ignore wrong RA errors */
661 error &= ~AR9170_RX_ERROR_WRONG_RA;
662
663 if (error & AR9170_RX_ERROR_DECRYPT) {
664 error &= ~AR9170_RX_ERROR_DECRYPT;
665 /*
666 * Rx decryption is done in place,
667 * the original data is lost anyway.
668 */
669
670 return -EINVAL;
671 }
672
673 /* drop any other error frames */
674 if (unlikely(error)) {
675 /* TODO: update netdevice's RX dropped/errors statistics */
676
677 if (ar9170_nag_limiter(ar))
678 wiphy_debug(ar->hw->wiphy,
679 "received frame with suspicious error code (%#x).\n",
680 error);
681
682 return -EINVAL;
683 }
684
685 status->band = ar->channel->band;
686 status->freq = ar->channel->center_freq;
687
688 switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
689 case AR9170_RX_STATUS_MODULATION_CCK:
690 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
691 status->flag |= RX_FLAG_SHORTPRE;
692 switch (head->plcp[0]) {
693 case 0x0a:
694 status->rate_idx = 0;
695 break;
696 case 0x14:
697 status->rate_idx = 1;
698 break;
699 case 0x37:
700 status->rate_idx = 2;
701 break;
702 case 0x6e:
703 status->rate_idx = 3;
704 break;
705 default:
706 if (ar9170_nag_limiter(ar))
707 wiphy_err(ar->hw->wiphy,
708 "invalid plcp cck rate (%x).\n",
709 head->plcp[0]);
710 return -EINVAL;
711 }
712 break;
713
714 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
715 case AR9170_RX_STATUS_MODULATION_OFDM:
716 switch (head->plcp[0] & 0xf) {
717 case 0xb:
718 status->rate_idx = 0;
719 break;
720 case 0xf:
721 status->rate_idx = 1;
722 break;
723 case 0xa:
724 status->rate_idx = 2;
725 break;
726 case 0xe:
727 status->rate_idx = 3;
728 break;
729 case 0x9:
730 status->rate_idx = 4;
731 break;
732 case 0xd:
733 status->rate_idx = 5;
734 break;
735 case 0x8:
736 status->rate_idx = 6;
737 break;
738 case 0xc:
739 status->rate_idx = 7;
740 break;
741 default:
742 if (ar9170_nag_limiter(ar))
743 wiphy_err(ar->hw->wiphy,
744 "invalid plcp ofdm rate (%x).\n",
745 head->plcp[0]);
746 return -EINVAL;
747 }
748 if (status->band == IEEE80211_BAND_2GHZ)
749 status->rate_idx += 4;
750 break;
751
752 case AR9170_RX_STATUS_MODULATION_HT:
753 if (head->plcp[3] & 0x80)
754 status->flag |= RX_FLAG_40MHZ;
755 if (head->plcp[6] & 0x80)
756 status->flag |= RX_FLAG_SHORT_GI;
757
758 status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
759 status->flag |= RX_FLAG_HT;
760 break;
761
762 default:
763 if (ar9170_nag_limiter(ar))
764 wiphy_err(ar->hw->wiphy, "invalid modulation\n");
765 return -EINVAL;
766 }
767
768 return 0;
769}
770
771static void ar9170_rx_phy_status(struct ar9170 *ar,
772 struct ar9170_rx_phystatus *phy,
773 struct ieee80211_rx_status *status)
774{
775 int i;
776
777 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
778
779 for (i = 0; i < 3; i++)
780 if (phy->rssi[i] != 0x80)
781 status->antenna |= BIT(i);
782
783 /* post-process RSSI */
784 for (i = 0; i < 7; i++)
785 if (phy->rssi[i] & 0x80)
786 phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
787
788 /* TODO: we could do something with phy_errors */
789 status->signal = ar->noise[0] + phy->rssi_combined;
790}
791
792static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
793{
794 struct sk_buff *skb;
795 int reserved = 0;
796 struct ieee80211_hdr *hdr = (void *) buf;
797
798 if (ieee80211_is_data_qos(hdr->frame_control)) {
799 u8 *qc = ieee80211_get_qos_ctl(hdr);
800 reserved += NET_IP_ALIGN;
801
802 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
803 reserved += NET_IP_ALIGN;
804 }
805
806 if (ieee80211_has_a4(hdr->frame_control))
807 reserved += NET_IP_ALIGN;
808
809 reserved = 32 + (reserved & NET_IP_ALIGN);
810
811 skb = dev_alloc_skb(len + reserved);
812 if (likely(skb)) {
813 skb_reserve(skb, reserved);
814 memcpy(skb_put(skb, len), buf, len);
815 }
816
817 return skb;
818}
819
820/*
821 * If the frame alignment is right (or the kernel has
822 * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
823 * is only a single MPDU in the USB frame, then we could
824 * submit to mac80211 the SKB directly. However, since
825 * there may be multiple packets in one SKB in stream
826 * mode, and we need to observe the proper ordering,
827 * this is non-trivial.
828 */
829
830static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
831{
832 struct ar9170_rx_head *head;
833 struct ar9170_rx_macstatus *mac;
834 struct ar9170_rx_phystatus *phy = NULL;
835 struct ieee80211_rx_status status;
836 struct sk_buff *skb;
837 int mpdu_len;
838
839 if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
840 return ;
841
842 /* Received MPDU */
843 mpdu_len = len - sizeof(*mac);
844
845 mac = (void *)(buf + mpdu_len);
846 if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
847 /* this frame is too damaged and can't be used - drop it */
848
849 return ;
850 }
851
852 switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
853 case AR9170_RX_STATUS_MPDU_FIRST:
854 /* first mpdu packet has the plcp header */
855 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
856 head = (void *) buf;
857 memcpy(&ar->rx_mpdu.plcp, (void *) buf,
858 sizeof(struct ar9170_rx_head));
859
860 mpdu_len -= sizeof(struct ar9170_rx_head);
861 buf += sizeof(struct ar9170_rx_head);
862 ar->rx_mpdu.has_plcp = true;
863 } else {
864 if (ar9170_nag_limiter(ar))
865 wiphy_err(ar->hw->wiphy,
866 "plcp info is clipped.\n");
867 return ;
868 }
869 break;
870
871 case AR9170_RX_STATUS_MPDU_LAST:
872 /* last mpdu has a extra tail with phy status information */
873
874 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
875 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
876 phy = (void *)(buf + mpdu_len);
877 } else {
878 if (ar9170_nag_limiter(ar))
879 wiphy_err(ar->hw->wiphy,
880 "frame tail is clipped.\n");
881 return ;
882 }
883
884 case AR9170_RX_STATUS_MPDU_MIDDLE:
885 /* middle mpdus are just data */
886 if (unlikely(!ar->rx_mpdu.has_plcp)) {
887 if (!ar9170_nag_limiter(ar))
888 return ;
889
890 wiphy_err(ar->hw->wiphy,
891 "rx stream did not start with a first_mpdu frame tag.\n");
892
893 return ;
894 }
895
896 head = &ar->rx_mpdu.plcp;
897 break;
898
899 case AR9170_RX_STATUS_MPDU_SINGLE:
900 /* single mpdu - has plcp (head) and phy status (tail) */
901 head = (void *) buf;
902
903 mpdu_len -= sizeof(struct ar9170_rx_head);
904 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
905
906 buf += sizeof(struct ar9170_rx_head);
907 phy = (void *)(buf + mpdu_len);
908 break;
909
910 default:
911 BUG_ON(1);
912 break;
913 }
914
915 if (unlikely(mpdu_len < FCS_LEN))
916 return ;
917
918 memset(&status, 0, sizeof(status));
919 if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
920 return ;
921
922 if (phy)
923 ar9170_rx_phy_status(ar, phy, &status);
924
925 skb = ar9170_rx_copy_data(buf, mpdu_len);
926 if (likely(skb)) {
927 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
928 ieee80211_rx_irqsafe(ar->hw, skb);
929 }
930}
931
932void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
933{
934 unsigned int i, tlen, resplen, wlen = 0, clen = 0;
935 u8 *tbuf, *respbuf;
936
937 tbuf = skb->data;
938 tlen = skb->len;
939
940 while (tlen >= 4) {
941 clen = tbuf[1] << 8 | tbuf[0];
942 wlen = ALIGN(clen, 4);
943
944 /* check if this is stream has a valid tag.*/
945 if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
946 /*
947 * TODO: handle the highly unlikely event that the
948 * corrupted stream has the TAG at the right position.
949 */
950
951 /* check if the frame can be repaired. */
952 if (!ar->rx_failover_missing) {
953 /* this is no "short read". */
954 if (ar9170_nag_limiter(ar)) {
955 wiphy_err(ar->hw->wiphy,
956 "missing tag!\n");
957 goto err_telluser;
958 } else
959 goto err_silent;
960 }
961
962 if (ar->rx_failover_missing > tlen) {
963 if (ar9170_nag_limiter(ar)) {
964 wiphy_err(ar->hw->wiphy,
965 "possible multi stream corruption!\n");
966 goto err_telluser;
967 } else
968 goto err_silent;
969 }
970
971 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
972 ar->rx_failover_missing -= tlen;
973
974 if (ar->rx_failover_missing <= 0) {
975 /*
976 * nested ar9170_rx call!
977 * termination is guaranteed, even when the
978 * combined frame also have a element with
979 * a bad tag.
980 */
981
982 ar->rx_failover_missing = 0;
983 ar9170_rx(ar, ar->rx_failover);
984
985 skb_reset_tail_pointer(ar->rx_failover);
986 skb_trim(ar->rx_failover, 0);
987 }
988
989 return ;
990 }
991
992 /* check if stream is clipped */
993 if (wlen > tlen - 4) {
994 if (ar->rx_failover_missing) {
995 /* TODO: handle double stream corruption. */
996 if (ar9170_nag_limiter(ar)) {
997 wiphy_err(ar->hw->wiphy,
998 "double rx stream corruption!\n");
999 goto err_telluser;
1000 } else
1001 goto err_silent;
1002 }
1003
1004 /*
1005 * save incomplete data set.
1006 * the firmware will resend the missing bits when
1007 * the rx - descriptor comes round again.
1008 */
1009
1010 memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
1011 ar->rx_failover_missing = clen - tlen;
1012 return ;
1013 }
1014 resplen = clen;
1015 respbuf = tbuf + 4;
1016 tbuf += wlen + 4;
1017 tlen -= wlen + 4;
1018
1019 i = 0;
1020
1021 /* weird thing, but this is the same in the original driver */
1022 while (resplen > 2 && i < 12 &&
1023 respbuf[0] == 0xff && respbuf[1] == 0xff) {
1024 i += 2;
1025 resplen -= 2;
1026 respbuf += 2;
1027 }
1028
1029 if (resplen < 4)
1030 continue;
1031
1032 /* found the 6 * 0xffff marker? */
1033 if (i == 12)
1034 ar9170_handle_command_response(ar, respbuf, resplen);
1035 else
1036 ar9170_handle_mpdu(ar, respbuf, clen);
1037 }
1038
1039 if (tlen) {
1040 if (net_ratelimit())
1041 wiphy_err(ar->hw->wiphy,
1042 "%d bytes of unprocessed data left in rx stream!\n",
1043 tlen);
1044
1045 goto err_telluser;
1046 }
1047
1048 return ;
1049
1050err_telluser:
1051 wiphy_err(ar->hw->wiphy,
1052 "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n",
1053 clen, wlen, tlen, ar->rx_failover_missing);
1054
1055 if (ar->rx_failover_missing)
1056 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
1057 ar->rx_failover->data,
1058 ar->rx_failover->len);
1059
1060 print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
1061 skb->data, skb->len);
1062
1063 wiphy_err(ar->hw->wiphy,
1064 "If you see this message frequently, please check your hardware and cables.\n");
1065
1066err_silent:
1067 if (ar->rx_failover_missing) {
1068 skb_reset_tail_pointer(ar->rx_failover);
1069 skb_trim(ar->rx_failover, 0);
1070 ar->rx_failover_missing = 0;
1071 }
1072}
1073
1074#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
1075do { \
1076 queue.aifs = ai_fs; \
1077 queue.cw_min = cwmin; \
1078 queue.cw_max = cwmax; \
1079 queue.txop = _txop; \
1080} while (0)
1081
1082static int ar9170_op_start(struct ieee80211_hw *hw)
1083{
1084 struct ar9170 *ar = hw->priv;
1085 int err, i;
1086
1087 mutex_lock(&ar->mutex);
1088
1089 /* reinitialize queues statistics */
1090 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
1091 for (i = 0; i < __AR9170_NUM_TXQ; i++)
1092 ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
1093
1094 /* reset QoS defaults */
1095 AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
1096 AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
1097 AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
1098 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1099 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1100
1101 /* set sane AMPDU defaults */
1102 ar->global_ampdu_density = 6;
1103 ar->global_ampdu_factor = 3;
1104
1105 ar->bad_hw_nagger = jiffies;
1106
1107 err = ar->open(ar);
1108 if (err)
1109 goto out;
1110
1111 err = ar9170_init_mac(ar);
1112 if (err)
1113 goto out;
1114
1115 err = ar9170_set_qos(ar);
1116 if (err)
1117 goto out;
1118
1119 err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
1120 if (err)
1121 goto out;
1122
1123 err = ar9170_init_rf(ar);
1124 if (err)
1125 goto out;
1126
1127 /* start DMA */
1128 err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
1129 if (err)
1130 goto out;
1131
1132 ar->state = AR9170_STARTED;
1133
1134out:
1135 mutex_unlock(&ar->mutex);
1136 return err;
1137}
1138
1139static void ar9170_op_stop(struct ieee80211_hw *hw)
1140{
1141 struct ar9170 *ar = hw->priv;
1142 unsigned int i;
1143
1144 if (IS_STARTED(ar))
1145 ar->state = AR9170_IDLE;
1146
1147 cancel_delayed_work_sync(&ar->tx_janitor);
1148#ifdef CONFIG_AR9170_LEDS
1149 cancel_delayed_work_sync(&ar->led_work);
1150#endif
1151 cancel_work_sync(&ar->beacon_work);
1152
1153 mutex_lock(&ar->mutex);
1154
1155 if (IS_ACCEPTING_CMD(ar)) {
1156 ar9170_set_leds_state(ar, 0);
1157
1158 /* stop DMA */
1159 ar9170_write_reg(ar, 0x1c3d30, 0);
1160 ar->stop(ar);
1161 }
1162
1163 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1164 skb_queue_purge(&ar->tx_pending[i]);
1165 skb_queue_purge(&ar->tx_status[i]);
1166 }
1167
1168 mutex_unlock(&ar->mutex);
1169}
1170
1171static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1172{
1173 struct ieee80211_hdr *hdr;
1174 struct ar9170_tx_control *txc;
1175 struct ieee80211_tx_info *info;
1176 struct ieee80211_tx_rate *txrate;
1177 struct ar9170_tx_info *arinfo;
1178 unsigned int queue = skb_get_queue_mapping(skb);
1179 u16 keytype = 0;
1180 u16 len, icv = 0;
1181
1182 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
1183
1184 hdr = (void *)skb->data;
1185 info = IEEE80211_SKB_CB(skb);
1186 len = skb->len;
1187
1188 txc = (void *)skb_push(skb, sizeof(*txc));
1189
1190 if (info->control.hw_key) {
1191 icv = info->control.hw_key->icv_len;
1192
1193 switch (info->control.hw_key->cipher) {
1194 case WLAN_CIPHER_SUITE_WEP40:
1195 case WLAN_CIPHER_SUITE_WEP104:
1196 case WLAN_CIPHER_SUITE_TKIP:
1197 keytype = AR9170_TX_MAC_ENCR_RC4;
1198 break;
1199 case WLAN_CIPHER_SUITE_CCMP:
1200 keytype = AR9170_TX_MAC_ENCR_AES;
1201 break;
1202 default:
1203 WARN_ON(1);
1204 goto err_out;
1205 }
1206 }
1207
1208 /* Length */
1209 txc->length = cpu_to_le16(len + icv + 4);
1210
1211 txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
1212 AR9170_TX_MAC_BACKOFF);
1213 txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
1214 AR9170_TX_MAC_QOS_SHIFT);
1215 txc->mac_control |= cpu_to_le16(keytype);
1216 txc->phy_control = cpu_to_le32(0);
1217
1218 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
1219 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
1220
1221 txrate = &info->control.rates[0];
1222 if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1223 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
1224 else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1225 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
1226
1227 arinfo = (void *)info->rate_driver_data;
1228 arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
1229
1230 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
1231 (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
1232 /*
1233 * WARNING:
1234 * Putting the QoS queue bits into an unexplored territory is
1235 * certainly not elegant.
1236 *
1237 * In my defense: This idea provides a reasonable way to
1238 * smuggle valuable information to the tx_status callback.
1239 * Also, the idea behind this bit-abuse came straight from
1240 * the original driver code.
1241 */
1242
1243 txc->phy_control |=
1244 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1245
1246 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1247 }
1248
1249 return 0;
1250
1251err_out:
1252 skb_pull(skb, sizeof(*txc));
1253 return -EINVAL;
1254}
1255
1256static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1257{
1258 struct ar9170_tx_control *txc;
1259 struct ieee80211_tx_info *info;
1260 struct ieee80211_rate *rate = NULL;
1261 struct ieee80211_tx_rate *txrate;
1262 u32 power, chains;
1263
1264 txc = (void *) skb->data;
1265 info = IEEE80211_SKB_CB(skb);
1266 txrate = &info->control.rates[0];
1267
1268 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
1269 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
1270
1271 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1272 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
1273
1274 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1275 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
1276 /* this works because 40 MHz is 2 and dup is 3 */
1277 if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
1278 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
1279
1280 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
1281 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
1282
1283 if (txrate->flags & IEEE80211_TX_RC_MCS) {
1284 u32 r = txrate->idx;
1285 u8 *txpower;
1286
1287 /* heavy clip control */
1288 txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
1289
1290 r <<= AR9170_TX_PHY_MCS_SHIFT;
1291 BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
1292
1293 txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
1294 txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
1295
1296 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1297 if (info->band == IEEE80211_BAND_5GHZ)
1298 txpower = ar->power_5G_ht40;
1299 else
1300 txpower = ar->power_2G_ht40;
1301 } else {
1302 if (info->band == IEEE80211_BAND_5GHZ)
1303 txpower = ar->power_5G_ht20;
1304 else
1305 txpower = ar->power_2G_ht20;
1306 }
1307
1308 power = txpower[(txrate->idx) & 7];
1309 } else {
1310 u8 *txpower;
1311 u32 mod;
1312 u32 phyrate;
1313 u8 idx = txrate->idx;
1314
1315 if (info->band != IEEE80211_BAND_2GHZ) {
1316 idx += 4;
1317 txpower = ar->power_5G_leg;
1318 mod = AR9170_TX_PHY_MOD_OFDM;
1319 } else {
1320 if (idx < 4) {
1321 txpower = ar->power_2G_cck;
1322 mod = AR9170_TX_PHY_MOD_CCK;
1323 } else {
1324 mod = AR9170_TX_PHY_MOD_OFDM;
1325 txpower = ar->power_2G_ofdm;
1326 }
1327 }
1328
1329 rate = &__ar9170_ratetable[idx];
1330
1331 phyrate = rate->hw_value & 0xF;
1332 power = txpower[(rate->hw_value & 0x30) >> 4];
1333 phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
1334
1335 txc->phy_control |= cpu_to_le32(mod);
1336 txc->phy_control |= cpu_to_le32(phyrate);
1337 }
1338
1339 power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
1340 power &= AR9170_TX_PHY_TX_PWR_MASK;
1341 txc->phy_control |= cpu_to_le32(power);
1342
1343 /* set TX chains */
1344 if (ar->eeprom.tx_mask == 1) {
1345 chains = AR9170_TX_PHY_TXCHAIN_1;
1346 } else {
1347 chains = AR9170_TX_PHY_TXCHAIN_2;
1348
1349 /* >= 36M legacy OFDM - use only one chain */
1350 if (rate && rate->bitrate >= 360)
1351 chains = AR9170_TX_PHY_TXCHAIN_1;
1352 }
1353 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
1354}
1355
1356static void ar9170_tx(struct ar9170 *ar)
1357{
1358 struct sk_buff *skb;
1359 unsigned long flags;
1360 struct ieee80211_tx_info *info;
1361 struct ar9170_tx_info *arinfo;
1362 unsigned int i, frames, frames_failed, remaining_space;
1363 int err;
1364 bool schedule_garbagecollector = false;
1365
1366 BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
1367
1368 if (unlikely(!IS_STARTED(ar)))
1369 return ;
1370
1371 remaining_space = AR9170_TX_MAX_PENDING;
1372
1373 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
1374 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1375 frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
1376 skb_queue_len(&ar->tx_pending[i]));
1377
1378 if (remaining_space < frames) {
1379#ifdef AR9170_QUEUE_DEBUG
1380 wiphy_debug(ar->hw->wiphy,
1381 "tx quota reached queue:%d, "
1382 "remaining slots:%d, needed:%d\n",
1383 i, remaining_space, frames);
1384#endif /* AR9170_QUEUE_DEBUG */
1385 frames = remaining_space;
1386 }
1387
1388 ar->tx_stats[i].len += frames;
1389 ar->tx_stats[i].count += frames;
1390 if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
1391#ifdef AR9170_QUEUE_DEBUG
1392 wiphy_debug(ar->hw->wiphy, "queue %d full\n", i);
1393 wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n");
1394 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1395 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1396#endif /* AR9170_QUEUE_DEBUG */
1397
1398#ifdef AR9170_QUEUE_STOP_DEBUG
1399 wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i);
1400 __ar9170_dump_txstats(ar);
1401#endif /* AR9170_QUEUE_STOP_DEBUG */
1402 ieee80211_stop_queue(ar->hw, i);
1403 }
1404
1405 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1406
1407 if (!frames)
1408 continue;
1409
1410 frames_failed = 0;
1411 while (frames) {
1412 skb = skb_dequeue(&ar->tx_pending[i]);
1413 if (unlikely(!skb)) {
1414 frames_failed += frames;
1415 frames = 0;
1416 break;
1417 }
1418
1419 info = IEEE80211_SKB_CB(skb);
1420 arinfo = (void *) info->rate_driver_data;
1421
1422 /* TODO: cancel stuck frames */
1423 arinfo->timeout = jiffies +
1424 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1425
1426#ifdef AR9170_QUEUE_DEBUG
1427 wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i);
1428 ar9170_print_txheader(ar, skb);
1429#endif /* AR9170_QUEUE_DEBUG */
1430
1431 err = ar->tx(ar, skb);
1432 if (unlikely(err)) {
1433 frames_failed++;
1434 dev_kfree_skb_any(skb);
1435 } else {
1436 remaining_space--;
1437 schedule_garbagecollector = true;
1438 }
1439
1440 frames--;
1441 }
1442
1443#ifdef AR9170_QUEUE_DEBUG
1444 wiphy_debug(ar->hw->wiphy,
1445 "ar9170_tx report for queue %d\n", i);
1446
1447 wiphy_debug(ar->hw->wiphy,
1448 "unprocessed pending frames left:\n");
1449 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1450#endif /* AR9170_QUEUE_DEBUG */
1451
1452 if (unlikely(frames_failed)) {
1453#ifdef AR9170_QUEUE_DEBUG
1454 wiphy_debug(ar->hw->wiphy,
1455 "frames failed %d =>\n", frames_failed);
1456#endif /* AR9170_QUEUE_DEBUG */
1457
1458 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1459 ar->tx_stats[i].len -= frames_failed;
1460 ar->tx_stats[i].count -= frames_failed;
1461#ifdef AR9170_QUEUE_STOP_DEBUG
1462 wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i);
1463 __ar9170_dump_txstats(ar);
1464#endif /* AR9170_QUEUE_STOP_DEBUG */
1465 ieee80211_wake_queue(ar->hw, i);
1466 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1467 }
1468 }
1469
1470 if (!schedule_garbagecollector)
1471 return;
1472
1473 ieee80211_queue_delayed_work(ar->hw,
1474 &ar->tx_janitor,
1475 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1476}
1477
1478void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1479{
1480 struct ar9170 *ar = hw->priv;
1481 struct ieee80211_tx_info *info;
1482 unsigned int queue;
1483
1484 if (unlikely(!IS_STARTED(ar)))
1485 goto err_free;
1486
1487 if (unlikely(ar9170_tx_prepare(ar, skb)))
1488 goto err_free;
1489
1490 queue = skb_get_queue_mapping(skb);
1491 info = IEEE80211_SKB_CB(skb);
1492 ar9170_tx_prepare_phy(ar, skb);
1493 skb_queue_tail(&ar->tx_pending[queue], skb);
1494
1495 ar9170_tx(ar);
1496 return;
1497
1498err_free:
1499 dev_kfree_skb_any(skb);
1500}
1501
1502static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1503 struct ieee80211_vif *vif)
1504{
1505 struct ar9170 *ar = hw->priv;
1506 struct ath_common *common = &ar->common;
1507 int err = 0;
1508
1509 mutex_lock(&ar->mutex);
1510
1511 if (ar->vif) {
1512 err = -EBUSY;
1513 goto unlock;
1514 }
1515
1516 ar->vif = vif;
1517 memcpy(common->macaddr, vif->addr, ETH_ALEN);
1518
1519 if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
1520 ar->rx_software_decryption = true;
1521 ar->disable_offload = true;
1522 }
1523
1524 ar->cur_filter = 0;
1525 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
1526 if (err)
1527 goto unlock;
1528
1529 err = ar9170_set_operating_mode(ar);
1530
1531unlock:
1532 mutex_unlock(&ar->mutex);
1533 return err;
1534}
1535
1536static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1537 struct ieee80211_vif *vif)
1538{
1539 struct ar9170 *ar = hw->priv;
1540
1541 mutex_lock(&ar->mutex);
1542 ar->vif = NULL;
1543 ar9170_update_frame_filter(ar, 0);
1544 ar9170_set_beacon_timers(ar);
1545 dev_kfree_skb(ar->beacon);
1546 ar->beacon = NULL;
1547 ar->sniffer_enabled = false;
1548 ar->rx_software_decryption = false;
1549 ar9170_set_operating_mode(ar);
1550 mutex_unlock(&ar->mutex);
1551}
1552
1553static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1554{
1555 struct ar9170 *ar = hw->priv;
1556 int err = 0;
1557
1558 mutex_lock(&ar->mutex);
1559
1560 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1561 /* TODO */
1562 err = 0;
1563 }
1564
1565 if (changed & IEEE80211_CONF_CHANGE_PS) {
1566 /* TODO */
1567 err = 0;
1568 }
1569
1570 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1571 /* TODO */
1572 err = 0;
1573 }
1574
1575 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
1576 /*
1577 * is it long_frame_max_tx_count or short_frame_max_tx_count?
1578 */
1579
1580 err = ar9170_set_hwretry_limit(ar,
1581 ar->hw->conf.long_frame_max_tx_count);
1582 if (err)
1583 goto out;
1584 }
1585
1586 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1587
1588 /* adjust slot time for 5 GHz */
1589 err = ar9170_set_slot_time(ar);
1590 if (err)
1591 goto out;
1592
1593 err = ar9170_set_dyn_sifs_ack(ar);
1594 if (err)
1595 goto out;
1596
1597 err = ar9170_set_channel(ar, hw->conf.channel,
1598 AR9170_RFI_NONE,
1599 nl80211_to_ar9170(hw->conf.channel_type));
1600 if (err)
1601 goto out;
1602 }
1603
1604out:
1605 mutex_unlock(&ar->mutex);
1606 return err;
1607}
1608
1609static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
1610 struct netdev_hw_addr_list *mc_list)
1611{
1612 u64 mchash;
1613 struct netdev_hw_addr *ha;
1614
1615 /* always get broadcast frames */
1616 mchash = 1ULL << (0xff >> 2);
1617
1618 netdev_hw_addr_list_for_each(ha, mc_list)
1619 mchash |= 1ULL << (ha->addr[5] >> 2);
1620
1621 return mchash;
1622}
1623
1624static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1625 unsigned int changed_flags,
1626 unsigned int *new_flags,
1627 u64 multicast)
1628{
1629 struct ar9170 *ar = hw->priv;
1630
1631 if (unlikely(!IS_ACCEPTING_CMD(ar)))
1632 return ;
1633
1634 mutex_lock(&ar->mutex);
1635
1636 /* mask supported flags */
1637 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
1638 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
1639 ar->filter_state = *new_flags;
1640 /*
1641 * We can support more by setting the sniffer bit and
1642 * then checking the error flags, later.
1643 */
1644
1645 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
1646 multicast = ~0ULL;
1647
1648 if (multicast != ar->cur_mc_hash)
1649 ar9170_update_multicast(ar, multicast);
1650
1651 if (changed_flags & FIF_CONTROL) {
1652 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
1653 AR9170_MAC_REG_FTF_RTS |
1654 AR9170_MAC_REG_FTF_CTS |
1655 AR9170_MAC_REG_FTF_ACK |
1656 AR9170_MAC_REG_FTF_CFE |
1657 AR9170_MAC_REG_FTF_CFE_ACK;
1658
1659 if (*new_flags & FIF_CONTROL)
1660 filter |= ar->cur_filter;
1661 else
1662 filter &= (~ar->cur_filter);
1663
1664 ar9170_update_frame_filter(ar, filter);
1665 }
1666
1667 if (changed_flags & FIF_PROMISC_IN_BSS) {
1668 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
1669 ar9170_set_operating_mode(ar);
1670 }
1671
1672 mutex_unlock(&ar->mutex);
1673}
1674
1675
1676static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1677 struct ieee80211_vif *vif,
1678 struct ieee80211_bss_conf *bss_conf,
1679 u32 changed)
1680{
1681 struct ar9170 *ar = hw->priv;
1682 struct ath_common *common = &ar->common;
1683 int err = 0;
1684
1685 mutex_lock(&ar->mutex);
1686
1687 if (changed & BSS_CHANGED_BSSID) {
1688 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1689 err = ar9170_set_operating_mode(ar);
1690 if (err)
1691 goto out;
1692 }
1693
1694 if (changed & BSS_CHANGED_BEACON_ENABLED)
1695 ar->enable_beacon = bss_conf->enable_beacon;
1696
1697 if (changed & BSS_CHANGED_BEACON) {
1698 err = ar9170_update_beacon(ar);
1699 if (err)
1700 goto out;
1701 }
1702
1703 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
1704 BSS_CHANGED_BEACON_INT)) {
1705 err = ar9170_set_beacon_timers(ar);
1706 if (err)
1707 goto out;
1708 }
1709
1710 if (changed & BSS_CHANGED_ASSOC) {
1711#ifndef CONFIG_AR9170_LEDS
1712 /* enable assoc LED. */
1713 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1714#endif /* CONFIG_AR9170_LEDS */
1715 }
1716
1717 if (changed & BSS_CHANGED_HT) {
1718 /* TODO */
1719 err = 0;
1720 }
1721
1722 if (changed & BSS_CHANGED_ERP_SLOT) {
1723 err = ar9170_set_slot_time(ar);
1724 if (err)
1725 goto out;
1726 }
1727
1728 if (changed & BSS_CHANGED_BASIC_RATES) {
1729 err = ar9170_set_basic_rates(ar);
1730 if (err)
1731 goto out;
1732 }
1733
1734out:
1735 mutex_unlock(&ar->mutex);
1736}
1737
1738static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
1739{
1740 struct ar9170 *ar = hw->priv;
1741 int err;
1742 u64 tsf;
1743#define NR 3
1744 static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
1745 AR9170_MAC_REG_TSF_L,
1746 AR9170_MAC_REG_TSF_H };
1747 u32 val[NR];
1748 int loops = 0;
1749
1750 mutex_lock(&ar->mutex);
1751
1752 while (loops++ < 10) {
1753 err = ar9170_read_mreg(ar, NR, addr, val);
1754 if (err || val[0] == val[2])
1755 break;
1756 }
1757
1758 mutex_unlock(&ar->mutex);
1759
1760 if (WARN_ON(err))
1761 return 0;
1762 tsf = val[0];
1763 tsf = (tsf << 32) | val[1];
1764 return tsf;
1765#undef NR
1766}
1767
1768static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1769 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
1770 struct ieee80211_key_conf *key)
1771{
1772 struct ar9170 *ar = hw->priv;
1773 int err = 0, i;
1774 u8 ktype;
1775
1776 if ((!ar->vif) || (ar->disable_offload))
1777 return -EOPNOTSUPP;
1778
1779 switch (key->cipher) {
1780 case WLAN_CIPHER_SUITE_WEP40:
1781 ktype = AR9170_ENC_ALG_WEP64;
1782 break;
1783 case WLAN_CIPHER_SUITE_WEP104:
1784 ktype = AR9170_ENC_ALG_WEP128;
1785 break;
1786 case WLAN_CIPHER_SUITE_TKIP:
1787 ktype = AR9170_ENC_ALG_TKIP;
1788 break;
1789 case WLAN_CIPHER_SUITE_CCMP:
1790 ktype = AR9170_ENC_ALG_AESCCMP;
1791 break;
1792 default:
1793 return -EOPNOTSUPP;
1794 }
1795
1796 mutex_lock(&ar->mutex);
1797 if (cmd == SET_KEY) {
1798 if (unlikely(!IS_STARTED(ar))) {
1799 err = -EOPNOTSUPP;
1800 goto out;
1801 }
1802
1803 /* group keys need all-zeroes address */
1804 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1805 sta = NULL;
1806
1807 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1808 for (i = 0; i < 64; i++)
1809 if (!(ar->usedkeys & BIT(i)))
1810 break;
1811 if (i == 64) {
1812 ar->rx_software_decryption = true;
1813 ar9170_set_operating_mode(ar);
1814 err = -ENOSPC;
1815 goto out;
1816 }
1817 } else {
1818 i = 64 + key->keyidx;
1819 }
1820
1821 key->hw_key_idx = i;
1822
1823 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
1824 key->key, min_t(u8, 16, key->keylen));
1825 if (err)
1826 goto out;
1827
1828 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
1829 err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
1830 ktype, 1, key->key + 16, 16);
1831 if (err)
1832 goto out;
1833
1834 /*
1835 * hardware is not capable generating the MMIC
1836 * for fragmented frames!
1837 */
1838 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1839 }
1840
1841 if (i < 64)
1842 ar->usedkeys |= BIT(i);
1843
1844 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1845 } else {
1846 if (unlikely(!IS_STARTED(ar))) {
1847 /* The device is gone... together with the key ;-) */
1848 err = 0;
1849 goto out;
1850 }
1851
1852 err = ar9170_disable_key(ar, key->hw_key_idx);
1853 if (err)
1854 goto out;
1855
1856 if (key->hw_key_idx < 64) {
1857 ar->usedkeys &= ~BIT(key->hw_key_idx);
1858 } else {
1859 err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
1860 AR9170_ENC_ALG_NONE, 0,
1861 NULL, 0);
1862 if (err)
1863 goto out;
1864
1865 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
1866 err = ar9170_upload_key(ar, key->hw_key_idx,
1867 NULL,
1868 AR9170_ENC_ALG_NONE, 1,
1869 NULL, 0);
1870 if (err)
1871 goto out;
1872 }
1873
1874 }
1875 }
1876
1877 ar9170_regwrite_begin(ar);
1878 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
1879 ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
1880 ar9170_regwrite_finish();
1881 err = ar9170_regwrite_result();
1882
1883out:
1884 mutex_unlock(&ar->mutex);
1885
1886 return err;
1887}
1888
1889static int ar9170_get_stats(struct ieee80211_hw *hw,
1890 struct ieee80211_low_level_stats *stats)
1891{
1892 struct ar9170 *ar = hw->priv;
1893 u32 val;
1894 int err;
1895
1896 mutex_lock(&ar->mutex);
1897 err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
1898 ar->stats.dot11ACKFailureCount += val;
1899
1900 memcpy(stats, &ar->stats, sizeof(*stats));
1901 mutex_unlock(&ar->mutex);
1902
1903 return 0;
1904}
1905
1906static int ar9170_get_survey(struct ieee80211_hw *hw, int idx,
1907 struct survey_info *survey)
1908{
1909 struct ar9170 *ar = hw->priv;
1910 struct ieee80211_conf *conf = &hw->conf;
1911
1912 if (idx != 0)
1913 return -ENOENT;
1914
1915 /* TODO: update noise value, e.g. call ar9170_set_channel */
1916
1917 survey->channel = conf->channel;
1918 survey->filled = SURVEY_INFO_NOISE_DBM;
1919 survey->noise = ar->noise[0];
1920
1921 return 0;
1922}
1923
1924static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
1925 const struct ieee80211_tx_queue_params *param)
1926{
1927 struct ar9170 *ar = hw->priv;
1928 int ret;
1929
1930 mutex_lock(&ar->mutex);
1931 if (queue < __AR9170_NUM_TXQ) {
1932 memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
1933 param, sizeof(*param));
1934
1935 ret = ar9170_set_qos(ar);
1936 } else {
1937 ret = -EINVAL;
1938 }
1939
1940 mutex_unlock(&ar->mutex);
1941 return ret;
1942}
1943
1944static int ar9170_ampdu_action(struct ieee80211_hw *hw,
1945 struct ieee80211_vif *vif,
1946 enum ieee80211_ampdu_mlme_action action,
1947 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
1948 u8 buf_size)
1949{
1950 switch (action) {
1951 case IEEE80211_AMPDU_RX_START:
1952 case IEEE80211_AMPDU_RX_STOP:
1953 /* Handled by firmware */
1954 break;
1955
1956 default:
1957 return -EOPNOTSUPP;
1958 }
1959
1960 return 0;
1961}
1962
1963static const struct ieee80211_ops ar9170_ops = {
1964 .start = ar9170_op_start,
1965 .stop = ar9170_op_stop,
1966 .tx = ar9170_op_tx,
1967 .add_interface = ar9170_op_add_interface,
1968 .remove_interface = ar9170_op_remove_interface,
1969 .config = ar9170_op_config,
1970 .prepare_multicast = ar9170_op_prepare_multicast,
1971 .configure_filter = ar9170_op_configure_filter,
1972 .conf_tx = ar9170_conf_tx,
1973 .bss_info_changed = ar9170_op_bss_info_changed,
1974 .get_tsf = ar9170_op_get_tsf,
1975 .set_key = ar9170_set_key,
1976 .get_stats = ar9170_get_stats,
1977 .get_survey = ar9170_get_survey,
1978 .ampdu_action = ar9170_ampdu_action,
1979};
1980
1981void *ar9170_alloc(size_t priv_size)
1982{
1983 struct ieee80211_hw *hw;
1984 struct ar9170 *ar;
1985 struct sk_buff *skb;
1986 int i;
1987
1988 /*
1989 * this buffer is used for rx stream reconstruction.
1990 * Under heavy load this device (or the transport layer?)
1991 * tends to split the streams into separate rx descriptors.
1992 */
1993
1994 skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
1995 if (!skb)
1996 goto err_nomem;
1997
1998 hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
1999 if (!hw)
2000 goto err_nomem;
2001
2002 ar = hw->priv;
2003 ar->hw = hw;
2004 ar->rx_failover = skb;
2005
2006 mutex_init(&ar->mutex);
2007 spin_lock_init(&ar->cmdlock);
2008 spin_lock_init(&ar->tx_stats_lock);
2009 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2010 skb_queue_head_init(&ar->tx_status[i]);
2011 skb_queue_head_init(&ar->tx_pending[i]);
2012 }
2013 ar9170_rx_reset_rx_mpdu(ar);
2014 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
2015 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
2016
2017 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2018 ar->channel = &ar9170_2ghz_chantable[0];
2019
2020 /* first part of wiphy init */
2021 ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2022 BIT(NL80211_IFTYPE_WDS) |
2023 BIT(NL80211_IFTYPE_ADHOC);
2024 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2025 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2026 IEEE80211_HW_SIGNAL_DBM;
2027
2028 ar->hw->queues = __AR9170_NUM_TXQ;
2029 ar->hw->extra_tx_headroom = 8;
2030
2031 ar->hw->max_rates = 1;
2032 ar->hw->max_rate_tries = 3;
2033
2034 for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
2035 ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
2036
2037 return ar;
2038
2039err_nomem:
2040 kfree_skb(skb);
2041 return ERR_PTR(-ENOMEM);
2042}
2043
2044static int ar9170_read_eeprom(struct ar9170 *ar)
2045{
2046#define RW 8 /* number of words to read at once */
2047#define RB (sizeof(u32) * RW)
2048 struct ath_regulatory *regulatory = &ar->common.regulatory;
2049 u8 *eeprom = (void *)&ar->eeprom;
2050 u8 *addr = ar->eeprom.mac_address;
2051 __le32 offsets[RW];
2052 unsigned int rx_streams, tx_streams, tx_params = 0;
2053 int i, j, err, bands = 0;
2054
2055 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
2056
2057 BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
2058#ifndef __CHECKER__
2059 /* don't want to handle trailing remains */
2060 BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
2061#endif
2062
2063 for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
2064 for (j = 0; j < RW; j++)
2065 offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
2066 RB * i + 4 * j);
2067
2068 err = ar->exec_cmd(ar, AR9170_CMD_RREG,
2069 RB, (u8 *) &offsets,
2070 RB, eeprom + RB * i);
2071 if (err)
2072 return err;
2073 }
2074
2075#undef RW
2076#undef RB
2077
2078 if (ar->eeprom.length == cpu_to_le16(0xFFFF))
2079 return -ENODATA;
2080
2081 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
2082 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
2083 bands++;
2084 }
2085 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
2086 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2087 bands++;
2088 }
2089
2090 rx_streams = hweight8(ar->eeprom.rx_mask);
2091 tx_streams = hweight8(ar->eeprom.tx_mask);
2092
2093 if (rx_streams != tx_streams)
2094 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2095
2096 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2097 tx_params = (tx_streams - 1) <<
2098 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2099
2100 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2101 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2102
2103 /*
2104 * I measured this, a bandswitch takes roughly
2105 * 135 ms and a frequency switch about 80.
2106 *
2107 * FIXME: measure these values again once EEPROM settings
2108 * are used, that will influence them!
2109 */
2110 if (bands == 2)
2111 ar->hw->channel_change_time = 135 * 1000;
2112 else
2113 ar->hw->channel_change_time = 80 * 1000;
2114
2115 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2116 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
2117
2118 /* second part of wiphy init */
2119 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
2120
2121 return bands ? 0 : -EINVAL;
2122}
2123
2124static int ar9170_reg_notifier(struct wiphy *wiphy,
2125 struct regulatory_request *request)
2126{
2127 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2128 struct ar9170 *ar = hw->priv;
2129
2130 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
2131}
2132
2133int ar9170_register(struct ar9170 *ar, struct device *pdev)
2134{
2135 struct ath_regulatory *regulatory = &ar->common.regulatory;
2136 int err;
2137
2138 /* try to read EEPROM, init MAC addr */
2139 err = ar9170_read_eeprom(ar);
2140 if (err)
2141 goto err_out;
2142
2143 err = ath_regd_init(regulatory, ar->hw->wiphy,
2144 ar9170_reg_notifier);
2145 if (err)
2146 goto err_out;
2147
2148 err = ieee80211_register_hw(ar->hw);
2149 if (err)
2150 goto err_out;
2151
2152 if (!ath_is_world_regd(regulatory))
2153 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
2154
2155 err = ar9170_init_leds(ar);
2156 if (err)
2157 goto err_unreg;
2158
2159#ifdef CONFIG_AR9170_LEDS
2160 err = ar9170_register_leds(ar);
2161 if (err)
2162 goto err_unreg;
2163#endif /* CONFIG_AR9170_LEDS */
2164
2165 dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
2166 wiphy_name(ar->hw->wiphy));
2167
2168 ar->registered = true;
2169 return 0;
2170
2171err_unreg:
2172 ieee80211_unregister_hw(ar->hw);
2173
2174err_out:
2175 return err;
2176}
2177
2178void ar9170_unregister(struct ar9170 *ar)
2179{
2180 if (ar->registered) {
2181#ifdef CONFIG_AR9170_LEDS
2182 ar9170_unregister_leds(ar);
2183#endif /* CONFIG_AR9170_LEDS */
2184
2185 ieee80211_unregister_hw(ar->hw);
2186 }
2187
2188 kfree_skb(ar->rx_failover);
2189 mutex_destroy(&ar->mutex);
2190}
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
deleted file mode 100644
index aa8d06ba1ee4..000000000000
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ /dev/null
@@ -1,1719 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * PHY and RF code
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, see
20 * http://www.gnu.org/licenses/.
21 *
22 * This file incorporates work covered by the following copyright and
23 * permission notice:
24 * Copyright (c) 2007-2008 Atheros Communications, Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
33 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */
38
39#include <linux/bitrev.h>
40#include "ar9170.h"
41#include "cmd.h"
42
43static int ar9170_init_power_cal(struct ar9170 *ar)
44{
45 ar9170_regwrite_begin(ar);
46
47 ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
48 ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
49 ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
50 ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
51 ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
52 ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
53 ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
54 ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
55 ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
56 ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
57
58 ar9170_regwrite_finish();
59 return ar9170_regwrite_result();
60}
61
62struct ar9170_phy_init {
63 u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
64};
65
66static struct ar9170_phy_init ar5416_phy_init[] = {
67 { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
68 { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
69 { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
70 { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
71 { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
72 { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
73 { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
74 { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
75 { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
76 { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
77 { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
78 { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
79 { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
80 { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
81 { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
82 { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
83 { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
84 { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
85 { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
86 { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
87 { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
88 { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
89 { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
90 { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
91 { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
92 { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
93 { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
94 { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
95 { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
96 { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
97 { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
98 { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
99 { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
100 { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
101 { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
102 { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
103 { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
104 { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
105 { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
106 { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
107 { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
108 { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
109 { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
110 { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
111 { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
112 { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
113 { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
114 { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
115 { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
116 { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
117 { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
118 { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
119 { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
120 { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
121 { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
122 { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
123 { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
124 { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
125 { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
126 { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
127 { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
128 { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
129 { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
130 { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
131 { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
132 { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
133 { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
134 { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
135 { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
136 { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
137 { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
138 { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
139 { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
140 { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
141 { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
142 { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
143 { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
144 { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
145 { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
146 { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
147 { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
148 { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
149 { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
150 { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
151 { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
152 { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
153 { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
154 { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
155 { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
156 { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
157 { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
158 { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
159 { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
160 { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
161 { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
162 { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
163 { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
164 { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
165 { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
166 { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
167 { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
168 { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
169 { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
170 { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
171 { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
172 { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
173 { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
174 { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
175 { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
176 { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
177 { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
178 { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
179 { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
180 { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
181 { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
182 { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
183 { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
184 { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
185 { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
186 { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
187 { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
188 { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
189 { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
190 { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
191 { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
192 { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
193 { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
194 { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
195 { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
196 { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
197 { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
198 { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
199 { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
200 { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
201 { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
202 { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
203 { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
204 { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
205 { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
206 { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
207 { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
208 { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
209 { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
210 { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
211 { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
212 { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
213 { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
214 { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
215 { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
216 { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
217 { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
218 { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
219 { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
220 { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
221 { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
222 { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
223 { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
224 { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
225 { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
226 { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
227 { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
228 { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
229 { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
230 { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
231 { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
232 { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
233 { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
234 { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
235 { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
236 { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
237 { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
238 { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
239 { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
240 { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
241 { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
242 { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
243 { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
244 { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
245 { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
246 { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
247 { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
248 { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
249 { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
250 { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
251 { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
252 { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
253 { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
254 { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
255 { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
256 { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
257 { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
258 { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
259 { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
260 { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
261 { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
262 { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
263 { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
264 { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
265 { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
266 { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
267 { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
268 { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
269 { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
270 { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
271 { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
272 { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
273 { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
274 { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
275 { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
276 { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
277 { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
278 { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
279 { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
280 { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
281 { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
282 { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
283 { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
284 { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
285 { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
286 { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
287 { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
288 { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
289 { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
290 { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
291 { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
292 { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
293 { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
294 { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
295 { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
296 { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
297 { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
298 { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
299 { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
300 { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
301 { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
302 { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
303 { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
304 { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
305 { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
306 { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
307 { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
308 { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
309 { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
310 { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
311 { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
312 { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
313 { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
314 { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
315 { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
316 { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
317 { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
318 { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
319 { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
320 { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
321 { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
322 { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
323 { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
324 { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
325 { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
326 { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
327 { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
328 { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
329 { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
330 { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
331 { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
332 { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
333 { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
334 { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
335 { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
336 { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
337 { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
338 { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
339 { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
340 { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
341 { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
342 { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
343 { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
344 { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
345 { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
346 { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
347 { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
348 { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
349 { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
350 { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
351 { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
352 { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
353 { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
354 { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
355 { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
356 { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
357 { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
358 { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
359 { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
360 { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
361 { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
362 { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
363 { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
364 { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
365 { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
366 { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
367 { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
368 { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
369 { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
370 { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
371 { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
372 { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
373 { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
374 { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
375 { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
376 { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
377 { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
378 { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
379 { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
380/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
381 { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
382 { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
383 { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
384 { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
385 { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
386 { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
387 { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
388 { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
389 { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
390 { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
391 { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
392 { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
393 { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
394 { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
395 { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
396 { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
397};
398
399/*
400 * look up a certain register in ar5416_phy_init[] and return the init. value
401 * for the band and bandwidth given. Return 0 if register address not found.
402 */
403static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz)
404{
405 unsigned int i;
406 for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
407 if (ar5416_phy_init[i].reg != reg)
408 continue;
409
410 if (is_2ghz) {
411 if (is_40mhz)
412 return ar5416_phy_init[i]._2ghz_40;
413 else
414 return ar5416_phy_init[i]._2ghz_20;
415 } else {
416 if (is_40mhz)
417 return ar5416_phy_init[i]._5ghz_40;
418 else
419 return ar5416_phy_init[i]._5ghz_20;
420 }
421 }
422 return 0;
423}
424
425/*
426 * initialize some phy regs from eeprom values in modal_header[]
427 * acc. to band and bandwidth
428 */
429static int ar9170_init_phy_from_eeprom(struct ar9170 *ar,
430 bool is_2ghz, bool is_40mhz)
431{
432 static const u8 xpd2pd[16] = {
433 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
434 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2
435 };
436 u32 defval, newval;
437 /* pointer to the modal_header acc. to band */
438 struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
439
440 ar9170_regwrite_begin(ar);
441
442 /* ant common control (index 0) */
443 newval = le32_to_cpu(m->antCtrlCommon);
444 ar9170_regwrite(0x1c5964, newval);
445
446 /* ant control chain 0 (index 1) */
447 newval = le32_to_cpu(m->antCtrlChain[0]);
448 ar9170_regwrite(0x1c5960, newval);
449
450 /* ant control chain 2 (index 2) */
451 newval = le32_to_cpu(m->antCtrlChain[1]);
452 ar9170_regwrite(0x1c7960, newval);
453
454 /* SwSettle (index 3) */
455 if (!is_40mhz) {
456 defval = ar9170_get_default_phy_reg_val(0x1c5844,
457 is_2ghz, is_40mhz);
458 newval = (defval & ~0x3f80) |
459 ((m->switchSettling & 0x7f) << 7);
460 ar9170_regwrite(0x1c5844, newval);
461 }
462
463 /* adcDesired, pdaDesired (index 4) */
464 defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz);
465 newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) |
466 ((u8)m->adcDesiredSize);
467 ar9170_regwrite(0x1c5850, newval);
468
469 /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
470 defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz);
471 newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) |
472 (m->txFrameToXpaOn << 8) | m->txFrameToXpaOn;
473 ar9170_regwrite(0x1c5834, newval);
474
475 /* TxEndToRxOn (index 6) */
476 defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz);
477 newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16);
478 ar9170_regwrite(0x1c5828, newval);
479
480 /* thresh62 (index 7) */
481 defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz);
482 newval = (defval & ~0x7f000) | (m->thresh62 << 12);
483 ar9170_regwrite(0x1c8864, newval);
484
485 /* tx/rx attenuation chain 0 (index 8) */
486 defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz);
487 newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12);
488 ar9170_regwrite(0x1c5848, newval);
489
490 /* tx/rx attenuation chain 2 (index 9) */
491 defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz);
492 newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12);
493 ar9170_regwrite(0x1c7848, newval);
494
495 /* tx/rx margin chain 0 (index 10) */
496 defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz);
497 newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18);
498 /* bsw margin chain 0 for 5GHz only */
499 if (!is_2ghz)
500 newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10);
501 ar9170_regwrite(0x1c620c, newval);
502
503 /* tx/rx margin chain 2 (index 11) */
504 defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz);
505 newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18);
506 ar9170_regwrite(0x1c820c, newval);
507
508 /* iqCall, iqCallq chain 0 (index 12) */
509 defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz);
510 newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) |
511 ((u8)m->iqCalQCh[0] & 0x1f);
512 ar9170_regwrite(0x1c5920, newval);
513
514 /* iqCall, iqCallq chain 2 (index 13) */
515 defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz);
516 newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) |
517 ((u8)m->iqCalQCh[1] & 0x1f);
518 ar9170_regwrite(0x1c7920, newval);
519
520 /* xpd gain mask (index 14) */
521 defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz);
522 newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16);
523 ar9170_regwrite(0x1c6258, newval);
524 ar9170_regwrite_finish();
525
526 return ar9170_regwrite_result();
527}
528
529int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
530{
531 int i, err;
532 u32 val;
533 bool is_2ghz = band == IEEE80211_BAND_2GHZ;
534 bool is_40mhz = conf_is_ht40(&ar->hw->conf);
535
536 ar9170_regwrite_begin(ar);
537
538 for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
539 if (is_40mhz) {
540 if (is_2ghz)
541 val = ar5416_phy_init[i]._2ghz_40;
542 else
543 val = ar5416_phy_init[i]._5ghz_40;
544 } else {
545 if (is_2ghz)
546 val = ar5416_phy_init[i]._2ghz_20;
547 else
548 val = ar5416_phy_init[i]._5ghz_20;
549 }
550
551 ar9170_regwrite(ar5416_phy_init[i].reg, val);
552 }
553
554 ar9170_regwrite_finish();
555 err = ar9170_regwrite_result();
556 if (err)
557 return err;
558
559 err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
560 if (err)
561 return err;
562
563 err = ar9170_init_power_cal(ar);
564 if (err)
565 return err;
566
567 /* XXX: remove magic! */
568 if (is_2ghz)
569 err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
570 else
571 err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
572
573 return err;
574}
575
576struct ar9170_rf_init {
577 u32 reg, _5ghz, _2ghz;
578};
579
580static struct ar9170_rf_init ar9170_rf_init[] = {
581 /* bank 0 */
582 { 0x1c58b0, 0x1e5795e5, 0x1e5795e5},
583 { 0x1c58e0, 0x02008020, 0x02008020},
584 /* bank 1 */
585 { 0x1c58b0, 0x02108421, 0x02108421},
586 { 0x1c58ec, 0x00000008, 0x00000008},
587 /* bank 2 */
588 { 0x1c58b0, 0x0e73ff17, 0x0e73ff17},
589 { 0x1c58e0, 0x00000420, 0x00000420},
590 /* bank 3 */
591 { 0x1c58f0, 0x01400018, 0x01c00018},
592 /* bank 4 */
593 { 0x1c58b0, 0x000001a1, 0x000001a1},
594 { 0x1c58e8, 0x00000001, 0x00000001},
595 /* bank 5 */
596 { 0x1c58b0, 0x00000013, 0x00000013},
597 { 0x1c58e4, 0x00000002, 0x00000002},
598 /* bank 6 */
599 { 0x1c58b0, 0x00000000, 0x00000000},
600 { 0x1c58b0, 0x00000000, 0x00000000},
601 { 0x1c58b0, 0x00000000, 0x00000000},
602 { 0x1c58b0, 0x00000000, 0x00000000},
603 { 0x1c58b0, 0x00000000, 0x00000000},
604 { 0x1c58b0, 0x00004000, 0x00004000},
605 { 0x1c58b0, 0x00006c00, 0x00006c00},
606 { 0x1c58b0, 0x00002c00, 0x00002c00},
607 { 0x1c58b0, 0x00004800, 0x00004800},
608 { 0x1c58b0, 0x00004000, 0x00004000},
609 { 0x1c58b0, 0x00006000, 0x00006000},
610 { 0x1c58b0, 0x00001000, 0x00001000},
611 { 0x1c58b0, 0x00004000, 0x00004000},
612 { 0x1c58b0, 0x00007c00, 0x00007c00},
613 { 0x1c58b0, 0x00007c00, 0x00007c00},
614 { 0x1c58b0, 0x00007c00, 0x00007c00},
615 { 0x1c58b0, 0x00007c00, 0x00007c00},
616 { 0x1c58b0, 0x00007c00, 0x00007c00},
617 { 0x1c58b0, 0x00087c00, 0x00087c00},
618 { 0x1c58b0, 0x00007c00, 0x00007c00},
619 { 0x1c58b0, 0x00005400, 0x00005400},
620 { 0x1c58b0, 0x00000c00, 0x00000c00},
621 { 0x1c58b0, 0x00001800, 0x00001800},
622 { 0x1c58b0, 0x00007c00, 0x00007c00},
623 { 0x1c58b0, 0x00006c00, 0x00006c00},
624 { 0x1c58b0, 0x00006c00, 0x00006c00},
625 { 0x1c58b0, 0x00007c00, 0x00007c00},
626 { 0x1c58b0, 0x00002c00, 0x00002c00},
627 { 0x1c58b0, 0x00003c00, 0x00003c00},
628 { 0x1c58b0, 0x00003800, 0x00003800},
629 { 0x1c58b0, 0x00001c00, 0x00001c00},
630 { 0x1c58b0, 0x00000800, 0x00000800},
631 { 0x1c58b0, 0x00000408, 0x00000408},
632 { 0x1c58b0, 0x00004c15, 0x00004c15},
633 { 0x1c58b0, 0x00004188, 0x00004188},
634 { 0x1c58b0, 0x0000201e, 0x0000201e},
635 { 0x1c58b0, 0x00010408, 0x00010408},
636 { 0x1c58b0, 0x00000801, 0x00000801},
637 { 0x1c58b0, 0x00000c08, 0x00000c08},
638 { 0x1c58b0, 0x0000181e, 0x0000181e},
639 { 0x1c58b0, 0x00001016, 0x00001016},
640 { 0x1c58b0, 0x00002800, 0x00002800},
641 { 0x1c58b0, 0x00004010, 0x00004010},
642 { 0x1c58b0, 0x0000081c, 0x0000081c},
643 { 0x1c58b0, 0x00000115, 0x00000115},
644 { 0x1c58b0, 0x00000015, 0x00000015},
645 { 0x1c58b0, 0x00000066, 0x00000066},
646 { 0x1c58b0, 0x0000001c, 0x0000001c},
647 { 0x1c58b0, 0x00000000, 0x00000000},
648 { 0x1c58b0, 0x00000004, 0x00000004},
649 { 0x1c58b0, 0x00000015, 0x00000015},
650 { 0x1c58b0, 0x0000001f, 0x0000001f},
651 { 0x1c58e0, 0x00000000, 0x00000400},
652 /* bank 7 */
653 { 0x1c58b0, 0x000000a0, 0x000000a0},
654 { 0x1c58b0, 0x00000000, 0x00000000},
655 { 0x1c58b0, 0x00000040, 0x00000040},
656 { 0x1c58f0, 0x0000001c, 0x0000001c},
657};
658
659static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
660{
661 int err, i;
662
663 ar9170_regwrite_begin(ar);
664
665 for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
666 ar9170_regwrite(ar9170_rf_init[i].reg,
667 band5ghz ? ar9170_rf_init[i]._5ghz
668 : ar9170_rf_init[i]._2ghz);
669
670 ar9170_regwrite_finish();
671 err = ar9170_regwrite_result();
672 if (err)
673 wiphy_err(ar->hw->wiphy, "rf init failed\n");
674 return err;
675}
676
677static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
678 u32 freq, enum ar9170_bw bw)
679{
680 int err;
681 u32 d0, d1, td0, td1, fd0, fd1;
682 u8 chansel;
683 u8 refsel0 = 1, refsel1 = 0;
684 u8 lf_synth = 0;
685
686 switch (bw) {
687 case AR9170_BW_40_ABOVE:
688 freq += 10;
689 break;
690 case AR9170_BW_40_BELOW:
691 freq -= 10;
692 break;
693 case AR9170_BW_20:
694 break;
695 case __AR9170_NUM_BW:
696 BUG();
697 }
698
699 if (band5ghz) {
700 if (freq % 10) {
701 chansel = (freq - 4800) / 5;
702 } else {
703 chansel = ((freq - 4800) / 10) * 2;
704 refsel0 = 0;
705 refsel1 = 1;
706 }
707 chansel = byte_rev_table[chansel];
708 } else {
709 if (freq == 2484) {
710 chansel = 10 + (freq - 2274) / 5;
711 lf_synth = 1;
712 } else
713 chansel = 16 + (freq - 2272) / 5;
714 chansel *= 4;
715 chansel = byte_rev_table[chansel];
716 }
717
718 d1 = chansel;
719 d0 = 0x21 |
720 refsel0 << 3 |
721 refsel1 << 2 |
722 lf_synth << 1;
723 td0 = d0 & 0x1f;
724 td1 = d1 & 0x1f;
725 fd0 = td1 << 5 | td0;
726
727 td0 = (d0 >> 5) & 0x7;
728 td1 = (d1 >> 5) & 0x7;
729 fd1 = td1 << 5 | td0;
730
731 ar9170_regwrite_begin(ar);
732
733 ar9170_regwrite(0x1c58b0, fd0);
734 ar9170_regwrite(0x1c58e8, fd1);
735
736 ar9170_regwrite_finish();
737 err = ar9170_regwrite_result();
738 if (err)
739 return err;
740
741 msleep(10);
742
743 return 0;
744}
745
746struct ar9170_phy_freq_params {
747 u8 coeff_exp;
748 u16 coeff_man;
749 u8 coeff_exp_shgi;
750 u16 coeff_man_shgi;
751};
752
753struct ar9170_phy_freq_entry {
754 u16 freq;
755 struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
756};
757
758/* NB: must be in sync with channel tables in main! */
759static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
760/*
761 * freq,
762 * 20MHz,
763 * 40MHz (below),
764 * 40Mhz (above),
765 */
766 { 2412, {
767 { 3, 21737, 3, 19563, },
768 { 3, 21827, 3, 19644, },
769 { 3, 21647, 3, 19482, },
770 } },
771 { 2417, {
772 { 3, 21692, 3, 19523, },
773 { 3, 21782, 3, 19604, },
774 { 3, 21602, 3, 19442, },
775 } },
776 { 2422, {
777 { 3, 21647, 3, 19482, },
778 { 3, 21737, 3, 19563, },
779 { 3, 21558, 3, 19402, },
780 } },
781 { 2427, {
782 { 3, 21602, 3, 19442, },
783 { 3, 21692, 3, 19523, },
784 { 3, 21514, 3, 19362, },
785 } },
786 { 2432, {
787 { 3, 21558, 3, 19402, },
788 { 3, 21647, 3, 19482, },
789 { 3, 21470, 3, 19323, },
790 } },
791 { 2437, {
792 { 3, 21514, 3, 19362, },
793 { 3, 21602, 3, 19442, },
794 { 3, 21426, 3, 19283, },
795 } },
796 { 2442, {
797 { 3, 21470, 3, 19323, },
798 { 3, 21558, 3, 19402, },
799 { 3, 21382, 3, 19244, },
800 } },
801 { 2447, {
802 { 3, 21426, 3, 19283, },
803 { 3, 21514, 3, 19362, },
804 { 3, 21339, 3, 19205, },
805 } },
806 { 2452, {
807 { 3, 21382, 3, 19244, },
808 { 3, 21470, 3, 19323, },
809 { 3, 21295, 3, 19166, },
810 } },
811 { 2457, {
812 { 3, 21339, 3, 19205, },
813 { 3, 21426, 3, 19283, },
814 { 3, 21252, 3, 19127, },
815 } },
816 { 2462, {
817 { 3, 21295, 3, 19166, },
818 { 3, 21382, 3, 19244, },
819 { 3, 21209, 3, 19088, },
820 } },
821 { 2467, {
822 { 3, 21252, 3, 19127, },
823 { 3, 21339, 3, 19205, },
824 { 3, 21166, 3, 19050, },
825 } },
826 { 2472, {
827 { 3, 21209, 3, 19088, },
828 { 3, 21295, 3, 19166, },
829 { 3, 21124, 3, 19011, },
830 } },
831 { 2484, {
832 { 3, 21107, 3, 18996, },
833 { 3, 21192, 3, 19073, },
834 { 3, 21022, 3, 18920, },
835 } },
836 { 4920, {
837 { 4, 21313, 4, 19181, },
838 { 4, 21356, 4, 19220, },
839 { 4, 21269, 4, 19142, },
840 } },
841 { 4940, {
842 { 4, 21226, 4, 19104, },
843 { 4, 21269, 4, 19142, },
844 { 4, 21183, 4, 19065, },
845 } },
846 { 4960, {
847 { 4, 21141, 4, 19027, },
848 { 4, 21183, 4, 19065, },
849 { 4, 21098, 4, 18988, },
850 } },
851 { 4980, {
852 { 4, 21056, 4, 18950, },
853 { 4, 21098, 4, 18988, },
854 { 4, 21014, 4, 18912, },
855 } },
856 { 5040, {
857 { 4, 20805, 4, 18725, },
858 { 4, 20846, 4, 18762, },
859 { 4, 20764, 4, 18687, },
860 } },
861 { 5060, {
862 { 4, 20723, 4, 18651, },
863 { 4, 20764, 4, 18687, },
864 { 4, 20682, 4, 18614, },
865 } },
866 { 5080, {
867 { 4, 20641, 4, 18577, },
868 { 4, 20682, 4, 18614, },
869 { 4, 20601, 4, 18541, },
870 } },
871 { 5180, {
872 { 4, 20243, 4, 18219, },
873 { 4, 20282, 4, 18254, },
874 { 4, 20204, 4, 18183, },
875 } },
876 { 5200, {
877 { 4, 20165, 4, 18148, },
878 { 4, 20204, 4, 18183, },
879 { 4, 20126, 4, 18114, },
880 } },
881 { 5220, {
882 { 4, 20088, 4, 18079, },
883 { 4, 20126, 4, 18114, },
884 { 4, 20049, 4, 18044, },
885 } },
886 { 5240, {
887 { 4, 20011, 4, 18010, },
888 { 4, 20049, 4, 18044, },
889 { 4, 19973, 4, 17976, },
890 } },
891 { 5260, {
892 { 4, 19935, 4, 17941, },
893 { 4, 19973, 4, 17976, },
894 { 4, 19897, 4, 17907, },
895 } },
896 { 5280, {
897 { 4, 19859, 4, 17873, },
898 { 4, 19897, 4, 17907, },
899 { 4, 19822, 4, 17840, },
900 } },
901 { 5300, {
902 { 4, 19784, 4, 17806, },
903 { 4, 19822, 4, 17840, },
904 { 4, 19747, 4, 17772, },
905 } },
906 { 5320, {
907 { 4, 19710, 4, 17739, },
908 { 4, 19747, 4, 17772, },
909 { 4, 19673, 4, 17706, },
910 } },
911 { 5500, {
912 { 4, 19065, 4, 17159, },
913 { 4, 19100, 4, 17190, },
914 { 4, 19030, 4, 17127, },
915 } },
916 { 5520, {
917 { 4, 18996, 4, 17096, },
918 { 4, 19030, 4, 17127, },
919 { 4, 18962, 4, 17065, },
920 } },
921 { 5540, {
922 { 4, 18927, 4, 17035, },
923 { 4, 18962, 4, 17065, },
924 { 4, 18893, 4, 17004, },
925 } },
926 { 5560, {
927 { 4, 18859, 4, 16973, },
928 { 4, 18893, 4, 17004, },
929 { 4, 18825, 4, 16943, },
930 } },
931 { 5580, {
932 { 4, 18792, 4, 16913, },
933 { 4, 18825, 4, 16943, },
934 { 4, 18758, 4, 16882, },
935 } },
936 { 5600, {
937 { 4, 18725, 4, 16852, },
938 { 4, 18758, 4, 16882, },
939 { 4, 18691, 4, 16822, },
940 } },
941 { 5620, {
942 { 4, 18658, 4, 16792, },
943 { 4, 18691, 4, 16822, },
944 { 4, 18625, 4, 16762, },
945 } },
946 { 5640, {
947 { 4, 18592, 4, 16733, },
948 { 4, 18625, 4, 16762, },
949 { 4, 18559, 4, 16703, },
950 } },
951 { 5660, {
952 { 4, 18526, 4, 16673, },
953 { 4, 18559, 4, 16703, },
954 { 4, 18493, 4, 16644, },
955 } },
956 { 5680, {
957 { 4, 18461, 4, 16615, },
958 { 4, 18493, 4, 16644, },
959 { 4, 18428, 4, 16586, },
960 } },
961 { 5700, {
962 { 4, 18396, 4, 16556, },
963 { 4, 18428, 4, 16586, },
964 { 4, 18364, 4, 16527, },
965 } },
966 { 5745, {
967 { 4, 18252, 4, 16427, },
968 { 4, 18284, 4, 16455, },
969 { 4, 18220, 4, 16398, },
970 } },
971 { 5765, {
972 { 4, 18189, 5, 32740, },
973 { 4, 18220, 4, 16398, },
974 { 4, 18157, 5, 32683, },
975 } },
976 { 5785, {
977 { 4, 18126, 5, 32626, },
978 { 4, 18157, 5, 32683, },
979 { 4, 18094, 5, 32570, },
980 } },
981 { 5805, {
982 { 4, 18063, 5, 32514, },
983 { 4, 18094, 5, 32570, },
984 { 4, 18032, 5, 32458, },
985 } },
986 { 5825, {
987 { 4, 18001, 5, 32402, },
988 { 4, 18032, 5, 32458, },
989 { 4, 17970, 5, 32347, },
990 } },
991 { 5170, {
992 { 4, 20282, 4, 18254, },
993 { 4, 20321, 4, 18289, },
994 { 4, 20243, 4, 18219, },
995 } },
996 { 5190, {
997 { 4, 20204, 4, 18183, },
998 { 4, 20243, 4, 18219, },
999 { 4, 20165, 4, 18148, },
1000 } },
1001 { 5210, {
1002 { 4, 20126, 4, 18114, },
1003 { 4, 20165, 4, 18148, },
1004 { 4, 20088, 4, 18079, },
1005 } },
1006 { 5230, {
1007 { 4, 20049, 4, 18044, },
1008 { 4, 20088, 4, 18079, },
1009 { 4, 20011, 4, 18010, },
1010 } },
1011};
1012
1013static const struct ar9170_phy_freq_params *
1014ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
1015 enum ar9170_bw bw)
1016{
1017 unsigned int chanidx = 0;
1018 u16 freq = 2412;
1019
1020 if (channel) {
1021 chanidx = channel->hw_value;
1022 freq = channel->center_freq;
1023 }
1024
1025 BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
1026
1027 BUILD_BUG_ON(__AR9170_NUM_BW != 3);
1028
1029 WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
1030
1031 return &ar9170_phy_freq_params[chanidx].params[bw];
1032}
1033
1034
1035int ar9170_init_rf(struct ar9170 *ar)
1036{
1037 const struct ar9170_phy_freq_params *freqpar;
1038 __le32 cmd[7];
1039 int err;
1040
1041 err = ar9170_init_rf_banks_0_7(ar, false);
1042 if (err)
1043 return err;
1044
1045 err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
1046 if (err)
1047 return err;
1048
1049 freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
1050
1051 cmd[0] = cpu_to_le32(2412 * 1000);
1052 cmd[1] = cpu_to_le32(0);
1053 cmd[2] = cpu_to_le32(1);
1054 cmd[3] = cpu_to_le32(freqpar->coeff_exp);
1055 cmd[4] = cpu_to_le32(freqpar->coeff_man);
1056 cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
1057 cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
1058
1059 /* RF_INIT echoes the command back to us */
1060 err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
1061 sizeof(cmd), (u8 *)cmd,
1062 sizeof(cmd), (u8 *)cmd);
1063 if (err)
1064 return err;
1065
1066 msleep(1000);
1067
1068 return ar9170_echo_test(ar, 0xaabbccdd);
1069}
1070
1071static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
1072{
1073 int idx = nfreqs - 2;
1074
1075 while (idx >= 0) {
1076 if (f >= freqs[idx])
1077 return idx;
1078 idx--;
1079 }
1080
1081 return 0;
1082}
1083
1084static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
1085{
1086 /* nothing to interpolate, it's horizontal */
1087 if (y2 == y1)
1088 return y1;
1089
1090 /* check if we hit one of the edges */
1091 if (x == x1)
1092 return y1;
1093 if (x == x2)
1094 return y2;
1095
1096 /* x1 == x2 is bad, hopefully == x */
1097 if (x2 == x1)
1098 return y1;
1099
1100 return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
1101}
1102
1103static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
1104{
1105#define SHIFT 8
1106 s32 y;
1107
1108 y = ar9170_interpolate_s32(x << SHIFT,
1109 x1 << SHIFT, y1 << SHIFT,
1110 x2 << SHIFT, y2 << SHIFT);
1111
1112 /*
1113 * XXX: unwrap this expression
1114 * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
1115 * Can we rely on the compiler to optimise away the div?
1116 */
1117 return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
1118#undef SHIFT
1119}
1120
1121static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
1122{
1123 int i;
1124
1125 for (i = 0; i < 3; i++)
1126 if (x <= x_array[i + 1])
1127 break;
1128
1129 return ar9170_interpolate_u8(x,
1130 x_array[i],
1131 y_array[i],
1132 x_array[i + 1],
1133 y_array[i + 1]);
1134}
1135
1136static int ar9170_set_freq_cal_data(struct ar9170 *ar,
1137 struct ieee80211_channel *channel)
1138{
1139 u8 *cal_freq_pier;
1140 u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
1141 u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
1142 int chain, idx, i;
1143 u32 phy_data = 0;
1144 u8 f, tmp;
1145
1146 switch (channel->band) {
1147 case IEEE80211_BAND_2GHZ:
1148 f = channel->center_freq - 2300;
1149 cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
1150 i = AR5416_NUM_2G_CAL_PIERS - 1;
1151 break;
1152
1153 case IEEE80211_BAND_5GHZ:
1154 f = (channel->center_freq - 4800) / 5;
1155 cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
1156 i = AR5416_NUM_5G_CAL_PIERS - 1;
1157 break;
1158
1159 default:
1160 return -EINVAL;
1161 break;
1162 }
1163
1164 for (; i >= 0; i--) {
1165 if (cal_freq_pier[i] != 0xff)
1166 break;
1167 }
1168 if (i < 0)
1169 return -EINVAL;
1170
1171 idx = ar9170_find_freq_idx(i, cal_freq_pier, f);
1172
1173 ar9170_regwrite_begin(ar);
1174
1175 for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
1176 for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
1177 struct ar9170_calibration_data_per_freq *cal_pier_data;
1178 int j;
1179
1180 switch (channel->band) {
1181 case IEEE80211_BAND_2GHZ:
1182 cal_pier_data = &ar->eeprom.
1183 cal_pier_data_2G[chain][idx];
1184 break;
1185
1186 case IEEE80211_BAND_5GHZ:
1187 cal_pier_data = &ar->eeprom.
1188 cal_pier_data_5G[chain][idx];
1189 break;
1190
1191 default:
1192 return -EINVAL;
1193 }
1194
1195 for (j = 0; j < 2; j++) {
1196 vpds[j][i] = ar9170_interpolate_u8(f,
1197 cal_freq_pier[idx],
1198 cal_pier_data->vpd_pdg[j][i],
1199 cal_freq_pier[idx + 1],
1200 cal_pier_data[1].vpd_pdg[j][i]);
1201
1202 pwrs[j][i] = ar9170_interpolate_u8(f,
1203 cal_freq_pier[idx],
1204 cal_pier_data->pwr_pdg[j][i],
1205 cal_freq_pier[idx + 1],
1206 cal_pier_data[1].pwr_pdg[j][i]) / 2;
1207 }
1208 }
1209
1210 for (i = 0; i < 76; i++) {
1211 if (i < 25) {
1212 tmp = ar9170_interpolate_val(i, &pwrs[0][0],
1213 &vpds[0][0]);
1214 } else {
1215 tmp = ar9170_interpolate_val(i - 12,
1216 &pwrs[1][0],
1217 &vpds[1][0]);
1218 }
1219
1220 phy_data |= tmp << ((i & 3) << 3);
1221 if ((i & 3) == 3) {
1222 ar9170_regwrite(0x1c6280 + chain * 0x1000 +
1223 (i & ~3), phy_data);
1224 phy_data = 0;
1225 }
1226 }
1227
1228 for (i = 19; i < 32; i++)
1229 ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
1230 0x0);
1231 }
1232
1233 ar9170_regwrite_finish();
1234 return ar9170_regwrite_result();
1235}
1236
1237static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
1238 struct ar9170_calctl_edges edges[],
1239 u32 freq)
1240{
1241 int i;
1242 u8 rc = AR5416_MAX_RATE_POWER;
1243 u8 f;
1244 if (freq < 3000)
1245 f = freq - 2300;
1246 else
1247 f = (freq - 4800) / 5;
1248
1249 for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
1250 if (edges[i].channel == 0xff)
1251 break;
1252 if (f == edges[i].channel) {
1253 /* exact freq match */
1254 rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
1255 break;
1256 }
1257 if (i > 0 && f < edges[i].channel) {
1258 if (f > edges[i - 1].channel &&
1259 edges[i - 1].power_flags &
1260 AR9170_CALCTL_EDGE_FLAGS) {
1261 /* lower channel has the inband flag set */
1262 rc = edges[i - 1].power_flags &
1263 ~AR9170_CALCTL_EDGE_FLAGS;
1264 }
1265 break;
1266 }
1267 }
1268
1269 if (i == AR5416_NUM_BAND_EDGES) {
1270 if (f > edges[i - 1].channel &&
1271 edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
1272 /* lower channel has the inband flag set */
1273 rc = edges[i - 1].power_flags &
1274 ~AR9170_CALCTL_EDGE_FLAGS;
1275 }
1276 }
1277 return rc;
1278}
1279
1280static u8 ar9170_get_heavy_clip(struct ar9170 *ar,
1281 struct ar9170_calctl_edges edges[],
1282 u32 freq, enum ar9170_bw bw)
1283{
1284 u8 f;
1285 int i;
1286 u8 rc = 0;
1287
1288 if (freq < 3000)
1289 f = freq - 2300;
1290 else
1291 f = (freq - 4800) / 5;
1292
1293 if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE)
1294 rc |= 0xf0;
1295
1296 for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
1297 if (edges[i].channel == 0xff)
1298 break;
1299 if (f == edges[i].channel) {
1300 if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS))
1301 rc |= 0x0f;
1302 break;
1303 }
1304 }
1305
1306 return rc;
1307}
1308
1309/*
1310 * calculate the conformance test limits and the heavy clip parameter
1311 * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706)
1312 */
1313static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1314{
1315 u8 ctl_grp; /* CTL group */
1316 u8 ctl_idx; /* CTL index */
1317 int i, j;
1318 struct ctl_modes {
1319 u8 ctl_mode;
1320 u8 max_power;
1321 u8 *pwr_cal_data;
1322 int pwr_cal_len;
1323 } *modes;
1324
1325 /*
1326 * order is relevant in the mode_list_*: we fall back to the
1327 * lower indices if any mode is missed in the EEPROM.
1328 */
1329 struct ctl_modes mode_list_2ghz[] = {
1330 { CTL_11B, 0, ar->power_2G_cck, 4 },
1331 { CTL_11G, 0, ar->power_2G_ofdm, 4 },
1332 { CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
1333 { CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
1334 };
1335 struct ctl_modes mode_list_5ghz[] = {
1336 { CTL_11A, 0, ar->power_5G_leg, 4 },
1337 { CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
1338 { CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
1339 };
1340 int nr_modes;
1341
1342#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
1343
1344 ar->phy_heavy_clip = 0;
1345
1346 /*
1347 * TODO: investigate the differences between OTUS'
1348 * hpreg.c::zfHpGetRegulatoryDomain() and
1349 * ath/regd.c::ath_regd_get_band_ctl() -
1350 * e.g. for FCC3_WORLD the OTUS procedure
1351 * always returns CTL_FCC, while the one in ath/ delivers
1352 * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
1353 */
1354 ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
1355 ar->hw->conf.channel->band);
1356
1357 /* ctl group not found - either invalid band (NO_CTL) or ww roaming */
1358 if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
1359 ctl_grp = CTL_FCC;
1360
1361 if (ctl_grp != CTL_FCC)
1362 /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
1363 return;
1364
1365 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
1366 modes = mode_list_2ghz;
1367 nr_modes = ARRAY_SIZE(mode_list_2ghz);
1368 } else {
1369 modes = mode_list_5ghz;
1370 nr_modes = ARRAY_SIZE(mode_list_5ghz);
1371 }
1372
1373 for (i = 0; i < nr_modes; i++) {
1374 u8 c = ctl_grp | modes[i].ctl_mode;
1375 for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
1376 if (c == ar->eeprom.ctl_index[ctl_idx])
1377 break;
1378 if (ctl_idx < AR5416_NUM_CTLS) {
1379 int f_off = 0;
1380
1381 /* determine heav clip parameter from
1382 the 11G edges array */
1383 if (modes[i].ctl_mode == CTL_11G) {
1384 ar->phy_heavy_clip =
1385 ar9170_get_heavy_clip(ar,
1386 EDGES(ctl_idx, 1),
1387 freq, bw);
1388 }
1389
1390 /* adjust freq for 40MHz */
1391 if (modes[i].ctl_mode == CTL_2GHT40 ||
1392 modes[i].ctl_mode == CTL_5GHT40) {
1393 if (bw == AR9170_BW_40_BELOW)
1394 f_off = -10;
1395 else
1396 f_off = 10;
1397 }
1398
1399 modes[i].max_power =
1400 ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
1401 freq+f_off);
1402
1403 /*
1404 * TODO: check if the regulatory max. power is
1405 * controlled by cfg80211 for DFS
1406 * (hpmain applies it to max_power itself for DFS freq)
1407 */
1408
1409 } else {
1410 /*
1411 * Workaround in otus driver, hpmain.c, line 3906:
1412 * if no data for 5GHT20 are found, take the
1413 * legacy 5G value.
1414 * We extend this here to fallback from any other *HT or
1415 * 11G, too.
1416 */
1417 int k = i;
1418
1419 modes[i].max_power = AR5416_MAX_RATE_POWER;
1420 while (k-- > 0) {
1421 if (modes[k].max_power !=
1422 AR5416_MAX_RATE_POWER) {
1423 modes[i].max_power = modes[k].max_power;
1424 break;
1425 }
1426 }
1427 }
1428
1429 /* apply max power to pwr_cal_data (ar->power_*) */
1430 for (j = 0; j < modes[i].pwr_cal_len; j++) {
1431 modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
1432 modes[i].max_power);
1433 }
1434 }
1435
1436 if (ar->phy_heavy_clip & 0xf0) {
1437 ar->power_2G_ht40[0]--;
1438 ar->power_2G_ht40[1]--;
1439 ar->power_2G_ht40[2]--;
1440 }
1441 if (ar->phy_heavy_clip & 0xf) {
1442 ar->power_2G_ht20[0]++;
1443 ar->power_2G_ht20[1]++;
1444 ar->power_2G_ht20[2]++;
1445 }
1446
1447
1448#undef EDGES
1449}
1450
1451static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
1452{
1453 struct ar9170_calibration_target_power_legacy *ctpl;
1454 struct ar9170_calibration_target_power_ht *ctph;
1455 u8 *ctpres;
1456 int ntargets;
1457 int idx, i, n;
1458 u8 ackpower, ackchains, f;
1459 u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
1460
1461 if (freq < 3000)
1462 f = freq - 2300;
1463 else
1464 f = (freq - 4800)/5;
1465
1466 /*
1467 * cycle through the various modes
1468 *
1469 * legacy modes first: 5G, 2G CCK, 2G OFDM
1470 */
1471 for (i = 0; i < 3; i++) {
1472 switch (i) {
1473 case 0: /* 5 GHz legacy */
1474 ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
1475 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1476 ctpres = ar->power_5G_leg;
1477 break;
1478 case 1: /* 2.4 GHz CCK */
1479 ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
1480 ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
1481 ctpres = ar->power_2G_cck;
1482 break;
1483 case 2: /* 2.4 GHz OFDM */
1484 ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
1485 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1486 ctpres = ar->power_2G_ofdm;
1487 break;
1488 default:
1489 BUG();
1490 }
1491
1492 for (n = 0; n < ntargets; n++) {
1493 if (ctpl[n].freq == 0xff)
1494 break;
1495 pwr_freqs[n] = ctpl[n].freq;
1496 }
1497 ntargets = n;
1498 idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
1499 for (n = 0; n < 4; n++)
1500 ctpres[n] = ar9170_interpolate_u8(
1501 f,
1502 ctpl[idx + 0].freq,
1503 ctpl[idx + 0].power[n],
1504 ctpl[idx + 1].freq,
1505 ctpl[idx + 1].power[n]);
1506 }
1507
1508 /*
1509 * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
1510 */
1511 for (i = 0; i < 4; i++) {
1512 switch (i) {
1513 case 0: /* 5 GHz HT 20 */
1514 ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
1515 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1516 ctpres = ar->power_5G_ht20;
1517 break;
1518 case 1: /* 5 GHz HT 40 */
1519 ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
1520 ntargets = AR5416_NUM_5G_TARGET_PWRS;
1521 ctpres = ar->power_5G_ht40;
1522 break;
1523 case 2: /* 2.4 GHz HT 20 */
1524 ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
1525 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1526 ctpres = ar->power_2G_ht20;
1527 break;
1528 case 3: /* 2.4 GHz HT 40 */
1529 ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
1530 ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
1531 ctpres = ar->power_2G_ht40;
1532 break;
1533 default:
1534 BUG();
1535 }
1536
1537 for (n = 0; n < ntargets; n++) {
1538 if (ctph[n].freq == 0xff)
1539 break;
1540 pwr_freqs[n] = ctph[n].freq;
1541 }
1542 ntargets = n;
1543 idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
1544 for (n = 0; n < 8; n++)
1545 ctpres[n] = ar9170_interpolate_u8(
1546 f,
1547 ctph[idx + 0].freq,
1548 ctph[idx + 0].power[n],
1549 ctph[idx + 1].freq,
1550 ctph[idx + 1].power[n]);
1551 }
1552
1553
1554 /* calc. conformance test limits and apply to ar->power*[] */
1555 ar9170_calc_ctl(ar, freq, bw);
1556
1557 /* set ACK/CTS TX power */
1558 ar9170_regwrite_begin(ar);
1559
1560 if (ar->eeprom.tx_mask != 1)
1561 ackchains = AR9170_TX_PHY_TXCHAIN_2;
1562 else
1563 ackchains = AR9170_TX_PHY_TXCHAIN_1;
1564
1565 if (freq < 3000)
1566 ackpower = ar->power_2G_ofdm[0] & 0x3f;
1567 else
1568 ackpower = ar->power_5G_leg[0] & 0x3f;
1569
1570 ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
1571 ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
1572 ackpower << 21 | ackchains << 27);
1573
1574 ar9170_regwrite_finish();
1575 return ar9170_regwrite_result();
1576}
1577
1578static int ar9170_calc_noise_dbm(u32 raw_noise)
1579{
1580 if (raw_noise & 0x100)
1581 return ~((raw_noise & 0x0ff) >> 1);
1582 else
1583 return (raw_noise & 0xff) >> 1;
1584}
1585
1586int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1587 enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
1588{
1589 const struct ar9170_phy_freq_params *freqpar;
1590 u32 cmd, tmp, offs;
1591 __le32 vals[8];
1592 int i, err;
1593 bool bandswitch;
1594
1595 /* clear BB heavy clip enable */
1596 err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
1597 if (err)
1598 return err;
1599
1600 /* may be NULL at first setup */
1601 if (ar->channel)
1602 bandswitch = ar->channel->band != channel->band;
1603 else
1604 bandswitch = true;
1605
1606 /* HW workaround */
1607 if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
1608 channel->center_freq <= 2417)
1609 bandswitch = true;
1610
1611 err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
1612 if (err)
1613 return err;
1614
1615 if (rfi != AR9170_RFI_NONE || bandswitch) {
1616 u32 val = 0x400;
1617
1618 if (rfi == AR9170_RFI_COLD)
1619 val = 0x800;
1620
1621 /* warm/cold reset BB/ADDA */
1622 err = ar9170_write_reg(ar, 0x1d4004, val);
1623 if (err)
1624 return err;
1625
1626 err = ar9170_write_reg(ar, 0x1d4004, 0x0);
1627 if (err)
1628 return err;
1629
1630 err = ar9170_init_phy(ar, channel->band);
1631 if (err)
1632 return err;
1633
1634 err = ar9170_init_rf_banks_0_7(ar,
1635 channel->band == IEEE80211_BAND_5GHZ);
1636 if (err)
1637 return err;
1638
1639 cmd = AR9170_CMD_RF_INIT;
1640 } else {
1641 cmd = AR9170_CMD_FREQUENCY;
1642 }
1643
1644 err = ar9170_init_rf_bank4_pwr(ar,
1645 channel->band == IEEE80211_BAND_5GHZ,
1646 channel->center_freq, bw);
1647 if (err)
1648 return err;
1649
1650 switch (bw) {
1651 case AR9170_BW_20:
1652 tmp = 0x240;
1653 offs = 0;
1654 break;
1655 case AR9170_BW_40_BELOW:
1656 tmp = 0x2c4;
1657 offs = 3;
1658 break;
1659 case AR9170_BW_40_ABOVE:
1660 tmp = 0x2d4;
1661 offs = 1;
1662 break;
1663 default:
1664 BUG();
1665 return -ENOSYS;
1666 }
1667
1668 if (ar->eeprom.tx_mask != 1)
1669 tmp |= 0x100;
1670
1671 err = ar9170_write_reg(ar, 0x1c5804, tmp);
1672 if (err)
1673 return err;
1674
1675 err = ar9170_set_freq_cal_data(ar, channel);
1676 if (err)
1677 return err;
1678
1679 err = ar9170_set_power_cal(ar, channel->center_freq, bw);
1680 if (err)
1681 return err;
1682
1683 freqpar = ar9170_get_hw_dyn_params(channel, bw);
1684
1685 vals[0] = cpu_to_le32(channel->center_freq * 1000);
1686 vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
1687 vals[2] = cpu_to_le32(offs << 2 | 1);
1688 vals[3] = cpu_to_le32(freqpar->coeff_exp);
1689 vals[4] = cpu_to_le32(freqpar->coeff_man);
1690 vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
1691 vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
1692 vals[7] = cpu_to_le32(1000);
1693
1694 err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
1695 sizeof(vals), (u8 *)vals);
1696 if (err)
1697 return err;
1698
1699 if (ar->phy_heavy_clip) {
1700 err = ar9170_write_reg(ar, 0x1c59e0,
1701 0x200 | ar->phy_heavy_clip);
1702 if (err) {
1703 if (ar9170_nag_limiter(ar))
1704 wiphy_err(ar->hw->wiphy,
1705 "failed to set heavy clip\n");
1706 }
1707 }
1708
1709 for (i = 0; i < 2; i++) {
1710 ar->noise[i] = ar9170_calc_noise_dbm(
1711 (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
1712
1713 ar->noise[i + 2] = ar9170_calc_noise_dbm(
1714 (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
1715 }
1716
1717 ar->channel = channel;
1718 return 0;
1719}
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
deleted file mode 100644
index d3be6f9816b5..000000000000
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ /dev/null
@@ -1,1008 +0,0 @@
1/*
2 * Atheros AR9170 driver
3 *
4 * USB - frontend
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; see the file COPYING. If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 * Copyright (c) 2007-2008 Atheros Communications, Inc.
26 *
27 * Permission to use, copy, modify, and/or distribute this software for any
28 * purpose with or without fee is hereby granted, provided that the above
29 * copyright notice and this permission notice appear in all copies.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39
40#include <linux/module.h>
41#include <linux/slab.h>
42#include <linux/usb.h>
43#include <linux/firmware.h>
44#include <linux/etherdevice.h>
45#include <linux/device.h>
46#include <net/mac80211.h>
47#include "ar9170.h"
48#include "cmd.h"
49#include "hw.h"
50#include "usb.h"
51
52MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
53MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
54MODULE_LICENSE("GPL");
55MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
56MODULE_FIRMWARE("ar9170.fw");
57
58enum ar9170_requirements {
59 AR9170_REQ_FW1_ONLY = 1,
60};
61
62static struct usb_device_id ar9170_usb_ids[] = {
63 /* Atheros 9170 */
64 { USB_DEVICE(0x0cf3, 0x9170) },
65 /* Atheros TG121N */
66 { USB_DEVICE(0x0cf3, 0x1001) },
67 /* TP-Link TL-WN821N v2 */
68 { USB_DEVICE(0x0cf3, 0x1002) },
69 /* 3Com Dual Band 802.11n USB Adapter */
70 { USB_DEVICE(0x0cf3, 0x1010) },
71 /* H3C Dual Band 802.11n USB Adapter */
72 { USB_DEVICE(0x0cf3, 0x1011) },
73 /* Cace Airpcap NX */
74 { USB_DEVICE(0xcace, 0x0300) },
75 /* D-Link DWA 160 A1 */
76 { USB_DEVICE(0x07d1, 0x3c10) },
77 /* D-Link DWA 160 A2 */
78 { USB_DEVICE(0x07d1, 0x3a09) },
79 /* Netgear WNA1000 */
80 { USB_DEVICE(0x0846, 0x9040) },
81 /* Netgear WNDA3100 */
82 { USB_DEVICE(0x0846, 0x9010) },
83 /* Netgear WN111 v2 */
84 { USB_DEVICE(0x0846, 0x9001) },
85 /* Zydas ZD1221 */
86 { USB_DEVICE(0x0ace, 0x1221) },
87 /* Proxim ORiNOCO 802.11n USB */
88 { USB_DEVICE(0x1435, 0x0804) },
89 /* WNC Generic 11n USB Dongle */
90 { USB_DEVICE(0x1435, 0x0326) },
91 /* ZyXEL NWD271N */
92 { USB_DEVICE(0x0586, 0x3417) },
93 /* Z-Com UB81 BG */
94 { USB_DEVICE(0x0cde, 0x0023) },
95 /* Z-Com UB82 ABG */
96 { USB_DEVICE(0x0cde, 0x0026) },
97 /* Sphairon Homelink 1202 */
98 { USB_DEVICE(0x0cde, 0x0027) },
99 /* Arcadyan WN7512 */
100 { USB_DEVICE(0x083a, 0xf522) },
101 /* Planex GWUS300 */
102 { USB_DEVICE(0x2019, 0x5304) },
103 /* IO-Data WNGDNUS2 */
104 { USB_DEVICE(0x04bb, 0x093f) },
105 /* AVM FRITZ!WLAN USB Stick N */
106 { USB_DEVICE(0x057C, 0x8401) },
107 /* NEC WL300NU-G */
108 { USB_DEVICE(0x0409, 0x0249) },
109 /* AVM FRITZ!WLAN USB Stick N 2.4 */
110 { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
111 /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
112 { USB_DEVICE(0x1668, 0x1200) },
113
114 /* terminate */
115 {}
116};
117MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
118
119static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
120{
121 struct urb *urb;
122 unsigned long flags;
123 int err;
124
125 if (unlikely(!IS_STARTED(&aru->common)))
126 return ;
127
128 spin_lock_irqsave(&aru->tx_urb_lock, flags);
129 if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) {
130 spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
131 return ;
132 }
133 atomic_inc(&aru->tx_submitted_urbs);
134
135 urb = usb_get_from_anchor(&aru->tx_pending);
136 if (!urb) {
137 atomic_dec(&aru->tx_submitted_urbs);
138 spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
139
140 return ;
141 }
142 spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
143
144 aru->tx_pending_urbs--;
145 usb_anchor_urb(urb, &aru->tx_submitted);
146
147 err = usb_submit_urb(urb, GFP_ATOMIC);
148 if (unlikely(err)) {
149 if (ar9170_nag_limiter(&aru->common))
150 dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
151 err);
152
153 usb_unanchor_urb(urb);
154 atomic_dec(&aru->tx_submitted_urbs);
155 ar9170_tx_callback(&aru->common, urb->context);
156 }
157
158 usb_free_urb(urb);
159}
160
161static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
162{
163 struct sk_buff *skb = urb->context;
164 struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
165
166 if (unlikely(!aru)) {
167 dev_kfree_skb_irq(skb);
168 return ;
169 }
170
171 atomic_dec(&aru->tx_submitted_urbs);
172
173 ar9170_tx_callback(&aru->common, skb);
174
175 ar9170_usb_submit_urb(aru);
176}
177
178static void ar9170_usb_tx_urb_complete(struct urb *urb)
179{
180}
181
182static void ar9170_usb_irq_completed(struct urb *urb)
183{
184 struct ar9170_usb *aru = urb->context;
185
186 switch (urb->status) {
187 /* everything is fine */
188 case 0:
189 break;
190
191 /* disconnect */
192 case -ENOENT:
193 case -ECONNRESET:
194 case -ENODEV:
195 case -ESHUTDOWN:
196 goto free;
197
198 default:
199 goto resubmit;
200 }
201
202 ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
203 urb->actual_length);
204
205resubmit:
206 usb_anchor_urb(urb, &aru->rx_submitted);
207 if (usb_submit_urb(urb, GFP_ATOMIC)) {
208 usb_unanchor_urb(urb);
209 goto free;
210 }
211
212 return;
213
214free:
215 usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
216}
217
218static void ar9170_usb_rx_completed(struct urb *urb)
219{
220 struct sk_buff *skb = urb->context;
221 struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
222 int err;
223
224 if (!aru)
225 goto free;
226
227 switch (urb->status) {
228 /* everything is fine */
229 case 0:
230 break;
231
232 /* disconnect */
233 case -ENOENT:
234 case -ECONNRESET:
235 case -ENODEV:
236 case -ESHUTDOWN:
237 goto free;
238
239 default:
240 goto resubmit;
241 }
242
243 skb_put(skb, urb->actual_length);
244 ar9170_rx(&aru->common, skb);
245
246resubmit:
247 skb_reset_tail_pointer(skb);
248 skb_trim(skb, 0);
249
250 usb_anchor_urb(urb, &aru->rx_submitted);
251 err = usb_submit_urb(urb, GFP_ATOMIC);
252 if (unlikely(err)) {
253 usb_unanchor_urb(urb);
254 goto free;
255 }
256
257 return ;
258
259free:
260 dev_kfree_skb_irq(skb);
261}
262
263static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
264 struct urb *urb, gfp_t gfp)
265{
266 struct sk_buff *skb;
267
268 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
269 if (!skb)
270 return -ENOMEM;
271
272 /* reserve some space for mac80211's radiotap */
273 skb_reserve(skb, 32);
274
275 usb_fill_bulk_urb(urb, aru->udev,
276 usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
277 skb->data, min(skb_tailroom(skb),
278 AR9170_MAX_RX_BUFFER_SIZE),
279 ar9170_usb_rx_completed, skb);
280
281 return 0;
282}
283
284static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
285{
286 struct urb *urb = NULL;
287 void *ibuf;
288 int err = -ENOMEM;
289
290 /* initialize interrupt endpoint */
291 urb = usb_alloc_urb(0, GFP_KERNEL);
292 if (!urb)
293 goto out;
294
295 ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
296 if (!ibuf)
297 goto out;
298
299 usb_fill_int_urb(urb, aru->udev,
300 usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
301 64, ar9170_usb_irq_completed, aru, 1);
302 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
303
304 usb_anchor_urb(urb, &aru->rx_submitted);
305 err = usb_submit_urb(urb, GFP_KERNEL);
306 if (err) {
307 usb_unanchor_urb(urb);
308 usb_free_coherent(aru->udev, 64, urb->transfer_buffer,
309 urb->transfer_dma);
310 }
311
312out:
313 usb_free_urb(urb);
314 return err;
315}
316
317static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
318{
319 struct urb *urb;
320 int i;
321 int err = -EINVAL;
322
323 for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
324 err = -ENOMEM;
325 urb = usb_alloc_urb(0, GFP_KERNEL);
326 if (!urb)
327 goto err_out;
328
329 err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
330 if (err) {
331 usb_free_urb(urb);
332 goto err_out;
333 }
334
335 usb_anchor_urb(urb, &aru->rx_submitted);
336 err = usb_submit_urb(urb, GFP_KERNEL);
337 if (err) {
338 usb_unanchor_urb(urb);
339 dev_kfree_skb_any((void *) urb->transfer_buffer);
340 usb_free_urb(urb);
341 goto err_out;
342 }
343 usb_free_urb(urb);
344 }
345
346 /* the device now waiting for a firmware. */
347 aru->common.state = AR9170_IDLE;
348 return 0;
349
350err_out:
351
352 usb_kill_anchored_urbs(&aru->rx_submitted);
353 return err;
354}
355
356static int ar9170_usb_flush(struct ar9170 *ar)
357{
358 struct ar9170_usb *aru = (void *) ar;
359 struct urb *urb;
360 int ret, err = 0;
361
362 if (IS_STARTED(ar))
363 aru->common.state = AR9170_IDLE;
364
365 usb_wait_anchor_empty_timeout(&aru->tx_pending,
366 msecs_to_jiffies(800));
367 while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
368 ar9170_tx_callback(&aru->common, (void *) urb->context);
369 usb_free_urb(urb);
370 }
371
372 /* lets wait a while until the tx - queues are dried out */
373 ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
374 msecs_to_jiffies(100));
375 if (ret == 0)
376 err = -ETIMEDOUT;
377
378 usb_kill_anchored_urbs(&aru->tx_submitted);
379
380 if (IS_ACCEPTING_CMD(ar))
381 aru->common.state = AR9170_STARTED;
382
383 return err;
384}
385
386static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
387{
388 int err;
389
390 aru->common.state = AR9170_UNKNOWN_STATE;
391
392 err = ar9170_usb_flush(&aru->common);
393 if (err)
394 dev_err(&aru->udev->dev, "stuck tx urbs!\n");
395
396 usb_poison_anchored_urbs(&aru->tx_submitted);
397 usb_poison_anchored_urbs(&aru->rx_submitted);
398}
399
400static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
401 unsigned int plen, void *payload,
402 unsigned int outlen, void *out)
403{
404 struct ar9170_usb *aru = (void *) ar;
405 struct urb *urb = NULL;
406 unsigned long flags;
407 int err = -ENOMEM;
408
409 if (unlikely(!IS_ACCEPTING_CMD(ar)))
410 return -EPERM;
411
412 if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
413 return -EINVAL;
414
415 urb = usb_alloc_urb(0, GFP_ATOMIC);
416 if (unlikely(!urb))
417 goto err_free;
418
419 ar->cmdbuf[0] = cpu_to_le32(plen);
420 ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
421 /* writing multiple regs fills this buffer already */
422 if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
423 memcpy(&ar->cmdbuf[1], payload, plen);
424
425 spin_lock_irqsave(&aru->common.cmdlock, flags);
426 aru->readbuf = (u8 *)out;
427 aru->readlen = outlen;
428 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
429
430 usb_fill_int_urb(urb, aru->udev,
431 usb_sndintpipe(aru->udev, AR9170_EP_CMD),
432 aru->common.cmdbuf, plen + 4,
433 ar9170_usb_tx_urb_complete, NULL, 1);
434
435 usb_anchor_urb(urb, &aru->tx_submitted);
436 err = usb_submit_urb(urb, GFP_ATOMIC);
437 if (unlikely(err)) {
438 usb_unanchor_urb(urb);
439 usb_free_urb(urb);
440 goto err_unbuf;
441 }
442 usb_free_urb(urb);
443
444 err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
445 if (err == 0) {
446 err = -ETIMEDOUT;
447 goto err_unbuf;
448 }
449
450 if (aru->readlen != outlen) {
451 err = -EMSGSIZE;
452 goto err_unbuf;
453 }
454
455 return 0;
456
457err_unbuf:
458 /* Maybe the device was removed in the second we were waiting? */
459 if (IS_STARTED(ar)) {
460 dev_err(&aru->udev->dev, "no command feedback "
461 "received (%d).\n", err);
462
463 /* provide some maybe useful debug information */
464 print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
465 aru->common.cmdbuf, plen + 4);
466 dump_stack();
467 }
468
469 /* invalidate to avoid completing the next prematurely */
470 spin_lock_irqsave(&aru->common.cmdlock, flags);
471 aru->readbuf = NULL;
472 aru->readlen = 0;
473 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
474
475err_free:
476
477 return err;
478}
479
480static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
481{
482 struct ar9170_usb *aru = (struct ar9170_usb *) ar;
483 struct urb *urb;
484
485 if (unlikely(!IS_STARTED(ar))) {
486 /* Seriously, what were you drink... err... thinking!? */
487 return -EPERM;
488 }
489
490 urb = usb_alloc_urb(0, GFP_ATOMIC);
491 if (unlikely(!urb))
492 return -ENOMEM;
493
494 usb_fill_bulk_urb(urb, aru->udev,
495 usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
496 skb->data, skb->len,
497 ar9170_usb_tx_urb_complete_frame, skb);
498 urb->transfer_flags |= URB_ZERO_PACKET;
499
500 usb_anchor_urb(urb, &aru->tx_pending);
501 aru->tx_pending_urbs++;
502
503 usb_free_urb(urb);
504
505 ar9170_usb_submit_urb(aru);
506 return 0;
507}
508
509static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
510{
511 struct ar9170_usb *aru = (void *) ar;
512 unsigned long flags;
513 u32 in, out;
514
515 if (unlikely(!buffer))
516 return ;
517
518 in = le32_to_cpup((__le32 *)buffer);
519 out = le32_to_cpu(ar->cmdbuf[0]);
520
521 /* mask off length byte */
522 out &= ~0xFF;
523
524 if (aru->readlen >= 0) {
525 /* add expected length */
526 out |= aru->readlen;
527 } else {
528 /* add obtained length */
529 out |= in & 0xFF;
530 }
531
532 /*
533 * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
534 * length and we cannot predict the correct length in advance.
535 * So we only check if we provided enough space for the data.
536 */
537 if (unlikely(out < in)) {
538 dev_warn(&aru->udev->dev, "received invalid command response "
539 "got %d bytes, instead of %d bytes "
540 "and the resp length is %d bytes\n",
541 in, out, len);
542 print_hex_dump_bytes("ar9170 invalid resp: ",
543 DUMP_PREFIX_OFFSET, buffer, len);
544 /*
545 * Do not complete, then the command times out,
546 * and we get a stack trace from there.
547 */
548 return ;
549 }
550
551 spin_lock_irqsave(&aru->common.cmdlock, flags);
552 if (aru->readbuf && len > 0) {
553 memcpy(aru->readbuf, buffer + 4, len - 4);
554 aru->readbuf = NULL;
555 }
556 complete(&aru->cmd_wait);
557 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
558}
559
560static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
561 size_t len, u32 addr, bool complete)
562{
563 int transfer, err;
564 u8 *buf = kmalloc(4096, GFP_KERNEL);
565
566 if (!buf)
567 return -ENOMEM;
568
569 while (len) {
570 transfer = min_t(int, len, 4096);
571 memcpy(buf, data, transfer);
572
573 err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
574 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
575 addr >> 8, 0, buf, transfer, 1000);
576
577 if (err < 0) {
578 kfree(buf);
579 return err;
580 }
581
582 len -= transfer;
583 data += transfer;
584 addr += transfer;
585 }
586 kfree(buf);
587
588 if (complete) {
589 err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
590 0x31 /* FW DL COMPLETE */,
591 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
592 }
593
594 return 0;
595}
596
597static int ar9170_usb_reset(struct ar9170_usb *aru)
598{
599 int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
600
601 if (lock) {
602 ret = usb_lock_device_for_reset(aru->udev, aru->intf);
603 if (ret < 0) {
604 dev_err(&aru->udev->dev, "unable to lock device "
605 "for reset (%d).\n", ret);
606 return ret;
607 }
608 }
609
610 ret = usb_reset_device(aru->udev);
611 if (lock)
612 usb_unlock_device(aru->udev);
613
614 /* let it rest - for a second - */
615 msleep(1000);
616
617 return ret;
618}
619
620static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
621{
622 int err;
623
624 if (!aru->init_values)
625 goto upload_fw_start;
626
627 /* First, upload initial values to device RAM */
628 err = ar9170_usb_upload(aru, aru->init_values->data,
629 aru->init_values->size, 0x102800, false);
630 if (err) {
631 dev_err(&aru->udev->dev, "firmware part 1 "
632 "upload failed (%d).\n", err);
633 return err;
634 }
635
636upload_fw_start:
637
638 /* Then, upload the firmware itself and start it */
639 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
640 0x200000, true);
641}
642
643static int ar9170_usb_init_transport(struct ar9170_usb *aru)
644{
645 struct ar9170 *ar = (void *) &aru->common;
646 int err;
647
648 ar9170_regwrite_begin(ar);
649
650 /* Set USB Rx stream mode MAX packet number to 2 */
651 ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
652
653 /* Set USB Rx stream mode timeout to 10us */
654 ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
655
656 ar9170_regwrite_finish();
657
658 err = ar9170_regwrite_result();
659 if (err)
660 dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
661
662 return err;
663}
664
665static void ar9170_usb_stop(struct ar9170 *ar)
666{
667 struct ar9170_usb *aru = (void *) ar;
668 int ret;
669
670 if (IS_ACCEPTING_CMD(ar))
671 aru->common.state = AR9170_STOPPED;
672
673 ret = ar9170_usb_flush(ar);
674 if (ret)
675 dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
676
677 usb_poison_anchored_urbs(&aru->tx_submitted);
678
679 /*
680 * Note:
681 * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
682 * Else we would end up with a unresponsive device...
683 */
684}
685
686static int ar9170_usb_open(struct ar9170 *ar)
687{
688 struct ar9170_usb *aru = (void *) ar;
689 int err;
690
691 usb_unpoison_anchored_urbs(&aru->tx_submitted);
692 err = ar9170_usb_init_transport(aru);
693 if (err) {
694 usb_poison_anchored_urbs(&aru->tx_submitted);
695 return err;
696 }
697
698 aru->common.state = AR9170_IDLE;
699 return 0;
700}
701
702static int ar9170_usb_init_device(struct ar9170_usb *aru)
703{
704 int err;
705
706 err = ar9170_usb_alloc_rx_irq_urb(aru);
707 if (err)
708 goto err_out;
709
710 err = ar9170_usb_alloc_rx_bulk_urbs(aru);
711 if (err)
712 goto err_unrx;
713
714 err = ar9170_usb_upload_firmware(aru);
715 if (err) {
716 err = ar9170_echo_test(&aru->common, 0x60d43110);
717 if (err) {
718 /* force user invention, by disabling the device */
719 err = usb_driver_set_configuration(aru->udev, -1);
720 dev_err(&aru->udev->dev, "device is in a bad state. "
721 "please reconnect it!\n");
722 goto err_unrx;
723 }
724 }
725
726 return 0;
727
728err_unrx:
729 ar9170_usb_cancel_urbs(aru);
730
731err_out:
732 return err;
733}
734
735static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
736{
737 struct device *parent = aru->udev->dev.parent;
738 struct usb_device *udev;
739
740 /*
741 * Store a copy of the usb_device pointer locally.
742 * This is because device_release_driver initiates
743 * ar9170_usb_disconnect, which in turn frees our
744 * driver context (aru).
745 */
746 udev = aru->udev;
747
748 complete(&aru->firmware_loading_complete);
749
750 /* unbind anything failed */
751 if (parent)
752 device_lock(parent);
753
754 device_release_driver(&udev->dev);
755 if (parent)
756 device_unlock(parent);
757
758 usb_put_dev(udev);
759}
760
761static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
762{
763 struct ar9170_usb *aru = context;
764 int err;
765
766 aru->firmware = fw;
767
768 if (!fw) {
769 dev_err(&aru->udev->dev, "firmware file not found.\n");
770 goto err_freefw;
771 }
772
773 err = ar9170_usb_init_device(aru);
774 if (err)
775 goto err_freefw;
776
777 err = ar9170_usb_open(&aru->common);
778 if (err)
779 goto err_unrx;
780
781 err = ar9170_register(&aru->common, &aru->udev->dev);
782
783 ar9170_usb_stop(&aru->common);
784 if (err)
785 goto err_unrx;
786
787 complete(&aru->firmware_loading_complete);
788 usb_put_dev(aru->udev);
789 return;
790
791 err_unrx:
792 ar9170_usb_cancel_urbs(aru);
793
794 err_freefw:
795 ar9170_usb_firmware_failed(aru);
796}
797
798static void ar9170_usb_firmware_inits(const struct firmware *fw,
799 void *context)
800{
801 struct ar9170_usb *aru = context;
802 int err;
803
804 if (!fw) {
805 dev_err(&aru->udev->dev, "file with init values not found.\n");
806 ar9170_usb_firmware_failed(aru);
807 return;
808 }
809
810 aru->init_values = fw;
811
812 /* ok so we have the init values -- get code for two-stage */
813
814 err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
815 &aru->udev->dev, GFP_KERNEL, aru,
816 ar9170_usb_firmware_finish);
817 if (err)
818 ar9170_usb_firmware_failed(aru);
819}
820
821static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
822{
823 struct ar9170_usb *aru = context;
824 int err;
825
826 if (fw) {
827 ar9170_usb_firmware_finish(fw, context);
828 return;
829 }
830
831 if (aru->req_one_stage_fw) {
832 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
833 "not found and is required for this device\n");
834 ar9170_usb_firmware_failed(aru);
835 return;
836 }
837
838 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
839 "not found, trying old firmware...\n");
840
841 err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
842 &aru->udev->dev, GFP_KERNEL, aru,
843 ar9170_usb_firmware_inits);
844 if (err)
845 ar9170_usb_firmware_failed(aru);
846}
847
848static bool ar9170_requires_one_stage(const struct usb_device_id *id)
849{
850 if (!id->driver_info)
851 return false;
852 if (id->driver_info == AR9170_REQ_FW1_ONLY)
853 return true;
854 return false;
855}
856
857static int ar9170_usb_probe(struct usb_interface *intf,
858 const struct usb_device_id *id)
859{
860 struct ar9170_usb *aru;
861 struct ar9170 *ar;
862 struct usb_device *udev;
863 int err;
864
865 aru = ar9170_alloc(sizeof(*aru));
866 if (IS_ERR(aru)) {
867 err = PTR_ERR(aru);
868 goto out;
869 }
870
871 udev = interface_to_usbdev(intf);
872 usb_get_dev(udev);
873 aru->udev = udev;
874 aru->intf = intf;
875 ar = &aru->common;
876
877 aru->req_one_stage_fw = ar9170_requires_one_stage(id);
878
879 usb_set_intfdata(intf, aru);
880 SET_IEEE80211_DEV(ar->hw, &intf->dev);
881
882 init_usb_anchor(&aru->rx_submitted);
883 init_usb_anchor(&aru->tx_pending);
884 init_usb_anchor(&aru->tx_submitted);
885 init_completion(&aru->cmd_wait);
886 init_completion(&aru->firmware_loading_complete);
887 spin_lock_init(&aru->tx_urb_lock);
888
889 aru->tx_pending_urbs = 0;
890 atomic_set(&aru->tx_submitted_urbs, 0);
891
892 aru->common.stop = ar9170_usb_stop;
893 aru->common.flush = ar9170_usb_flush;
894 aru->common.open = ar9170_usb_open;
895 aru->common.tx = ar9170_usb_tx;
896 aru->common.exec_cmd = ar9170_usb_exec_cmd;
897 aru->common.callback_cmd = ar9170_usb_callback_cmd;
898
899#ifdef CONFIG_PM
900 udev->reset_resume = 1;
901#endif /* CONFIG_PM */
902 err = ar9170_usb_reset(aru);
903 if (err)
904 goto err_freehw;
905
906 usb_get_dev(aru->udev);
907 return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
908 &aru->udev->dev, GFP_KERNEL, aru,
909 ar9170_usb_firmware_step2);
910err_freehw:
911 usb_set_intfdata(intf, NULL);
912 usb_put_dev(udev);
913 ieee80211_free_hw(ar->hw);
914out:
915 return err;
916}
917
918static void ar9170_usb_disconnect(struct usb_interface *intf)
919{
920 struct ar9170_usb *aru = usb_get_intfdata(intf);
921
922 if (!aru)
923 return;
924
925 aru->common.state = AR9170_IDLE;
926
927 wait_for_completion(&aru->firmware_loading_complete);
928
929 ar9170_unregister(&aru->common);
930 ar9170_usb_cancel_urbs(aru);
931
932 usb_put_dev(aru->udev);
933 usb_set_intfdata(intf, NULL);
934 ieee80211_free_hw(aru->common.hw);
935
936 release_firmware(aru->init_values);
937 release_firmware(aru->firmware);
938}
939
940#ifdef CONFIG_PM
941static int ar9170_suspend(struct usb_interface *intf,
942 pm_message_t message)
943{
944 struct ar9170_usb *aru = usb_get_intfdata(intf);
945
946 if (!aru)
947 return -ENODEV;
948
949 aru->common.state = AR9170_IDLE;
950 ar9170_usb_cancel_urbs(aru);
951
952 return 0;
953}
954
955static int ar9170_resume(struct usb_interface *intf)
956{
957 struct ar9170_usb *aru = usb_get_intfdata(intf);
958 int err;
959
960 if (!aru)
961 return -ENODEV;
962
963 usb_unpoison_anchored_urbs(&aru->rx_submitted);
964 usb_unpoison_anchored_urbs(&aru->tx_submitted);
965
966 err = ar9170_usb_init_device(aru);
967 if (err)
968 goto err_unrx;
969
970 err = ar9170_usb_open(&aru->common);
971 if (err)
972 goto err_unrx;
973
974 return 0;
975
976err_unrx:
977 aru->common.state = AR9170_IDLE;
978 ar9170_usb_cancel_urbs(aru);
979
980 return err;
981}
982#endif /* CONFIG_PM */
983
984static struct usb_driver ar9170_driver = {
985 .name = "ar9170usb",
986 .probe = ar9170_usb_probe,
987 .disconnect = ar9170_usb_disconnect,
988 .id_table = ar9170_usb_ids,
989 .soft_unbind = 1,
990#ifdef CONFIG_PM
991 .suspend = ar9170_suspend,
992 .resume = ar9170_resume,
993 .reset_resume = ar9170_resume,
994#endif /* CONFIG_PM */
995};
996
997static int __init ar9170_init(void)
998{
999 return usb_register(&ar9170_driver);
1000}
1001
1002static void __exit ar9170_exit(void)
1003{
1004 usb_deregister(&ar9170_driver);
1005}
1006
1007module_init(ar9170_init);
1008module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
deleted file mode 100644
index 919b06046eb3..000000000000
--- a/drivers/net/wireless/ath/ar9170/usb.h
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * Atheros AR9170 USB driver
3 *
4 * Driver specific definitions
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; see the file COPYING. If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 * Copyright (c) 2007-2008 Atheros Communications, Inc.
26 *
27 * Permission to use, copy, modify, and/or distribute this software for any
28 * purpose with or without fee is hereby granted, provided that the above
29 * copyright notice and this permission notice appear in all copies.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39#ifndef __USB_H
40#define __USB_H
41
42#include <linux/usb.h>
43#include <linux/completion.h>
44#include <linux/spinlock.h>
45#include <linux/leds.h>
46#include <net/cfg80211.h>
47#include <net/mac80211.h>
48#include <linux/firmware.h>
49#include "eeprom.h"
50#include "hw.h"
51#include "ar9170.h"
52
53#define AR9170_NUM_RX_URBS 16
54#define AR9170_NUM_TX_URBS 8
55
56struct firmware;
57
58struct ar9170_usb {
59 struct ar9170 common;
60 struct usb_device *udev;
61 struct usb_interface *intf;
62
63 struct usb_anchor rx_submitted;
64 struct usb_anchor tx_pending;
65 struct usb_anchor tx_submitted;
66
67 bool req_one_stage_fw;
68
69 spinlock_t tx_urb_lock;
70 atomic_t tx_submitted_urbs;
71 unsigned int tx_pending_urbs;
72
73 struct completion cmd_wait;
74 struct completion firmware_loading_complete;
75 int readlen;
76 u8 *readbuf;
77
78 const struct firmware *init_values;
79 const struct firmware *firmware;
80};
81
82#endif /* __USB_H */
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index a6c6a466000f..6d7105b7e8f1 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -119,6 +119,7 @@ struct ath_ops {
119 void (*write)(void *, u32 val, u32 reg_offset); 119 void (*write)(void *, u32 val, u32 reg_offset);
120 void (*enable_write_buffer)(void *); 120 void (*enable_write_buffer)(void *);
121 void (*write_flush) (void *); 121 void (*write_flush) (void *);
122 u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
122}; 123};
123 124
124struct ath_common; 125struct ath_common;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 106c0b06cf55..4bf9dab4f2b3 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -44,6 +44,34 @@ static const int m1ThreshExt_off = 127;
44static const int m2ThreshExt_off = 127; 44static const int m2ThreshExt_off = 127;
45 45
46 46
47static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array,
48 int col)
49{
50 int i;
51
52 for (i = 0; i < array->ia_rows; i++)
53 bank[i] = INI_RA(array, i, col);
54}
55
56
57#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \
58 ar5008_write_rf_array(ah, iniarray, regData, &(regWr))
59
60static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array,
61 u32 *data, unsigned int *writecnt)
62{
63 int r;
64
65 ENABLE_REGWRITE_BUFFER(ah);
66
67 for (r = 0; r < array->ia_rows; r++) {
68 REG_WRITE(ah, INI_RA(array, r, 0), data[r]);
69 DO_DELAY(*writecnt);
70 }
71
72 REGWRITE_BUFFER_FLUSH(ah);
73}
74
47/** 75/**
48 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters 76 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
49 * @rfbuf: 77 * @rfbuf:
@@ -530,16 +558,16 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
530 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); 558 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
531 559
532 /* Setup Bank 0 Write */ 560 /* Setup Bank 0 Write */
533 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); 561 ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1);
534 562
535 /* Setup Bank 1 Write */ 563 /* Setup Bank 1 Write */
536 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); 564 ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1);
537 565
538 /* Setup Bank 2 Write */ 566 /* Setup Bank 2 Write */
539 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); 567 ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1);
540 568
541 /* Setup Bank 6 Write */ 569 /* Setup Bank 6 Write */
542 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, 570 ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3,
543 modesIndex); 571 modesIndex);
544 { 572 {
545 int i; 573 int i;
@@ -569,7 +597,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
569 } 597 }
570 598
571 /* Setup Bank 7 Setup */ 599 /* Setup Bank 7 Setup */
572 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); 600 ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1);
573 601
574 /* Write Analog registers */ 602 /* Write Analog registers */
575 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, 603 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
@@ -729,6 +757,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
729 struct ath9k_channel *chan) 757 struct ath9k_channel *chan)
730{ 758{
731 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 759 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
760 struct ath_common *common = ath9k_hw_common(ah);
732 int i, regWrites = 0; 761 int i, regWrites = 0;
733 struct ieee80211_channel *channel = chan->chan; 762 struct ieee80211_channel *channel = chan->chan;
734 u32 modesIndex, freqIndex; 763 u32 modesIndex, freqIndex;
@@ -805,7 +834,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
805 REG_WRITE(ah, reg, val); 834 REG_WRITE(ah, reg, val);
806 835
807 if (reg >= 0x7800 && reg < 0x78a0 836 if (reg >= 0x7800 && reg < 0x78a0
808 && ah->config.analog_shiftreg) { 837 && ah->config.analog_shiftreg
838 && (common->bus_ops->ath_bus_type != ATH_USB)) {
809 udelay(100); 839 udelay(100);
810 } 840 }
811 841
@@ -835,7 +865,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
835 REG_WRITE(ah, reg, val); 865 REG_WRITE(ah, reg, val);
836 866
837 if (reg >= 0x7800 && reg < 0x78a0 867 if (reg >= 0x7800 && reg < 0x78a0
838 && ah->config.analog_shiftreg) { 868 && ah->config.analog_shiftreg
869 && (common->bus_ops->ath_bus_type != ATH_USB)) {
839 udelay(100); 870 udelay(100);
840 } 871 }
841 872
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 76388c6d6692..cb611b287b35 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -26,6 +26,27 @@ enum ar9002_cal_types {
26 IQ_MISMATCH_CAL = BIT(2), 26 IQ_MISMATCH_CAL = BIT(2),
27}; 27};
28 28
29static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
30 struct ath9k_channel *chan,
31 enum ar9002_cal_types cal_type)
32{
33 bool supported = false;
34 switch (ah->supp_cals & cal_type) {
35 case IQ_MISMATCH_CAL:
36 /* Run IQ Mismatch for non-CCK only */
37 if (!IS_CHAN_B(chan))
38 supported = true;
39 break;
40 case ADC_GAIN_CAL:
41 case ADC_DC_CAL:
42 /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
43 if (!IS_CHAN_B(chan) &&
44 !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
45 supported = true;
46 break;
47 }
48 return supported;
49}
29 50
30static void ar9002_hw_setup_calibration(struct ath_hw *ah, 51static void ar9002_hw_setup_calibration(struct ath_hw *ah,
31 struct ath9k_cal_list *currCal) 52 struct ath9k_cal_list *currCal)
@@ -858,26 +879,32 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
858 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { 879 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
859 ah->supp_cals = IQ_MISMATCH_CAL; 880 ah->supp_cals = IQ_MISMATCH_CAL;
860 881
861 if (AR_SREV_9160_10_OR_LATER(ah) && 882 if (AR_SREV_9160_10_OR_LATER(ah))
862 !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
863 ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL; 883 ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
864 884
885 if (AR_SREV_9287(ah))
886 ah->supp_cals &= ~ADC_GAIN_CAL;
865 887
888 if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
866 INIT_CAL(&ah->adcgain_caldata); 889 INIT_CAL(&ah->adcgain_caldata);
867 INSERT_CAL(ah, &ah->adcgain_caldata); 890 INSERT_CAL(ah, &ah->adcgain_caldata);
868 ath_dbg(common, ATH_DBG_CALIBRATE, 891 ath_dbg(common, ATH_DBG_CALIBRATE,
869 "enabling ADC Gain Calibration.\n"); 892 "enabling ADC Gain Calibration.\n");
893 }
870 894
895 if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
871 INIT_CAL(&ah->adcdc_caldata); 896 INIT_CAL(&ah->adcdc_caldata);
872 INSERT_CAL(ah, &ah->adcdc_caldata); 897 INSERT_CAL(ah, &ah->adcdc_caldata);
873 ath_dbg(common, ATH_DBG_CALIBRATE, 898 ath_dbg(common, ATH_DBG_CALIBRATE,
874 "enabling ADC DC Calibration.\n"); 899 "enabling ADC DC Calibration.\n");
875 } 900 }
876 901
877 INIT_CAL(&ah->iq_caldata); 902 if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
878 INSERT_CAL(ah, &ah->iq_caldata); 903 INIT_CAL(&ah->iq_caldata);
879 ath_dbg(common, ATH_DBG_CALIBRATE, 904 INSERT_CAL(ah, &ah->iq_caldata);
880 "enabling IQ Calibration.\n"); 905 ath_dbg(common, ATH_DBG_CALIBRATE,
906 "enabling IQ Calibration.\n");
907 }
881 908
882 ah->cal_list_curr = ah->cal_list; 909 ah->cal_list_curr = ah->cal_list;
883 910
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 399ab3bb299b..8dd8f6308502 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -415,17 +415,6 @@ static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
415 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); 415 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
416} 416}
417 417
418static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
419 u32 vmf)
420{
421 struct ar5416_desc *ads = AR5416DESC(ds);
422
423 if (vmf)
424 ads->ds_ctl0 |= AR_VirtMoreFrag;
425 else
426 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
427}
428
429void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 418void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
430 u32 size, u32 flags) 419 u32 size, u32 flags)
431{ 420{
@@ -459,5 +448,4 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
459 ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; 448 ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
460 ops->clr11n_aggr = ar9002_hw_clr11n_aggr; 449 ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
461 ops->set11n_burstduration = ar9002_hw_set11n_burstduration; 450 ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
462 ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
463} 451}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 7f5de6e4448b..aebaad97b190 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -66,8 +66,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
66 66
67 /* rx/tx gain */ 67 /* rx/tx gain */
68 INIT_INI_ARRAY(&ah->iniModesRxGain, 68 INIT_INI_ARRAY(&ah->iniModesRxGain,
69 ar9485_common_rx_gain_1_1, 69 ar9485Common_wo_xlna_rx_gain_1_1,
70 ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2); 70 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
71 INIT_INI_ARRAY(&ah->iniModesTxGain, 71 INIT_INI_ARRAY(&ah->iniModesTxGain,
72 ar9485_modes_lowest_ob_db_tx_gain_1_1, 72 ar9485_modes_lowest_ob_db_tx_gain_1_1,
73 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), 73 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
@@ -88,66 +88,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
88 ar9485_1_1_pcie_phy_clkreq_disable_L1, 88 ar9485_1_1_pcie_phy_clkreq_disable_L1,
89 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 89 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
90 2); 90 2);
91 } else if (AR_SREV_9485(ah)) {
92 /* mac */
93 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
94 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
95 ar9485_1_0_mac_core,
96 ARRAY_SIZE(ar9485_1_0_mac_core), 2);
97 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
98 ar9485_1_0_mac_postamble,
99 ARRAY_SIZE(ar9485_1_0_mac_postamble), 5);
100
101 /* bb */
102 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0,
103 ARRAY_SIZE(ar9485_1_0), 2);
104 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
105 ar9485_1_0_baseband_core,
106 ARRAY_SIZE(ar9485_1_0_baseband_core), 2);
107 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
108 ar9485_1_0_baseband_postamble,
109 ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5);
110
111 /* radio */
112 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
113 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
114 ar9485_1_0_radio_core,
115 ARRAY_SIZE(ar9485_1_0_radio_core), 2);
116 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
117 ar9485_1_0_radio_postamble,
118 ARRAY_SIZE(ar9485_1_0_radio_postamble), 2);
119
120 /* soc */
121 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
122 ar9485_1_0_soc_preamble,
123 ARRAY_SIZE(ar9485_1_0_soc_preamble), 2);
124 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
125 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
126
127 /* rx/tx gain */
128 INIT_INI_ARRAY(&ah->iniModesRxGain,
129 ar9485Common_rx_gain_1_0,
130 ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2);
131 INIT_INI_ARRAY(&ah->iniModesTxGain,
132 ar9485Modes_lowest_ob_db_tx_gain_1_0,
133 ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
134 5);
135
136 /* Load PCIE SERDES settings from INI */
137
138 /* Awake Setting */
139
140 INIT_INI_ARRAY(&ah->iniPcieSerdes,
141 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
142 ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
143 2);
144
145 /* Sleep Setting */
146
147 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
148 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
149 ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
150 2);
151 } else { 91 } else {
152 /* mac */ 92 /* mac */
153 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 93 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -228,11 +168,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
228 ar9485_modes_lowest_ob_db_tx_gain_1_1, 168 ar9485_modes_lowest_ob_db_tx_gain_1_1,
229 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), 169 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
230 5); 170 5);
231 else if (AR_SREV_9485(ah))
232 INIT_INI_ARRAY(&ah->iniModesTxGain,
233 ar9485Modes_lowest_ob_db_tx_gain_1_0,
234 ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
235 5);
236 else 171 else
237 INIT_INI_ARRAY(&ah->iniModesTxGain, 172 INIT_INI_ARRAY(&ah->iniModesTxGain,
238 ar9300Modes_lowest_ob_db_tx_gain_table_2p2, 173 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
@@ -245,11 +180,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
245 ar9485Modes_high_ob_db_tx_gain_1_1, 180 ar9485Modes_high_ob_db_tx_gain_1_1,
246 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), 181 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
247 5); 182 5);
248 else if (AR_SREV_9485(ah))
249 INIT_INI_ARRAY(&ah->iniModesTxGain,
250 ar9485Modes_high_ob_db_tx_gain_1_0,
251 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0),
252 5);
253 else 183 else
254 INIT_INI_ARRAY(&ah->iniModesTxGain, 184 INIT_INI_ARRAY(&ah->iniModesTxGain,
255 ar9300Modes_high_ob_db_tx_gain_table_2p2, 185 ar9300Modes_high_ob_db_tx_gain_table_2p2,
@@ -262,11 +192,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
262 ar9485Modes_low_ob_db_tx_gain_1_1, 192 ar9485Modes_low_ob_db_tx_gain_1_1,
263 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), 193 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
264 5); 194 5);
265 else if (AR_SREV_9485(ah))
266 INIT_INI_ARRAY(&ah->iniModesTxGain,
267 ar9485Modes_low_ob_db_tx_gain_1_0,
268 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0),
269 5);
270 else 195 else
271 INIT_INI_ARRAY(&ah->iniModesTxGain, 196 INIT_INI_ARRAY(&ah->iniModesTxGain,
272 ar9300Modes_low_ob_db_tx_gain_table_2p2, 197 ar9300Modes_low_ob_db_tx_gain_table_2p2,
@@ -279,11 +204,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
279 ar9485Modes_high_power_tx_gain_1_1, 204 ar9485Modes_high_power_tx_gain_1_1,
280 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), 205 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
281 5); 206 5);
282 else if (AR_SREV_9485(ah))
283 INIT_INI_ARRAY(&ah->iniModesTxGain,
284 ar9485Modes_high_power_tx_gain_1_0,
285 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
286 5);
287 else 207 else
288 INIT_INI_ARRAY(&ah->iniModesTxGain, 208 INIT_INI_ARRAY(&ah->iniModesTxGain,
289 ar9300Modes_high_power_tx_gain_table_2p2, 209 ar9300Modes_high_power_tx_gain_table_2p2,
@@ -300,13 +220,8 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
300 default: 220 default:
301 if (AR_SREV_9485_11(ah)) 221 if (AR_SREV_9485_11(ah))
302 INIT_INI_ARRAY(&ah->iniModesRxGain, 222 INIT_INI_ARRAY(&ah->iniModesRxGain,
303 ar9485_common_rx_gain_1_1, 223 ar9485Common_wo_xlna_rx_gain_1_1,
304 ARRAY_SIZE(ar9485_common_rx_gain_1_1), 224 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
305 2);
306 else if (AR_SREV_9485(ah))
307 INIT_INI_ARRAY(&ah->iniModesRxGain,
308 ar9485Common_rx_gain_1_0,
309 ARRAY_SIZE(ar9485Common_rx_gain_1_0),
310 2); 225 2);
311 else 226 else
312 INIT_INI_ARRAY(&ah->iniModesRxGain, 227 INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -320,11 +235,6 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
320 ar9485Common_wo_xlna_rx_gain_1_1, 235 ar9485Common_wo_xlna_rx_gain_1_1,
321 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 236 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
322 2); 237 2);
323 else if (AR_SREV_9485(ah))
324 INIT_INI_ARRAY(&ah->iniModesRxGain,
325 ar9485Common_wo_xlna_rx_gain_1_0,
326 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),
327 2);
328 else 238 else
329 INIT_INI_ARRAY(&ah->iniModesRxGain, 239 INIT_INI_ARRAY(&ah->iniModesRxGain,
330 ar9300Common_wo_xlna_rx_gain_table_2p2, 240 ar9300Common_wo_xlna_rx_gain_table_2p2,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 038a0cbfc6e7..724ac2464ad5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -485,17 +485,6 @@ static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
485 485
486} 486}
487 487
488static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
489 u32 vmf)
490{
491 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
492
493 if (vmf)
494 ads->ctl11 |= AR_VirtMoreFrag;
495 else
496 ads->ctl11 &= ~AR_VirtMoreFrag;
497}
498
499void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) 488void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
500{ 489{
501 struct ar9003_txc *ads = ds; 490 struct ar9003_txc *ads = ds;
@@ -521,7 +510,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
521 ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; 510 ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
522 ops->clr11n_aggr = ar9003_hw_clr11n_aggr; 511 ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
523 ops->set11n_burstduration = ar9003_hw_set11n_burstduration; 512 ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
524 ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
525} 513}
526 514
527void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) 515void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index 71cc0a3a29fb..f91f73e50d00 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -17,931 +17,6 @@
17#ifndef INITVALS_9485_H 17#ifndef INITVALS_9485_H
18#define INITVALS_9485_H 18#define INITVALS_9485_H
19 19
20static const u32 ar9485Common_1_0[][2] = {
21 /* Addr allmodes */
22 {0x00007010, 0x00000022},
23 {0x00007020, 0x00000000},
24 {0x00007034, 0x00000002},
25 {0x00007038, 0x000004c2},
26};
27
28static const u32 ar9485_1_0_mac_postamble[][5] = {
29 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
30 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
31 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
32 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
33 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
34 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
35 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
36 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
37 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
38};
39
40static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
41 /* Addr allmodes */
42 {0x00018c00, 0x10212e5e},
43 {0x00018c04, 0x000801d8},
44 {0x00018c08, 0x0000580c},
45};
46
47static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = {
48 /* Addr allmodes */
49 {0x0000a000, 0x00010000},
50 {0x0000a004, 0x00030002},
51 {0x0000a008, 0x00050004},
52 {0x0000a00c, 0x00810080},
53 {0x0000a010, 0x01800082},
54 {0x0000a014, 0x01820181},
55 {0x0000a018, 0x01840183},
56 {0x0000a01c, 0x01880185},
57 {0x0000a020, 0x018a0189},
58 {0x0000a024, 0x02850284},
59 {0x0000a028, 0x02890288},
60 {0x0000a02c, 0x03850384},
61 {0x0000a030, 0x03890388},
62 {0x0000a034, 0x038b038a},
63 {0x0000a038, 0x038d038c},
64 {0x0000a03c, 0x03910390},
65 {0x0000a040, 0x03930392},
66 {0x0000a044, 0x03950394},
67 {0x0000a048, 0x00000396},
68 {0x0000a04c, 0x00000000},
69 {0x0000a050, 0x00000000},
70 {0x0000a054, 0x00000000},
71 {0x0000a058, 0x00000000},
72 {0x0000a05c, 0x00000000},
73 {0x0000a060, 0x00000000},
74 {0x0000a064, 0x00000000},
75 {0x0000a068, 0x00000000},
76 {0x0000a06c, 0x00000000},
77 {0x0000a070, 0x00000000},
78 {0x0000a074, 0x00000000},
79 {0x0000a078, 0x00000000},
80 {0x0000a07c, 0x00000000},
81 {0x0000a080, 0x28282828},
82 {0x0000a084, 0x28282828},
83 {0x0000a088, 0x28282828},
84 {0x0000a08c, 0x28282828},
85 {0x0000a090, 0x28282828},
86 {0x0000a094, 0x21212128},
87 {0x0000a098, 0x171c1c1c},
88 {0x0000a09c, 0x02020212},
89 {0x0000a0a0, 0x00000202},
90 {0x0000a0a4, 0x00000000},
91 {0x0000a0a8, 0x00000000},
92 {0x0000a0ac, 0x00000000},
93 {0x0000a0b0, 0x00000000},
94 {0x0000a0b4, 0x00000000},
95 {0x0000a0b8, 0x00000000},
96 {0x0000a0bc, 0x00000000},
97 {0x0000a0c0, 0x001f0000},
98 {0x0000a0c4, 0x111f1100},
99 {0x0000a0c8, 0x111d111e},
100 {0x0000a0cc, 0x111b111c},
101 {0x0000a0d0, 0x22032204},
102 {0x0000a0d4, 0x22012202},
103 {0x0000a0d8, 0x221f2200},
104 {0x0000a0dc, 0x221d221e},
105 {0x0000a0e0, 0x33013302},
106 {0x0000a0e4, 0x331f3300},
107 {0x0000a0e8, 0x4402331e},
108 {0x0000a0ec, 0x44004401},
109 {0x0000a0f0, 0x441e441f},
110 {0x0000a0f4, 0x55015502},
111 {0x0000a0f8, 0x551f5500},
112 {0x0000a0fc, 0x6602551e},
113 {0x0000a100, 0x66006601},
114 {0x0000a104, 0x661e661f},
115 {0x0000a108, 0x7703661d},
116 {0x0000a10c, 0x77017702},
117 {0x0000a110, 0x00007700},
118 {0x0000a114, 0x00000000},
119 {0x0000a118, 0x00000000},
120 {0x0000a11c, 0x00000000},
121 {0x0000a120, 0x00000000},
122 {0x0000a124, 0x00000000},
123 {0x0000a128, 0x00000000},
124 {0x0000a12c, 0x00000000},
125 {0x0000a130, 0x00000000},
126 {0x0000a134, 0x00000000},
127 {0x0000a138, 0x00000000},
128 {0x0000a13c, 0x00000000},
129 {0x0000a140, 0x001f0000},
130 {0x0000a144, 0x111f1100},
131 {0x0000a148, 0x111d111e},
132 {0x0000a14c, 0x111b111c},
133 {0x0000a150, 0x22032204},
134 {0x0000a154, 0x22012202},
135 {0x0000a158, 0x221f2200},
136 {0x0000a15c, 0x221d221e},
137 {0x0000a160, 0x33013302},
138 {0x0000a164, 0x331f3300},
139 {0x0000a168, 0x4402331e},
140 {0x0000a16c, 0x44004401},
141 {0x0000a170, 0x441e441f},
142 {0x0000a174, 0x55015502},
143 {0x0000a178, 0x551f5500},
144 {0x0000a17c, 0x6602551e},
145 {0x0000a180, 0x66006601},
146 {0x0000a184, 0x661e661f},
147 {0x0000a188, 0x7703661d},
148 {0x0000a18c, 0x77017702},
149 {0x0000a190, 0x00007700},
150 {0x0000a194, 0x00000000},
151 {0x0000a198, 0x00000000},
152 {0x0000a19c, 0x00000000},
153 {0x0000a1a0, 0x00000000},
154 {0x0000a1a4, 0x00000000},
155 {0x0000a1a8, 0x00000000},
156 {0x0000a1ac, 0x00000000},
157 {0x0000a1b0, 0x00000000},
158 {0x0000a1b4, 0x00000000},
159 {0x0000a1b8, 0x00000000},
160 {0x0000a1bc, 0x00000000},
161 {0x0000a1c0, 0x00000000},
162 {0x0000a1c4, 0x00000000},
163 {0x0000a1c8, 0x00000000},
164 {0x0000a1cc, 0x00000000},
165 {0x0000a1d0, 0x00000000},
166 {0x0000a1d4, 0x00000000},
167 {0x0000a1d8, 0x00000000},
168 {0x0000a1dc, 0x00000000},
169 {0x0000a1e0, 0x00000000},
170 {0x0000a1e4, 0x00000000},
171 {0x0000a1e8, 0x00000000},
172 {0x0000a1ec, 0x00000000},
173 {0x0000a1f0, 0x00000396},
174 {0x0000a1f4, 0x00000396},
175 {0x0000a1f8, 0x00000396},
176 {0x0000a1fc, 0x00000296},
177};
178
179static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = {
180 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
181 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
182 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
183 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
184 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
185 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
186 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
187 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
188 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
189 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
190 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
191 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
192 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
193 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
194 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
195 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
196 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
197 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
198 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
199 {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
200 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
201 {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
202 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
203 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
204 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
205 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
206 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
207 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
208 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
209 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
210 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
211 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
212 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
213 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
214 {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
215};
216
217static const u32 ar9485_1_0[][2] = {
218 /* Addr allmodes */
219 {0x0000a580, 0x00000000},
220 {0x0000a584, 0x00000000},
221 {0x0000a588, 0x00000000},
222 {0x0000a58c, 0x00000000},
223 {0x0000a590, 0x00000000},
224 {0x0000a594, 0x00000000},
225 {0x0000a598, 0x00000000},
226 {0x0000a59c, 0x00000000},
227 {0x0000a5a0, 0x00000000},
228 {0x0000a5a4, 0x00000000},
229 {0x0000a5a8, 0x00000000},
230 {0x0000a5ac, 0x00000000},
231 {0x0000a5b0, 0x00000000},
232 {0x0000a5b4, 0x00000000},
233 {0x0000a5b8, 0x00000000},
234 {0x0000a5bc, 0x00000000},
235};
236
237static const u32 ar9485_1_0_radio_core[][2] = {
238 /* Addr allmodes */
239 {0x00016000, 0x36db6db6},
240 {0x00016004, 0x6db6db40},
241 {0x00016008, 0x73800000},
242 {0x0001600c, 0x00000000},
243 {0x00016040, 0x7f80fff8},
244 {0x00016048, 0x6c92426e},
245 {0x0001604c, 0x000f0278},
246 {0x00016050, 0x6db6db6c},
247 {0x00016054, 0x6db60000},
248 {0x00016080, 0x00080000},
249 {0x00016084, 0x0e48048c},
250 {0x00016088, 0x14214514},
251 {0x0001608c, 0x119f081e},
252 {0x00016090, 0x24926490},
253 {0x00016098, 0xd28b3330},
254 {0x000160a0, 0xc2108ffe},
255 {0x000160a4, 0x812fc370},
256 {0x000160a8, 0x423c8000},
257 {0x000160b4, 0x92480040},
258 {0x000160c0, 0x006db6db},
259 {0x000160c4, 0x0186db60},
260 {0x000160c8, 0x6db6db6c},
261 {0x000160cc, 0x6de6fbe0},
262 {0x000160d0, 0xf7dfcf3c},
263 {0x00016100, 0x04cb0001},
264 {0x00016104, 0xfff80015},
265 {0x00016108, 0x00080010},
266 {0x00016144, 0x01884080},
267 {0x00016148, 0x00008040},
268 {0x00016180, 0x08453333},
269 {0x00016184, 0x18e82f01},
270 {0x00016188, 0x00000000},
271 {0x0001618c, 0x00000000},
272 {0x00016240, 0x08400000},
273 {0x00016244, 0x1bf90f00},
274 {0x00016248, 0x00000000},
275 {0x0001624c, 0x00000000},
276 {0x00016280, 0x01000015},
277 {0x00016284, 0x00d30000},
278 {0x00016288, 0x00318000},
279 {0x0001628c, 0x50000000},
280 {0x00016290, 0x4b96210f},
281 {0x00016380, 0x00000000},
282 {0x00016384, 0x00000000},
283 {0x00016388, 0x00800700},
284 {0x0001638c, 0x00800700},
285 {0x00016390, 0x00800700},
286 {0x00016394, 0x00000000},
287 {0x00016398, 0x00000000},
288 {0x0001639c, 0x00000000},
289 {0x000163a0, 0x00000001},
290 {0x000163a4, 0x00000001},
291 {0x000163a8, 0x00000000},
292 {0x000163ac, 0x00000000},
293 {0x000163b0, 0x00000000},
294 {0x000163b4, 0x00000000},
295 {0x000163b8, 0x00000000},
296 {0x000163bc, 0x00000000},
297 {0x000163c0, 0x000000a0},
298 {0x000163c4, 0x000c0000},
299 {0x000163c8, 0x14021402},
300 {0x000163cc, 0x00001402},
301 {0x000163d0, 0x00000000},
302 {0x000163d4, 0x00000000},
303 {0x00016c40, 0x1319c178},
304 {0x00016c44, 0x10000000},
305};
306
307static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = {
308 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
309 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
310 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
311 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
312 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
313 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
314 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
315 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
316 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
317 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
318 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
319 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
320 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
321 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
322 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
323 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
324 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
325 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
326 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
327 {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
328 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
329 {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
330 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
331 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
332 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
333 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
334 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
335 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
336 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
337 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
338 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
339 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
340 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
341 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
342 {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
343};
344
345static const u32 ar9485_1_0_baseband_core[][2] = {
346 /* Addr allmodes */
347 {0x00009800, 0xafe68e30},
348 {0x00009804, 0xfd14e000},
349 {0x00009808, 0x9c0a8f6b},
350 {0x0000980c, 0x04800000},
351 {0x00009814, 0x9280c00a},
352 {0x00009818, 0x00000000},
353 {0x0000981c, 0x00020028},
354 {0x00009834, 0x5f3ca3de},
355 {0x00009838, 0x0108ecff},
356 {0x0000983c, 0x14750600},
357 {0x00009880, 0x201fff00},
358 {0x00009884, 0x00001042},
359 {0x000098a4, 0x00200400},
360 {0x000098b0, 0x52440bbe},
361 {0x000098bc, 0x00000002},
362 {0x000098d0, 0x004b6a8e},
363 {0x000098d4, 0x00000820},
364 {0x000098dc, 0x00000000},
365 {0x000098f0, 0x00000000},
366 {0x000098f4, 0x00000000},
367 {0x00009c04, 0x00000000},
368 {0x00009c08, 0x03200000},
369 {0x00009c0c, 0x00000000},
370 {0x00009c10, 0x00000000},
371 {0x00009c14, 0x00046384},
372 {0x00009c18, 0x05b6b440},
373 {0x00009c1c, 0x00b6b440},
374 {0x00009d00, 0xc080a333},
375 {0x00009d04, 0x40206c10},
376 {0x00009d08, 0x009c4060},
377 {0x00009d0c, 0x1883800a},
378 {0x00009d10, 0x01834061},
379 {0x00009d14, 0x00c00400},
380 {0x00009d18, 0x00000000},
381 {0x00009d1c, 0x00000000},
382 {0x00009e08, 0x0038233c},
383 {0x00009e24, 0x990bb515},
384 {0x00009e28, 0x0a6f0000},
385 {0x00009e30, 0x06336f77},
386 {0x00009e34, 0x6af6532f},
387 {0x00009e38, 0x0cc80c00},
388 {0x00009e40, 0x0d261820},
389 {0x00009e4c, 0x00001004},
390 {0x00009e50, 0x00ff03f1},
391 {0x00009fc0, 0x80be4788},
392 {0x00009fc4, 0x0001efb5},
393 {0x00009fcc, 0x40000014},
394 {0x0000a20c, 0x00000000},
395 {0x0000a210, 0x00000000},
396 {0x0000a220, 0x00000000},
397 {0x0000a224, 0x00000000},
398 {0x0000a228, 0x10002310},
399 {0x0000a23c, 0x00000000},
400 {0x0000a244, 0x0c000000},
401 {0x0000a2a0, 0x00000001},
402 {0x0000a2c0, 0x00000001},
403 {0x0000a2c8, 0x00000000},
404 {0x0000a2cc, 0x18c43433},
405 {0x0000a2d4, 0x00000000},
406 {0x0000a2dc, 0x00000000},
407 {0x0000a2e0, 0x00000000},
408 {0x0000a2e4, 0x00000000},
409 {0x0000a2e8, 0x00000000},
410 {0x0000a2ec, 0x00000000},
411 {0x0000a2f0, 0x00000000},
412 {0x0000a2f4, 0x00000000},
413 {0x0000a2f8, 0x00000000},
414 {0x0000a344, 0x00000000},
415 {0x0000a34c, 0x00000000},
416 {0x0000a350, 0x0000a000},
417 {0x0000a364, 0x00000000},
418 {0x0000a370, 0x00000000},
419 {0x0000a390, 0x00000001},
420 {0x0000a394, 0x00000444},
421 {0x0000a398, 0x001f0e0f},
422 {0x0000a39c, 0x0075393f},
423 {0x0000a3a0, 0xb79f6427},
424 {0x0000a3a4, 0x00000000},
425 {0x0000a3a8, 0xaaaaaaaa},
426 {0x0000a3ac, 0x3c466478},
427 {0x0000a3c0, 0x20202020},
428 {0x0000a3c4, 0x22222220},
429 {0x0000a3c8, 0x20200020},
430 {0x0000a3cc, 0x20202020},
431 {0x0000a3d0, 0x20202020},
432 {0x0000a3d4, 0x20202020},
433 {0x0000a3d8, 0x20202020},
434 {0x0000a3dc, 0x20202020},
435 {0x0000a3e0, 0x20202020},
436 {0x0000a3e4, 0x20202020},
437 {0x0000a3e8, 0x20202020},
438 {0x0000a3ec, 0x20202020},
439 {0x0000a3f0, 0x00000000},
440 {0x0000a3f4, 0x00000006},
441 {0x0000a3f8, 0x0cdbd380},
442 {0x0000a3fc, 0x000f0f01},
443 {0x0000a400, 0x8fa91f01},
444 {0x0000a404, 0x00000000},
445 {0x0000a408, 0x0e79e5c6},
446 {0x0000a40c, 0x00820820},
447 {0x0000a414, 0x1ce739ce},
448 {0x0000a418, 0x2d0011ce},
449 {0x0000a41c, 0x1ce739ce},
450 {0x0000a420, 0x000001ce},
451 {0x0000a424, 0x1ce739ce},
452 {0x0000a428, 0x000001ce},
453 {0x0000a42c, 0x1ce739ce},
454 {0x0000a430, 0x1ce739ce},
455 {0x0000a434, 0x00000000},
456 {0x0000a438, 0x00001801},
457 {0x0000a43c, 0x00000000},
458 {0x0000a440, 0x00000000},
459 {0x0000a444, 0x00000000},
460 {0x0000a448, 0x04000000},
461 {0x0000a44c, 0x00000001},
462 {0x0000a450, 0x00010000},
463 {0x0000a458, 0x00000000},
464 {0x0000a5c4, 0x3fad9d74},
465 {0x0000a5c8, 0x0048060a},
466 {0x0000a5cc, 0x00000637},
467 {0x0000a760, 0x03020100},
468 {0x0000a764, 0x09080504},
469 {0x0000a768, 0x0d0c0b0a},
470 {0x0000a76c, 0x13121110},
471 {0x0000a770, 0x31301514},
472 {0x0000a774, 0x35343332},
473 {0x0000a778, 0x00000036},
474 {0x0000a780, 0x00000838},
475 {0x0000a7c0, 0x00000000},
476 {0x0000a7c4, 0xfffffffc},
477 {0x0000a7c8, 0x00000000},
478 {0x0000a7cc, 0x00000000},
479 {0x0000a7d0, 0x00000000},
480 {0x0000a7d4, 0x00000004},
481 {0x0000a7dc, 0x00000001},
482};
483
484static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = {
485 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
486 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
487 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
488 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
489 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
490 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
491 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
492 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
493 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
494 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
495 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
496 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
497 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
498 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
499 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
500 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
501 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
502 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
503 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
504 {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
505 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
506 {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
507 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
508 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
509 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
510 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
511 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
512 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
513 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
514 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
515 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
516 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
517 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
518 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
519 {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
520};
521
522static const u32 ar9485Common_rx_gain_1_0[][2] = {
523 /* Addr allmodes */
524 {0x0000a000, 0x00010000},
525 {0x0000a004, 0x00030002},
526 {0x0000a008, 0x00050004},
527 {0x0000a00c, 0x00810080},
528 {0x0000a010, 0x01800082},
529 {0x0000a014, 0x01820181},
530 {0x0000a018, 0x01840183},
531 {0x0000a01c, 0x01880185},
532 {0x0000a020, 0x018a0189},
533 {0x0000a024, 0x02850284},
534 {0x0000a028, 0x02890288},
535 {0x0000a02c, 0x03850384},
536 {0x0000a030, 0x03890388},
537 {0x0000a034, 0x038b038a},
538 {0x0000a038, 0x038d038c},
539 {0x0000a03c, 0x03910390},
540 {0x0000a040, 0x03930392},
541 {0x0000a044, 0x03950394},
542 {0x0000a048, 0x00000396},
543 {0x0000a04c, 0x00000000},
544 {0x0000a050, 0x00000000},
545 {0x0000a054, 0x00000000},
546 {0x0000a058, 0x00000000},
547 {0x0000a05c, 0x00000000},
548 {0x0000a060, 0x00000000},
549 {0x0000a064, 0x00000000},
550 {0x0000a068, 0x00000000},
551 {0x0000a06c, 0x00000000},
552 {0x0000a070, 0x00000000},
553 {0x0000a074, 0x00000000},
554 {0x0000a078, 0x00000000},
555 {0x0000a07c, 0x00000000},
556 {0x0000a080, 0x28282828},
557 {0x0000a084, 0x28282828},
558 {0x0000a088, 0x28282828},
559 {0x0000a08c, 0x28282828},
560 {0x0000a090, 0x28282828},
561 {0x0000a094, 0x21212128},
562 {0x0000a098, 0x171c1c1c},
563 {0x0000a09c, 0x02020212},
564 {0x0000a0a0, 0x00000202},
565 {0x0000a0a4, 0x00000000},
566 {0x0000a0a8, 0x00000000},
567 {0x0000a0ac, 0x00000000},
568 {0x0000a0b0, 0x00000000},
569 {0x0000a0b4, 0x00000000},
570 {0x0000a0b8, 0x00000000},
571 {0x0000a0bc, 0x00000000},
572 {0x0000a0c0, 0x001f0000},
573 {0x0000a0c4, 0x111f1100},
574 {0x0000a0c8, 0x111d111e},
575 {0x0000a0cc, 0x111b111c},
576 {0x0000a0d0, 0x22032204},
577 {0x0000a0d4, 0x22012202},
578 {0x0000a0d8, 0x221f2200},
579 {0x0000a0dc, 0x221d221e},
580 {0x0000a0e0, 0x33013302},
581 {0x0000a0e4, 0x331f3300},
582 {0x0000a0e8, 0x4402331e},
583 {0x0000a0ec, 0x44004401},
584 {0x0000a0f0, 0x441e441f},
585 {0x0000a0f4, 0x55015502},
586 {0x0000a0f8, 0x551f5500},
587 {0x0000a0fc, 0x6602551e},
588 {0x0000a100, 0x66006601},
589 {0x0000a104, 0x661e661f},
590 {0x0000a108, 0x7703661d},
591 {0x0000a10c, 0x77017702},
592 {0x0000a110, 0x00007700},
593 {0x0000a114, 0x00000000},
594 {0x0000a118, 0x00000000},
595 {0x0000a11c, 0x00000000},
596 {0x0000a120, 0x00000000},
597 {0x0000a124, 0x00000000},
598 {0x0000a128, 0x00000000},
599 {0x0000a12c, 0x00000000},
600 {0x0000a130, 0x00000000},
601 {0x0000a134, 0x00000000},
602 {0x0000a138, 0x00000000},
603 {0x0000a13c, 0x00000000},
604 {0x0000a140, 0x001f0000},
605 {0x0000a144, 0x111f1100},
606 {0x0000a148, 0x111d111e},
607 {0x0000a14c, 0x111b111c},
608 {0x0000a150, 0x22032204},
609 {0x0000a154, 0x22012202},
610 {0x0000a158, 0x221f2200},
611 {0x0000a15c, 0x221d221e},
612 {0x0000a160, 0x33013302},
613 {0x0000a164, 0x331f3300},
614 {0x0000a168, 0x4402331e},
615 {0x0000a16c, 0x44004401},
616 {0x0000a170, 0x441e441f},
617 {0x0000a174, 0x55015502},
618 {0x0000a178, 0x551f5500},
619 {0x0000a17c, 0x6602551e},
620 {0x0000a180, 0x66006601},
621 {0x0000a184, 0x661e661f},
622 {0x0000a188, 0x7703661d},
623 {0x0000a18c, 0x77017702},
624 {0x0000a190, 0x00007700},
625 {0x0000a194, 0x00000000},
626 {0x0000a198, 0x00000000},
627 {0x0000a19c, 0x00000000},
628 {0x0000a1a0, 0x00000000},
629 {0x0000a1a4, 0x00000000},
630 {0x0000a1a8, 0x00000000},
631 {0x0000a1ac, 0x00000000},
632 {0x0000a1b0, 0x00000000},
633 {0x0000a1b4, 0x00000000},
634 {0x0000a1b8, 0x00000000},
635 {0x0000a1bc, 0x00000000},
636 {0x0000a1c0, 0x00000000},
637 {0x0000a1c4, 0x00000000},
638 {0x0000a1c8, 0x00000000},
639 {0x0000a1cc, 0x00000000},
640 {0x0000a1d0, 0x00000000},
641 {0x0000a1d4, 0x00000000},
642 {0x0000a1d8, 0x00000000},
643 {0x0000a1dc, 0x00000000},
644 {0x0000a1e0, 0x00000000},
645 {0x0000a1e4, 0x00000000},
646 {0x0000a1e8, 0x00000000},
647 {0x0000a1ec, 0x00000000},
648 {0x0000a1f0, 0x00000396},
649 {0x0000a1f4, 0x00000396},
650 {0x0000a1f8, 0x00000396},
651 {0x0000a1fc, 0x00000296},
652};
653
654static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
655 /* Addr allmodes */
656 {0x00018c00, 0x10252e5e},
657 {0x00018c04, 0x000801d8},
658 {0x00018c08, 0x0000580c},
659};
660
661static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = {
662 /* Addr allmodes */
663 {0x00018c00, 0x10253e5e},
664 {0x00018c04, 0x000801d8},
665 {0x00018c08, 0x0000580c},
666};
667
668static const u32 ar9485_1_0_soc_preamble[][2] = {
669 /* Addr allmodes */
670 {0x00004090, 0x00aa10aa},
671 {0x000040a4, 0x00a0c9c9},
672 {0x00007048, 0x00000004},
673};
674
675static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = {
676 /* Addr 5G_HT20 5G_HT40 */
677 {0x00009e00, 0x03721821, 0x03721821},
678 {0x0000a230, 0x0000400b, 0x00004016},
679 {0x0000a254, 0x00000898, 0x00001130},
680};
681
682static const u32 ar9485_1_0_baseband_postamble[][5] = {
683 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
684 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
685 {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
686 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
687 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
688 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
689 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
690 {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
691 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
692 {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
693 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
694 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
695 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
696 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
697 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
698 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
699 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
700 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
701 {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
702 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
703 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
704 {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
705 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
706 {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
707 {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
708 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
709 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
710 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
711 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
712 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
713 {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
714 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
715 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
716 {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
717 {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
718 {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
719 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
720 {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
721 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
722 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
723 {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
724 {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
725};
726
727static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = {
728 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
729 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
730 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
731 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
732 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
733 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
734 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
735 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
736 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
737 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
738 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
739 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
740 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
741 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
742 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
743 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
744 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
745 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
746 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
747 {0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
748 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
749 {0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
750 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
751 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
752 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
753 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
754 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
755 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
756 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
757 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
758 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
759 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
760 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
761 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
762 {0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
763};
764
765static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = {
766 /* Addr allmodes */
767 {0x00018c00, 0x10213e5e},
768 {0x00018c04, 0x000801d8},
769 {0x00018c08, 0x0000580c},
770};
771
772static const u32 ar9485_1_0_radio_postamble[][2] = {
773 /* Addr allmodes */
774 {0x0001609c, 0x0b283f31},
775 {0x000160ac, 0x24611800},
776 {0x000160b0, 0x03284f3e},
777 {0x0001610c, 0x00170000},
778 {0x00016140, 0x10804008},
779};
780
781static const u32 ar9485_1_0_mac_core[][2] = {
782 /* Addr allmodes */
783 {0x00000008, 0x00000000},
784 {0x00000030, 0x00020085},
785 {0x00000034, 0x00000005},
786 {0x00000040, 0x00000000},
787 {0x00000044, 0x00000000},
788 {0x00000048, 0x00000008},
789 {0x0000004c, 0x00000010},
790 {0x00000050, 0x00000000},
791 {0x00001040, 0x002ffc0f},
792 {0x00001044, 0x002ffc0f},
793 {0x00001048, 0x002ffc0f},
794 {0x0000104c, 0x002ffc0f},
795 {0x00001050, 0x002ffc0f},
796 {0x00001054, 0x002ffc0f},
797 {0x00001058, 0x002ffc0f},
798 {0x0000105c, 0x002ffc0f},
799 {0x00001060, 0x002ffc0f},
800 {0x00001064, 0x002ffc0f},
801 {0x000010f0, 0x00000100},
802 {0x00001270, 0x00000000},
803 {0x000012b0, 0x00000000},
804 {0x000012f0, 0x00000000},
805 {0x0000143c, 0x00000000},
806 {0x0000147c, 0x00000000},
807 {0x00008000, 0x00000000},
808 {0x00008004, 0x00000000},
809 {0x00008008, 0x00000000},
810 {0x0000800c, 0x00000000},
811 {0x00008018, 0x00000000},
812 {0x00008020, 0x00000000},
813 {0x00008038, 0x00000000},
814 {0x0000803c, 0x00000000},
815 {0x00008040, 0x00000000},
816 {0x00008044, 0x00000000},
817 {0x00008048, 0x00000000},
818 {0x0000804c, 0xffffffff},
819 {0x00008054, 0x00000000},
820 {0x00008058, 0x00000000},
821 {0x0000805c, 0x000fc78f},
822 {0x00008060, 0x0000000f},
823 {0x00008064, 0x00000000},
824 {0x00008070, 0x00000310},
825 {0x00008074, 0x00000020},
826 {0x00008078, 0x00000000},
827 {0x0000809c, 0x0000000f},
828 {0x000080a0, 0x00000000},
829 {0x000080a4, 0x02ff0000},
830 {0x000080a8, 0x0e070605},
831 {0x000080ac, 0x0000000d},
832 {0x000080b0, 0x00000000},
833 {0x000080b4, 0x00000000},
834 {0x000080b8, 0x00000000},
835 {0x000080bc, 0x00000000},
836 {0x000080c0, 0x2a800000},
837 {0x000080c4, 0x06900168},
838 {0x000080c8, 0x13881c20},
839 {0x000080cc, 0x01f40000},
840 {0x000080d0, 0x00252500},
841 {0x000080d4, 0x00a00000},
842 {0x000080d8, 0x00400000},
843 {0x000080dc, 0x00000000},
844 {0x000080e0, 0xffffffff},
845 {0x000080e4, 0x0000ffff},
846 {0x000080e8, 0x3f3f3f3f},
847 {0x000080ec, 0x00000000},
848 {0x000080f0, 0x00000000},
849 {0x000080f4, 0x00000000},
850 {0x000080fc, 0x00020000},
851 {0x00008100, 0x00000000},
852 {0x00008108, 0x00000052},
853 {0x0000810c, 0x00000000},
854 {0x00008110, 0x00000000},
855 {0x00008114, 0x000007ff},
856 {0x00008118, 0x000000aa},
857 {0x0000811c, 0x00003210},
858 {0x00008124, 0x00000000},
859 {0x00008128, 0x00000000},
860 {0x0000812c, 0x00000000},
861 {0x00008130, 0x00000000},
862 {0x00008134, 0x00000000},
863 {0x00008138, 0x00000000},
864 {0x0000813c, 0x0000ffff},
865 {0x00008144, 0xffffffff},
866 {0x00008168, 0x00000000},
867 {0x0000816c, 0x00000000},
868 {0x00008170, 0x18486200},
869 {0x00008174, 0x33332210},
870 {0x00008178, 0x00000000},
871 {0x0000817c, 0x00020000},
872 {0x000081c0, 0x00000000},
873 {0x000081c4, 0x33332210},
874 {0x000081c8, 0x00000000},
875 {0x000081cc, 0x00000000},
876 {0x000081d4, 0x00000000},
877 {0x000081ec, 0x00000000},
878 {0x000081f0, 0x00000000},
879 {0x000081f4, 0x00000000},
880 {0x000081f8, 0x00000000},
881 {0x000081fc, 0x00000000},
882 {0x00008240, 0x00100000},
883 {0x00008244, 0x0010f400},
884 {0x00008248, 0x00000800},
885 {0x0000824c, 0x0001e800},
886 {0x00008250, 0x00000000},
887 {0x00008254, 0x00000000},
888 {0x00008258, 0x00000000},
889 {0x0000825c, 0x40000000},
890 {0x00008260, 0x00080922},
891 {0x00008264, 0x9ca00010},
892 {0x00008268, 0xffffffff},
893 {0x0000826c, 0x0000ffff},
894 {0x00008270, 0x00000000},
895 {0x00008274, 0x40000000},
896 {0x00008278, 0x003e4180},
897 {0x0000827c, 0x00000004},
898 {0x00008284, 0x0000002c},
899 {0x00008288, 0x0000002c},
900 {0x0000828c, 0x000000ff},
901 {0x00008294, 0x00000000},
902 {0x00008298, 0x00000000},
903 {0x0000829c, 0x00000000},
904 {0x00008300, 0x00000140},
905 {0x00008314, 0x00000000},
906 {0x0000831c, 0x0000010d},
907 {0x00008328, 0x00000000},
908 {0x0000832c, 0x00000007},
909 {0x00008330, 0x00000302},
910 {0x00008334, 0x00000700},
911 {0x00008338, 0x00ff0000},
912 {0x0000833c, 0x02400000},
913 {0x00008340, 0x000107ff},
914 {0x00008344, 0xa248105b},
915 {0x00008348, 0x008f0000},
916 {0x0000835c, 0x00000000},
917 {0x00008360, 0xffffffff},
918 {0x00008364, 0xffffffff},
919 {0x00008368, 0x00000000},
920 {0x00008370, 0x00000000},
921 {0x00008374, 0x000000ff},
922 {0x00008378, 0x00000000},
923 {0x0000837c, 0x00000000},
924 {0x00008380, 0xffffffff},
925 {0x00008384, 0xffffffff},
926 {0x00008390, 0xffffffff},
927 {0x00008394, 0xffffffff},
928 {0x00008398, 0x00000000},
929 {0x0000839c, 0x00000000},
930 {0x000083a0, 0x00000000},
931 {0x000083a4, 0x0000fa14},
932 {0x000083a8, 0x000f0c00},
933 {0x000083ac, 0x33332210},
934 {0x000083b0, 0x33332210},
935 {0x000083b4, 0x33332210},
936 {0x000083b8, 0x33332210},
937 {0x000083bc, 0x00000000},
938 {0x000083c0, 0x00000000},
939 {0x000083c4, 0x00000000},
940 {0x000083c8, 0x00000000},
941 {0x000083cc, 0x00000200},
942 {0x000083d0, 0x000301ff},
943};
944
945static const u32 ar9485_1_1_mac_core[][2] = { 20static const u32 ar9485_1_1_mac_core[][2] = {
946 /* Addr allmodes */ 21 /* Addr allmodes */
947 {0x00000008, 0x00000000}, 22 {0x00000008, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 099bd4183ad0..38835bc324b2 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -120,13 +120,11 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
120/* RX / TX */ 120/* RX / TX */
121/***********/ 121/***********/
122 122
123#define ATH_MAX_ANTENNA 3
124#define ATH_RXBUF 512 123#define ATH_RXBUF 512
125#define ATH_TXBUF 512 124#define ATH_TXBUF 512
126#define ATH_TXBUF_RESERVE 5 125#define ATH_TXBUF_RESERVE 5
127#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) 126#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
128#define ATH_TXMAXTRY 13 127#define ATH_TXMAXTRY 13
129#define ATH_MGT_TXMAXTRY 4
130 128
131#define TID_TO_WME_AC(_tid) \ 129#define TID_TO_WME_AC(_tid) \
132 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ 130 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
@@ -346,11 +344,9 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
346 344
347struct ath_vif { 345struct ath_vif {
348 int av_bslot; 346 int av_bslot;
349 bool is_bslot_active; 347 bool is_bslot_active, primary_sta_vif;
350 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ 348 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
351 enum nl80211_iftype av_opmode;
352 struct ath_buf *av_bcbuf; 349 struct ath_buf *av_bcbuf;
353 u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
354}; 350};
355 351
356/*******************/ 352/*******************/
@@ -362,7 +358,7 @@ struct ath_vif {
362 * number of BSSIDs) if a given beacon does not go out even after waiting this 358 * number of BSSIDs) if a given beacon does not go out even after waiting this
363 * number of beacon intervals, the game's up. 359 * number of beacon intervals, the game's up.
364 */ 360 */
365#define BSTUCK_THRESH (9 * ATH_BCBUF) 361#define BSTUCK_THRESH 9
366#define ATH_BCBUF 4 362#define ATH_BCBUF 4
367#define ATH_DEFAULT_BINTVAL 100 /* TU */ 363#define ATH_DEFAULT_BINTVAL 100 /* TU */
368#define ATH_DEFAULT_BMISS_LIMIT 10 364#define ATH_DEFAULT_BMISS_LIMIT 10
@@ -386,7 +382,7 @@ struct ath_beacon {
386 u32 beaconq; 382 u32 beaconq;
387 u32 bmisscnt; 383 u32 bmisscnt;
388 u32 ast_be_xmit; 384 u32 ast_be_xmit;
389 u64 bc_tstamp; 385 u32 bc_tstamp;
390 struct ieee80211_vif *bslot[ATH_BCBUF]; 386 struct ieee80211_vif *bslot[ATH_BCBUF];
391 int slottime; 387 int slottime;
392 int slotupdate; 388 int slotupdate;
@@ -401,6 +397,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
401int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); 397int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif);
402void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); 398void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
403int ath_beaconq_config(struct ath_softc *sc); 399int ath_beaconq_config(struct ath_softc *sc);
400void ath_set_beacon(struct ath_softc *sc);
404void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); 401void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
405 402
406/*******/ 403/*******/
@@ -550,6 +547,7 @@ struct ath_ant_comb {
550#define SC_OP_BT_SCAN BIT(13) 547#define SC_OP_BT_SCAN BIT(13)
551#define SC_OP_ANI_RUN BIT(14) 548#define SC_OP_ANI_RUN BIT(14)
552#define SC_OP_ENABLE_APM BIT(15) 549#define SC_OP_ENABLE_APM BIT(15)
550#define SC_OP_PRIM_STA_VIF BIT(16)
553 551
554/* Powersave flags */ 552/* Powersave flags */
555#define PS_WAIT_FOR_BEACON BIT(0) 553#define PS_WAIT_FOR_BEACON BIT(0)
@@ -688,8 +686,6 @@ void ath9k_ps_restore(struct ath_softc *sc);
688 686
689u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); 687u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
690 688
691void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
692
693void ath_start_rfkill_poll(struct ath_softc *sc); 689void ath_start_rfkill_poll(struct ath_softc *sc);
694extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); 690extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
695void ath9k_calculate_iter_data(struct ieee80211_hw *hw, 691void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 6d2a545fc35e..eccb0ec87adb 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -57,8 +57,8 @@ int ath_beaconq_config(struct ath_softc *sc)
57 57
58/* 58/*
59 * Associates the beacon frame buffer with a transmit descriptor. Will set 59 * Associates the beacon frame buffer with a transmit descriptor. Will set
60 * up all required antenna switch parameters, rate codes, and channel flags. 60 * up rate codes, and channel flags. Beacons are always sent out at the
61 * Beacons are always sent out at the lowest rate, and are not retried. 61 * lowest rate, and are not retried.
62*/ 62*/
63static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, 63static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
64 struct ath_buf *bf, int rateidx) 64 struct ath_buf *bf, int rateidx)
@@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
68 struct ath_common *common = ath9k_hw_common(ah); 68 struct ath_common *common = ath9k_hw_common(ah);
69 struct ath_desc *ds; 69 struct ath_desc *ds;
70 struct ath9k_11n_rate_series series[4]; 70 struct ath9k_11n_rate_series series[4];
71 int flags, antenna, ctsrate = 0, ctsduration = 0; 71 int flags, ctsrate = 0, ctsduration = 0;
72 struct ieee80211_supported_band *sband; 72 struct ieee80211_supported_band *sband;
73 u8 rate = 0; 73 u8 rate = 0;
74 74
@@ -76,12 +76,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
76 flags = ATH9K_TXDESC_NOACK; 76 flags = ATH9K_TXDESC_NOACK;
77 77
78 ds->ds_link = 0; 78 ds->ds_link = 0;
79 /*
80 * Switch antenna every beacon.
81 * Should only switch every beacon period, not for every SWBA
82 * XXX assumes two antennae
83 */
84 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
85 79
86 sband = &sc->sbands[common->hw->conf.channel->band]; 80 sband = &sc->sbands[common->hw->conf.channel->band];
87 rate = sband->bitrates[rateidx].hw_value; 81 rate = sband->bitrates[rateidx].hw_value;
@@ -278,7 +272,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
278 return -ENOMEM; 272 return -ENOMEM;
279 273
280 tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 274 tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
281 sc->beacon.bc_tstamp = le64_to_cpu(tstamp); 275 sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp);
282 /* Calculate a TSF adjustment factor required for staggered beacons. */ 276 /* Calculate a TSF adjustment factor required for staggered beacons. */
283 if (avp->av_bslot > 0) { 277 if (avp->av_bslot > 0) {
284 u64 tsfadjust; 278 u64 tsfadjust;
@@ -294,8 +288,8 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
294 * adjustment. Other slots are adjusted to get the timestamp 288 * adjustment. Other slots are adjusted to get the timestamp
295 * close to the TBTT for the BSS. 289 * close to the TBTT for the BSS.
296 */ 290 */
297 tsfadjust = intval * avp->av_bslot / ATH_BCBUF; 291 tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF;
298 avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); 292 avp->tsf_adjust = cpu_to_le64(tsfadjust);
299 293
300 ath_dbg(common, ATH_DBG_BEACON, 294 ath_dbg(common, ATH_DBG_BEACON,
301 "stagger beacons, bslot %d intval %u tsfadjust %llu\n", 295 "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
@@ -329,6 +323,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
329 if (avp->av_bslot != -1) { 323 if (avp->av_bslot != -1) {
330 sc->beacon.bslot[avp->av_bslot] = NULL; 324 sc->beacon.bslot[avp->av_bslot] = NULL;
331 sc->nbcnvifs--; 325 sc->nbcnvifs--;
326 avp->av_bslot = -1;
332 } 327 }
333 328
334 bf = avp->av_bcbuf; 329 bf = avp->av_bcbuf;
@@ -369,12 +364,13 @@ void ath_beacon_tasklet(unsigned long data)
369 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { 364 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
370 sc->beacon.bmisscnt++; 365 sc->beacon.bmisscnt++;
371 366
372 if (sc->beacon.bmisscnt < BSTUCK_THRESH) { 367 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
373 ath_dbg(common, ATH_DBG_BSTUCK, 368 ath_dbg(common, ATH_DBG_BSTUCK,
374 "missed %u consecutive beacons\n", 369 "missed %u consecutive beacons\n",
375 sc->beacon.bmisscnt); 370 sc->beacon.bmisscnt);
376 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); 371 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
377 ath9k_hw_bstuck_nfcal(ah); 372 if (sc->beacon.bmisscnt > 3)
373 ath9k_hw_bstuck_nfcal(ah);
378 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { 374 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
379 ath_dbg(common, ATH_DBG_BSTUCK, 375 ath_dbg(common, ATH_DBG_BSTUCK,
380 "beacon is officially stuck\n"); 376 "beacon is officially stuck\n");
@@ -385,13 +381,6 @@ void ath_beacon_tasklet(unsigned long data)
385 return; 381 return;
386 } 382 }
387 383
388 if (sc->beacon.bmisscnt != 0) {
389 ath_dbg(common, ATH_DBG_BSTUCK,
390 "resume beacon xmit after %u misses\n",
391 sc->beacon.bmisscnt);
392 sc->beacon.bmisscnt = 0;
393 }
394
395 /* 384 /*
396 * Generate beacon frames. we are sending frames 385 * Generate beacon frames. we are sending frames
397 * staggered so calculate the slot for this frame based 386 * staggered so calculate the slot for this frame based
@@ -401,21 +390,14 @@ void ath_beacon_tasklet(unsigned long data)
401 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; 390 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
402 391
403 tsf = ath9k_hw_gettsf64(ah); 392 tsf = ath9k_hw_gettsf64(ah);
404 tsftu = TSF_TO_TU(tsf>>32, tsf); 393 tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
405 slot = ((tsftu % intval) * ATH_BCBUF) / intval; 394 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
406 /* 395 slot = (tsftu % (intval * ATH_BCBUF)) / intval;
407 * Reverse the slot order to get slot 0 on the TBTT offset that does
408 * not require TSF adjustment and other slots adding
409 * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
410 * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
411 * and slot 0 is at correct offset to TBTT.
412 */
413 slot = ATH_BCBUF - slot - 1;
414 vif = sc->beacon.bslot[slot]; 396 vif = sc->beacon.bslot[slot];
415 397
416 ath_dbg(common, ATH_DBG_BEACON, 398 ath_dbg(common, ATH_DBG_BEACON,
417 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", 399 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
418 slot, tsf, tsftu, intval, vif); 400 slot, tsf, tsftu / ATH_BCBUF, intval, vif);
419 401
420 bfaddr = 0; 402 bfaddr = 0;
421 if (vif) { 403 if (vif) {
@@ -424,6 +406,13 @@ void ath_beacon_tasklet(unsigned long data)
424 bfaddr = bf->bf_daddr; 406 bfaddr = bf->bf_daddr;
425 bc = 1; 407 bc = 1;
426 } 408 }
409
410 if (sc->beacon.bmisscnt != 0) {
411 ath_dbg(common, ATH_DBG_BSTUCK,
412 "resume beacon xmit after %u misses\n",
413 sc->beacon.bmisscnt);
414 sc->beacon.bmisscnt = 0;
415 }
427 } 416 }
428 417
429 /* 418 /*
@@ -463,13 +452,17 @@ static void ath9k_beacon_init(struct ath_softc *sc,
463 u32 next_beacon, 452 u32 next_beacon,
464 u32 beacon_period) 453 u32 beacon_period)
465{ 454{
466 if (beacon_period & ATH9K_BEACON_RESET_TSF) 455 if (sc->sc_flags & SC_OP_TSF_RESET) {
467 ath9k_ps_wakeup(sc); 456 ath9k_ps_wakeup(sc);
457 ath9k_hw_reset_tsf(sc->sc_ah);
458 }
468 459
469 ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); 460 ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
470 461
471 if (beacon_period & ATH9K_BEACON_RESET_TSF) 462 if (sc->sc_flags & SC_OP_TSF_RESET) {
472 ath9k_ps_restore(sc); 463 ath9k_ps_restore(sc);
464 sc->sc_flags &= ~SC_OP_TSF_RESET;
465 }
473} 466}
474 467
475/* 468/*
@@ -484,18 +477,14 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
484 u32 nexttbtt, intval; 477 u32 nexttbtt, intval;
485 478
486 /* NB: the beacon interval is kept internally in TU's */ 479 /* NB: the beacon interval is kept internally in TU's */
487 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 480 intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
488 intval /= ATH_BCBUF; /* for staggered beacons */ 481 intval /= ATH_BCBUF; /* for staggered beacons */
489 nexttbtt = intval; 482 nexttbtt = intval;
490 483
491 if (sc->sc_flags & SC_OP_TSF_RESET)
492 intval |= ATH9K_BEACON_RESET_TSF;
493
494 /* 484 /*
495 * In AP mode we enable the beacon timers and SWBA interrupts to 485 * In AP mode we enable the beacon timers and SWBA interrupts to
496 * prepare beacon frames. 486 * prepare beacon frames.
497 */ 487 */
498 intval |= ATH9K_BEACON_ENA;
499 ah->imask |= ATH9K_INT_SWBA; 488 ah->imask |= ATH9K_INT_SWBA;
500 ath_beaconq_config(sc); 489 ath_beaconq_config(sc);
501 490
@@ -505,11 +494,6 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
505 ath9k_beacon_init(sc, nexttbtt, intval); 494 ath9k_beacon_init(sc, nexttbtt, intval);
506 sc->beacon.bmisscnt = 0; 495 sc->beacon.bmisscnt = 0;
507 ath9k_hw_set_interrupts(ah, ah->imask); 496 ath9k_hw_set_interrupts(ah, ah->imask);
508
509 /* Clear the reset TSF flag, so that subsequent beacon updation
510 will not reset the HW TSF. */
511
512 sc->sc_flags &= ~SC_OP_TSF_RESET;
513} 497}
514 498
515/* 499/*
@@ -643,25 +627,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
643{ 627{
644 struct ath_hw *ah = sc->sc_ah; 628 struct ath_hw *ah = sc->sc_ah;
645 struct ath_common *common = ath9k_hw_common(ah); 629 struct ath_common *common = ath9k_hw_common(ah);
646 u64 tsf; 630 u32 tsf, delta, intval, nexttbtt;
647 u32 tsftu, intval, nexttbtt; 631
648 632 tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
649 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 633 intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
650 634
651 635 if (!sc->beacon.bc_tstamp)
652 /* Pull nexttbtt forward to reflect the current TSF */ 636 nexttbtt = tsf + intval;
653 637 else {
654 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); 638 if (tsf > sc->beacon.bc_tstamp)
655 if (nexttbtt == 0) 639 delta = (tsf - sc->beacon.bc_tstamp);
656 nexttbtt = intval; 640 else
657 else if (intval) 641 delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
658 nexttbtt = roundup(nexttbtt, intval); 642 nexttbtt = tsf + roundup(delta, intval);
659 643 }
660 tsf = ath9k_hw_gettsf64(ah);
661 tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
662 do {
663 nexttbtt += intval;
664 } while (nexttbtt < tsftu);
665 644
666 ath_dbg(common, ATH_DBG_BEACON, 645 ath_dbg(common, ATH_DBG_BEACON,
667 "IBSS nexttbtt %u intval %u (%u)\n", 646 "IBSS nexttbtt %u intval %u (%u)\n",
@@ -672,7 +651,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
672 * if we need to manually prepare beacon frames. Otherwise we use a 651 * if we need to manually prepare beacon frames. Otherwise we use a
673 * self-linked tx descriptor and let the hardware deal with things. 652 * self-linked tx descriptor and let the hardware deal with things.
674 */ 653 */
675 intval |= ATH9K_BEACON_ENA;
676 ah->imask |= ATH9K_INT_SWBA; 654 ah->imask |= ATH9K_INT_SWBA;
677 655
678 ath_beaconq_config(sc); 656 ath_beaconq_config(sc);
@@ -685,22 +663,63 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
685 ath9k_hw_set_interrupts(ah, ah->imask); 663 ath9k_hw_set_interrupts(ah, ah->imask);
686} 664}
687 665
688void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) 666static bool ath9k_allow_beacon_config(struct ath_softc *sc,
667 struct ieee80211_vif *vif)
689{ 668{
690 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 669 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
691 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 670 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
692 enum nl80211_iftype iftype; 671 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
672 struct ath_vif *avp = (void *)vif->drv_priv;
693 673
694 /* Setup the beacon configuration parameters */ 674 /*
695 if (vif) { 675 * Can not have different beacon interval on multiple
696 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 676 * AP interface case
697 iftype = vif->type; 677 */
698 cur_conf->beacon_interval = bss_conf->beacon_int; 678 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
699 cur_conf->dtim_period = bss_conf->dtim_period; 679 (sc->nbcnvifs > 1) &&
700 } else { 680 (vif->type == NL80211_IFTYPE_AP) &&
701 iftype = sc->sc_ah->opmode; 681 (cur_conf->beacon_interval != bss_conf->beacon_int)) {
682 ath_dbg(common, ATH_DBG_CONFIG,
683 "Changing beacon interval of multiple \
684 AP interfaces !\n");
685 return false;
702 } 686 }
687 /*
688 * Can not configure station vif's beacon config
689 * while on AP opmode
690 */
691 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
692 (vif->type != NL80211_IFTYPE_AP)) {
693 ath_dbg(common, ATH_DBG_CONFIG,
694 "STA vif's beacon not allowed on AP mode\n");
695 return false;
696 }
697 /*
698 * Do not allow beacon config if HW was already configured
699 * with another STA vif
700 */
701 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
702 (vif->type == NL80211_IFTYPE_STATION) &&
703 (sc->sc_flags & SC_OP_BEACONS) &&
704 !avp->primary_sta_vif) {
705 ath_dbg(common, ATH_DBG_CONFIG,
706 "Beacon already configured for a station interface\n");
707 return false;
708 }
709 return true;
710}
711
712void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
713{
714 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
715 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
716
717 if (!ath9k_allow_beacon_config(sc, vif))
718 return;
703 719
720 /* Setup the beacon configuration parameters */
721 cur_conf->beacon_interval = bss_conf->beacon_int;
722 cur_conf->dtim_period = bss_conf->dtim_period;
704 cur_conf->listen_interval = 1; 723 cur_conf->listen_interval = 1;
705 cur_conf->dtim_count = 1; 724 cur_conf->dtim_count = 1;
706 cur_conf->bmiss_timeout = 725 cur_conf->bmiss_timeout =
@@ -723,7 +742,16 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
723 if (cur_conf->dtim_period == 0) 742 if (cur_conf->dtim_period == 0)
724 cur_conf->dtim_period = 1; 743 cur_conf->dtim_period = 1;
725 744
726 switch (iftype) { 745 ath_set_beacon(sc);
746 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
747}
748
749void ath_set_beacon(struct ath_softc *sc)
750{
751 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
752 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
753
754 switch (sc->sc_ah->opmode) {
727 case NL80211_IFTYPE_AP: 755 case NL80211_IFTYPE_AP:
728 ath_beacon_config_ap(sc, cur_conf); 756 ath_beacon_config_ap(sc, cur_conf);
729 break; 757 break;
@@ -750,22 +778,23 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
750 int slot; 778 int slot;
751 bool found = false; 779 bool found = false;
752 780
753 ath9k_ps_wakeup(sc); 781 for (slot = 0; slot < ATH_BCBUF; slot++) {
754 if (status) { 782 if (sc->beacon.bslot[slot]) {
755 for (slot = 0; slot < ATH_BCBUF; slot++) { 783 avp = (void *)sc->beacon.bslot[slot]->drv_priv;
756 if (sc->beacon.bslot[slot]) { 784 if (avp->is_bslot_active) {
757 avp = (void *)sc->beacon.bslot[slot]->drv_priv; 785 found = true;
758 if (avp->is_bslot_active) { 786 break;
759 found = true;
760 break;
761 }
762 } 787 }
763 } 788 }
764 if (found) { 789 }
765 /* Re-enable beaconing */ 790 if (!found)
766 ah->imask |= ATH9K_INT_SWBA; 791 return;
767 ath9k_hw_set_interrupts(ah, ah->imask); 792
768 } 793 ath9k_ps_wakeup(sc);
794 if (status) {
795 /* Re-enable beaconing */
796 ah->imask |= ATH9K_INT_SWBA;
797 ath9k_hw_set_interrupts(ah, ah->imask);
769 } else { 798 } else {
770 /* Disable SWBA interrupt */ 799 /* Disable SWBA interrupt */
771 ah->imask &= ~ATH9K_INT_SWBA; 800 ah->imask &= ~ATH9K_INT_SWBA;
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 615e68276e72..16ba8c67fbd5 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -116,7 +116,7 @@ void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
116 116
117 if (chan->band == IEEE80211_BAND_2GHZ) { 117 if (chan->band == IEEE80211_BAND_2GHZ) {
118 ichan->chanmode = CHANNEL_G; 118 ichan->chanmode = CHANNEL_G;
119 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G; 119 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
120 } else { 120 } else {
121 ichan->chanmode = CHANNEL_A; 121 ichan->chanmode = CHANNEL_A;
122 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; 122 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 8df5a92a20f1..a762cadb3ab7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1088,67 +1088,43 @@ int ath9k_init_debug(struct ath_hw *ah)
1088 return -ENOMEM; 1088 return -ENOMEM;
1089 1089
1090#ifdef CONFIG_ATH_DEBUG 1090#ifdef CONFIG_ATH_DEBUG
1091 if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR, 1091 debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1092 sc->debug.debugfs_phy, sc, &fops_debug)) 1092 sc, &fops_debug);
1093 goto err;
1094#endif 1093#endif
1095 1094 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
1096 if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, 1095 &fops_dma);
1097 sc, &fops_dma)) 1096 debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
1098 goto err; 1097 &fops_interrupt);
1099 1098 debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1100 if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, 1099 sc, &fops_wiphy);
1101 sc, &fops_interrupt)) 1100 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
1102 goto err; 1101 &fops_xmit);
1103 1102 debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
1104 if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, 1103 &fops_stations);
1105 sc->debug.debugfs_phy, sc, &fops_wiphy)) 1104 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
1106 goto err; 1105 &fops_misc);
1107 1106 debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
1108 if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, 1107 &fops_recv);
1109 sc, &fops_xmit)) 1108 debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
1110 goto err; 1109 sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
1111 1110 debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
1112 if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, 1111 sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
1113 sc, &fops_stations)) 1112 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1114 goto err; 1113 sc, &fops_regidx);
1115 1114 debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1116 if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, 1115 sc, &fops_regval);
1117 sc, &fops_misc)) 1116 debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
1118 goto err; 1117 sc->debug.debugfs_phy,
1119 1118 &ah->config.cwm_ignore_extcca);
1120 if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, 1119 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
1121 sc, &fops_recv)) 1120 &fops_regdump);
1122 goto err; 1121
1123 1122 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1124 if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, 1123 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
1125 sc->debug.debugfs_phy, sc, &fops_rx_chainmask)) 1124
1126 goto err; 1125 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
1127 1126 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
1128 if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
1129 sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
1130 goto err;
1131
1132 if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
1133 sc->debug.debugfs_phy, sc, &fops_regidx))
1134 goto err;
1135
1136 if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
1137 sc->debug.debugfs_phy, sc, &fops_regval))
1138 goto err;
1139
1140 if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
1141 sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
1142 goto err;
1143
1144 if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy,
1145 sc, &fops_regdump))
1146 goto err;
1147 1127
1148 sc->debug.regidx = 0; 1128 sc->debug.regidx = 0;
1149 return 0; 1129 return 0;
1150err:
1151 debugfs_remove_recursive(sc->debug.debugfs_phy);
1152 sc->debug.debugfs_phy = NULL;
1153 return -ENOMEM;
1154} 1130}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 8cd8333cc086..2f0712ea49a6 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -392,6 +392,8 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
392 numXpdGain); 392 numXpdGain);
393 } 393 }
394 394
395 ENABLE_REGWRITE_BUFFER(ah);
396
395 if (i == 0) { 397 if (i == 0) {
396 if (!ath9k_hw_ar9287_get_eeprom(ah, 398 if (!ath9k_hw_ar9287_get_eeprom(ah,
397 EEP_OL_PWRCTRL)) { 399 EEP_OL_PWRCTRL)) {
@@ -442,6 +444,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
442 regOffset += 4; 444 regOffset += 4;
443 } 445 }
444 } 446 }
447 REGWRITE_BUFFER_FLUSH(ah);
445 } 448 }
446 } 449 }
447 450
@@ -757,6 +760,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
757 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; 760 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
758 } 761 }
759 762
763 ENABLE_REGWRITE_BUFFER(ah);
764
760 /* OFDM power per rate */ 765 /* OFDM power per rate */
761 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 766 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
762 ATH9K_POW_SM(ratesArray[rate18mb], 24) 767 ATH9K_POW_SM(ratesArray[rate18mb], 24)
@@ -840,6 +845,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
840 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 845 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
841 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 846 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
842 } 847 }
848 REGWRITE_BUFFER_FLUSH(ah);
843} 849}
844 850
845static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, 851static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index fccd87df7300..995949ddd63e 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -799,6 +799,8 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
799 pwr_table_offset, 799 pwr_table_offset,
800 &diff); 800 &diff);
801 801
802 ENABLE_REGWRITE_BUFFER(ah);
803
802 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 804 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
803 if (OLC_FOR_AR9280_20_LATER) { 805 if (OLC_FOR_AR9280_20_LATER) {
804 REG_WRITE(ah, 806 REG_WRITE(ah,
@@ -847,6 +849,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
847 849
848 regOffset += 4; 850 regOffset += 4;
849 } 851 }
852 REGWRITE_BUFFER_FLUSH(ah);
850 } 853 }
851 } 854 }
852 855
@@ -1205,6 +1208,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1205 } 1208 }
1206 } 1209 }
1207 1210
1211 ENABLE_REGWRITE_BUFFER(ah);
1212
1208 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 1213 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1209 ATH9K_POW_SM(ratesArray[rate18mb], 24) 1214 ATH9K_POW_SM(ratesArray[rate18mb], 24)
1210 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 1215 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
@@ -1291,6 +1296,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1291 REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1296 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1292 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1297 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1293 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 1298 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1299
1300 REGWRITE_BUFFER_FLUSH(ah);
1294} 1301}
1295 1302
1296static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1303static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 0fb8f8ac275a..44a0a886124d 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -41,12 +41,14 @@ void ath_init_leds(struct ath_softc *sc)
41{ 41{
42 int ret; 42 int ret;
43 43
44 if (AR_SREV_9287(sc->sc_ah)) 44 if (sc->sc_ah->led_pin < 0) {
45 sc->sc_ah->led_pin = ATH_LED_PIN_9287; 45 if (AR_SREV_9287(sc->sc_ah))
46 else if (AR_SREV_9485(sc->sc_ah)) 46 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
47 sc->sc_ah->led_pin = ATH_LED_PIN_9485; 47 else if (AR_SREV_9485(sc->sc_ah))
48 else 48 sc->sc_ah->led_pin = ATH_LED_PIN_9485;
49 sc->sc_ah->led_pin = ATH_LED_PIN_DEF; 49 else
50 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
51 }
50 52
51 /* Configure gpio 1 for output */ 53 /* Configure gpio 1 for output */
52 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, 54 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 753a245c5ad1..ec47be94b74f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -328,7 +328,7 @@ struct ath9k_debug {
328#endif /* CONFIG_ATH9K_HTC_DEBUGFS */ 328#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
329 329
330#define ATH_LED_PIN_DEF 1 330#define ATH_LED_PIN_DEF 1
331#define ATH_LED_PIN_9287 8 331#define ATH_LED_PIN_9287 10
332#define ATH_LED_PIN_9271 15 332#define ATH_LED_PIN_9271 15
333#define ATH_LED_PIN_7010 12 333#define ATH_LED_PIN_7010 12
334#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ 334#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 8d1d8792436d..8f56158e5887 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -155,7 +155,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
155 nexttbtt = intval; 155 nexttbtt = intval;
156 156
157 if (priv->op_flags & OP_TSF_RESET) { 157 if (priv->op_flags & OP_TSF_RESET) {
158 intval |= ATH9K_BEACON_RESET_TSF; 158 ath9k_hw_reset_tsf(priv->ah);
159 priv->op_flags &= ~OP_TSF_RESET; 159 priv->op_flags &= ~OP_TSF_RESET;
160 } else { 160 } else {
161 /* 161 /*
@@ -168,8 +168,6 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
168 } while (nexttbtt < tsftu); 168 } while (nexttbtt < tsftu);
169 } 169 }
170 170
171 intval |= ATH9K_BEACON_ENA;
172
173 if (priv->op_flags & OP_ENABLE_BEACON) 171 if (priv->op_flags & OP_ENABLE_BEACON)
174 imask |= ATH9K_INT_SWBA; 172 imask |= ATH9K_INT_SWBA;
175 173
@@ -178,7 +176,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
178 bss_conf->beacon_interval, nexttbtt, imask); 176 bss_conf->beacon_interval, nexttbtt, imask);
179 177
180 WMI_CMD(WMI_DISABLE_INTR_CMDID); 178 WMI_CMD(WMI_DISABLE_INTR_CMDID);
181 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); 179 ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
182 priv->bmiss_cnt = 0; 180 priv->bmiss_cnt = 0;
183 htc_imask = cpu_to_be32(imask); 181 htc_imask = cpu_to_be32(imask);
184 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); 182 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
@@ -207,7 +205,6 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
207 nexttbtt += intval; 205 nexttbtt += intval;
208 } while (nexttbtt < tsftu); 206 } while (nexttbtt < tsftu);
209 207
210 intval |= ATH9K_BEACON_ENA;
211 if (priv->op_flags & OP_ENABLE_BEACON) 208 if (priv->op_flags & OP_ENABLE_BEACON)
212 imask |= ATH9K_INT_SWBA; 209 imask |= ATH9K_INT_SWBA;
213 210
@@ -216,7 +213,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
216 bss_conf->beacon_interval, nexttbtt, imask); 213 bss_conf->beacon_interval, nexttbtt, imask);
217 214
218 WMI_CMD(WMI_DISABLE_INTR_CMDID); 215 WMI_CMD(WMI_DISABLE_INTR_CMDID);
219 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); 216 ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
220 priv->bmiss_cnt = 0; 217 priv->bmiss_cnt = 0;
221 htc_imask = cpu_to_be32(imask); 218 htc_imask = cpu_to_be32(imask);
222 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); 219 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index fc67c937e172..8303b34bdc90 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -430,13 +430,16 @@ static void ath9k_regwrite_flush(void *hw_priv)
430 mutex_unlock(&priv->wmi->multi_write_mutex); 430 mutex_unlock(&priv->wmi->multi_write_mutex);
431} 431}
432 432
433static const struct ath_ops ath9k_common_ops = { 433static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
434 .read = ath9k_regread, 434{
435 .multi_read = ath9k_multi_regread, 435 u32 val;
436 .write = ath9k_regwrite, 436
437 .enable_write_buffer = ath9k_enable_regwrite_buffer, 437 val = ath9k_regread(hw_priv, reg_offset);
438 .write_flush = ath9k_regwrite_flush, 438 val &= ~clr;
439}; 439 val |= set;
440 ath9k_regwrite(hw_priv, val, reg_offset);
441 return val;
442}
440 443
441static void ath_usb_read_cachesize(struct ath_common *common, int *csz) 444static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
442{ 445{
@@ -561,13 +564,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
561 int i = 0; 564 int i = 0;
562 565
563 /* Get the hardware key cache size. */ 566 /* Get the hardware key cache size. */
564 common->keymax = priv->ah->caps.keycache_size; 567 common->keymax = AR_KEYTABLE_SIZE;
565 if (common->keymax > ATH_KEYMAX) {
566 ath_dbg(common, ATH_DBG_ANY,
567 "Warning, using only %u entries in %u key cache\n",
568 ATH_KEYMAX, common->keymax);
569 common->keymax = ATH_KEYMAX;
570 }
571 568
572 if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) 569 if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
573 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; 570 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
@@ -658,10 +655,16 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
658 ah->hw_version.subsysid = 0; /* FIXME */ 655 ah->hw_version.subsysid = 0; /* FIXME */
659 ah->hw_version.usbdev = drv_info; 656 ah->hw_version.usbdev = drv_info;
660 ah->ah_flags |= AH_USE_EEPROM; 657 ah->ah_flags |= AH_USE_EEPROM;
658 ah->reg_ops.read = ath9k_regread;
659 ah->reg_ops.multi_read = ath9k_multi_regread;
660 ah->reg_ops.write = ath9k_regwrite;
661 ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
662 ah->reg_ops.write_flush = ath9k_regwrite_flush;
663 ah->reg_ops.rmw = ath9k_reg_rmw;
661 priv->ah = ah; 664 priv->ah = ah;
662 665
663 common = ath9k_hw_common(ah); 666 common = ath9k_hw_common(ah);
664 common->ops = &ath9k_common_ops; 667 common->ops = &ah->reg_ops;
665 common->bus_ops = &ath9k_usb_bus_ops; 668 common->bus_ops = &ath9k_usb_bus_ops;
666 common->ah = ah; 669 common->ah = ah;
667 common->hw = priv->hw; 670 common->hw = priv->hw;
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index c8f254fe0f0b..22ee888b0baf 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -122,12 +122,6 @@ static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
122 ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); 122 ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
123} 123}
124 124
125static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
126 u32 vmf)
127{
128 ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
129}
130
131/* Private hardware call ops */ 125/* Private hardware call ops */
132 126
133/* PHY ops */ 127/* PHY ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1ec9bcd6b281..1b5bd13b0a6c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -130,6 +130,20 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
130} 130}
131EXPORT_SYMBOL(ath9k_hw_wait); 131EXPORT_SYMBOL(ath9k_hw_wait);
132 132
133void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
134 int column, unsigned int *writecnt)
135{
136 int r;
137
138 ENABLE_REGWRITE_BUFFER(ah);
139 for (r = 0; r < array->ia_rows; r++) {
140 REG_WRITE(ah, INI_RA(array, r, 0),
141 INI_RA(array, r, column));
142 DO_DELAY(*writecnt);
143 }
144 REGWRITE_BUFFER_FLUSH(ah);
145}
146
133u32 ath9k_hw_reverse_bits(u32 val, u32 n) 147u32 ath9k_hw_reverse_bits(u32 val, u32 n)
134{ 148{
135 u32 retval; 149 u32 retval;
@@ -142,25 +156,6 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n)
142 return retval; 156 return retval;
143} 157}
144 158
145bool ath9k_get_channel_edges(struct ath_hw *ah,
146 u16 flags, u16 *low,
147 u16 *high)
148{
149 struct ath9k_hw_capabilities *pCap = &ah->caps;
150
151 if (flags & CHANNEL_5GHZ) {
152 *low = pCap->low_5ghz_chan;
153 *high = pCap->high_5ghz_chan;
154 return true;
155 }
156 if ((flags & CHANNEL_2GHZ)) {
157 *low = pCap->low_2ghz_chan;
158 *high = pCap->high_2ghz_chan;
159 return true;
160 }
161 return false;
162}
163
164u16 ath9k_hw_computetxtime(struct ath_hw *ah, 159u16 ath9k_hw_computetxtime(struct ath_hw *ah,
165 u8 phy, int kbps, 160 u8 phy, int kbps,
166 u32 frameLen, u16 rateix, 161 u32 frameLen, u16 rateix,
@@ -364,11 +359,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
364 ah->config.spurchans[i][1] = AR_NO_SPUR; 359 ah->config.spurchans[i][1] = AR_NO_SPUR;
365 } 360 }
366 361
367 if (ah->hw_version.devid != AR2427_DEVID_PCIE)
368 ah->config.ht_enable = 1;
369 else
370 ah->config.ht_enable = 0;
371
372 /* PAPRD needs some more work to be enabled */ 362 /* PAPRD needs some more work to be enabled */
373 ah->config.paprd_disable = 1; 363 ah->config.paprd_disable = 1;
374 364
@@ -410,6 +400,8 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
410 ah->sta_id1_defaults = 400 ah->sta_id1_defaults =
411 AR_STA_ID1_CRPT_MIC_ENABLE | 401 AR_STA_ID1_CRPT_MIC_ENABLE |
412 AR_STA_ID1_MCAST_KSRCH; 402 AR_STA_ID1_MCAST_KSRCH;
403 if (AR_SREV_9100(ah))
404 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
413 ah->enable_32kHz_clock = DONT_USE_32KHZ; 405 ah->enable_32kHz_clock = DONT_USE_32KHZ;
414 ah->slottime = 20; 406 ah->slottime = 20;
415 ah->globaltxtimeout = (u32) -1; 407 ah->globaltxtimeout = (u32) -1;
@@ -673,14 +665,14 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
673 665
674unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) 666unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
675{ 667{
676 REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK))); 668 REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
677 udelay(100); 669 udelay(100);
678 REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK)); 670 REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
679 671
680 while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) 672 while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
681 udelay(100); 673 udelay(100);
682 674
683 return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; 675 return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
684} 676}
685EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); 677EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
686 678
@@ -830,8 +822,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
830 ah->misc_mode); 822 ah->misc_mode);
831 823
832 if (ah->misc_mode != 0) 824 if (ah->misc_mode != 0)
833 REG_WRITE(ah, AR_PCU_MISC, 825 REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
834 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
835 826
836 if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) 827 if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
837 sifstime = 16; 828 sifstime = 16;
@@ -899,23 +890,19 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
899static inline void ath9k_hw_set_dma(struct ath_hw *ah) 890static inline void ath9k_hw_set_dma(struct ath_hw *ah)
900{ 891{
901 struct ath_common *common = ath9k_hw_common(ah); 892 struct ath_common *common = ath9k_hw_common(ah);
902 u32 regval;
903 893
904 ENABLE_REGWRITE_BUFFER(ah); 894 ENABLE_REGWRITE_BUFFER(ah);
905 895
906 /* 896 /*
907 * set AHB_MODE not to do cacheline prefetches 897 * set AHB_MODE not to do cacheline prefetches
908 */ 898 */
909 if (!AR_SREV_9300_20_OR_LATER(ah)) { 899 if (!AR_SREV_9300_20_OR_LATER(ah))
910 regval = REG_READ(ah, AR_AHB_MODE); 900 REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
911 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
912 }
913 901
914 /* 902 /*
915 * let mac dma reads be in 128 byte chunks 903 * let mac dma reads be in 128 byte chunks
916 */ 904 */
917 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; 905 REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK);
918 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
919 906
920 REGWRITE_BUFFER_FLUSH(ah); 907 REGWRITE_BUFFER_FLUSH(ah);
921 908
@@ -932,8 +919,7 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
932 /* 919 /*
933 * let mac dma writes be in 128 byte chunks 920 * let mac dma writes be in 128 byte chunks
934 */ 921 */
935 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; 922 REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK);
936 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
937 923
938 /* 924 /*
939 * Setup receive FIFO threshold to hold off TX activities 925 * Setup receive FIFO threshold to hold off TX activities
@@ -972,30 +958,27 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
972 958
973static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) 959static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
974{ 960{
975 u32 val; 961 u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
962 u32 set = AR_STA_ID1_KSRCH_MODE;
976 963
977 val = REG_READ(ah, AR_STA_ID1);
978 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
979 switch (opmode) { 964 switch (opmode) {
980 case NL80211_IFTYPE_AP:
981 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
982 | AR_STA_ID1_KSRCH_MODE);
983 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
984 break;
985 case NL80211_IFTYPE_ADHOC: 965 case NL80211_IFTYPE_ADHOC:
986 case NL80211_IFTYPE_MESH_POINT: 966 case NL80211_IFTYPE_MESH_POINT:
987 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC 967 set |= AR_STA_ID1_ADHOC;
988 | AR_STA_ID1_KSRCH_MODE);
989 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 968 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
990 break; 969 break;
970 case NL80211_IFTYPE_AP:
971 set |= AR_STA_ID1_STA_AP;
972 /* fall through */
991 case NL80211_IFTYPE_STATION: 973 case NL80211_IFTYPE_STATION:
992 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); 974 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
993 break; 975 break;
994 default: 976 default:
995 if (ah->is_monitoring) 977 if (!ah->is_monitoring)
996 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); 978 set = 0;
997 break; 979 break;
998 } 980 }
981 REG_RMW(ah, AR_STA_ID1, set, mask);
999} 982}
1000 983
1001void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, 984void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1021,10 +1004,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1021 u32 tmpReg; 1004 u32 tmpReg;
1022 1005
1023 if (AR_SREV_9100(ah)) { 1006 if (AR_SREV_9100(ah)) {
1024 u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK); 1007 REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK,
1025 val &= ~AR_RTC_DERIVED_CLK_PERIOD; 1008 AR_RTC_DERIVED_CLK_PERIOD, 1);
1026 val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
1027 REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
1028 (void)REG_READ(ah, AR_RTC_DERIVED_CLK); 1009 (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
1029 } 1010 }
1030 1011
@@ -1212,6 +1193,20 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1212 return true; 1193 return true;
1213} 1194}
1214 1195
1196static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
1197{
1198 u32 gpio_mask = ah->gpio_mask;
1199 int i;
1200
1201 for (i = 0; gpio_mask; i++, gpio_mask >>= 1) {
1202 if (!(gpio_mask & 1))
1203 continue;
1204
1205 ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1206 ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
1207 }
1208}
1209
1215bool ath9k_hw_check_alive(struct ath_hw *ah) 1210bool ath9k_hw_check_alive(struct ath_hw *ah)
1216{ 1211{
1217 int count = 50; 1212 int count = 50;
@@ -1418,7 +1413,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1418 REGWRITE_BUFFER_FLUSH(ah); 1413 REGWRITE_BUFFER_FLUSH(ah);
1419 1414
1420 ah->intr_txqs = 0; 1415 ah->intr_txqs = 0;
1421 for (i = 0; i < ah->caps.total_queues; i++) 1416 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1422 ath9k_hw_resettxqueue(ah, i); 1417 ath9k_hw_resettxqueue(ah, i);
1423 1418
1424 ath9k_hw_init_interrupt_masks(ah, ah->opmode); 1419 ath9k_hw_init_interrupt_masks(ah, ah->opmode);
@@ -1435,8 +1430,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1435 ar9002_hw_enable_wep_aggregation(ah); 1430 ar9002_hw_enable_wep_aggregation(ah);
1436 } 1431 }
1437 1432
1438 REG_WRITE(ah, AR_STA_ID1, 1433 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
1439 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
1440 1434
1441 ath9k_hw_set_dma(ah); 1435 ath9k_hw_set_dma(ah);
1442 1436
@@ -1500,6 +1494,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1500 if (AR_SREV_9300_20_OR_LATER(ah)) 1494 if (AR_SREV_9300_20_OR_LATER(ah))
1501 ar9003_hw_bb_watchdog_config(ah); 1495 ar9003_hw_bb_watchdog_config(ah);
1502 1496
1497 ath9k_hw_apply_gpio_override(ah);
1498
1503 return 0; 1499 return 0;
1504} 1500}
1505EXPORT_SYMBOL(ath9k_hw_reset); 1501EXPORT_SYMBOL(ath9k_hw_reset);
@@ -1679,21 +1675,15 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
1679 case NL80211_IFTYPE_MESH_POINT: 1675 case NL80211_IFTYPE_MESH_POINT:
1680 REG_SET_BIT(ah, AR_TXCFG, 1676 REG_SET_BIT(ah, AR_TXCFG,
1681 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 1677 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
1682 REG_WRITE(ah, AR_NEXT_NDP_TIMER, 1678 REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
1683 TU_TO_USEC(next_beacon + 1679 TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
1684 (ah->atim_window ? ah->
1685 atim_window : 1)));
1686 flags |= AR_NDP_TIMER_EN; 1680 flags |= AR_NDP_TIMER_EN;
1687 case NL80211_IFTYPE_AP: 1681 case NL80211_IFTYPE_AP:
1688 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); 1682 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
1689 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 1683 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
1690 TU_TO_USEC(next_beacon - 1684 TU_TO_USEC(ah->config.dma_beacon_response_time));
1691 ah->config. 1685 REG_WRITE(ah, AR_NEXT_SWBA, next_beacon -
1692 dma_beacon_response_time)); 1686 TU_TO_USEC(ah->config.sw_beacon_response_time));
1693 REG_WRITE(ah, AR_NEXT_SWBA,
1694 TU_TO_USEC(next_beacon -
1695 ah->config.
1696 sw_beacon_response_time));
1697 flags |= 1687 flags |=
1698 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; 1688 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
1699 break; 1689 break;
@@ -1705,18 +1695,13 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
1705 break; 1695 break;
1706 } 1696 }
1707 1697
1708 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); 1698 REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
1709 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period)); 1699 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
1710 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); 1700 REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
1711 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); 1701 REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
1712 1702
1713 REGWRITE_BUFFER_FLUSH(ah); 1703 REGWRITE_BUFFER_FLUSH(ah);
1714 1704
1715 beacon_period &= ~ATH9K_BEACON_ENA;
1716 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
1717 ath9k_hw_reset_tsf(ah);
1718 }
1719
1720 REG_SET_BIT(ah, AR_TIMER_MODE, flags); 1705 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
1721} 1706}
1722EXPORT_SYMBOL(ath9k_hw_beaconinit); 1707EXPORT_SYMBOL(ath9k_hw_beaconinit);
@@ -1851,6 +1836,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1851 !(AR_SREV_9271(ah))) 1836 !(AR_SREV_9271(ah)))
1852 /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */ 1837 /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
1853 pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; 1838 pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
1839 else if (AR_SREV_9100(ah))
1840 pCap->rx_chainmask = 0x7;
1854 else 1841 else
1855 /* Use rx_chainmask from EEPROM. */ 1842 /* Use rx_chainmask from EEPROM. */
1856 pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); 1843 pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
@@ -1861,36 +1848,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1861 if (AR_SREV_9300_20_OR_LATER(ah)) 1848 if (AR_SREV_9300_20_OR_LATER(ah))
1862 ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH; 1849 ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
1863 1850
1864 pCap->low_2ghz_chan = 2312;
1865 pCap->high_2ghz_chan = 2732;
1866
1867 pCap->low_5ghz_chan = 4920;
1868 pCap->high_5ghz_chan = 6100;
1869
1870 common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; 1851 common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
1871 1852
1872 if (ah->config.ht_enable) 1853 if (ah->hw_version.devid != AR2427_DEVID_PCIE)
1873 pCap->hw_caps |= ATH9K_HW_CAP_HT; 1854 pCap->hw_caps |= ATH9K_HW_CAP_HT;
1874 else 1855 else
1875 pCap->hw_caps &= ~ATH9K_HW_CAP_HT; 1856 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
1876 1857
1877 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
1878 pCap->total_queues =
1879 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
1880 else
1881 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
1882
1883 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
1884 pCap->keycache_size =
1885 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
1886 else
1887 pCap->keycache_size = AR_KEYTABLE_SIZE;
1888
1889 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
1890 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
1891 else
1892 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
1893
1894 if (AR_SREV_9271(ah)) 1858 if (AR_SREV_9271(ah))
1895 pCap->num_gpio_pins = AR9271_NUM_GPIO; 1859 pCap->num_gpio_pins = AR9271_NUM_GPIO;
1896 else if (AR_DEVID_7010(ah)) 1860 else if (AR_DEVID_7010(ah))
@@ -1909,8 +1873,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1909 pCap->rts_aggr_limit = (8 * 1024); 1873 pCap->rts_aggr_limit = (8 * 1024);
1910 } 1874 }
1911 1875
1912 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
1913
1914#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 1876#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1915 ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); 1877 ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
1916 if (ah->rfsilent & EEP_RFSILENT_ENABLED) { 1878 if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
@@ -1932,23 +1894,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1932 else 1894 else
1933 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; 1895 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
1934 1896
1935 if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
1936 pCap->reg_cap =
1937 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
1938 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
1939 AR_EEPROM_EEREGCAP_EN_KK_U2 |
1940 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
1941 } else {
1942 pCap->reg_cap =
1943 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
1944 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
1945 }
1946
1947 /* Advertise midband for AR5416 with FCC midband set in eeprom */
1948 if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) &&
1949 AR_SREV_5416(ah))
1950 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
1951
1952 if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { 1897 if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
1953 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; 1898 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
1954 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; 1899 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
@@ -2195,11 +2140,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
2195 REG_WRITE(ah, AR_PHY_ERR, phybits); 2140 REG_WRITE(ah, AR_PHY_ERR, phybits);
2196 2141
2197 if (phybits) 2142 if (phybits)
2198 REG_WRITE(ah, AR_RXCFG, 2143 REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
2199 REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
2200 else 2144 else
2201 REG_WRITE(ah, AR_RXCFG, 2145 REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
2202 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
2203 2146
2204 REGWRITE_BUFFER_FLUSH(ah); 2147 REGWRITE_BUFFER_FLUSH(ah);
2205} 2148}
@@ -2375,10 +2318,11 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
2375 return timer_table->gen_timer_index[b]; 2318 return timer_table->gen_timer_index[b];
2376} 2319}
2377 2320
2378static u32 ath9k_hw_gettsf32(struct ath_hw *ah) 2321u32 ath9k_hw_gettsf32(struct ath_hw *ah)
2379{ 2322{
2380 return REG_READ(ah, AR_TSF_L32); 2323 return REG_READ(ah, AR_TSF_L32);
2381} 2324}
2325EXPORT_SYMBOL(ath9k_hw_gettsf32);
2382 2326
2383struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 2327struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
2384 void (*trigger)(void *), 2328 void (*trigger)(void *),
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 6650fd48415c..a778b66f4438 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -65,53 +65,49 @@
65 65
66/* Register read/write primitives */ 66/* Register read/write primitives */
67#define REG_WRITE(_ah, _reg, _val) \ 67#define REG_WRITE(_ah, _reg, _val) \
68 ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) 68 (_ah)->reg_ops.write((_ah), (_val), (_reg))
69 69
70#define REG_READ(_ah, _reg) \ 70#define REG_READ(_ah, _reg) \
71 ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) 71 (_ah)->reg_ops.read((_ah), (_reg))
72 72
73#define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ 73#define REG_READ_MULTI(_ah, _addr, _val, _cnt) \
74 ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt)) 74 (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
75
76#define REG_RMW(_ah, _reg, _set, _clr) \
77 (_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr))
75 78
76#define ENABLE_REGWRITE_BUFFER(_ah) \ 79#define ENABLE_REGWRITE_BUFFER(_ah) \
77 do { \ 80 do { \
78 if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ 81 if ((_ah)->reg_ops.enable_write_buffer) \
79 ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ 82 (_ah)->reg_ops.enable_write_buffer((_ah)); \
80 } while (0) 83 } while (0)
81 84
82#define REGWRITE_BUFFER_FLUSH(_ah) \ 85#define REGWRITE_BUFFER_FLUSH(_ah) \
83 do { \ 86 do { \
84 if (ath9k_hw_common(_ah)->ops->write_flush) \ 87 if ((_ah)->reg_ops.write_flush) \
85 ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ 88 (_ah)->reg_ops.write_flush((_ah)); \
86 } while (0) 89 } while (0)
87 90
88#define SM(_v, _f) (((_v) << _f##_S) & _f) 91#define SM(_v, _f) (((_v) << _f##_S) & _f)
89#define MS(_v, _f) (((_v) & _f) >> _f##_S) 92#define MS(_v, _f) (((_v) & _f) >> _f##_S)
90#define REG_RMW(_a, _r, _set, _clr) \
91 REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
92#define REG_RMW_FIELD(_a, _r, _f, _v) \ 93#define REG_RMW_FIELD(_a, _r, _f, _v) \
93 REG_WRITE(_a, _r, \ 94 REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f))
94 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
95#define REG_READ_FIELD(_a, _r, _f) \ 95#define REG_READ_FIELD(_a, _r, _f) \
96 (((REG_READ(_a, _r) & _f) >> _f##_S)) 96 (((REG_READ(_a, _r) & _f) >> _f##_S))
97#define REG_SET_BIT(_a, _r, _f) \ 97#define REG_SET_BIT(_a, _r, _f) \
98 REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f)) 98 REG_RMW(_a, _r, (_f), 0)
99#define REG_CLR_BIT(_a, _r, _f) \ 99#define REG_CLR_BIT(_a, _r, _f) \
100 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f)) 100 REG_RMW(_a, _r, 0, (_f))
101 101
102#define DO_DELAY(x) do { \ 102#define DO_DELAY(x) do { \
103 if ((++(x) % 64) == 0) \ 103 if (((++(x) % 64) == 0) && \
104 udelay(1); \ 104 (ath9k_hw_common(ah)->bus_ops->ath_bus_type \
105 != ATH_USB)) \
106 udelay(1); \
105 } while (0) 107 } while (0)
106 108
107#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ 109#define REG_WRITE_ARRAY(iniarray, column, regWr) \
108 int r; \ 110 ath9k_hw_write_array(ah, iniarray, column, &(regWr))
109 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
110 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
111 INI_RA((iniarray), r, (column))); \
112 DO_DELAY(regWr); \
113 } \
114 } while (0)
115 111
116#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 112#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
117#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 113#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -178,7 +174,6 @@ enum ath9k_hw_caps {
178 ATH9K_HW_CAP_HT = BIT(0), 174 ATH9K_HW_CAP_HT = BIT(0),
179 ATH9K_HW_CAP_RFSILENT = BIT(1), 175 ATH9K_HW_CAP_RFSILENT = BIT(1),
180 ATH9K_HW_CAP_CST = BIT(2), 176 ATH9K_HW_CAP_CST = BIT(2),
181 ATH9K_HW_CAP_ENHANCEDPM = BIT(3),
182 ATH9K_HW_CAP_AUTOSLEEP = BIT(4), 177 ATH9K_HW_CAP_AUTOSLEEP = BIT(4),
183 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5), 178 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5),
184 ATH9K_HW_CAP_EDMA = BIT(6), 179 ATH9K_HW_CAP_EDMA = BIT(6),
@@ -195,17 +190,11 @@ enum ath9k_hw_caps {
195 190
196struct ath9k_hw_capabilities { 191struct ath9k_hw_capabilities {
197 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ 192 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
198 u16 total_queues;
199 u16 keycache_size;
200 u16 low_5ghz_chan, high_5ghz_chan;
201 u16 low_2ghz_chan, high_2ghz_chan;
202 u16 rts_aggr_limit; 193 u16 rts_aggr_limit;
203 u8 tx_chainmask; 194 u8 tx_chainmask;
204 u8 rx_chainmask; 195 u8 rx_chainmask;
205 u8 max_txchains; 196 u8 max_txchains;
206 u8 max_rxchains; 197 u8 max_rxchains;
207 u16 tx_triglevel_max;
208 u16 reg_cap;
209 u8 num_gpio_pins; 198 u8 num_gpio_pins;
210 u8 rx_hp_qdepth; 199 u8 rx_hp_qdepth;
211 u8 rx_lp_qdepth; 200 u8 rx_lp_qdepth;
@@ -227,7 +216,6 @@ struct ath9k_ops_config {
227 u8 pcie_clock_req; 216 u8 pcie_clock_req;
228 u32 pcie_waen; 217 u32 pcie_waen;
229 u8 analog_shiftreg; 218 u8 analog_shiftreg;
230 u8 ht_enable;
231 u8 paprd_disable; 219 u8 paprd_disable;
232 u32 ofdm_trig_low; 220 u32 ofdm_trig_low;
233 u32 ofdm_trig_high; 221 u32 ofdm_trig_high;
@@ -412,8 +400,6 @@ struct ath9k_beacon_state {
412 u32 bs_nextdtim; 400 u32 bs_nextdtim;
413 u32 bs_intval; 401 u32 bs_intval;
414#define ATH9K_BEACON_PERIOD 0x0000ffff 402#define ATH9K_BEACON_PERIOD 0x0000ffff
415#define ATH9K_BEACON_ENA 0x00800000
416#define ATH9K_BEACON_RESET_TSF 0x01000000
417#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ 403#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
418 u32 bs_dtimperiod; 404 u32 bs_dtimperiod;
419 u16 bs_cfpperiod; 405 u16 bs_cfpperiod;
@@ -640,8 +626,6 @@ struct ath_hw_ops {
640 void (*clr11n_aggr)(struct ath_hw *ah, void *ds); 626 void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
641 void (*set11n_burstduration)(struct ath_hw *ah, void *ds, 627 void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
642 u32 burstDuration); 628 u32 burstDuration);
643 void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
644 u32 vmf);
645}; 629};
646 630
647struct ath_nf_limits { 631struct ath_nf_limits {
@@ -655,6 +639,8 @@ struct ath_nf_limits {
655#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ 639#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
656 640
657struct ath_hw { 641struct ath_hw {
642 struct ath_ops reg_ops;
643
658 struct ieee80211_hw *hw; 644 struct ieee80211_hw *hw;
659 struct ath_common common; 645 struct ath_common common;
660 struct ath9k_hw_version hw_version; 646 struct ath9k_hw_version hw_version;
@@ -794,7 +780,9 @@ struct ath_hw {
794 u32 originalGain[22]; 780 u32 originalGain[22];
795 int initPDADC; 781 int initPDADC;
796 int PDADCdelta; 782 int PDADCdelta;
797 u8 led_pin; 783 int led_pin;
784 u32 gpio_mask;
785 u32 gpio_val;
798 786
799 struct ar5416IniArray iniModes; 787 struct ar5416IniArray iniModes;
800 struct ar5416IniArray iniCommon; 788 struct ar5416IniArray iniCommon;
@@ -907,8 +895,9 @@ void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
907 895
908/* General Operation */ 896/* General Operation */
909bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); 897bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
898void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
899 int column, unsigned int *writecnt);
910u32 ath9k_hw_reverse_bits(u32 val, u32 n); 900u32 ath9k_hw_reverse_bits(u32 val, u32 n);
911bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
912u16 ath9k_hw_computetxtime(struct ath_hw *ah, 901u16 ath9k_hw_computetxtime(struct ath_hw *ah,
913 u8 phy, int kbps, 902 u8 phy, int kbps,
914 u32 frameLen, u16 rateix, bool shortPreamble); 903 u32 frameLen, u16 rateix, bool shortPreamble);
@@ -924,6 +913,7 @@ void ath9k_hw_setopmode(struct ath_hw *ah);
924void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); 913void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
925void ath9k_hw_setbssidmask(struct ath_hw *ah); 914void ath9k_hw_setbssidmask(struct ath_hw *ah);
926void ath9k_hw_write_associd(struct ath_hw *ah); 915void ath9k_hw_write_associd(struct ath_hw *ah);
916u32 ath9k_hw_gettsf32(struct ath_hw *ah);
927u64 ath9k_hw_gettsf64(struct ath_hw *ah); 917u64 ath9k_hw_gettsf64(struct ath_hw *ah);
928void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); 918void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
929void ath9k_hw_reset_tsf(struct ath_hw *ah); 919void ath9k_hw_reset_tsf(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 79aec983279f..1ac8318d82a3 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/ath9k_platform.h>
18 19
19#include "ath9k.h" 20#include "ath9k.h"
20 21
@@ -195,10 +196,27 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
195 return val; 196 return val;
196} 197}
197 198
198static const struct ath_ops ath9k_common_ops = { 199static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
199 .read = ath9k_ioread32, 200{
200 .write = ath9k_iowrite32, 201 struct ath_hw *ah = (struct ath_hw *) hw_priv;
201}; 202 struct ath_common *common = ath9k_hw_common(ah);
203 struct ath_softc *sc = (struct ath_softc *) common->priv;
204 unsigned long uninitialized_var(flags);
205 u32 val;
206
207 if (ah->config.serialize_regmode == SER_REG_MODE_ON)
208 spin_lock_irqsave(&sc->sc_serial_rw, flags);
209
210 val = ioread32(sc->mem + reg_offset);
211 val &= ~clr;
212 val |= set;
213 iowrite32(val, sc->mem + reg_offset);
214
215 if (ah->config.serialize_regmode == SER_REG_MODE_ON)
216 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
217
218 return val;
219}
202 220
203/**************************/ 221/**************************/
204/* Initialization */ 222/* Initialization */
@@ -389,13 +407,7 @@ void ath9k_init_crypto(struct ath_softc *sc)
389 int i = 0; 407 int i = 0;
390 408
391 /* Get the hardware key cache size. */ 409 /* Get the hardware key cache size. */
392 common->keymax = sc->sc_ah->caps.keycache_size; 410 common->keymax = AR_KEYTABLE_SIZE;
393 if (common->keymax > ATH_KEYMAX) {
394 ath_dbg(common, ATH_DBG_ANY,
395 "Warning, using only %u entries in %u key cache\n",
396 ATH_KEYMAX, common->keymax);
397 common->keymax = ATH_KEYMAX;
398 }
399 411
400 /* 412 /*
401 * Reset the key cache since some parts do not 413 * Reset the key cache since some parts do not
@@ -537,6 +549,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
537static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, 549static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
538 const struct ath_bus_ops *bus_ops) 550 const struct ath_bus_ops *bus_ops)
539{ 551{
552 struct ath9k_platform_data *pdata = sc->dev->platform_data;
540 struct ath_hw *ah = NULL; 553 struct ath_hw *ah = NULL;
541 struct ath_common *common; 554 struct ath_common *common;
542 int ret = 0, i; 555 int ret = 0, i;
@@ -549,13 +562,22 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
549 ah->hw = sc->hw; 562 ah->hw = sc->hw;
550 ah->hw_version.devid = devid; 563 ah->hw_version.devid = devid;
551 ah->hw_version.subsysid = subsysid; 564 ah->hw_version.subsysid = subsysid;
565 ah->reg_ops.read = ath9k_ioread32;
566 ah->reg_ops.write = ath9k_iowrite32;
567 ah->reg_ops.rmw = ath9k_reg_rmw;
552 sc->sc_ah = ah; 568 sc->sc_ah = ah;
553 569
554 if (!sc->dev->platform_data) 570 if (!pdata) {
555 ah->ah_flags |= AH_USE_EEPROM; 571 ah->ah_flags |= AH_USE_EEPROM;
572 sc->sc_ah->led_pin = -1;
573 } else {
574 sc->sc_ah->gpio_mask = pdata->gpio_mask;
575 sc->sc_ah->gpio_val = pdata->gpio_val;
576 sc->sc_ah->led_pin = pdata->led_pin;
577 }
556 578
557 common = ath9k_hw_common(ah); 579 common = ath9k_hw_common(ah);
558 common->ops = &ath9k_common_ops; 580 common->ops = &ah->reg_ops;
559 common->bus_ops = bus_ops; 581 common->bus_ops = bus_ops;
560 common->ah = ah; 582 common->ah = ah;
561 common->hw = sc->hw; 583 common->hw = sc->hw;
@@ -587,6 +609,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
587 if (ret) 609 if (ret)
588 goto err_hw; 610 goto err_hw;
589 611
612 if (pdata && pdata->macaddr)
613 memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
614
590 ret = ath9k_init_queues(sc); 615 ret = ath9k_init_queues(sc);
591 if (ret) 616 if (ret)
592 goto err_queues; 617 goto err_queues;
@@ -679,6 +704,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
679 if (AR_SREV_5416(sc->sc_ah)) 704 if (AR_SREV_5416(sc->sc_ah))
680 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 705 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
681 706
707 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
708
682 hw->queues = 4; 709 hw->queues = 4;
683 hw->max_rates = 4; 710 hw->max_rates = 4;
684 hw->channel_change_time = 5000; 711 hw->channel_change_time = 5000;
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 562257ac52cf..6f431cbff38a 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -209,15 +209,8 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
209{ 209{
210 u32 cw; 210 u32 cw;
211 struct ath_common *common = ath9k_hw_common(ah); 211 struct ath_common *common = ath9k_hw_common(ah);
212 struct ath9k_hw_capabilities *pCap = &ah->caps;
213 struct ath9k_tx_queue_info *qi; 212 struct ath9k_tx_queue_info *qi;
214 213
215 if (q >= pCap->total_queues) {
216 ath_dbg(common, ATH_DBG_QUEUE,
217 "Set TXQ properties, invalid queue: %u\n", q);
218 return false;
219 }
220
221 qi = &ah->txq[q]; 214 qi = &ah->txq[q];
222 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 215 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
223 ath_dbg(common, ATH_DBG_QUEUE, 216 ath_dbg(common, ATH_DBG_QUEUE,
@@ -280,15 +273,8 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
280 struct ath9k_tx_queue_info *qinfo) 273 struct ath9k_tx_queue_info *qinfo)
281{ 274{
282 struct ath_common *common = ath9k_hw_common(ah); 275 struct ath_common *common = ath9k_hw_common(ah);
283 struct ath9k_hw_capabilities *pCap = &ah->caps;
284 struct ath9k_tx_queue_info *qi; 276 struct ath9k_tx_queue_info *qi;
285 277
286 if (q >= pCap->total_queues) {
287 ath_dbg(common, ATH_DBG_QUEUE,
288 "Get TXQ properties, invalid queue: %u\n", q);
289 return false;
290 }
291
292 qi = &ah->txq[q]; 278 qi = &ah->txq[q];
293 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 279 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
294 ath_dbg(common, ATH_DBG_QUEUE, 280 ath_dbg(common, ATH_DBG_QUEUE,
@@ -320,28 +306,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
320{ 306{
321 struct ath_common *common = ath9k_hw_common(ah); 307 struct ath_common *common = ath9k_hw_common(ah);
322 struct ath9k_tx_queue_info *qi; 308 struct ath9k_tx_queue_info *qi;
323 struct ath9k_hw_capabilities *pCap = &ah->caps;
324 int q; 309 int q;
325 310
326 switch (type) { 311 switch (type) {
327 case ATH9K_TX_QUEUE_BEACON: 312 case ATH9K_TX_QUEUE_BEACON:
328 q = pCap->total_queues - 1; 313 q = ATH9K_NUM_TX_QUEUES - 1;
329 break; 314 break;
330 case ATH9K_TX_QUEUE_CAB: 315 case ATH9K_TX_QUEUE_CAB:
331 q = pCap->total_queues - 2; 316 q = ATH9K_NUM_TX_QUEUES - 2;
332 break; 317 break;
333 case ATH9K_TX_QUEUE_PSPOLL: 318 case ATH9K_TX_QUEUE_PSPOLL:
334 q = 1; 319 q = 1;
335 break; 320 break;
336 case ATH9K_TX_QUEUE_UAPSD: 321 case ATH9K_TX_QUEUE_UAPSD:
337 q = pCap->total_queues - 3; 322 q = ATH9K_NUM_TX_QUEUES - 3;
338 break; 323 break;
339 case ATH9K_TX_QUEUE_DATA: 324 case ATH9K_TX_QUEUE_DATA:
340 for (q = 0; q < pCap->total_queues; q++) 325 for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
341 if (ah->txq[q].tqi_type == 326 if (ah->txq[q].tqi_type ==
342 ATH9K_TX_QUEUE_INACTIVE) 327 ATH9K_TX_QUEUE_INACTIVE)
343 break; 328 break;
344 if (q == pCap->total_queues) { 329 if (q == ATH9K_NUM_TX_QUEUES) {
345 ath_err(common, "No available TX queue\n"); 330 ath_err(common, "No available TX queue\n");
346 return -1; 331 return -1;
347 } 332 }
@@ -382,15 +367,9 @@ EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
382 367
383bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) 368bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
384{ 369{
385 struct ath9k_hw_capabilities *pCap = &ah->caps;
386 struct ath_common *common = ath9k_hw_common(ah); 370 struct ath_common *common = ath9k_hw_common(ah);
387 struct ath9k_tx_queue_info *qi; 371 struct ath9k_tx_queue_info *qi;
388 372
389 if (q >= pCap->total_queues) {
390 ath_dbg(common, ATH_DBG_QUEUE,
391 "Release TXQ, invalid queue: %u\n", q);
392 return false;
393 }
394 qi = &ah->txq[q]; 373 qi = &ah->txq[q];
395 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 374 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
396 ath_dbg(common, ATH_DBG_QUEUE, 375 ath_dbg(common, ATH_DBG_QUEUE,
@@ -414,18 +393,11 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
414 393
415bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) 394bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
416{ 395{
417 struct ath9k_hw_capabilities *pCap = &ah->caps;
418 struct ath_common *common = ath9k_hw_common(ah); 396 struct ath_common *common = ath9k_hw_common(ah);
419 struct ath9k_channel *chan = ah->curchan; 397 struct ath9k_channel *chan = ah->curchan;
420 struct ath9k_tx_queue_info *qi; 398 struct ath9k_tx_queue_info *qi;
421 u32 cwMin, chanCwMin, value; 399 u32 cwMin, chanCwMin, value;
422 400
423 if (q >= pCap->total_queues) {
424 ath_dbg(common, ATH_DBG_QUEUE,
425 "Reset TXQ, invalid queue: %u\n", q);
426 return false;
427 }
428
429 qi = &ah->txq[q]; 401 qi = &ah->txq[q];
430 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 402 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
431 ath_dbg(common, ATH_DBG_QUEUE, 403 ath_dbg(common, ATH_DBG_QUEUE,
@@ -465,10 +437,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
465 REG_WRITE(ah, AR_QCBRCFG(q), 437 REG_WRITE(ah, AR_QCBRCFG(q),
466 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | 438 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
467 SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); 439 SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
468 REG_WRITE(ah, AR_QMISC(q), 440 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
469 REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | 441 (qi->tqi_cbrOverflowLimit ?
470 (qi->tqi_cbrOverflowLimit ? 442 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
471 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
472 } 443 }
473 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { 444 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
474 REG_WRITE(ah, AR_QRDYTIMECFG(q), 445 REG_WRITE(ah, AR_QRDYTIMECFG(q),
@@ -481,40 +452,31 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
481 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); 452 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
482 453
483 if (qi->tqi_burstTime 454 if (qi->tqi_burstTime
484 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { 455 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
485 REG_WRITE(ah, AR_QMISC(q), 456 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
486 REG_READ(ah, AR_QMISC(q)) |
487 AR_Q_MISC_RDYTIME_EXP_POLICY);
488
489 }
490 457
491 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) { 458 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
492 REG_WRITE(ah, AR_DMISC(q), 459 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
493 REG_READ(ah, AR_DMISC(q)) |
494 AR_D_MISC_POST_FR_BKOFF_DIS);
495 }
496 460
497 REGWRITE_BUFFER_FLUSH(ah); 461 REGWRITE_BUFFER_FLUSH(ah);
498 462
499 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { 463 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
500 REG_WRITE(ah, AR_DMISC(q), 464 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
501 REG_READ(ah, AR_DMISC(q)) | 465
502 AR_D_MISC_FRAG_BKOFF_EN);
503 }
504 switch (qi->tqi_type) { 466 switch (qi->tqi_type) {
505 case ATH9K_TX_QUEUE_BEACON: 467 case ATH9K_TX_QUEUE_BEACON:
506 ENABLE_REGWRITE_BUFFER(ah); 468 ENABLE_REGWRITE_BUFFER(ah);
507 469
508 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 470 REG_SET_BIT(ah, AR_QMISC(q),
509 | AR_Q_MISC_FSP_DBA_GATED 471 AR_Q_MISC_FSP_DBA_GATED
510 | AR_Q_MISC_BEACON_USE 472 | AR_Q_MISC_BEACON_USE
511 | AR_Q_MISC_CBR_INCR_DIS1); 473 | AR_Q_MISC_CBR_INCR_DIS1);
512 474
513 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 475 REG_SET_BIT(ah, AR_DMISC(q),
514 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 476 (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
515 AR_D_MISC_ARB_LOCKOUT_CNTRL_S) 477 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
516 | AR_D_MISC_BEACON_USE 478 | AR_D_MISC_BEACON_USE
517 | AR_D_MISC_POST_FR_BKOFF_DIS); 479 | AR_D_MISC_POST_FR_BKOFF_DIS);
518 480
519 REGWRITE_BUFFER_FLUSH(ah); 481 REGWRITE_BUFFER_FLUSH(ah);
520 482
@@ -533,41 +495,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
533 case ATH9K_TX_QUEUE_CAB: 495 case ATH9K_TX_QUEUE_CAB:
534 ENABLE_REGWRITE_BUFFER(ah); 496 ENABLE_REGWRITE_BUFFER(ah);
535 497
536 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 498 REG_SET_BIT(ah, AR_QMISC(q),
537 | AR_Q_MISC_FSP_DBA_GATED 499 AR_Q_MISC_FSP_DBA_GATED
538 | AR_Q_MISC_CBR_INCR_DIS1 500 | AR_Q_MISC_CBR_INCR_DIS1
539 | AR_Q_MISC_CBR_INCR_DIS0); 501 | AR_Q_MISC_CBR_INCR_DIS0);
540 value = (qi->tqi_readyTime - 502 value = (qi->tqi_readyTime -
541 (ah->config.sw_beacon_response_time - 503 (ah->config.sw_beacon_response_time -
542 ah->config.dma_beacon_response_time) - 504 ah->config.dma_beacon_response_time) -
543 ah->config.additional_swba_backoff) * 1024; 505 ah->config.additional_swba_backoff) * 1024;
544 REG_WRITE(ah, AR_QRDYTIMECFG(q), 506 REG_WRITE(ah, AR_QRDYTIMECFG(q),
545 value | AR_Q_RDYTIMECFG_EN); 507 value | AR_Q_RDYTIMECFG_EN);
546 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 508 REG_SET_BIT(ah, AR_DMISC(q),
547 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 509 (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
548 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); 510 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
549 511
550 REGWRITE_BUFFER_FLUSH(ah); 512 REGWRITE_BUFFER_FLUSH(ah);
551 513
552 break; 514 break;
553 case ATH9K_TX_QUEUE_PSPOLL: 515 case ATH9K_TX_QUEUE_PSPOLL:
554 REG_WRITE(ah, AR_QMISC(q), 516 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1);
555 REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
556 break; 517 break;
557 case ATH9K_TX_QUEUE_UAPSD: 518 case ATH9K_TX_QUEUE_UAPSD:
558 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | 519 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
559 AR_D_MISC_POST_FR_BKOFF_DIS);
560 break; 520 break;
561 default: 521 default:
562 break; 522 break;
563 } 523 }
564 524
565 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { 525 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
566 REG_WRITE(ah, AR_DMISC(q), 526 REG_SET_BIT(ah, AR_DMISC(q),
567 REG_READ(ah, AR_DMISC(q)) | 527 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
568 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, 528 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
569 AR_D_MISC_ARB_LOCKOUT_CNTRL) | 529 AR_D_MISC_POST_FR_BKOFF_DIS);
570 AR_D_MISC_POST_FR_BKOFF_DIS);
571 } 530 }
572 531
573 if (AR_SREV_9300_20_OR_LATER(ah)) 532 if (AR_SREV_9300_20_OR_LATER(ah))
@@ -754,7 +713,6 @@ EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
754bool ath9k_hw_stopdmarecv(struct ath_hw *ah) 713bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
755{ 714{
756#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 715#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
757#define AH_RX_TIME_QUANTUM 100 /* usec */
758 struct ath_common *common = ath9k_hw_common(ah); 716 struct ath_common *common = ath9k_hw_common(ah);
759 int i; 717 int i;
760 718
@@ -778,7 +736,6 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
778 return true; 736 return true;
779 } 737 }
780 738
781#undef AH_RX_TIME_QUANTUM
782#undef AH_RX_STOP_DMA_TIMEOUT 739#undef AH_RX_STOP_DMA_TIMEOUT
783} 740}
784EXPORT_SYMBOL(ath9k_hw_stopdmarecv); 741EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 17d04ff8d678..4c5c9997dac6 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -299,7 +299,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
299 299
300 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { 300 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
301 if (sc->sc_flags & SC_OP_BEACONS) 301 if (sc->sc_flags & SC_OP_BEACONS)
302 ath_beacon_config(sc, NULL); 302 ath_set_beacon(sc);
303 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 303 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
304 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); 304 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
305 ath_start_ani(common); 305 ath_start_ani(common);
@@ -828,48 +828,6 @@ chip_reset:
828#undef SCHED_INTR 828#undef SCHED_INTR
829} 829}
830 830
831static void ath9k_bss_assoc_info(struct ath_softc *sc,
832 struct ieee80211_hw *hw,
833 struct ieee80211_vif *vif,
834 struct ieee80211_bss_conf *bss_conf)
835{
836 struct ath_hw *ah = sc->sc_ah;
837 struct ath_common *common = ath9k_hw_common(ah);
838
839 if (bss_conf->assoc) {
840 ath_dbg(common, ATH_DBG_CONFIG,
841 "Bss Info ASSOC %d, bssid: %pM\n",
842 bss_conf->aid, common->curbssid);
843
844 /* New association, store aid */
845 common->curaid = bss_conf->aid;
846 ath9k_hw_write_associd(ah);
847
848 /*
849 * Request a re-configuration of Beacon related timers
850 * on the receipt of the first Beacon frame (i.e.,
851 * after time sync with the AP).
852 */
853 sc->ps_flags |= PS_BEACON_SYNC;
854
855 /* Configure the beacon */
856 ath_beacon_config(sc, vif);
857
858 /* Reset rssi stats */
859 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
860 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
861
862 sc->sc_flags |= SC_OP_ANI_RUN;
863 ath_start_ani(common);
864 } else {
865 ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
866 common->curaid = 0;
867 /* Stop ANI */
868 sc->sc_flags &= ~SC_OP_ANI_RUN;
869 del_timer_sync(&common->ani.timer);
870 }
871}
872
873void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) 831void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
874{ 832{
875 struct ath_hw *ah = sc->sc_ah; 833 struct ath_hw *ah = sc->sc_ah;
@@ -899,7 +857,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
899 goto out; 857 goto out;
900 } 858 }
901 if (sc->sc_flags & SC_OP_BEACONS) 859 if (sc->sc_flags & SC_OP_BEACONS)
902 ath_beacon_config(sc, NULL); /* restart beacons */ 860 ath_set_beacon(sc); /* restart beacons */
903 861
904 /* Re-Enable interrupts */ 862 /* Re-Enable interrupts */
905 ath9k_hw_set_interrupts(ah, ah->imask); 863 ath9k_hw_set_interrupts(ah, ah->imask);
@@ -1006,7 +964,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1006 sc->config.txpowlimit, &sc->curtxpow); 964 sc->config.txpowlimit, &sc->curtxpow);
1007 965
1008 if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) 966 if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
1009 ath_beacon_config(sc, NULL); /* restart beacons */ 967 ath_set_beacon(sc); /* restart beacons */
1010 968
1011 ath9k_hw_set_interrupts(ah, ah->imask); 969 ath9k_hw_set_interrupts(ah, ah->imask);
1012 970
@@ -1415,9 +1373,6 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1415 if ((iter_data.naps + iter_data.nadhocs) > 0) { 1373 if ((iter_data.naps + iter_data.nadhocs) > 0) {
1416 sc->sc_flags |= SC_OP_ANI_RUN; 1374 sc->sc_flags |= SC_OP_ANI_RUN;
1417 ath_start_ani(common); 1375 ath_start_ani(common);
1418 } else {
1419 sc->sc_flags &= ~SC_OP_ANI_RUN;
1420 del_timer_sync(&common->ani.timer);
1421 } 1376 }
1422} 1377}
1423 1378
@@ -1452,7 +1407,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1452 struct ath_softc *sc = hw->priv; 1407 struct ath_softc *sc = hw->priv;
1453 struct ath_hw *ah = sc->sc_ah; 1408 struct ath_hw *ah = sc->sc_ah;
1454 struct ath_common *common = ath9k_hw_common(ah); 1409 struct ath_common *common = ath9k_hw_common(ah);
1455 struct ath_vif *avp = (void *)vif->drv_priv;
1456 int ret = 0; 1410 int ret = 0;
1457 1411
1458 ath9k_ps_wakeup(sc); 1412 ath9k_ps_wakeup(sc);
@@ -1482,8 +1436,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1482 } 1436 }
1483 } 1437 }
1484 1438
1485 if ((vif->type == NL80211_IFTYPE_ADHOC) && 1439 if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
1486 sc->nvifs > 0) { 1440 ((vif->type == NL80211_IFTYPE_ADHOC) &&
1441 sc->nvifs > 0)) {
1487 ath_err(common, "Cannot create ADHOC interface when other" 1442 ath_err(common, "Cannot create ADHOC interface when other"
1488 " interfaces already exist.\n"); 1443 " interfaces already exist.\n");
1489 ret = -EINVAL; 1444 ret = -EINVAL;
@@ -1493,10 +1448,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1493 ath_dbg(common, ATH_DBG_CONFIG, 1448 ath_dbg(common, ATH_DBG_CONFIG,
1494 "Attach a VIF of type: %d\n", vif->type); 1449 "Attach a VIF of type: %d\n", vif->type);
1495 1450
1496 /* Set the VIF opmode */
1497 avp->av_opmode = vif->type;
1498 avp->av_bslot = -1;
1499
1500 sc->nvifs++; 1451 sc->nvifs++;
1501 1452
1502 ath9k_do_vif_add_setup(hw, vif); 1453 ath9k_do_vif_add_setup(hw, vif);
@@ -1855,6 +1806,20 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1855 if (ath9k_modparam_nohwcrypt) 1806 if (ath9k_modparam_nohwcrypt)
1856 return -ENOSPC; 1807 return -ENOSPC;
1857 1808
1809 if (vif->type == NL80211_IFTYPE_ADHOC &&
1810 (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
1811 key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
1812 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
1813 /*
1814 * For now, disable hw crypto for the RSN IBSS group keys. This
1815 * could be optimized in the future to use a modified key cache
1816 * design to support per-STA RX GTK, but until that gets
1817 * implemented, use of software crypto for group addressed
1818 * frames is a acceptable to allow RSN IBSS to be used.
1819 */
1820 return -EOPNOTSUPP;
1821 }
1822
1858 mutex_lock(&sc->mutex); 1823 mutex_lock(&sc->mutex);
1859 ath9k_ps_wakeup(sc); 1824 ath9k_ps_wakeup(sc);
1860 ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); 1825 ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
@@ -1886,6 +1851,86 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1886 1851
1887 return ret; 1852 return ret;
1888} 1853}
1854static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1855{
1856 struct ath_softc *sc = data;
1857 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1858 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1859 struct ath_vif *avp = (void *)vif->drv_priv;
1860
1861 switch (sc->sc_ah->opmode) {
1862 case NL80211_IFTYPE_ADHOC:
1863 /* There can be only one vif available */
1864 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1865 common->curaid = bss_conf->aid;
1866 ath9k_hw_write_associd(sc->sc_ah);
1867 /* configure beacon */
1868 if (bss_conf->enable_beacon)
1869 ath_beacon_config(sc, vif);
1870 break;
1871 case NL80211_IFTYPE_STATION:
1872 /*
1873 * Skip iteration if primary station vif's bss info
1874 * was not changed
1875 */
1876 if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
1877 break;
1878
1879 if (bss_conf->assoc) {
1880 sc->sc_flags |= SC_OP_PRIM_STA_VIF;
1881 avp->primary_sta_vif = true;
1882 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1883 common->curaid = bss_conf->aid;
1884 ath9k_hw_write_associd(sc->sc_ah);
1885 ath_dbg(common, ATH_DBG_CONFIG,
1886 "Bss Info ASSOC %d, bssid: %pM\n",
1887 bss_conf->aid, common->curbssid);
1888 ath_beacon_config(sc, vif);
1889 /* Reset rssi stats */
1890 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
1891 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1892
1893 sc->sc_flags |= SC_OP_ANI_RUN;
1894 ath_start_ani(common);
1895 }
1896 break;
1897 default:
1898 break;
1899 }
1900}
1901
1902static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
1903{
1904 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1905 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1906 struct ath_vif *avp = (void *)vif->drv_priv;
1907
1908 /* Reconfigure bss info */
1909 if (avp->primary_sta_vif && !bss_conf->assoc) {
1910 ath_dbg(common, ATH_DBG_CONFIG,
1911 "Bss Info DISASSOC %d, bssid %pM\n",
1912 common->curaid, common->curbssid);
1913 sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
1914 avp->primary_sta_vif = false;
1915 memset(common->curbssid, 0, ETH_ALEN);
1916 common->curaid = 0;
1917 }
1918
1919 ieee80211_iterate_active_interfaces_atomic(
1920 sc->hw, ath9k_bss_iter, sc);
1921
1922 /*
1923 * None of station vifs are associated.
1924 * Clear bssid & aid
1925 */
1926 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
1927 !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
1928 ath9k_hw_write_associd(sc->sc_ah);
1929 /* Stop ANI */
1930 sc->sc_flags &= ~SC_OP_ANI_RUN;
1931 del_timer_sync(&common->ani.timer);
1932 }
1933}
1889 1934
1890static void ath9k_bss_info_changed(struct ieee80211_hw *hw, 1935static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1891 struct ieee80211_vif *vif, 1936 struct ieee80211_vif *vif,
@@ -1893,7 +1938,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1893 u32 changed) 1938 u32 changed)
1894{ 1939{
1895 struct ath_softc *sc = hw->priv; 1940 struct ath_softc *sc = hw->priv;
1896 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
1897 struct ath_hw *ah = sc->sc_ah; 1941 struct ath_hw *ah = sc->sc_ah;
1898 struct ath_common *common = ath9k_hw_common(ah); 1942 struct ath_common *common = ath9k_hw_common(ah);
1899 struct ath_vif *avp = (void *)vif->drv_priv; 1943 struct ath_vif *avp = (void *)vif->drv_priv;
@@ -1904,20 +1948,13 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1904 mutex_lock(&sc->mutex); 1948 mutex_lock(&sc->mutex);
1905 1949
1906 if (changed & BSS_CHANGED_BSSID) { 1950 if (changed & BSS_CHANGED_BSSID) {
1907 /* Set BSSID */ 1951 ath9k_config_bss(sc, vif);
1908 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1909 memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
1910 common->curaid = 0;
1911 ath9k_hw_write_associd(ah);
1912 1952
1913 /* Set aggregation protection mode parameters */ 1953 /* Set aggregation protection mode parameters */
1914 sc->config.ath_aggr_prot = 0; 1954 sc->config.ath_aggr_prot = 0;
1915 1955
1916 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", 1956 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
1917 common->curbssid, common->curaid); 1957 common->curbssid, common->curaid);
1918
1919 /* need to reconfigure the beacon */
1920 sc->sc_flags &= ~SC_OP_BEACONS ;
1921 } 1958 }
1922 1959
1923 /* Enable transmission of beacons (AP, IBSS, MESH) */ 1960 /* Enable transmission of beacons (AP, IBSS, MESH) */
@@ -1958,7 +1995,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1958 } 1995 }
1959 1996
1960 if (changed & BSS_CHANGED_BEACON_INT) { 1997 if (changed & BSS_CHANGED_BEACON_INT) {
1961 cur_conf->beacon_interval = bss_conf->beacon_int;
1962 /* 1998 /*
1963 * In case of AP mode, the HW TSF has to be reset 1999 * In case of AP mode, the HW TSF has to be reset
1964 * when the beacon interval changes. 2000 * when the beacon interval changes.
@@ -1970,9 +2006,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1970 if (!error) 2006 if (!error)
1971 ath_beacon_config(sc, vif); 2007 ath_beacon_config(sc, vif);
1972 ath9k_set_beaconing_status(sc, true); 2008 ath9k_set_beaconing_status(sc, true);
1973 } else { 2009 } else
1974 ath_beacon_config(sc, vif); 2010 ath_beacon_config(sc, vif);
1975 }
1976 } 2011 }
1977 2012
1978 if (changed & BSS_CHANGED_ERP_PREAMBLE) { 2013 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -1994,12 +2029,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1994 sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; 2029 sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
1995 } 2030 }
1996 2031
1997 if (changed & BSS_CHANGED_ASSOC) {
1998 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1999 bss_conf->assoc);
2000 ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
2001 }
2002
2003 mutex_unlock(&sc->mutex); 2032 mutex_unlock(&sc->mutex);
2004 ath9k_ps_restore(sc); 2033 ath9k_ps_restore(sc);
2005} 2034}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 5e3d7496986e..f50e2c29f71e 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -38,25 +38,11 @@
38#define AR_PHY_CLC_Q0 0x0000ffd0 38#define AR_PHY_CLC_Q0 0x0000ffd0
39#define AR_PHY_CLC_Q0_S 5 39#define AR_PHY_CLC_Q0_S 5
40 40
41#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
42 int r; \
43 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
44 REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
45 DO_DELAY(regWr); \
46 } \
47 } while (0)
48
49#define ANTSWAP_AB 0x0001 41#define ANTSWAP_AB 0x0001
50#define REDUCE_CHAIN_0 0x00000050 42#define REDUCE_CHAIN_0 0x00000050
51#define REDUCE_CHAIN_1 0x00000051 43#define REDUCE_CHAIN_1 0x00000051
52#define AR_PHY_CHIP_ID 0x9818 44#define AR_PHY_CHIP_ID 0x9818
53 45
54#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
55 int i; \
56 for (i = 0; i < (_iniarray)->ia_rows; i++) \
57 (_bank)[i] = INI_RA((_iniarray), i, _col);; \
58 } while (0)
59
60#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 46#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
61#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 47#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
62 48
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index a9c3f4672aa0..3842b7518661 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -574,7 +574,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
574 sc->ps_flags &= ~PS_BEACON_SYNC; 574 sc->ps_flags &= ~PS_BEACON_SYNC;
575 ath_dbg(common, ATH_DBG_PS, 575 ath_dbg(common, ATH_DBG_PS,
576 "Reconfigure Beacon timers based on timestamp from the AP\n"); 576 "Reconfigure Beacon timers based on timestamp from the AP\n");
577 ath_beacon_config(sc, NULL); 577 ath_set_beacon(sc);
578 } 578 }
579 579
580 if (ath_beacon_dtim_pending_cab(skb)) { 580 if (ath_beacon_dtim_pending_cab(skb)) {
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8fa8acfde62e..693d543937b5 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1396,6 +1396,7 @@ enum {
1396#define AR_STA_ID1_PCF 0x00100000 1396#define AR_STA_ID1_PCF 0x00100000
1397#define AR_STA_ID1_USE_DEFANT 0x00200000 1397#define AR_STA_ID1_USE_DEFANT 0x00200000
1398#define AR_STA_ID1_DEFANT_UPDATE 0x00400000 1398#define AR_STA_ID1_DEFANT_UPDATE 0x00400000
1399#define AR_STA_ID1_AR9100_BA_FIX 0x00400000
1399#define AR_STA_ID1_RTS_USE_DEF 0x00800000 1400#define AR_STA_ID1_RTS_USE_DEF 0x00800000
1400#define AR_STA_ID1_ACKCTS_6MB 0x01000000 1401#define AR_STA_ID1_ACKCTS_6MB 0x01000000
1401#define AR_STA_ID1_BASE_RATE_11B 0x02000000 1402#define AR_STA_ID1_BASE_RATE_11B 0x02000000
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 88fa7fdffd05..3cea3f76e373 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1980,7 +1980,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
1980 if (ieee80211_is_data(hdr->frame_control) && 1980 if (ieee80211_is_data(hdr->frame_control) &&
1981 (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | 1981 (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
1982 ATH9K_TX_DELIM_UNDERRUN)) && 1982 ATH9K_TX_DELIM_UNDERRUN)) &&
1983 ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max) 1983 ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level)
1984 tx_info->status.rates[tx_rateindex].count = 1984 tx_info->status.rates[tx_rateindex].count =
1985 hw->max_rate_tries; 1985 hw->max_rate_tries;
1986 } 1986 }
@@ -2144,33 +2144,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
2144 } else { 2144 } else {
2145 txq->axq_tx_inprogress = true; 2145 txq->axq_tx_inprogress = true;
2146 } 2146 }
2147 } else {
2148 /* If the queue has pending buffers, then it
2149 * should be doing tx work (and have axq_depth).
2150 * Shouldn't get to this state I think..but
2151 * we do.
2152 */
2153 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) &&
2154 (txq->pending_frames > 0 ||
2155 !list_empty(&txq->axq_acq) ||
2156 txq->stopped)) {
2157 ath_err(ath9k_hw_common(sc->sc_ah),
2158 "txq: %p axq_qnum: %u,"
2159 " mac80211_qnum: %i"
2160 " axq_link: %p"
2161 " pending frames: %i"
2162 " axq_acq empty: %i"
2163 " stopped: %i"
2164 " axq_depth: 0 Attempting to"
2165 " restart tx logic.\n",
2166 txq, txq->axq_qnum,
2167 txq->mac80211_qnum,
2168 txq->axq_link,
2169 txq->pending_frames,
2170 list_empty(&txq->axq_acq),
2171 txq->stopped);
2172 ath_txq_schedule(sc, txq);
2173 }
2174 } 2147 }
2175 spin_unlock_bh(&txq->axq_lock); 2148 spin_unlock_bh(&txq->axq_lock);
2176 } 2149 }
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index 37b8e115375a..0d4f39cbdcab 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -23,6 +23,14 @@
23 23
24#define REG_READ (common->ops->read) 24#define REG_READ (common->ops->read)
25#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) 25#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg)
26#define ENABLE_REGWRITE_BUFFER(_ah) \
27 if (common->ops->enable_write_buffer) \
28 common->ops->enable_write_buffer((_ah));
29
30#define REGWRITE_BUFFER_FLUSH(_ah) \
31 if (common->ops->write_flush) \
32 common->ops->write_flush((_ah));
33
26 34
27#define IEEE80211_WEP_NKID 4 /* number of key ids */ 35#define IEEE80211_WEP_NKID 4 /* number of key ids */
28 36
@@ -42,6 +50,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
42 50
43 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); 51 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
44 52
53 ENABLE_REGWRITE_BUFFER(ah);
54
45 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); 55 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
46 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); 56 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
47 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); 57 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
@@ -66,6 +76,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
66 76
67 } 77 }
68 78
79 REGWRITE_BUFFER_FLUSH(ah);
80
69 return true; 81 return true;
70} 82}
71EXPORT_SYMBOL(ath_hw_keyreset); 83EXPORT_SYMBOL(ath_hw_keyreset);
@@ -104,9 +116,13 @@ static bool ath_hw_keysetmac(struct ath_common *common,
104 } else { 116 } else {
105 macLo = macHi = 0; 117 macLo = macHi = 0;
106 } 118 }
119 ENABLE_REGWRITE_BUFFER(ah);
120
107 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); 121 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
108 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); 122 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
109 123
124 REGWRITE_BUFFER_FLUSH(ah);
125
110 return true; 126 return true;
111} 127}
112 128
@@ -223,6 +239,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
223 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; 239 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
224 mic4 = get_unaligned_le32(k->kv_txmic + 4); 240 mic4 = get_unaligned_le32(k->kv_txmic + 4);
225 241
242 ENABLE_REGWRITE_BUFFER(ah);
243
226 /* Write RX[31:0] and TX[31:16] */ 244 /* Write RX[31:0] and TX[31:16] */
227 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 245 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
228 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); 246 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
@@ -236,6 +254,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
236 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), 254 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
237 AR_KEYTABLE_TYPE_CLR); 255 AR_KEYTABLE_TYPE_CLR);
238 256
257 REGWRITE_BUFFER_FLUSH(ah);
258
239 } else { 259 } else {
240 /* 260 /*
241 * TKIP uses four key cache entries (two for group 261 * TKIP uses four key cache entries (two for group
@@ -258,6 +278,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
258 mic0 = get_unaligned_le32(k->kv_mic + 0); 278 mic0 = get_unaligned_le32(k->kv_mic + 0);
259 mic2 = get_unaligned_le32(k->kv_mic + 4); 279 mic2 = get_unaligned_le32(k->kv_mic + 4);
260 280
281 ENABLE_REGWRITE_BUFFER(ah);
282
261 /* Write MIC key[31:0] */ 283 /* Write MIC key[31:0] */
262 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 284 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
263 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); 285 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
@@ -270,8 +292,12 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
270 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); 292 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
271 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), 293 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
272 AR_KEYTABLE_TYPE_CLR); 294 AR_KEYTABLE_TYPE_CLR);
295
296 REGWRITE_BUFFER_FLUSH(ah);
273 } 297 }
274 298
299 ENABLE_REGWRITE_BUFFER(ah);
300
275 /* MAC address registers are reserved for the MIC entry */ 301 /* MAC address registers are reserved for the MIC entry */
276 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); 302 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
277 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); 303 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
@@ -283,7 +309,11 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
283 */ 309 */
284 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 310 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
285 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 311 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
312
313 REGWRITE_BUFFER_FLUSH(ah);
286 } else { 314 } else {
315 ENABLE_REGWRITE_BUFFER(ah);
316
287 /* Write key[47:0] */ 317 /* Write key[47:0] */
288 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 318 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
289 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 319 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
@@ -296,6 +326,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
296 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 326 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
297 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 327 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
298 328
329 REGWRITE_BUFFER_FLUSH(ah);
330
299 /* Write MAC address for the entry */ 331 /* Write MAC address for the entry */
300 (void) ath_hw_keysetmac(common, entry, mac); 332 (void) ath_hw_keysetmac(common, entry, mac);
301 } 333 }
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 9d6ee836426c..3652931753e0 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,7 +2,7 @@
2obj-$(CONFIG_IWLAGN) += iwlagn.o 2obj-$(CONFIG_IWLAGN) += iwlagn.o
3iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o 3iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
4iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o 4iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
5iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o 5iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
6iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o 6iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
7 7
8iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o 8iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 27c5007e577c..1b2799291834 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -141,7 +141,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
141 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 141 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
142 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 142 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
143 143
144 priv->hw_params.max_bsm_size = 0;
145 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 144 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
146 BIT(IEEE80211_BAND_5GHZ); 145 BIT(IEEE80211_BAND_5GHZ);
147 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 146 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -179,21 +178,16 @@ static struct iwl_lib_ops iwl1000_lib = {
179 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 178 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
180 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 179 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
181 .txq_set_sched = iwlagn_txq_set_sched, 180 .txq_set_sched = iwlagn_txq_set_sched,
182 .txq_agg_enable = iwlagn_txq_agg_enable,
183 .txq_agg_disable = iwlagn_txq_agg_disable,
184 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 181 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
185 .txq_free_tfd = iwl_hw_txq_free_tfd, 182 .txq_free_tfd = iwl_hw_txq_free_tfd,
186 .txq_init = iwl_hw_tx_queue_init, 183 .txq_init = iwl_hw_tx_queue_init,
187 .rx_handler_setup = iwlagn_rx_handler_setup, 184 .rx_handler_setup = iwlagn_rx_handler_setup,
188 .setup_deferred_work = iwlagn_setup_deferred_work, 185 .setup_deferred_work = iwlagn_setup_deferred_work,
189 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 186 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
190 .load_ucode = iwlagn_load_ucode,
191 .dump_nic_event_log = iwl_dump_nic_event_log, 187 .dump_nic_event_log = iwl_dump_nic_event_log,
192 .dump_nic_error_log = iwl_dump_nic_error_log, 188 .dump_nic_error_log = iwl_dump_nic_error_log,
193 .dump_csr = iwl_dump_csr, 189 .dump_csr = iwl_dump_csr,
194 .dump_fh = iwl_dump_fh, 190 .dump_fh = iwl_dump_fh,
195 .init_alive_start = iwlagn_init_alive_start,
196 .alive_notify = iwlagn_alive_notify,
197 .send_tx_power = iwlagn_send_tx_power, 191 .send_tx_power = iwlagn_send_tx_power,
198 .update_chain_flags = iwl_update_chain_flags, 192 .update_chain_flags = iwl_update_chain_flags,
199 .apm_ops = { 193 .apm_ops = {
@@ -215,13 +209,6 @@ static struct iwl_lib_ops iwl1000_lib = {
215 .calib_version = iwlagn_eeprom_calib_version, 209 .calib_version = iwlagn_eeprom_calib_version,
216 .query_addr = iwlagn_eeprom_query_addr, 210 .query_addr = iwlagn_eeprom_query_addr,
217 }, 211 },
218 .isr_ops = {
219 .isr = iwl_isr_ict,
220 .free = iwl_free_isr_ict,
221 .alloc = iwl_alloc_isr_ict,
222 .reset = iwl_reset_ict,
223 .disable = iwl_disable_ict,
224 },
225 .temp_ops = { 212 .temp_ops = {
226 .temperature = iwlagn_temperature, 213 .temperature = iwlagn_temperature,
227 }, 214 },
@@ -255,7 +242,6 @@ static struct iwl_base_params iwl1000_base_params = {
255 .eeprom_size = OTP_LOW_IMAGE_SIZE, 242 .eeprom_size = OTP_LOW_IMAGE_SIZE,
256 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 243 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
257 .set_l0s = true, 244 .set_l0s = true,
258 .use_bsm = false,
259 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 245 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
260 .shadow_ram_support = false, 246 .shadow_ram_support = false,
261 .led_compensation = 51, 247 .led_compensation = 51,
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index d7b6126408c9..f602af4b9408 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -147,7 +147,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
147 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; 147 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
148 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; 148 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
149 149
150 priv->hw_params.max_bsm_size = 0;
151 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 150 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
152 BIT(IEEE80211_BAND_5GHZ); 151 BIT(IEEE80211_BAND_5GHZ);
153 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 152 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -259,8 +258,6 @@ static struct iwl_lib_ops iwl2000_lib = {
259 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 258 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
260 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 259 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
261 .txq_set_sched = iwlagn_txq_set_sched, 260 .txq_set_sched = iwlagn_txq_set_sched,
262 .txq_agg_enable = iwlagn_txq_agg_enable,
263 .txq_agg_disable = iwlagn_txq_agg_disable,
264 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 261 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
265 .txq_free_tfd = iwl_hw_txq_free_tfd, 262 .txq_free_tfd = iwl_hw_txq_free_tfd,
266 .txq_init = iwl_hw_tx_queue_init, 263 .txq_init = iwl_hw_tx_queue_init,
@@ -268,13 +265,10 @@ static struct iwl_lib_ops iwl2000_lib = {
268 .setup_deferred_work = iwlagn_bt_setup_deferred_work, 265 .setup_deferred_work = iwlagn_bt_setup_deferred_work,
269 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, 266 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
270 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 267 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
271 .load_ucode = iwlagn_load_ucode,
272 .dump_nic_event_log = iwl_dump_nic_event_log, 268 .dump_nic_event_log = iwl_dump_nic_event_log,
273 .dump_nic_error_log = iwl_dump_nic_error_log, 269 .dump_nic_error_log = iwl_dump_nic_error_log,
274 .dump_csr = iwl_dump_csr, 270 .dump_csr = iwl_dump_csr,
275 .dump_fh = iwl_dump_fh, 271 .dump_fh = iwl_dump_fh,
276 .init_alive_start = iwlagn_init_alive_start,
277 .alive_notify = iwlagn_alive_notify,
278 .send_tx_power = iwlagn_send_tx_power, 272 .send_tx_power = iwlagn_send_tx_power,
279 .update_chain_flags = iwl_update_chain_flags, 273 .update_chain_flags = iwl_update_chain_flags,
280 .set_channel_switch = iwl2030_hw_channel_switch, 274 .set_channel_switch = iwl2030_hw_channel_switch,
@@ -298,13 +292,6 @@ static struct iwl_lib_ops iwl2000_lib = {
298 .query_addr = iwlagn_eeprom_query_addr, 292 .query_addr = iwlagn_eeprom_query_addr,
299 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 293 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
300 }, 294 },
301 .isr_ops = {
302 .isr = iwl_isr_ict,
303 .free = iwl_free_isr_ict,
304 .alloc = iwl_alloc_isr_ict,
305 .reset = iwl_reset_ict,
306 .disable = iwl_disable_ict,
307 },
308 .temp_ops = { 295 .temp_ops = {
309 .temperature = iwlagn_temperature, 296 .temperature = iwlagn_temperature,
310 }, 297 },
@@ -362,7 +349,6 @@ static struct iwl_base_params iwl2000_base_params = {
362 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 349 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
363 .pll_cfg_val = 0, 350 .pll_cfg_val = 0,
364 .set_l0s = true, 351 .set_l0s = true,
365 .use_bsm = false,
366 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 352 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
367 .shadow_ram_support = true, 353 .shadow_ram_support = true,
368 .led_compensation = 51, 354 .led_compensation = 51,
@@ -386,7 +372,6 @@ static struct iwl_base_params iwl2030_base_params = {
386 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 372 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
387 .pll_cfg_val = 0, 373 .pll_cfg_val = 0,
388 .set_l0s = true, 374 .set_l0s = true,
389 .use_bsm = false,
390 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 375 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
391 .shadow_ram_support = true, 376 .shadow_ram_support = true,
392 .led_compensation = 57, 377 .led_compensation = 57,
@@ -471,37 +456,6 @@ struct iwl_cfg iwl2030_2bg_cfg = {
471 IWL_DEVICE_2030, 456 IWL_DEVICE_2030,
472}; 457};
473 458
474#define IWL_DEVICE_6035 \
475 .fw_name_pre = IWL2030_FW_PRE, \
476 .ucode_api_max = IWL2030_UCODE_API_MAX, \
477 .ucode_api_min = IWL2030_UCODE_API_MIN, \
478 .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \
479 .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \
480 .ops = &iwl2030_ops, \
481 .mod_params = &iwlagn_mod_params, \
482 .base_params = &iwl2030_base_params, \
483 .bt_params = &iwl2030_bt_params, \
484 .need_dc_calib = true, \
485 .need_temp_offset_calib = true, \
486 .led_mode = IWL_LED_RF_STATE, \
487 .adv_pm = true \
488
489struct iwl_cfg iwl6035_2agn_cfg = {
490 .name = "2000 Series 2x2 AGN/BT",
491 IWL_DEVICE_6035,
492 .ht_params = &iwl2000_ht_params,
493};
494
495struct iwl_cfg iwl6035_2abg_cfg = {
496 .name = "2000 Series 2x2 ABG/BT",
497 IWL_DEVICE_6035,
498};
499
500struct iwl_cfg iwl6035_2bg_cfg = {
501 .name = "2000 Series 2x2 BG/BT",
502 IWL_DEVICE_6035,
503};
504
505#define IWL_DEVICE_200 \ 459#define IWL_DEVICE_200 \
506 .fw_name_pre = IWL200_FW_PRE, \ 460 .fw_name_pre = IWL200_FW_PRE, \
507 .ucode_api_max = IWL200_UCODE_API_MAX, \ 461 .ucode_api_max = IWL200_UCODE_API_MAX, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 3975e45e7500..05ad47628b63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 22e045b5bcee..66f5fe8fe1ac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -185,7 +185,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
187 187
188 priv->hw_params.max_bsm_size = 0;
189 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 188 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
190 BIT(IEEE80211_BAND_5GHZ); 189 BIT(IEEE80211_BAND_5GHZ);
191 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 190 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -231,7 +230,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
231 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 230 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
232 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 231 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
233 232
234 priv->hw_params.max_bsm_size = 0;
235 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 233 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
236 BIT(IEEE80211_BAND_5GHZ); 234 BIT(IEEE80211_BAND_5GHZ);
237 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 235 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -348,8 +346,6 @@ static struct iwl_lib_ops iwl5000_lib = {
348 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 346 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
349 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 347 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
350 .txq_set_sched = iwlagn_txq_set_sched, 348 .txq_set_sched = iwlagn_txq_set_sched,
351 .txq_agg_enable = iwlagn_txq_agg_enable,
352 .txq_agg_disable = iwlagn_txq_agg_disable,
353 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 349 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
354 .txq_free_tfd = iwl_hw_txq_free_tfd, 350 .txq_free_tfd = iwl_hw_txq_free_tfd,
355 .txq_init = iwl_hw_tx_queue_init, 351 .txq_init = iwl_hw_tx_queue_init,
@@ -360,9 +356,6 @@ static struct iwl_lib_ops iwl5000_lib = {
360 .dump_nic_error_log = iwl_dump_nic_error_log, 356 .dump_nic_error_log = iwl_dump_nic_error_log,
361 .dump_csr = iwl_dump_csr, 357 .dump_csr = iwl_dump_csr,
362 .dump_fh = iwl_dump_fh, 358 .dump_fh = iwl_dump_fh,
363 .load_ucode = iwlagn_load_ucode,
364 .init_alive_start = iwlagn_init_alive_start,
365 .alive_notify = iwlagn_alive_notify,
366 .send_tx_power = iwlagn_send_tx_power, 359 .send_tx_power = iwlagn_send_tx_power,
367 .update_chain_flags = iwl_update_chain_flags, 360 .update_chain_flags = iwl_update_chain_flags,
368 .set_channel_switch = iwl5000_hw_channel_switch, 361 .set_channel_switch = iwl5000_hw_channel_switch,
@@ -385,13 +378,6 @@ static struct iwl_lib_ops iwl5000_lib = {
385 .calib_version = iwlagn_eeprom_calib_version, 378 .calib_version = iwlagn_eeprom_calib_version,
386 .query_addr = iwlagn_eeprom_query_addr, 379 .query_addr = iwlagn_eeprom_query_addr,
387 }, 380 },
388 .isr_ops = {
389 .isr = iwl_isr_ict,
390 .free = iwl_free_isr_ict,
391 .alloc = iwl_alloc_isr_ict,
392 .reset = iwl_reset_ict,
393 .disable = iwl_disable_ict,
394 },
395 .temp_ops = { 381 .temp_ops = {
396 .temperature = iwlagn_temperature, 382 .temperature = iwlagn_temperature,
397 }, 383 },
@@ -416,8 +402,6 @@ static struct iwl_lib_ops iwl5150_lib = {
416 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 402 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
417 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 403 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
418 .txq_set_sched = iwlagn_txq_set_sched, 404 .txq_set_sched = iwlagn_txq_set_sched,
419 .txq_agg_enable = iwlagn_txq_agg_enable,
420 .txq_agg_disable = iwlagn_txq_agg_disable,
421 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 405 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
422 .txq_free_tfd = iwl_hw_txq_free_tfd, 406 .txq_free_tfd = iwl_hw_txq_free_tfd,
423 .txq_init = iwl_hw_tx_queue_init, 407 .txq_init = iwl_hw_tx_queue_init,
@@ -427,9 +411,6 @@ static struct iwl_lib_ops iwl5150_lib = {
427 .dump_nic_event_log = iwl_dump_nic_event_log, 411 .dump_nic_event_log = iwl_dump_nic_event_log,
428 .dump_nic_error_log = iwl_dump_nic_error_log, 412 .dump_nic_error_log = iwl_dump_nic_error_log,
429 .dump_csr = iwl_dump_csr, 413 .dump_csr = iwl_dump_csr,
430 .load_ucode = iwlagn_load_ucode,
431 .init_alive_start = iwlagn_init_alive_start,
432 .alive_notify = iwlagn_alive_notify,
433 .send_tx_power = iwlagn_send_tx_power, 414 .send_tx_power = iwlagn_send_tx_power,
434 .update_chain_flags = iwl_update_chain_flags, 415 .update_chain_flags = iwl_update_chain_flags,
435 .set_channel_switch = iwl5000_hw_channel_switch, 416 .set_channel_switch = iwl5000_hw_channel_switch,
@@ -452,13 +433,6 @@ static struct iwl_lib_ops iwl5150_lib = {
452 .calib_version = iwlagn_eeprom_calib_version, 433 .calib_version = iwlagn_eeprom_calib_version,
453 .query_addr = iwlagn_eeprom_query_addr, 434 .query_addr = iwlagn_eeprom_query_addr,
454 }, 435 },
455 .isr_ops = {
456 .isr = iwl_isr_ict,
457 .free = iwl_free_isr_ict,
458 .alloc = iwl_alloc_isr_ict,
459 .reset = iwl_reset_ict,
460 .disable = iwl_disable_ict,
461 },
462 .temp_ops = { 436 .temp_ops = {
463 .temperature = iwl5150_temperature, 437 .temperature = iwl5150_temperature,
464 }, 438 },
@@ -500,7 +474,6 @@ static struct iwl_base_params iwl5000_base_params = {
500 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 474 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
501 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 475 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
502 .set_l0s = true, 476 .set_l0s = true,
503 .use_bsm = false,
504 .led_compensation = 51, 477 .led_compensation = 51,
505 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 478 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
506 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 479 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 47891e16a758..b27986e57c92 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a745b01c0ec1..24d105b29aec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -176,7 +176,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
176 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; 176 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
177 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; 177 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
178 178
179 priv->hw_params.max_bsm_size = 0;
180 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 179 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
181 BIT(IEEE80211_BAND_5GHZ); 180 BIT(IEEE80211_BAND_5GHZ);
182 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 181 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -288,21 +287,16 @@ static struct iwl_lib_ops iwl6000_lib = {
288 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 287 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
289 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 288 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
290 .txq_set_sched = iwlagn_txq_set_sched, 289 .txq_set_sched = iwlagn_txq_set_sched,
291 .txq_agg_enable = iwlagn_txq_agg_enable,
292 .txq_agg_disable = iwlagn_txq_agg_disable,
293 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 290 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
294 .txq_free_tfd = iwl_hw_txq_free_tfd, 291 .txq_free_tfd = iwl_hw_txq_free_tfd,
295 .txq_init = iwl_hw_tx_queue_init, 292 .txq_init = iwl_hw_tx_queue_init,
296 .rx_handler_setup = iwlagn_rx_handler_setup, 293 .rx_handler_setup = iwlagn_rx_handler_setup,
297 .setup_deferred_work = iwlagn_setup_deferred_work, 294 .setup_deferred_work = iwlagn_setup_deferred_work,
298 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 295 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
299 .load_ucode = iwlagn_load_ucode,
300 .dump_nic_event_log = iwl_dump_nic_event_log, 296 .dump_nic_event_log = iwl_dump_nic_event_log,
301 .dump_nic_error_log = iwl_dump_nic_error_log, 297 .dump_nic_error_log = iwl_dump_nic_error_log,
302 .dump_csr = iwl_dump_csr, 298 .dump_csr = iwl_dump_csr,
303 .dump_fh = iwl_dump_fh, 299 .dump_fh = iwl_dump_fh,
304 .init_alive_start = iwlagn_init_alive_start,
305 .alive_notify = iwlagn_alive_notify,
306 .send_tx_power = iwlagn_send_tx_power, 300 .send_tx_power = iwlagn_send_tx_power,
307 .update_chain_flags = iwl_update_chain_flags, 301 .update_chain_flags = iwl_update_chain_flags,
308 .set_channel_switch = iwl6000_hw_channel_switch, 302 .set_channel_switch = iwl6000_hw_channel_switch,
@@ -326,13 +320,6 @@ static struct iwl_lib_ops iwl6000_lib = {
326 .query_addr = iwlagn_eeprom_query_addr, 320 .query_addr = iwlagn_eeprom_query_addr,
327 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 321 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
328 }, 322 },
329 .isr_ops = {
330 .isr = iwl_isr_ict,
331 .free = iwl_free_isr_ict,
332 .alloc = iwl_alloc_isr_ict,
333 .reset = iwl_reset_ict,
334 .disable = iwl_disable_ict,
335 },
336 .temp_ops = { 323 .temp_ops = {
337 .temperature = iwlagn_temperature, 324 .temperature = iwlagn_temperature,
338 }, 325 },
@@ -357,8 +344,6 @@ static struct iwl_lib_ops iwl6030_lib = {
357 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 344 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
358 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, 345 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
359 .txq_set_sched = iwlagn_txq_set_sched, 346 .txq_set_sched = iwlagn_txq_set_sched,
360 .txq_agg_enable = iwlagn_txq_agg_enable,
361 .txq_agg_disable = iwlagn_txq_agg_disable,
362 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 347 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
363 .txq_free_tfd = iwl_hw_txq_free_tfd, 348 .txq_free_tfd = iwl_hw_txq_free_tfd,
364 .txq_init = iwl_hw_tx_queue_init, 349 .txq_init = iwl_hw_tx_queue_init,
@@ -366,13 +351,10 @@ static struct iwl_lib_ops iwl6030_lib = {
366 .setup_deferred_work = iwlagn_bt_setup_deferred_work, 351 .setup_deferred_work = iwlagn_bt_setup_deferred_work,
367 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, 352 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
368 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 353 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
369 .load_ucode = iwlagn_load_ucode,
370 .dump_nic_event_log = iwl_dump_nic_event_log, 354 .dump_nic_event_log = iwl_dump_nic_event_log,
371 .dump_nic_error_log = iwl_dump_nic_error_log, 355 .dump_nic_error_log = iwl_dump_nic_error_log,
372 .dump_csr = iwl_dump_csr, 356 .dump_csr = iwl_dump_csr,
373 .dump_fh = iwl_dump_fh, 357 .dump_fh = iwl_dump_fh,
374 .init_alive_start = iwlagn_init_alive_start,
375 .alive_notify = iwlagn_alive_notify,
376 .send_tx_power = iwlagn_send_tx_power, 358 .send_tx_power = iwlagn_send_tx_power,
377 .update_chain_flags = iwl_update_chain_flags, 359 .update_chain_flags = iwl_update_chain_flags,
378 .set_channel_switch = iwl6000_hw_channel_switch, 360 .set_channel_switch = iwl6000_hw_channel_switch,
@@ -396,13 +378,6 @@ static struct iwl_lib_ops iwl6030_lib = {
396 .query_addr = iwlagn_eeprom_query_addr, 378 .query_addr = iwlagn_eeprom_query_addr,
397 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 379 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
398 }, 380 },
399 .isr_ops = {
400 .isr = iwl_isr_ict,
401 .free = iwl_free_isr_ict,
402 .alloc = iwl_alloc_isr_ict,
403 .reset = iwl_reset_ict,
404 .disable = iwl_disable_ict,
405 },
406 .temp_ops = { 381 .temp_ops = {
407 .temperature = iwlagn_temperature, 382 .temperature = iwlagn_temperature,
408 }, 383 },
@@ -470,7 +445,6 @@ static struct iwl_base_params iwl6000_base_params = {
470 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 445 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
471 .pll_cfg_val = 0, 446 .pll_cfg_val = 0,
472 .set_l0s = true, 447 .set_l0s = true,
473 .use_bsm = false,
474 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 448 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
475 .shadow_ram_support = true, 449 .shadow_ram_support = true,
476 .led_compensation = 51, 450 .led_compensation = 51,
@@ -493,7 +467,6 @@ static struct iwl_base_params iwl6050_base_params = {
493 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 467 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
494 .pll_cfg_val = 0, 468 .pll_cfg_val = 0,
495 .set_l0s = true, 469 .set_l0s = true,
496 .use_bsm = false,
497 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 470 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
498 .shadow_ram_support = true, 471 .shadow_ram_support = true,
499 .led_compensation = 51, 472 .led_compensation = 51,
@@ -515,7 +488,6 @@ static struct iwl_base_params iwl6000_g2_base_params = {
515 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 488 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
516 .pll_cfg_val = 0, 489 .pll_cfg_val = 0,
517 .set_l0s = true, 490 .set_l0s = true,
518 .use_bsm = false,
519 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 491 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
520 .shadow_ram_support = true, 492 .shadow_ram_support = true,
521 .led_compensation = 57, 493 .led_compensation = 57,
@@ -613,6 +585,22 @@ struct iwl_cfg iwl6030_2bg_cfg = {
613 IWL_DEVICE_6030, 585 IWL_DEVICE_6030,
614}; 586};
615 587
588struct iwl_cfg iwl6035_2agn_cfg = {
589 .name = "6035 Series 2x2 AGN/BT",
590 IWL_DEVICE_6030,
591 .ht_params = &iwl6000_ht_params,
592};
593
594struct iwl_cfg iwl6035_2abg_cfg = {
595 .name = "6035 Series 2x2 ABG/BT",
596 IWL_DEVICE_6030,
597};
598
599struct iwl_cfg iwl6035_2bg_cfg = {
600 .name = "6035 Series 2x2 BG/BT",
601 IWL_DEVICE_6030,
602};
603
616struct iwl_cfg iwl1030_bgn_cfg = { 604struct iwl_cfg iwl1030_bgn_cfg = {
617 .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", 605 .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
618 IWL_DEVICE_6030, 606 IWL_DEVICE_6030,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 9006293e740c..7b761de77b0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index e37ae7261630..ef4d5079a7ed 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index b500aaae53ec..d1834aa7edf0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -1,30 +1,30 @@
1/****************************************************************************** 1/******************************************************************************
2* 2 *
3* GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4* 4 *
5* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6* 6 *
7* This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8* it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
9* published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10* 10 *
11* This program is distributed in the hope that it will be useful, but 11 * This program is distributed in the hope that it will be useful, but
12* WITHOUT ANY WARRANTY; without even the implied warranty of 12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14* General Public License for more details. 14 * General Public License for more details.
15* 15 *
16* You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19* USA 19 * USA
20* 20 *
21* The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22* in the file called LICENSE.GPL. 22 * in the file called LICENSE.GPL.
23* 23 *
24* Contact Information: 24 * Contact Information:
25* Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
26* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27*****************************************************************************/ 27 *****************************************************************************/
28#include "iwl-agn.h" 28#include "iwl-agn.h"
29#include "iwl-agn-debugfs.h" 29#include "iwl-agn-debugfs.h"
30 30
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
index f2573b5486cd..9a3f329e508f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index 27b5a3eec9dc..3bcaa10f9929 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -103,7 +103,7 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
103 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, 103 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
104 EEPROM_SEM_TIMEOUT); 104 EEPROM_SEM_TIMEOUT);
105 if (ret >= 0) { 105 if (ret >= 0) {
106 IWL_DEBUG_IO(priv, 106 IWL_DEBUG_EEPROM(priv,
107 "Acquired semaphore after %d tries.\n", 107 "Acquired semaphore after %d tries.\n",
108 count+1); 108 count+1);
109 return ret; 109 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 41543ad4cb84..861cc93957a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index a52b82c8e7a6..7bd19f4e66de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index ed0148d714de..0d5fda44c3a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -59,8 +59,6 @@ void iwl_free_isr_ict(struct iwl_priv *priv)
59int iwl_alloc_isr_ict(struct iwl_priv *priv) 59int iwl_alloc_isr_ict(struct iwl_priv *priv)
60{ 60{
61 61
62 if (priv->cfg->base_params->use_isr_legacy)
63 return 0;
64 /* allocate shrared data table */ 62 /* allocate shrared data table */
65 priv->_agn.ict_tbl_vir = 63 priv->_agn.ict_tbl_vir =
66 dma_alloc_coherent(&priv->pci_dev->dev, 64 dma_alloc_coherent(&priv->pci_dev->dev,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
index c1190d965614..4bb877e600c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
index 96f323dc5dd6..c0b7611b72c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 08ccb9496f76..9e47be6a7393 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -652,8 +652,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
652 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ 652 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
653 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ 653 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
654 654
655 if (!priv->cfg->base_params->use_isr_legacy) 655 rb_timeout = RX_RB_TIMEOUT;
656 rb_timeout = RX_RB_TIMEOUT;
657 656
658 if (priv->cfg->mod_params->amsdu_size_8K) 657 if (priv->cfg->mod_params->amsdu_size_8K)
659 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; 658 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
@@ -913,7 +912,6 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
913 912
914 list_add_tail(&rxb->list, &rxq->rx_free); 913 list_add_tail(&rxb->list, &rxq->rx_free);
915 rxq->free_count++; 914 rxq->free_count++;
916 priv->alloc_rxb_page++;
917 915
918 spin_unlock_irqrestore(&rxq->lock, flags); 916 spin_unlock_irqrestore(&rxq->lock, flags);
919 } 917 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index d03b4734c892..dbe6295bbf23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -115,13 +115,18 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
115 /* FIXME:RS: ^^ should be INV (legacy) */ 115 /* FIXME:RS: ^^ should be INV (legacy) */
116}; 116};
117 117
118static inline u8 rs_extract_rate(u32 rate_n_flags)
119{
120 return (u8)(rate_n_flags & RATE_MCS_RATE_MSK);
121}
122
118static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) 123static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
119{ 124{
120 int idx = 0; 125 int idx = 0;
121 126
122 /* HT rate format */ 127 /* HT rate format */
123 if (rate_n_flags & RATE_MCS_HT_MSK) { 128 if (rate_n_flags & RATE_MCS_HT_MSK) {
124 idx = (rate_n_flags & 0xff); 129 idx = rs_extract_rate(rate_n_flags);
125 130
126 if (idx >= IWL_RATE_MIMO3_6M_PLCP) 131 if (idx >= IWL_RATE_MIMO3_6M_PLCP)
127 idx = idx - IWL_RATE_MIMO3_6M_PLCP; 132 idx = idx - IWL_RATE_MIMO3_6M_PLCP;
@@ -138,7 +143,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
138 /* legacy rate format, search for match in table */ 143 /* legacy rate format, search for match in table */
139 } else { 144 } else {
140 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) 145 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
141 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) 146 if (iwl_rates[idx].plcp ==
147 rs_extract_rate(rate_n_flags))
142 return idx; 148 return idx;
143 } 149 }
144 150
@@ -239,11 +245,6 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
239 245
240#define MCS_INDEX_PER_STREAM (8) 246#define MCS_INDEX_PER_STREAM (8)
241 247
242static inline u8 rs_extract_rate(u32 rate_n_flags)
243{
244 return (u8)(rate_n_flags & 0xFF);
245}
246
247static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 248static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
248{ 249{
249 window->data = 0; 250 window->data = 0;
@@ -2770,16 +2771,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2770static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, 2771static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
2771 gfp_t gfp) 2772 gfp_t gfp)
2772{ 2773{
2773 struct iwl_lq_sta *lq_sta;
2774 struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; 2774 struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
2775 struct iwl_priv *priv; 2775 struct iwl_priv *priv;
2776 2776
2777 priv = (struct iwl_priv *)priv_rate; 2777 priv = (struct iwl_priv *)priv_rate;
2778 IWL_DEBUG_RATE(priv, "create station rate scale window\n"); 2778 IWL_DEBUG_RATE(priv, "create station rate scale window\n");
2779 2779
2780 lq_sta = &sta_priv->lq_sta; 2780 return &sta_priv->lq_sta;
2781
2782 return lq_sta;
2783} 2781}
2784 2782
2785/* 2783/*
@@ -2912,7 +2910,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2912 ant_toggle_cnt = 1; 2910 ant_toggle_cnt = 1;
2913 repeat_rate = IWL_NUMBER_TRY; 2911 repeat_rate = IWL_NUMBER_TRY;
2914 } else { 2912 } else {
2915 repeat_rate = IWL_HT_NUMBER_TRY; 2913 repeat_rate = min(IWL_HT_NUMBER_TRY,
2914 LINK_QUAL_AGG_DISABLE_START_DEF - 1);
2916 } 2915 }
2917 2916
2918 lq_cmd->general_params.mimo_delimiter = 2917 lq_cmd->general_params.mimo_delimiter =
@@ -3257,7 +3256,6 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
3257{ 3256{
3258 char buff[120]; 3257 char buff[120];
3259 int desc = 0; 3258 int desc = 0;
3260 ssize_t ret;
3261 3259
3262 struct iwl_lq_sta *lq_sta = file->private_data; 3260 struct iwl_lq_sta *lq_sta = file->private_data;
3263 struct iwl_priv *priv; 3261 struct iwl_priv *priv;
@@ -3274,8 +3272,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
3274 "Bit Rate= %d Mb/s\n", 3272 "Bit Rate= %d Mb/s\n",
3275 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); 3273 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
3276 3274
3277 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 3275 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
3278 return ret;
3279} 3276}
3280 3277
3281static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { 3278static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 184828c72b31..69a29932babc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -41,20 +41,6 @@ struct iwl_rate_info {
41 u8 next_rs_tgg; /* next rate used in TGG rs algo */ 41 u8 next_rs_tgg; /* next rate used in TGG rs algo */
42}; 42};
43 43
44struct iwl3945_rate_info {
45 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
46 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
47 u8 prev_ieee; /* previous rate in IEEE speeds */
48 u8 next_ieee; /* next rate in IEEE speeds */
49 u8 prev_rs; /* previous rate used in rs algo */
50 u8 next_rs; /* next rate used in rs algo */
51 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
52 u8 next_rs_tgg; /* next rate used in TGG rs algo */
53 u8 table_rs_index; /* index in rate scale table cmd */
54 u8 prev_table_rs; /* prev in rate table cmd */
55};
56
57
58/* 44/*
59 * These serve as indexes into 45 * These serve as indexes into
60 * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; 46 * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -75,7 +61,6 @@ enum {
75 IWL_RATE_60M_INDEX, 61 IWL_RATE_60M_INDEX,
76 IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/ 62 IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
77 IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */ 63 IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */
78 IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
79 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, 64 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
80 IWL_RATE_INVALID = IWL_RATE_COUNT, 65 IWL_RATE_INVALID = IWL_RATE_COUNT,
81}; 66};
@@ -213,7 +198,6 @@ enum {
213 IWL_CCK_BASIC_RATES_MASK) 198 IWL_CCK_BASIC_RATES_MASK)
214 199
215#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) 200#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
216#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1)
217 201
218#define IWL_INVALID_VALUE -1 202#define IWL_INVALID_VALUE -1
219 203
@@ -453,19 +437,9 @@ static inline u8 first_antenna(u8 mask)
453} 437}
454 438
455 439
456/**
457 * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
458 *
459 * The specific throughput table used is based on the type of network
460 * the associated with, including A, B, G, and G w/ TGG protection
461 */
462extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
463
464/* Initialize station's rate scaling information after adding station */ 440/* Initialize station's rate scaling information after adding station */
465extern void iwl_rs_rate_init(struct iwl_priv *priv, 441extern void iwl_rs_rate_init(struct iwl_priv *priv,
466 struct ieee80211_sta *sta, u8 sta_id); 442 struct ieee80211_sta *sta, u8 sta_id);
467extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
468 struct ieee80211_sta *sta, u8 sta_id);
469 443
470/** 444/**
471 * iwl_rate_control_register - Register the rate control algorithm callbacks 445 * iwl_rate_control_register - Register the rate control algorithm callbacks
@@ -478,7 +452,6 @@ extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
478 * 452 *
479 */ 453 */
480extern int iwlagn_rate_control_register(void); 454extern int iwlagn_rate_control_register(void);
481extern int iwl3945_rate_control_register(void);
482 455
483/** 456/**
484 * iwl_rate_control_unregister - Unregister the rate control callbacks 457 * iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -487,6 +460,5 @@ extern int iwl3945_rate_control_register(void);
487 * the driver is unloaded. 460 * the driver is unloaded.
488 */ 461 */
489extern void iwlagn_rate_control_unregister(void); 462extern void iwlagn_rate_control_unregister(void);
490extern void iwl3945_rate_control_unregister(void);
491 463
492#endif /* __iwl_agn__rs__ */ 464#endif /* __iwl_agn__rs__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index dfdbea6e8f99..c335ee6883ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 35f085ac336b..079275f2c64d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -474,7 +474,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
474 memset(&priv->stations[sta_id].keyinfo, 0, 474 memset(&priv->stations[sta_id].keyinfo, 0,
475 sizeof(struct iwl_hw_key)); 475 sizeof(struct iwl_hw_key));
476 memset(&priv->stations[sta_id].sta.key, 0, 476 memset(&priv->stations[sta_id].sta.key, 0,
477 sizeof(struct iwl4965_keyinfo)); 477 sizeof(struct iwl_keyinfo));
478 priv->stations[sta_id].sta.key.key_flags = 478 priv->stations[sta_id].sta.key.key_flags =
479 STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; 479 STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
480 priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; 480 priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index e3a8216a033c..348f74f1c8e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
index d55060427cac..d118ed29bf3f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index a709d05c5868..2816b432c62f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -222,13 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
222 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); 222 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
223} 223}
224 224
225int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, 225static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
226 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
227{ 226{
228 unsigned long flags;
229 u16 ra_tid;
230 int ret;
231
232 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 227 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
233 (IWLAGN_FIRST_AMPDU_QUEUE + 228 (IWLAGN_FIRST_AMPDU_QUEUE +
234 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { 229 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
@@ -240,12 +235,33 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
240 return -EINVAL; 235 return -EINVAL;
241 } 236 }
242 237
243 ra_tid = BUILD_RAxTID(sta_id, tid);
244
245 /* Modify device's station table to Tx this TID */ 238 /* Modify device's station table to Tx this TID */
246 ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 239 return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
247 if (ret) 240}
248 return ret; 241
242void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
243 struct ieee80211_sta *sta,
244 int tid, int frame_limit)
245{
246 int sta_id, tx_fifo, txq_id, ssn_idx;
247 u16 ra_tid;
248 unsigned long flags;
249 struct iwl_tid_data *tid_data;
250
251 sta_id = iwl_sta_id(sta);
252 if (WARN_ON(sta_id == IWL_INVALID_STATION))
253 return;
254 if (WARN_ON(tid >= MAX_TID_COUNT))
255 return;
256
257 spin_lock_irqsave(&priv->sta_lock, flags);
258 tid_data = &priv->stations[sta_id].tid[tid];
259 ssn_idx = SEQ_TO_SN(tid_data->seq_number);
260 txq_id = tid_data->agg.txq_id;
261 tx_fifo = tid_data->agg.tx_fifo;
262 spin_unlock_irqrestore(&priv->sta_lock, flags);
263
264 ra_tid = BUILD_RAxTID(sta_id, tid);
249 265
250 spin_lock_irqsave(&priv->lock, flags); 266 spin_lock_irqsave(&priv->lock, flags);
251 267
@@ -271,10 +287,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
271 iwl_write_targ_mem(priv, priv->scd_base_addr + 287 iwl_write_targ_mem(priv, priv->scd_base_addr +
272 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + 288 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
273 sizeof(u32), 289 sizeof(u32),
274 ((SCD_WIN_SIZE << 290 ((frame_limit <<
275 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & 291 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
276 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | 292 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
277 ((SCD_FRAME_LIMIT << 293 ((frame_limit <<
278 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & 294 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
279 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); 295 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
280 296
@@ -284,12 +300,10 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
284 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); 300 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
285 301
286 spin_unlock_irqrestore(&priv->lock, flags); 302 spin_unlock_irqrestore(&priv->lock, flags);
287
288 return 0;
289} 303}
290 304
291int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, 305static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
292 u16 ssn_idx, u8 tx_fifo) 306 u16 ssn_idx, u8 tx_fifo)
293{ 307{
294 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 308 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
295 (IWLAGN_FIRST_AMPDU_QUEUE + 309 (IWLAGN_FIRST_AMPDU_QUEUE +
@@ -1034,11 +1048,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1034 tid_data = &priv->stations[sta_id].tid[tid]; 1048 tid_data = &priv->stations[sta_id].tid[tid];
1035 *ssn = SEQ_TO_SN(tid_data->seq_number); 1049 *ssn = SEQ_TO_SN(tid_data->seq_number);
1036 tid_data->agg.txq_id = txq_id; 1050 tid_data->agg.txq_id = txq_id;
1051 tid_data->agg.tx_fifo = tx_fifo;
1037 iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); 1052 iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
1038 spin_unlock_irqrestore(&priv->sta_lock, flags); 1053 spin_unlock_irqrestore(&priv->sta_lock, flags);
1039 1054
1040 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, 1055 ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid);
1041 sta_id, tid, *ssn);
1042 if (ret) 1056 if (ret)
1043 return ret; 1057 return ret;
1044 1058
@@ -1125,8 +1139,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1125 * to deactivate the uCode queue, just return "success" to allow 1139 * to deactivate the uCode queue, just return "success" to allow
1126 * mac80211 to clean up it own data. 1140 * mac80211 to clean up it own data.
1127 */ 1141 */
1128 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, 1142 iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id);
1129 tx_fifo_id);
1130 spin_unlock_irqrestore(&priv->lock, flags); 1143 spin_unlock_irqrestore(&priv->lock, flags);
1131 1144
1132 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1145 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -1155,8 +1168,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1155 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 1168 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1156 int tx_fifo = get_fifo_from_tid(ctx, tid); 1169 int tx_fifo = get_fifo_from_tid(ctx, tid);
1157 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); 1170 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1158 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, 1171 iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo);
1159 ssn, tx_fifo);
1160 tid_data->agg.state = IWL_AGG_OFF; 1172 tid_data->agg.state = IWL_AGG_OFF;
1161 ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); 1173 ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
1162 } 1174 }
@@ -1251,11 +1263,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1251 struct iwl_compressed_ba_resp *ba_resp) 1263 struct iwl_compressed_ba_resp *ba_resp)
1252 1264
1253{ 1265{
1254 int i, sh, ack; 1266 int sh;
1255 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); 1267 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1256 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1268 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1257 int successes = 0;
1258 struct ieee80211_tx_info *info; 1269 struct ieee80211_tx_info *info;
1270 u64 bitmap, sent_bitmap;
1259 1271
1260 if (unlikely(!agg->wait_for_ba)) { 1272 if (unlikely(!agg->wait_for_ba)) {
1261 if (unlikely(ba_resp->bitmap)) 1273 if (unlikely(ba_resp->bitmap))
@@ -1269,70 +1281,42 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1269 1281
1270 /* Calculate shift to align block-ack bits with our Tx window bits */ 1282 /* Calculate shift to align block-ack bits with our Tx window bits */
1271 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4); 1283 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1272 if (sh < 0) /* tbw something is wrong with indices */ 1284 if (sh < 0)
1273 sh += 0x100; 1285 sh += 0x100;
1274 1286
1275 if (agg->frame_count > (64 - sh)) { 1287 /*
1276 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); 1288 * Check for success or failure according to the
1277 return -1; 1289 * transmitted bitmap and block-ack bitmap
1278 } 1290 */
1279 if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { 1291 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1292 sent_bitmap = bitmap & agg->bitmap;
1293
1294 /* Sanity check values reported by uCode */
1295 if (ba_resp->txed_2_done > ba_resp->txed) {
1296 IWL_DEBUG_TX_REPLY(priv,
1297 "bogus sent(%d) and ack(%d) count\n",
1298 ba_resp->txed, ba_resp->txed_2_done);
1280 /* 1299 /*
1281 * sent and ack information provided by uCode 1300 * set txed_2_done = txed,
1282 * use it instead of figure out ourself 1301 * so it won't impact rate scale
1283 */ 1302 */
1284 if (ba_resp->txed_2_done > ba_resp->txed) { 1303 ba_resp->txed = ba_resp->txed_2_done;
1285 IWL_DEBUG_TX_REPLY(priv, 1304 }
1286 "bogus sent(%d) and ack(%d) count\n", 1305 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
1287 ba_resp->txed, ba_resp->txed_2_done); 1306 ba_resp->txed, ba_resp->txed_2_done);
1288 /*
1289 * set txed_2_done = txed,
1290 * so it won't impact rate scale
1291 */
1292 ba_resp->txed = ba_resp->txed_2_done;
1293 }
1294 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
1295 ba_resp->txed, ba_resp->txed_2_done);
1296 } else {
1297 u64 bitmap, sent_bitmap;
1298
1299 /* don't use 64-bit values for now */
1300 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1301
1302 /* check for success or failure according to the
1303 * transmitted bitmap and block-ack bitmap */
1304 sent_bitmap = bitmap & agg->bitmap;
1305
1306 /* For each frame attempted in aggregation,
1307 * update driver's record of tx frame's status. */
1308 i = 0;
1309 while (sent_bitmap) {
1310 ack = sent_bitmap & 1ULL;
1311 successes += ack;
1312 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1313 ack ? "ACK" : "NACK", i,
1314 (agg->start_idx + i) & 0xff,
1315 agg->start_idx + i);
1316 sent_bitmap >>= 1;
1317 ++i;
1318 }
1319 1307
1320 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", 1308 /* Find the first ACKed frame to store the TX status */
1321 (unsigned long long)bitmap); 1309 while (sent_bitmap && !(sent_bitmap & 1)) {
1310 agg->start_idx = (agg->start_idx + 1) & 0xff;
1311 sent_bitmap >>= 1;
1322 } 1312 }
1323 1313
1324 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); 1314 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
1325 memset(&info->status, 0, sizeof(info->status)); 1315 memset(&info->status, 0, sizeof(info->status));
1326 info->flags |= IEEE80211_TX_STAT_ACK; 1316 info->flags |= IEEE80211_TX_STAT_ACK;
1327 info->flags |= IEEE80211_TX_STAT_AMPDU; 1317 info->flags |= IEEE80211_TX_STAT_AMPDU;
1328 if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { 1318 info->status.ampdu_ack_len = ba_resp->txed_2_done;
1329 info->status.ampdu_ack_len = ba_resp->txed_2_done; 1319 info->status.ampdu_len = ba_resp->txed;
1330 info->status.ampdu_len = ba_resp->txed;
1331
1332 } else {
1333 info->status.ampdu_ack_len = successes;
1334 info->status.ampdu_len = agg->frame_count;
1335 }
1336 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); 1320 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1337 1321
1338 return 0; 1322 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index d807e5e2b718..01a6d2fc795c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -311,14 +311,14 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
311 /* initialize uCode was loaded... verify inst image. 311 /* initialize uCode was loaded... verify inst image.
312 * This is a paranoid check, because we would not have gotten the 312 * This is a paranoid check, because we would not have gotten the
313 * "initialize" alive if code weren't properly loaded. */ 313 * "initialize" alive if code weren't properly loaded. */
314 if (iwl_verify_ucode(priv)) { 314 if (iwl_verify_ucode(priv, &priv->ucode_init)) {
315 /* Runtime instruction load was bad; 315 /* Runtime instruction load was bad;
316 * take it all the way back down so we can try again */ 316 * take it all the way back down so we can try again */
317 IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); 317 IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
318 goto restart; 318 goto restart;
319 } 319 }
320 320
321 ret = priv->cfg->ops->lib->alive_notify(priv); 321 ret = iwlagn_alive_notify(priv);
322 if (ret) { 322 if (ret) {
323 IWL_WARN(priv, 323 IWL_WARN(priv,
324 "Could not complete ALIVE transition: %d\n", ret); 324 "Could not complete ALIVE transition: %d\n", ret);
@@ -432,6 +432,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
432 unsigned long flags; 432 unsigned long flags;
433 int i, chan; 433 int i, chan;
434 u32 reg_val; 434 u32 reg_val;
435 int ret;
435 436
436 spin_lock_irqsave(&priv->lock, flags); 437 spin_lock_irqsave(&priv->lock, flags);
437 438
@@ -527,12 +528,15 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
527 iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG, 528 iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
528 APMG_PCIDEV_STT_VAL_L1_ACT_DIS); 529 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
529 530
530 iwlagn_send_wimax_coex(priv); 531 ret = iwlagn_send_wimax_coex(priv);
532 if (ret)
533 return ret;
531 534
532 iwlagn_set_Xtal_calib(priv); 535 ret = iwlagn_set_Xtal_calib(priv);
533 iwl_send_calib_results(priv); 536 if (ret)
537 return ret;
534 538
535 return 0; 539 return iwl_send_calib_results(priv);
536} 540}
537 541
538 542
@@ -541,11 +545,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
541 * using sample data 100 bytes apart. If these sample points are good, 545 * using sample data 100 bytes apart. If these sample points are good,
542 * it's a pretty good bet that everything between them is good, too. 546 * it's a pretty good bet that everything between them is good, too.
543 */ 547 */
544static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) 548static int iwlcore_verify_inst_sparse(struct iwl_priv *priv,
549 struct fw_desc *fw_desc)
545{ 550{
551 __le32 *image = (__le32 *)fw_desc->v_addr;
552 u32 len = fw_desc->len;
546 u32 val; 553 u32 val;
547 int ret = 0;
548 u32 errcnt = 0;
549 u32 i; 554 u32 i;
550 555
551 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); 556 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
@@ -556,104 +561,55 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
556 * if IWL_DL_IO is set */ 561 * if IWL_DL_IO is set */
557 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, 562 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
558 i + IWLAGN_RTC_INST_LOWER_BOUND); 563 i + IWLAGN_RTC_INST_LOWER_BOUND);
559 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 564 val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
560 if (val != le32_to_cpu(*image)) { 565 if (val != le32_to_cpu(*image))
561 ret = -EIO; 566 return -EIO;
562 errcnt++;
563 if (errcnt >= 3)
564 break;
565 }
566 } 567 }
567 568
568 return ret; 569 return 0;
569} 570}
570 571
571/** 572static void iwl_print_mismatch_inst(struct iwl_priv *priv,
572 * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host, 573 struct fw_desc *fw_desc)
573 * looking at all data.
574 */
575static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
576 u32 len)
577{ 574{
575 __le32 *image = (__le32 *)fw_desc->v_addr;
576 u32 len = fw_desc->len;
578 u32 val; 577 u32 val;
579 u32 save_len = len; 578 u32 offs;
580 int ret = 0; 579 int errors = 0;
581 u32 errcnt;
582 580
583 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); 581 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
584 582
585 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, 583 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
586 IWLAGN_RTC_INST_LOWER_BOUND); 584 IWLAGN_RTC_INST_LOWER_BOUND);
587 585
588 errcnt = 0; 586 for (offs = 0;
589 for (; len > 0; len -= sizeof(u32), image++) { 587 offs < len && errors < 20;
588 offs += sizeof(u32), image++) {
590 /* read data comes through single port, auto-incr addr */ 589 /* read data comes through single port, auto-incr addr */
591 /* NOTE: Use the debugless read so we don't flood kernel log 590 val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
592 * if IWL_DL_IO is set */
593 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
594 if (val != le32_to_cpu(*image)) { 591 if (val != le32_to_cpu(*image)) {
595 IWL_ERR(priv, "uCode INST section is invalid at " 592 IWL_ERR(priv, "uCode INST section at "
596 "offset 0x%x, is 0x%x, s/b 0x%x\n", 593 "offset 0x%x, is 0x%x, s/b 0x%x\n",
597 save_len - len, val, le32_to_cpu(*image)); 594 offs, val, le32_to_cpu(*image));
598 ret = -EIO; 595 errors++;
599 errcnt++;
600 if (errcnt >= 20)
601 break;
602 } 596 }
603 } 597 }
604
605 if (!errcnt)
606 IWL_DEBUG_INFO(priv,
607 "ucode image in INSTRUCTION memory is good\n");
608
609 return ret;
610} 598}
611 599
612/** 600/**
613 * iwl_verify_ucode - determine which instruction image is in SRAM, 601 * iwl_verify_ucode - determine which instruction image is in SRAM,
614 * and verify its contents 602 * and verify its contents
615 */ 603 */
616int iwl_verify_ucode(struct iwl_priv *priv) 604int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc)
617{ 605{
618 __le32 *image; 606 if (!iwlcore_verify_inst_sparse(priv, fw_desc)) {
619 u32 len; 607 IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
620 int ret;
621
622 /* Try bootstrap */
623 image = (__le32 *)priv->ucode_boot.v_addr;
624 len = priv->ucode_boot.len;
625 ret = iwlcore_verify_inst_sparse(priv, image, len);
626 if (!ret) {
627 IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
628 return 0;
629 }
630
631 /* Try initialize */
632 image = (__le32 *)priv->ucode_init.v_addr;
633 len = priv->ucode_init.len;
634 ret = iwlcore_verify_inst_sparse(priv, image, len);
635 if (!ret) {
636 IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
637 return 0;
638 }
639
640 /* Try runtime/protocol */
641 image = (__le32 *)priv->ucode_code.v_addr;
642 len = priv->ucode_code.len;
643 ret = iwlcore_verify_inst_sparse(priv, image, len);
644 if (!ret) {
645 IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
646 return 0; 608 return 0;
647 } 609 }
648 610
649 IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); 611 IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
650 612
651 /* Since nothing seems to match, show first several data entries in 613 iwl_print_mismatch_inst(priv, fw_desc);
652 * instruction SRAM, so maybe visual inspection will give a clue. 614 return -EIO;
653 * Selection of bootstrap image (vs. other images) is arbitrary. */
654 image = (__le32 *)priv->ucode_boot.v_addr;
655 len = priv->ucode_boot.len;
656 ret = iwl_verify_inst_full(priv, image, len);
657
658 return ret;
659} 615}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 321b18b59135..60bfde75ce87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -409,7 +409,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
409 * Tell nic where to find circular buffer of Tx Frame Descriptors for 409 * Tell nic where to find circular buffer of Tx Frame Descriptors for
410 * given Tx queue, and enable the DMA channel used for that queue. 410 * given Tx queue, and enable the DMA channel used for that queue.
411 * 411 *
412 * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA 412 * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
413 * channels supported in hardware. 413 * channels supported in hardware.
414 */ 414 */
415int iwl_hw_tx_queue_init(struct iwl_priv *priv, 415int iwl_hw_tx_queue_init(struct iwl_priv *priv,
@@ -483,12 +483,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
483 container_of(work, struct iwl_priv, bt_full_concurrency); 483 container_of(work, struct iwl_priv, bt_full_concurrency);
484 struct iwl_rxon_context *ctx; 484 struct iwl_rxon_context *ctx;
485 485
486 mutex_lock(&priv->mutex);
487
486 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 488 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
487 return; 489 goto out;
488 490
489 /* dont send host command if rf-kill is on */ 491 /* dont send host command if rf-kill is on */
490 if (!iwl_is_ready_rf(priv)) 492 if (!iwl_is_ready_rf(priv))
491 return; 493 goto out;
492 494
493 IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", 495 IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
494 priv->bt_full_concurrent ? 496 priv->bt_full_concurrent ?
@@ -498,15 +500,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
498 * LQ & RXON updated cmds must be sent before BT Config cmd 500 * LQ & RXON updated cmds must be sent before BT Config cmd
499 * to avoid 3-wire collisions 501 * to avoid 3-wire collisions
500 */ 502 */
501 mutex_lock(&priv->mutex);
502 for_each_context(priv, ctx) { 503 for_each_context(priv, ctx) {
503 if (priv->cfg->ops->hcmd->set_rxon_chain) 504 if (priv->cfg->ops->hcmd->set_rxon_chain)
504 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); 505 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
505 iwlcore_commit_rxon(priv, ctx); 506 iwlcore_commit_rxon(priv, ctx);
506 } 507 }
507 mutex_unlock(&priv->mutex);
508 508
509 priv->cfg->ops->hcmd->send_bt_config(priv); 509 priv->cfg->ops->hcmd->send_bt_config(priv);
510out:
511 mutex_unlock(&priv->mutex);
510} 512}
511 513
512/** 514/**
@@ -556,7 +558,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
556 } 558 }
557 559
558 /* Set starting address; reads will auto-increment */ 560 /* Set starting address; reads will auto-increment */
559 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); 561 iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
560 rmb(); 562 rmb();
561 563
562 /* 564 /*
@@ -564,13 +566,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
564 * place event id # at far right for easier visual parsing. 566 * place event id # at far right for easier visual parsing.
565 */ 567 */
566 for (i = 0; i < num_events; i++) { 568 for (i = 0; i < num_events; i++) {
567 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 569 ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
568 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 570 time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
569 if (mode == 0) { 571 if (mode == 0) {
570 trace_iwlwifi_dev_ucode_cont_event(priv, 572 trace_iwlwifi_dev_ucode_cont_event(priv,
571 0, time, ev); 573 0, time, ev);
572 } else { 574 } else {
573 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 575 data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
574 trace_iwlwifi_dev_ucode_cont_event(priv, 576 trace_iwlwifi_dev_ucode_cont_event(priv,
575 time, data, ev); 577 time, data, ev);
576 } 578 }
@@ -588,10 +590,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
588 u32 num_wraps; /* # times uCode wrapped to top of log */ 590 u32 num_wraps; /* # times uCode wrapped to top of log */
589 u32 next_entry; /* index of next entry to be written by uCode */ 591 u32 next_entry; /* index of next entry to be written by uCode */
590 592
591 if (priv->ucode_type == UCODE_INIT) 593 base = priv->device_pointers.error_event_table;
592 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
593 else
594 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
595 if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 594 if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
596 capacity = iwl_read_targ_mem(priv, base); 595 capacity = iwl_read_targ_mem(priv, base);
597 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 596 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
@@ -845,191 +844,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
845 tasklet_kill(&priv->irq_tasklet); 844 tasklet_kill(&priv->irq_tasklet);
846} 845}
847 846
848static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
849{
850 u32 inta, handled = 0;
851 u32 inta_fh;
852 unsigned long flags;
853 u32 i;
854#ifdef CONFIG_IWLWIFI_DEBUG
855 u32 inta_mask;
856#endif
857
858 spin_lock_irqsave(&priv->lock, flags);
859
860 /* Ack/clear/reset pending uCode interrupts.
861 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
862 * and will clear only when CSR_FH_INT_STATUS gets cleared. */
863 inta = iwl_read32(priv, CSR_INT);
864 iwl_write32(priv, CSR_INT, inta);
865
866 /* Ack/clear/reset pending flow-handler (DMA) interrupts.
867 * Any new interrupts that happen after this, either while we're
868 * in this tasklet, or later, will show up in next ISR/tasklet. */
869 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
870 iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
871
872#ifdef CONFIG_IWLWIFI_DEBUG
873 if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
874 /* just for debug */
875 inta_mask = iwl_read32(priv, CSR_INT_MASK);
876 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
877 inta, inta_mask, inta_fh);
878 }
879#endif
880
881 spin_unlock_irqrestore(&priv->lock, flags);
882
883 /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
884 * atomic, make sure that inta covers all the interrupts that
885 * we've discovered, even if FH interrupt came in just after
886 * reading CSR_INT. */
887 if (inta_fh & CSR49_FH_INT_RX_MASK)
888 inta |= CSR_INT_BIT_FH_RX;
889 if (inta_fh & CSR49_FH_INT_TX_MASK)
890 inta |= CSR_INT_BIT_FH_TX;
891
892 /* Now service all interrupt bits discovered above. */
893 if (inta & CSR_INT_BIT_HW_ERR) {
894 IWL_ERR(priv, "Hardware error detected. Restarting.\n");
895
896 /* Tell the device to stop sending interrupts */
897 iwl_disable_interrupts(priv);
898
899 priv->isr_stats.hw++;
900 iwl_irq_handle_error(priv);
901
902 handled |= CSR_INT_BIT_HW_ERR;
903
904 return;
905 }
906
907#ifdef CONFIG_IWLWIFI_DEBUG
908 if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
909 /* NIC fires this, but we don't use it, redundant with WAKEUP */
910 if (inta & CSR_INT_BIT_SCD) {
911 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
912 "the frame/frames.\n");
913 priv->isr_stats.sch++;
914 }
915
916 /* Alive notification via Rx interrupt will do the real work */
917 if (inta & CSR_INT_BIT_ALIVE) {
918 IWL_DEBUG_ISR(priv, "Alive interrupt\n");
919 priv->isr_stats.alive++;
920 }
921 }
922#endif
923 /* Safely ignore these bits for debug checks below */
924 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
925
926 /* HW RF KILL switch toggled */
927 if (inta & CSR_INT_BIT_RF_KILL) {
928 int hw_rf_kill = 0;
929 if (!(iwl_read32(priv, CSR_GP_CNTRL) &
930 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
931 hw_rf_kill = 1;
932
933 IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
934 hw_rf_kill ? "disable radio" : "enable radio");
935
936 priv->isr_stats.rfkill++;
937
938 /* driver only loads ucode once setting the interface up.
939 * the driver allows loading the ucode even if the radio
940 * is killed. Hence update the killswitch state here. The
941 * rfkill handler will care about restarting if needed.
942 */
943 if (!test_bit(STATUS_ALIVE, &priv->status)) {
944 if (hw_rf_kill)
945 set_bit(STATUS_RF_KILL_HW, &priv->status);
946 else
947 clear_bit(STATUS_RF_KILL_HW, &priv->status);
948 wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
949 }
950
951 handled |= CSR_INT_BIT_RF_KILL;
952 }
953
954 /* Chip got too hot and stopped itself */
955 if (inta & CSR_INT_BIT_CT_KILL) {
956 IWL_ERR(priv, "Microcode CT kill error detected.\n");
957 priv->isr_stats.ctkill++;
958 handled |= CSR_INT_BIT_CT_KILL;
959 }
960
961 /* Error detected by uCode */
962 if (inta & CSR_INT_BIT_SW_ERR) {
963 IWL_ERR(priv, "Microcode SW error detected. "
964 " Restarting 0x%X.\n", inta);
965 priv->isr_stats.sw++;
966 iwl_irq_handle_error(priv);
967 handled |= CSR_INT_BIT_SW_ERR;
968 }
969
970 /*
971 * uCode wakes up after power-down sleep.
972 * Tell device about any new tx or host commands enqueued,
973 * and about any Rx buffers made available while asleep.
974 */
975 if (inta & CSR_INT_BIT_WAKEUP) {
976 IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
977 iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
978 for (i = 0; i < priv->hw_params.max_txq_num; i++)
979 iwl_txq_update_write_ptr(priv, &priv->txq[i]);
980 priv->isr_stats.wakeup++;
981 handled |= CSR_INT_BIT_WAKEUP;
982 }
983
984 /* All uCode command responses, including Tx command responses,
985 * Rx "responses" (frame-received notification), and other
986 * notifications from uCode come through here*/
987 if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
988 iwl_rx_handle(priv);
989 priv->isr_stats.rx++;
990 handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
991 }
992
993 /* This "Tx" DMA channel is used only for loading uCode */
994 if (inta & CSR_INT_BIT_FH_TX) {
995 IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
996 priv->isr_stats.tx++;
997 handled |= CSR_INT_BIT_FH_TX;
998 /* Wake up uCode load routine, now that load is complete */
999 priv->ucode_write_complete = 1;
1000 wake_up_interruptible(&priv->wait_command_queue);
1001 }
1002
1003 if (inta & ~handled) {
1004 IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
1005 priv->isr_stats.unhandled++;
1006 }
1007
1008 if (inta & ~(priv->inta_mask)) {
1009 IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
1010 inta & ~priv->inta_mask);
1011 IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
1012 }
1013
1014 /* Re-enable all interrupts */
1015 /* only Re-enable if disabled by irq */
1016 if (test_bit(STATUS_INT_ENABLED, &priv->status))
1017 iwl_enable_interrupts(priv);
1018 /* Re-enable RF_KILL if it occurred */
1019 else if (handled & CSR_INT_BIT_RF_KILL)
1020 iwl_enable_rfkill_int(priv);
1021
1022#ifdef CONFIG_IWLWIFI_DEBUG
1023 if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
1024 inta = iwl_read32(priv, CSR_INT);
1025 inta_mask = iwl_read32(priv, CSR_INT_MASK);
1026 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1027 IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
1028 "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
1029 }
1030#endif
1031}
1032
1033/* tasklet for iwlagn interrupt */ 847/* tasklet for iwlagn interrupt */
1034static void iwl_irq_tasklet(struct iwl_priv *priv) 848static void iwl_irq_tasklet(struct iwl_priv *priv)
1035{ 849{
@@ -1171,7 +985,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1171 if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { 985 if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
1172 handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); 986 handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
1173 iwl_write32(priv, CSR_FH_INT_STATUS, 987 iwl_write32(priv, CSR_FH_INT_STATUS,
1174 CSR49_FH_INT_RX_MASK); 988 CSR_FH_INT_RX_MASK);
1175 } 989 }
1176 if (inta & CSR_INT_BIT_RX_PERIODIC) { 990 if (inta & CSR_INT_BIT_RX_PERIODIC) {
1177 handled |= CSR_INT_BIT_RX_PERIODIC; 991 handled |= CSR_INT_BIT_RX_PERIODIC;
@@ -1209,7 +1023,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1209 1023
1210 /* This "Tx" DMA channel is used only for loading uCode */ 1024 /* This "Tx" DMA channel is used only for loading uCode */
1211 if (inta & CSR_INT_BIT_FH_TX) { 1025 if (inta & CSR_INT_BIT_FH_TX) {
1212 iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK); 1026 iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
1213 IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); 1027 IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
1214 priv->isr_stats.tx++; 1028 priv->isr_stats.tx++;
1215 handled |= CSR_INT_BIT_FH_TX; 1029 handled |= CSR_INT_BIT_FH_TX;
@@ -1361,10 +1175,8 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
1361{ 1175{
1362 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); 1176 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
1363 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); 1177 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
1364 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
1365 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); 1178 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
1366 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); 1179 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
1367 iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
1368} 1180}
1369 1181
1370static void iwl_nic_start(struct iwl_priv *priv) 1182static void iwl_nic_start(struct iwl_priv *priv)
@@ -1376,7 +1188,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
1376struct iwlagn_ucode_capabilities { 1188struct iwlagn_ucode_capabilities {
1377 u32 max_probe_length; 1189 u32 max_probe_length;
1378 u32 standard_phy_calibration_size; 1190 u32 standard_phy_calibration_size;
1379 bool pan; 1191 u32 flags;
1380}; 1192};
1381 1193
1382static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); 1194static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
@@ -1422,8 +1234,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
1422} 1234}
1423 1235
1424struct iwlagn_firmware_pieces { 1236struct iwlagn_firmware_pieces {
1425 const void *inst, *data, *init, *init_data, *boot; 1237 const void *inst, *data, *init, *init_data;
1426 size_t inst_size, data_size, init_size, init_data_size, boot_size; 1238 size_t inst_size, data_size, init_size, init_data_size;
1427 1239
1428 u32 build; 1240 u32 build;
1429 1241
@@ -1444,28 +1256,18 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
1444 1256
1445 switch (api_ver) { 1257 switch (api_ver) {
1446 default: 1258 default:
1447 /* 1259 hdr_size = 28;
1448 * 4965 doesn't revision the firmware file format 1260 if (ucode_raw->size < hdr_size) {
1449 * along with the API version, it always uses v1 1261 IWL_ERR(priv, "File size too small!\n");
1450 * file format. 1262 return -EINVAL;
1451 */
1452 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
1453 CSR_HW_REV_TYPE_4965) {
1454 hdr_size = 28;
1455 if (ucode_raw->size < hdr_size) {
1456 IWL_ERR(priv, "File size too small!\n");
1457 return -EINVAL;
1458 }
1459 pieces->build = le32_to_cpu(ucode->u.v2.build);
1460 pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
1461 pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
1462 pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
1463 pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
1464 pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
1465 src = ucode->u.v2.data;
1466 break;
1467 } 1263 }
1468 /* fall through for 4965 */ 1264 pieces->build = le32_to_cpu(ucode->u.v2.build);
1265 pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
1266 pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
1267 pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
1268 pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
1269 src = ucode->u.v2.data;
1270 break;
1469 case 0: 1271 case 0:
1470 case 1: 1272 case 1:
1471 case 2: 1273 case 2:
@@ -1479,7 +1281,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
1479 pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); 1281 pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
1480 pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); 1282 pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
1481 pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); 1283 pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
1482 pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
1483 src = ucode->u.v1.data; 1284 src = ucode->u.v1.data;
1484 break; 1285 break;
1485 } 1286 }
@@ -1487,7 +1288,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
1487 /* Verify size of file vs. image size info in file's header */ 1288 /* Verify size of file vs. image size info in file's header */
1488 if (ucode_raw->size != hdr_size + pieces->inst_size + 1289 if (ucode_raw->size != hdr_size + pieces->inst_size +
1489 pieces->data_size + pieces->init_size + 1290 pieces->data_size + pieces->init_size +
1490 pieces->init_data_size + pieces->boot_size) { 1291 pieces->init_data_size) {
1491 1292
1492 IWL_ERR(priv, 1293 IWL_ERR(priv,
1493 "uCode file size %d does not match expected size\n", 1294 "uCode file size %d does not match expected size\n",
@@ -1503,8 +1304,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
1503 src += pieces->init_size; 1304 src += pieces->init_size;
1504 pieces->init_data = src; 1305 pieces->init_data = src;
1505 src += pieces->init_data_size; 1306 src += pieces->init_data_size;
1506 pieces->boot = src;
1507 src += pieces->boot_size;
1508 1307
1509 return 0; 1308 return 0;
1510} 1309}
@@ -1605,8 +1404,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1605 pieces->init_data_size = tlv_len; 1404 pieces->init_data_size = tlv_len;
1606 break; 1405 break;
1607 case IWL_UCODE_TLV_BOOT: 1406 case IWL_UCODE_TLV_BOOT:
1608 pieces->boot = tlv_data; 1407 IWL_ERR(priv, "Found unexpected BOOT ucode\n");
1609 pieces->boot_size = tlv_len;
1610 break; 1408 break;
1611 case IWL_UCODE_TLV_PROBE_MAX_LEN: 1409 case IWL_UCODE_TLV_PROBE_MAX_LEN:
1612 if (tlv_len != sizeof(u32)) 1410 if (tlv_len != sizeof(u32))
@@ -1617,7 +1415,23 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1617 case IWL_UCODE_TLV_PAN: 1415 case IWL_UCODE_TLV_PAN:
1618 if (tlv_len) 1416 if (tlv_len)
1619 goto invalid_tlv_len; 1417 goto invalid_tlv_len;
1620 capa->pan = true; 1418 capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
1419 break;
1420 case IWL_UCODE_TLV_FLAGS:
1421 /* must be at least one u32 */
1422 if (tlv_len < sizeof(u32))
1423 goto invalid_tlv_len;
1424 /* and a proper number of u32s */
1425 if (tlv_len % sizeof(u32))
1426 goto invalid_tlv_len;
1427 /*
1428 * This driver only reads the first u32 as
1429 * right now no more features are defined,
1430 * if that changes then either the driver
1431 * will not work with the new firmware, or
1432 * it'll not take advantage of new features.
1433 */
1434 capa->flags = le32_to_cpup((__le32 *)tlv_data);
1621 break; 1435 break;
1622 case IWL_UCODE_TLV_INIT_EVTLOG_PTR: 1436 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1623 if (tlv_len != sizeof(u32)) 1437 if (tlv_len != sizeof(u32))
@@ -1806,8 +1620,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1806 pieces.init_size); 1620 pieces.init_size);
1807 IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", 1621 IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
1808 pieces.init_data_size); 1622 pieces.init_data_size);
1809 IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
1810 pieces.boot_size);
1811 1623
1812 /* Verify that uCode images will fit in card's SRAM */ 1624 /* Verify that uCode images will fit in card's SRAM */
1813 if (pieces.inst_size > priv->hw_params.max_inst_size) { 1625 if (pieces.inst_size > priv->hw_params.max_inst_size) {
@@ -1834,12 +1646,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1834 goto try_again; 1646 goto try_again;
1835 } 1647 }
1836 1648
1837 if (pieces.boot_size > priv->hw_params.max_bsm_size) {
1838 IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
1839 pieces.boot_size);
1840 goto try_again;
1841 }
1842
1843 /* Allocate ucode buffers for card's bus-master loading ... */ 1649 /* Allocate ucode buffers for card's bus-master loading ... */
1844 1650
1845 /* Runtime instructions and 2 copies of data: 1651 /* Runtime instructions and 2 copies of data:
@@ -1851,11 +1657,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1851 priv->ucode_data.len = pieces.data_size; 1657 priv->ucode_data.len = pieces.data_size;
1852 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); 1658 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
1853 1659
1854 priv->ucode_data_backup.len = pieces.data_size; 1660 if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr)
1855 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
1856
1857 if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
1858 !priv->ucode_data_backup.v_addr)
1859 goto err_pci_alloc; 1661 goto err_pci_alloc;
1860 1662
1861 /* Initialization instructions and data */ 1663 /* Initialization instructions and data */
@@ -1870,15 +1672,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1870 goto err_pci_alloc; 1672 goto err_pci_alloc;
1871 } 1673 }
1872 1674
1873 /* Bootstrap (instructions only, no data) */
1874 if (pieces.boot_size) {
1875 priv->ucode_boot.len = pieces.boot_size;
1876 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
1877
1878 if (!priv->ucode_boot.v_addr)
1879 goto err_pci_alloc;
1880 }
1881
1882 /* Now that we can no longer fail, copy information */ 1675 /* Now that we can no longer fail, copy information */
1883 1676
1884 /* 1677 /*
@@ -1901,12 +1694,21 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1901 priv->cfg->base_params->max_event_log_size; 1694 priv->cfg->base_params->max_event_log_size;
1902 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; 1695 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
1903 1696
1904 if (ucode_capa.pan) { 1697 if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
1905 priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); 1698 priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
1906 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; 1699 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
1907 } else 1700 } else
1908 priv->sta_key_max_num = STA_KEY_MAX_NUM; 1701 priv->sta_key_max_num = STA_KEY_MAX_NUM;
1909 1702
1703 if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
1704 priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
1705 else
1706 priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1707
1708 if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS ||
1709 (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics))
1710 priv->bt_statistics = true;
1711
1910 /* Copy images into buffers for card's bus-master reads ... */ 1712 /* Copy images into buffers for card's bus-master reads ... */
1911 1713
1912 /* Runtime instructions (first block of data in file) */ 1714 /* Runtime instructions (first block of data in file) */
@@ -1924,7 +1726,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1924 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", 1726 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
1925 pieces.data_size); 1727 pieces.data_size);
1926 memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size); 1728 memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
1927 memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
1928 1729
1929 /* Initialization instructions */ 1730 /* Initialization instructions */
1930 if (pieces.init_size) { 1731 if (pieces.init_size) {
@@ -1941,11 +1742,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1941 pieces.init_data_size); 1742 pieces.init_data_size);
1942 } 1743 }
1943 1744
1944 /* Bootstrap instructions */
1945 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
1946 pieces.boot_size);
1947 memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
1948
1949 /* 1745 /*
1950 * figure out the offset of chain noise reset and gain commands 1746 * figure out the offset of chain noise reset and gain commands
1951 * base on the size of standard phy calibration commands table size 1747 * base on the size of standard phy calibration commands table size
@@ -2077,12 +1873,11 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
2077 u32 blink1, blink2, ilink1, ilink2; 1873 u32 blink1, blink2, ilink1, ilink2;
2078 u32 pc, hcmd; 1874 u32 pc, hcmd;
2079 1875
1876 base = priv->device_pointers.error_event_table;
2080 if (priv->ucode_type == UCODE_INIT) { 1877 if (priv->ucode_type == UCODE_INIT) {
2081 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
2082 if (!base) 1878 if (!base)
2083 base = priv->_agn.init_errlog_ptr; 1879 base = priv->_agn.init_errlog_ptr;
2084 } else { 1880 } else {
2085 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
2086 if (!base) 1881 if (!base)
2087 base = priv->_agn.inst_errlog_ptr; 1882 base = priv->_agn.inst_errlog_ptr;
2088 } 1883 }
@@ -2147,12 +1942,11 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2147 if (num_events == 0) 1942 if (num_events == 0)
2148 return pos; 1943 return pos;
2149 1944
1945 base = priv->device_pointers.log_event_table;
2150 if (priv->ucode_type == UCODE_INIT) { 1946 if (priv->ucode_type == UCODE_INIT) {
2151 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2152 if (!base) 1947 if (!base)
2153 base = priv->_agn.init_evtlog_ptr; 1948 base = priv->_agn.init_evtlog_ptr;
2154 } else { 1949 } else {
2155 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2156 if (!base) 1950 if (!base)
2157 base = priv->_agn.inst_evtlog_ptr; 1951 base = priv->_agn.inst_evtlog_ptr;
2158 } 1952 }
@@ -2169,14 +1963,14 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2169 iwl_grab_nic_access(priv); 1963 iwl_grab_nic_access(priv);
2170 1964
2171 /* Set starting address; reads will auto-increment */ 1965 /* Set starting address; reads will auto-increment */
2172 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); 1966 iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
2173 rmb(); 1967 rmb();
2174 1968
2175 /* "time" is actually "data" for mode 0 (no timestamp). 1969 /* "time" is actually "data" for mode 0 (no timestamp).
2176 * place event id # at far right for easier visual parsing. */ 1970 * place event id # at far right for easier visual parsing. */
2177 for (i = 0; i < num_events; i++) { 1971 for (i = 0; i < num_events; i++) {
2178 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1972 ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
2179 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1973 time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
2180 if (mode == 0) { 1974 if (mode == 0) {
2181 /* data, ev */ 1975 /* data, ev */
2182 if (bufsz) { 1976 if (bufsz) {
@@ -2190,7 +1984,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2190 time, ev); 1984 time, ev);
2191 } 1985 }
2192 } else { 1986 } else {
2193 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1987 data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
2194 if (bufsz) { 1988 if (bufsz) {
2195 pos += scnprintf(*buf + pos, bufsz - pos, 1989 pos += scnprintf(*buf + pos, bufsz - pos,
2196 "EVT_LOGT:%010u:0x%08x:%04u\n", 1990 "EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -2261,13 +2055,12 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2261 int pos = 0; 2055 int pos = 0;
2262 size_t bufsz = 0; 2056 size_t bufsz = 0;
2263 2057
2058 base = priv->device_pointers.log_event_table;
2264 if (priv->ucode_type == UCODE_INIT) { 2059 if (priv->ucode_type == UCODE_INIT) {
2265 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2266 logsize = priv->_agn.init_evtlog_size; 2060 logsize = priv->_agn.init_evtlog_size;
2267 if (!base) 2061 if (!base)
2268 base = priv->_agn.init_evtlog_ptr; 2062 base = priv->_agn.init_evtlog_ptr;
2269 } else { 2063 } else {
2270 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2271 logsize = priv->_agn.inst_evtlog_size; 2064 logsize = priv->_agn.inst_evtlog_size;
2272 if (!base) 2065 if (!base)
2273 base = priv->_agn.inst_evtlog_ptr; 2066 base = priv->_agn.inst_evtlog_ptr;
@@ -2433,14 +2226,14 @@ static void iwl_alive_start(struct iwl_priv *priv)
2433 /* Initialize uCode has loaded Runtime uCode ... verify inst image. 2226 /* Initialize uCode has loaded Runtime uCode ... verify inst image.
2434 * This is a paranoid check, because we would not have gotten the 2227 * This is a paranoid check, because we would not have gotten the
2435 * "runtime" alive if code weren't properly loaded. */ 2228 * "runtime" alive if code weren't properly loaded. */
2436 if (iwl_verify_ucode(priv)) { 2229 if (iwl_verify_ucode(priv, &priv->ucode_code)) {
2437 /* Runtime instruction load was bad; 2230 /* Runtime instruction load was bad;
2438 * take it all the way back down so we can try again */ 2231 * take it all the way back down so we can try again */
2439 IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); 2232 IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
2440 goto restart; 2233 goto restart;
2441 } 2234 }
2442 2235
2443 ret = priv->cfg->ops->lib->alive_notify(priv); 2236 ret = iwlagn_alive_notify(priv);
2444 if (ret) { 2237 if (ret) {
2445 IWL_WARN(priv, 2238 IWL_WARN(priv,
2446 "Could not complete ALIVE transition [ntf]: %d\n", ret); 2239 "Could not complete ALIVE transition [ntf]: %d\n", ret);
@@ -2537,7 +2330,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv);
2537static void __iwl_down(struct iwl_priv *priv) 2330static void __iwl_down(struct iwl_priv *priv)
2538{ 2331{
2539 unsigned long flags; 2332 unsigned long flags;
2540 int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); 2333 int exit_pending;
2541 2334
2542 IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); 2335 IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
2543 2336
@@ -2563,9 +2356,6 @@ static void __iwl_down(struct iwl_priv *priv)
2563 priv->bt_full_concurrent = false; 2356 priv->bt_full_concurrent = false;
2564 priv->bt_ci_compliance = 0; 2357 priv->bt_ci_compliance = 0;
2565 2358
2566 /* Unblock any waiting calls */
2567 wake_up_interruptible_all(&priv->wait_command_queue);
2568
2569 /* Wipe out the EXIT_PENDING status bit if we are not actually 2359 /* Wipe out the EXIT_PENDING status bit if we are not actually
2570 * exiting the module */ 2360 * exiting the module */
2571 if (!exit_pending) 2361 if (!exit_pending)
@@ -2607,8 +2397,7 @@ static void __iwl_down(struct iwl_priv *priv)
2607 STATUS_EXIT_PENDING; 2397 STATUS_EXIT_PENDING;
2608 2398
2609 /* device going down, Stop using ICT table */ 2399 /* device going down, Stop using ICT table */
2610 if (priv->cfg->ops->lib->isr_ops.disable) 2400 iwl_disable_ict(priv);
2611 priv->cfg->ops->lib->isr_ops.disable(priv);
2612 2401
2613 iwlagn_txq_ctx_stop(priv); 2402 iwlagn_txq_ctx_stop(priv);
2614 iwlagn_rxq_stop(priv); 2403 iwlagn_rxq_stop(priv);
@@ -2624,8 +2413,6 @@ static void __iwl_down(struct iwl_priv *priv)
2624 iwl_apm_stop(priv); 2413 iwl_apm_stop(priv);
2625 2414
2626 exit: 2415 exit:
2627 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
2628
2629 dev_kfree_skb(priv->beacon_skb); 2416 dev_kfree_skb(priv->beacon_skb);
2630 priv->beacon_skb = NULL; 2417 priv->beacon_skb = NULL;
2631 2418
@@ -2704,11 +2491,6 @@ static int __iwl_up(struct iwl_priv *priv)
2704 return -EIO; 2491 return -EIO;
2705 } 2492 }
2706 2493
2707 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
2708 IWL_ERR(priv, "ucode not available for device bringup\n");
2709 return -EIO;
2710 }
2711
2712 for_each_context(priv, ctx) { 2494 for_each_context(priv, ctx) {
2713 ret = iwlagn_alloc_bcast_station(priv, ctx); 2495 ret = iwlagn_alloc_bcast_station(priv, ctx);
2714 if (ret) { 2496 if (ret) {
@@ -2740,12 +2522,6 @@ static int __iwl_up(struct iwl_priv *priv)
2740 2522
2741 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2523 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2742 2524
2743 /* must be initialised before iwl_hw_nic_init */
2744 if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
2745 priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
2746 else
2747 priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
2748
2749 ret = iwlagn_hw_nic_init(priv); 2525 ret = iwlagn_hw_nic_init(priv);
2750 if (ret) { 2526 if (ret) {
2751 IWL_ERR(priv, "Unable to init nic\n"); 2527 IWL_ERR(priv, "Unable to init nic\n");
@@ -2765,18 +2541,12 @@ static int __iwl_up(struct iwl_priv *priv)
2765 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 2541 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2766 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 2542 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2767 2543
2768 /* Copy original ucode data image from disk into backup cache.
2769 * This will be used to initialize the on-board processor's
2770 * data SRAM for a clean start when the runtime program first loads. */
2771 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
2772 priv->ucode_data.len);
2773
2774 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2544 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2775 2545
2776 /* load bootstrap state machine, 2546 /* load bootstrap state machine,
2777 * load bootstrap program into processor's memory, 2547 * load bootstrap program into processor's memory,
2778 * prepare to load the "initialize" uCode */ 2548 * prepare to load the "initialize" uCode */
2779 ret = priv->cfg->ops->lib->load_ucode(priv); 2549 ret = iwlagn_load_ucode(priv);
2780 2550
2781 if (ret) { 2551 if (ret) {
2782 IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", 2552 IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
@@ -2814,11 +2584,14 @@ static void iwl_bg_init_alive_start(struct work_struct *data)
2814 struct iwl_priv *priv = 2584 struct iwl_priv *priv =
2815 container_of(data, struct iwl_priv, init_alive_start.work); 2585 container_of(data, struct iwl_priv, init_alive_start.work);
2816 2586
2817 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2587 mutex_lock(&priv->mutex);
2588
2589 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
2590 mutex_unlock(&priv->mutex);
2818 return; 2591 return;
2592 }
2819 2593
2820 mutex_lock(&priv->mutex); 2594 iwlagn_init_alive_start(priv);
2821 priv->cfg->ops->lib->init_alive_start(priv);
2822 mutex_unlock(&priv->mutex); 2595 mutex_unlock(&priv->mutex);
2823} 2596}
2824 2597
@@ -2827,15 +2600,15 @@ static void iwl_bg_alive_start(struct work_struct *data)
2827 struct iwl_priv *priv = 2600 struct iwl_priv *priv =
2828 container_of(data, struct iwl_priv, alive_start.work); 2601 container_of(data, struct iwl_priv, alive_start.work);
2829 2602
2603 mutex_lock(&priv->mutex);
2830 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2604 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2831 return; 2605 goto unlock;
2832 2606
2833 /* enable dram interrupt */ 2607 /* enable dram interrupt */
2834 if (priv->cfg->ops->lib->isr_ops.reset) 2608 iwl_reset_ict(priv);
2835 priv->cfg->ops->lib->isr_ops.reset(priv);
2836 2609
2837 mutex_lock(&priv->mutex);
2838 iwl_alive_start(priv); 2610 iwl_alive_start(priv);
2611unlock:
2839 mutex_unlock(&priv->mutex); 2612 mutex_unlock(&priv->mutex);
2840} 2613}
2841 2614
@@ -3063,6 +2836,9 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3063 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 2836 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
3064 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 2837 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
3065 2838
2839 if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
2840 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
2841
3066 hw->sta_data_size = sizeof(struct iwl_station_priv); 2842 hw->sta_data_size = sizeof(struct iwl_station_priv);
3067 hw->vif_data_size = sizeof(struct iwl_vif_priv); 2843 hw->vif_data_size = sizeof(struct iwl_vif_priv);
3068 2844
@@ -3112,7 +2888,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3112} 2888}
3113 2889
3114 2890
3115int iwlagn_mac_start(struct ieee80211_hw *hw) 2891static int iwlagn_mac_start(struct ieee80211_hw *hw)
3116{ 2892{
3117 struct iwl_priv *priv = hw->priv; 2893 struct iwl_priv *priv = hw->priv;
3118 int ret; 2894 int ret;
@@ -3153,7 +2929,7 @@ out:
3153 return 0; 2929 return 0;
3154} 2930}
3155 2931
3156void iwlagn_mac_stop(struct ieee80211_hw *hw) 2932static void iwlagn_mac_stop(struct ieee80211_hw *hw)
3157{ 2933{
3158 struct iwl_priv *priv = hw->priv; 2934 struct iwl_priv *priv = hw->priv;
3159 2935
@@ -3176,7 +2952,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw)
3176 IWL_DEBUG_MAC80211(priv, "leave\n"); 2952 IWL_DEBUG_MAC80211(priv, "leave\n");
3177} 2953}
3178 2954
3179void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 2955static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3180{ 2956{
3181 struct iwl_priv *priv = hw->priv; 2957 struct iwl_priv *priv = hw->priv;
3182 2958
@@ -3191,11 +2967,11 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3191 IWL_DEBUG_MACDUMP(priv, "leave\n"); 2967 IWL_DEBUG_MACDUMP(priv, "leave\n");
3192} 2968}
3193 2969
3194void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, 2970static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
3195 struct ieee80211_vif *vif, 2971 struct ieee80211_vif *vif,
3196 struct ieee80211_key_conf *keyconf, 2972 struct ieee80211_key_conf *keyconf,
3197 struct ieee80211_sta *sta, 2973 struct ieee80211_sta *sta,
3198 u32 iv32, u16 *phase1key) 2974 u32 iv32, u16 *phase1key)
3199{ 2975{
3200 struct iwl_priv *priv = hw->priv; 2976 struct iwl_priv *priv = hw->priv;
3201 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 2977 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3208,9 +2984,10 @@ void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
3208 IWL_DEBUG_MAC80211(priv, "leave\n"); 2984 IWL_DEBUG_MAC80211(priv, "leave\n");
3209} 2985}
3210 2986
3211int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2987static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3212 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 2988 struct ieee80211_vif *vif,
3213 struct ieee80211_key_conf *key) 2989 struct ieee80211_sta *sta,
2990 struct ieee80211_key_conf *key)
3214{ 2991{
3215 struct iwl_priv *priv = hw->priv; 2992 struct iwl_priv *priv = hw->priv;
3216 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 2993 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3285,11 +3062,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3285 return ret; 3062 return ret;
3286} 3063}
3287 3064
3288int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, 3065static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
3289 struct ieee80211_vif *vif, 3066 struct ieee80211_vif *vif,
3290 enum ieee80211_ampdu_mlme_action action, 3067 enum ieee80211_ampdu_mlme_action action,
3291 struct ieee80211_sta *sta, u16 tid, u16 *ssn, 3068 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
3292 u8 buf_size) 3069 u8 buf_size)
3293{ 3070{
3294 struct iwl_priv *priv = hw->priv; 3071 struct iwl_priv *priv = hw->priv;
3295 int ret = -EINVAL; 3072 int ret = -EINVAL;
@@ -3348,6 +3125,10 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
3348 } 3125 }
3349 break; 3126 break;
3350 case IEEE80211_AMPDU_TX_OPERATIONAL: 3127 case IEEE80211_AMPDU_TX_OPERATIONAL:
3128 buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
3129
3130 iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size);
3131
3351 /* 3132 /*
3352 * If the limit is 0, then it wasn't initialised yet, 3133 * If the limit is 0, then it wasn't initialised yet,
3353 * use the default. We can do that since we take the 3134 * use the default. We can do that since we take the
@@ -3392,9 +3173,9 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
3392 return ret; 3173 return ret;
3393} 3174}
3394 3175
3395int iwlagn_mac_sta_add(struct ieee80211_hw *hw, 3176static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3396 struct ieee80211_vif *vif, 3177 struct ieee80211_vif *vif,
3397 struct ieee80211_sta *sta) 3178 struct ieee80211_sta *sta)
3398{ 3179{
3399 struct iwl_priv *priv = hw->priv; 3180 struct iwl_priv *priv = hw->priv;
3400 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3181 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3435,8 +3216,8 @@ int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3435 return 0; 3216 return 0;
3436} 3217}
3437 3218
3438void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, 3219static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3439 struct ieee80211_channel_switch *ch_switch) 3220 struct ieee80211_channel_switch *ch_switch)
3440{ 3221{
3441 struct iwl_priv *priv = hw->priv; 3222 struct iwl_priv *priv = hw->priv;
3442 const struct iwl_channel_info *ch_info; 3223 const struct iwl_channel_info *ch_info;
@@ -3457,21 +3238,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3457 3238
3458 IWL_DEBUG_MAC80211(priv, "enter\n"); 3239 IWL_DEBUG_MAC80211(priv, "enter\n");
3459 3240
3241 mutex_lock(&priv->mutex);
3242
3460 if (iwl_is_rfkill(priv)) 3243 if (iwl_is_rfkill(priv))
3461 goto out_exit; 3244 goto out;
3462 3245
3463 if (test_bit(STATUS_EXIT_PENDING, &priv->status) || 3246 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
3464 test_bit(STATUS_SCANNING, &priv->status)) 3247 test_bit(STATUS_SCANNING, &priv->status))
3465 goto out_exit; 3248 goto out;
3466 3249
3467 if (!iwl_is_associated_ctx(ctx)) 3250 if (!iwl_is_associated_ctx(ctx))
3468 goto out_exit; 3251 goto out;
3469 3252
3470 /* channel switch in progress */ 3253 /* channel switch in progress */
3471 if (priv->switch_rxon.switch_in_progress == true) 3254 if (priv->switch_rxon.switch_in_progress == true)
3472 goto out_exit; 3255 goto out;
3473 3256
3474 mutex_lock(&priv->mutex);
3475 if (priv->cfg->ops->lib->set_channel_switch) { 3257 if (priv->cfg->ops->lib->set_channel_switch) {
3476 3258
3477 ch = channel->hw_value; 3259 ch = channel->hw_value;
@@ -3527,16 +3309,15 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3527 } 3309 }
3528out: 3310out:
3529 mutex_unlock(&priv->mutex); 3311 mutex_unlock(&priv->mutex);
3530out_exit:
3531 if (!priv->switch_rxon.switch_in_progress) 3312 if (!priv->switch_rxon.switch_in_progress)
3532 ieee80211_chswitch_done(ctx->vif, false); 3313 ieee80211_chswitch_done(ctx->vif, false);
3533 IWL_DEBUG_MAC80211(priv, "leave\n"); 3314 IWL_DEBUG_MAC80211(priv, "leave\n");
3534} 3315}
3535 3316
3536void iwlagn_configure_filter(struct ieee80211_hw *hw, 3317static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3537 unsigned int changed_flags, 3318 unsigned int changed_flags,
3538 unsigned int *total_flags, 3319 unsigned int *total_flags,
3539 u64 multicast) 3320 u64 multicast)
3540{ 3321{
3541 struct iwl_priv *priv = hw->priv; 3322 struct iwl_priv *priv = hw->priv;
3542 __le32 filter_or = 0, filter_nand = 0; 3323 __le32 filter_or = 0, filter_nand = 0;
@@ -3583,7 +3364,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw,
3583 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 3364 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
3584} 3365}
3585 3366
3586void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) 3367static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
3587{ 3368{
3588 struct iwl_priv *priv = hw->priv; 3369 struct iwl_priv *priv = hw->priv;
3589 3370
@@ -3750,12 +3531,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3750 priv->watchdog.data = (unsigned long)priv; 3531 priv->watchdog.data = (unsigned long)priv;
3751 priv->watchdog.function = iwl_bg_watchdog; 3532 priv->watchdog.function = iwl_bg_watchdog;
3752 3533
3753 if (!priv->cfg->base_params->use_isr_legacy) 3534 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3754 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3535 iwl_irq_tasklet, (unsigned long)priv);
3755 iwl_irq_tasklet, (unsigned long)priv);
3756 else
3757 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3758 iwl_irq_tasklet_legacy, (unsigned long)priv);
3759} 3536}
3760 3537
3761static void iwl_cancel_deferred_work(struct iwl_priv *priv) 3538static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3808,7 +3585,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
3808 INIT_LIST_HEAD(&priv->free_frames); 3585 INIT_LIST_HEAD(&priv->free_frames);
3809 3586
3810 mutex_init(&priv->mutex); 3587 mutex_init(&priv->mutex);
3811 mutex_init(&priv->sync_cmd_mutex);
3812 3588
3813 priv->ieee_channels = NULL; 3589 priv->ieee_channels = NULL;
3814 priv->ieee_rates = NULL; 3590 priv->ieee_rates = NULL;
@@ -3907,12 +3683,13 @@ struct ieee80211_ops iwlagn_hw_ops = {
3907 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, 3683 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
3908}; 3684};
3909 3685
3910static void iwl_hw_detect(struct iwl_priv *priv) 3686static u32 iwl_hw_detect(struct iwl_priv *priv)
3911{ 3687{
3912 priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); 3688 u8 rev_id;
3913 priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); 3689
3914 priv->rev_id = priv->pci_dev->revision; 3690 pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
3915 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); 3691 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
3692 return iwl_read32(priv, CSR_HW_REV);
3916} 3693}
3917 3694
3918static int iwl_set_hw_params(struct iwl_priv *priv) 3695static int iwl_set_hw_params(struct iwl_priv *priv)
@@ -3963,19 +3740,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3963 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 3740 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
3964 unsigned long flags; 3741 unsigned long flags;
3965 u16 pci_cmd, num_mac; 3742 u16 pci_cmd, num_mac;
3743 u32 hw_rev;
3966 3744
3967 /************************ 3745 /************************
3968 * 1. Allocating HW data 3746 * 1. Allocating HW data
3969 ************************/ 3747 ************************/
3970 3748
3971 /* Disabling hardware scan means that mac80211 will perform scans
3972 * "the hard way", rather than using device's scan. */
3973 if (cfg->mod_params->disable_hw_scan) {
3974 dev_printk(KERN_DEBUG, &(pdev->dev),
3975 "sw scan support is deprecated\n");
3976 iwlagn_hw_ops.hw_scan = NULL;
3977 }
3978
3979 hw = iwl_alloc_all(cfg); 3749 hw = iwl_alloc_all(cfg);
3980 if (!hw) { 3750 if (!hw) {
3981 err = -ENOMEM; 3751 err = -ENOMEM;
@@ -4116,9 +3886,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4116 */ 3886 */
4117 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 3887 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
4118 3888
4119 iwl_hw_detect(priv); 3889 hw_rev = iwl_hw_detect(priv);
4120 IWL_INFO(priv, "Detected %s, REV=0x%X\n", 3890 IWL_INFO(priv, "Detected %s, REV=0x%X\n",
4121 priv->cfg->name, priv->hw_rev); 3891 priv->cfg->name, hw_rev);
4122 3892
4123 /* We disable the RETRY_TIMEOUT register (0x41) to keep 3893 /* We disable the RETRY_TIMEOUT register (0x41) to keep
4124 * PCI Tx retries from interfering with C3 CPU state */ 3894 * PCI Tx retries from interfering with C3 CPU state */
@@ -4134,7 +3904,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4134 * 4. Read EEPROM 3904 * 4. Read EEPROM
4135 *****************/ 3905 *****************/
4136 /* Read the EEPROM */ 3906 /* Read the EEPROM */
4137 err = iwl_eeprom_init(priv); 3907 err = iwl_eeprom_init(priv, hw_rev);
4138 if (err) { 3908 if (err) {
4139 IWL_ERR(priv, "Unable to init EEPROM\n"); 3909 IWL_ERR(priv, "Unable to init EEPROM\n");
4140 goto out_iounmap; 3910 goto out_iounmap;
@@ -4186,10 +3956,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4186 3956
4187 pci_enable_msi(priv->pci_dev); 3957 pci_enable_msi(priv->pci_dev);
4188 3958
4189 if (priv->cfg->ops->lib->isr_ops.alloc) 3959 iwl_alloc_isr_ict(priv);
4190 priv->cfg->ops->lib->isr_ops.alloc(priv);
4191 3960
4192 err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, 3961 err = request_irq(priv->pci_dev->irq, iwl_isr_ict,
4193 IRQF_SHARED, DRV_NAME, priv); 3962 IRQF_SHARED, DRV_NAME, priv);
4194 if (err) { 3963 if (err) {
4195 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); 3964 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4236,8 +4005,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4236 destroy_workqueue(priv->workqueue); 4005 destroy_workqueue(priv->workqueue);
4237 priv->workqueue = NULL; 4006 priv->workqueue = NULL;
4238 free_irq(priv->pci_dev->irq, priv); 4007 free_irq(priv->pci_dev->irq, priv);
4239 if (priv->cfg->ops->lib->isr_ops.free) 4008 iwl_free_isr_ict(priv);
4240 priv->cfg->ops->lib->isr_ops.free(priv);
4241 out_disable_msi: 4009 out_disable_msi:
4242 pci_disable_msi(priv->pci_dev); 4010 pci_disable_msi(priv->pci_dev);
4243 iwl_uninit_drv(priv); 4011 iwl_uninit_drv(priv);
@@ -4335,8 +4103,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
4335 4103
4336 iwl_uninit_drv(priv); 4104 iwl_uninit_drv(priv);
4337 4105
4338 if (priv->cfg->ops->lib->isr_ops.free) 4106 iwl_free_isr_ict(priv);
4339 priv->cfg->ops->lib->isr_ops.free(priv);
4340 4107
4341 dev_kfree_skb(priv->beacon_skb); 4108 dev_kfree_skb(priv->beacon_skb);
4342 4109
@@ -4585,43 +4352,21 @@ module_exit(iwl_exit);
4585module_init(iwl_init); 4352module_init(iwl_init);
4586 4353
4587#ifdef CONFIG_IWLWIFI_DEBUG 4354#ifdef CONFIG_IWLWIFI_DEBUG
4588module_param_named(debug50, iwl_debug_level, uint, S_IRUGO);
4589MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
4590module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); 4355module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
4591MODULE_PARM_DESC(debug, "debug output mask"); 4356MODULE_PARM_DESC(debug, "debug output mask");
4592#endif 4357#endif
4593 4358
4594module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO);
4595MODULE_PARM_DESC(swcrypto50,
4596 "using crypto in software (default 0 [hardware]) (deprecated)");
4597module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); 4359module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
4598MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); 4360MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
4599module_param_named(queues_num50,
4600 iwlagn_mod_params.num_of_queues, int, S_IRUGO);
4601MODULE_PARM_DESC(queues_num50,
4602 "number of hw queues in 50xx series (deprecated)");
4603module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); 4361module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
4604MODULE_PARM_DESC(queues_num, "number of hw queues."); 4362MODULE_PARM_DESC(queues_num, "number of hw queues.");
4605module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO);
4606MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)");
4607module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO); 4363module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO);
4608MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); 4364MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
4609module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K,
4610 int, S_IRUGO);
4611MODULE_PARM_DESC(amsdu_size_8K50,
4612 "enable 8K amsdu size in 50XX series (deprecated)");
4613module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K, 4365module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
4614 int, S_IRUGO); 4366 int, S_IRUGO);
4615MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); 4367MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
4616module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO);
4617MODULE_PARM_DESC(fw_restart50,
4618 "restart firmware in case of error (deprecated)");
4619module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); 4368module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
4620MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 4369MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
4621module_param_named(
4622 disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
4623MODULE_PARM_DESC(disable_hw_scan,
4624 "disable hardware scanning (default 0) (deprecated)");
4625 4370
4626module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, 4371module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
4627 S_IRUGO); 4372 S_IRUGO);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 20f8e4188994..016b79e4421e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,6 @@
66#include "iwl-dev.h" 66#include "iwl-dev.h"
67 67
68/* configuration for the _agn devices */ 68/* configuration for the _agn devices */
69extern struct iwl_cfg iwl4965_agn_cfg;
70extern struct iwl_cfg iwl5300_agn_cfg; 69extern struct iwl_cfg iwl5300_agn_cfg;
71extern struct iwl_cfg iwl5100_agn_cfg; 70extern struct iwl_cfg iwl5100_agn_cfg;
72extern struct iwl_cfg iwl5350_agn_cfg; 71extern struct iwl_cfg iwl5350_agn_cfg;
@@ -114,7 +113,6 @@ extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
114extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; 113extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
115 114
116extern struct ieee80211_ops iwlagn_hw_ops; 115extern struct ieee80211_ops iwlagn_hw_ops;
117extern struct ieee80211_ops iwl4965_hw_ops;
118 116
119int iwl_reset_ict(struct iwl_priv *priv); 117int iwl_reset_ict(struct iwl_priv *priv);
120void iwl_disable_ict(struct iwl_priv *priv); 118void iwl_disable_ict(struct iwl_priv *priv);
@@ -133,10 +131,6 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
133 u16 byte_cnt); 131 u16 byte_cnt);
134void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, 132void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
135 struct iwl_tx_queue *txq); 133 struct iwl_tx_queue *txq);
136int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
137 int tx_fifo, int sta_id, int tid, u16 ssn_idx);
138int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
139 u16 ssn_idx, u8 tx_fifo);
140void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); 134void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
141void iwl_free_tfds_in_queue(struct iwl_priv *priv, 135void iwl_free_tfds_in_queue(struct iwl_priv *priv,
142 int sta_id, int tid, int freed); 136 int sta_id, int tid, int freed);
@@ -158,7 +152,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv,
158 struct iwl_rx_mem_buffer *rxb); 152 struct iwl_rx_mem_buffer *rxb);
159void iwlagn_init_alive_start(struct iwl_priv *priv); 153void iwlagn_init_alive_start(struct iwl_priv *priv);
160int iwlagn_alive_notify(struct iwl_priv *priv); 154int iwlagn_alive_notify(struct iwl_priv *priv);
161int iwl_verify_ucode(struct iwl_priv *priv); 155int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc);
162void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); 156void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
163void iwlagn_send_prio_tbl(struct iwl_priv *priv); 157void iwlagn_send_prio_tbl(struct iwl_priv *priv);
164 158
@@ -206,6 +200,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
206 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 200 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
207int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 201int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
208 struct ieee80211_sta *sta, u16 tid); 202 struct ieee80211_sta *sta, u16 tid);
203void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
204 struct ieee80211_sta *sta,
205 int tid, int frame_limit);
209int iwlagn_txq_check_empty(struct iwl_priv *priv, 206int iwlagn_txq_check_empty(struct iwl_priv *priv,
210 int sta_id, u8 tid, int txq_id); 207 int sta_id, u8 tid, int txq_id);
211void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 208void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
@@ -311,7 +308,7 @@ static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
311 308
312static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) 309static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
313{ 310{
314 return le32_to_cpu(rate_n_flags) & 0xFF; 311 return le32_to_cpu(rate_n_flags) & RATE_MCS_RATE_MSK;
315} 312}
316 313
317static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) 314static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
@@ -340,32 +337,4 @@ void __releases(wait_entry)
340iwlagn_remove_notification(struct iwl_priv *priv, 337iwlagn_remove_notification(struct iwl_priv *priv,
341 struct iwl_notification_wait *wait_entry); 338 struct iwl_notification_wait *wait_entry);
342 339
343/* mac80211 handlers (for 4965) */
344void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
345int iwlagn_mac_start(struct ieee80211_hw *hw);
346void iwlagn_mac_stop(struct ieee80211_hw *hw);
347void iwlagn_configure_filter(struct ieee80211_hw *hw,
348 unsigned int changed_flags,
349 unsigned int *total_flags,
350 u64 multicast);
351int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
352 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
353 struct ieee80211_key_conf *key);
354void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
355 struct ieee80211_vif *vif,
356 struct ieee80211_key_conf *keyconf,
357 struct ieee80211_sta *sta,
358 u32 iv32, u16 *phase1key);
359int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
360 struct ieee80211_vif *vif,
361 enum ieee80211_ampdu_mlme_action action,
362 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
363 u8 buf_size);
364int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
365 struct ieee80211_vif *vif,
366 struct ieee80211_sta *sta);
367void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
368 struct ieee80211_channel_switch *ch_switch);
369void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
370
371#endif /* __iwl_agn_h__ */ 340#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ca42ffa63ed7..a1a5c1b23096 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -103,9 +103,7 @@ enum {
103 REPLY_WEPKEY = 0x20, 103 REPLY_WEPKEY = 0x20,
104 104
105 /* RX, TX, LEDs */ 105 /* RX, TX, LEDs */
106 REPLY_3945_RX = 0x1b, /* 3945 only */
107 REPLY_TX = 0x1c, 106 REPLY_TX = 0x1c,
108 REPLY_RATE_SCALE = 0x47, /* 3945 only */
109 REPLY_LEDS_CMD = 0x48, 107 REPLY_LEDS_CMD = 0x48,
110 REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */ 108 REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */
111 109
@@ -229,7 +227,7 @@ struct iwl_cmd_header {
229 * There is one exception: uCode sets bit 15 when it originates 227 * There is one exception: uCode sets bit 15 when it originates
230 * the response/notification, i.e. when the response/notification 228 * the response/notification, i.e. when the response/notification
231 * is not a direct response to a command sent by the driver. For 229 * is not a direct response to a command sent by the driver. For
232 * example, uCode issues REPLY_3945_RX when it sends a received frame 230 * example, uCode issues REPLY_RX when it sends a received frame
233 * to the driver; it is not a direct response to any driver command. 231 * to the driver; it is not a direct response to any driver command.
234 * 232 *
235 * The Linux driver uses the following format: 233 * The Linux driver uses the following format:
@@ -249,36 +247,6 @@ struct iwl_cmd_header {
249 247
250 248
251/** 249/**
252 * struct iwl3945_tx_power
253 *
254 * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
255 *
256 * Each entry contains two values:
257 * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
258 * linear value that multiplies the output of the digital signal processor,
259 * before being sent to the analog radio.
260 * 2) Radio gain. This sets the analog gain of the radio Tx path.
261 * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
262 *
263 * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
264 */
265struct iwl3945_tx_power {
266 u8 tx_gain; /* gain for analog radio */
267 u8 dsp_atten; /* gain for DSP */
268} __packed;
269
270/**
271 * struct iwl3945_power_per_rate
272 *
273 * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
274 */
275struct iwl3945_power_per_rate {
276 u8 rate; /* plcp */
277 struct iwl3945_tx_power tpc;
278 u8 reserved;
279} __packed;
280
281/**
282 * iwlagn rate_n_flags bit fields 250 * iwlagn rate_n_flags bit fields
283 * 251 *
284 * rate_n_flags format is used in following iwlagn commands: 252 * rate_n_flags format is used in following iwlagn commands:
@@ -324,6 +292,8 @@ struct iwl3945_power_per_rate {
324#define RATE_MCS_SPATIAL_MSK 0x18 292#define RATE_MCS_SPATIAL_MSK 0x18
325#define RATE_MCS_HT_DUP_POS 5 293#define RATE_MCS_HT_DUP_POS 5
326#define RATE_MCS_HT_DUP_MSK 0x20 294#define RATE_MCS_HT_DUP_MSK 0x20
295/* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */
296#define RATE_MCS_RATE_MSK 0xff
327 297
328/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ 298/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */
329#define RATE_MCS_FLAGS_POS 8 299#define RATE_MCS_FLAGS_POS 8
@@ -375,30 +345,6 @@ struct iwl3945_power_per_rate {
375#define IWL_PWR_CCK_ENTRIES 2 345#define IWL_PWR_CCK_ENTRIES 2
376 346
377/** 347/**
378 * union iwl4965_tx_power_dual_stream
379 *
380 * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
381 * Use __le32 version (struct tx_power_dual_stream) when building command.
382 *
383 * Driver provides radio gain and DSP attenuation settings to device in pairs,
384 * one value for each transmitter chain. The first value is for transmitter A,
385 * second for transmitter B.
386 *
387 * For SISO bit rates, both values in a pair should be identical.
388 * For MIMO rates, one value may be different from the other,
389 * in order to balance the Tx output between the two transmitters.
390 *
391 * See more details in doc for TXPOWER in iwl-4965-hw.h.
392 */
393union iwl4965_tx_power_dual_stream {
394 struct {
395 u8 radio_tx_gain[2];
396 u8 dsp_predis_atten[2];
397 } s;
398 u32 dw;
399};
400
401/**
402 * struct tx_power_dual_stream 348 * struct tx_power_dual_stream
403 * 349 *
404 * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH 350 * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
@@ -410,15 +356,6 @@ struct tx_power_dual_stream {
410} __packed; 356} __packed;
411 357
412/** 358/**
413 * struct iwl4965_tx_power_db
414 *
415 * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
416 */
417struct iwl4965_tx_power_db {
418 struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
419} __packed;
420
421/**
422 * Command REPLY_TX_POWER_DBM_CMD = 0x98 359 * Command REPLY_TX_POWER_DBM_CMD = 0x98
423 * struct iwlagn_tx_power_dbm_cmd 360 * struct iwlagn_tx_power_dbm_cmd
424 */ 361 */
@@ -451,54 +388,6 @@ struct iwl_tx_ant_config_cmd {
451#define UCODE_VALID_OK cpu_to_le32(0x1) 388#define UCODE_VALID_OK cpu_to_le32(0x1)
452#define INITIALIZE_SUBTYPE (9) 389#define INITIALIZE_SUBTYPE (9)
453 390
454/*
455 * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
456 *
457 * uCode issues this "initialize alive" notification once the initialization
458 * uCode image has completed its work, and is ready to load the runtime image.
459 * This is the *first* "alive" notification that the driver will receive after
460 * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
461 *
462 * See comments documenting "BSM" (bootstrap state machine).
463 *
464 * For 4965, this notification contains important calibration data for
465 * calculating txpower settings:
466 *
467 * 1) Power supply voltage indication. The voltage sensor outputs higher
468 * values for lower voltage, and vice verse.
469 *
470 * 2) Temperature measurement parameters, for each of two channel widths
471 * (20 MHz and 40 MHz) supported by the radios. Temperature sensing
472 * is done via one of the receiver chains, and channel width influences
473 * the results.
474 *
475 * 3) Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation,
476 * for each of 5 frequency ranges.
477 */
478struct iwl_init_alive_resp {
479 u8 ucode_minor;
480 u8 ucode_major;
481 __le16 reserved1;
482 u8 sw_rev[8];
483 u8 ver_type;
484 u8 ver_subtype; /* "9" for initialize alive */
485 __le16 reserved2;
486 __le32 log_event_table_ptr;
487 __le32 error_event_table_ptr;
488 __le32 timestamp;
489 __le32 is_valid;
490
491 /* calibration values from "initialize" uCode */
492 __le32 voltage; /* signed, higher value is lower voltage */
493 __le32 therm_r1[2]; /* signed, 1st for normal, 2nd for HT40 */
494 __le32 therm_r2[2]; /* signed */
495 __le32 therm_r3[2]; /* signed */
496 __le32 therm_r4[2]; /* signed */
497 __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups,
498 * 2 Tx chains */
499} __packed;
500
501
502/** 391/**
503 * REPLY_ALIVE = 0x1 (response only, not a command) 392 * REPLY_ALIVE = 0x1 (response only, not a command)
504 * 393 *
@@ -722,46 +611,6 @@ enum {
722 * regardless of whether RXON_FILTER_ASSOC_MSK is set. 611 * regardless of whether RXON_FILTER_ASSOC_MSK is set.
723 */ 612 */
724 613
725struct iwl3945_rxon_cmd {
726 u8 node_addr[6];
727 __le16 reserved1;
728 u8 bssid_addr[6];
729 __le16 reserved2;
730 u8 wlap_bssid_addr[6];
731 __le16 reserved3;
732 u8 dev_type;
733 u8 air_propagation;
734 __le16 reserved4;
735 u8 ofdm_basic_rates;
736 u8 cck_basic_rates;
737 __le16 assoc_id;
738 __le32 flags;
739 __le32 filter_flags;
740 __le16 channel;
741 __le16 reserved5;
742} __packed;
743
744struct iwl4965_rxon_cmd {
745 u8 node_addr[6];
746 __le16 reserved1;
747 u8 bssid_addr[6];
748 __le16 reserved2;
749 u8 wlap_bssid_addr[6];
750 __le16 reserved3;
751 u8 dev_type;
752 u8 air_propagation;
753 __le16 rx_chain;
754 u8 ofdm_basic_rates;
755 u8 cck_basic_rates;
756 __le16 assoc_id;
757 __le32 flags;
758 __le32 filter_flags;
759 __le16 channel;
760 u8 ofdm_ht_single_stream_basic_rates;
761 u8 ofdm_ht_dual_stream_basic_rates;
762} __packed;
763
764/* 5000 HW just extend this command */
765struct iwl_rxon_cmd { 614struct iwl_rxon_cmd {
766 u8 node_addr[6]; 615 u8 node_addr[6];
767 __le16 reserved1; 616 __le16 reserved1;
@@ -789,25 +638,6 @@ struct iwl_rxon_cmd {
789/* 638/*
790 * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) 639 * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
791 */ 640 */
792struct iwl3945_rxon_assoc_cmd {
793 __le32 flags;
794 __le32 filter_flags;
795 u8 ofdm_basic_rates;
796 u8 cck_basic_rates;
797 __le16 reserved;
798} __packed;
799
800struct iwl4965_rxon_assoc_cmd {
801 __le32 flags;
802 __le32 filter_flags;
803 u8 ofdm_basic_rates;
804 u8 cck_basic_rates;
805 u8 ofdm_ht_single_stream_basic_rates;
806 u8 ofdm_ht_dual_stream_basic_rates;
807 __le16 rx_chain_select_flags;
808 __le16 reserved;
809} __packed;
810
811struct iwl5000_rxon_assoc_cmd { 641struct iwl5000_rxon_assoc_cmd {
812 __le32 flags; 642 __le32 flags;
813 __le32 filter_flags; 643 __le32 filter_flags;
@@ -843,26 +673,6 @@ struct iwl_rxon_time_cmd {
843/* 673/*
844 * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) 674 * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
845 */ 675 */
846struct iwl3945_channel_switch_cmd {
847 u8 band;
848 u8 expect_beacon;
849 __le16 channel;
850 __le32 rxon_flags;
851 __le32 rxon_filter_flags;
852 __le32 switch_time;
853 struct iwl3945_power_per_rate power[IWL_MAX_RATES];
854} __packed;
855
856struct iwl4965_channel_switch_cmd {
857 u8 band;
858 u8 expect_beacon;
859 __le16 channel;
860 __le32 rxon_flags;
861 __le32 rxon_filter_flags;
862 __le32 switch_time;
863 struct iwl4965_tx_power_db tx_power;
864} __packed;
865
866/** 676/**
867 * struct iwl5000_channel_switch_cmd 677 * struct iwl5000_channel_switch_cmd
868 * @band: 0- 5.2GHz, 1- 2.4GHz 678 * @band: 0- 5.2GHz, 1- 2.4GHz
@@ -976,15 +786,10 @@ struct iwl_qosparam_cmd {
976#define IWL_AP_ID 0 786#define IWL_AP_ID 0
977#define IWL_AP_ID_PAN 1 787#define IWL_AP_ID_PAN 1
978#define IWL_STA_ID 2 788#define IWL_STA_ID 2
979#define IWL3945_BROADCAST_ID 24
980#define IWL3945_STATION_COUNT 25
981#define IWL4965_BROADCAST_ID 31
982#define IWL4965_STATION_COUNT 32
983#define IWLAGN_PAN_BCAST_ID 14 789#define IWLAGN_PAN_BCAST_ID 14
984#define IWLAGN_BROADCAST_ID 15 790#define IWLAGN_BROADCAST_ID 15
985#define IWLAGN_STATION_COUNT 16 791#define IWLAGN_STATION_COUNT 16
986 792
987#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
988#define IWL_INVALID_STATION 255 793#define IWL_INVALID_STATION 255
989 794
990#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) 795#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
@@ -1032,16 +837,6 @@ struct iwl_qosparam_cmd {
1032 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ 837 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
1033#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) 838#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1034 839
1035struct iwl4965_keyinfo {
1036 __le16 key_flags;
1037 u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
1038 u8 reserved1;
1039 __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
1040 u8 key_offset;
1041 u8 reserved2;
1042 u8 key[16]; /* 16-byte unicast decryption key */
1043} __packed;
1044
1045/* agn */ 840/* agn */
1046struct iwl_keyinfo { 841struct iwl_keyinfo {
1047 __le16 key_flags; 842 __le16 key_flags;
@@ -1083,7 +878,6 @@ struct sta_id_modify {
1083 * with info on security keys, aggregation parameters, and Tx rates for 878 * with info on security keys, aggregation parameters, and Tx rates for
1084 * initial Tx attempt and any retries (agn devices uses 879 * initial Tx attempt and any retries (agn devices uses
1085 * REPLY_TX_LINK_QUALITY_CMD, 880 * REPLY_TX_LINK_QUALITY_CMD,
1086 * 3945 uses REPLY_RATE_SCALE to set up rate tables).
1087 * 881 *
1088 * REPLY_ADD_STA sets up the table entry for one station, either creating 882 * REPLY_ADD_STA sets up the table entry for one station, either creating
1089 * a new entry, or modifying a pre-existing one. 883 * a new entry, or modifying a pre-existing one.
@@ -1103,72 +897,6 @@ struct sta_id_modify {
1103 * entries for all STAs in network, starting with index IWL_STA_ID. 897 * entries for all STAs in network, starting with index IWL_STA_ID.
1104 */ 898 */
1105 899
1106struct iwl3945_addsta_cmd {
1107 u8 mode; /* 1: modify existing, 0: add new station */
1108 u8 reserved[3];
1109 struct sta_id_modify sta;
1110 struct iwl4965_keyinfo key;
1111 __le32 station_flags; /* STA_FLG_* */
1112 __le32 station_flags_msk; /* STA_FLG_* */
1113
1114 /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
1115 * corresponding to bit (e.g. bit 5 controls TID 5).
1116 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
1117 __le16 tid_disable_tx;
1118
1119 __le16 rate_n_flags;
1120
1121 /* TID for which to add block-ack support.
1122 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
1123 u8 add_immediate_ba_tid;
1124
1125 /* TID for which to remove block-ack support.
1126 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
1127 u8 remove_immediate_ba_tid;
1128
1129 /* Starting Sequence Number for added block-ack support.
1130 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
1131 __le16 add_immediate_ba_ssn;
1132} __packed;
1133
1134struct iwl4965_addsta_cmd {
1135 u8 mode; /* 1: modify existing, 0: add new station */
1136 u8 reserved[3];
1137 struct sta_id_modify sta;
1138 struct iwl4965_keyinfo key;
1139 __le32 station_flags; /* STA_FLG_* */
1140 __le32 station_flags_msk; /* STA_FLG_* */
1141
1142 /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
1143 * corresponding to bit (e.g. bit 5 controls TID 5).
1144 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
1145 __le16 tid_disable_tx;
1146
1147 __le16 reserved1;
1148
1149 /* TID for which to add block-ack support.
1150 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
1151 u8 add_immediate_ba_tid;
1152
1153 /* TID for which to remove block-ack support.
1154 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
1155 u8 remove_immediate_ba_tid;
1156
1157 /* Starting Sequence Number for added block-ack support.
1158 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
1159 __le16 add_immediate_ba_ssn;
1160
1161 /*
1162 * Number of packets OK to transmit to station even though
1163 * it is asleep -- used to synchronise PS-poll and u-APSD
1164 * responses while ucode keeps track of STA sleep state.
1165 */
1166 __le16 sleep_tx_count;
1167
1168 __le16 reserved2;
1169} __packed;
1170
1171/* agn */
1172struct iwl_addsta_cmd { 900struct iwl_addsta_cmd {
1173 u8 mode; /* 1: modify existing, 0: add new station */ 901 u8 mode; /* 1: modify existing, 0: add new station */
1174 u8 reserved[3]; 902 u8 reserved[3];
@@ -1337,62 +1065,6 @@ struct iwl_wep_cmd {
1337#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) 1065#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
1338 1066
1339 1067
1340struct iwl3945_rx_frame_stats {
1341 u8 phy_count;
1342 u8 id;
1343 u8 rssi;
1344 u8 agc;
1345 __le16 sig_avg;
1346 __le16 noise_diff;
1347 u8 payload[0];
1348} __packed;
1349
1350struct iwl3945_rx_frame_hdr {
1351 __le16 channel;
1352 __le16 phy_flags;
1353 u8 reserved1;
1354 u8 rate;
1355 __le16 len;
1356 u8 payload[0];
1357} __packed;
1358
1359struct iwl3945_rx_frame_end {
1360 __le32 status;
1361 __le64 timestamp;
1362 __le32 beacon_timestamp;
1363} __packed;
1364
1365/*
1366 * REPLY_3945_RX = 0x1b (response only, not a command)
1367 *
1368 * NOTE: DO NOT dereference from casts to this structure
1369 * It is provided only for calculating minimum data set size.
1370 * The actual offsets of the hdr and end are dynamic based on
1371 * stats.phy_count
1372 */
1373struct iwl3945_rx_frame {
1374 struct iwl3945_rx_frame_stats stats;
1375 struct iwl3945_rx_frame_hdr hdr;
1376 struct iwl3945_rx_frame_end end;
1377} __packed;
1378
1379#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
1380
1381/* Fixed (non-configurable) rx data from phy */
1382
1383#define IWL49_RX_RES_PHY_CNT 14
1384#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
1385#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
1386#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
1387#define IWL49_AGC_DB_POS (7)
1388struct iwl4965_rx_non_cfg_phy {
1389 __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */
1390 __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */
1391 u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */
1392 u8 pad[0];
1393} __packed;
1394
1395
1396#define IWLAGN_RX_RES_PHY_CNT 8 1068#define IWLAGN_RX_RES_PHY_CNT 8
1397#define IWLAGN_RX_RES_AGC_IDX 1 1069#define IWLAGN_RX_RES_AGC_IDX 1
1398#define IWLAGN_RX_RES_RSSI_AB_IDX 2 1070#define IWLAGN_RX_RES_RSSI_AB_IDX 2
@@ -1576,80 +1248,6 @@ struct iwl_rx_mpdu_res_start {
1576 * REPLY_TX = 0x1c (command) 1248 * REPLY_TX = 0x1c (command)
1577 */ 1249 */
1578 1250
1579struct iwl3945_tx_cmd {
1580 /*
1581 * MPDU byte count:
1582 * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
1583 * + 8 byte IV for CCM or TKIP (not used for WEP)
1584 * + Data payload
1585 * + 8-byte MIC (not used for CCM/WEP)
1586 * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
1587 * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
1588 * Range: 14-2342 bytes.
1589 */
1590 __le16 len;
1591
1592 /*
1593 * MPDU or MSDU byte count for next frame.
1594 * Used for fragmentation and bursting, but not 11n aggregation.
1595 * Same as "len", but for next frame. Set to 0 if not applicable.
1596 */
1597 __le16 next_frame_len;
1598
1599 __le32 tx_flags; /* TX_CMD_FLG_* */
1600
1601 u8 rate;
1602
1603 /* Index of recipient station in uCode's station table */
1604 u8 sta_id;
1605 u8 tid_tspec;
1606 u8 sec_ctl;
1607 u8 key[16];
1608 union {
1609 u8 byte[8];
1610 __le16 word[4];
1611 __le32 dw[2];
1612 } tkip_mic;
1613 __le32 next_frame_info;
1614 union {
1615 __le32 life_time;
1616 __le32 attempt;
1617 } stop_time;
1618 u8 supp_rates[2];
1619 u8 rts_retry_limit; /*byte 50 */
1620 u8 data_retry_limit; /*byte 51 */
1621 union {
1622 __le16 pm_frame_timeout;
1623 __le16 attempt_duration;
1624 } timeout;
1625
1626 /*
1627 * Duration of EDCA burst Tx Opportunity, in 32-usec units.
1628 * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
1629 */
1630 __le16 driver_txop;
1631
1632 /*
1633 * MAC header goes here, followed by 2 bytes padding if MAC header
1634 * length is 26 or 30 bytes, followed by payload data
1635 */
1636 u8 payload[0];
1637 struct ieee80211_hdr hdr[0];
1638} __packed;
1639
1640/*
1641 * REPLY_TX = 0x1c (response)
1642 */
1643struct iwl3945_tx_resp {
1644 u8 failure_rts;
1645 u8 failure_frame;
1646 u8 bt_kill_count;
1647 u8 rate;
1648 __le32 wireless_media_time;
1649 __le32 status; /* TX status */
1650} __packed;
1651
1652
1653/* 1251/*
1654 * 4965 uCode updates these Tx attempt count values in host DRAM. 1252 * 4965 uCode updates these Tx attempt count values in host DRAM.
1655 * Used for managing Tx retries when expecting block-acks. 1253 * Used for managing Tx retries when expecting block-acks.
@@ -1740,54 +1338,6 @@ struct iwl_tx_cmd {
1740 struct ieee80211_hdr hdr[0]; 1338 struct ieee80211_hdr hdr[0];
1741} __packed; 1339} __packed;
1742 1340
1743/* TX command response is sent after *3945* transmission attempts.
1744 *
1745 * NOTES:
1746 *
1747 * TX_STATUS_FAIL_NEXT_FRAG
1748 *
1749 * If the fragment flag in the MAC header for the frame being transmitted
1750 * is set and there is insufficient time to transmit the next frame, the
1751 * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
1752 *
1753 * TX_STATUS_FIFO_UNDERRUN
1754 *
1755 * Indicates the host did not provide bytes to the FIFO fast enough while
1756 * a TX was in progress.
1757 *
1758 * TX_STATUS_FAIL_MGMNT_ABORT
1759 *
1760 * This status is only possible if the ABORT ON MGMT RX parameter was
1761 * set to true with the TX command.
1762 *
1763 * If the MSB of the status parameter is set then an abort sequence is
1764 * required. This sequence consists of the host activating the TX Abort
1765 * control line, and then waiting for the TX Abort command response. This
1766 * indicates that a the device is no longer in a transmit state, and that the
1767 * command FIFO has been cleared. The host must then deactivate the TX Abort
1768 * control line. Receiving is still allowed in this case.
1769 */
1770enum {
1771 TX_3945_STATUS_SUCCESS = 0x01,
1772 TX_3945_STATUS_DIRECT_DONE = 0x02,
1773 TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82,
1774 TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83,
1775 TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
1776 TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85,
1777 TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86,
1778 TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87,
1779 TX_3945_STATUS_FAIL_DEST_PS = 0x88,
1780 TX_3945_STATUS_FAIL_ABORTED = 0x89,
1781 TX_3945_STATUS_FAIL_BT_RETRY = 0x8a,
1782 TX_3945_STATUS_FAIL_STA_INVALID = 0x8b,
1783 TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c,
1784 TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d,
1785 TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
1786 TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
1787 TX_3945_STATUS_FAIL_TX_LOCKED = 0x90,
1788 TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
1789};
1790
1791/* 1341/*
1792 * TX command response is sent after *agn* transmission attempts. 1342 * TX command response is sent after *agn* transmission attempts.
1793 * 1343 *
@@ -1905,43 +1455,6 @@ struct agg_tx_status {
1905 __le16 sequence; 1455 __le16 sequence;
1906} __packed; 1456} __packed;
1907 1457
1908struct iwl4965_tx_resp {
1909 u8 frame_count; /* 1 no aggregation, >1 aggregation */
1910 u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
1911 u8 failure_rts; /* # failures due to unsuccessful RTS */
1912 u8 failure_frame; /* # failures due to no ACK (unused for agg) */
1913
1914 /* For non-agg: Rate at which frame was successful.
1915 * For agg: Rate at which all frames were transmitted. */
1916 __le32 rate_n_flags; /* RATE_MCS_* */
1917
1918 /* For non-agg: RTS + CTS + frame tx attempts time + ACK.
1919 * For agg: RTS + CTS + aggregation tx time + block-ack time. */
1920 __le16 wireless_media_time; /* uSecs */
1921
1922 __le16 reserved;
1923 __le32 pa_power1; /* RF power amplifier measurement (not used) */
1924 __le32 pa_power2;
1925
1926 /*
1927 * For non-agg: frame status TX_STATUS_*
1928 * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status
1929 * fields follow this one, up to frame_count.
1930 * Bit fields:
1931 * 11- 0: AGG_TX_STATE_* status code
1932 * 15-12: Retry count for 1st frame in aggregation (retries
1933 * occur if tx failed for this frame when it was a
1934 * member of a previous aggregation block). If rate
1935 * scaling is used, retry count indicates the rate
1936 * table entry used for all frames in the new agg.
1937 * 31-16: Sequence # for this frame's Tx cmd (not SSN!)
1938 */
1939 union {
1940 __le32 status;
1941 struct agg_tx_status agg_status[0]; /* for each agg frame */
1942 } u;
1943} __packed;
1944
1945/* 1458/*
1946 * definitions for initial rate index field 1459 * definitions for initial rate index field
1947 * bits [3:0] initial rate index 1460 * bits [3:0] initial rate index
@@ -2030,51 +1543,7 @@ struct iwl_compressed_ba_resp {
2030/* 1543/*
2031 * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) 1544 * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
2032 * 1545 *
2033 * See details under "TXPOWER" in iwl-4965-hw.h.
2034 */
2035
2036struct iwl3945_txpowertable_cmd {
2037 u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
2038 u8 reserved;
2039 __le16 channel;
2040 struct iwl3945_power_per_rate power[IWL_MAX_RATES];
2041} __packed;
2042
2043struct iwl4965_txpowertable_cmd {
2044 u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
2045 u8 reserved;
2046 __le16 channel;
2047 struct iwl4965_tx_power_db tx_power;
2048} __packed;
2049
2050
2051/**
2052 * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
2053 *
2054 * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
2055 *
2056 * NOTE: The table of rates passed to the uCode via the
2057 * RATE_SCALE command sets up the corresponding order of
2058 * rates used for all related commands, including rate
2059 * masks, etc.
2060 *
2061 * For example, if you set 9MB (PLCP 0x0f) as the first
2062 * rate in the rate table, the bit mask for that rate
2063 * when passed through ofdm_basic_rates on the REPLY_RXON
2064 * command would be bit 0 (1 << 0)
2065 */ 1546 */
2066struct iwl3945_rate_scaling_info {
2067 __le16 rate_n_flags;
2068 u8 try_cnt;
2069 u8 next_rate_index;
2070} __packed;
2071
2072struct iwl3945_rate_scaling_cmd {
2073 u8 table_id;
2074 u8 reserved[3];
2075 struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
2076} __packed;
2077
2078 1547
2079/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ 1548/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
2080#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) 1549#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0)
@@ -2130,7 +1599,7 @@ struct iwl_link_qual_general_params {
2130#define LINK_QUAL_AGG_DISABLE_START_MAX (255) 1599#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
2131#define LINK_QUAL_AGG_DISABLE_START_MIN (0) 1600#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
2132 1601
2133#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31) 1602#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
2134#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) 1603#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
2135#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) 1604#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
2136 1605
@@ -2696,14 +2165,6 @@ struct iwl_spectrum_notification {
2696#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8)) 2165#define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8))
2697#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9)) 2166#define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9))
2698 2167
2699struct iwl3945_powertable_cmd {
2700 __le16 flags;
2701 u8 reserved[2];
2702 __le32 rx_data_timeout;
2703 __le32 tx_data_timeout;
2704 __le32 sleep_interval[IWL_POWER_VEC_SIZE];
2705} __packed;
2706
2707struct iwl_powertable_cmd { 2168struct iwl_powertable_cmd {
2708 __le16 flags; 2169 __le16 flags;
2709 u8 keep_alive_seconds; /* 3945 reserved */ 2170 u8 keep_alive_seconds; /* 3945 reserved */
@@ -2806,25 +2267,6 @@ struct iwl_ct_kill_throttling_config {
2806 * active_dwell < max_out_time 2267 * active_dwell < max_out_time
2807 */ 2268 */
2808 2269
2809/* FIXME: rename to AP1, remove tpc */
2810struct iwl3945_scan_channel {
2811 /*
2812 * type is defined as:
2813 * 0:0 1 = active, 0 = passive
2814 * 1:4 SSID direct bit map; if a bit is set, then corresponding
2815 * SSID IE is transmitted in probe request.
2816 * 5:7 reserved
2817 */
2818 u8 type;
2819 u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
2820 struct iwl3945_tx_power tpc;
2821 __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
2822 __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
2823} __packed;
2824
2825/* set number of direct probes u8 type */
2826#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
2827
2828struct iwl_scan_channel { 2270struct iwl_scan_channel {
2829 /* 2271 /*
2830 * type is defined as: 2272 * type is defined as:
@@ -2920,50 +2362,6 @@ struct iwl_ssid_ie {
2920 * struct iwl_scan_channel. 2362 * struct iwl_scan_channel.
2921 */ 2363 */
2922 2364
2923struct iwl3945_scan_cmd {
2924 __le16 len;
2925 u8 reserved0;
2926 u8 channel_count; /* # channels in channel list */
2927 __le16 quiet_time; /* dwell only this # millisecs on quiet channel
2928 * (only for active scan) */
2929 __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
2930 __le16 good_CRC_th; /* passive -> active promotion threshold */
2931 __le16 reserved1;
2932 __le32 max_out_time; /* max usec to be away from associated (service)
2933 * channel */
2934 __le32 suspend_time; /* pause scan this long (in "extended beacon
2935 * format") when returning to service channel:
2936 * 3945; 31:24 # beacons, 19:0 additional usec,
2937 * 4965; 31:22 # beacons, 21:0 additional usec.
2938 */
2939 __le32 flags; /* RXON_FLG_* */
2940 __le32 filter_flags; /* RXON_FILTER_* */
2941
2942 /* For active scans (set to all-0s for passive scans).
2943 * Does not include payload. Must specify Tx rate; no rate scaling. */
2944 struct iwl3945_tx_cmd tx_cmd;
2945
2946 /* For directed active scans (set to all-0s otherwise) */
2947 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
2948
2949 /*
2950 * Probe request frame, followed by channel list.
2951 *
2952 * Size of probe request frame is specified by byte count in tx_cmd.
2953 * Channel list follows immediately after probe request frame.
2954 * Number of channels in list is specified by channel_count.
2955 * Each channel in list is of type:
2956 *
2957 * struct iwl3945_scan_channel channels[0];
2958 *
2959 * NOTE: Only one band of channels can be scanned per pass. You
2960 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
2961 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
2962 * before requesting another scan.
2963 */
2964 u8 data[0];
2965} __packed;
2966
2967enum iwl_scan_flags { 2365enum iwl_scan_flags {
2968 /* BIT(0) currently unused */ 2366 /* BIT(0) currently unused */
2969 IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1), 2367 IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1),
@@ -3090,20 +2488,6 @@ enum iwl_ibss_manager {
3090 * BEACON_NOTIFICATION = 0x90 (notification only, not a command) 2488 * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
3091 */ 2489 */
3092 2490
3093struct iwl3945_beacon_notif {
3094 struct iwl3945_tx_resp beacon_notify_hdr;
3095 __le32 low_tsf;
3096 __le32 high_tsf;
3097 __le32 ibss_mgr_status;
3098} __packed;
3099
3100struct iwl4965_beacon_notif {
3101 struct iwl4965_tx_resp beacon_notify_hdr;
3102 __le32 low_tsf;
3103 __le32 high_tsf;
3104 __le32 ibss_mgr_status;
3105} __packed;
3106
3107struct iwlagn_beacon_notif { 2491struct iwlagn_beacon_notif {
3108 struct iwlagn_tx_resp beacon_notify_hdr; 2492 struct iwlagn_tx_resp beacon_notify_hdr;
3109 __le32 low_tsf; 2493 __le32 low_tsf;
@@ -3115,14 +2499,6 @@ struct iwlagn_beacon_notif {
3115 * REPLY_TX_BEACON = 0x91 (command, has simple generic response) 2499 * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
3116 */ 2500 */
3117 2501
3118struct iwl3945_tx_beacon_cmd {
3119 struct iwl3945_tx_cmd tx;
3120 __le16 tim_idx;
3121 u8 tim_size;
3122 u8 reserved1;
3123 struct ieee80211_hdr frame[0]; /* beacon frame */
3124} __packed;
3125
3126struct iwl_tx_beacon_cmd { 2502struct iwl_tx_beacon_cmd {
3127 struct iwl_tx_cmd tx; 2503 struct iwl_tx_cmd tx;
3128 __le16 tim_idx; 2504 __le16 tim_idx;
@@ -3471,13 +2847,6 @@ struct iwl_statistics_cmd {
3471#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) 2847#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
3472#define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8) 2848#define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8)
3473 2849
3474struct iwl3945_notif_statistics {
3475 __le32 flag;
3476 struct iwl39_statistics_rx rx;
3477 struct iwl39_statistics_tx tx;
3478 struct iwl39_statistics_general general;
3479} __packed;
3480
3481struct iwl_notif_statistics { 2850struct iwl_notif_statistics {
3482 __le32 flag; 2851 __le32 flag;
3483 struct statistics_rx rx; 2852 struct statistics_rx rx;
@@ -4451,10 +3820,6 @@ struct iwl_rx_packet {
4451 __le32 len_n_flags; 3820 __le32 len_n_flags;
4452 struct iwl_cmd_header hdr; 3821 struct iwl_cmd_header hdr;
4453 union { 3822 union {
4454 struct iwl3945_rx_frame rx_frame;
4455 struct iwl3945_tx_resp tx_resp;
4456 struct iwl3945_beacon_notif beacon_status;
4457
4458 struct iwl_alive_resp alive_frame; 3823 struct iwl_alive_resp alive_frame;
4459 struct iwl_spectrum_notification spectrum_notif; 3824 struct iwl_spectrum_notification spectrum_notif;
4460 struct iwl_csa_notification csa_notif; 3825 struct iwl_csa_notification csa_notif;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index bafbe57c9602..45ec5cfe3fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -890,10 +890,8 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
890 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); 890 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
891} 891}
892#endif 892#endif
893/** 893
894 * iwl_irq_handle_error - called for HW or SW error interrupt from card 894void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
895 */
896void iwl_irq_handle_error(struct iwl_priv *priv)
897{ 895{
898 unsigned int reload_msec; 896 unsigned int reload_msec;
899 unsigned long reload_jiffies; 897 unsigned long reload_jiffies;
@@ -904,18 +902,62 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
904 /* Cancel currently queued command. */ 902 /* Cancel currently queued command. */
905 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 903 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
906 904
905 /* Keep the restart process from trying to send host
906 * commands by clearing the ready bit */
907 clear_bit(STATUS_READY, &priv->status);
908
909 wake_up_interruptible(&priv->wait_command_queue);
910
911 if (!ondemand) {
912 /*
913 * If firmware keep reloading, then it indicate something
914 * serious wrong and firmware having problem to recover
915 * from it. Instead of keep trying which will fill the syslog
916 * and hang the system, let's just stop it
917 */
918 reload_jiffies = jiffies;
919 reload_msec = jiffies_to_msecs((long) reload_jiffies -
920 (long) priv->reload_jiffies);
921 priv->reload_jiffies = reload_jiffies;
922 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
923 priv->reload_count++;
924 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
925 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
926 return;
927 }
928 } else
929 priv->reload_count = 0;
930 }
931
932 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
933 if (priv->cfg->mod_params->restart_fw) {
934 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
935 "Restarting adapter due to uCode error.\n");
936 queue_work(priv->workqueue, &priv->restart);
937 } else
938 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
939 "Detected FW error, but not restarting\n");
940 }
941}
942
943/**
944 * iwl_irq_handle_error - called for HW or SW error interrupt from card
945 */
946void iwl_irq_handle_error(struct iwl_priv *priv)
947{
907 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ 948 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
908 if (priv->cfg->internal_wimax_coex && 949 if (priv->cfg->internal_wimax_coex &&
909 (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) & 950 (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
910 APMS_CLK_VAL_MRB_FUNC_MODE) || 951 APMS_CLK_VAL_MRB_FUNC_MODE) ||
911 (iwl_read_prph(priv, APMG_PS_CTRL_REG) & 952 (iwl_read_prph(priv, APMG_PS_CTRL_REG) &
912 APMG_PS_CTRL_VAL_RESET_REQ))) { 953 APMG_PS_CTRL_VAL_RESET_REQ))) {
913 wake_up_interruptible(&priv->wait_command_queue);
914 /* 954 /*
915 *Keep the restart process from trying to send host 955 * Keep the restart process from trying to send host
916 * commands by clearing the INIT status bit 956 * commands by clearing the ready bit.
917 */ 957 */
918 clear_bit(STATUS_READY, &priv->status); 958 clear_bit(STATUS_READY, &priv->status);
959 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
960 wake_up_interruptible(&priv->wait_command_queue);
919 IWL_ERR(priv, "RF is used by WiMAX\n"); 961 IWL_ERR(priv, "RF is used by WiMAX\n");
920 return; 962 return;
921 } 963 }
@@ -935,38 +977,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
935 &priv->contexts[IWL_RXON_CTX_BSS]); 977 &priv->contexts[IWL_RXON_CTX_BSS]);
936#endif 978#endif
937 979
938 wake_up_interruptible(&priv->wait_command_queue); 980 iwlagn_fw_error(priv, false);
939
940 /* Keep the restart process from trying to send host
941 * commands by clearing the INIT status bit */
942 clear_bit(STATUS_READY, &priv->status);
943
944 /*
945 * If firmware keep reloading, then it indicate something
946 * serious wrong and firmware having problem to recover
947 * from it. Instead of keep trying which will fill the syslog
948 * and hang the system, let's just stop it
949 */
950 reload_jiffies = jiffies;
951 reload_msec = jiffies_to_msecs((long) reload_jiffies -
952 (long) priv->reload_jiffies);
953 priv->reload_jiffies = reload_jiffies;
954 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
955 priv->reload_count++;
956 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
957 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
958 return;
959 }
960 } else
961 priv->reload_count = 0;
962
963 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
964 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
965 "Restarting adapter due to uCode error.\n");
966
967 if (priv->cfg->mod_params->restart_fw)
968 queue_work(priv->workqueue, &priv->restart);
969 }
970} 981}
971 982
972static int iwl_apm_stop_master(struct iwl_priv *priv) 983static int iwl_apm_stop_master(struct iwl_priv *priv)
@@ -1094,21 +1105,13 @@ int iwl_apm_init(struct iwl_priv *priv)
1094 } 1105 }
1095 1106
1096 /* 1107 /*
1097 * Enable DMA and BSM (if used) clocks, wait for them to stabilize. 1108 * Enable DMA clock and wait for it to stabilize.
1098 * BSM (Boostrap State Machine) is only in 3945 and 4965;
1099 * later devices (i.e. 5000 and later) have non-volatile SRAM,
1100 * and don't need BSM to restore data after power-saving sleep.
1101 * 1109 *
1102 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits 1110 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
1103 * do not disable clocks. This preserves any hardware bits already 1111 * do not disable clocks. This preserves any hardware bits already
1104 * set by default in "CLK_CTRL_REG" after reset. 1112 * set by default in "CLK_CTRL_REG" after reset.
1105 */ 1113 */
1106 if (priv->cfg->base_params->use_bsm) 1114 iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
1107 iwl_write_prph(priv, APMG_CLK_EN_REG,
1108 APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
1109 else
1110 iwl_write_prph(priv, APMG_CLK_EN_REG,
1111 APMG_CLK_VAL_DMA_CLK_RQT);
1112 udelay(20); 1115 udelay(20);
1113 1116
1114 /* Disable L1-Active */ 1117 /* Disable L1-Active */
@@ -1430,7 +1433,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1430 1433
1431 iwl_teardown_interface(priv, vif, false); 1434 iwl_teardown_interface(priv, vif, false);
1432 1435
1433 memset(priv->bssid, 0, ETH_ALEN);
1434 mutex_unlock(&priv->mutex); 1436 mutex_unlock(&priv->mutex);
1435 1437
1436 IWL_DEBUG_MAC80211(priv, "leave\n"); 1438 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1756,15 +1758,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
1756 break; 1758 break;
1757 } 1759 }
1758 IWL_ERR(priv, "On demand firmware reload\n"); 1760 IWL_ERR(priv, "On demand firmware reload\n");
1759 /* Set the FW error flag -- cleared on iwl_down */ 1761 iwlagn_fw_error(priv, true);
1760 set_bit(STATUS_FW_ERROR, &priv->status);
1761 wake_up_interruptible(&priv->wait_command_queue);
1762 /*
1763 * Keep the restart process from trying to send host
1764 * commands by clearing the INIT status bit
1765 */
1766 clear_bit(STATUS_READY, &priv->status);
1767 queue_work(priv->workqueue, &priv->restart);
1768 break; 1762 break;
1769 } 1763 }
1770 return 0; 1764 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b316d833d9a2..82939f851eb9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,7 @@ struct iwl_cmd;
73 73
74 74
75#define IWLWIFI_VERSION "in-tree:" 75#define IWLWIFI_VERSION "in-tree:"
76#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" 76#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation"
77#define DRV_AUTHOR "<ilw@linux.intel.com>" 77#define DRV_AUTHOR "<ilw@linux.intel.com>"
78 78
79#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 79#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -122,14 +122,6 @@ struct iwl_apm_ops {
122 void (*config)(struct iwl_priv *priv); 122 void (*config)(struct iwl_priv *priv);
123}; 123};
124 124
125struct iwl_isr_ops {
126 irqreturn_t (*isr) (int irq, void *data);
127 void (*free)(struct iwl_priv *priv);
128 int (*alloc)(struct iwl_priv *priv);
129 int (*reset)(struct iwl_priv *priv);
130 void (*disable)(struct iwl_priv *priv);
131};
132
133struct iwl_debugfs_ops { 125struct iwl_debugfs_ops {
134 ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf, 126 ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
135 size_t count, loff_t *ppos); 127 size_t count, loff_t *ppos);
@@ -171,25 +163,15 @@ struct iwl_lib_ops {
171 struct iwl_tx_queue *txq); 163 struct iwl_tx_queue *txq);
172 int (*txq_init)(struct iwl_priv *priv, 164 int (*txq_init)(struct iwl_priv *priv,
173 struct iwl_tx_queue *txq); 165 struct iwl_tx_queue *txq);
174 /* aggregations */
175 int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
176 int sta_id, int tid, u16 ssn_idx);
177 int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
178 u8 tx_fifo);
179 /* setup Rx handler */ 166 /* setup Rx handler */
180 void (*rx_handler_setup)(struct iwl_priv *priv); 167 void (*rx_handler_setup)(struct iwl_priv *priv);
181 /* setup deferred work */ 168 /* setup deferred work */
182 void (*setup_deferred_work)(struct iwl_priv *priv); 169 void (*setup_deferred_work)(struct iwl_priv *priv);
183 /* cancel deferred work */ 170 /* cancel deferred work */
184 void (*cancel_deferred_work)(struct iwl_priv *priv); 171 void (*cancel_deferred_work)(struct iwl_priv *priv);
185 /* alive notification after init uCode load */
186 void (*init_alive_start)(struct iwl_priv *priv);
187 /* alive notification */
188 int (*alive_notify)(struct iwl_priv *priv);
189 /* check validity of rtc data address */ 172 /* check validity of rtc data address */
190 int (*is_valid_rtc_data_addr)(u32 addr); 173 int (*is_valid_rtc_data_addr)(u32 addr);
191 /* 1st ucode load */ 174
192 int (*load_ucode)(struct iwl_priv *priv);
193 int (*dump_nic_event_log)(struct iwl_priv *priv, 175 int (*dump_nic_event_log)(struct iwl_priv *priv,
194 bool full_log, char **buf, bool display); 176 bool full_log, char **buf, bool display);
195 void (*dump_nic_error_log)(struct iwl_priv *priv); 177 void (*dump_nic_error_log)(struct iwl_priv *priv);
@@ -204,9 +186,6 @@ struct iwl_lib_ops {
204 int (*send_tx_power) (struct iwl_priv *priv); 186 int (*send_tx_power) (struct iwl_priv *priv);
205 void (*update_chain_flags)(struct iwl_priv *priv); 187 void (*update_chain_flags)(struct iwl_priv *priv);
206 188
207 /* isr */
208 struct iwl_isr_ops isr_ops;
209
210 /* eeprom operations (as defined in iwl-eeprom.h) */ 189 /* eeprom operations (as defined in iwl-eeprom.h) */
211 struct iwl_eeprom_ops eeprom_ops; 190 struct iwl_eeprom_ops eeprom_ops;
212 191
@@ -252,7 +231,6 @@ struct iwl_ops {
252 231
253struct iwl_mod_params { 232struct iwl_mod_params {
254 int sw_crypto; /* def: 0 = using hardware encryption */ 233 int sw_crypto; /* def: 0 = using hardware encryption */
255 int disable_hw_scan; /* def: 0 = use h/w scan */
256 int num_of_queues; /* def: HW dependent */ 234 int num_of_queues; /* def: HW dependent */
257 int disable_11n; /* def: 0 = 11n capabilities enabled */ 235 int disable_11n; /* def: 0 = 11n capabilities enabled */
258 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ 236 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
@@ -286,8 +264,6 @@ struct iwl_mod_params {
286 * @chain_noise_calib_by_driver: driver has the capability to perform 264 * @chain_noise_calib_by_driver: driver has the capability to perform
287 * chain noise calibration operation 265 * chain noise calibration operation
288 * @shadow_reg_enable: HW shadhow register bit 266 * @shadow_reg_enable: HW shadhow register bit
289 * @no_agg_framecnt_info: uCode do not provide aggregation frame count
290 * information
291 */ 267 */
292struct iwl_base_params { 268struct iwl_base_params {
293 int eeprom_size; 269 int eeprom_size;
@@ -296,9 +272,7 @@ struct iwl_base_params {
296 /* for iwl_apm_init() */ 272 /* for iwl_apm_init() */
297 u32 pll_cfg_val; 273 u32 pll_cfg_val;
298 bool set_l0s; 274 bool set_l0s;
299 bool use_bsm;
300 275
301 bool use_isr_legacy;
302 const u16 max_ll_items; 276 const u16 max_ll_items;
303 const bool shadow_ram_support; 277 const bool shadow_ram_support;
304 u16 led_compensation; 278 u16 led_compensation;
@@ -317,7 +291,6 @@ struct iwl_base_params {
317 const bool sensitivity_calib_by_driver; 291 const bool sensitivity_calib_by_driver;
318 const bool chain_noise_calib_by_driver; 292 const bool chain_noise_calib_by_driver;
319 const bool shadow_reg_enable; 293 const bool shadow_reg_enable;
320 const bool no_agg_framecnt_info;
321}; 294};
322/* 295/*
323 * @advanced_bt_coexist: support advanced bt coexist 296 * @advanced_bt_coexist: support advanced bt coexist
@@ -738,10 +711,13 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
738 711
739static inline bool iwl_bt_statistics(struct iwl_priv *priv) 712static inline bool iwl_bt_statistics(struct iwl_priv *priv)
740{ 713{
741 return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics; 714 return priv->bt_statistics;
742} 715}
743 716
744extern bool bt_coex_active; 717extern bool bt_coex_active;
745extern bool bt_siso_mode; 718extern bool bt_siso_mode;
746 719
720
721void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
722
747#endif /* __iwl_core_h__ */ 723#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f52bc040bcbf..5ab90ba7a024 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -155,18 +155,10 @@
155#define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) 155#define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250)
156 156
157/* Bits for CSR_HW_IF_CONFIG_REG */ 157/* Bits for CSR_HW_IF_CONFIG_REG */
158#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
159#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) 158#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)
160#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) 159#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
161#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) 160#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
162 161
163#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100)
164#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200)
165#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400)
166#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800)
167#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
168#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
169
170#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) 162#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
171#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) 163#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
172#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */ 164#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */
@@ -186,7 +178,7 @@
186#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ 178#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
187#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ 179#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
188#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ 180#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
189#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */ 181#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses */
190#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */ 182#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */
191#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */ 183#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */
192 184
@@ -202,29 +194,17 @@
202/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ 194/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
203#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ 195#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */
204#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */ 196#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */
205#define CSR39_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */
206#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */ 197#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */
207#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */ 198#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */
208#define CSR39_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */
209#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */ 199#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */
210#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */ 200#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */
211 201
212#define CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ 202#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
213 CSR39_FH_INT_BIT_RX_CHNL2 | \ 203 CSR_FH_INT_BIT_RX_CHNL1 | \
214 CSR_FH_INT_BIT_RX_CHNL1 | \ 204 CSR_FH_INT_BIT_RX_CHNL0)
215 CSR_FH_INT_BIT_RX_CHNL0)
216
217
218#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \
219 CSR_FH_INT_BIT_TX_CHNL1 | \
220 CSR_FH_INT_BIT_TX_CHNL0)
221
222#define CSR49_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
223 CSR_FH_INT_BIT_RX_CHNL1 | \
224 CSR_FH_INT_BIT_RX_CHNL0)
225 205
226#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ 206#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
227 CSR_FH_INT_BIT_TX_CHNL0) 207 CSR_FH_INT_BIT_TX_CHNL0)
228 208
229/* GPIO */ 209/* GPIO */
230#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) 210#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
@@ -268,7 +248,7 @@
268 * Indicates MAC (ucode processor, etc.) is powered up and can run. 248 * Indicates MAC (ucode processor, etc.) is powered up and can run.
269 * Internal resources are accessible. 249 * Internal resources are accessible.
270 * NOTE: This does not indicate that the processor is actually running. 250 * NOTE: This does not indicate that the processor is actually running.
271 * NOTE: This does not indicate that 4965 or 3945 has completed 251 * NOTE: This does not indicate that device has completed
272 * init or post-power-down restore of internal SRAM memory. 252 * init or post-power-down restore of internal SRAM memory.
273 * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that 253 * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
274 * SRAM is restored and uCode is in normal operation mode. 254 * SRAM is restored and uCode is in normal operation mode.
@@ -291,8 +271,6 @@
291 271
292/* HW REV */ 272/* HW REV */
293#define CSR_HW_REV_TYPE_MSK (0x00001F0) 273#define CSR_HW_REV_TYPE_MSK (0x00001F0)
294#define CSR_HW_REV_TYPE_3945 (0x00000D0)
295#define CSR_HW_REV_TYPE_4965 (0x0000000)
296#define CSR_HW_REV_TYPE_5300 (0x0000020) 274#define CSR_HW_REV_TYPE_5300 (0x0000020)
297#define CSR_HW_REV_TYPE_5350 (0x0000030) 275#define CSR_HW_REV_TYPE_5350 (0x0000030)
298#define CSR_HW_REV_TYPE_5100 (0x0000050) 276#define CSR_HW_REV_TYPE_5100 (0x0000050)
@@ -363,7 +341,7 @@
363 * 0: MAC_SLEEP 341 * 0: MAC_SLEEP
364 * uCode sets this when preparing a power-saving power-down. 342 * uCode sets this when preparing a power-saving power-down.
365 * uCode resets this when power-up is complete and SRAM is sane. 343 * uCode resets this when power-up is complete and SRAM is sane.
366 * NOTE: 3945/4965 saves internal SRAM data to host when powering down, 344 * NOTE: device saves internal SRAM data to host when powering down,
367 * and must restore this data after powering back up. 345 * and must restore this data after powering back up.
368 * MAC_SLEEP is the best indication that restore is complete. 346 * MAC_SLEEP is the best indication that restore is complete.
369 * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and 347 * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
@@ -394,7 +372,6 @@
394#define CSR_LED_REG_TRUN_OFF (0x38) 372#define CSR_LED_REG_TRUN_OFF (0x38)
395 373
396/* ANA_PLL */ 374/* ANA_PLL */
397#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
398#define CSR50_ANA_PLL_CFG_VAL (0x00880300) 375#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
399 376
400/* HPET MEM debug */ 377/* HPET MEM debug */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index ebdea3be3ef9..2824ccbcc1fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -146,7 +146,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
146#define IWL_DL_RX (1 << 24) 146#define IWL_DL_RX (1 << 24)
147#define IWL_DL_ISR (1 << 25) 147#define IWL_DL_ISR (1 << 25)
148#define IWL_DL_HT (1 << 26) 148#define IWL_DL_HT (1 << 26)
149#define IWL_DL_IO (1 << 27)
150/* 0xF0000000 - 0x10000000 */ 149/* 0xF0000000 - 0x10000000 */
151#define IWL_DL_11H (1 << 28) 150#define IWL_DL_11H (1 << 28)
152#define IWL_DL_STATS (1 << 29) 151#define IWL_DL_STATS (1 << 29)
@@ -174,7 +173,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
174 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) 173 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
175#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) 174#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a)
176#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) 175#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
177#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a)
178#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) 176#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
179#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ 177#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \
180 IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) 178 IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8842411f1cf3..92f6efd2c73f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -1572,12 +1572,10 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
1572 int pos = 0; 1572 int pos = 0;
1573 char buf[200]; 1573 char buf[200];
1574 const size_t bufsz = sizeof(buf); 1574 const size_t bufsz = sizeof(buf);
1575 ssize_t ret;
1576 1575
1577 if (!priv->bt_enable_flag) { 1576 if (!priv->bt_enable_flag) {
1578 pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n"); 1577 pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
1579 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1578 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1580 return ret;
1581 } 1579 }
1582 pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n", 1580 pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
1583 priv->bt_enable_flag); 1581 priv->bt_enable_flag);
@@ -1608,8 +1606,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
1608 break; 1606 break;
1609 } 1607 }
1610 1608
1611 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1609 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1612 return ret;
1613} 1610}
1614 1611
1615static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, 1612static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 68b953f2bdc7..72133368c1f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -26,7 +26,6 @@
26/* 26/*
27 * Please use this file (iwl-dev.h) for driver implementation definitions. 27 * Please use this file (iwl-dev.h) for driver implementation definitions.
28 * Please use iwl-commands.h for uCode API definitions. 28 * Please use iwl-commands.h for uCode API definitions.
29 * Please use iwl-4965-hw.h for hardware-related definitions.
30 */ 29 */
31 30
32#ifndef __iwl_dev_h__ 31#ifndef __iwl_dev_h__
@@ -179,53 +178,12 @@ struct iwl_tx_queue {
179 178
180#define IWL_NUM_SCAN_RATES (2) 179#define IWL_NUM_SCAN_RATES (2)
181 180
182struct iwl4965_channel_tgd_info {
183 u8 type;
184 s8 max_power;
185};
186
187struct iwl4965_channel_tgh_info {
188 s64 last_radar_time;
189};
190
191#define IWL4965_MAX_RATE (33)
192
193struct iwl3945_clip_group {
194 /* maximum power level to prevent clipping for each rate, derived by
195 * us from this band's saturation power in EEPROM */
196 const s8 clip_powers[IWL_MAX_RATES];
197};
198
199/* current Tx power values to use, one for each rate for each channel.
200 * requested power is limited by:
201 * -- regulatory EEPROM limits for this channel
202 * -- hardware capabilities (clip-powers)
203 * -- spectrum management
204 * -- user preference (e.g. iwconfig)
205 * when requested power is set, base power index must also be set. */
206struct iwl3945_channel_power_info {
207 struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
208 s8 power_table_index; /* actual (compenst'd) index into gain table */
209 s8 base_power_index; /* gain index for power at factory temp. */
210 s8 requested_power; /* power (dBm) requested for this chnl/rate */
211};
212
213/* current scan Tx power values to use, one for each scan rate for each
214 * channel. */
215struct iwl3945_scan_power_info {
216 struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
217 s8 power_table_index; /* actual (compenst'd) index into gain table */
218 s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
219};
220
221/* 181/*
222 * One for each channel, holds all channel setup data 182 * One for each channel, holds all channel setup data
223 * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant 183 * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
224 * with one another! 184 * with one another!
225 */ 185 */
226struct iwl_channel_info { 186struct iwl_channel_info {
227 struct iwl4965_channel_tgd_info tgd;
228 struct iwl4965_channel_tgh_info tgh;
229 struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ 187 struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */
230 struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for 188 struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for
231 * HT40 channel */ 189 * HT40 channel */
@@ -245,14 +203,6 @@ struct iwl_channel_info {
245 s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ 203 s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
246 u8 ht40_flags; /* flags copied from EEPROM */ 204 u8 ht40_flags; /* flags copied from EEPROM */
247 u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ 205 u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
248
249 /* Radio/DSP gain settings for each "normal" data Tx rate.
250 * These include, in addition to RF and DSP gain, a few fields for
251 * remembering/modifying gain settings (indexes). */
252 struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
253
254 /* Radio/DSP gain settings for each scan rate, for directed scans. */
255 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
256}; 206};
257 207
258#define IWL_TX_FIFO_BK 0 /* shared */ 208#define IWL_TX_FIFO_BK 0 /* shared */
@@ -309,6 +259,7 @@ enum {
309 CMD_SIZE_HUGE = (1 << 0), 259 CMD_SIZE_HUGE = (1 << 0),
310 CMD_ASYNC = (1 << 1), 260 CMD_ASYNC = (1 << 1),
311 CMD_WANT_SKB = (1 << 2), 261 CMD_WANT_SKB = (1 << 2),
262 CMD_MAPPED = (1 << 3),
312}; 263};
313 264
314#define DEF_CMD_PAYLOAD_SIZE 320 265#define DEF_CMD_PAYLOAD_SIZE 320
@@ -416,6 +367,7 @@ struct iwl_ht_agg {
416#define IWL_EMPTYING_HW_QUEUE_ADDBA 2 367#define IWL_EMPTYING_HW_QUEUE_ADDBA 2
417#define IWL_EMPTYING_HW_QUEUE_DELBA 3 368#define IWL_EMPTYING_HW_QUEUE_DELBA 3
418 u8 state; 369 u8 state;
370 u8 tx_fifo;
419}; 371};
420 372
421 373
@@ -499,9 +451,6 @@ struct iwl_station_priv_common {
499 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 451 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
500 * in the structure for use by driver. This structure is places in that 452 * in the structure for use by driver. This structure is places in that
501 * space. 453 * space.
502 *
503 * The common struct MUST be first because it is shared between
504 * 3945 and agn!
505 */ 454 */
506struct iwl_station_priv { 455struct iwl_station_priv {
507 struct iwl_station_priv_common common; 456 struct iwl_station_priv_common common;
@@ -586,6 +535,22 @@ enum iwl_ucode_tlv_type {
586 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, 535 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
587 IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, 536 IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
588 IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, 537 IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
538 /* 16 and 17 reserved for future use */
539 IWL_UCODE_TLV_FLAGS = 18,
540};
541
542/**
543 * enum iwl_ucode_tlv_flag - ucode API flags
544 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
545 * was a separate TLV but moved here to save space.
546 * @IWL_UCODE_TLV_FLAGS_BTSTATS: This uCode image uses BT statistics, which
547 * may be true even if the device doesn't have BT.
548 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
549 */
550enum iwl_ucode_tlv_flag {
551 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
552 IWL_UCODE_TLV_FLAGS_BTSTATS = BIT(1),
553 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
589}; 554};
590 555
591struct iwl_ucode_tlv { 556struct iwl_ucode_tlv {
@@ -619,14 +584,6 @@ struct iwl_tlv_ucode_header {
619 u8 data[0]; 584 u8 data[0];
620}; 585};
621 586
622struct iwl4965_ibss_seq {
623 u8 mac[ETH_ALEN];
624 u16 seq_num;
625 u16 frag_num;
626 unsigned long packet_time;
627 struct list_head list;
628};
629
630struct iwl_sensitivity_ranges { 587struct iwl_sensitivity_ranges {
631 u16 min_nrg_cck; 588 u16 min_nrg_cck;
632 u16 max_nrg_cck; 589 u16 max_nrg_cck;
@@ -700,7 +657,6 @@ struct iwl_hw_params {
700 u8 max_beacon_itrvl; /* in 1024 ms */ 657 u8 max_beacon_itrvl; /* in 1024 ms */
701 u32 max_inst_size; 658 u32 max_inst_size;
702 u32 max_data_size; 659 u32 max_data_size;
703 u32 max_bsm_size;
704 u32 ct_kill_threshold; /* value in hw-dependent units */ 660 u32 ct_kill_threshold; /* value in hw-dependent units */
705 u32 ct_kill_exit_threshold; /* value in hw-dependent units */ 661 u32 ct_kill_exit_threshold; /* value in hw-dependent units */
706 /* for 1000, 6000 series and up */ 662 /* for 1000, 6000 series and up */
@@ -722,8 +678,6 @@ struct iwl_hw_params {
722 * Naming convention -- 678 * Naming convention --
723 * iwl_ <-- Is part of iwlwifi 679 * iwl_ <-- Is part of iwlwifi
724 * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) 680 * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
725 * iwl4965_bg_ <-- Called from work queue context
726 * iwl4965_mac_ <-- mac80211 callback
727 * 681 *
728 ****************************************************************************/ 682 ****************************************************************************/
729extern void iwl_update_chain_flags(struct iwl_priv *priv); 683extern void iwl_update_chain_flags(struct iwl_priv *priv);
@@ -772,7 +726,6 @@ struct iwl_dma_ptr {
772 726
773/* Sensitivity and chain noise calibration */ 727/* Sensitivity and chain noise calibration */
774#define INITIALIZATION_VALUE 0xFFFF 728#define INITIALIZATION_VALUE 0xFFFF
775#define IWL4965_CAL_NUM_BEACONS 20
776#define IWL_CAL_NUM_BEACONS 16 729#define IWL_CAL_NUM_BEACONS 16
777#define MAXIMUM_ALLOWED_PATHLOSS 15 730#define MAXIMUM_ALLOWED_PATHLOSS 15
778 731
@@ -806,24 +759,19 @@ struct iwl_dma_ptr {
806#define NRG_NUM_PREV_STAT_L 20 759#define NRG_NUM_PREV_STAT_L 20
807#define NUM_RX_CHAINS 3 760#define NUM_RX_CHAINS 3
808 761
809enum iwl4965_false_alarm_state { 762enum iwlagn_false_alarm_state {
810 IWL_FA_TOO_MANY = 0, 763 IWL_FA_TOO_MANY = 0,
811 IWL_FA_TOO_FEW = 1, 764 IWL_FA_TOO_FEW = 1,
812 IWL_FA_GOOD_RANGE = 2, 765 IWL_FA_GOOD_RANGE = 2,
813}; 766};
814 767
815enum iwl4965_chain_noise_state { 768enum iwlagn_chain_noise_state {
816 IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ 769 IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */
817 IWL_CHAIN_NOISE_ACCUMULATE, 770 IWL_CHAIN_NOISE_ACCUMULATE,
818 IWL_CHAIN_NOISE_CALIBRATED, 771 IWL_CHAIN_NOISE_CALIBRATED,
819 IWL_CHAIN_NOISE_DONE, 772 IWL_CHAIN_NOISE_DONE,
820}; 773};
821 774
822enum iwl4965_calib_enabled_state {
823 IWL_CALIB_DISABLED = 0, /* must be 0 */
824 IWL_CALIB_ENABLED = 1,
825};
826
827 775
828/* 776/*
829 * enum iwl_calib 777 * enum iwl_calib
@@ -1131,12 +1079,6 @@ struct iwl_force_reset {
1131 1079
1132/* extend beacon time format bit shifting */ 1080/* extend beacon time format bit shifting */
1133/* 1081/*
1134 * for _3945 devices
1135 * bits 31:24 - extended
1136 * bits 23:0 - interval
1137 */
1138#define IWL3945_EXT_BEACON_TIME_POS 24
1139/*
1140 * for _agn devices 1082 * for _agn devices
1141 * bits 31:22 - extended 1083 * bits 31:22 - extended
1142 * bits 21:0 - interval 1084 * bits 21:0 - interval
@@ -1249,7 +1191,6 @@ struct iwl_priv {
1249 int frames_count; 1191 int frames_count;
1250 1192
1251 enum ieee80211_band band; 1193 enum ieee80211_band band;
1252 int alloc_rxb_page;
1253 1194
1254 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, 1195 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
1255 struct iwl_rx_mem_buffer *rxb); 1196 struct iwl_rx_mem_buffer *rxb);
@@ -1305,16 +1246,12 @@ struct iwl_priv {
1305 spinlock_t hcmd_lock; /* protect hcmd */ 1246 spinlock_t hcmd_lock; /* protect hcmd */
1306 spinlock_t reg_lock; /* protect hw register access */ 1247 spinlock_t reg_lock; /* protect hw register access */
1307 struct mutex mutex; 1248 struct mutex mutex;
1308 struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
1309 1249
1310 /* basic pci-network driver stuff */ 1250 /* basic pci-network driver stuff */
1311 struct pci_dev *pci_dev; 1251 struct pci_dev *pci_dev;
1312 1252
1313 /* pci hardware address support */ 1253 /* pci hardware address support */
1314 void __iomem *hw_base; 1254 void __iomem *hw_base;
1315 u32 hw_rev;
1316 u32 hw_wa_rev;
1317 u8 rev_id;
1318 1255
1319 /* microcode/device supports multiple contexts */ 1256 /* microcode/device supports multiple contexts */
1320 u8 valid_contexts; 1257 u8 valid_contexts;
@@ -1334,10 +1271,8 @@ struct iwl_priv {
1334 iwl_ucode.ver */ 1271 iwl_ucode.ver */
1335 struct fw_desc ucode_code; /* runtime inst */ 1272 struct fw_desc ucode_code; /* runtime inst */
1336 struct fw_desc ucode_data; /* runtime data original */ 1273 struct fw_desc ucode_data; /* runtime data original */
1337 struct fw_desc ucode_data_backup; /* runtime data save/restore */
1338 struct fw_desc ucode_init; /* initialization inst */ 1274 struct fw_desc ucode_init; /* initialization inst */
1339 struct fw_desc ucode_init_data; /* initialization data */ 1275 struct fw_desc ucode_init_data; /* initialization data */
1340 struct fw_desc ucode_boot; /* bootstrap inst */
1341 enum ucode_type ucode_type; 1276 enum ucode_type ucode_type;
1342 u8 ucode_write_complete; /* the image write is complete */ 1277 u8 ucode_write_complete; /* the image write is complete */
1343 char firmware_name[25]; 1278 char firmware_name[25];
@@ -1346,10 +1281,10 @@ struct iwl_priv {
1346 1281
1347 struct iwl_switch_rxon switch_rxon; 1282 struct iwl_switch_rxon switch_rxon;
1348 1283
1349 /* 1st responses from initialize and runtime uCode images. 1284 struct {
1350 * _agn's initialize alive response contains some calibration data. */ 1285 u32 error_event_table;
1351 struct iwl_init_alive_resp card_alive_init; 1286 u32 log_event_table;
1352 struct iwl_alive_resp card_alive; 1287 } device_pointers;
1353 1288
1354 u16 active_rate; 1289 u16 active_rate;
1355 1290
@@ -1390,15 +1325,12 @@ struct iwl_priv {
1390 struct iwl_power_mgr power_data; 1325 struct iwl_power_mgr power_data;
1391 struct iwl_tt_mgmt thermal_throttle; 1326 struct iwl_tt_mgmt thermal_throttle;
1392 1327
1393 /* context information */
1394 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
1395
1396 /* station table variables */ 1328 /* station table variables */
1397 1329
1398 /* Note: if lock and sta_lock are needed, lock must be acquired first */ 1330 /* Note: if lock and sta_lock are needed, lock must be acquired first */
1399 spinlock_t sta_lock; 1331 spinlock_t sta_lock;
1400 int num_stations; 1332 int num_stations;
1401 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1333 struct iwl_station_entry stations[IWLAGN_STATION_COUNT];
1402 unsigned long ucode_key_table; 1334 unsigned long ucode_key_table;
1403 1335
1404 /* queue refcounts */ 1336 /* queue refcounts */
@@ -1422,101 +1354,66 @@ struct iwl_priv {
1422 /* Last Rx'd beacon timestamp */ 1354 /* Last Rx'd beacon timestamp */
1423 u64 timestamp; 1355 u64 timestamp;
1424 1356
1425 union { 1357 struct {
1426#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) 1358 /* INT ICT Table */
1427 struct { 1359 __le32 *ict_tbl;
1428 void *shared_virt; 1360 void *ict_tbl_vir;
1429 dma_addr_t shared_phys; 1361 dma_addr_t ict_tbl_dma;
1430 1362 dma_addr_t aligned_ict_tbl_dma;
1431 struct delayed_work thermal_periodic; 1363 int ict_index;
1432 struct delayed_work rfkill_poll; 1364 u32 inta;
1433 1365 bool use_ict;
1434 struct iwl3945_notif_statistics statistics; 1366 /*
1435#ifdef CONFIG_IWLWIFI_DEBUGFS 1367 * reporting the number of tids has AGG on. 0 means
1436 struct iwl3945_notif_statistics accum_statistics; 1368 * no AGGREGATION
1437 struct iwl3945_notif_statistics delta_statistics; 1369 */
1438 struct iwl3945_notif_statistics max_delta; 1370 u8 agg_tids_count;
1439#endif 1371
1440 1372 struct iwl_rx_phy_res last_phy_res;
1441 u32 sta_supp_rates; 1373 bool last_phy_res_valid;
1442 int last_rx_rssi; /* From Rx packet statistics */ 1374
1443 1375 struct completion firmware_loading_complete;
1444 /* Rx'd packet timing information */ 1376
1445 u32 last_beacon_time; 1377 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1446 u64 last_tsf; 1378 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1447 1379
1448 /* 1380 /*
1449 * each calibration channel group in the 1381 * chain noise reset and gain commands are the
1450 * EEPROM has a derived clip setting for 1382 * two extra calibration commands follows the standard
1451 * each rate. 1383 * phy calibration commands
1452 */ 1384 */
1453 const struct iwl3945_clip_group clip_groups[5]; 1385 u8 phy_calib_chain_noise_reset_cmd;
1454 1386 u8 phy_calib_chain_noise_gain_cmd;
1455 } _3945; 1387
1456#endif 1388 struct iwl_notif_statistics statistics;
1457#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE) 1389 struct iwl_bt_notif_statistics statistics_bt;
1458 struct { 1390 /* counts reply_tx error */
1459 /* INT ICT Table */ 1391 struct reply_tx_error_statistics reply_tx_stats;
1460 __le32 *ict_tbl; 1392 struct reply_agg_tx_error_statistics reply_agg_tx_stats;
1461 void *ict_tbl_vir;
1462 dma_addr_t ict_tbl_dma;
1463 dma_addr_t aligned_ict_tbl_dma;
1464 int ict_index;
1465 u32 inta;
1466 bool use_ict;
1467 /*
1468 * reporting the number of tids has AGG on. 0 means
1469 * no AGGREGATION
1470 */
1471 u8 agg_tids_count;
1472
1473 struct iwl_rx_phy_res last_phy_res;
1474 bool last_phy_res_valid;
1475
1476 struct completion firmware_loading_complete;
1477
1478 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1479 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1480
1481 /*
1482 * chain noise reset and gain commands are the
1483 * two extra calibration commands follows the standard
1484 * phy calibration commands
1485 */
1486 u8 phy_calib_chain_noise_reset_cmd;
1487 u8 phy_calib_chain_noise_gain_cmd;
1488
1489 struct iwl_notif_statistics statistics;
1490 struct iwl_bt_notif_statistics statistics_bt;
1491 /* counts reply_tx error */
1492 struct reply_tx_error_statistics reply_tx_stats;
1493 struct reply_agg_tx_error_statistics reply_agg_tx_stats;
1494#ifdef CONFIG_IWLWIFI_DEBUGFS 1393#ifdef CONFIG_IWLWIFI_DEBUGFS
1495 struct iwl_notif_statistics accum_statistics; 1394 struct iwl_notif_statistics accum_statistics;
1496 struct iwl_notif_statistics delta_statistics; 1395 struct iwl_notif_statistics delta_statistics;
1497 struct iwl_notif_statistics max_delta; 1396 struct iwl_notif_statistics max_delta;
1498 struct iwl_bt_notif_statistics accum_statistics_bt; 1397 struct iwl_bt_notif_statistics accum_statistics_bt;
1499 struct iwl_bt_notif_statistics delta_statistics_bt; 1398 struct iwl_bt_notif_statistics delta_statistics_bt;
1500 struct iwl_bt_notif_statistics max_delta_bt; 1399 struct iwl_bt_notif_statistics max_delta_bt;
1501#endif 1400#endif
1502 1401 /* notification wait support */
1503 /* notification wait support */ 1402 struct list_head notif_waits;
1504 struct list_head notif_waits; 1403 spinlock_t notif_wait_lock;
1505 spinlock_t notif_wait_lock; 1404 wait_queue_head_t notif_waitq;
1506 wait_queue_head_t notif_waitq; 1405
1507 1406 /* remain-on-channel offload support */
1508 /* remain-on-channel offload support */ 1407 struct ieee80211_channel *hw_roc_channel;
1509 struct ieee80211_channel *hw_roc_channel; 1408 struct delayed_work hw_roc_work;
1510 struct delayed_work hw_roc_work; 1409 enum nl80211_channel_type hw_roc_chantype;
1511 enum nl80211_channel_type hw_roc_chantype; 1410 int hw_roc_duration;
1512 int hw_roc_duration; 1411 bool hw_roc_setup;
1513 1412
1514 struct sk_buff *offchan_tx_skb; 1413 struct sk_buff *offchan_tx_skb;
1515 int offchan_tx_timeout; 1414 int offchan_tx_timeout;
1516 struct ieee80211_channel *offchan_tx_chan; 1415 struct ieee80211_channel *offchan_tx_chan;
1517 } _agn; 1416 } _agn;
1518#endif
1519 };
1520 1417
1521 /* bt coex */ 1418 /* bt coex */
1522 u8 bt_enable_flag; 1419 u8 bt_enable_flag;
@@ -1525,6 +1422,7 @@ struct iwl_priv {
1525 bool bt_ch_announce; 1422 bool bt_ch_announce;
1526 bool bt_full_concurrent; 1423 bool bt_full_concurrent;
1527 bool bt_ant_couple_ok; 1424 bool bt_ant_couple_ok;
1425 bool bt_statistics;
1528 __le32 kill_ack_mask; 1426 __le32 kill_ack_mask;
1529 __le32 kill_cts_mask; 1427 __le32 kill_cts_mask;
1530 __le16 bt_valid; 1428 __le16 bt_valid;
@@ -1710,12 +1608,10 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
1710static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page) 1608static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page)
1711{ 1609{
1712 __free_pages(page, priv->hw_params.rx_page_order); 1610 __free_pages(page, priv->hw_params.rx_page_order);
1713 priv->alloc_rxb_page--;
1714} 1611}
1715 1612
1716static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page) 1613static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page)
1717{ 1614{
1718 free_pages(page, priv->hw_params.rx_page_order); 1615 free_pages(page, priv->hw_params.rx_page_order);
1719 priv->alloc_rxb_page--;
1720} 1616}
1721#endif /* __iwl_dev_h__ */ 1617#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 4a487639d932..a635a7e75447 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 4cf864c664ee..f00172cb8a6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 833194a2c639..859b94a12297 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -188,18 +188,16 @@ static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
188 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 188 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
189} 189}
190 190
191static int iwlcore_get_nvm_type(struct iwl_priv *priv) 191static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev)
192{ 192{
193 u32 otpgp; 193 u32 otpgp;
194 int nvm_type; 194 int nvm_type;
195 195
196 /* OTP only valid for CP/PP and after */ 196 /* OTP only valid for CP/PP and after */
197 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 197 switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
198 case CSR_HW_REV_TYPE_NONE: 198 case CSR_HW_REV_TYPE_NONE:
199 IWL_ERR(priv, "Unknown hardware type\n"); 199 IWL_ERR(priv, "Unknown hardware type\n");
200 return -ENOENT; 200 return -ENOENT;
201 case CSR_HW_REV_TYPE_3945:
202 case CSR_HW_REV_TYPE_4965:
203 case CSR_HW_REV_TYPE_5300: 201 case CSR_HW_REV_TYPE_5300:
204 case CSR_HW_REV_TYPE_5350: 202 case CSR_HW_REV_TYPE_5350:
205 case CSR_HW_REV_TYPE_5100: 203 case CSR_HW_REV_TYPE_5100:
@@ -228,15 +226,15 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
228 int ret; 226 int ret;
229 227
230 /* Enable 40MHz radio clock */ 228 /* Enable 40MHz radio clock */
231 _iwl_write32(priv, CSR_GP_CNTRL, 229 iwl_write32(priv, CSR_GP_CNTRL,
232 _iwl_read32(priv, CSR_GP_CNTRL) | 230 iwl_read32(priv, CSR_GP_CNTRL) |
233 CSR_GP_CNTRL_REG_FLAG_INIT_DONE); 231 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
234 232
235 /* wait for clock to be ready */ 233 /* wait for clock to be ready */
236 ret = iwl_poll_bit(priv, CSR_GP_CNTRL, 234 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
237 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 235 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
238 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 236 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
239 25000); 237 25000);
240 if (ret < 0) 238 if (ret < 0)
241 IWL_ERR(priv, "Time out access OTP\n"); 239 IWL_ERR(priv, "Time out access OTP\n");
242 else { 240 else {
@@ -263,17 +261,17 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat
263 u32 r; 261 u32 r;
264 u32 otpgp; 262 u32 otpgp;
265 263
266 _iwl_write32(priv, CSR_EEPROM_REG, 264 iwl_write32(priv, CSR_EEPROM_REG,
267 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 265 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
268 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 266 ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
269 CSR_EEPROM_REG_READ_VALID_MSK, 267 CSR_EEPROM_REG_READ_VALID_MSK,
270 CSR_EEPROM_REG_READ_VALID_MSK, 268 CSR_EEPROM_REG_READ_VALID_MSK,
271 IWL_EEPROM_ACCESS_TIMEOUT); 269 IWL_EEPROM_ACCESS_TIMEOUT);
272 if (ret < 0) { 270 if (ret < 0) {
273 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); 271 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
274 return ret; 272 return ret;
275 } 273 }
276 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 274 r = iwl_read32(priv, CSR_EEPROM_REG);
277 /* check for ECC errors: */ 275 /* check for ECC errors: */
278 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 276 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
279 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { 277 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
@@ -396,7 +394,7 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
396 * 394 *
397 * NOTE: This routine uses the non-debug IO access functions. 395 * NOTE: This routine uses the non-debug IO access functions.
398 */ 396 */
399int iwl_eeprom_init(struct iwl_priv *priv) 397int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
400{ 398{
401 __le16 *e; 399 __le16 *e;
402 u32 gp = iwl_read32(priv, CSR_EEPROM_GP); 400 u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
@@ -406,7 +404,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
406 u16 validblockaddr = 0; 404 u16 validblockaddr = 0;
407 u16 cache_addr = 0; 405 u16 cache_addr = 0;
408 406
409 priv->nvm_device_type = iwlcore_get_nvm_type(priv); 407 priv->nvm_device_type = iwlcore_get_nvm_type(priv, hw_rev);
410 if (priv->nvm_device_type == -ENOENT) 408 if (priv->nvm_device_type == -ENOENT)
411 return -ENOENT; 409 return -ENOENT;
412 /* allocate eeprom */ 410 /* allocate eeprom */
@@ -444,9 +442,9 @@ int iwl_eeprom_init(struct iwl_priv *priv)
444 ret = -ENOENT; 442 ret = -ENOENT;
445 goto done; 443 goto done;
446 } 444 }
447 _iwl_write32(priv, CSR_EEPROM_GP, 445 iwl_write32(priv, CSR_EEPROM_GP,
448 iwl_read32(priv, CSR_EEPROM_GP) & 446 iwl_read32(priv, CSR_EEPROM_GP) &
449 ~CSR_EEPROM_GP_IF_OWNER_MSK); 447 ~CSR_EEPROM_GP_IF_OWNER_MSK);
450 448
451 iwl_set_bit(priv, CSR_OTP_GP_REG, 449 iwl_set_bit(priv, CSR_OTP_GP_REG,
452 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 450 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
@@ -473,8 +471,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
473 for (addr = 0; addr < sz; addr += sizeof(u16)) { 471 for (addr = 0; addr < sz; addr += sizeof(u16)) {
474 u32 r; 472 u32 r;
475 473
476 _iwl_write32(priv, CSR_EEPROM_REG, 474 iwl_write32(priv, CSR_EEPROM_REG,
477 CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); 475 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
478 476
479 ret = iwl_poll_bit(priv, CSR_EEPROM_REG, 477 ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
480 CSR_EEPROM_REG_READ_VALID_MSK, 478 CSR_EEPROM_REG_READ_VALID_MSK,
@@ -484,7 +482,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
484 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); 482 IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
485 goto done; 483 goto done;
486 } 484 }
487 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 485 r = iwl_read32(priv, CSR_EEPROM_REG);
488 e[addr / 2] = cpu_to_le16(r >> 16); 486 e[addr / 2] = cpu_to_le16(r >> 16);
489 } 487 }
490 } 488 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 20b66469d68f..0e9d9703636a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -110,10 +110,6 @@ enum {
110}; 110};
111 111
112/* SKU Capabilities */ 112/* SKU Capabilities */
113/* 3945 only */
114#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
115#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
116
117/* 5000 and up */ 113/* 5000 and up */
118#define EEPROM_SKU_CAP_BAND_POS (4) 114#define EEPROM_SKU_CAP_BAND_POS (4)
119#define EEPROM_SKU_CAP_BAND_SELECTION \ 115#define EEPROM_SKU_CAP_BAND_SELECTION \
@@ -168,28 +164,6 @@ struct iwl_eeprom_enhanced_txpwr {
168 s8 mimo3_max; 164 s8 mimo3_max;
169} __packed; 165} __packed;
170 166
171/* 3945 Specific */
172#define EEPROM_3945_EEPROM_VERSION (0x2f)
173
174/* 4965 has two radio transmitters (and 3 radio receivers) */
175#define EEPROM_TX_POWER_TX_CHAINS (2)
176
177/* 4965 has room for up to 8 sets of txpower calibration data */
178#define EEPROM_TX_POWER_BANDS (8)
179
180/* 4965 factory calibration measures txpower gain settings for
181 * each of 3 target output levels */
182#define EEPROM_TX_POWER_MEASUREMENTS (3)
183
184/* 4965 Specific */
185/* 4965 driver does not work with txpower calibration version < 5 */
186#define EEPROM_4965_TX_POWER_VERSION (5)
187#define EEPROM_4965_EEPROM_VERSION (0x2f)
188#define EEPROM_4965_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */
189#define EEPROM_4965_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */
190#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */
191#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */
192
193/* 5000 Specific */ 167/* 5000 Specific */
194#define EEPROM_5000_TX_POWER_VERSION (4) 168#define EEPROM_5000_TX_POWER_VERSION (4)
195#define EEPROM_5000_EEPROM_VERSION (0x11A) 169#define EEPROM_5000_EEPROM_VERSION (0x11A)
@@ -282,90 +256,6 @@ struct iwl_eeprom_enhanced_txpwr {
282/* 2.4 GHz */ 256/* 2.4 GHz */
283extern const u8 iwl_eeprom_band_1[14]; 257extern const u8 iwl_eeprom_band_1[14];
284 258
285/*
286 * factory calibration data for one txpower level, on one channel,
287 * measured on one of the 2 tx chains (radio transmitter and associated
288 * antenna). EEPROM contains:
289 *
290 * 1) Temperature (degrees Celsius) of device when measurement was made.
291 *
292 * 2) Gain table index used to achieve the target measurement power.
293 * This refers to the "well-known" gain tables (see iwl-4965-hw.h).
294 *
295 * 3) Actual measured output power, in half-dBm ("34" = 17 dBm).
296 *
297 * 4) RF power amplifier detector level measurement (not used).
298 */
299struct iwl_eeprom_calib_measure {
300 u8 temperature; /* Device temperature (Celsius) */
301 u8 gain_idx; /* Index into gain table */
302 u8 actual_pow; /* Measured RF output power, half-dBm */
303 s8 pa_det; /* Power amp detector level (not used) */
304} __packed;
305
306
307/*
308 * measurement set for one channel. EEPROM contains:
309 *
310 * 1) Channel number measured
311 *
312 * 2) Measurements for each of 3 power levels for each of 2 radio transmitters
313 * (a.k.a. "tx chains") (6 measurements altogether)
314 */
315struct iwl_eeprom_calib_ch_info {
316 u8 ch_num;
317 struct iwl_eeprom_calib_measure
318 measurements[EEPROM_TX_POWER_TX_CHAINS]
319 [EEPROM_TX_POWER_MEASUREMENTS];
320} __packed;
321
322/*
323 * txpower subband info.
324 *
325 * For each frequency subband, EEPROM contains the following:
326 *
327 * 1) First and last channels within range of the subband. "0" values
328 * indicate that this sample set is not being used.
329 *
330 * 2) Sample measurement sets for 2 channels close to the range endpoints.
331 */
332struct iwl_eeprom_calib_subband_info {
333 u8 ch_from; /* channel number of lowest channel in subband */
334 u8 ch_to; /* channel number of highest channel in subband */
335 struct iwl_eeprom_calib_ch_info ch1;
336 struct iwl_eeprom_calib_ch_info ch2;
337} __packed;
338
339
340/*
341 * txpower calibration info. EEPROM contains:
342 *
343 * 1) Factory-measured saturation power levels (maximum levels at which
344 * tx power amplifier can output a signal without too much distortion).
345 * There is one level for 2.4 GHz band and one for 5 GHz band. These
346 * values apply to all channels within each of the bands.
347 *
348 * 2) Factory-measured power supply voltage level. This is assumed to be
349 * constant (i.e. same value applies to all channels/bands) while the
350 * factory measurements are being made.
351 *
352 * 3) Up to 8 sets of factory-measured txpower calibration values.
353 * These are for different frequency ranges, since txpower gain
354 * characteristics of the analog radio circuitry vary with frequency.
355 *
356 * Not all sets need to be filled with data;
357 * struct iwl_eeprom_calib_subband_info contains range of channels
358 * (0 if unused) for each set of data.
359 */
360struct iwl_eeprom_calib_info {
361 u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
362 u8 saturation_power52; /* half-dBm */
363 __le16 voltage; /* signed */
364 struct iwl_eeprom_calib_subband_info
365 band_info[EEPROM_TX_POWER_BANDS];
366} __packed;
367
368
369#define ADDRESS_MSK 0x0000FFFF 259#define ADDRESS_MSK 0x0000FFFF
370#define INDIRECT_TYPE_MSK 0x000F0000 260#define INDIRECT_TYPE_MSK 0x000F0000
371#define INDIRECT_HOST 0x00010000 261#define INDIRECT_HOST 0x00010000
@@ -398,83 +288,8 @@ struct iwl_eeprom_calib_info {
398#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ 288#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
399#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ 289#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
400 290
401#define EEPROM_3945_RF_CFG_TYPE_MAX 0x0
402#define EEPROM_4965_RF_CFG_TYPE_MAX 0x1
403
404/* Radio Config for 5000 and up */
405#define EEPROM_RF_CONFIG_TYPE_R3x3 0x0
406#define EEPROM_RF_CONFIG_TYPE_R2x2 0x1
407#define EEPROM_RF_CONFIG_TYPE_R1x2 0x2
408#define EEPROM_RF_CONFIG_TYPE_MAX 0x3 291#define EEPROM_RF_CONFIG_TYPE_MAX 0x3
409 292
410/*
411 * Per-channel regulatory data.
412 *
413 * Each channel that *might* be supported by iwl has a fixed location
414 * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
415 * txpower (MSB).
416 *
417 * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz)
418 * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
419 *
420 * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
421 */
422#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */
423#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */
424#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */
425
426/*
427 * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
428 * 5.0 GHz channels 7, 8, 11, 12, 16
429 * (4915-5080MHz) (none of these is ever supported)
430 */
431#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */
432#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */
433
434/*
435 * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
436 * (5170-5320MHz)
437 */
438#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */
439#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */
440
441/*
442 * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
443 * (5500-5700MHz)
444 */
445#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */
446#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */
447
448/*
449 * 5.7 GHz channels 145, 149, 153, 157, 161, 165
450 * (5725-5825MHz)
451 */
452#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */
453#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */
454
455/*
456 * 2.4 GHz HT40 channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
457 *
458 * The channel listed is the center of the lower 20 MHz half of the channel.
459 * The overall center frequency is actually 2 channels (10 MHz) above that,
460 * and the upper half of each HT40 channel is centered 4 channels (20 MHz) away
461 * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5,
462 * and the overall HT40 channel width centers on channel 3.
463 *
464 * NOTE: The RXON command uses 20 MHz channel numbers to specify the
465 * control channel to which to tune. RXON also specifies whether the
466 * control channel is the upper or lower half of a HT40 channel.
467 *
468 * NOTE: 4965 does not support HT40 channels on 2.4 GHz.
469 */
470#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0) /* 14 bytes */
471
472/*
473 * 5.2 GHz HT40 channels 36 (40), 44 (48), 52 (56), 60 (64),
474 * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
475 */
476#define EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8) /* 22 bytes */
477
478#define EEPROM_REGULATORY_BAND_NO_HT40 (0) 293#define EEPROM_REGULATORY_BAND_NO_HT40 (0)
479 294
480struct iwl_eeprom_ops { 295struct iwl_eeprom_ops {
@@ -487,7 +302,7 @@ struct iwl_eeprom_ops {
487}; 302};
488 303
489 304
490int iwl_eeprom_init(struct iwl_priv *priv); 305int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
491void iwl_eeprom_free(struct iwl_priv *priv); 306void iwl_eeprom_free(struct iwl_priv *priv);
492int iwl_eeprom_check_version(struct iwl_priv *priv); 307int iwl_eeprom_check_version(struct iwl_priv *priv);
493int iwl_eeprom_check_sku(struct iwl_priv *priv); 308int iwl_eeprom_check_sku(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 474009a244d4..e7a1bc6b76fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 02499f684683..9177b553fe57 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -51,9 +51,7 @@ const char *get_cmd_string(u8 cmd)
51 IWL_CMD(REPLY_REMOVE_ALL_STA); 51 IWL_CMD(REPLY_REMOVE_ALL_STA);
52 IWL_CMD(REPLY_TXFIFO_FLUSH); 52 IWL_CMD(REPLY_TXFIFO_FLUSH);
53 IWL_CMD(REPLY_WEPKEY); 53 IWL_CMD(REPLY_WEPKEY);
54 IWL_CMD(REPLY_3945_RX);
55 IWL_CMD(REPLY_TX); 54 IWL_CMD(REPLY_TX);
56 IWL_CMD(REPLY_RATE_SCALE);
57 IWL_CMD(REPLY_LEDS_CMD); 55 IWL_CMD(REPLY_LEDS_CMD);
58 IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); 56 IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
59 IWL_CMD(COEX_PRIORITY_TABLE_CMD); 57 IWL_CMD(COEX_PRIORITY_TABLE_CMD);
@@ -171,14 +169,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
171 int cmd_idx; 169 int cmd_idx;
172 int ret; 170 int ret;
173 171
174 BUG_ON(cmd->flags & CMD_ASYNC); 172 lockdep_assert_held(&priv->mutex);
175 173
176 /* A synchronous command can not have a callback set. */ 174 /* A synchronous command can not have a callback set. */
177 BUG_ON(cmd->callback); 175 BUG_ON((cmd->flags & CMD_ASYNC) || cmd->callback);
178 176
179 IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", 177 IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
180 get_cmd_string(cmd->id)); 178 get_cmd_string(cmd->id));
181 mutex_lock(&priv->sync_cmd_mutex);
182 179
183 set_bit(STATUS_HCMD_ACTIVE, &priv->status); 180 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
184 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", 181 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -189,7 +186,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
189 ret = cmd_idx; 186 ret = cmd_idx;
190 IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", 187 IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
191 get_cmd_string(cmd->id), ret); 188 get_cmd_string(cmd->id), ret);
192 goto out; 189 return ret;
193 } 190 }
194 191
195 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 192 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -229,8 +226,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
229 goto cancel; 226 goto cancel;
230 } 227 }
231 228
232 ret = 0; 229 return 0;
233 goto out;
234 230
235cancel: 231cancel:
236 if (cmd->flags & CMD_WANT_SKB) { 232 if (cmd->flags & CMD_WANT_SKB) {
@@ -248,8 +244,7 @@ fail:
248 iwl_free_pages(priv, cmd->reply_page); 244 iwl_free_pages(priv, cmd->reply_page);
249 cmd->reply_page = 0; 245 cmd->reply_page = 0;
250 } 246 }
251out: 247
252 mutex_unlock(&priv->sync_cmd_mutex);
253 return ret; 248 return ret;
254} 249}
255 250
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 8821f088ba7f..5da5761c74b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
new file mode 100644
index 000000000000..51337416e4ca
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -0,0 +1,274 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * The full GNU General Public License is included in this distribution in the
21 * file called LICENSE.
22 *
23 * Contact Information:
24 * Intel Linux Wireless <ilw@linux.intel.com>
25 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26 *
27 *****************************************************************************/
28
29#include "iwl-io.h"
30
31#define IWL_POLL_INTERVAL 10 /* microseconds */
32
33static inline void __iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
34{
35 iwl_write32(priv, reg, iwl_read32(priv, reg) | mask);
36}
37
38static inline void __iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
39{
40 iwl_write32(priv, reg, iwl_read32(priv, reg) & ~mask);
41}
42
43void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
44{
45 unsigned long flags;
46
47 spin_lock_irqsave(&priv->reg_lock, flags);
48 __iwl_set_bit(priv, reg, mask);
49 spin_unlock_irqrestore(&priv->reg_lock, flags);
50}
51
52void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
53{
54 unsigned long flags;
55
56 spin_lock_irqsave(&priv->reg_lock, flags);
57 __iwl_clear_bit(priv, reg, mask);
58 spin_unlock_irqrestore(&priv->reg_lock, flags);
59}
60
61int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
62 u32 bits, u32 mask, int timeout)
63{
64 int t = 0;
65
66 do {
67 if ((iwl_read32(priv, addr) & mask) == (bits & mask))
68 return t;
69 udelay(IWL_POLL_INTERVAL);
70 t += IWL_POLL_INTERVAL;
71 } while (t < timeout);
72
73 return -ETIMEDOUT;
74}
75
76int iwl_grab_nic_access(struct iwl_priv *priv)
77{
78 int ret;
79 u32 val;
80
81 lockdep_assert_held(&priv->reg_lock);
82
83 /* this bit wakes up the NIC */
84 __iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
85
86 /*
87 * These bits say the device is running, and should keep running for
88 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
89 * but they do not indicate that embedded SRAM is restored yet;
90 * 3945 and 4965 have volatile SRAM, and must save/restore contents
91 * to/from host DRAM when sleeping/waking for power-saving.
92 * Each direction takes approximately 1/4 millisecond; with this
93 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
94 * series of register accesses are expected (e.g. reading Event Log),
95 * to keep device from sleeping.
96 *
97 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
98 * SRAM is okay/restored. We don't check that here because this call
99 * is just for hardware register access; but GP1 MAC_SLEEP check is a
100 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
101 *
102 * 5000 series and later (including 1000 series) have non-volatile SRAM,
103 * and do not save/restore SRAM when power cycling.
104 */
105 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
106 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
107 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
108 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
109 if (ret < 0) {
110 val = iwl_read32(priv, CSR_GP_CNTRL);
111 IWL_ERR(priv,
112 "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
113 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
114 return -EIO;
115 }
116
117 return 0;
118}
119
120void iwl_release_nic_access(struct iwl_priv *priv)
121{
122 lockdep_assert_held(&priv->reg_lock);
123 __iwl_clear_bit(priv, CSR_GP_CNTRL,
124 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
125}
126
127u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
128{
129 u32 value;
130 unsigned long flags;
131
132 spin_lock_irqsave(&priv->reg_lock, flags);
133 iwl_grab_nic_access(priv);
134 value = iwl_read32(priv, reg);
135 iwl_release_nic_access(priv);
136 spin_unlock_irqrestore(&priv->reg_lock, flags);
137
138 return value;
139}
140
141void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
142{
143 unsigned long flags;
144
145 spin_lock_irqsave(&priv->reg_lock, flags);
146 if (!iwl_grab_nic_access(priv)) {
147 iwl_write32(priv, reg, value);
148 iwl_release_nic_access(priv);
149 }
150 spin_unlock_irqrestore(&priv->reg_lock, flags);
151}
152
153int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
154 int timeout)
155{
156 int t = 0;
157
158 do {
159 if ((iwl_read_direct32(priv, addr) & mask) == mask)
160 return t;
161 udelay(IWL_POLL_INTERVAL);
162 t += IWL_POLL_INTERVAL;
163 } while (t < timeout);
164
165 return -ETIMEDOUT;
166}
167
168static inline u32 __iwl_read_prph(struct iwl_priv *priv, u32 reg)
169{
170 iwl_write32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
171 rmb();
172 return iwl_read32(priv, HBUS_TARG_PRPH_RDAT);
173}
174
175static inline void __iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
176{
177 iwl_write32(priv, HBUS_TARG_PRPH_WADDR,
178 ((addr & 0x0000FFFF) | (3 << 24)));
179 wmb();
180 iwl_write32(priv, HBUS_TARG_PRPH_WDAT, val);
181}
182
183u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
184{
185 unsigned long flags;
186 u32 val;
187
188 spin_lock_irqsave(&priv->reg_lock, flags);
189 iwl_grab_nic_access(priv);
190 val = __iwl_read_prph(priv, reg);
191 iwl_release_nic_access(priv);
192 spin_unlock_irqrestore(&priv->reg_lock, flags);
193 return val;
194}
195
196void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
197{
198 unsigned long flags;
199
200 spin_lock_irqsave(&priv->reg_lock, flags);
201 if (!iwl_grab_nic_access(priv)) {
202 __iwl_write_prph(priv, addr, val);
203 iwl_release_nic_access(priv);
204 }
205 spin_unlock_irqrestore(&priv->reg_lock, flags);
206}
207
208void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
209{
210 unsigned long flags;
211
212 spin_lock_irqsave(&priv->reg_lock, flags);
213 iwl_grab_nic_access(priv);
214 __iwl_write_prph(priv, reg, __iwl_read_prph(priv, reg) | mask);
215 iwl_release_nic_access(priv);
216 spin_unlock_irqrestore(&priv->reg_lock, flags);
217}
218
219void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
220 u32 bits, u32 mask)
221{
222 unsigned long flags;
223
224 spin_lock_irqsave(&priv->reg_lock, flags);
225 iwl_grab_nic_access(priv);
226 __iwl_write_prph(priv, reg,
227 (__iwl_read_prph(priv, reg) & mask) | bits);
228 iwl_release_nic_access(priv);
229 spin_unlock_irqrestore(&priv->reg_lock, flags);
230}
231
232void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
233{
234 unsigned long flags;
235 u32 val;
236
237 spin_lock_irqsave(&priv->reg_lock, flags);
238 iwl_grab_nic_access(priv);
239 val = __iwl_read_prph(priv, reg);
240 __iwl_write_prph(priv, reg, (val & ~mask));
241 iwl_release_nic_access(priv);
242 spin_unlock_irqrestore(&priv->reg_lock, flags);
243}
244
245u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
246{
247 unsigned long flags;
248 u32 value;
249
250 spin_lock_irqsave(&priv->reg_lock, flags);
251 iwl_grab_nic_access(priv);
252
253 iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
254 rmb();
255 value = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
256
257 iwl_release_nic_access(priv);
258 spin_unlock_irqrestore(&priv->reg_lock, flags);
259 return value;
260}
261
262void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
263{
264 unsigned long flags;
265
266 spin_lock_irqsave(&priv->reg_lock, flags);
267 if (!iwl_grab_nic_access(priv)) {
268 iwl_write32(priv, HBUS_TARG_MEM_WADDR, addr);
269 wmb();
270 iwl_write32(priv, HBUS_TARG_MEM_WDAT, val);
271 iwl_release_nic_access(priv);
272 }
273 spin_unlock_irqrestore(&priv->reg_lock, flags);
274}
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0203a3bbf872..ab632baf49d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -35,494 +35,47 @@
35#include "iwl-debug.h" 35#include "iwl-debug.h"
36#include "iwl-devtrace.h" 36#include "iwl-devtrace.h"
37 37
38/* 38static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
39 * IO, register, and NIC memory access functions
40 *
41 * NOTE on naming convention and macro usage for these
42 *
43 * A single _ prefix before a an access function means that no state
44 * check or debug information is printed when that function is called.
45 *
46 * A double __ prefix before an access function means that state is checked
47 * and the current line number and caller function name are printed in addition
48 * to any other debug output.
49 *
50 * The non-prefixed name is the #define that maps the caller into a
51 * #define that provides the caller's name and __LINE__ to the double
52 * prefix version.
53 *
54 * If you wish to call the function without any debug or state checking,
55 * you should use the single _ prefix version (as is used by dependent IO
56 * routines, for example _iwl_read_direct32 calls the non-check version of
57 * _iwl_read32.)
58 *
59 * These declarations are *extremely* useful in quickly isolating code deltas
60 * which result in misconfiguration of the hardware I/O. In combination with
61 * git-bisect and the IO debug level you can quickly determine the specific
62 * commit which breaks the IO sequence to the hardware.
63 *
64 */
65
66static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
67{ 39{
68 trace_iwlwifi_dev_iowrite8(priv, ofs, val); 40 trace_iwlwifi_dev_iowrite8(priv, ofs, val);
69 iowrite8(val, priv->hw_base + ofs); 41 iowrite8(val, priv->hw_base + ofs);
70} 42}
71 43
72#ifdef CONFIG_IWLWIFI_DEBUG 44static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
73static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv,
74 u32 ofs, u8 val)
75{
76 IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
77 _iwl_write8(priv, ofs, val);
78}
79#define iwl_write8(priv, ofs, val) \
80 __iwl_write8(__FILE__, __LINE__, priv, ofs, val)
81#else
82#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val)
83#endif
84
85
86static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
87{ 45{
88 trace_iwlwifi_dev_iowrite32(priv, ofs, val); 46 trace_iwlwifi_dev_iowrite32(priv, ofs, val);
89 iowrite32(val, priv->hw_base + ofs); 47 iowrite32(val, priv->hw_base + ofs);
90} 48}
91 49
92#ifdef CONFIG_IWLWIFI_DEBUG 50static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
93static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
94 u32 ofs, u32 val)
95{
96 IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
97 _iwl_write32(priv, ofs, val);
98}
99#define iwl_write32(priv, ofs, val) \
100 __iwl_write32(__FILE__, __LINE__, priv, ofs, val)
101#else
102#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
103#endif
104
105static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs)
106{ 51{
107 u32 val = ioread32(priv->hw_base + ofs); 52 u32 val = ioread32(priv->hw_base + ofs);
108 trace_iwlwifi_dev_ioread32(priv, ofs, val); 53 trace_iwlwifi_dev_ioread32(priv, ofs, val);
109 return val; 54 return val;
110} 55}
111 56
112#ifdef CONFIG_IWLWIFI_DEBUG 57void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask);
113static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) 58void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask);
114{
115 IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
116 return _iwl_read32(priv, ofs);
117}
118#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
119#else
120#define iwl_read32(p, o) _iwl_read32(p, o)
121#endif
122
123#define IWL_POLL_INTERVAL 10 /* microseconds */
124static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
125 u32 bits, u32 mask, int timeout)
126{
127 int t = 0;
128
129 do {
130 if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
131 return t;
132 udelay(IWL_POLL_INTERVAL);
133 t += IWL_POLL_INTERVAL;
134 } while (t < timeout);
135
136 return -ETIMEDOUT;
137}
138#ifdef CONFIG_IWLWIFI_DEBUG
139static inline int __iwl_poll_bit(const char *f, u32 l,
140 struct iwl_priv *priv, u32 addr,
141 u32 bits, u32 mask, int timeout)
142{
143 int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
144 IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
145 addr, bits, mask,
146 unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
147 return ret;
148}
149#define iwl_poll_bit(priv, addr, bits, mask, timeout) \
150 __iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
151#else
152#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
153#endif
154
155static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
156{
157 _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask);
158}
159#ifdef CONFIG_IWLWIFI_DEBUG
160static inline void __iwl_set_bit(const char *f, u32 l,
161 struct iwl_priv *priv, u32 reg, u32 mask)
162{
163 u32 val = _iwl_read32(priv, reg) | mask;
164 IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
165 _iwl_write32(priv, reg, val);
166}
167static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
168{
169 unsigned long reg_flags;
170
171 spin_lock_irqsave(&p->reg_lock, reg_flags);
172 __iwl_set_bit(__FILE__, __LINE__, p, r, m);
173 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
174}
175#else
176static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
177{
178 unsigned long reg_flags;
179
180 spin_lock_irqsave(&p->reg_lock, reg_flags);
181 _iwl_set_bit(p, r, m);
182 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
183}
184#endif
185
186static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
187{
188 _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
189}
190#ifdef CONFIG_IWLWIFI_DEBUG
191static inline void __iwl_clear_bit(const char *f, u32 l,
192 struct iwl_priv *priv, u32 reg, u32 mask)
193{
194 u32 val = _iwl_read32(priv, reg) & ~mask;
195 IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
196 _iwl_write32(priv, reg, val);
197}
198static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
199{
200 unsigned long reg_flags;
201
202 spin_lock_irqsave(&p->reg_lock, reg_flags);
203 __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
204 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
205}
206#else
207static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
208{
209 unsigned long reg_flags;
210
211 spin_lock_irqsave(&p->reg_lock, reg_flags);
212 _iwl_clear_bit(p, r, m);
213 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
214}
215#endif
216
217static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
218{
219 int ret;
220 u32 val;
221
222 /* this bit wakes up the NIC */
223 _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
224
225 /*
226 * These bits say the device is running, and should keep running for
227 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
228 * but they do not indicate that embedded SRAM is restored yet;
229 * 3945 and 4965 have volatile SRAM, and must save/restore contents
230 * to/from host DRAM when sleeping/waking for power-saving.
231 * Each direction takes approximately 1/4 millisecond; with this
232 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
233 * series of register accesses are expected (e.g. reading Event Log),
234 * to keep device from sleeping.
235 *
236 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
237 * SRAM is okay/restored. We don't check that here because this call
238 * is just for hardware register access; but GP1 MAC_SLEEP check is a
239 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
240 *
241 * 5000 series and later (including 1000 series) have non-volatile SRAM,
242 * and do not save/restore SRAM when power cycling.
243 */
244 ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
245 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
246 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
247 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
248 if (ret < 0) {
249 val = _iwl_read32(priv, CSR_GP_CNTRL);
250 IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
251 _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
252 return -EIO;
253 }
254
255 return 0;
256}
257
258#ifdef CONFIG_IWLWIFI_DEBUG
259static inline int __iwl_grab_nic_access(const char *f, u32 l,
260 struct iwl_priv *priv)
261{
262 IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
263 return _iwl_grab_nic_access(priv);
264}
265#define iwl_grab_nic_access(priv) \
266 __iwl_grab_nic_access(__FILE__, __LINE__, priv)
267#else
268#define iwl_grab_nic_access(priv) \
269 _iwl_grab_nic_access(priv)
270#endif
271
272static inline void _iwl_release_nic_access(struct iwl_priv *priv)
273{
274 _iwl_clear_bit(priv, CSR_GP_CNTRL,
275 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
276}
277#ifdef CONFIG_IWLWIFI_DEBUG
278static inline void __iwl_release_nic_access(const char *f, u32 l,
279 struct iwl_priv *priv)
280{
281
282 IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
283 _iwl_release_nic_access(priv);
284}
285#define iwl_release_nic_access(priv) \
286 __iwl_release_nic_access(__FILE__, __LINE__, priv)
287#else
288#define iwl_release_nic_access(priv) \
289 _iwl_release_nic_access(priv)
290#endif
291
292static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg)
293{
294 return _iwl_read32(priv, reg);
295}
296#ifdef CONFIG_IWLWIFI_DEBUG
297static inline u32 __iwl_read_direct32(const char *f, u32 l,
298 struct iwl_priv *priv, u32 reg)
299{
300 u32 value = _iwl_read_direct32(priv, reg);
301 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
302 f, l);
303 return value;
304}
305static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
306{
307 u32 value;
308 unsigned long reg_flags;
309
310 spin_lock_irqsave(&priv->reg_lock, reg_flags);
311 iwl_grab_nic_access(priv);
312 value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
313 iwl_release_nic_access(priv);
314 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
315 return value;
316}
317
318#else
319static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
320{
321 u32 value;
322 unsigned long reg_flags;
323
324 spin_lock_irqsave(&priv->reg_lock, reg_flags);
325 iwl_grab_nic_access(priv);
326 value = _iwl_read_direct32(priv, reg);
327 iwl_release_nic_access(priv);
328 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
329 return value;
330
331}
332#endif
333
334static inline void _iwl_write_direct32(struct iwl_priv *priv,
335 u32 reg, u32 value)
336{
337 _iwl_write32(priv, reg, value);
338}
339static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
340{
341 unsigned long reg_flags;
342
343 spin_lock_irqsave(&priv->reg_lock, reg_flags);
344 if (!iwl_grab_nic_access(priv)) {
345 _iwl_write_direct32(priv, reg, value);
346 iwl_release_nic_access(priv);
347 }
348 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
349}
350
351static inline void iwl_write_reg_buf(struct iwl_priv *priv,
352 u32 reg, u32 len, u32 *values)
353{
354 u32 count = sizeof(u32);
355
356 if ((priv != NULL) && (values != NULL)) {
357 for (; 0 < len; len -= count, reg += count, values++)
358 iwl_write_direct32(priv, reg, *values);
359 }
360}
361
362static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
363 u32 mask, int timeout)
364{
365 int t = 0;
366
367 do {
368 if ((iwl_read_direct32(priv, addr) & mask) == mask)
369 return t;
370 udelay(IWL_POLL_INTERVAL);
371 t += IWL_POLL_INTERVAL;
372 } while (t < timeout);
373
374 return -ETIMEDOUT;
375}
376
377#ifdef CONFIG_IWLWIFI_DEBUG
378static inline int __iwl_poll_direct_bit(const char *f, u32 l,
379 struct iwl_priv *priv,
380 u32 addr, u32 mask, int timeout)
381{
382 int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout);
383
384 if (unlikely(ret == -ETIMEDOUT))
385 IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
386 "timedout - %s %d\n", addr, mask, f, l);
387 else
388 IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
389 "- %s %d\n", addr, mask, ret, f, l);
390 return ret;
391}
392#define iwl_poll_direct_bit(priv, addr, mask, timeout) \
393 __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
394#else
395#define iwl_poll_direct_bit _iwl_poll_direct_bit
396#endif
397
398static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
399{
400 _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
401 rmb();
402 return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
403}
404static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
405{
406 unsigned long reg_flags;
407 u32 val;
408
409 spin_lock_irqsave(&priv->reg_lock, reg_flags);
410 iwl_grab_nic_access(priv);
411 val = _iwl_read_prph(priv, reg);
412 iwl_release_nic_access(priv);
413 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
414 return val;
415}
416
417static inline void _iwl_write_prph(struct iwl_priv *priv,
418 u32 addr, u32 val)
419{
420 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
421 ((addr & 0x0000FFFF) | (3 << 24)));
422 wmb();
423 _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
424}
425
426static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
427{
428 unsigned long reg_flags;
429 59
430 spin_lock_irqsave(&priv->reg_lock, reg_flags); 60int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
431 if (!iwl_grab_nic_access(priv)) { 61 u32 bits, u32 mask, int timeout);
432 _iwl_write_prph(priv, addr, val); 62int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
433 iwl_release_nic_access(priv); 63 int timeout);
434 }
435 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
436}
437 64
438#define _iwl_set_bits_prph(priv, reg, mask) \ 65int iwl_grab_nic_access(struct iwl_priv *priv);
439 _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask)) 66void iwl_release_nic_access(struct iwl_priv *priv);
440 67
441static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) 68u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg);
442{ 69void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value);
443 unsigned long reg_flags;
444 70
445 spin_lock_irqsave(&priv->reg_lock, reg_flags);
446 iwl_grab_nic_access(priv);
447 _iwl_set_bits_prph(priv, reg, mask);
448 iwl_release_nic_access(priv);
449 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
450}
451 71
452#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \ 72u32 iwl_read_prph(struct iwl_priv *priv, u32 reg);
453 _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits)) 73void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val);
74void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
75void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
76 u32 bits, u32 mask);
77void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
454 78
455static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, 79u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
456 u32 bits, u32 mask) 80void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
457{
458 unsigned long reg_flags;
459
460 spin_lock_irqsave(&priv->reg_lock, reg_flags);
461 iwl_grab_nic_access(priv);
462 _iwl_set_bits_mask_prph(priv, reg, bits, mask);
463 iwl_release_nic_access(priv);
464 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
465}
466
467static inline void iwl_clear_bits_prph(struct iwl_priv
468 *priv, u32 reg, u32 mask)
469{
470 unsigned long reg_flags;
471 u32 val;
472
473 spin_lock_irqsave(&priv->reg_lock, reg_flags);
474 iwl_grab_nic_access(priv);
475 val = _iwl_read_prph(priv, reg);
476 _iwl_write_prph(priv, reg, (val & ~mask));
477 iwl_release_nic_access(priv);
478 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
479}
480
481static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
482{
483 unsigned long reg_flags;
484 u32 value;
485
486 spin_lock_irqsave(&priv->reg_lock, reg_flags);
487 iwl_grab_nic_access(priv);
488
489 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
490 rmb();
491 value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
492
493 iwl_release_nic_access(priv);
494 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
495 return value;
496}
497
498static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
499{
500 unsigned long reg_flags;
501
502 spin_lock_irqsave(&priv->reg_lock, reg_flags);
503 if (!iwl_grab_nic_access(priv)) {
504 _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
505 wmb();
506 _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
507 iwl_release_nic_access(priv);
508 }
509 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
510}
511
512static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
513 u32 len, u32 *values)
514{
515 unsigned long reg_flags;
516
517 spin_lock_irqsave(&priv->reg_lock, reg_flags);
518 if (!iwl_grab_nic_access(priv)) {
519 _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
520 wmb();
521 for (; 0 < len; len -= sizeof(u32), values++)
522 _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
523
524 iwl_release_nic_access(priv);
525 }
526 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
527}
528#endif 81#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index d7f2a0bb32c9..c2862d4e00e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 101eef12b3bb..05b8e8f7dd4a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 576795e2c75b..c43c8e66de73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index fe012032c28c..59635d784e27 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 86f5123bccda..c960195df989 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,6 @@
91#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000) 91#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
92#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000) 92#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
93#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000) 93#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
94#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
95#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000) 94#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
96#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */ 95#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */
97#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060) 96#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
@@ -99,152 +98,6 @@
99#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) 98#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
100 99
101/** 100/**
102 * BSM (Bootstrap State Machine)
103 *
104 * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
105 * in special SRAM that does not power down when the embedded control
106 * processor is sleeping (e.g. for periodic power-saving shutdowns of radio).
107 *
108 * When powering back up after sleeps (or during initial uCode load), the BSM
109 * internally loads the short bootstrap program from the special SRAM into the
110 * embedded processor's instruction SRAM, and starts the processor so it runs
111 * the bootstrap program.
112 *
113 * This bootstrap program loads (via PCI busmaster DMA) instructions and data
114 * images for a uCode program from host DRAM locations. The host driver
115 * indicates DRAM locations and sizes for instruction and data images via the
116 * four BSM_DRAM_* registers. Once the bootstrap program loads the new program,
117 * the new program starts automatically.
118 *
119 * The uCode used for open-source drivers includes two programs:
120 *
121 * 1) Initialization -- performs hardware calibration and sets up some
122 * internal data, then notifies host via "initialize alive" notification
123 * (struct iwl_init_alive_resp) that it has completed all of its work.
124 * After signal from host, it then loads and starts the runtime program.
125 * The initialization program must be used when initially setting up the
126 * NIC after loading the driver.
127 *
128 * 2) Runtime/Protocol -- performs all normal runtime operations. This
129 * notifies host via "alive" notification (struct iwl_alive_resp) that it
130 * is ready to be used.
131 *
132 * When initializing the NIC, the host driver does the following procedure:
133 *
134 * 1) Load bootstrap program (instructions only, no data image for bootstrap)
135 * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND
136 *
137 * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction
138 * images in host DRAM.
139 *
140 * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked:
141 * BSM_WR_MEM_SRC_REG = 0
142 * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND
143 * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image
144 *
145 * 4) Load bootstrap into instruction SRAM:
146 * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START
147 *
148 * 5) Wait for load completion:
149 * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0
150 *
151 * 6) Enable future boot loads whenever NIC's power management triggers it:
152 * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN
153 *
154 * 7) Start the NIC by removing all reset bits:
155 * CSR_RESET = 0
156 *
157 * The bootstrap uCode (already in instruction SRAM) loads initialization
158 * uCode. Initialization uCode performs data initialization, sends
159 * "initialize alive" notification to host, and waits for a signal from
160 * host to load runtime code.
161 *
162 * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction
163 * images in host DRAM. The last register loaded must be the instruction
164 * byte count register ("1" in MSbit tells initialization uCode to load
165 * the runtime uCode):
166 * BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD
167 *
168 * 5) Wait for "alive" notification, then issue normal runtime commands.
169 *
170 * Data caching during power-downs:
171 *
172 * Just before the embedded controller powers down (e.g for automatic
173 * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA)
174 * a current snapshot of the embedded processor's data SRAM into host DRAM.
175 * This caches the data while the embedded processor's memory is powered down.
176 * Location and size are controlled by BSM_DRAM_DATA_* registers.
177 *
178 * NOTE: Instruction SRAM does not need to be saved, since that doesn't
179 * change during operation; the original image (from uCode distribution
180 * file) can be used for reload.
181 *
182 * When powering back up, the BSM loads the bootstrap program. Bootstrap looks
183 * at the BSM_DRAM_* registers, which now point to the runtime instruction
184 * image and the cached (modified) runtime data (*not* the initialization
185 * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the
186 * uCode from where it left off before the power-down.
187 *
188 * NOTE: Initialization uCode does *not* run as part of the save/restore
189 * procedure.
190 *
191 * This save/restore method is mostly for autonomous power management during
192 * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and
193 * RFKILL should use complete restarts (with total re-initialization) of uCode,
194 * allowing total shutdown (including BSM memory).
195 *
196 * Note that, during normal operation, the host DRAM that held the initial
197 * startup data for the runtime code is now being used as a backup data cache
198 * for modified data! If you need to completely re-initialize the NIC, make
199 * sure that you use the runtime data image from the uCode distribution file,
200 * not the modified/saved runtime data. You may want to store a separate
201 * "clean" runtime data image in DRAM to avoid disk reads of distribution file.
202 */
203
204/* BSM bit fields */
205#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */
206#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/
207#define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */
208
209/* BSM addresses */
210#define BSM_BASE (PRPH_BASE + 0x3400)
211#define BSM_END (PRPH_BASE + 0x3800)
212
213#define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */
214#define BSM_WR_MEM_SRC_REG (BSM_BASE + 0x004) /* source in BSM mem */
215#define BSM_WR_MEM_DST_REG (BSM_BASE + 0x008) /* dest in SRAM mem */
216#define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */
217#define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */
218
219/*
220 * Pointers and size regs for bootstrap load and data SRAM save/restore.
221 * NOTE: 3945 pointers use bits 31:0 of DRAM address.
222 * 4965 pointers use bits 35:4 of DRAM address.
223 */
224#define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090)
225#define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094)
226#define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098)
227#define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C)
228
229/*
230 * BSM special memory, stays powered on during power-save sleeps.
231 * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1)
232 */
233#define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800)
234#define BSM_SRAM_SIZE (1024) /* bytes */
235
236
237/* 3945 Tx scheduler registers */
238#define ALM_SCD_BASE (PRPH_BASE + 0x2E00)
239#define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000)
240#define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004)
241#define ALM_SCD_TXFACT_REG (ALM_SCD_BASE + 0x010)
242#define ALM_SCD_TXF4MF_REG (ALM_SCD_BASE + 0x014)
243#define ALM_SCD_TXF5MF_REG (ALM_SCD_BASE + 0x020)
244#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C)
245#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030)
246
247/**
248 * Tx Scheduler 101 * Tx Scheduler
249 * 102 *
250 * The Tx Scheduler selects the next frame to be transmitted, choosing TFDs 103 * The Tx Scheduler selects the next frame to be transmitted, choosing TFDs
@@ -330,201 +183,10 @@
330 * Max Tx window size is the max number of contiguous TFDs that the scheduler 183 * Max Tx window size is the max number of contiguous TFDs that the scheduler
331 * can keep track of at one time when creating block-ack chains of frames. 184 * can keep track of at one time when creating block-ack chains of frames.
332 * Note that "64" matches the number of ack bits in a block-ack packet. 185 * Note that "64" matches the number of ack bits in a block-ack packet.
333 * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize
334 * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values.
335 */ 186 */
336#define SCD_WIN_SIZE 64 187#define SCD_WIN_SIZE 64
337#define SCD_FRAME_LIMIT 64 188#define SCD_FRAME_LIMIT 64
338 189
339/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
340#define IWL49_SCD_START_OFFSET 0xa02c00
341
342/*
343 * 4965 tells driver SRAM address for internal scheduler structs via this reg.
344 * Value is valid only after "Alive" response from uCode.
345 */
346#define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x0)
347
348/*
349 * Driver may need to update queue-empty bits after changing queue's
350 * write and read pointers (indexes) during (re-)initialization (i.e. when
351 * scheduler is not tracking what's happening).
352 * Bit fields:
353 * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit
354 * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty
355 * NOTE: This register is not used by Linux driver.
356 */
357#define IWL49_SCD_EMPTY_BITS (IWL49_SCD_START_OFFSET + 0x4)
358
359/*
360 * Physical base address of array of byte count (BC) circular buffers (CBs).
361 * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode.
362 * This register points to BC CB for queue 0, must be on 1024-byte boundary.
363 * Others are spaced by 1024 bytes.
364 * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad.
365 * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff).
366 * Bit fields:
367 * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned.
368 */
369#define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10)
370
371/*
372 * Enables any/all Tx DMA/FIFO channels.
373 * Scheduler generates requests for only the active channels.
374 * Set this to 0xff to enable all 8 channels (normal usage).
375 * Bit fields:
376 * 7- 0: Enable (1), disable (0), one bit for each channel 0-7
377 */
378#define IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c)
379/*
380 * Queue (x) Write Pointers (indexes, really!), one for each Tx queue.
381 * Initialized and updated by driver as new TFDs are added to queue.
382 * NOTE: If using Block Ack, index must correspond to frame's
383 * Start Sequence Number; index = (SSN & 0xff)
384 * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses?
385 */
386#define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4)
387
388/*
389 * Queue (x) Read Pointers (indexes, really!), one for each Tx queue.
390 * For FIFO mode, index indicates next frame to transmit.
391 * For Scheduler-ACK mode, index indicates first frame in Tx window.
392 * Initialized by driver, updated by scheduler.
393 */
394#define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4)
395
396/*
397 * Select which queues work in chain mode (1) vs. not (0).
398 * Use chain mode to build chains of aggregated frames.
399 * Bit fields:
400 * 31-16: Reserved
401 * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time
402 * NOTE: If driver sets up queue for chain mode, it should be also set up
403 * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x).
404 */
405#define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_START_OFFSET + 0xd0)
406
407/*
408 * Select which queues interrupt driver when scheduler increments
409 * a queue's read pointer (index).
410 * Bit fields:
411 * 31-16: Reserved
412 * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled
413 * NOTE: This functionality is apparently a no-op; driver relies on interrupts
414 * from Rx queue to read Tx command responses and update Tx queues.
415 */
416#define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4)
417
418/*
419 * Queue search status registers. One for each queue.
420 * Sets up queue mode and assigns queue to Tx DMA channel.
421 * Bit fields:
422 * 19-10: Write mask/enable bits for bits 0-9
423 * 9: Driver should init to "0"
424 * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0).
425 * Driver should init to "1" for aggregation mode, or "0" otherwise.
426 * 7-6: Driver should init to "0"
427 * 5: Window Size Left; indicates whether scheduler can request
428 * another TFD, based on window size, etc. Driver should init
429 * this bit to "1" for aggregation mode, or "0" for non-agg.
430 * 4-1: Tx FIFO to use (range 0-7).
431 * 0: Queue is active (1), not active (0).
432 * Other bits should be written as "0"
433 *
434 * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled
435 * via SCD_QUEUECHAIN_SEL.
436 */
437#define IWL49_SCD_QUEUE_STATUS_BITS(x)\
438 (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4)
439
440/* Bit field positions */
441#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0)
442#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1)
443#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5)
444#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8)
445
446/* Write masks */
447#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)
448#define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00)
449
450/**
451 * 4965 internal SRAM structures for scheduler, shared with driver ...
452 *
453 * Driver should clear and initialize the following areas after receiving
454 * "Alive" response from 4965 uCode, i.e. after initial
455 * uCode load, or after a uCode load done for error recovery:
456 *
457 * SCD_CONTEXT_DATA_OFFSET (size 128 bytes)
458 * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes)
459 * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes)
460 *
461 * Driver accesses SRAM via HBUS_TARG_MEM_* registers.
462 * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR.
463 * All OFFSET values must be added to this base address.
464 */
465
466/*
467 * Queue context. One 8-byte entry for each of 16 queues.
468 *
469 * Driver should clear this entire area (size 0x80) to 0 after receiving
470 * "Alive" notification from uCode. Additionally, driver should init
471 * each queue's entry as follows:
472 *
473 * LS Dword bit fields:
474 * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64.
475 *
476 * MS Dword bit fields:
477 * 16-22: Frame limit. Driver should init to 10 (0xa).
478 *
479 * Driver should init all other bits to 0.
480 *
481 * Init must be done after driver receives "Alive" response from 4965 uCode,
482 * and when setting up queue for aggregation.
483 */
484#define IWL49_SCD_CONTEXT_DATA_OFFSET 0x380
485#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \
486 (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
487
488#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)
489#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F)
490#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
491#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
492
493/*
494 * Tx Status Bitmap
495 *
496 * Driver should clear this entire area (size 0x100) to 0 after receiving
497 * "Alive" notification from uCode. Area is used only by device itself;
498 * no other support (besides clearing) is required from driver.
499 */
500#define IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400
501
502/*
503 * RAxTID to queue translation mapping.
504 *
505 * When queue is in Scheduler-ACK mode, frames placed in a that queue must be
506 * for only one combination of receiver address (RA) and traffic ID (TID), i.e.
507 * one QOS priority level destined for one station (for this wireless link,
508 * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit
509 * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK
510 * mode, the device ignores the mapping value.
511 *
512 * Bit fields, for each 16-bit map:
513 * 15-9: Reserved, set to 0
514 * 8-4: Index into device's station table for recipient station
515 * 3-0: Traffic ID (tid), range 0-15
516 *
517 * Driver should clear this entire area (size 32 bytes) to 0 after receiving
518 * "Alive" notification from uCode. To update a 16-bit map value, driver
519 * must read a dword-aligned value from device SRAM, replace the 16-bit map
520 * value of interest, and write the dword value back into device SRAM.
521 */
522#define IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500
523
524/* Find translation table dword to read/write for given queue */
525#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
526 ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
527
528#define IWL_SCD_TXFIFO_POS_TID (0) 190#define IWL_SCD_TXFIFO_POS_TID (0)
529#define IWL_SCD_TXFIFO_POS_RA (4) 191#define IWL_SCD_TXFIFO_POS_RA (4)
530#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) 192#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 6f9a2fa04763..c421f566982f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -239,16 +239,16 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
239 palive->is_valid, palive->ver_type, 239 palive->is_valid, palive->ver_type,
240 palive->ver_subtype); 240 palive->ver_subtype);
241 241
242 priv->device_pointers.log_event_table =
243 le32_to_cpu(palive->log_event_table_ptr);
244 priv->device_pointers.error_event_table =
245 le32_to_cpu(palive->error_event_table_ptr);
246
242 if (palive->ver_subtype == INITIALIZE_SUBTYPE) { 247 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
243 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); 248 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
244 memcpy(&priv->card_alive_init,
245 &pkt->u.alive_frame,
246 sizeof(struct iwl_init_alive_resp));
247 pwork = &priv->init_alive_start; 249 pwork = &priv->init_alive_start;
248 } else { 250 } else {
249 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 251 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
250 memcpy(&priv->card_alive, &pkt->u.alive_frame,
251 sizeof(struct iwl_alive_resp));
252 pwork = &priv->alive_start; 252 pwork = &priv->alive_start;
253 } 253 }
254 254
@@ -898,7 +898,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
898 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 898 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
899 899
900 ieee80211_rx(priv->hw, skb); 900 ieee80211_rx(priv->hw, skb);
901 priv->alloc_rxb_page--;
902 rxb->page = NULL; 901 rxb->page = NULL;
903} 902}
904 903
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 914c77e44588..d60d630cb93a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index c4ca0b5d77da..cb80bb4ce45e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ieee80211 subsystem header files. 5 * Portions of this file are derived from the ieee80211 subsystem header files.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index bc90a12408a3..c21515640077 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -233,7 +233,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
233 struct iwl_station_entry *station; 233 struct iwl_station_entry *station;
234 int i; 234 int i;
235 u8 sta_id = IWL_INVALID_STATION; 235 u8 sta_id = IWL_INVALID_STATION;
236 u16 rate;
237 236
238 if (is_ap) 237 if (is_ap)
239 sta_id = ctx->ap_sta_id; 238 sta_id = ctx->ap_sta_id;
@@ -306,12 +305,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
306 */ 305 */
307 iwl_set_ht_add_station(priv, sta_id, sta, ctx); 306 iwl_set_ht_add_station(priv, sta_id, sta, ctx);
308 307
309 /* 3945 only */
310 rate = (priv->band == IEEE80211_BAND_5GHZ) ?
311 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
312 /* Turn on both antennas for the station... */
313 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
314
315 return sta_id; 308 return sta_id;
316 309
317} 310}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 206f1e1a0caf..ff64027ff4cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 277c9175dcf6..565980fbb591 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -149,32 +149,31 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv)
149 struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; 149 struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
150 struct iwl_queue *q = &txq->q; 150 struct iwl_queue *q = &txq->q;
151 int i; 151 int i;
152 bool huge = false;
153 152
154 if (q->n_bd == 0) 153 if (q->n_bd == 0)
155 return; 154 return;
156 155
157 while (q->read_ptr != q->write_ptr) { 156 while (q->read_ptr != q->write_ptr) {
158 /* we have no way to tell if it is a huge cmd ATM */
159 i = get_cmd_index(q, q->read_ptr, 0); 157 i = get_cmd_index(q, q->read_ptr, 0);
160 158
161 if (txq->meta[i].flags & CMD_SIZE_HUGE) 159 if (txq->meta[i].flags & CMD_MAPPED) {
162 huge = true;
163 else
164 pci_unmap_single(priv->pci_dev, 160 pci_unmap_single(priv->pci_dev,
165 dma_unmap_addr(&txq->meta[i], mapping), 161 dma_unmap_addr(&txq->meta[i], mapping),
166 dma_unmap_len(&txq->meta[i], len), 162 dma_unmap_len(&txq->meta[i], len),
167 PCI_DMA_BIDIRECTIONAL); 163 PCI_DMA_BIDIRECTIONAL);
164 txq->meta[i].flags = 0;
165 }
168 166
169 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 167 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
170 } 168 }
171 169
172 if (huge) { 170 i = q->n_window;
173 i = q->n_window; 171 if (txq->meta[i].flags & CMD_MAPPED) {
174 pci_unmap_single(priv->pci_dev, 172 pci_unmap_single(priv->pci_dev,
175 dma_unmap_addr(&txq->meta[i], mapping), 173 dma_unmap_addr(&txq->meta[i], mapping),
176 dma_unmap_len(&txq->meta[i], len), 174 dma_unmap_len(&txq->meta[i], len),
177 PCI_DMA_BIDIRECTIONAL); 175 PCI_DMA_BIDIRECTIONAL);
176 txq->meta[i].flags = 0;
178 } 177 }
179} 178}
180 179
@@ -463,7 +462,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
463 return -EIO; 462 return -EIO;
464 } 463 }
465 464
465 spin_lock_irqsave(&priv->hcmd_lock, flags);
466
466 if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { 467 if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
468 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
469
467 IWL_ERR(priv, "No space in command queue\n"); 470 IWL_ERR(priv, "No space in command queue\n");
468 if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { 471 if (priv->cfg->ops->lib->tt_ops.ct_kill_check) {
469 is_ct_kill = 472 is_ct_kill =
@@ -471,27 +474,22 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
471 } 474 }
472 if (!is_ct_kill) { 475 if (!is_ct_kill) {
473 IWL_ERR(priv, "Restarting adapter due to queue full\n"); 476 IWL_ERR(priv, "Restarting adapter due to queue full\n");
474 queue_work(priv->workqueue, &priv->restart); 477 iwlagn_fw_error(priv, false);
475 } 478 }
476 return -ENOSPC; 479 return -ENOSPC;
477 } 480 }
478 481
479 spin_lock_irqsave(&priv->hcmd_lock, flags);
480
481 /* If this is a huge cmd, mark the huge flag also on the meta.flags
482 * of the _original_ cmd. This is used for DMA mapping clean up.
483 */
484 if (cmd->flags & CMD_SIZE_HUGE) {
485 idx = get_cmd_index(q, q->write_ptr, 0);
486 txq->meta[idx].flags = CMD_SIZE_HUGE;
487 }
488
489 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); 482 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
490 out_cmd = txq->cmd[idx]; 483 out_cmd = txq->cmd[idx];
491 out_meta = &txq->meta[idx]; 484 out_meta = &txq->meta[idx];
492 485
486 if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
487 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
488 return -ENOSPC;
489 }
490
493 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ 491 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
494 out_meta->flags = cmd->flags; 492 out_meta->flags = cmd->flags | CMD_MAPPED;
495 if (cmd->flags & CMD_WANT_SKB) 493 if (cmd->flags & CMD_WANT_SKB)
496 out_meta->source = cmd; 494 out_meta->source = cmd;
497 if (cmd->flags & CMD_ASYNC) 495 if (cmd->flags & CMD_ASYNC)
@@ -584,7 +582,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
584 if (nfreed++ > 0) { 582 if (nfreed++ > 0) {
585 IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx, 583 IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
586 q->write_ptr, q->read_ptr); 584 q->write_ptr, q->read_ptr);
587 queue_work(priv->workqueue, &priv->restart); 585 iwlagn_fw_error(priv, false);
588 } 586 }
589 587
590 } 588 }
@@ -609,6 +607,10 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
609 struct iwl_device_cmd *cmd; 607 struct iwl_device_cmd *cmd;
610 struct iwl_cmd_meta *meta; 608 struct iwl_cmd_meta *meta;
611 struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; 609 struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
610 unsigned long flags;
611 void (*callback) (struct iwl_priv *priv, struct iwl_device_cmd *cmd,
612 struct iwl_rx_packet *pkt);
613
612 614
613 /* If a Tx command is being handled and it isn't in the actual 615 /* If a Tx command is being handled and it isn't in the actual
614 * command queue then there a command routing bug has been introduced 616 * command queue then there a command routing bug has been introduced
@@ -622,14 +624,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
622 return; 624 return;
623 } 625 }
624 626
625 /* If this is a huge cmd, clear the huge flag on the meta.flags 627 spin_lock_irqsave(&priv->hcmd_lock, flags);
626 * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap 628
627 * the DMA buffer for the scan (huge) command.
628 */
629 if (huge) {
630 cmd_index = get_cmd_index(&txq->q, index, 0);
631 txq->meta[cmd_index].flags = 0;
632 }
633 cmd_index = get_cmd_index(&txq->q, index, huge); 629 cmd_index = get_cmd_index(&txq->q, index, huge);
634 cmd = txq->cmd[cmd_index]; 630 cmd = txq->cmd[cmd_index];
635 meta = &txq->meta[cmd_index]; 631 meta = &txq->meta[cmd_index];
@@ -639,12 +635,13 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
639 dma_unmap_len(meta, len), 635 dma_unmap_len(meta, len),
640 PCI_DMA_BIDIRECTIONAL); 636 PCI_DMA_BIDIRECTIONAL);
641 637
638 callback = NULL;
642 /* Input error checking is done when commands are added to queue. */ 639 /* Input error checking is done when commands are added to queue. */
643 if (meta->flags & CMD_WANT_SKB) { 640 if (meta->flags & CMD_WANT_SKB) {
644 meta->source->reply_page = (unsigned long)rxb_addr(rxb); 641 meta->source->reply_page = (unsigned long)rxb_addr(rxb);
645 rxb->page = NULL; 642 rxb->page = NULL;
646 } else if (meta->callback) 643 } else
647 meta->callback(priv, cmd, pkt); 644 callback = meta->callback;
648 645
649 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); 646 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
650 647
@@ -654,5 +651,12 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
654 get_cmd_string(cmd->hdr.cmd)); 651 get_cmd_string(cmd->hdr.cmd));
655 wake_up_interruptible(&priv->wait_command_queue); 652 wake_up_interruptible(&priv->wait_command_queue);
656 } 653 }
654
655 /* Mark as unmapped */
657 meta->flags = 0; 656 meta->flags = 0;
657
658 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
659
660 if (callback)
661 callback(priv, cmd, pkt);
658} 662}
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index f6c2cd665f49..078ef43d957d 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -57,6 +57,7 @@ struct if_spi_card {
57 /* Handles all SPI communication (except for FW load) */ 57 /* Handles all SPI communication (except for FW load) */
58 struct workqueue_struct *workqueue; 58 struct workqueue_struct *workqueue;
59 struct work_struct packet_work; 59 struct work_struct packet_work;
60 struct work_struct resume_work;
60 61
61 u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; 62 u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE];
62 63
@@ -68,6 +69,9 @@ struct if_spi_card {
68 69
69 /* Protects cmd_packet_list and data_packet_list */ 70 /* Protects cmd_packet_list and data_packet_list */
70 spinlock_t buffer_lock; 71 spinlock_t buffer_lock;
72
73 /* True is card suspended */
74 u8 suspended;
71}; 75};
72 76
73static void free_if_spi_card(struct if_spi_card *card) 77static void free_if_spi_card(struct if_spi_card *card)
@@ -1057,6 +1061,28 @@ out:
1057 return err; 1061 return err;
1058} 1062}
1059 1063
1064static void if_spi_resume_worker(struct work_struct *work)
1065{
1066 struct if_spi_card *card;
1067
1068 card = container_of(work, struct if_spi_card, resume_work);
1069
1070 if (card->suspended) {
1071 if (card->pdata->setup)
1072 card->pdata->setup(card->spi);
1073
1074 /* Init card ... */
1075 if_spi_init_card(card);
1076
1077 enable_irq(card->spi->irq);
1078
1079 /* And resume it ... */
1080 lbs_resume(card->priv);
1081
1082 card->suspended = 0;
1083 }
1084}
1085
1060static int __devinit if_spi_probe(struct spi_device *spi) 1086static int __devinit if_spi_probe(struct spi_device *spi)
1061{ 1087{
1062 struct if_spi_card *card; 1088 struct if_spi_card *card;
@@ -1107,6 +1133,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
1107 goto free_card; 1133 goto free_card;
1108 } 1134 }
1109 card->priv = priv; 1135 card->priv = priv;
1136 priv->setup_fw_on_resume = 1;
1110 priv->card = card; 1137 priv->card = card;
1111 priv->hw_host_to_card = if_spi_host_to_card; 1138 priv->hw_host_to_card = if_spi_host_to_card;
1112 priv->enter_deep_sleep = NULL; 1139 priv->enter_deep_sleep = NULL;
@@ -1117,6 +1144,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
1117 /* Initialize interrupt handling stuff. */ 1144 /* Initialize interrupt handling stuff. */
1118 card->workqueue = create_workqueue("libertas_spi"); 1145 card->workqueue = create_workqueue("libertas_spi");
1119 INIT_WORK(&card->packet_work, if_spi_host_to_card_worker); 1146 INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
1147 INIT_WORK(&card->resume_work, if_spi_resume_worker);
1120 1148
1121 err = request_irq(spi->irq, if_spi_host_interrupt, 1149 err = request_irq(spi->irq, if_spi_host_interrupt,
1122 IRQF_TRIGGER_FALLING, "libertas_spi", card); 1150 IRQF_TRIGGER_FALLING, "libertas_spi", card);
@@ -1161,6 +1189,8 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
1161 lbs_deb_spi("libertas_spi_remove\n"); 1189 lbs_deb_spi("libertas_spi_remove\n");
1162 lbs_deb_enter(LBS_DEB_SPI); 1190 lbs_deb_enter(LBS_DEB_SPI);
1163 1191
1192 cancel_work_sync(&card->resume_work);
1193
1164 lbs_stop_card(priv); 1194 lbs_stop_card(priv);
1165 lbs_remove_card(priv); /* will call free_netdev */ 1195 lbs_remove_card(priv); /* will call free_netdev */
1166 1196
@@ -1174,6 +1204,40 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
1174 return 0; 1204 return 0;
1175} 1205}
1176 1206
1207static int if_spi_suspend(struct device *dev)
1208{
1209 struct spi_device *spi = to_spi_device(dev);
1210 struct if_spi_card *card = spi_get_drvdata(spi);
1211
1212 if (!card->suspended) {
1213 lbs_suspend(card->priv);
1214 flush_workqueue(card->workqueue);
1215 disable_irq(spi->irq);
1216
1217 if (card->pdata->teardown)
1218 card->pdata->teardown(spi);
1219 card->suspended = 1;
1220 }
1221
1222 return 0;
1223}
1224
1225static int if_spi_resume(struct device *dev)
1226{
1227 struct spi_device *spi = to_spi_device(dev);
1228 struct if_spi_card *card = spi_get_drvdata(spi);
1229
1230 /* Schedule delayed work */
1231 schedule_work(&card->resume_work);
1232
1233 return 0;
1234}
1235
1236static const struct dev_pm_ops if_spi_pm_ops = {
1237 .suspend = if_spi_suspend,
1238 .resume = if_spi_resume,
1239};
1240
1177static struct spi_driver libertas_spi_driver = { 1241static struct spi_driver libertas_spi_driver = {
1178 .probe = if_spi_probe, 1242 .probe = if_spi_probe,
1179 .remove = __devexit_p(libertas_spi_remove), 1243 .remove = __devexit_p(libertas_spi_remove),
@@ -1181,6 +1245,7 @@ static struct spi_driver libertas_spi_driver = {
1181 .name = "libertas_spi", 1245 .name = "libertas_spi",
1182 .bus = &spi_bus_type, 1246 .bus = &spi_bus_type,
1183 .owner = THIS_MODULE, 1247 .owner = THIS_MODULE,
1248 .pm = &if_spi_pm_ops,
1184 }, 1249 },
1185}; 1250};
1186 1251
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
new file mode 100644
index 000000000000..73a6e62f5680
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -0,0 +1,809 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11n
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * Fills HT capability information field, AMPDU Parameters field, HT extended
30 * capability field, and supported MCS set fields.
31 *
32 * Only the following HT capability information fields are used, all other
33 * fields are always turned off.
34 *
35 * Bit 1 : Supported channel width (0: 20MHz, 1: Both 20 and 40 MHz)
36 * Bit 4 : Greenfield support (0: Not supported, 1: Supported)
37 * Bit 5 : Short GI for 20 MHz support (0: Not supported, 1: Supported)
38 * Bit 6 : Short GI for 40 MHz support (0: Not supported, 1: Supported)
39 * Bit 7 : Tx STBC (0: Not supported, 1: Supported)
40 * Bit 8-9 : Rx STBC (0: Not supported, X: Support for up to X spatial streams)
41 * Bit 10 : Delayed BA support (0: Not supported, 1: Supported)
42 * Bit 11 : Maximum AMSDU length (0: 3839 octets, 1: 7935 octets)
43 * Bit 14 : 40-Mhz intolerant support (0: Not supported, 1: Supported)
44 *
45 * In addition, the following AMPDU Parameters are set -
46 * - Maximum AMPDU length exponent (set to 3)
47 * - Minimum AMPDU start spacing (set to 0 - No restrictions)
48 *
49 * MCS is set for 1x1, with MSC32 for infra mode or ad-hoc mode with 40 MHz
50 * support.
51 *
52 * RD responder bit to set to clear in the extended capability header.
53 */
54void
55mwifiex_fill_cap_info(struct mwifiex_private *priv,
56 struct mwifiex_ie_types_htcap *ht_cap)
57{
58 struct mwifiex_adapter *adapter = priv->adapter;
59 u8 *mcs;
60 int rx_mcs_supp;
61 uint16_t ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info);
62 uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info);
63
64 /* Convert dev_cap to IEEE80211_HT_CAP */
65 if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
66 ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
67 else
68 ht_cap_info &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
69
70 if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap))
71 ht_cap_info |= IEEE80211_HT_CAP_SGI_20;
72 else
73 ht_cap_info &= ~IEEE80211_HT_CAP_SGI_20;
74
75 if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap))
76 ht_cap_info |= IEEE80211_HT_CAP_SGI_40;
77 else
78 ht_cap_info &= ~IEEE80211_HT_CAP_SGI_40;
79
80 if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
81 ht_cap_info |= IEEE80211_HT_CAP_TX_STBC;
82 else
83 ht_cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
84
85 if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap))
86 ht_cap_info |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
87 else
88 ht_cap_info &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
89
90 if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap))
91 ht_cap_info |= IEEE80211_HT_CAP_GRN_FLD;
92 else
93 ht_cap_info &= ~IEEE80211_HT_CAP_GRN_FLD;
94
95 ht_cap_info &= ~IEEE80211_HT_CAP_MAX_AMSDU;
96 ht_cap_info |= IEEE80211_HT_CAP_SM_PS;
97
98 ht_cap->ht_cap.ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR;
99 ht_cap->ht_cap.ampdu_params_info &= ~IEEE80211_HT_AMPDU_PARM_DENSITY;
100
101 rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support);
102
103 mcs = (u8 *)&ht_cap->ht_cap.mcs;
104
105 /* Set MCS for 1x1 */
106 memset(mcs, 0xff, rx_mcs_supp);
107
108 /* Clear all the other values */
109 memset(&mcs[rx_mcs_supp], 0,
110 sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
111
112 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
113 (ht_cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
114 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
115 SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
116
117 /* Clear RD responder bit */
118 RESETHT_EXTCAP_RDG(ht_ext_cap);
119
120 ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info);
121 ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap);
122}
123
124/*
125 * This function returns the pointer to an entry in BA Stream
126 * table which matches the requested BA status.
127 */
128static struct mwifiex_tx_ba_stream_tbl *
129mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
130 enum mwifiex_ba_status ba_status)
131{
132 struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
133 unsigned long flags;
134
135 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
136 list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
137 if (tx_ba_tsr_tbl->ba_status == ba_status) {
138 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
139 flags);
140 return tx_ba_tsr_tbl;
141 }
142 }
143 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
144 return NULL;
145}
146
147/*
148 * This function handles the command response of delete a block
149 * ack request.
150 *
151 * The function checks the response success status and takes action
152 * accordingly (send an add BA request in case of success, or recreate
153 * the deleted stream in case of failure, if the add BA was also
154 * initiated by us).
155 */
156int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
157 struct host_cmd_ds_command *resp)
158{
159 int tid;
160 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
161 struct host_cmd_ds_11n_delba *del_ba =
162 (struct host_cmd_ds_11n_delba *) &resp->params.del_ba;
163 uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set);
164
165 tid = del_ba_param_set >> DELBA_TID_POS;
166 if (del_ba->del_result == BA_RESULT_SUCCESS) {
167 mwifiex_11n_delete_ba_stream_tbl(priv, tid,
168 del_ba->peer_mac_addr, TYPE_DELBA_SENT,
169 INITIATOR_BIT(del_ba_param_set));
170
171 tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
172 BA_STREAM_SETUP_INPROGRESS);
173 if (tx_ba_tbl)
174 mwifiex_send_addba(priv, tx_ba_tbl->tid,
175 tx_ba_tbl->ra);
176 } else { /*
177 * In case of failure, recreate the deleted stream in case
178 * we initiated the ADDBA
179 */
180 if (INITIATOR_BIT(del_ba_param_set)) {
181 mwifiex_11n_create_tx_ba_stream_tbl(priv,
182 del_ba->peer_mac_addr, tid,
183 BA_STREAM_SETUP_INPROGRESS);
184
185 tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
186 BA_STREAM_SETUP_INPROGRESS);
187 if (tx_ba_tbl)
188 mwifiex_11n_delete_ba_stream_tbl(priv,
189 tx_ba_tbl->tid, tx_ba_tbl->ra,
190 TYPE_DELBA_SENT, true);
191 }
192 }
193
194 return 0;
195}
196
197/*
198 * This function handles the command response of add a block
199 * ack request.
200 *
201 * Handling includes changing the header fields to CPU formats, checking
202 * the response success status and taking actions accordingly (delete the
203 * BA stream table in case of failure).
204 */
205int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
206 struct host_cmd_ds_command *resp)
207{
208 int tid;
209 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
210 (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp;
211 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
212
213 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
214 & SSN_MASK);
215
216 tid = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
217 & IEEE80211_ADDBA_PARAM_TID_MASK)
218 >> BLOCKACKPARAM_TID_POS;
219 if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
220 tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid,
221 add_ba_rsp->peer_mac_addr);
222 if (tx_ba_tbl) {
223 dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
224 tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
225 } else {
226 dev_err(priv->adapter->dev, "BA stream not created\n");
227 }
228 } else {
229 mwifiex_11n_delete_ba_stream_tbl(priv, tid,
230 add_ba_rsp->peer_mac_addr,
231 TYPE_DELBA_SENT, true);
232 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
233 priv->aggr_prio_tbl[tid].ampdu_ap =
234 BA_STREAM_NOT_ALLOWED;
235 }
236
237 return 0;
238}
239
240/*
241 * This function handles the command response of 11n configuration request.
242 *
243 * Handling includes changing the header fields into CPU format.
244 */
245int mwifiex_ret_11n_cfg(struct mwifiex_private *priv,
246 struct host_cmd_ds_command *resp,
247 void *data_buf)
248{
249 struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL;
250 struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
251
252 if (data_buf) {
253 tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf;
254 tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap);
255 tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info);
256 }
257 return 0;
258}
259
260/*
261 * This function prepares command of reconfigure Tx buffer.
262 *
263 * Preparation includes -
264 * - Setting command ID, action and proper size
265 * - Setting Tx buffer size (for SET only)
266 * - Ensuring correct endian-ness
267 */
268int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
269 struct host_cmd_ds_command *cmd, int cmd_action,
270 void *data_buf)
271{
272 struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf;
273 u16 action = (u16) cmd_action;
274 u16 buf_size = *((u16 *) data_buf);
275
276 cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
277 cmd->size =
278 cpu_to_le16(sizeof(struct host_cmd_ds_txbuf_cfg) + S_DS_GEN);
279 tx_buf->action = cpu_to_le16(action);
280 switch (action) {
281 case HostCmd_ACT_GEN_SET:
282 dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size);
283 tx_buf->buff_size = cpu_to_le16(buf_size);
284 break;
285 case HostCmd_ACT_GEN_GET:
286 default:
287 tx_buf->buff_size = 0;
288 break;
289 }
290 return 0;
291}
292
293/*
294 * This function prepares command of AMSDU aggregation control.
295 *
296 * Preparation includes -
297 * - Setting command ID, action and proper size
298 * - Setting AMSDU control parameters (for SET only)
299 * - Ensuring correct endian-ness
300 */
301int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv,
302 struct host_cmd_ds_command *cmd,
303 int cmd_action, void *data_buf)
304{
305 struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
306 &cmd->params.amsdu_aggr_ctrl;
307 u16 action = (u16) cmd_action;
308 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl =
309 (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
310
311 cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
312 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl)
313 + S_DS_GEN);
314 amsdu_ctrl->action = cpu_to_le16(action);
315 switch (action) {
316 case HostCmd_ACT_GEN_SET:
317 amsdu_ctrl->enable = cpu_to_le16(aa_ctrl->enable);
318 amsdu_ctrl->curr_buf_size = 0;
319 break;
320 case HostCmd_ACT_GEN_GET:
321 default:
322 amsdu_ctrl->curr_buf_size = 0;
323 break;
324 }
325 return 0;
326}
327
328/*
329 * This function handles the command response of AMSDU aggregation
330 * control request.
331 *
332 * Handling includes changing the header fields into CPU format.
333 */
334int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv,
335 struct host_cmd_ds_command *resp,
336 void *data_buf)
337{
338 struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL;
339 struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
340 &resp->params.amsdu_aggr_ctrl;
341
342 if (data_buf) {
343 amsdu_aggr_ctrl =
344 (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
345 amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable);
346 amsdu_aggr_ctrl->curr_buf_size =
347 le16_to_cpu(amsdu_ctrl->curr_buf_size);
348 }
349 return 0;
350}
351
352/*
353 * This function prepares 11n configuration command.
354 *
355 * Preparation includes -
356 * - Setting command ID, action and proper size
357 * - Setting HT Tx capability and HT Tx information fields
358 * - Ensuring correct endian-ness
359 */
360int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
361 struct host_cmd_ds_command *cmd,
362 u16 cmd_action, void *data_buf)
363{
364 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
365 struct mwifiex_ds_11n_tx_cfg *txcfg =
366 (struct mwifiex_ds_11n_tx_cfg *) data_buf;
367
368 cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG);
369 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN);
370 htcfg->action = cpu_to_le16(cmd_action);
371 htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
372 htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
373 return 0;
374}
375
376/*
377 * This function appends an 11n TLV to a buffer.
378 *
379 * Buffer allocation is responsibility of the calling
380 * function. No size validation is made here.
381 *
382 * The function fills up the following sections, if applicable -
383 * - HT capability IE
384 * - HT information IE (with channel list)
385 * - 20/40 BSS Coexistence IE
386 * - HT Extended Capabilities IE
387 */
388int
389mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
390 struct mwifiex_bssdescriptor *bss_desc,
391 u8 **buffer)
392{
393 struct mwifiex_ie_types_htcap *ht_cap;
394 struct mwifiex_ie_types_htinfo *ht_info;
395 struct mwifiex_ie_types_chan_list_param_set *chan_list;
396 struct mwifiex_ie_types_2040bssco *bss_co_2040;
397 struct mwifiex_ie_types_extcap *ext_cap;
398 int ret_len = 0;
399
400 if (!buffer || !*buffer)
401 return ret_len;
402
403 if (bss_desc->bcn_ht_cap) {
404 ht_cap = (struct mwifiex_ie_types_htcap *) *buffer;
405 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
406 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
407 ht_cap->header.len =
408 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
409 memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header),
410 (u8 *) bss_desc->bcn_ht_cap +
411 sizeof(struct ieee_types_header),
412 le16_to_cpu(ht_cap->header.len));
413
414 mwifiex_fill_cap_info(priv, ht_cap);
415
416 *buffer += sizeof(struct mwifiex_ie_types_htcap);
417 ret_len += sizeof(struct mwifiex_ie_types_htcap);
418 }
419
420 if (bss_desc->bcn_ht_info) {
421 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
422 ht_info = (struct mwifiex_ie_types_htinfo *) *buffer;
423 memset(ht_info, 0,
424 sizeof(struct mwifiex_ie_types_htinfo));
425 ht_info->header.type =
426 cpu_to_le16(WLAN_EID_HT_INFORMATION);
427 ht_info->header.len =
428 cpu_to_le16(sizeof(struct ieee80211_ht_info));
429
430 memcpy((u8 *) ht_info +
431 sizeof(struct mwifiex_ie_types_header),
432 (u8 *) bss_desc->bcn_ht_info +
433 sizeof(struct ieee_types_header),
434 le16_to_cpu(ht_info->header.len));
435
436 if (!ISSUPP_CHANWIDTH40
437 (priv->adapter->hw_dot_11n_dev_cap))
438 ht_info->ht_info.ht_param &=
439 ~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY |
440 IEEE80211_HT_PARAM_CHA_SEC_OFFSET);
441
442 *buffer += sizeof(struct mwifiex_ie_types_htinfo);
443 ret_len += sizeof(struct mwifiex_ie_types_htinfo);
444 }
445
446 chan_list =
447 (struct mwifiex_ie_types_chan_list_param_set *) *buffer;
448 memset(chan_list, 0,
449 sizeof(struct mwifiex_ie_types_chan_list_param_set));
450 chan_list->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
451 chan_list->header.len = cpu_to_le16(
452 sizeof(struct mwifiex_ie_types_chan_list_param_set) -
453 sizeof(struct mwifiex_ie_types_header));
454 chan_list->chan_scan_param[0].chan_number =
455 bss_desc->bcn_ht_info->control_chan;
456 chan_list->chan_scan_param[0].radio_type =
457 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
458
459 if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap)
460 && (bss_desc->bcn_ht_info->ht_param &
461 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
462 SET_SECONDARYCHAN(chan_list->chan_scan_param[0].
463 radio_type,
464 (bss_desc->bcn_ht_info->ht_param &
465 IEEE80211_HT_PARAM_CHA_SEC_OFFSET));
466
467 *buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set);
468 ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set);
469 }
470
471 if (bss_desc->bcn_bss_co_2040) {
472 bss_co_2040 = (struct mwifiex_ie_types_2040bssco *) *buffer;
473 memset(bss_co_2040, 0,
474 sizeof(struct mwifiex_ie_types_2040bssco));
475 bss_co_2040->header.type = cpu_to_le16(WLAN_EID_BSS_COEX_2040);
476 bss_co_2040->header.len =
477 cpu_to_le16(sizeof(bss_co_2040->bss_co_2040));
478
479 memcpy((u8 *) bss_co_2040 +
480 sizeof(struct mwifiex_ie_types_header),
481 (u8 *) bss_desc->bcn_bss_co_2040 +
482 sizeof(struct ieee_types_header),
483 le16_to_cpu(bss_co_2040->header.len));
484
485 *buffer += sizeof(struct mwifiex_ie_types_2040bssco);
486 ret_len += sizeof(struct mwifiex_ie_types_2040bssco);
487 }
488
489 if (bss_desc->bcn_ext_cap) {
490 ext_cap = (struct mwifiex_ie_types_extcap *) *buffer;
491 memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap));
492 ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
493 ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap));
494
495 memcpy((u8 *) ext_cap +
496 sizeof(struct mwifiex_ie_types_header),
497 (u8 *) bss_desc->bcn_ext_cap +
498 sizeof(struct ieee_types_header),
499 le16_to_cpu(ext_cap->header.len));
500
501 *buffer += sizeof(struct mwifiex_ie_types_extcap);
502 ret_len += sizeof(struct mwifiex_ie_types_extcap);
503 }
504
505 return ret_len;
506}
507
508/*
509 * This function reconfigures the Tx buffer size in firmware.
510 *
511 * This function prepares a firmware command and issues it, if
512 * the current Tx buffer size is different from the one requested.
513 * Maximum configurable Tx buffer size is limited by the HT capability
514 * field value.
515 */
516void
517mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
518 struct mwifiex_bssdescriptor *bss_desc)
519{
520 u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K;
521 u16 tx_buf = 0;
522 u16 curr_tx_buf_size = 0;
523
524 if (bss_desc->bcn_ht_cap) {
525 if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) &
526 IEEE80211_HT_CAP_MAX_AMSDU)
527 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_8K;
528 else
529 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_4K;
530 }
531
532 tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu);
533
534 dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n",
535 max_amsdu, priv->adapter->max_tx_buf_size);
536
537 if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K)
538 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
539 else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_4K)
540 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
541 else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K)
542 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K;
543 if (curr_tx_buf_size != tx_buf)
544 mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
545 HostCmd_ACT_GEN_SET, 0,
546 NULL, &tx_buf);
547
548 return;
549}
550
551/*
552 * This function checks if the given pointer is valid entry of
553 * Tx BA Stream table.
554 */
555static int mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
556 struct mwifiex_tx_ba_stream_tbl *tx_tbl_ptr)
557{
558 struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
559
560 list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
561 if (tx_ba_tsr_tbl == tx_tbl_ptr)
562 return true;
563 }
564
565 return false;
566}
567
568/*
569 * This function deletes the given entry in Tx BA Stream table.
570 *
571 * The function also performs a validity check on the supplied
572 * pointer before trying to delete.
573 */
574void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
575 struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
576{
577 if (!tx_ba_tsr_tbl &&
578 mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
579 return;
580
581 dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl);
582
583 list_del(&tx_ba_tsr_tbl->list);
584
585 kfree(tx_ba_tsr_tbl);
586
587 return;
588}
589
590/*
591 * This function deletes all the entries in Tx BA Stream table.
592 */
593void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
594{
595 int i;
596 struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr, *tmp_node;
597 unsigned long flags;
598
599 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
600 list_for_each_entry_safe(del_tbl_ptr, tmp_node,
601 &priv->tx_ba_stream_tbl_ptr, list)
602 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr);
603 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
604
605 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
606
607 for (i = 0; i < MAX_NUM_TID; ++i)
608 priv->aggr_prio_tbl[i].ampdu_ap =
609 priv->aggr_prio_tbl[i].ampdu_user;
610}
611
612/*
613 * This function returns the pointer to an entry in BA Stream
614 * table which matches the given RA/TID pair.
615 */
616struct mwifiex_tx_ba_stream_tbl *
617mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
618 int tid, u8 *ra)
619{
620 struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
621 unsigned long flags;
622
623 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
624 list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
625 if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN))
626 && (tx_ba_tsr_tbl->tid == tid)) {
627 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
628 flags);
629 return tx_ba_tsr_tbl;
630 }
631 }
632 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
633 return NULL;
634}
635
636/*
637 * This function creates an entry in Tx BA stream table for the
638 * given RA/TID pair.
639 */
640void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
641 u8 *ra, int tid,
642 enum mwifiex_ba_status ba_status)
643{
644 struct mwifiex_tx_ba_stream_tbl *new_node;
645 unsigned long flags;
646
647 if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) {
648 new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
649 GFP_ATOMIC);
650 if (!new_node) {
651 dev_err(priv->adapter->dev,
652 "%s: failed to alloc new_node\n", __func__);
653 return;
654 }
655
656 INIT_LIST_HEAD(&new_node->list);
657
658 new_node->tid = tid;
659 new_node->ba_status = ba_status;
660 memcpy(new_node->ra, ra, ETH_ALEN);
661
662 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
663 list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr);
664 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
665 }
666
667 return;
668}
669
670/*
671 * This function sends an add BA request to the given TID/RA pair.
672 */
673int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
674{
675 struct host_cmd_ds_11n_addba_req add_ba_req;
676 static u8 dialog_tok;
677 int ret;
678
679 dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid);
680
681 add_ba_req.block_ack_param_set = cpu_to_le16(
682 (u16) ((tid << BLOCKACKPARAM_TID_POS) |
683 (priv->add_ba_param.
684 tx_win_size << BLOCKACKPARAM_WINSIZE_POS) |
685 IMMEDIATE_BLOCK_ACK));
686 add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout);
687
688 ++dialog_tok;
689
690 if (dialog_tok == 0)
691 dialog_tok = 1;
692
693 add_ba_req.dialog_token = dialog_tok;
694 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
695
696 /* We don't wait for the response of this command */
697 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ,
698 0, 0, NULL, &add_ba_req);
699
700 return ret;
701}
702
703/*
704 * This function sends a delete BA request to the given TID/RA pair.
705 */
706int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
707 int initiator)
708{
709 struct host_cmd_ds_11n_delba delba;
710 int ret;
711 uint16_t del_ba_param_set;
712
713 memset(&delba, 0, sizeof(delba));
714 delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS);
715
716 del_ba_param_set = le16_to_cpu(delba.del_ba_param_set);
717 if (initiator)
718 del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK;
719 else
720 del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK;
721
722 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
723
724 /* We don't wait for the response of this command */
725 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA,
726 HostCmd_ACT_GEN_SET, 0, NULL, &delba);
727
728 return ret;
729}
730
731/*
732 * This function handles the command response of a delete BA request.
733 */
734void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
735{
736 struct host_cmd_ds_11n_delba *cmd_del_ba =
737 (struct host_cmd_ds_11n_delba *) del_ba;
738 uint16_t del_ba_param_set = le16_to_cpu(cmd_del_ba->del_ba_param_set);
739 int tid;
740
741 tid = del_ba_param_set >> DELBA_TID_POS;
742
743 mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
744 TYPE_DELBA_RECEIVE,
745 INITIATOR_BIT(del_ba_param_set));
746}
747
748/*
749 * This function retrieves the Rx reordering table.
750 */
751int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
752 struct mwifiex_ds_rx_reorder_tbl *buf)
753{
754 int i;
755 struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf;
756 struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr;
757 int count = 0;
758 unsigned long flags;
759
760 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
761 list_for_each_entry(rx_reorder_tbl_ptr, &priv->rx_reorder_tbl_ptr,
762 list) {
763 rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid;
764 memcpy(rx_reo_tbl->ta, rx_reorder_tbl_ptr->ta, ETH_ALEN);
765 rx_reo_tbl->start_win = rx_reorder_tbl_ptr->start_win;
766 rx_reo_tbl->win_size = rx_reorder_tbl_ptr->win_size;
767 for (i = 0; i < rx_reorder_tbl_ptr->win_size; ++i) {
768 if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
769 rx_reo_tbl->buffer[i] = true;
770 else
771 rx_reo_tbl->buffer[i] = false;
772 }
773 rx_reo_tbl++;
774 count++;
775
776 if (count >= MWIFIEX_MAX_RX_BASTREAM_SUPPORTED)
777 break;
778 }
779 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
780
781 return count;
782}
783
784/*
785 * This function retrieves the Tx BA stream table.
786 */
787int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
788 struct mwifiex_ds_tx_ba_stream_tbl *buf)
789{
790 struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
791 struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf;
792 int count = 0;
793 unsigned long flags;
794
795 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
796 list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
797 rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
798 dev_dbg(priv->adapter->dev, "data: %s tid=%d\n",
799 __func__, rx_reo_tbl->tid);
800 memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
801 rx_reo_tbl++;
802 count++;
803 if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED)
804 break;
805 }
806 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
807
808 return count;
809}
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
new file mode 100644
index 000000000000..71a853e61b61
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -0,0 +1,176 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11n
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_11N_H_
21#define _MWIFIEX_11N_H_
22
23#include "11n_aggr.h"
24#include "11n_rxreorder.h"
25#include "wmm.h"
26
27int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
28 struct host_cmd_ds_command *resp);
29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
30 struct host_cmd_ds_command *resp);
31int mwifiex_ret_11n_cfg(struct mwifiex_private *priv,
32 struct host_cmd_ds_command *resp,
33 void *data_buf);
34int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
35 struct host_cmd_ds_command *cmd,
36 u16 cmd_action, void *data_buf);
37
38int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
39 struct host_cmd_ds_command *cmd,
40 u16 cmd_action, void *data_buf);
41
42int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
43 struct mwifiex_bssdescriptor *bss_desc,
44 u8 **buffer);
45void mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
46 struct mwifiex_bssdescriptor *bss_desc);
47void mwifiex_fill_cap_info(struct mwifiex_private *,
48 struct mwifiex_ie_types_htcap *);
49int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
50 u16 action, int *htcap_cfg);
51void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
52 struct mwifiex_tx_ba_stream_tbl
53 *tx_tbl);
54void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
55struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct
56 mwifiex_private
57 *priv, int tid,
58 u8 *ra);
59void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra,
60 int tid,
61 enum mwifiex_ba_status ba_status);
62int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
63int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
64 int initiator);
65void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba);
66int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
67 struct mwifiex_ds_rx_reorder_tbl *buf);
68int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
69 struct mwifiex_ds_tx_ba_stream_tbl *buf);
70int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv,
71 struct host_cmd_ds_command
72 *resp,
73 void *data_buf);
74int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
75 struct host_cmd_ds_command *cmd,
76 int cmd_action, void *data_buf);
77int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv,
78 struct host_cmd_ds_command *cmd,
79 int cmd_action,
80 void *data_buf);
81
82/*
83 * This function checks whether AMPDU is allowed or not for a particular TID.
84 */
85static inline u8
86mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
87 struct mwifiex_ra_list_tbl *ptr, int tid)
88{
89 return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED)
90 ? true : false);
91}
92
93/*
94 * This function checks whether AMSDU is allowed or not for a particular TID.
95 */
96static inline u8
97mwifiex_is_amsdu_allowed(struct mwifiex_private *priv,
98 struct mwifiex_ra_list_tbl *ptr, int tid)
99{
100 return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
101 && ((priv->is_data_rate_auto)
102 || !((priv->bitmap_rates[2]) & 0x03)))
103 ? true : false);
104}
105
106/*
107 * This function checks whether a BA stream is available or not.
108 */
109static inline u8
110mwifiex_is_ba_stream_avail(struct mwifiex_private *priv)
111{
112 struct mwifiex_private *pmpriv = NULL;
113 u8 i = 0;
114 u32 ba_stream_num = 0;
115
116 for (i = 0; i < priv->adapter->priv_num; i++) {
117 pmpriv = priv->adapter->priv[i];
118 if (pmpriv)
119 ba_stream_num +=
120 mwifiex_wmm_list_len(priv->adapter,
121 (struct list_head
122 *) &pmpriv->
123 tx_ba_stream_tbl_ptr);
124 }
125
126 return ((ba_stream_num <
127 MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) ? true : false);
128}
129
130/*
131 * This function finds the correct Tx BA stream to delete.
132 *
133 * Upon successfully locating, both the TID and the RA are returned.
134 */
135static inline u8
136mwifiex_find_stream_to_delete(struct mwifiex_private *priv,
137 struct mwifiex_ra_list_tbl *ptr, int ptr_tid,
138 int *ptid, u8 *ra)
139{
140 int tid;
141 u8 ret = false;
142 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
143 unsigned long flags;
144
145 tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
146
147 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
148 list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
149 if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) {
150 tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user;
151 *ptid = tx_tbl->tid;
152 memcpy(ra, tx_tbl->ra, ETH_ALEN);
153 ret = true;
154 }
155 }
156 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
157
158 return ret;
159}
160
161/*
162 * This function checks whether BA stream is set up or not.
163 */
164static inline int
165mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
166 struct mwifiex_ra_list_tbl *ptr, int tid)
167{
168 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
169
170 tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra);
171 if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
172 return true;
173
174 return false;
175}
176#endif /* !_MWIFIEX_11N_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
new file mode 100644
index 000000000000..c2abced66957
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -0,0 +1,423 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11n Aggregation
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27#include "11n_aggr.h"
28
29/*
30 * Creates an AMSDU subframe for aggregation into one AMSDU packet.
31 *
32 * The resultant AMSDU subframe format is -
33 *
34 * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+
35 * | DA | SA | Length | SNAP header | MSDU |
36 * | data[0..5] | data[6..11] | | | data[14..] |
37 * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+
38 * <--6-bytes--> <--6-bytes--> <--2-bytes--><--8-bytes--> <--n-bytes-->
39 *
40 * This function also computes the amount of padding required to make the
41 * buffer length multiple of 4 bytes.
42 *
43 * Data => |DA|SA|SNAP-TYPE|........ .|
44 * MSDU => |DA|SA|Length|SNAP|...... ..|
45 */
46static int
47mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter,
48 struct sk_buff *skb_aggr,
49 struct sk_buff *skb_src, int *pad)
50
51{
52 int dt_offset;
53 struct rfc_1042_hdr snap = {
54 0xaa, /* LLC DSAP */
55 0xaa, /* LLC SSAP */
56 0x03, /* LLC CTRL */
57 {0x00, 0x00, 0x00}, /* SNAP OUI */
58 0x0000 /* SNAP type */
59 /*
60 * This field will be overwritten
61 * later with ethertype
62 */
63 };
64 struct tx_packet_hdr *tx_header = NULL;
65
66 skb_put(skb_aggr, sizeof(*tx_header));
67
68 tx_header = (struct tx_packet_hdr *) skb_aggr->data;
69
70 /* Copy DA and SA */
71 dt_offset = 2 * ETH_ALEN;
72 memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset);
73
74 /* Copy SNAP header */
75 snap.snap_type = *(u16 *) ((u8 *)skb_src->data + dt_offset);
76 dt_offset += sizeof(u16);
77
78 memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr));
79
80 skb_pull(skb_src, dt_offset);
81
82 /* Update Length field */
83 tx_header->eth803_hdr.h_proto = htons(skb_src->len + LLC_SNAP_LEN);
84
85 /* Add payload */
86 skb_put(skb_aggr, skb_src->len);
87 memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data,
88 skb_src->len);
89 *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len +
90 LLC_SNAP_LEN)) & 3)) : 0;
91 skb_put(skb_aggr, *pad);
92
93 return skb_aggr->len + *pad;
94}
95
96/*
97 * Adds TxPD to AMSDU header.
98 *
99 * Each AMSDU packet will contain one TxPD at the beginning,
100 * followed by multiple AMSDU subframes.
101 */
102static void
103mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
104 struct sk_buff *skb)
105{
106 struct txpd *local_tx_pd;
107
108 skb_push(skb, sizeof(*local_tx_pd));
109
110 local_tx_pd = (struct txpd *) skb->data;
111 memset(local_tx_pd, 0, sizeof(struct txpd));
112
113 /* Original priority has been overwritten */
114 local_tx_pd->priority = (u8) skb->priority;
115 local_tx_pd->pkt_delay_2ms =
116 mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
117 local_tx_pd->bss_num = priv->bss_num;
118 local_tx_pd->bss_type = priv->bss_type;
119 /* Always zero as the data is followed by struct txpd */
120 local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
121 local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
122 local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
123 sizeof(*local_tx_pd));
124
125 if (local_tx_pd->tx_control == 0)
126 /* TxCtrl set by user or default */
127 local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
128
129 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
130 (priv->adapter->pps_uapsd_mode)) {
131 if (true == mwifiex_check_last_packet_indication(priv)) {
132 priv->adapter->tx_lock_flag = true;
133 local_tx_pd->flags =
134 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET;
135 }
136 }
137}
138
139/*
140 * Counts the number of subframes in an aggregate packet.
141 *
142 * This function parses an aggregate packet buffer, looking for
143 * subframes and counting the number of such subframe found. The
144 * function automatically skips the DA/SA fields at the beginning
145 * of each subframe and padding at the end.
146 */
147static int
148mwifiex_11n_get_num_aggr_pkts(u8 *data, int total_pkt_len)
149{
150 int pkt_count = 0, pkt_len, pad;
151
152 while (total_pkt_len > 0) {
153 /* Length will be in network format, change it to host */
154 pkt_len = ntohs((*(__be16 *)(data + 2 * ETH_ALEN)));
155 pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ?
156 (4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0;
157 data += pkt_len + pad + sizeof(struct ethhdr);
158 total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr);
159 ++pkt_count;
160 }
161
162 return pkt_count;
163}
164
165/*
166 * De-aggregate received packets.
167 *
168 * This function parses the received aggregate buffer, extracts each subframe,
169 * strips off the SNAP header from them and sends the data portion for further
170 * processing.
171 *
172 * Each subframe body is copied onto a separate buffer, which are freed by
173 * upper layer after processing. The function also performs sanity tests on
174 * the received buffer.
175 */
176int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
177 struct sk_buff *skb)
178{
179 u16 pkt_len;
180 int total_pkt_len;
181 u8 *data;
182 int pad;
183 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
184 struct rxpd *local_rx_pd = (struct rxpd *) skb->data;
185 struct sk_buff *skb_daggr;
186 struct mwifiex_rxinfo *rx_info_daggr = NULL;
187 int ret = -1;
188 struct rx_packet_hdr *rx_pkt_hdr;
189 struct mwifiex_adapter *adapter = priv->adapter;
190 u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
191
192 data = (u8 *) (local_rx_pd + local_rx_pd->rx_pkt_offset);
193 total_pkt_len = local_rx_pd->rx_pkt_length;
194
195 /* Sanity test */
196 if (total_pkt_len > MWIFIEX_RX_DATA_BUF_SIZE) {
197 dev_err(adapter->dev, "total pkt len greater than buffer"
198 " size %d\n", total_pkt_len);
199 return -1;
200 }
201
202 rx_info->use_count = mwifiex_11n_get_num_aggr_pkts(data, total_pkt_len);
203
204 while (total_pkt_len > 0) {
205 rx_pkt_hdr = (struct rx_packet_hdr *) data;
206 /* Length will be in network format, change it to host */
207 pkt_len = ntohs((*(__be16 *) (data + 2 * ETH_ALEN)));
208 if (pkt_len > total_pkt_len) {
209 dev_err(adapter->dev, "pkt_len %d > total_pkt_len %d\n",
210 total_pkt_len, pkt_len);
211 break;
212 }
213
214 pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ?
215 (4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0;
216
217 total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr);
218
219 if (memcmp(&rx_pkt_hdr->rfc1042_hdr,
220 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
221 memmove(data + LLC_SNAP_LEN, data, 2 * ETH_ALEN);
222 data += LLC_SNAP_LEN;
223 pkt_len += sizeof(struct ethhdr) - LLC_SNAP_LEN;
224 } else {
225 *(u16 *) (data + 2 * ETH_ALEN) = (u16) 0;
226 pkt_len += sizeof(struct ethhdr);
227 }
228
229 skb_daggr = dev_alloc_skb(pkt_len);
230 if (!skb_daggr) {
231 dev_err(adapter->dev, "%s: failed to alloc skb_daggr\n",
232 __func__);
233 return -1;
234 }
235 rx_info_daggr = MWIFIEX_SKB_RXCB(skb_daggr);
236
237 rx_info_daggr->bss_index = rx_info->bss_index;
238 skb_daggr->tstamp = skb->tstamp;
239 rx_info_daggr->parent = skb;
240 skb_daggr->priority = skb->priority;
241 skb_put(skb_daggr, pkt_len);
242 memcpy(skb_daggr->data, data, pkt_len);
243
244 ret = mwifiex_recv_packet(adapter, skb_daggr);
245
246 switch (ret) {
247 case -EINPROGRESS:
248 break;
249 case -1:
250 dev_err(adapter->dev, "deaggr: host_to_card failed\n");
251 case 0:
252 mwifiex_recv_packet_complete(adapter, skb_daggr, ret);
253 break;
254 default:
255 break;
256 }
257
258 data += pkt_len + pad;
259 }
260
261 return ret;
262}
263
264/*
265 * Create aggregated packet.
266 *
267 * This function creates an aggregated MSDU packet, by combining buffers
268 * from the RA list. Each individual buffer is encapsulated as an AMSDU
269 * subframe and all such subframes are concatenated together to form the
270 * AMSDU packet.
271 *
272 * A TxPD is also added to the front of the resultant AMSDU packets for
273 * transmission. The resultant packets format is -
274 *
275 * +---- ~ ----+------ ~ ------+------ ~ ------+-..-+------ ~ ------+
276 * | TxPD |AMSDU sub-frame|AMSDU sub-frame| .. |AMSDU sub-frame|
277 * | | 1 | 2 | .. | n |
278 * +---- ~ ----+------ ~ ------+------ ~ ------+ .. +------ ~ ------+
279 */
280int
281mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
282 struct mwifiex_ra_list_tbl *pra_list, int headroom,
283 int ptrindex, unsigned long ra_list_flags)
284 __releases(&priv->wmm.ra_list_spinlock)
285{
286 struct mwifiex_adapter *adapter = priv->adapter;
287 struct sk_buff *skb_aggr, *skb_src;
288 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
289 int pad = 0;
290 int ret = 0;
291 struct mwifiex_tx_param tx_param;
292 struct txpd *ptx_pd = NULL;
293
294 if (skb_queue_empty(&pra_list->skb_head)) {
295 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
296 ra_list_flags);
297 return 0;
298 }
299 skb_src = skb_peek(&pra_list->skb_head);
300 tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
301 skb_aggr = dev_alloc_skb(adapter->tx_buf_size);
302 if (!skb_aggr) {
303 dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
304 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
305 ra_list_flags);
306 return -1;
307 }
308 skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
309 tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
310
311 tx_info_aggr->bss_index = tx_info_src->bss_index;
312 skb_aggr->priority = skb_src->priority;
313
314 while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len
315 + LLC_SNAP_LEN)
316 <= adapter->tx_buf_size)) {
317
318 if (!skb_queue_empty(&pra_list->skb_head))
319 skb_src = skb_dequeue(&pra_list->skb_head);
320 else
321 skb_src = NULL;
322
323 pra_list->total_pkts_size -= skb_src->len;
324
325 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
326 ra_list_flags);
327 mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad);
328
329 mwifiex_write_data_complete(adapter, skb_src, 0);
330
331 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
332
333 if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
334 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
335 ra_list_flags);
336 return -1;
337 }
338
339 if (!skb_queue_empty(&pra_list->skb_head))
340 skb_src = skb_peek(&pra_list->skb_head);
341 else
342 skb_src = NULL;
343 }
344
345 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
346
347 /* Last AMSDU packet does not need padding */
348 skb_trim(skb_aggr, skb_aggr->len - pad);
349
350 /* Form AMSDU */
351 mwifiex_11n_form_amsdu_txpd(priv, skb_aggr);
352 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
353 ptx_pd = (struct txpd *)skb_aggr->data;
354
355 skb_push(skb_aggr, headroom);
356
357 tx_param.next_pkt_len = ((pra_list->total_pkts_size) ?
358 (((pra_list->total_pkts_size) >
359 adapter->tx_buf_size) ? adapter->
360 tx_buf_size : pra_list->total_pkts_size +
361 LLC_SNAP_LEN + sizeof(struct txpd)) : 0);
362 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
363 skb_aggr->data,
364 skb_aggr->len, &tx_param);
365 switch (ret) {
366 case -EBUSY:
367 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
368 if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
369 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
370 ra_list_flags);
371 mwifiex_write_data_complete(adapter, skb_aggr, -1);
372 return -1;
373 }
374 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
375 (adapter->pps_uapsd_mode) &&
376 (adapter->tx_lock_flag)) {
377 priv->adapter->tx_lock_flag = false;
378 ptx_pd->flags = 0;
379 }
380
381 skb_queue_tail(&pra_list->skb_head, skb_aggr);
382
383 pra_list->total_pkts_size += skb_aggr->len;
384
385 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
386 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
387 ra_list_flags);
388 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
389 break;
390 case -1:
391 adapter->data_sent = false;
392 dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
393 __func__, ret);
394 adapter->dbg.num_tx_host_to_card_failure++;
395 mwifiex_write_data_complete(adapter, skb_aggr, ret);
396 return 0;
397 case -EINPROGRESS:
398 adapter->data_sent = false;
399 break;
400 case 0:
401 mwifiex_write_data_complete(adapter, skb_aggr, ret);
402 break;
403 default:
404 break;
405 }
406 if (ret != -EBUSY) {
407 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
408 if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
409 priv->wmm.packets_out[ptrindex]++;
410 priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
411 }
412 /* Now bss_prio_cur pointer points to next node */
413 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
414 list_first_entry(
415 &adapter->bss_prio_tbl[priv->bss_priority]
416 .bss_prio_cur->list,
417 struct mwifiex_bss_prio_node, list);
418 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
419 ra_list_flags);
420 }
421
422 return 0;
423}
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h
new file mode 100644
index 000000000000..9c6dca7ab02c
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_aggr.h
@@ -0,0 +1,32 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11n Aggregation
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_11N_AGGR_H_
21#define _MWIFIEX_11N_AGGR_H_
22
23#define PKT_TYPE_AMSDU 0xE6
24
25int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
26 struct sk_buff *skb);
27int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
28 struct mwifiex_ra_list_tbl *ptr, int headroom,
29 int ptr_index, unsigned long flags)
30 __releases(&priv->wmm.ra_list_spinlock);
31
32#endif /* !_MWIFIEX_11N_AGGR_H_ */
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
new file mode 100644
index 000000000000..8e94e620e6f4
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -0,0 +1,637 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27#include "11n_rxreorder.h"
28
29/*
30 * This function processes a received packet and forwards
31 * it to the kernel/upper layer.
32 */
33static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload)
34{
35 int ret = 0;
36 struct mwifiex_adapter *adapter = priv->adapter;
37
38 ret = mwifiex_process_rx_packet(adapter, (struct sk_buff *) payload);
39 return ret;
40}
41
42/*
43 * This function dispatches all packets in the Rx reorder table.
44 *
45 * There could be holes in the buffer, which are skipped by the function.
46 * Since the buffer is linear, the function uses rotation to simulate
47 * circular buffer.
48 */
49static int
50mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
51 struct mwifiex_rx_reorder_tbl
52 *rx_reor_tbl_ptr, int start_win)
53{
54 int no_pkt_to_send, i, xchg;
55 void *rx_tmp_ptr = NULL;
56 unsigned long flags;
57
58 no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
59 min((start_win - rx_reor_tbl_ptr->start_win),
60 rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size;
61
62 for (i = 0; i < no_pkt_to_send; ++i) {
63 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
64 rx_tmp_ptr = NULL;
65 if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
66 rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
67 rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
68 }
69 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
70 if (rx_tmp_ptr)
71 mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr);
72 }
73
74 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
75 /*
76 * We don't have a circular buffer, hence use rotation to simulate
77 * circular buffer
78 */
79 xchg = rx_reor_tbl_ptr->win_size - no_pkt_to_send;
80 for (i = 0; i < xchg; ++i) {
81 rx_reor_tbl_ptr->rx_reorder_ptr[i] =
82 rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i];
83 rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL;
84 }
85
86 rx_reor_tbl_ptr->start_win = start_win;
87 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
88
89 return 0;
90}
91
92/*
93 * This function dispatches all packets in the Rx reorder table until
94 * a hole is found.
95 *
96 * The start window is adjusted automatically when a hole is located.
97 * Since the buffer is linear, the function uses rotation to simulate
98 * circular buffer.
99 */
100static int
101mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
102 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
103{
104 int i, j, xchg;
105 void *rx_tmp_ptr = NULL;
106 unsigned long flags;
107
108 for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
109 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
110 if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
111 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
112 break;
113 }
114 rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
115 rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
116 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
117 mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr);
118 }
119
120 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
121 /*
122 * We don't have a circular buffer, hence use rotation to simulate
123 * circular buffer
124 */
125 if (i > 0) {
126 xchg = rx_reor_tbl_ptr->win_size - i;
127 for (j = 0; j < xchg; ++j) {
128 rx_reor_tbl_ptr->rx_reorder_ptr[j] =
129 rx_reor_tbl_ptr->rx_reorder_ptr[i + j];
130 rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL;
131 }
132 }
133 rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)
134 &(MAX_TID_VALUE - 1);
135 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
136 return 0;
137}
138
139/*
140 * This function deletes the Rx reorder table and frees the memory.
141 *
142 * The function stops the associated timer and dispatches all the
143 * pending packets in the Rx reorder table before deletion.
144 */
145static void
146mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
147 struct mwifiex_rx_reorder_tbl
148 *rx_reor_tbl_ptr)
149{
150 unsigned long flags;
151
152 if (!rx_reor_tbl_ptr)
153 return;
154
155 mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
156 (rx_reor_tbl_ptr->start_win +
157 rx_reor_tbl_ptr->win_size)
158 &(MAX_TID_VALUE - 1));
159
160 del_timer(&rx_reor_tbl_ptr->timer_context.timer);
161
162 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
163 list_del(&rx_reor_tbl_ptr->list);
164 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
165
166 kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
167 kfree(rx_reor_tbl_ptr);
168}
169
170/*
171 * This function returns the pointer to an entry in Rx reordering
172 * table which matches the given TA/TID pair.
173 */
174static struct mwifiex_rx_reorder_tbl *
175mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
176{
177 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
178 unsigned long flags;
179
180 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
181 list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
182 if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN))
183 && (rx_reor_tbl_ptr->tid == tid)) {
184 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
185 flags);
186 return rx_reor_tbl_ptr;
187 }
188 }
189 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
190
191 return NULL;
192}
193
194/*
195 * This function finds the last sequence number used in the packets
196 * buffered in Rx reordering table.
197 */
198static int
199mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
200{
201 int i;
202
203 for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i)
204 if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
205 return i;
206
207 return -1;
208}
209
210/*
211 * This function flushes all the packets in Rx reordering table.
212 *
213 * The function checks if any packets are currently buffered in the
214 * table or not. In case there are packets available, it dispatches
215 * them and then dumps the Rx reordering table.
216 */
217static void
218mwifiex_flush_data(unsigned long context)
219{
220 struct reorder_tmr_cnxt *reorder_cnxt =
221 (struct reorder_tmr_cnxt *) context;
222 int start_win;
223
224 start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr);
225 if (start_win >= 0) {
226 dev_dbg(reorder_cnxt->priv->adapter->dev,
227 "info: flush data %d\n", start_win);
228 mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv,
229 reorder_cnxt->ptr,
230 ((reorder_cnxt->ptr->start_win +
231 start_win + 1) & (MAX_TID_VALUE - 1)));
232 }
233}
234
235/*
236 * This function creates an entry in Rx reordering table for the
237 * given TA/TID.
238 *
239 * The function also initializes the entry with sequence number, window
240 * size as well as initializes the timer.
241 *
242 * If the received TA/TID pair is already present, all the packets are
243 * dispatched and the window size is moved until the SSN.
244 */
245static void
246mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
247 int tid, int win_size, int seq_num)
248{
249 int i;
250 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
251 u16 last_seq = 0;
252 unsigned long flags;
253
254 /*
255 * If we get a TID, ta pair which is already present dispatch all the
256 * the packets and move the window size until the ssn
257 */
258 rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
259 if (rx_reor_tbl_ptr) {
260 mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
261 seq_num);
262 return;
263 }
264 /* if !rx_reor_tbl_ptr then create one */
265 new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL);
266 if (!new_node) {
267 dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n",
268 __func__);
269 return;
270 }
271
272 INIT_LIST_HEAD(&new_node->list);
273 new_node->tid = tid;
274 memcpy(new_node->ta, ta, ETH_ALEN);
275 new_node->start_win = seq_num;
276 if (mwifiex_queuing_ra_based(priv))
277 /* TODO for adhoc */
278 dev_dbg(priv->adapter->dev,
279 "info: ADHOC:last_seq=%d start_win=%d\n",
280 last_seq, new_node->start_win);
281 else
282 last_seq = priv->rx_seq[tid];
283
284 if (last_seq >= new_node->start_win)
285 new_node->start_win = last_seq + 1;
286
287 new_node->win_size = win_size;
288
289 new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
290 GFP_KERNEL);
291 if (!new_node->rx_reorder_ptr) {
292 kfree((u8 *) new_node);
293 dev_err(priv->adapter->dev,
294 "%s: failed to alloc reorder_ptr\n", __func__);
295 return;
296 }
297
298 new_node->timer_context.ptr = new_node;
299 new_node->timer_context.priv = priv;
300
301 init_timer(&new_node->timer_context.timer);
302 new_node->timer_context.timer.function = mwifiex_flush_data;
303 new_node->timer_context.timer.data =
304 (unsigned long) &new_node->timer_context;
305
306 for (i = 0; i < win_size; ++i)
307 new_node->rx_reorder_ptr[i] = NULL;
308
309 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
310 list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr);
311 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
312
313 return;
314}
315
316/*
317 * This function prepares command for adding a BA request.
318 *
319 * Preparation includes -
320 * - Setting command ID and proper size
321 * - Setting add BA request buffer
322 * - Ensuring correct endian-ness
323 */
324int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv,
325 struct host_cmd_ds_command *cmd, void *data_buf)
326{
327 struct host_cmd_ds_11n_addba_req *add_ba_req =
328 (struct host_cmd_ds_11n_addba_req *)
329 &cmd->params.add_ba_req;
330
331 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ);
332 cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN);
333 memcpy(add_ba_req, data_buf, sizeof(*add_ba_req));
334
335 return 0;
336}
337
338/*
339 * This function prepares command for adding a BA response.
340 *
341 * Preparation includes -
342 * - Setting command ID and proper size
343 * - Setting add BA response buffer
344 * - Ensuring correct endian-ness
345 */
346int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
347 struct host_cmd_ds_command *cmd,
348 void *data_buf)
349{
350 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
351 (struct host_cmd_ds_11n_addba_rsp *)
352 &cmd->params.add_ba_rsp;
353 struct host_cmd_ds_11n_addba_req *cmd_addba_req =
354 (struct host_cmd_ds_11n_addba_req *) data_buf;
355 u8 tid = 0;
356 int win_size = 0;
357 uint16_t block_ack_param_set;
358
359 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
360 cmd->size = cpu_to_le16(sizeof(*add_ba_rsp) + S_DS_GEN);
361
362 memcpy(add_ba_rsp->peer_mac_addr, cmd_addba_req->peer_mac_addr,
363 ETH_ALEN);
364 add_ba_rsp->dialog_token = cmd_addba_req->dialog_token;
365 add_ba_rsp->block_ack_tmo = cmd_addba_req->block_ack_tmo;
366 add_ba_rsp->ssn = cmd_addba_req->ssn;
367
368 block_ack_param_set = le16_to_cpu(cmd_addba_req->block_ack_param_set);
369 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
370 >> BLOCKACKPARAM_TID_POS;
371 add_ba_rsp->status_code = cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT);
372 block_ack_param_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
373 /* We donot support AMSDU inside AMPDU, hence reset the bit */
374 block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK;
375 block_ack_param_set |= (priv->add_ba_param.rx_win_size <<
376 BLOCKACKPARAM_WINSIZE_POS);
377 add_ba_rsp->block_ack_param_set = cpu_to_le16(block_ack_param_set);
378 win_size = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
379 & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
380 >> BLOCKACKPARAM_WINSIZE_POS;
381 cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set);
382
383 mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr,
384 tid, win_size, le16_to_cpu(cmd_addba_req->ssn));
385 return 0;
386}
387
388/*
389 * This function prepares command for deleting a BA request.
390 *
391 * Preparation includes -
392 * - Setting command ID and proper size
393 * - Setting del BA request buffer
394 * - Ensuring correct endian-ness
395 */
396int mwifiex_cmd_11n_delba(struct mwifiex_private *priv,
397 struct host_cmd_ds_command *cmd, void *data_buf)
398{
399 struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *)
400 &cmd->params.del_ba;
401
402 cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA);
403 cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN);
404 memcpy(del_ba, data_buf, sizeof(*del_ba));
405
406 return 0;
407}
408
409/*
410 * This function identifies if Rx reordering is needed for a received packet.
411 *
412 * In case reordering is required, the function will do the reordering
413 * before sending it to kernel.
414 *
415 * The Rx reorder table is checked first with the received TID/TA pair. If
416 * not found, the received packet is dispatched immediately. But if found,
417 * the packet is reordered and all the packets in the updated Rx reordering
418 * table is dispatched until a hole is found.
419 *
420 * For sequence number less than the starting window, the packet is dropped.
421 */
422int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
423 u16 seq_num, u16 tid,
424 u8 *ta, u8 pkt_type, void *payload)
425{
426 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
427 int start_win, end_win, win_size;
428 int ret = 0;
429 u16 pkt_index = 0;
430
431 rx_reor_tbl_ptr =
432 mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
433 tid, ta);
434 if (!rx_reor_tbl_ptr) {
435 if (pkt_type != PKT_TYPE_BAR)
436 mwifiex_11n_dispatch_pkt(priv, payload);
437 return 0;
438 }
439 start_win = rx_reor_tbl_ptr->start_win;
440 win_size = rx_reor_tbl_ptr->win_size;
441 end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
442 del_timer(&rx_reor_tbl_ptr->timer_context.timer);
443 mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies
444 + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
445
446 /*
447 * If seq_num is less then starting win then ignore and drop the
448 * packet
449 */
450 if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */
451 if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1))
452 && (seq_num < start_win))
453 return -1;
454 } else if ((seq_num < start_win)
455 || (seq_num > (start_win + (TWOPOW11)))) {
456 return -1;
457 }
458
459 /*
460 * If this packet is a BAR we adjust seq_num as
461 * WinStart = seq_num
462 */
463 if (pkt_type == PKT_TYPE_BAR)
464 seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
465
466 if (((end_win < start_win)
467 && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win)))
468 && (seq_num > end_win)) || ((end_win > start_win)
469 && ((seq_num > end_win) || (seq_num < start_win)))) {
470 end_win = seq_num;
471 if (((seq_num - win_size) + 1) >= 0)
472 start_win = (end_win - win_size) + 1;
473 else
474 start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
475 ret = mwifiex_11n_dispatch_pkt_until_start_win(priv,
476 rx_reor_tbl_ptr, start_win);
477
478 if (ret)
479 return ret;
480 }
481
482 if (pkt_type != PKT_TYPE_BAR) {
483 if (seq_num >= start_win)
484 pkt_index = seq_num - start_win;
485 else
486 pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
487
488 if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index])
489 return -1;
490
491 rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload;
492 }
493
494 /*
495 * Dispatch all packets sequentially from start_win until a
496 * hole is found and adjust the start_win appropriately
497 */
498 ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
499
500 return ret;
501}
502
503/*
504 * This function deletes an entry for a given TID/TA pair.
505 *
506 * The TID/TA are taken from del BA event body.
507 */
508void
509mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
510 u8 *peer_mac, u8 type, int initiator)
511{
512 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
513 struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
514 u8 cleanup_rx_reorder_tbl;
515 unsigned long flags;
516
517 if (type == TYPE_DELBA_RECEIVE)
518 cleanup_rx_reorder_tbl = (initiator) ? true : false;
519 else
520 cleanup_rx_reorder_tbl = (initiator) ? false : true;
521
522 dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, "
523 "initiator=%d\n", peer_mac, tid, initiator);
524
525 if (cleanup_rx_reorder_tbl) {
526 rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
527 peer_mac);
528 if (!rx_reor_tbl_ptr) {
529 dev_dbg(priv->adapter->dev,
530 "event: TID, TA not found in table\n");
531 return;
532 }
533 mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr);
534 } else {
535 ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac);
536 if (!ptx_tbl) {
537 dev_dbg(priv->adapter->dev,
538 "event: TID, RA not found in table\n");
539 return;
540 }
541
542 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
543 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl);
544 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
545 }
546}
547
548/*
549 * This function handles the command response of an add BA response.
550 *
551 * Handling includes changing the header fields into CPU format and
552 * creating the stream, provided the add BA is accepted.
553 */
554int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
555 struct host_cmd_ds_command *resp)
556{
557 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
558 (struct host_cmd_ds_11n_addba_rsp *)
559 &resp->params.add_ba_rsp;
560 int tid, win_size;
561 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr = NULL;
562 uint16_t block_ack_param_set;
563
564 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
565
566 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
567 >> BLOCKACKPARAM_TID_POS;
568 /*
569 * Check if we had rejected the ADDBA, if yes then do not create
570 * the stream
571 */
572 if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
573 win_size = (block_ack_param_set &
574 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
575 >> BLOCKACKPARAM_WINSIZE_POS;
576
577 dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM"
578 " tid=%d ssn=%d win_size=%d\n",
579 add_ba_rsp->peer_mac_addr,
580 tid, add_ba_rsp->ssn, win_size);
581 } else {
582 dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n",
583 add_ba_rsp->peer_mac_addr, tid);
584
585 rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv,
586 tid, add_ba_rsp->peer_mac_addr);
587 if (rx_reor_tbl_ptr)
588 mwifiex_11n_delete_rx_reorder_tbl_entry(priv,
589 rx_reor_tbl_ptr);
590 }
591
592 return 0;
593}
594
595/*
596 * This function handles BA stream timeout event by preparing and sending
597 * a command to the firmware.
598 */
599void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
600 struct host_cmd_ds_11n_batimeout *event)
601{
602 struct host_cmd_ds_11n_delba delba;
603
604 memset(&delba, 0, sizeof(struct host_cmd_ds_11n_delba));
605 memcpy(delba.peer_mac_addr, event->peer_mac_addr, ETH_ALEN);
606
607 delba.del_ba_param_set |=
608 cpu_to_le16((u16) event->tid << DELBA_TID_POS);
609 delba.del_ba_param_set |= cpu_to_le16(
610 (u16) event->origninator << DELBA_INITIATOR_POS);
611 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
612 mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba);
613
614 return;
615}
616
617/*
618 * This function cleans up the Rx reorder table by deleting all the entries
619 * and re-initializing.
620 */
621void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
622{
623 struct mwifiex_rx_reorder_tbl *del_tbl_ptr, *tmp_node;
624 unsigned long flags;
625
626 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
627 list_for_each_entry_safe(del_tbl_ptr, tmp_node,
628 &priv->rx_reorder_tbl_ptr, list) {
629 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
630 mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
631 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
632 }
633 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
634
635 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
636 memset(priv->rx_seq, 0, sizeof(priv->rx_seq));
637}
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
new file mode 100644
index 000000000000..42f569035745
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -0,0 +1,67 @@
1/*
2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_11N_RXREORDER_H_
21#define _MWIFIEX_11N_RXREORDER_H_
22
23#define MIN_FLUSH_TIMER_MS 50
24
25#define PKT_TYPE_BAR 0xE7
26#define MAX_TID_VALUE (2 << 11)
27#define TWOPOW11 (2 << 10)
28
29#define BLOCKACKPARAM_TID_POS 2
30#define BLOCKACKPARAM_AMSDU_SUPP_MASK 0x1
31#define BLOCKACKPARAM_WINSIZE_POS 6
32#define DELBA_TID_POS 12
33#define DELBA_INITIATOR_POS 11
34#define TYPE_DELBA_SENT 1
35#define TYPE_DELBA_RECEIVE 2
36#define IMMEDIATE_BLOCK_ACK 0x2
37
38#define ADDBA_RSP_STATUS_ACCEPT 0
39
40int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
41 u16 seqNum,
42 u16 tid, u8 *ta,
43 u8 pkttype, void *payload);
44void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid,
45 u8 *PeerMACAddr, u8 type,
46 int initiator);
47void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
48 struct host_cmd_ds_11n_batimeout *event);
49int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
50 struct host_cmd_ds_command
51 *resp);
52int mwifiex_cmd_11n_delba(struct mwifiex_private *priv,
53 struct host_cmd_ds_command *cmd,
54 void *data_buf);
55int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
56 struct host_cmd_ds_command
57 *cmd, void *data_buf);
58int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv,
59 struct host_cmd_ds_command *cmd,
60 void *data_buf);
61void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv);
62struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
63 mwifiex_private
64 *priv, int tid,
65 u8 *ta);
66
67#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
new file mode 100644
index 000000000000..86962920cef3
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -0,0 +1,21 @@
1config MWIFIEX
2 tristate "Marvell WiFi-Ex Driver"
3 depends on CFG80211
4 select LIB80211
5 ---help---
6 This adds support for wireless adapters based on Marvell
7 802.11n chipsets.
8
9 If you choose to build it as a module, it will be called
10 mwifiex.
11
12config MWIFIEX_SDIO
13 tristate "Marvell WiFi-Ex Driver for SD8787"
14 depends on MWIFIEX && MMC
15 select FW_LOADER
16 ---help---
17 This adds support for wireless adapters based on Marvell
18 8787 chipset with SDIO interface.
19
20 If you choose to build it as a module, it will be called
21 mwifiex_sdio.
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
new file mode 100644
index 000000000000..42cb733ea33a
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -0,0 +1,41 @@
1#
2# Copyright (C) 2011, Marvell International Ltd.
3#
4# This software file (the "File") is distributed by Marvell International
5# Ltd. under the terms of the GNU General Public License Version 2, June 1991
6# (the "License"). You may use, redistribute and/or modify this File in
7# accordance with the terms and conditions of the License, a copy of which
8# is available by writing to the Free Software Foundation, Inc.,
9# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
10# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
11#
12# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
13# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
14# ARE EXPRESSLY DISCLAIMED. The License provides additional details about
15# this warranty disclaimer.
16
17
18mwifiex-y += main.o
19mwifiex-y += init.o
20mwifiex-y += cfp.o
21mwifiex-y += cmdevt.o
22mwifiex-y += util.o
23mwifiex-y += txrx.o
24mwifiex-y += wmm.o
25mwifiex-y += 11n.o
26mwifiex-y += 11n_aggr.o
27mwifiex-y += 11n_rxreorder.o
28mwifiex-y += scan.o
29mwifiex-y += join.o
30mwifiex-y += sta_ioctl.o
31mwifiex-y += sta_cmd.o
32mwifiex-y += sta_cmdresp.o
33mwifiex-y += sta_event.o
34mwifiex-y += sta_tx.o
35mwifiex-y += sta_rx.o
36mwifiex-y += cfg80211.o
37mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
38obj-$(CONFIG_MWIFIEX) += mwifiex.o
39
40mwifiex_sdio-y += sdio.o
41obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
new file mode 100644
index 000000000000..338377f7093b
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/README
@@ -0,0 +1,204 @@
1# Copyright (C) 2011, Marvell International Ltd.
2#
3# This software file (the "File") is distributed by Marvell International
4# Ltd. under the terms of the GNU General Public License Version 2, June 1991
5# (the "License"). You may use, redistribute and/or modify this File in
6# accordance with the terms and conditions of the License, a copy of which
7# is available by writing to the Free Software Foundation, Inc.,
8# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
9# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
10#
11# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
12# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
13# ARE EXPRESSLY DISCLAIMED. The License provides additional details about
14# this warranty disclaimer.
15
16
17===============================================================================
18 U S E R M A N U A L
19
201) FOR DRIVER INSTALL
21
22 a) Copy sd8787.bin to /lib/firmware/mrvl/ directory,
23 create the directory if it doesn't exist.
24 b) Install WLAN driver,
25 insmod mwifiex.ko
26 c) Uninstall WLAN driver,
27 ifconfig mlanX down
28 rmmod mwifiex
29
30
312) FOR DRIVER CONFIGURATION AND INFO
32 The configurations can be done either using the 'iw' user space
33 utility or debugfs.
34
35 a) 'iw' utility commands
36
37 Following are some useful iw commands:-
38
39iw dev mlan0 scan
40
41 This command will trigger a scan.
42 The command will then display the scan table entries
43
44iw dev mlan0 connect -w <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1123456789a]
45 The above command can be used to connect to an AP with a particular SSID.
46 Ap's operating frequency can be specified or even the bssid. If the AP is using
47 WEP encryption, wep keys can be specified in the command.
48 Note: Every time before connecting to an AP scan command (iw dev mlan0 scan) should be used by user.
49
50iw dev mlan0 disconnect
51 This command will be used to disconnect from an AP.
52
53
54iw dev mlan0 ibss join <SSID> <freq in MHz> [fixed-freq] [fixed-bssid] [key 0:abcde]
55 The command will be used to join or create an ibss. Optionally, operating frequency,
56 bssid and the security related parameters can be specified while joining/creating
57 and ibss.
58
59iw dev mlan0 ibss leave
60 The command will be used to leave an ibss network.
61
62iw dev mlan0 link
63 The command will be used to get the connection status. The command will return parameters
64 such as SSID, operating frequency, rx/tx packets, signal strength, tx bitrate.
65
66 Apart from the iw utility all standard configurations using the 'iwconfig' utility are also supported.
67
68 b) Debugfs interface
69
70 The debugfs interface can be used for configurations and for getting
71 some useful information from the driver.
72 The section below explains the configurations that can be
73 done.
74
75 Mount debugfs to /debugfs mount point:
76
77 mkdir /debugfs
78 mount -t debugfs debugfs /debugfs
79
80 The information is provided in /debugfs/mwifiex/mlanX/:
81
82iw reg set <country code>
83 The command will be used to change the regulatory domain.
84
85iw reg get
86 The command will be used to get current regulatory domain.
87
88info
89 This command is used to get driver info.
90
91 Usage:
92 cat info
93
94 driver_name = "mwifiex"
95 driver_version = <driver_name, driver_version, (firmware_version)>
96 interface_name = "mlanX"
97 bss_mode = "Ad-hoc" | "Managed" | "Auto" | "Unknown"
98 media_state = "Disconnected" | "Connected"
99 mac_address = <6-byte adapter MAC address>
100 multicase_count = <multicast address count>
101 essid = <current SSID>
102 bssid = <current BSSID>
103 channel = <current channel>
104 region_code = <current region code>
105 multicasr_address[n] = <multicast address>
106 num_tx_bytes = <number of bytes sent to device>
107 num_rx_bytes = <number of bytes received from device and sent to kernel>
108 num_tx_pkts = <number of packets sent to device>
109 num_rx_pkts = <number of packets received from device and sent to kernel>
110 num_tx_pkts_dropped = <number of Tx packets dropped by driver>
111 num_rx_pkts_dropped = <number of Rx packets dropped by driver>
112 num_tx_pkts_err = <number of Tx packets failed to send to device>
113 num_rx_pkts_err = <number of Rx packets failed to receive from device>
114 carrier "on" | "off"
115 tx queue "stopped" | "started"
116
117 The following debug info are provided in /debugfs/mwifiex/mlanX/debug:
118
119 int_counter = <interrupt count, cleared when interrupt handled>
120 wmm_ac_vo = <number of packets sent to device from WMM AcVo queue>
121 wmm_ac_vi = <number of packets sent to device from WMM AcVi queue>
122 wmm_ac_be = <number of packets sent to device from WMM AcBE queue>
123 wmm_ac_bk = <number of packets sent to device from WMM AcBK queue>
124 max_tx_buf_size = <maximum Tx buffer size>
125 tx_buf_size = <current Tx buffer size>
126 curr_tx_buf_size = <current Tx buffer size>
127 ps_mode = <0/1, CAM mode/PS mode>
128 ps_state = <0/1/2/3, full power state/awake state/pre-sleep state/sleep state>
129 is_deep_sleep = <0/1, not deep sleep state/deep sleep state>
130 wakeup_dev_req = <0/1, wakeup device not required/required>
131 wakeup_tries = <wakeup device count, cleared when device awake>
132 hs_configured = <0/1, host sleep not configured/configured>
133 hs_activated = <0/1, extended host sleep not activated/activated>
134 num_tx_timeout = <number of Tx timeout>
135 num_cmd_timeout = <number of timeout commands>
136 timeout_cmd_id = <command id of the last timeout command>
137 timeout_cmd_act = <command action of the last timeout command>
138 last_cmd_id = <command id of the last several commands sent to device>
139 last_cmd_act = <command action of the last several commands sent to device>
140 last_cmd_index = <0 based last command index>
141 last_cmd_resp_id = <command id of the last several command responses received from device>
142 last_cmd_resp_index = <0 based last command response index>
143 last_event = <event id of the last several events received from device>
144 last_event_index = <0 based last event index>
145 num_cmd_h2c_fail = <number of commands failed to send to device>
146 num_cmd_sleep_cfm_fail = <number of sleep confirm failed to send to device>
147 num_tx_h2c_fail = <number of data packets failed to send to device>
148 num_evt_deauth = <number of deauthenticated events received from device>
149 num_evt_disassoc = <number of disassociated events received from device>
150 num_evt_link_lost = <number of link lost events received from device>
151 num_cmd_deauth = <number of deauthenticate commands sent to device>
152 num_cmd_assoc_ok = <number of associate commands with success return>
153 num_cmd_assoc_fail = <number of associate commands with failure return>
154 cmd_sent = <0/1, send command resources available/sending command to device>
155 data_sent = <0/1, send data resources available/sending data to device>
156 mp_rd_bitmap = <SDIO multi-port read bitmap>
157 mp_wr_bitmap = <SDIO multi-port write bitmap>
158 cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
159 event_received = <0/1, no event to process/event received and yet to process>
160 ioctl_pending = <number of ioctl pending>
161 tx_pending = <number of Tx packet pending>
162 rx_pending = <number of Rx packet pending>
163
164
1653) FOR DRIVER CONFIGURATION
166
167regrdwr
168 This command is used to read/write the adapter register.
169
170 Usage:
171 echo " <type> <offset> [value]" > regrdwr
172 cat regrdwr
173
174 where the parameters are,
175 <type>: 1:MAC/SOC, 2:BBP, 3:RF, 4:PMIC, 5:CAU
176 <offset>: offset of register
177 [value]: value to be written
178
179 Examples:
180 echo "1 0xa060" > regrdwr : Read the MAC register
181 echo "1 0xa060 0x12" > regrdwr : Write the MAC register
182 echo "1 0xa794 0x80000000" > regrdwr
183 : Write 0x80000000 to MAC register
184rdeeprom
185 This command is used to read the EEPROM contents of the card.
186
187 Usage:
188 echo "<offset> <length>" > rdeeprom
189 cat rdeeprom
190
191 where the parameters are,
192 <offset>: multiples of 4
193 <length>: 4-20, multiples of 4
194
195 Example:
196 echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0
197
198getlog
199 This command is used to get the statistics available in the station.
200 Usage:
201
202 cat getlog
203
204===============================================================================
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
new file mode 100644
index 000000000000..ec0895f4e8d3
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -0,0 +1,1456 @@
1/*
2 * Marvell Wireless LAN device driver: CFG80211
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "cfg80211.h"
21#include "main.h"
22
23/*
24 * This function maps the nl802.11 channel type into driver channel type.
25 *
26 * The mapping is as follows -
27 * NL80211_CHAN_NO_HT -> NO_SEC_CHANNEL
28 * NL80211_CHAN_HT20 -> NO_SEC_CHANNEL
29 * NL80211_CHAN_HT40PLUS -> SEC_CHANNEL_ABOVE
30 * NL80211_CHAN_HT40MINUS -> SEC_CHANNEL_BELOW
31 * Others -> NO_SEC_CHANNEL
32 */
33static int
34mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type
35 channel_type)
36{
37 int channel;
38 switch (channel_type) {
39 case NL80211_CHAN_NO_HT:
40 case NL80211_CHAN_HT20:
41 channel = NO_SEC_CHANNEL;
42 break;
43 case NL80211_CHAN_HT40PLUS:
44 channel = SEC_CHANNEL_ABOVE;
45 break;
46 case NL80211_CHAN_HT40MINUS:
47 channel = SEC_CHANNEL_BELOW;
48 break;
49 default:
50 channel = NO_SEC_CHANNEL;
51 }
52 return channel;
53}
54
55/*
56 * This function maps the driver channel type into nl802.11 channel type.
57 *
58 * The mapping is as follows -
59 * NO_SEC_CHANNEL -> NL80211_CHAN_HT20
60 * SEC_CHANNEL_ABOVE -> NL80211_CHAN_HT40PLUS
61 * SEC_CHANNEL_BELOW -> NL80211_CHAN_HT40MINUS
62 * Others -> NL80211_CHAN_HT20
63 */
64static enum nl80211_channel_type
65mwifiex_channels_to_cfg80211_channel_type(int channel_type)
66{
67 int channel;
68 switch (channel_type) {
69 case NO_SEC_CHANNEL:
70 channel = NL80211_CHAN_HT20;
71 break;
72 case SEC_CHANNEL_ABOVE:
73 channel = NL80211_CHAN_HT40PLUS;
74 break;
75 case SEC_CHANNEL_BELOW:
76 channel = NL80211_CHAN_HT40MINUS;
77 break;
78 default:
79 channel = NL80211_CHAN_HT20;
80 }
81 return channel;
82}
83
84/*
85 * This function checks whether WEP is set.
86 */
87static int
88mwifiex_is_alg_wep(u32 cipher)
89{
90 int alg = 0;
91
92 switch (cipher) {
93 case WLAN_CIPHER_SUITE_WEP40:
94 case WLAN_CIPHER_SUITE_WEP104:
95 alg = 1;
96 break;
97 default:
98 alg = 0;
99 break;
100 }
101 return alg;
102}
103
104/*
105 * This function retrieves the private structure from kernel wiphy structure.
106 */
107static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy)
108{
109 return (void *) (*(unsigned long *) wiphy_priv(wiphy));
110}
111
112/*
113 * CFG802.11 operation handler to delete a network key.
114 */
115static int
116mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
117 u8 key_index, bool pairwise, const u8 *mac_addr)
118{
119 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
120 int ret = 0;
121
122 ret = mwifiex_set_encode(priv, NULL, 0, key_index, 1);
123 if (ret) {
124 wiphy_err(wiphy, "deleting the crypto keys\n");
125 return -EFAULT;
126 }
127
128 wiphy_dbg(wiphy, "info: crypto keys deleted\n");
129 return 0;
130}
131
132/*
133 * CFG802.11 operation handler to set Tx power.
134 */
135static int
136mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
137 enum nl80211_tx_power_setting type,
138 int dbm)
139{
140 int ret = 0;
141 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
142
143 ret = mwifiex_set_tx_power(priv, type, dbm);
144
145 return ret;
146}
147
148/*
149 * CFG802.11 operation handler to set Power Save option.
150 *
151 * The timeout value, if provided, is currently ignored.
152 */
153static int
154mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
155 struct net_device *dev,
156 bool enabled, int timeout)
157{
158 int ret = 0;
159 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
160
161 if (timeout)
162 wiphy_dbg(wiphy,
163 "info: ignoring the timeout value"
164 " for IEEE power save\n");
165
166 ret = mwifiex_drv_set_power(priv, enabled);
167
168 return ret;
169}
170
171/*
172 * CFG802.11 operation handler to set the default network key.
173 */
174static int
175mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
176 u8 key_index, bool unicast,
177 bool multicast)
178{
179 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
180 int ret;
181
182 /* Return if WEP key not configured */
183 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED)
184 return 0;
185
186 ret = mwifiex_set_encode(priv, NULL, 0, key_index, 0);
187
188 wiphy_dbg(wiphy, "info: set default Tx key index\n");
189
190 if (ret)
191 return -EFAULT;
192
193 return 0;
194}
195
196/*
197 * CFG802.11 operation handler to add a network key.
198 */
199static int
200mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
201 u8 key_index, bool pairwise, const u8 *mac_addr,
202 struct key_params *params)
203{
204 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
205 int ret = 0;
206
207 ret = mwifiex_set_encode(priv, params->key, params->key_len,
208 key_index, 0);
209
210 wiphy_dbg(wiphy, "info: crypto keys added\n");
211
212 if (ret)
213 return -EFAULT;
214
215 return 0;
216}
217
218/*
219 * This function sends domain information to the firmware.
220 *
221 * The following information are passed to the firmware -
222 * - Country codes
223 * - Sub bands (first channel, number of channels, maximum Tx power)
224 */
225static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
226{
227 u8 no_of_triplet = 0;
228 struct ieee80211_country_ie_triplet *t;
229 u8 no_of_parsed_chan = 0;
230 u8 first_chan = 0, next_chan = 0, max_pwr = 0;
231 u8 i, flag = 0;
232 enum ieee80211_band band;
233 struct ieee80211_supported_band *sband;
234 struct ieee80211_channel *ch;
235 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
236 struct mwifiex_adapter *adapter = priv->adapter;
237 struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
238 int ret = 0;
239
240 /* Set country code */
241 domain_info->country_code[0] = priv->country_code[0];
242 domain_info->country_code[1] = priv->country_code[1];
243 domain_info->country_code[2] = ' ';
244
245 band = mwifiex_band_to_radio_type(adapter->config_bands);
246 if (!wiphy->bands[band]) {
247 wiphy_err(wiphy, "11D: setting domain info in FW\n");
248 return -1;
249 }
250
251 sband = wiphy->bands[band];
252
253 for (i = 0; i < sband->n_channels ; i++) {
254 ch = &sband->channels[i];
255 if (ch->flags & IEEE80211_CHAN_DISABLED)
256 continue;
257
258 if (!flag) {
259 flag = 1;
260 first_chan = (u32) ch->hw_value;
261 next_chan = first_chan;
262 max_pwr = ch->max_power;
263 no_of_parsed_chan = 1;
264 continue;
265 }
266
267 if (ch->hw_value == next_chan + 1 &&
268 ch->max_power == max_pwr) {
269 next_chan++;
270 no_of_parsed_chan++;
271 } else {
272 t = &domain_info->triplet[no_of_triplet];
273 t->chans.first_channel = first_chan;
274 t->chans.num_channels = no_of_parsed_chan;
275 t->chans.max_power = max_pwr;
276 no_of_triplet++;
277 first_chan = (u32) ch->hw_value;
278 next_chan = first_chan;
279 max_pwr = ch->max_power;
280 no_of_parsed_chan = 1;
281 }
282 }
283
284 if (flag) {
285 t = &domain_info->triplet[no_of_triplet];
286 t->chans.first_channel = first_chan;
287 t->chans.num_channels = no_of_parsed_chan;
288 t->chans.max_power = max_pwr;
289 no_of_triplet++;
290 }
291
292 domain_info->no_of_triplet = no_of_triplet;
293 /* Send cmd to FW to set domain info */
294 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
295 HostCmd_ACT_GEN_SET, 0, NULL, NULL);
296 if (ret)
297 wiphy_err(wiphy, "11D: setting domain info in FW\n");
298
299 return ret;
300}
301
302/*
303 * CFG802.11 regulatory domain callback function.
304 *
305 * This function is called when the regulatory domain is changed due to the
306 * following reasons -
307 * - Set by driver
308 * - Set by system core
309 * - Set by user
310 * - Set bt Country IE
311 */
312static int mwifiex_reg_notifier(struct wiphy *wiphy,
313 struct regulatory_request *request)
314{
315 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
316
317 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain"
318 " %c%c\n", request->alpha2[0], request->alpha2[1]);
319
320 memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
321
322 switch (request->initiator) {
323 case NL80211_REGDOM_SET_BY_DRIVER:
324 case NL80211_REGDOM_SET_BY_CORE:
325 case NL80211_REGDOM_SET_BY_USER:
326 break;
327 /* Todo: apply driver specific changes in channel flags based
328 on the request initiator if necessary. */
329 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
330 break;
331 }
332 mwifiex_send_domain_info_cmd_fw(wiphy);
333
334 return 0;
335}
336
337/*
338 * This function sets the RF channel.
339 *
340 * This function creates multiple IOCTL requests, populates them accordingly
341 * and issues them to set the band/channel and frequency.
342 */
343static int
344mwifiex_set_rf_channel(struct mwifiex_private *priv,
345 struct ieee80211_channel *chan,
346 enum nl80211_channel_type channel_type)
347{
348 struct mwifiex_chan_freq_power cfp;
349 int ret = 0;
350 int status = 0;
351 struct mwifiex_ds_band_cfg band_cfg;
352 u32 config_bands = 0;
353 struct wiphy *wiphy = priv->wdev->wiphy;
354
355 if (chan) {
356 memset(&band_cfg, 0, sizeof(band_cfg));
357 /* Set appropriate bands */
358 if (chan->band == IEEE80211_BAND_2GHZ)
359 config_bands = BAND_B | BAND_G | BAND_GN;
360 else
361 config_bands = BAND_AN | BAND_A;
362 if (priv->bss_mode == NL80211_IFTYPE_STATION
363 || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) {
364 band_cfg.config_bands = config_bands;
365 } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
366 band_cfg.config_bands = config_bands;
367 band_cfg.adhoc_start_band = config_bands;
368 }
369 /* Set channel offset */
370 band_cfg.sec_chan_offset =
371 mwifiex_cfg80211_channel_type_to_mwifiex_channels
372 (channel_type);
373 status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET,
374 &band_cfg);
375
376 if (status)
377 return -EFAULT;
378 mwifiex_send_domain_info_cmd_fw(wiphy);
379 }
380
381 wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and "
382 "mode %d\n", config_bands, band_cfg.sec_chan_offset,
383 priv->bss_mode);
384 if (!chan)
385 return ret;
386
387 memset(&cfp, 0, sizeof(cfp));
388 cfp.freq = chan->center_freq;
389 /* Convert frequency to channel */
390 cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
391
392 status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp);
393 if (status)
394 return -EFAULT;
395
396 ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
397
398 return ret;
399}
400
401/*
402 * CFG802.11 operation handler to set channel.
403 *
404 * This function can only be used when station is not connected.
405 */
406static int
407mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
408 struct ieee80211_channel *chan,
409 enum nl80211_channel_type channel_type)
410{
411 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
412
413 if (priv->media_connected) {
414 wiphy_err(wiphy, "This setting is valid only when station "
415 "is not connected\n");
416 return -EINVAL;
417 }
418
419 return mwifiex_set_rf_channel(priv, chan, channel_type);
420}
421
422/*
423 * This function sets the fragmentation threshold.
424 *
425 * This function creates an IOCTL request, populates it accordingly
426 * and issues an IOCTL.
427 *
428 * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE
429 * and MWIFIEX_FRAG_MAX_VALUE.
430 */
431static int
432mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
433{
434 int ret = 0;
435 int status = 0;
436 struct mwifiex_wait_queue *wait = NULL;
437 u8 wait_option = MWIFIEX_IOCTL_WAIT;
438
439 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
440 || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
441 return -EINVAL;
442
443 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
444 if (!wait)
445 return -ENOMEM;
446
447 status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I,
448 HostCmd_ACT_GEN_SET, &frag_thr);
449
450 if (mwifiex_request_ioctl(priv, wait, status, wait_option))
451 ret = -EFAULT;
452
453 kfree(wait);
454 return ret;
455}
456
457/*
458 * This function sets the RTS threshold.
459 *
460 * This function creates an IOCTL request, populates it accordingly
461 * and issues an IOCTL.
462 */
463static int
464mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
465{
466 int ret = 0;
467 struct mwifiex_wait_queue *wait = NULL;
468 int status = 0;
469 u8 wait_option = MWIFIEX_IOCTL_WAIT;
470
471 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
472 rts_thr = MWIFIEX_RTS_MAX_VALUE;
473
474 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
475 if (!wait)
476 return -ENOMEM;
477
478 status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I,
479 HostCmd_ACT_GEN_SET, &rts_thr);
480
481 if (mwifiex_request_ioctl(priv, wait, status, wait_option))
482 ret = -EFAULT;
483
484 kfree(wait);
485 return ret;
486}
487
488/*
489 * CFG802.11 operation handler to set wiphy parameters.
490 *
491 * This function can be used to set the RTS threshold and the
492 * Fragmentation threshold of the driver.
493 */
494static int
495mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
496{
497 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
498
499 int ret = 0;
500
501 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
502 ret = mwifiex_set_rts(priv, wiphy->rts_threshold);
503
504 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
505 ret = mwifiex_set_frag(priv, wiphy->frag_threshold);
506
507 return ret;
508}
509
510/*
511 * CFG802.11 operation handler to change interface type.
512 */
513static int
514mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
515 struct net_device *dev,
516 enum nl80211_iftype type, u32 *flags,
517 struct vif_params *params)
518{
519 int ret = 0;
520 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
521 struct mwifiex_wait_queue *wait = NULL;
522
523 if (priv->bss_mode == type) {
524 wiphy_warn(wiphy, "already set to required type\n");
525 return 0;
526 }
527
528 priv->bss_mode = type;
529
530 switch (type) {
531 case NL80211_IFTYPE_ADHOC:
532 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC;
533 wiphy_dbg(wiphy, "info: setting interface type to adhoc\n");
534 break;
535 case NL80211_IFTYPE_STATION:
536 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
537 wiphy_dbg(wiphy, "info: setting interface type to managed\n");
538 break;
539 case NL80211_IFTYPE_UNSPECIFIED:
540 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
541 wiphy_dbg(wiphy, "info: setting interface type to auto\n");
542 return 0;
543 default:
544 wiphy_err(wiphy, "unknown interface type: %d\n", type);
545 return -EINVAL;
546 }
547
548 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
549 if (!wait)
550 return -ENOMEM;
551
552 mwifiex_deauthenticate(priv, wait, NULL);
553
554 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
555
556 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
557 HostCmd_ACT_GEN_SET, 0, wait, NULL);
558 if (!ret)
559 ret = -EINPROGRESS;
560
561 ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT);
562 if (ret)
563 ret = -EFAULT;
564
565 kfree(wait);
566 return ret;
567}
568
569/*
570 * This function dumps the station information on a buffer.
571 *
572 * The following information are shown -
573 * - Total bytes transmitted
574 * - Total bytes received
575 * - Total packets transmitted
576 * - Total packets received
577 * - Signal quality level
578 * - Transmission rate
579 */
580static int
581mwifiex_dump_station_info(struct mwifiex_private *priv,
582 struct station_info *sinfo)
583{
584 struct mwifiex_ds_get_signal signal;
585 struct mwifiex_rate_cfg rate;
586 int ret = 0;
587
588 sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES |
589 STATION_INFO_RX_PACKETS |
590 STATION_INFO_TX_PACKETS
591 | STATION_INFO_SIGNAL | STATION_INFO_TX_BITRATE;
592
593 /* Get signal information from the firmware */
594 memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal));
595 if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) {
596 dev_err(priv->adapter->dev, "getting signal information\n");
597 ret = -EFAULT;
598 }
599
600 if (mwifiex_drv_get_data_rate(priv, &rate)) {
601 dev_err(priv->adapter->dev, "getting data rate\n");
602 ret = -EFAULT;
603 }
604
605 sinfo->rx_bytes = priv->stats.rx_bytes;
606 sinfo->tx_bytes = priv->stats.tx_bytes;
607 sinfo->rx_packets = priv->stats.rx_packets;
608 sinfo->tx_packets = priv->stats.tx_packets;
609 sinfo->signal = priv->w_stats.qual.level;
610 sinfo->txrate.legacy = rate.rate;
611
612 return ret;
613}
614
615/*
616 * CFG802.11 operation handler to get station information.
617 *
618 * This function only works in connected mode, and dumps the
619 * requested station information, if available.
620 */
621static int
622mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
623 u8 *mac, struct station_info *sinfo)
624{
625 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
626 int ret = 0;
627
628 mwifiex_dump_station_info(priv, sinfo);
629
630 if (!priv->media_connected)
631 return -ENOENT;
632 if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
633 return -ENOENT;
634
635
636 ret = mwifiex_dump_station_info(priv, sinfo);
637
638 return ret;
639}
640
641/* Supported rates to be advertised to the cfg80211 */
642
643static struct ieee80211_rate mwifiex_rates[] = {
644 {.bitrate = 10, .hw_value = 2, },
645 {.bitrate = 20, .hw_value = 4, },
646 {.bitrate = 55, .hw_value = 11, },
647 {.bitrate = 110, .hw_value = 22, },
648 {.bitrate = 220, .hw_value = 44, },
649 {.bitrate = 60, .hw_value = 12, },
650 {.bitrate = 90, .hw_value = 18, },
651 {.bitrate = 120, .hw_value = 24, },
652 {.bitrate = 180, .hw_value = 36, },
653 {.bitrate = 240, .hw_value = 48, },
654 {.bitrate = 360, .hw_value = 72, },
655 {.bitrate = 480, .hw_value = 96, },
656 {.bitrate = 540, .hw_value = 108, },
657 {.bitrate = 720, .hw_value = 144, },
658};
659
660/* Channel definitions to be advertised to cfg80211 */
661
662static struct ieee80211_channel mwifiex_channels_2ghz[] = {
663 {.center_freq = 2412, .hw_value = 1, },
664 {.center_freq = 2417, .hw_value = 2, },
665 {.center_freq = 2422, .hw_value = 3, },
666 {.center_freq = 2427, .hw_value = 4, },
667 {.center_freq = 2432, .hw_value = 5, },
668 {.center_freq = 2437, .hw_value = 6, },
669 {.center_freq = 2442, .hw_value = 7, },
670 {.center_freq = 2447, .hw_value = 8, },
671 {.center_freq = 2452, .hw_value = 9, },
672 {.center_freq = 2457, .hw_value = 10, },
673 {.center_freq = 2462, .hw_value = 11, },
674 {.center_freq = 2467, .hw_value = 12, },
675 {.center_freq = 2472, .hw_value = 13, },
676 {.center_freq = 2484, .hw_value = 14, },
677};
678
679static struct ieee80211_supported_band mwifiex_band_2ghz = {
680 .channels = mwifiex_channels_2ghz,
681 .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
682 .bitrates = mwifiex_rates,
683 .n_bitrates = 14,
684};
685
686static struct ieee80211_channel mwifiex_channels_5ghz[] = {
687 {.center_freq = 5040, .hw_value = 8, },
688 {.center_freq = 5060, .hw_value = 12, },
689 {.center_freq = 5080, .hw_value = 16, },
690 {.center_freq = 5170, .hw_value = 34, },
691 {.center_freq = 5190, .hw_value = 38, },
692 {.center_freq = 5210, .hw_value = 42, },
693 {.center_freq = 5230, .hw_value = 46, },
694 {.center_freq = 5180, .hw_value = 36, },
695 {.center_freq = 5200, .hw_value = 40, },
696 {.center_freq = 5220, .hw_value = 44, },
697 {.center_freq = 5240, .hw_value = 48, },
698 {.center_freq = 5260, .hw_value = 52, },
699 {.center_freq = 5280, .hw_value = 56, },
700 {.center_freq = 5300, .hw_value = 60, },
701 {.center_freq = 5320, .hw_value = 64, },
702 {.center_freq = 5500, .hw_value = 100, },
703 {.center_freq = 5520, .hw_value = 104, },
704 {.center_freq = 5540, .hw_value = 108, },
705 {.center_freq = 5560, .hw_value = 112, },
706 {.center_freq = 5580, .hw_value = 116, },
707 {.center_freq = 5600, .hw_value = 120, },
708 {.center_freq = 5620, .hw_value = 124, },
709 {.center_freq = 5640, .hw_value = 128, },
710 {.center_freq = 5660, .hw_value = 132, },
711 {.center_freq = 5680, .hw_value = 136, },
712 {.center_freq = 5700, .hw_value = 140, },
713 {.center_freq = 5745, .hw_value = 149, },
714 {.center_freq = 5765, .hw_value = 153, },
715 {.center_freq = 5785, .hw_value = 157, },
716 {.center_freq = 5805, .hw_value = 161, },
717 {.center_freq = 5825, .hw_value = 165, },
718};
719
720static struct ieee80211_supported_band mwifiex_band_5ghz = {
721 .channels = mwifiex_channels_5ghz,
722 .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
723 .bitrates = mwifiex_rates - 4,
724 .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4,
725};
726
727
728/* Supported crypto cipher suits to be advertised to cfg80211 */
729
730static const u32 mwifiex_cipher_suites[] = {
731 WLAN_CIPHER_SUITE_WEP40,
732 WLAN_CIPHER_SUITE_WEP104,
733 WLAN_CIPHER_SUITE_TKIP,
734 WLAN_CIPHER_SUITE_CCMP,
735};
736
737/*
738 * CFG802.11 operation handler for disconnection request.
739 *
740 * This function does not work when there is already a disconnection
741 * procedure going on.
742 */
743static int
744mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
745 u16 reason_code)
746{
747 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
748
749 if (priv->disconnect)
750 return -EBUSY;
751
752 priv->disconnect = 1;
753 if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL))
754 return -EFAULT;
755
756 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
757 " reason code %d\n", priv->cfg_bssid, reason_code);
758
759 queue_work(priv->workqueue, &priv->cfg_workqueue);
760
761 return 0;
762}
763
764/*
765 * This function informs the CFG802.11 subsystem of a new IBSS.
766 *
767 * The following information are sent to the CFG802.11 subsystem
768 * to register the new IBSS. If we do not register the new IBSS,
769 * a kernel panic will result.
770 * - SSID
771 * - SSID length
772 * - BSSID
773 * - Channel
774 */
775static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
776{
777 int ret = 0;
778 struct ieee80211_channel *chan;
779 struct mwifiex_bss_info bss_info;
780 int ie_len = 0;
781 u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
782
783 ret = mwifiex_get_bss_info(priv, &bss_info);
784 if (ret)
785 return ret;
786
787 ie_buf[0] = WLAN_EID_SSID;
788 ie_buf[1] = bss_info.ssid.ssid_len;
789
790 memcpy(&ie_buf[sizeof(struct ieee_types_header)],
791 &bss_info.ssid.ssid,
792 bss_info.ssid.ssid_len);
793 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
794
795 chan = __ieee80211_get_channel(priv->wdev->wiphy,
796 ieee80211_channel_to_frequency(bss_info.bss_chan,
797 priv->curr_bss_params.band));
798
799 cfg80211_inform_bss(priv->wdev->wiphy, chan,
800 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
801 0, ie_buf, ie_len, 0, GFP_KERNEL);
802 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
803
804 return ret;
805}
806
807/*
808 * This function informs the CFG802.11 subsystem of a new BSS connection.
809 *
810 * The following information are sent to the CFG802.11 subsystem
811 * to register the new BSS connection. If we do not register the new BSS,
812 * a kernel panic will result.
813 * - MAC address
814 * - Capabilities
815 * - Beacon period
816 * - RSSI value
817 * - Channel
818 * - Supported rates IE
819 * - Extended capabilities IE
820 * - DS parameter set IE
821 * - HT Capability IE
822 * - Vendor Specific IE (221)
823 * - WPA IE
824 * - RSN IE
825 */
826static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
827 struct mwifiex_802_11_ssid *ssid)
828{
829 struct mwifiex_scan_resp scan_resp;
830 struct mwifiex_bssdescriptor *scan_table;
831 int i, j;
832 struct ieee80211_channel *chan;
833 u8 *ie, *tmp, *ie_buf;
834 u32 ie_len;
835 u64 ts = 0;
836 u8 *beacon;
837 int beacon_size;
838 u8 element_id, element_len;
839
840 memset(&scan_resp, 0, sizeof(scan_resp));
841 if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp))
842 return -EFAULT;
843
844#define MAX_IE_BUF 2048
845 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
846 if (!ie_buf) {
847 dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n",
848 __func__);
849 return -ENOMEM;
850 }
851
852 scan_table = (struct mwifiex_bssdescriptor *) scan_resp.scan_table;
853 for (i = 0; i < scan_resp.num_in_scan_table; i++) {
854 if (ssid) {
855 /* Inform specific BSS only */
856 if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
857 ssid->ssid_len))
858 continue;
859 }
860 memset(ie_buf, 0, MAX_IE_BUF);
861 ie_buf[0] = WLAN_EID_SSID;
862 ie_buf[1] = scan_table[i].ssid.ssid_len;
863 memcpy(&ie_buf[sizeof(struct ieee_types_header)],
864 scan_table[i].ssid.ssid, ie_buf[1]);
865
866 ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header);
867 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
868
869 ie[0] = WLAN_EID_SUPP_RATES;
870
871 for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
872 if (!scan_table[i].supported_rates[j])
873 break;
874 else
875 ie[j + sizeof(struct ieee_types_header)] =
876 scan_table[i].supported_rates[j];
877 }
878
879 ie[1] = j;
880 ie_len += ie[1] + sizeof(struct ieee_types_header);
881
882 beacon = scan_table[i].beacon_buf;
883 beacon_size = scan_table[i].beacon_buf_size;
884
885 /* Skip time stamp, beacon interval and capability */
886
887 if (beacon) {
888 beacon += sizeof(scan_table[i].beacon_period)
889 + sizeof(scan_table[i].time_stamp) +
890 +sizeof(scan_table[i].cap_info_bitmap);
891
892 beacon_size -= sizeof(scan_table[i].beacon_period)
893 + sizeof(scan_table[i].time_stamp)
894 + sizeof(scan_table[i].cap_info_bitmap);
895 }
896
897 while (beacon_size >= sizeof(struct ieee_types_header)) {
898 ie = ie_buf + ie_len;
899 element_id = *beacon;
900 element_len = *(beacon + 1);
901 if (beacon_size < (int) element_len +
902 sizeof(struct ieee_types_header)) {
903 dev_err(priv->adapter->dev, "%s: in processing"
904 " IE, bytes left < IE length\n",
905 __func__);
906 break;
907 }
908 switch (element_id) {
909 case WLAN_EID_EXT_CAPABILITY:
910 case WLAN_EID_DS_PARAMS:
911 case WLAN_EID_HT_CAPABILITY:
912 case WLAN_EID_VENDOR_SPECIFIC:
913 case WLAN_EID_RSN:
914 case WLAN_EID_BSS_AC_ACCESS_DELAY:
915 ie[0] = element_id;
916 ie[1] = element_len;
917 tmp = (u8 *) beacon;
918 memcpy(&ie[sizeof(struct ieee_types_header)],
919 tmp + sizeof(struct ieee_types_header),
920 element_len);
921 ie_len += ie[1] +
922 sizeof(struct ieee_types_header);
923 break;
924 default:
925 break;
926 }
927 beacon += element_len +
928 sizeof(struct ieee_types_header);
929 beacon_size -= element_len +
930 sizeof(struct ieee_types_header);
931 }
932 chan = ieee80211_get_channel(priv->wdev->wiphy,
933 scan_table[i].freq);
934 cfg80211_inform_bss(priv->wdev->wiphy, chan,
935 scan_table[i].mac_address,
936 ts, scan_table[i].cap_info_bitmap,
937 scan_table[i].beacon_period,
938 ie_buf, ie_len,
939 scan_table[i].rssi, GFP_KERNEL);
940 }
941
942 kfree(ie_buf);
943 return 0;
944}
945
946/*
947 * This function connects with a BSS.
948 *
949 * This function handles both Infra and Ad-Hoc modes. It also performs
950 * validity checking on the provided parameters, disconnects from the
951 * current BSS (if any), sets up the association/scan parameters,
952 * including security settings, and performs specific SSID scan before
953 * trying to connect.
954 *
955 * For Infra mode, the function returns failure if the specified SSID
956 * is not found in scan table. However, for Ad-Hoc mode, it can create
957 * the IBSS if it does not exist. On successful completion in either case,
958 * the function notifies the CFG802.11 subsystem of the new BSS connection,
959 * otherwise the kernel will panic.
960 */
961static int
962mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
963 u8 *bssid, int mode, struct ieee80211_channel *channel,
964 struct cfg80211_connect_params *sme, bool privacy)
965{
966 struct mwifiex_802_11_ssid req_ssid;
967 struct mwifiex_ssid_bssid ssid_bssid;
968 int ret = 0;
969 int auth_type = 0, pairwise_encrypt_mode = 0;
970 int group_encrypt_mode = 0;
971 int alg_is_wep = 0;
972
973 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
974 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
975
976 req_ssid.ssid_len = ssid_len;
977 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
978 dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
979 return -EINVAL;
980 }
981
982 memcpy(req_ssid.ssid, ssid, ssid_len);
983 if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
984 dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
985 return -EINVAL;
986 }
987
988 /* disconnect before try to associate */
989 mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL);
990
991 if (channel)
992 ret = mwifiex_set_rf_channel(priv, channel,
993 mwifiex_channels_to_cfg80211_channel_type
994 (priv->adapter->chan_offset));
995
996 ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */
997
998 if (mode == NL80211_IFTYPE_ADHOC) {
999 /* "privacy" is set only for ad-hoc mode */
1000 if (privacy) {
1001 /*
1002 * Keep WLAN_CIPHER_SUITE_WEP104 for now so that
1003 * the firmware can find a matching network from the
1004 * scan. The cfg80211 does not give us the encryption
1005 * mode at this stage so just setting it to WEP here.
1006 */
1007 priv->sec_info.encryption_mode =
1008 WLAN_CIPHER_SUITE_WEP104;
1009 priv->sec_info.authentication_mode =
1010 NL80211_AUTHTYPE_OPEN_SYSTEM;
1011 }
1012
1013 goto done;
1014 }
1015
1016 /* Now handle infra mode. "sme" is valid for infra mode only */
1017 if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC
1018 || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
1019 auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1020 else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
1021 auth_type = NL80211_AUTHTYPE_SHARED_KEY;
1022
1023 if (sme->crypto.n_ciphers_pairwise) {
1024 priv->sec_info.encryption_mode =
1025 sme->crypto.ciphers_pairwise[0];
1026 priv->sec_info.authentication_mode = auth_type;
1027 }
1028
1029 if (sme->crypto.cipher_group) {
1030 priv->sec_info.encryption_mode = sme->crypto.cipher_group;
1031 priv->sec_info.authentication_mode = auth_type;
1032 }
1033 if (sme->ie)
1034 ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
1035
1036 if (sme->key) {
1037 alg_is_wep = mwifiex_is_alg_wep(pairwise_encrypt_mode)
1038 | mwifiex_is_alg_wep(group_encrypt_mode);
1039 if (alg_is_wep) {
1040 dev_dbg(priv->adapter->dev,
1041 "info: setting wep encryption"
1042 " with key len %d\n", sme->key_len);
1043 ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
1044 sme->key_idx, 0);
1045 }
1046 }
1047done:
1048 /* Do specific SSID scanning */
1049 if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) {
1050 dev_err(priv->adapter->dev, "scan error\n");
1051 return -EFAULT;
1052 }
1053
1054
1055 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
1056
1057 if (mode != NL80211_IFTYPE_ADHOC) {
1058 if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT,
1059 &ssid_bssid))
1060 return -EFAULT;
1061 /* Inform the BSS information to kernel, otherwise
1062 * kernel will give a panic after successful assoc */
1063 if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid))
1064 return -EFAULT;
1065 }
1066
1067 dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
1068 (char *) req_ssid.ssid, ssid_bssid.bssid);
1069
1070 memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6);
1071
1072 /* Connect to BSS by ESSID */
1073 memset(&ssid_bssid.bssid, 0, ETH_ALEN);
1074
1075 if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid))
1076 return -EFAULT;
1077
1078 if (mode == NL80211_IFTYPE_ADHOC) {
1079 /* Inform the BSS information to kernel, otherwise
1080 * kernel will give a panic after successful assoc */
1081 if (mwifiex_cfg80211_inform_ibss_bss(priv))
1082 return -EFAULT;
1083 }
1084
1085 return ret;
1086}
1087
1088/*
1089 * CFG802.11 operation handler for association request.
1090 *
1091 * This function does not work when the current mode is set to Ad-Hoc, or
1092 * when there is already an association procedure going on. The given BSS
1093 * information is used to associate.
1094 */
1095static int
1096mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1097 struct cfg80211_connect_params *sme)
1098{
1099 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1100 int ret = 0;
1101
1102 if (priv->assoc_request)
1103 return -EBUSY;
1104
1105 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
1106 wiphy_err(wiphy, "received infra assoc request "
1107 "when station is in ibss mode\n");
1108 goto done;
1109 }
1110
1111 priv->assoc_request = 1;
1112
1113 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1114 (char *) sme->ssid, sme->bssid);
1115
1116 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
1117 priv->bss_mode, sme->channel, sme, 0);
1118
1119done:
1120 priv->assoc_result = ret;
1121 queue_work(priv->workqueue, &priv->cfg_workqueue);
1122 return ret;
1123}
1124
1125/*
1126 * CFG802.11 operation handler to join an IBSS.
1127 *
1128 * This function does not work in any mode other than Ad-Hoc, or if
1129 * a join operation is already in progress.
1130 */
1131static int
1132mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1133 struct cfg80211_ibss_params *params)
1134{
1135 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1136 int ret = 0;
1137
1138 if (priv->ibss_join_request)
1139 return -EBUSY;
1140
1141 if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
1142 wiphy_err(wiphy, "request to join ibss received "
1143 "when station is not in ibss mode\n");
1144 goto done;
1145 }
1146
1147 priv->ibss_join_request = 1;
1148
1149 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
1150 (char *) params->ssid, params->bssid);
1151
1152 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1153 params->bssid, priv->bss_mode,
1154 params->channel, NULL, params->privacy);
1155done:
1156 priv->ibss_join_result = ret;
1157 queue_work(priv->workqueue, &priv->cfg_workqueue);
1158 return ret;
1159}
1160
1161/*
1162 * CFG802.11 operation handler to leave an IBSS.
1163 *
1164 * This function does not work if a leave operation is
1165 * already in progress.
1166 */
1167static int
1168mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1169{
1170 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1171
1172 if (priv->disconnect)
1173 return -EBUSY;
1174
1175 priv->disconnect = 1;
1176
1177 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
1178 priv->cfg_bssid);
1179 if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL))
1180 return -EFAULT;
1181
1182 queue_work(priv->workqueue, &priv->cfg_workqueue);
1183
1184 return 0;
1185}
1186
1187/*
1188 * CFG802.11 operation handler for scan request.
1189 *
1190 * This function issues a scan request to the firmware based upon
1191 * the user specified scan configuration. On successfull completion,
1192 * it also informs the results.
1193 */
1194static int
1195mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
1196 struct cfg80211_scan_request *request)
1197{
1198 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1199
1200 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1201
1202 if (priv->scan_request && priv->scan_request != request)
1203 return -EBUSY;
1204
1205 priv->scan_request = request;
1206
1207 queue_work(priv->workqueue, &priv->cfg_workqueue);
1208 return 0;
1209}
1210
1211/*
1212 * This function sets up the CFG802.11 specific HT capability fields
1213 * with default values.
1214 *
1215 * The following default values are set -
1216 * - HT Supported = True
1217 * - Maximum AMPDU length factor = 0x3
1218 * - Minimum AMPDU spacing = 0x6
1219 * - HT Capabilities map = IEEE80211_HT_CAP_SUP_WIDTH_20_40 (0x0002)
1220 * - MCS information, Rx mask = 0xff
1221 * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01)
1222 */
1223static void
1224mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
1225 struct mwifiex_private *priv)
1226{
1227 int rx_mcs_supp;
1228 struct ieee80211_mcs_info mcs_set;
1229 u8 *mcs = (u8 *)&mcs_set;
1230 struct mwifiex_adapter *adapter = priv->adapter;
1231
1232 ht_info->ht_supported = true;
1233 ht_info->ampdu_factor = 0x3;
1234 ht_info->ampdu_density = 0x6;
1235
1236 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
1237 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1238
1239 rx_mcs_supp = GET_RXMCSSUPP(priv->adapter->hw_dev_mcs_support);
1240 /* Set MCS for 1x1 */
1241 memset(mcs, 0xff, rx_mcs_supp);
1242 /* Clear all the other values */
1243 memset(&mcs[rx_mcs_supp], 0,
1244 sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
1245 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
1246 ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
1247 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
1248 SETHT_MCS32(mcs_set.rx_mask);
1249
1250 memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info));
1251
1252 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1253}
1254
1255/* station cfg80211 operations */
1256static struct cfg80211_ops mwifiex_cfg80211_ops = {
1257 .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
1258 .scan = mwifiex_cfg80211_scan,
1259 .connect = mwifiex_cfg80211_connect,
1260 .disconnect = mwifiex_cfg80211_disconnect,
1261 .get_station = mwifiex_cfg80211_get_station,
1262 .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
1263 .set_channel = mwifiex_cfg80211_set_channel,
1264 .join_ibss = mwifiex_cfg80211_join_ibss,
1265 .leave_ibss = mwifiex_cfg80211_leave_ibss,
1266 .add_key = mwifiex_cfg80211_add_key,
1267 .del_key = mwifiex_cfg80211_del_key,
1268 .set_default_key = mwifiex_cfg80211_set_default_key,
1269 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
1270 .set_tx_power = mwifiex_cfg80211_set_tx_power,
1271};
1272
1273/*
1274 * This function registers the device with CFG802.11 subsystem.
1275 *
1276 * The function creates the wireless device/wiphy, populates it with
1277 * default parameters and handler function pointers, and finally
1278 * registers the device.
1279 */
1280int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
1281 struct mwifiex_private *priv)
1282{
1283 int ret = 0;
1284 void *wdev_priv = NULL;
1285 struct wireless_dev *wdev;
1286
1287 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1288 if (!wdev) {
1289 dev_err(priv->adapter->dev, "%s: allocating wireless device\n",
1290 __func__);
1291 return -ENOMEM;
1292 }
1293 wdev->wiphy =
1294 wiphy_new(&mwifiex_cfg80211_ops,
1295 sizeof(struct mwifiex_private *));
1296 if (!wdev->wiphy)
1297 return -ENOMEM;
1298 wdev->iftype = NL80211_IFTYPE_STATION;
1299 wdev->wiphy->max_scan_ssids = 10;
1300 wdev->wiphy->interface_modes =
1301 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
1302 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
1303 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
1304
1305 /* Initialize cipher suits */
1306 wdev->wiphy->cipher_suites = mwifiex_cipher_suites;
1307 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
1308
1309 /* Initialize parameters for 2GHz band */
1310
1311 mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap,
1312 priv);
1313 mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap,
1314 priv);
1315
1316 memcpy(wdev->wiphy->perm_addr, mac, 6);
1317 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1318
1319 /* We are using custom domains */
1320 wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
1321
1322 wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
1323
1324 /* Set struct mwifiex_private pointer in wiphy_priv */
1325 wdev_priv = wiphy_priv(wdev->wiphy);
1326
1327 *(unsigned long *) wdev_priv = (unsigned long) priv;
1328
1329 ret = wiphy_register(wdev->wiphy);
1330 if (ret < 0) {
1331 dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
1332 __func__);
1333 wiphy_free(wdev->wiphy);
1334 return ret;
1335 } else {
1336 dev_dbg(priv->adapter->dev,
1337 "info: successfully registered wiphy device\n");
1338 }
1339
1340 dev_net_set(dev, wiphy_net(wdev->wiphy));
1341 dev->ieee80211_ptr = wdev;
1342 memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6);
1343 memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6);
1344 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1345 priv->wdev = wdev;
1346
1347 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1348 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
1349 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
1350
1351 return ret;
1352}
1353
1354/*
1355 * This function handles the result of different pending network operations.
1356 *
1357 * The following operations are handled and CFG802.11 subsystem is
1358 * notified accordingly -
1359 * - Scan request completion
1360 * - Association request completion
1361 * - IBSS join request completion
1362 * - Disconnect request completion
1363 */
1364void
1365mwifiex_cfg80211_results(struct work_struct *work)
1366{
1367 struct mwifiex_private *priv =
1368 container_of(work, struct mwifiex_private, cfg_workqueue);
1369 struct mwifiex_user_scan_cfg *scan_req;
1370 int ret = 0, i;
1371 struct ieee80211_channel *chan;
1372
1373 if (priv->scan_request) {
1374 scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
1375 GFP_KERNEL);
1376 if (!scan_req) {
1377 dev_err(priv->adapter->dev, "failed to alloc "
1378 "scan_req\n");
1379 return;
1380 }
1381 for (i = 0; i < priv->scan_request->n_ssids; i++) {
1382 memcpy(scan_req->ssid_list[i].ssid,
1383 priv->scan_request->ssids[i].ssid,
1384 priv->scan_request->ssids[i].ssid_len);
1385 scan_req->ssid_list[i].max_len =
1386 priv->scan_request->ssids[i].ssid_len;
1387 }
1388 for (i = 0; i < priv->scan_request->n_channels; i++) {
1389 chan = priv->scan_request->channels[i];
1390 scan_req->chan_list[i].chan_number = chan->hw_value;
1391 scan_req->chan_list[i].radio_type = chan->band;
1392 if (chan->flags & IEEE80211_CHAN_DISABLED)
1393 scan_req->chan_list[i].scan_type =
1394 MWIFIEX_SCAN_TYPE_PASSIVE;
1395 else
1396 scan_req->chan_list[i].scan_type =
1397 MWIFIEX_SCAN_TYPE_ACTIVE;
1398 scan_req->chan_list[i].scan_time = 0;
1399 }
1400 if (mwifiex_set_user_scan_ioctl(priv, scan_req)) {
1401 ret = -EFAULT;
1402 goto done;
1403 }
1404 if (mwifiex_inform_bss_from_scan_result(priv, NULL))
1405 ret = -EFAULT;
1406done:
1407 priv->scan_result_status = ret;
1408 dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
1409 __func__);
1410 cfg80211_scan_done(priv->scan_request,
1411 (priv->scan_result_status < 0));
1412 priv->scan_request = NULL;
1413 kfree(scan_req);
1414 }
1415
1416 if (priv->assoc_request) {
1417 if (!priv->assoc_result) {
1418 cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1419 NULL, 0, NULL, 0,
1420 WLAN_STATUS_SUCCESS,
1421 GFP_KERNEL);
1422 dev_dbg(priv->adapter->dev,
1423 "info: associated to bssid %pM successfully\n",
1424 priv->cfg_bssid);
1425 } else {
1426 dev_dbg(priv->adapter->dev,
1427 "info: association to bssid %pM failed\n",
1428 priv->cfg_bssid);
1429 memset(priv->cfg_bssid, 0, ETH_ALEN);
1430 }
1431 priv->assoc_request = 0;
1432 priv->assoc_result = 0;
1433 }
1434
1435 if (priv->ibss_join_request) {
1436 if (!priv->ibss_join_result) {
1437 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
1438 GFP_KERNEL);
1439 dev_dbg(priv->adapter->dev,
1440 "info: joined/created adhoc network with bssid"
1441 " %pM successfully\n", priv->cfg_bssid);
1442 } else {
1443 dev_dbg(priv->adapter->dev,
1444 "info: failed creating/joining adhoc network\n");
1445 }
1446 priv->ibss_join_request = 0;
1447 priv->ibss_join_result = 0;
1448 }
1449
1450 if (priv->disconnect) {
1451 memset(priv->cfg_bssid, 0, ETH_ALEN);
1452 priv->disconnect = 0;
1453 }
1454
1455 return;
1456}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
new file mode 100644
index 000000000000..c4db8f36aa16
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -0,0 +1,31 @@
1/*
2 * Marvell Wireless LAN device driver: CFG80211
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef __MWIFIEX_CFG80211__
21#define __MWIFIEX_CFG80211__
22
23#include <net/cfg80211.h>
24
25#include "main.h"
26
27int mwifiex_register_cfg80211(struct net_device *, u8 *,
28 struct mwifiex_private *);
29
30void mwifiex_cfg80211_results(struct work_struct *work);
31#endif
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
new file mode 100644
index 000000000000..07187a405fee
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -0,0 +1,367 @@
1/*
2 * Marvell Wireless LAN device driver: Channel, Frequence and Power
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "cfg80211.h"
26
27/* 100mW */
28#define MWIFIEX_TX_PWR_DEFAULT 20
29/* 100mW */
30#define MWIFIEX_TX_PWR_US_DEFAULT 20
31/* 50mW */
32#define MWIFIEX_TX_PWR_JP_DEFAULT 16
33/* 100mW */
34#define MWIFIEX_TX_PWR_FR_100MW 20
35/* 10mW */
36#define MWIFIEX_TX_PWR_FR_10MW 10
37/* 100mW */
38#define MWIFIEX_TX_PWR_EMEA_DEFAULT 20
39
40static u8 adhoc_rates_b[B_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, 0 };
41
42static u8 adhoc_rates_g[G_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
43 0xb0, 0x48, 0x60, 0x6c, 0 };
44
45static u8 adhoc_rates_bg[BG_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96,
46 0x0c, 0x12, 0x18, 0x24,
47 0x30, 0x48, 0x60, 0x6c, 0 };
48
49static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
50 0xb0, 0x48, 0x60, 0x6c, 0 };
51u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
52 0xb0, 0x48, 0x60, 0x6c, 0 };
53static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04,
54 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18,
55 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90,
56 0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68,
57 0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51,
58 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 };
59
60u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 };
61
62u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
63 0x30, 0x48, 0x60, 0x6c, 0 };
64
65u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c,
66 0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
67 0x60, 0x6c, 0 };
68
69u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
70 0x32, 0x40, 0x41, 0xff };
71
72u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
73
74/*
75 * This function maps an index in supported rates table into
76 * the corresponding data rate.
77 */
78u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index,
79 u8 ht_info)
80{
81 u16 mcs_rate[4][8] = {
82 {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e}
83 , /* LG 40M */
84 {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c}
85 , /* SG 40M */
86 {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82}
87 , /* LG 20M */
88 {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90}
89 }; /* SG 20M */
90
91 u32 rate;
92
93 if (ht_info & BIT(0)) {
94 if (index == MWIFIEX_RATE_BITMAP_MCS0) {
95 if (ht_info & BIT(2))
96 rate = 0x0D; /* MCS 32 SGI rate */
97 else
98 rate = 0x0C; /* MCS 32 LGI rate */
99 } else if (index < 8) {
100 if (ht_info & BIT(1)) {
101 if (ht_info & BIT(2))
102 /* SGI, 40M */
103 rate = mcs_rate[1][index];
104 else
105 /* LGI, 40M */
106 rate = mcs_rate[0][index];
107 } else {
108 if (ht_info & BIT(2))
109 /* SGI, 20M */
110 rate = mcs_rate[3][index];
111 else
112 /* LGI, 20M */
113 rate = mcs_rate[2][index];
114 }
115 } else
116 rate = mwifiex_data_rates[0];
117 } else {
118 if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
119 index = 0;
120 rate = mwifiex_data_rates[index];
121 }
122 return rate;
123}
124
125/*
126 * This function maps a data rate value into corresponding index in supported
127 * rates table.
128 */
129u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate)
130{
131 u16 *ptr;
132
133 if (rate) {
134 ptr = memchr(mwifiex_data_rates, rate,
135 sizeof(mwifiex_data_rates));
136 if (ptr)
137 return (u8) (ptr - mwifiex_data_rates);
138 }
139 return 0;
140}
141
142/*
143 * This function returns the current active data rates.
144 *
145 * The result may vary depending upon connection status.
146 */
147u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates)
148{
149 u32 k;
150
151 if (!priv->media_connected)
152 k = mwifiex_get_supported_rates(priv, rates);
153 else
154 k = mwifiex_copy_rates(rates, 0,
155 priv->curr_bss_params.data_rates,
156 priv->curr_bss_params.num_of_rates);
157
158 return k;
159}
160
161/*
162 * This function locates the Channel-Frequency-Power triplet based upon
163 * band and channel parameters.
164 */
165struct mwifiex_chan_freq_power *
166mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private
167 *priv, u8 band, u16 channel)
168{
169 struct mwifiex_chan_freq_power *cfp = NULL;
170 struct ieee80211_supported_band *sband;
171 struct ieee80211_channel *ch;
172 int i;
173
174 if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
175 sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
176 else
177 sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
178
179 if (!sband) {
180 dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
181 " & channel %d\n", __func__, band, channel);
182 return cfp;
183 }
184
185 for (i = 0; i < sband->n_channels; i++) {
186 ch = &sband->channels[i];
187 if (((ch->hw_value == channel) ||
188 (channel == FIRST_VALID_CHANNEL))
189 && !(ch->flags & IEEE80211_CHAN_DISABLED)) {
190 priv->cfp.channel = channel;
191 priv->cfp.freq = ch->center_freq;
192 priv->cfp.max_tx_power = ch->max_power;
193 cfp = &priv->cfp;
194 break;
195 }
196 }
197 if (i == sband->n_channels)
198 dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
199 " & channel %d\n", __func__, band, channel);
200
201 return cfp;
202}
203
204/*
205 * This function locates the Channel-Frequency-Power triplet based upon
206 * band and frequency parameters.
207 */
208struct mwifiex_chan_freq_power *
209mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv,
210 u8 band, u32 freq)
211{
212 struct mwifiex_chan_freq_power *cfp = NULL;
213 struct ieee80211_supported_band *sband;
214 struct ieee80211_channel *ch;
215 int i;
216
217 if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
218 sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
219 else
220 sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
221
222 if (!sband) {
223 dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
224 " & freq %d\n", __func__, band, freq);
225 return cfp;
226 }
227
228 for (i = 0; i < sband->n_channels; i++) {
229 ch = &sband->channels[i];
230 if ((ch->center_freq == freq) &&
231 !(ch->flags & IEEE80211_CHAN_DISABLED)) {
232 priv->cfp.channel = ch->hw_value;
233 priv->cfp.freq = freq;
234 priv->cfp.max_tx_power = ch->max_power;
235 cfp = &priv->cfp;
236 break;
237 }
238 }
239 if (i == sband->n_channels)
240 dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
241 " & freq %d\n", __func__, band, freq);
242
243 return cfp;
244}
245
246/*
247 * This function checks if the data rate is set to auto.
248 */
249u8
250mwifiex_is_rate_auto(struct mwifiex_private *priv)
251{
252 u32 i;
253 int rate_num = 0;
254
255 for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates); i++)
256 if (priv->bitmap_rates[i])
257 rate_num++;
258
259 if (rate_num > 1)
260 return true;
261 else
262 return false;
263}
264
265/*
266 * This function converts rate bitmap into rate index.
267 */
268int
269mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap,
270 int size)
271{
272 int i;
273
274 for (i = 0; i < size * 8; i++)
275 if (rate_bitmap[i / 16] & (1 << (i % 16)))
276 return i;
277
278 return 0;
279}
280
281/*
282 * This function gets the supported data rates.
283 *
284 * The function works in both Ad-Hoc and infra mode by printing the
285 * band and returning the data rates.
286 */
287u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
288{
289 u32 k = 0;
290 struct mwifiex_adapter *adapter = priv->adapter;
291 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
292 switch (adapter->config_bands) {
293 case BAND_B:
294 dev_dbg(adapter->dev, "info: infra band=%d "
295 "supported_rates_b\n", adapter->config_bands);
296 k = mwifiex_copy_rates(rates, k, supported_rates_b,
297 sizeof(supported_rates_b));
298 break;
299 case BAND_G:
300 case BAND_G | BAND_GN:
301 dev_dbg(adapter->dev, "info: infra band=%d "
302 "supported_rates_g\n", adapter->config_bands);
303 k = mwifiex_copy_rates(rates, k, supported_rates_g,
304 sizeof(supported_rates_g));
305 break;
306 case BAND_B | BAND_G:
307 case BAND_A | BAND_B | BAND_G:
308 case BAND_A | BAND_B:
309 case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
310 case BAND_B | BAND_G | BAND_GN:
311 dev_dbg(adapter->dev, "info: infra band=%d "
312 "supported_rates_bg\n", adapter->config_bands);
313 k = mwifiex_copy_rates(rates, k, supported_rates_bg,
314 sizeof(supported_rates_bg));
315 break;
316 case BAND_A:
317 case BAND_A | BAND_G:
318 dev_dbg(adapter->dev, "info: infra band=%d "
319 "supported_rates_a\n", adapter->config_bands);
320 k = mwifiex_copy_rates(rates, k, supported_rates_a,
321 sizeof(supported_rates_a));
322 break;
323 case BAND_A | BAND_AN:
324 case BAND_A | BAND_G | BAND_AN | BAND_GN:
325 dev_dbg(adapter->dev, "info: infra band=%d "
326 "supported_rates_a\n", adapter->config_bands);
327 k = mwifiex_copy_rates(rates, k, supported_rates_a,
328 sizeof(supported_rates_a));
329 break;
330 case BAND_GN:
331 dev_dbg(adapter->dev, "info: infra band=%d "
332 "supported_rates_n\n", adapter->config_bands);
333 k = mwifiex_copy_rates(rates, k, supported_rates_n,
334 sizeof(supported_rates_n));
335 break;
336 }
337 } else {
338 /* Ad-hoc mode */
339 switch (adapter->adhoc_start_band) {
340 case BAND_B:
341 dev_dbg(adapter->dev, "info: adhoc B\n");
342 k = mwifiex_copy_rates(rates, k, adhoc_rates_b,
343 sizeof(adhoc_rates_b));
344 break;
345 case BAND_G:
346 case BAND_G | BAND_GN:
347 dev_dbg(adapter->dev, "info: adhoc G only\n");
348 k = mwifiex_copy_rates(rates, k, adhoc_rates_g,
349 sizeof(adhoc_rates_g));
350 break;
351 case BAND_B | BAND_G:
352 case BAND_B | BAND_G | BAND_GN:
353 dev_dbg(adapter->dev, "info: adhoc BG\n");
354 k = mwifiex_copy_rates(rates, k, adhoc_rates_bg,
355 sizeof(adhoc_rates_bg));
356 break;
357 case BAND_A:
358 case BAND_A | BAND_AN:
359 dev_dbg(adapter->dev, "info: adhoc A\n");
360 k = mwifiex_copy_rates(rates, k, adhoc_rates_a,
361 sizeof(adhoc_rates_a));
362 break;
363 }
364 }
365
366 return k;
367}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
new file mode 100644
index 000000000000..a9aeb31af455
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -0,0 +1,1459 @@
1/*
2 * Marvell Wireless LAN device driver: commands and events
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * This function initializes a command node.
30 *
31 * The actual allocation of the node is not done by this function. It only
32 * initiates a node by filling it with default parameters. Similarly,
33 * allocation of the different buffers used (IOCTL buffer, data buffer) are
34 * not done by this function either.
35 */
36static void
37mwifiex_init_cmd_node(struct mwifiex_private *priv,
38 struct cmd_ctrl_node *cmd_node,
39 u32 cmd_oid, void *wait_queue, void *data_buf)
40{
41 cmd_node->priv = priv;
42 cmd_node->cmd_oid = cmd_oid;
43 cmd_node->wq_buf = wait_queue;
44 cmd_node->data_buf = data_buf;
45 cmd_node->cmd_skb = cmd_node->skb;
46}
47
48/*
49 * This function returns a command node from the free queue depending upon
50 * availability.
51 */
52static struct cmd_ctrl_node *
53mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
54{
55 struct cmd_ctrl_node *cmd_node;
56 unsigned long flags;
57
58 spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
59 if (list_empty(&adapter->cmd_free_q)) {
60 dev_err(adapter->dev, "GET_CMD_NODE: cmd node not available\n");
61 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
62 return NULL;
63 }
64 cmd_node = list_first_entry(&adapter->cmd_free_q,
65 struct cmd_ctrl_node, list);
66 list_del(&cmd_node->list);
67 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
68
69 return cmd_node;
70}
71
72/*
73 * This function cleans up a command node.
74 *
75 * The function resets the fields including the buffer pointers.
76 * This function does not try to free the buffers. They must be
77 * freed before calling this function.
78 *
79 * This function will however call the receive completion callback
80 * in case a response buffer is still available before resetting
81 * the pointer.
82 */
83static void
84mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
85 struct cmd_ctrl_node *cmd_node)
86{
87 cmd_node->cmd_oid = 0;
88 cmd_node->cmd_flag = 0;
89 cmd_node->wq_buf = NULL;
90 cmd_node->data_buf = NULL;
91
92 if (cmd_node->resp_skb) {
93 mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0);
94 cmd_node->resp_skb = NULL;
95 }
96
97 return;
98}
99
100/*
101 * This function returns a command node from the pending queue which
102 * matches the given IOCTL request.
103 */
104static struct cmd_ctrl_node *
105mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter,
106 struct mwifiex_wait_queue *wait_queue)
107{
108 unsigned long flags;
109 struct cmd_ctrl_node *cmd_node;
110
111 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
112 list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
113 if (cmd_node->wq_buf == wait_queue) {
114 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
115 flags);
116 return cmd_node;
117 }
118 }
119 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
120
121 return NULL;
122}
123
124/*
125 * This function sends a host command to the firmware.
126 *
127 * The function copies the host command into the driver command
128 * buffer, which will be transferred to the firmware later by the
129 * main thread.
130 */
131static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv,
132 struct host_cmd_ds_command *cmd, void *data_buf)
133{
134 struct mwifiex_ds_misc_cmd *pcmd_ptr =
135 (struct mwifiex_ds_misc_cmd *) data_buf;
136
137 /* Copy the HOST command to command buffer */
138 memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len);
139 dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len);
140 return 0;
141}
142
143/*
144 * This function downloads a command to the firmware.
145 *
146 * The function performs sanity tests, sets the command sequence
147 * number and size, converts the header fields to CPU format before
148 * sending. Afterwards, it logs the command ID and action for debugging
149 * and sets up the command timeout timer.
150 */
151static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
152 struct cmd_ctrl_node *cmd_node)
153{
154
155 struct mwifiex_adapter *adapter = priv->adapter;
156 int ret = 0;
157 struct host_cmd_ds_command *host_cmd;
158 struct mwifiex_wait_queue *wait_queue = NULL;
159 uint16_t cmd_code;
160 uint16_t cmd_size;
161 struct timeval tstamp;
162 unsigned long flags;
163
164 if (!adapter || !cmd_node)
165 return -1;
166
167 host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
168 if (cmd_node->wq_buf)
169 wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
170
171 /* Sanity test */
172 if (host_cmd == NULL || host_cmd->size == 0) {
173 dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
174 " or cmd size is 0, not sending\n");
175 if (wait_queue)
176 wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL;
177 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
178 return -1;
179 }
180
181 /* Set command sequence number */
182 adapter->seq_num++;
183 host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
184 (adapter->seq_num, cmd_node->priv->bss_num,
185 cmd_node->priv->bss_type));
186
187 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
188 adapter->curr_cmd = cmd_node;
189 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
190
191 cmd_code = le16_to_cpu(host_cmd->command);
192 cmd_size = le16_to_cpu(host_cmd->size);
193
194 skb_trim(cmd_node->cmd_skb, cmd_size);
195
196 do_gettimeofday(&tstamp);
197 dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
198 " seqno %#x\n",
199 tstamp.tv_sec, tstamp.tv_usec, cmd_code,
200 le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
201 le16_to_cpu(host_cmd->seq_num));
202
203 skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
204
205 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
206 cmd_node->cmd_skb->data,
207 cmd_node->cmd_skb->len, NULL);
208
209 if (ret == -1) {
210 dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
211 if (wait_queue)
212 wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL;
213 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
214
215 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
216 adapter->curr_cmd = NULL;
217 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
218
219 adapter->dbg.num_cmd_host_to_card_failure++;
220 return -1;
221 }
222
223 /* Save the last command id and action to debug log */
224 adapter->dbg.last_cmd_index =
225 (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
226 adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
227 adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
228 le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
229
230 /* Clear BSS_NO_BITS from HostCmd */
231 cmd_code &= HostCmd_CMD_ID_MASK;
232
233 /* Setup the timer after transmit command */
234 mod_timer(&adapter->cmd_timer,
235 jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
236
237 return 0;
238}
239
240/*
241 * This function downloads a sleep confirm command to the firmware.
242 *
243 * The function performs sanity tests, sets the command sequence
244 * number and size, converts the header fields to CPU format before
245 * sending.
246 *
247 * No responses are needed for sleep confirm command.
248 */
249static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
250{
251 int ret = 0;
252 u16 cmd_len = 0;
253 struct mwifiex_private *priv;
254 struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf =
255 (struct mwifiex_opt_sleep_confirm_buffer *)
256 adapter->sleep_cfm->data;
257 cmd_len = sizeof(struct mwifiex_opt_sleep_confirm);
258 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
259
260 sleep_cfm_buf->ps_cfm_sleep.seq_num =
261 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
262 (adapter->seq_num, priv->bss_num,
263 priv->bss_type)));
264 adapter->seq_num++;
265
266 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
267 adapter->sleep_cfm->data,
268 adapter->sleep_cfm->len +
269 INTF_HEADER_LEN, NULL);
270
271 if (ret == -1) {
272 dev_err(adapter->dev, "SLEEP_CFM: failed\n");
273 adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
274 return -1;
275 }
276 if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
277 == MWIFIEX_BSS_ROLE_STA) {
278 if (!sleep_cfm_buf->ps_cfm_sleep.resp_ctrl)
279 /* Response is not needed for sleep
280 confirm command */
281 adapter->ps_state = PS_STATE_SLEEP;
282 else
283 adapter->ps_state = PS_STATE_SLEEP_CFM;
284
285 if (!sleep_cfm_buf->ps_cfm_sleep.resp_ctrl
286 && (adapter->is_hs_configured
287 && !adapter->sleep_period.period)) {
288 adapter->pm_wakeup_card_req = true;
289 mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
290 MWIFIEX_BSS_ROLE_STA), true);
291 }
292 }
293
294 return ret;
295}
296
297/*
298 * This function allocates the command buffers and links them to
299 * the command free queue.
300 *
301 * The driver uses a pre allocated number of command buffers, which
302 * are created at driver initializations and freed at driver cleanup.
303 * Every command needs to obtain a command buffer from this pool before
304 * it can be issued. The command free queue lists the command buffers
305 * currently free to use, while the command pending queue lists the
306 * command buffers already in use and awaiting handling. Command buffers
307 * are returned to the free queue after use.
308 */
309int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
310{
311 struct cmd_ctrl_node *cmd_array;
312 u32 buf_size;
313 u32 i;
314
315 /* Allocate and initialize struct cmd_ctrl_node */
316 buf_size = sizeof(struct cmd_ctrl_node) * MWIFIEX_NUM_OF_CMD_BUFFER;
317 cmd_array = kzalloc(buf_size, GFP_KERNEL);
318 if (!cmd_array) {
319 dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
320 __func__);
321 return -1;
322 }
323
324 adapter->cmd_pool = cmd_array;
325 memset(adapter->cmd_pool, 0, buf_size);
326
327 /* Allocate and initialize command buffers */
328 for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
329 cmd_array[i].skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
330 if (!cmd_array[i].skb) {
331 dev_err(adapter->dev, "ALLOC_CMD_BUF: out of memory\n");
332 return -1;
333 }
334 }
335
336 for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++)
337 mwifiex_insert_cmd_to_free_q(adapter, &cmd_array[i]);
338
339 return 0;
340}
341
342/*
343 * This function frees the command buffers.
344 *
345 * The function calls the completion callback for all the command
346 * buffers that still have response buffers associated with them.
347 */
348int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
349{
350 struct cmd_ctrl_node *cmd_array;
351 u32 i;
352
353 /* Need to check if cmd pool is allocated or not */
354 if (!adapter->cmd_pool) {
355 dev_dbg(adapter->dev, "info: FREE_CMD_BUF: cmd_pool is null\n");
356 return 0;
357 }
358
359 cmd_array = adapter->cmd_pool;
360
361 /* Release shared memory buffers */
362 for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
363 if (cmd_array[i].skb) {
364 dev_dbg(adapter->dev, "cmd: free cmd buffer %d\n", i);
365 dev_kfree_skb_any(cmd_array[i].skb);
366 }
367 if (!cmd_array[i].resp_skb)
368 continue;
369 mwifiex_recv_complete(adapter, cmd_array[i].resp_skb, 0);
370 }
371 /* Release struct cmd_ctrl_node */
372 if (adapter->cmd_pool) {
373 dev_dbg(adapter->dev, "cmd: free cmd pool\n");
374 kfree(adapter->cmd_pool);
375 adapter->cmd_pool = NULL;
376 }
377
378 return 0;
379}
380
381/*
382 * This function handles events generated by firmware.
383 *
384 * Event body of events received from firmware are not used (though they are
385 * saved), only the event ID is used. Some events are re-invoked by
386 * the driver, with a new event body.
387 *
388 * After processing, the function calls the completion callback
389 * for cleanup.
390 */
391int mwifiex_process_event(struct mwifiex_adapter *adapter)
392{
393 int ret = 0;
394 struct mwifiex_private *priv =
395 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
396 struct sk_buff *skb = adapter->event_skb;
397 u32 eventcause = adapter->event_cause;
398 struct timeval tstamp;
399 struct mwifiex_rxinfo *rx_info = NULL;
400
401 /* Save the last event to debug log */
402 adapter->dbg.last_event_index =
403 (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
404 adapter->dbg.last_event[adapter->dbg.last_event_index] =
405 (u16) eventcause;
406
407 /* Get BSS number and corresponding priv */
408 priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause),
409 EVENT_GET_BSS_TYPE(eventcause));
410 if (!priv)
411 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
412 /* Clear BSS_NO_BITS from event */
413 eventcause &= EVENT_ID_MASK;
414 adapter->event_cause = eventcause;
415
416 if (skb) {
417 rx_info = MWIFIEX_SKB_RXCB(skb);
418 rx_info->bss_index = priv->bss_index;
419 }
420
421 if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
422 do_gettimeofday(&tstamp);
423 dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
424 tstamp.tv_sec, tstamp.tv_usec, eventcause);
425 }
426
427 ret = mwifiex_process_sta_event(priv);
428
429 adapter->event_cause = 0;
430 adapter->event_skb = NULL;
431
432 mwifiex_recv_complete(adapter, skb, 0);
433
434 return ret;
435}
436
437/*
438 * This function prepares a command before sending it to the firmware.
439 *
440 * Preparation includes -
441 * - Sanity tests to make sure the card is still present or the FW
442 * is not reset
443 * - Getting a new command node from the command free queue
444 * - Initializing the command node for default parameters
445 * - Fill up the non-default parameters and buffer pointers
446 * - Add the command to pending queue
447 */
448int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
449 u16 cmd_action, u32 cmd_oid,
450 void *wait_queue, void *data_buf)
451{
452 int ret = 0;
453 struct mwifiex_adapter *adapter = priv->adapter;
454 struct cmd_ctrl_node *cmd_node = NULL;
455 struct host_cmd_ds_command *cmd_ptr = NULL;
456
457 if (!adapter) {
458 pr_err("PREP_CMD: adapter is NULL\n");
459 return -1;
460 }
461
462 if (adapter->is_suspended) {
463 dev_err(adapter->dev, "PREP_CMD: device in suspended state\n");
464 return -1;
465 }
466
467 if (adapter->surprise_removed) {
468 dev_err(adapter->dev, "PREP_CMD: card is removed\n");
469 return -1;
470 }
471
472 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
473 if (cmd_no != HostCmd_CMD_FUNC_INIT) {
474 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
475 return -1;
476 }
477 }
478
479 /* Get a new command node */
480 cmd_node = mwifiex_get_cmd_node(adapter);
481
482 if (!cmd_node) {
483 dev_err(adapter->dev, "PREP_CMD: no free cmd node\n");
484 return -1;
485 }
486
487 /* Initialize the command node */
488 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf);
489
490 if (!cmd_node->cmd_skb) {
491 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
492 return -1;
493 }
494
495 memset(skb_put(cmd_node->cmd_skb, sizeof(struct host_cmd_ds_command)),
496 0, sizeof(struct host_cmd_ds_command));
497
498 cmd_ptr = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
499 cmd_ptr->command = cpu_to_le16(cmd_no);
500 cmd_ptr->result = 0;
501
502 /* Prepare command */
503 if (cmd_no) {
504 ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
505 cmd_oid, data_buf, cmd_ptr);
506 } else {
507 ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
508 cmd_node->cmd_flag |= CMD_F_HOSTCMD;
509 }
510
511 /* Return error, since the command preparation failed */
512 if (ret) {
513 dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n",
514 cmd_no);
515 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
516 return -1;
517 }
518
519 /* Send command */
520 if (cmd_no == HostCmd_CMD_802_11_SCAN)
521 mwifiex_queue_scan_cmd(priv, cmd_node);
522 else
523 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
524
525 return ret;
526}
527
528/*
529 * This function returns a command to the command free queue.
530 *
531 * The function also calls the completion callback if required, before
532 * cleaning the command node and re-inserting it into the free queue.
533 */
534void
535mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
536 struct cmd_ctrl_node *cmd_node)
537{
538 struct mwifiex_wait_queue *wait_queue = NULL;
539 unsigned long flags;
540
541 if (cmd_node == NULL)
542 return;
543 if (cmd_node->wq_buf) {
544 wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
545 if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR)
546 mwifiex_ioctl_complete(adapter, wait_queue, -1);
547 else
548 mwifiex_ioctl_complete(adapter, wait_queue, 0);
549 }
550 /* Clean the node */
551 mwifiex_clean_cmd_node(adapter, cmd_node);
552
553 /* Insert node into cmd_free_q */
554 spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
555 list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
556 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
557
558 return;
559}
560
561/*
562 * This function queues a command to the command pending queue.
563 *
564 * This in effect adds the command to the command list to be executed.
565 * Exit PS command is handled specially, by placing it always to the
566 * front of the command queue.
567 */
568void
569mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
570 struct cmd_ctrl_node *cmd_node, u32 add_tail)
571{
572 struct host_cmd_ds_command *host_cmd = NULL;
573 u16 command;
574 unsigned long flags;
575
576 host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
577 if (!host_cmd) {
578 dev_err(adapter->dev, "QUEUE_CMD: host_cmd is NULL\n");
579 return;
580 }
581
582 command = le16_to_cpu(host_cmd->command);
583
584 /* Exit_PS command needs to be queued in the header always. */
585 if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
586 struct host_cmd_ds_802_11_ps_mode_enh *pm =
587 &host_cmd->params.psmode_enh;
588 if ((le16_to_cpu(pm->action) == DIS_PS)
589 || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
590 if (adapter->ps_state != PS_STATE_AWAKE)
591 add_tail = false;
592 }
593 }
594
595 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
596 if (add_tail)
597 list_add_tail(&cmd_node->list, &adapter->cmd_pending_q);
598 else
599 list_add(&cmd_node->list, &adapter->cmd_pending_q);
600 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
601
602 dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command);
603
604 return;
605}
606
607/*
608 * This function executes the next command in command pending queue.
609 *
610 * This function will fail if a command is already in processing stage,
611 * otherwise it will dequeue the first command from the command pending
612 * queue and send to the firmware.
613 *
614 * If the device is currently in host sleep mode, any commands, except the
615 * host sleep configuration command will de-activate the host sleep. For PS
616 * mode, the function will put the firmware back to sleep if applicable.
617 */
618int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
619{
620 struct mwifiex_private *priv = NULL;
621 struct cmd_ctrl_node *cmd_node = NULL;
622 int ret = 0;
623 struct host_cmd_ds_command *host_cmd;
624 unsigned long cmd_flags;
625 unsigned long cmd_pending_q_flags;
626
627 /* Check if already in processing */
628 if (adapter->curr_cmd) {
629 dev_err(adapter->dev, "EXEC_NEXT_CMD: cmd in processing\n");
630 return -1;
631 }
632
633 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
634 /* Check if any command is pending */
635 spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
636 if (list_empty(&adapter->cmd_pending_q)) {
637 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
638 cmd_pending_q_flags);
639 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
640 return 0;
641 }
642 cmd_node = list_first_entry(&adapter->cmd_pending_q,
643 struct cmd_ctrl_node, list);
644 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
645 cmd_pending_q_flags);
646
647 host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
648 priv = cmd_node->priv;
649
650 if (adapter->ps_state != PS_STATE_AWAKE) {
651 dev_err(adapter->dev, "%s: cannot send cmd in sleep state,"
652 " this should not happen\n", __func__);
653 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
654 return ret;
655 }
656
657 spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
658 list_del(&cmd_node->list);
659 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
660 cmd_pending_q_flags);
661
662 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
663 ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
664 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
665 /* Any command sent to the firmware when host is in sleep
666 * mode should de-configure host sleep. We should skip the
667 * host sleep configuration command itself though
668 */
669 if (priv && (host_cmd->command !=
670 cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
671 if (adapter->hs_activated) {
672 adapter->is_hs_configured = false;
673 mwifiex_hs_activated_event(priv, false);
674 }
675 }
676
677 return ret;
678}
679
680/*
681 * This function handles the command response.
682 *
683 * After processing, the function cleans the command node and puts
684 * it back to the command free queue.
685 */
686int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
687{
688 struct host_cmd_ds_command *resp = NULL;
689 struct mwifiex_private *priv =
690 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
691 int ret = 0;
692 uint16_t orig_cmdresp_no;
693 uint16_t cmdresp_no;
694 uint16_t cmdresp_result;
695 struct mwifiex_wait_queue *wait_queue = NULL;
696 struct timeval tstamp;
697 unsigned long flags;
698
699 /* Now we got response from FW, cancel the command timer */
700 del_timer(&adapter->cmd_timer);
701
702 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
703 resp = (struct host_cmd_ds_command *) adapter->upld_buf;
704 dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n",
705 le16_to_cpu(resp->command));
706 return -1;
707 }
708
709 if (adapter->curr_cmd->wq_buf)
710 wait_queue = (struct mwifiex_wait_queue *)
711 adapter->curr_cmd->wq_buf;
712
713 adapter->num_cmd_timeout = 0;
714
715 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
716 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
717 dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
718 le16_to_cpu(resp->command));
719 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
720 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
721 adapter->curr_cmd = NULL;
722 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
723 return -1;
724 }
725
726 if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
727 /* Copy original response back to response buffer */
728 struct mwifiex_ds_misc_cmd *hostcmd = NULL;
729 uint16_t size = le16_to_cpu(resp->size);
730 dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size);
731 size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER);
732 if (adapter->curr_cmd->data_buf) {
733 hostcmd = (struct mwifiex_ds_misc_cmd *)
734 adapter->curr_cmd->data_buf;
735 hostcmd->len = size;
736 memcpy(hostcmd->cmd, (void *) resp, size);
737 }
738 }
739 orig_cmdresp_no = le16_to_cpu(resp->command);
740
741 /* Get BSS number and corresponding priv */
742 priv = mwifiex_get_priv_by_id(adapter,
743 HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
744 HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
745 if (!priv)
746 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
747 /* Clear RET_BIT from HostCmd */
748 resp->command = cpu_to_le16(orig_cmdresp_no & HostCmd_CMD_ID_MASK);
749
750 cmdresp_no = le16_to_cpu(resp->command);
751 cmdresp_result = le16_to_cpu(resp->result);
752
753 /* Save the last command response to debug log */
754 adapter->dbg.last_cmd_resp_index =
755 (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
756 adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
757 orig_cmdresp_no;
758
759 do_gettimeofday(&tstamp);
760 dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
761 " len %d, seqno 0x%x\n",
762 tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result,
763 le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
764
765 if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
766 dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
767 if (wait_queue)
768 wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP;
769
770 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
771 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
772 adapter->curr_cmd = NULL;
773 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
774 return -1;
775 }
776
777 if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
778 adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
779 if ((cmdresp_result == HostCmd_RESULT_OK)
780 && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
781 ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
782 } else {
783 /* handle response */
784 ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp,
785 wait_queue);
786 }
787
788 /* Check init command response */
789 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
790 if (ret == -1) {
791 dev_err(adapter->dev, "%s: cmd %#x failed during "
792 "initialization\n", __func__, cmdresp_no);
793 mwifiex_init_fw_complete(adapter);
794 return -1;
795 } else if (adapter->last_init_cmd == cmdresp_no)
796 adapter->hw_status = MWIFIEX_HW_STATUS_INIT_DONE;
797 }
798
799 if (adapter->curr_cmd) {
800 if (wait_queue && (!ret))
801 wait_queue->status = MWIFIEX_ERROR_NO_ERROR;
802 else if (wait_queue && (ret == -1))
803 wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL;
804
805 /* Clean up and put current command back to cmd_free_q */
806 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
807
808 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
809 adapter->curr_cmd = NULL;
810 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
811 }
812
813 return ret;
814}
815
816/*
817 * This function handles the timeout of command sending.
818 *
819 * It will re-send the same command again.
820 */
821void
822mwifiex_cmd_timeout_func(unsigned long function_context)
823{
824 struct mwifiex_adapter *adapter =
825 (struct mwifiex_adapter *) function_context;
826 struct cmd_ctrl_node *cmd_node = NULL;
827 struct mwifiex_wait_queue *wait_queue = NULL;
828 struct timeval tstamp;
829
830 adapter->num_cmd_timeout++;
831 adapter->dbg.num_cmd_timeout++;
832 if (!adapter->curr_cmd) {
833 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
834 return;
835 }
836 cmd_node = adapter->curr_cmd;
837 if (cmd_node->wq_buf) {
838 wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
839 wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT;
840 }
841
842 if (cmd_node) {
843 adapter->dbg.timeout_cmd_id =
844 adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
845 adapter->dbg.timeout_cmd_act =
846 adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
847 do_gettimeofday(&tstamp);
848 dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x,"
849 " act = %#x\n", __func__,
850 tstamp.tv_sec, tstamp.tv_usec,
851 adapter->dbg.timeout_cmd_id,
852 adapter->dbg.timeout_cmd_act);
853
854 dev_err(adapter->dev, "num_data_h2c_failure = %d\n",
855 adapter->dbg.num_tx_host_to_card_failure);
856 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
857 adapter->dbg.num_cmd_host_to_card_failure);
858
859 dev_err(adapter->dev, "num_cmd_timeout = %d\n",
860 adapter->dbg.num_cmd_timeout);
861 dev_err(adapter->dev, "num_tx_timeout = %d\n",
862 adapter->dbg.num_tx_timeout);
863
864 dev_err(adapter->dev, "last_cmd_index = %d\n",
865 adapter->dbg.last_cmd_index);
866 print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET,
867 adapter->dbg.last_cmd_id, DBG_CMD_NUM);
868 print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET,
869 adapter->dbg.last_cmd_act, DBG_CMD_NUM);
870
871 dev_err(adapter->dev, "last_cmd_resp_index = %d\n",
872 adapter->dbg.last_cmd_resp_index);
873 print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET,
874 adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM);
875
876 dev_err(adapter->dev, "last_event_index = %d\n",
877 adapter->dbg.last_event_index);
878 print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET,
879 adapter->dbg.last_event, DBG_CMD_NUM);
880
881 dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n",
882 adapter->data_sent, adapter->cmd_sent);
883
884 dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
885 adapter->ps_mode, adapter->ps_state);
886 }
887 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
888 mwifiex_init_fw_complete(adapter);
889
890 return;
891}
892
893/*
894 * This function cancels all the pending commands.
895 *
896 * The current command, all commands in command pending queue and all scan
897 * commands in scan pending queue are cancelled. All the completion callbacks
898 * are called with failure status to ensure cleanup.
899 */
900void
901mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
902{
903 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
904 struct mwifiex_wait_queue *wait_queue = NULL;
905 unsigned long flags;
906
907 /* Cancel current cmd */
908 if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) {
909 wait_queue =
910 (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf;
911 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
912 adapter->curr_cmd->wq_buf = NULL;
913 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
914 wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL;
915 mwifiex_ioctl_complete(adapter, wait_queue, -1);
916 }
917 /* Cancel all pending command */
918 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
919 list_for_each_entry_safe(cmd_node, tmp_node,
920 &adapter->cmd_pending_q, list) {
921 list_del(&cmd_node->list);
922 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
923
924 if (cmd_node->wq_buf) {
925 wait_queue =
926 (struct mwifiex_wait_queue *) cmd_node->wq_buf;
927 wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL;
928 mwifiex_ioctl_complete(adapter, wait_queue, -1);
929 cmd_node->wq_buf = NULL;
930 }
931 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
932 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
933 }
934 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
935
936 /* Cancel all pending scan command */
937 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
938 list_for_each_entry_safe(cmd_node, tmp_node,
939 &adapter->scan_pending_q, list) {
940 list_del(&cmd_node->list);
941 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
942
943 cmd_node->wq_buf = NULL;
944 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
945 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
946 }
947 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
948
949 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
950 adapter->scan_processing = false;
951 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
952}
953
954/*
955 * This function cancels all pending commands that matches with
956 * the given IOCTL request.
957 *
958 * Both the current command buffer and the pending command queue are
959 * searched for matching IOCTL request. The completion callback of
960 * the matched command is called with failure status to ensure cleanup.
961 * In case of scan commands, all pending commands in scan pending queue
962 * are cancelled.
963 */
964void
965mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
966 struct mwifiex_wait_queue *wait_queue)
967{
968 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
969 unsigned long cmd_flags;
970 unsigned long cmd_pending_q_flags;
971 unsigned long scan_pending_q_flags;
972 uint16_t cancel_scan_cmd = false;
973
974 if ((adapter->curr_cmd) &&
975 (adapter->curr_cmd->wq_buf == wait_queue)) {
976 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
977 cmd_node = adapter->curr_cmd;
978 cmd_node->wq_buf = NULL;
979 cmd_node->cmd_flag |= CMD_F_CANCELED;
980 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
981 }
982
983 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
984 while (1) {
985 cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue);
986 if (!cmd_node)
987 break;
988
989 spin_lock_irqsave(&adapter->cmd_pending_q_lock,
990 cmd_pending_q_flags);
991 list_del(&cmd_node->list);
992 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
993 cmd_pending_q_flags);
994
995 cmd_node->wq_buf = NULL;
996 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
997 }
998 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
999 /* Cancel all pending scan command */
1000 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1001 scan_pending_q_flags);
1002 list_for_each_entry_safe(cmd_node, tmp_node,
1003 &adapter->scan_pending_q, list) {
1004 if (cmd_node->wq_buf == wait_queue) {
1005 list_del(&cmd_node->list);
1006 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1007 scan_pending_q_flags);
1008 cmd_node->wq_buf = NULL;
1009 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1010 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1011 scan_pending_q_flags);
1012 cancel_scan_cmd = true;
1013 }
1014 }
1015 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1016 scan_pending_q_flags);
1017
1018 if (cancel_scan_cmd) {
1019 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1020 adapter->scan_processing = false;
1021 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1022 }
1023 wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL;
1024 mwifiex_ioctl_complete(adapter, wait_queue, -1);
1025
1026 return;
1027}
1028
1029/*
1030 * This function sends the sleep confirm command to firmware, if
1031 * possible.
1032 *
1033 * The sleep confirm command cannot be issued if command response,
1034 * data response or event response is awaiting handling, or if we
1035 * are in the middle of sending a command, or expecting a command
1036 * response.
1037 */
1038void
1039mwifiex_check_ps_cond(struct mwifiex_adapter *adapter)
1040{
1041 if (!adapter->cmd_sent &&
1042 !adapter->curr_cmd && !IS_CARD_RX_RCVD(adapter))
1043 mwifiex_dnld_sleep_confirm_cmd(adapter);
1044 else
1045 dev_dbg(adapter->dev,
1046 "cmd: Delay Sleep Confirm (%s%s%s)\n",
1047 (adapter->cmd_sent) ? "D" : "",
1048 (adapter->curr_cmd) ? "C" : "",
1049 (IS_CARD_RX_RCVD(adapter)) ? "R" : "");
1050}
1051
1052/*
1053 * This function sends a Host Sleep activated event to applications.
1054 *
1055 * This event is generated by the driver, with a blank event body.
1056 */
1057void
1058mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
1059{
1060 if (activated) {
1061 if (priv->adapter->is_hs_configured) {
1062 priv->adapter->hs_activated = true;
1063 dev_dbg(priv->adapter->dev, "event: hs_activated\n");
1064 priv->adapter->hs_activate_wait_q_woken = true;
1065 wake_up_interruptible(
1066 &priv->adapter->hs_activate_wait_q);
1067 } else {
1068 dev_dbg(priv->adapter->dev, "event: HS not configured\n");
1069 }
1070 } else {
1071 dev_dbg(priv->adapter->dev, "event: hs_deactivated\n");
1072 priv->adapter->hs_activated = false;
1073 }
1074}
1075
1076/*
1077 * This function handles the command response of a Host Sleep configuration
1078 * command.
1079 *
1080 * Handling includes changing the header fields into CPU format
1081 * and setting the current host sleep activation status in driver.
1082 *
1083 * In case host sleep status change, the function generates an event to
1084 * notify the applications.
1085 */
1086int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
1087 struct host_cmd_ds_command *resp)
1088{
1089 struct mwifiex_adapter *adapter = priv->adapter;
1090 struct host_cmd_ds_802_11_hs_cfg_enh *phs_cfg =
1091 &resp->params.opt_hs_cfg;
1092 uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions);
1093
1094 if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) {
1095 mwifiex_hs_activated_event(priv, true);
1096 return 0;
1097 } else {
1098 dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply"
1099 " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n",
1100 resp->result, conditions,
1101 phs_cfg->params.hs_config.gpio,
1102 phs_cfg->params.hs_config.gap);
1103 }
1104 if (conditions != HOST_SLEEP_CFG_CANCEL) {
1105 adapter->is_hs_configured = true;
1106 } else {
1107 adapter->is_hs_configured = false;
1108 if (adapter->hs_activated)
1109 mwifiex_hs_activated_event(priv, false);
1110 }
1111
1112 return 0;
1113}
1114
1115/*
1116 * This function wakes up the adapter and generates a Host Sleep
1117 * cancel event on receiving the power up interrupt.
1118 */
1119void
1120mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
1121{
1122 dev_dbg(adapter->dev, "info: %s: auto cancelling host sleep"
1123 " since there is interrupt from the firmware\n", __func__);
1124
1125 adapter->if_ops.wakeup(adapter);
1126 adapter->hs_activated = false;
1127 adapter->is_hs_configured = false;
1128 mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
1129 MWIFIEX_BSS_ROLE_ANY), false);
1130 return;
1131}
1132
1133/*
1134 * This function handles the command response of a sleep confirm command.
1135 *
1136 * The function sets the card state to SLEEP if the response indicates success.
1137 */
1138void
1139mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
1140 u8 *pbuf, u32 upld_len)
1141{
1142 struct host_cmd_ds_command *cmd = (struct host_cmd_ds_command *) pbuf;
1143 struct mwifiex_private *priv =
1144 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
1145 uint16_t result = le16_to_cpu(cmd->result);
1146 uint16_t command = le16_to_cpu(cmd->command);
1147 uint16_t seq_num = le16_to_cpu(cmd->seq_num);
1148
1149 if (!upld_len) {
1150 dev_err(adapter->dev, "%s: cmd size is 0\n", __func__);
1151 return;
1152 }
1153
1154 /* Get BSS number and corresponding priv */
1155 priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
1156 HostCmd_GET_BSS_TYPE(seq_num));
1157 if (!priv)
1158 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
1159
1160 /* Update sequence number */
1161 seq_num = HostCmd_GET_SEQ_NO(seq_num);
1162 /* Clear RET_BIT from HostCmd */
1163 command &= HostCmd_CMD_ID_MASK;
1164
1165 if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
1166 dev_err(adapter->dev, "%s: received unexpected response for"
1167 " cmd %x, result = %x\n", __func__, command, result);
1168 return;
1169 }
1170
1171 if (result) {
1172 dev_err(adapter->dev, "%s: sleep confirm cmd failed\n",
1173 __func__);
1174 adapter->pm_wakeup_card_req = false;
1175 adapter->ps_state = PS_STATE_AWAKE;
1176 return;
1177 }
1178 adapter->pm_wakeup_card_req = true;
1179 if (adapter->is_hs_configured)
1180 mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
1181 MWIFIEX_BSS_ROLE_ANY), true);
1182 adapter->ps_state = PS_STATE_SLEEP;
1183 cmd->command = cpu_to_le16(command);
1184 cmd->seq_num = cpu_to_le16(seq_num);
1185}
1186EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp);
1187
1188/*
1189 * This function prepares an enhanced power mode command.
1190 *
1191 * This function can be used to disable power save or to configure
1192 * power save with auto PS or STA PS or auto deep sleep.
1193 *
1194 * Preparation includes -
1195 * - Setting command ID, action and proper size
1196 * - Setting Power Save bitmap, PS parameters TLV, PS mode TLV,
1197 * auto deep sleep TLV (as required)
1198 * - Ensuring correct endian-ness
1199 */
1200int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
1201 struct host_cmd_ds_command *cmd,
1202 u16 cmd_action, uint16_t ps_bitmap,
1203 void *data_buf)
1204{
1205 struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh =
1206 &cmd->params.psmode_enh;
1207 u8 *tlv = NULL;
1208 u16 cmd_size = 0;
1209
1210 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
1211 if (cmd_action == DIS_AUTO_PS) {
1212 psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
1213 psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
1214 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
1215 sizeof(psmode_enh->params.ps_bitmap));
1216 } else if (cmd_action == GET_PS) {
1217 psmode_enh->action = cpu_to_le16(GET_PS);
1218 psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
1219 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
1220 sizeof(psmode_enh->params.ps_bitmap));
1221 } else if (cmd_action == EN_AUTO_PS) {
1222 psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
1223 psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
1224 cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
1225 sizeof(psmode_enh->params.ps_bitmap);
1226 tlv = (u8 *) cmd + cmd_size;
1227 if (ps_bitmap & BITMAP_STA_PS) {
1228 struct mwifiex_adapter *adapter = priv->adapter;
1229 struct mwifiex_ie_types_ps_param *ps_tlv =
1230 (struct mwifiex_ie_types_ps_param *) tlv;
1231 struct mwifiex_ps_param *ps_mode = &ps_tlv->param;
1232 ps_tlv->header.type = cpu_to_le16(TLV_TYPE_PS_PARAM);
1233 ps_tlv->header.len = cpu_to_le16(sizeof(*ps_tlv) -
1234 sizeof(struct mwifiex_ie_types_header));
1235 cmd_size += sizeof(*ps_tlv);
1236 tlv += sizeof(*ps_tlv);
1237 dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n");
1238 ps_mode->null_pkt_interval =
1239 cpu_to_le16(adapter->null_pkt_interval);
1240 ps_mode->multiple_dtims =
1241 cpu_to_le16(adapter->multiple_dtim);
1242 ps_mode->bcn_miss_timeout =
1243 cpu_to_le16(adapter->bcn_miss_time_out);
1244 ps_mode->local_listen_interval =
1245 cpu_to_le16(adapter->local_listen_interval);
1246 ps_mode->adhoc_wake_period =
1247 cpu_to_le16(adapter->adhoc_awake_period);
1248 ps_mode->delay_to_ps =
1249 cpu_to_le16(adapter->delay_to_ps);
1250 ps_mode->mode =
1251 cpu_to_le16(adapter->enhanced_ps_mode);
1252
1253 }
1254 if (ps_bitmap & BITMAP_AUTO_DS) {
1255 struct mwifiex_ie_types_auto_ds_param *auto_ds_tlv =
1256 (struct mwifiex_ie_types_auto_ds_param *) tlv;
1257 u16 idletime = 0;
1258
1259 auto_ds_tlv->header.type =
1260 cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
1261 auto_ds_tlv->header.len =
1262 cpu_to_le16(sizeof(*auto_ds_tlv) -
1263 sizeof(struct mwifiex_ie_types_header));
1264 cmd_size += sizeof(*auto_ds_tlv);
1265 tlv += sizeof(*auto_ds_tlv);
1266 if (data_buf)
1267 idletime = ((struct mwifiex_ds_auto_ds *)
1268 data_buf)->idle_time;
1269 dev_dbg(priv->adapter->dev,
1270 "cmd: PS Command: Enter Auto Deep Sleep\n");
1271 auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
1272 }
1273 cmd->size = cpu_to_le16(cmd_size);
1274 }
1275 return 0;
1276}
1277
1278/*
1279 * This function handles the command response of an enhanced power mode
1280 * command.
1281 *
1282 * Handling includes changing the header fields into CPU format
1283 * and setting the current enhanced power mode in driver.
1284 */
1285int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
1286 struct host_cmd_ds_command *resp,
1287 void *data_buf)
1288{
1289 struct mwifiex_adapter *adapter = priv->adapter;
1290 struct host_cmd_ds_802_11_ps_mode_enh *ps_mode =
1291 &resp->params.psmode_enh;
1292 uint16_t action = le16_to_cpu(ps_mode->action);
1293 uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap);
1294 uint16_t auto_ps_bitmap =
1295 le16_to_cpu(ps_mode->params.ps_bitmap);
1296
1297 dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
1298 __func__, resp->result, action);
1299 if (action == EN_AUTO_PS) {
1300 if (auto_ps_bitmap & BITMAP_AUTO_DS) {
1301 dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n");
1302 priv->adapter->is_deep_sleep = true;
1303 }
1304 if (auto_ps_bitmap & BITMAP_STA_PS) {
1305 dev_dbg(adapter->dev, "cmd: Enabled STA power save\n");
1306 if (adapter->sleep_period.period)
1307 dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n");
1308 }
1309 } else if (action == DIS_AUTO_PS) {
1310 if (ps_bitmap & BITMAP_AUTO_DS) {
1311 priv->adapter->is_deep_sleep = false;
1312 dev_dbg(adapter->dev, "cmd: Disabled auto deep sleep\n");
1313 }
1314 if (ps_bitmap & BITMAP_STA_PS) {
1315 dev_dbg(adapter->dev, "cmd: Disabled STA power save\n");
1316 if (adapter->sleep_period.period) {
1317 adapter->delay_null_pkt = false;
1318 adapter->tx_lock_flag = false;
1319 adapter->pps_uapsd_mode = false;
1320 }
1321 }
1322 } else if (action == GET_PS) {
1323 if (ps_bitmap & BITMAP_STA_PS)
1324 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1325 else
1326 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
1327
1328 dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap);
1329
1330 if (data_buf) {
1331 /* This section is for get power save mode */
1332 struct mwifiex_ds_pm_cfg *pm_cfg =
1333 (struct mwifiex_ds_pm_cfg *)data_buf;
1334 if (ps_bitmap & BITMAP_STA_PS)
1335 pm_cfg->param.ps_mode = 1;
1336 else
1337 pm_cfg->param.ps_mode = 0;
1338 }
1339 }
1340 return 0;
1341}
1342
1343/*
1344 * This function prepares command to get hardware specifications.
1345 *
1346 * Preparation includes -
1347 * - Setting command ID, action and proper size
1348 * - Setting permanent address parameter
1349 * - Ensuring correct endian-ness
1350 */
1351int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
1352 struct host_cmd_ds_command *cmd)
1353{
1354 struct host_cmd_ds_get_hw_spec *hw_spec = &cmd->params.hw_spec;
1355
1356 cmd->command = cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
1357 cmd->size =
1358 cpu_to_le16(sizeof(struct host_cmd_ds_get_hw_spec) + S_DS_GEN);
1359 memcpy(hw_spec->permanent_addr, priv->curr_addr, ETH_ALEN);
1360
1361 return 0;
1362}
1363
1364/*
1365 * This function handles the command response of get hardware
1366 * specifications.
1367 *
1368 * Handling includes changing the header fields into CPU format
1369 * and saving/updating the following parameters in driver -
1370 * - Firmware capability information
1371 * - Firmware band settings
1372 * - Ad-hoc start band and channel
1373 * - Ad-hoc 11n activation status
1374 * - Firmware release number
1375 * - Number of antennas
1376 * - Hardware address
1377 * - Hardware interface version
1378 * - Firmware version
1379 * - Region code
1380 * - 11n capabilities
1381 * - MCS support fields
1382 * - MP end port
1383 */
1384int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1385 struct host_cmd_ds_command *resp)
1386{
1387 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
1388 struct mwifiex_adapter *adapter = priv->adapter;
1389 int i;
1390
1391 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
1392
1393 if (IS_SUPPORT_MULTI_BANDS(adapter))
1394 adapter->fw_bands = (u8) GET_FW_DEFAULT_BANDS(adapter);
1395 else
1396 adapter->fw_bands = BAND_B;
1397
1398 adapter->config_bands = adapter->fw_bands;
1399
1400 if (adapter->fw_bands & BAND_A) {
1401 if (adapter->fw_bands & BAND_GN) {
1402 adapter->config_bands |= BAND_AN;
1403 adapter->fw_bands |= BAND_AN;
1404 }
1405 if (adapter->fw_bands & BAND_AN) {
1406 adapter->adhoc_start_band = BAND_A | BAND_AN;
1407 adapter->adhoc_11n_enabled = true;
1408 } else {
1409 adapter->adhoc_start_band = BAND_A;
1410 }
1411 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
1412 } else if (adapter->fw_bands & BAND_GN) {
1413 adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
1414 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1415 adapter->adhoc_11n_enabled = true;
1416 } else if (adapter->fw_bands & BAND_G) {
1417 adapter->adhoc_start_band = BAND_G | BAND_B;
1418 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1419 } else if (adapter->fw_bands & BAND_B) {
1420 adapter->adhoc_start_band = BAND_B;
1421 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1422 }
1423
1424 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1425 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1426
1427 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1428 adapter->fw_release_number);
1429 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
1430 hw_spec->permanent_addr);
1431 dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n",
1432 le16_to_cpu(hw_spec->hw_if_version),
1433 le16_to_cpu(hw_spec->version));
1434
1435 if (priv->curr_addr[0] == 0xff)
1436 memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
1437
1438 adapter->region_code = le16_to_cpu(hw_spec->region_code);
1439
1440 for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++)
1441 /* Use the region code to search for the index */
1442 if (adapter->region_code == region_code_index[i])
1443 break;
1444
1445 /* If it's unidentified region code, use the default (USA) */
1446 if (i >= MWIFIEX_MAX_REGION_CODE) {
1447 adapter->region_code = 0x10;
1448 dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n");
1449 }
1450
1451 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
1452 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1453
1454 if (adapter->if_ops.update_mp_end_port)
1455 adapter->if_ops.update_mp_end_port(adapter,
1456 le16_to_cpu(hw_spec->mp_end_port));
1457
1458 return 0;
1459}
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
new file mode 100644
index 000000000000..63b09692f27d
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -0,0 +1,773 @@
1/*
2 * Marvell Wireless LAN device driver: debugfs
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/debugfs.h>
21
22#include "main.h"
23#include "11n.h"
24
25
26static struct dentry *mwifiex_dfs_dir;
27
28static char *bss_modes[] = {
29 "Unknown",
30 "Managed",
31 "Ad-hoc",
32 "Auto"
33};
34
35/* size/addr for mwifiex_debug_info */
36#define item_size(n) (FIELD_SIZEOF(struct mwifiex_debug_info, n))
37#define item_addr(n) (offsetof(struct mwifiex_debug_info, n))
38
39/* size/addr for struct mwifiex_adapter */
40#define adapter_item_size(n) (FIELD_SIZEOF(struct mwifiex_adapter, n))
41#define adapter_item_addr(n) (offsetof(struct mwifiex_adapter, n))
42
43struct mwifiex_debug_data {
44 char name[32]; /* variable/array name */
45 u32 size; /* size of the variable/array */
46 size_t addr; /* address of the variable/array */
47 int num; /* number of variables in an array */
48};
49
50static struct mwifiex_debug_data items[] = {
51 {"int_counter", item_size(int_counter),
52 item_addr(int_counter), 1},
53 {"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
54 item_addr(packets_out[WMM_AC_VO]), 1},
55 {"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
56 item_addr(packets_out[WMM_AC_VI]), 1},
57 {"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
58 item_addr(packets_out[WMM_AC_BE]), 1},
59 {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
60 item_addr(packets_out[WMM_AC_BK]), 1},
61 {"max_tx_buf_size", item_size(max_tx_buf_size),
62 item_addr(max_tx_buf_size), 1},
63 {"tx_buf_size", item_size(tx_buf_size),
64 item_addr(tx_buf_size), 1},
65 {"curr_tx_buf_size", item_size(curr_tx_buf_size),
66 item_addr(curr_tx_buf_size), 1},
67 {"ps_mode", item_size(ps_mode),
68 item_addr(ps_mode), 1},
69 {"ps_state", item_size(ps_state),
70 item_addr(ps_state), 1},
71 {"is_deep_sleep", item_size(is_deep_sleep),
72 item_addr(is_deep_sleep), 1},
73 {"wakeup_dev_req", item_size(pm_wakeup_card_req),
74 item_addr(pm_wakeup_card_req), 1},
75 {"wakeup_tries", item_size(pm_wakeup_fw_try),
76 item_addr(pm_wakeup_fw_try), 1},
77 {"hs_configured", item_size(is_hs_configured),
78 item_addr(is_hs_configured), 1},
79 {"hs_activated", item_size(hs_activated),
80 item_addr(hs_activated), 1},
81 {"num_tx_timeout", item_size(num_tx_timeout),
82 item_addr(num_tx_timeout), 1},
83 {"num_cmd_timeout", item_size(num_cmd_timeout),
84 item_addr(num_cmd_timeout), 1},
85 {"timeout_cmd_id", item_size(timeout_cmd_id),
86 item_addr(timeout_cmd_id), 1},
87 {"timeout_cmd_act", item_size(timeout_cmd_act),
88 item_addr(timeout_cmd_act), 1},
89 {"last_cmd_id", item_size(last_cmd_id),
90 item_addr(last_cmd_id), DBG_CMD_NUM},
91 {"last_cmd_act", item_size(last_cmd_act),
92 item_addr(last_cmd_act), DBG_CMD_NUM},
93 {"last_cmd_index", item_size(last_cmd_index),
94 item_addr(last_cmd_index), 1},
95 {"last_cmd_resp_id", item_size(last_cmd_resp_id),
96 item_addr(last_cmd_resp_id), DBG_CMD_NUM},
97 {"last_cmd_resp_index", item_size(last_cmd_resp_index),
98 item_addr(last_cmd_resp_index), 1},
99 {"last_event", item_size(last_event),
100 item_addr(last_event), DBG_CMD_NUM},
101 {"last_event_index", item_size(last_event_index),
102 item_addr(last_event_index), 1},
103 {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
104 item_addr(num_cmd_host_to_card_failure), 1},
105 {"num_cmd_sleep_cfm_fail",
106 item_size(num_cmd_sleep_cfm_host_to_card_failure),
107 item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1},
108 {"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
109 item_addr(num_tx_host_to_card_failure), 1},
110 {"num_evt_deauth", item_size(num_event_deauth),
111 item_addr(num_event_deauth), 1},
112 {"num_evt_disassoc", item_size(num_event_disassoc),
113 item_addr(num_event_disassoc), 1},
114 {"num_evt_link_lost", item_size(num_event_link_lost),
115 item_addr(num_event_link_lost), 1},
116 {"num_cmd_deauth", item_size(num_cmd_deauth),
117 item_addr(num_cmd_deauth), 1},
118 {"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
119 item_addr(num_cmd_assoc_success), 1},
120 {"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
121 item_addr(num_cmd_assoc_failure), 1},
122 {"cmd_sent", item_size(cmd_sent),
123 item_addr(cmd_sent), 1},
124 {"data_sent", item_size(data_sent),
125 item_addr(data_sent), 1},
126 {"cmd_resp_received", item_size(cmd_resp_received),
127 item_addr(cmd_resp_received), 1},
128 {"event_received", item_size(event_received),
129 item_addr(event_received), 1},
130
131 /* variables defined in struct mwifiex_adapter */
132 {"ioctl_pending", adapter_item_size(ioctl_pending),
133 adapter_item_addr(ioctl_pending), 1},
134 {"tx_pending", adapter_item_size(tx_pending),
135 adapter_item_addr(tx_pending), 1},
136 {"rx_pending", adapter_item_size(rx_pending),
137 adapter_item_addr(rx_pending), 1},
138};
139
140static int num_of_items = ARRAY_SIZE(items);
141
142/*
143 * Generic proc file open handler.
144 *
145 * This function is called every time a file is accessed for read or write.
146 */
147static int
148mwifiex_open_generic(struct inode *inode, struct file *file)
149{
150 file->private_data = inode->i_private;
151 return 0;
152}
153
154/*
155 * Proc info file read handler.
156 *
157 * This function is called when the 'info' file is opened for reading.
158 * It prints the following driver related information -
159 * - Driver name
160 * - Driver version
161 * - Driver extended version
162 * - Interface name
163 * - BSS mode
164 * - Media state (connected or disconnected)
165 * - MAC address
166 * - Total number of Tx bytes
167 * - Total number of Rx bytes
168 * - Total number of Tx packets
169 * - Total number of Rx packets
170 * - Total number of dropped Tx packets
171 * - Total number of dropped Rx packets
172 * - Total number of corrupted Tx packets
173 * - Total number of corrupted Rx packets
174 * - Carrier status (on or off)
175 * - Tx queue status (started or stopped)
176 *
177 * For STA mode drivers, it also prints the following extra -
178 * - ESSID
179 * - BSSID
180 * - Channel
181 * - Region code
182 * - Multicast count
183 * - Multicast addresses
184 */
185static ssize_t
186mwifiex_info_read(struct file *file, char __user *ubuf,
187 size_t count, loff_t *ppos)
188{
189 struct mwifiex_private *priv =
190 (struct mwifiex_private *) file->private_data;
191 struct net_device *netdev = priv->netdev;
192 struct netdev_hw_addr *ha;
193 unsigned long page = get_zeroed_page(GFP_KERNEL);
194 char *p = (char *) page, fmt[64];
195 struct mwifiex_bss_info info;
196 ssize_t ret = 0;
197 int i = 0;
198
199 if (!p)
200 return -ENOMEM;
201
202 memset(&info, 0, sizeof(info));
203 ret = mwifiex_get_bss_info(priv, &info);
204 if (ret)
205 goto free_and_exit;
206
207 mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1);
208
209 if (!priv->version_str[0])
210 mwifiex_get_ver_ext(priv);
211
212 p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
213 p += sprintf(p, "driver_version = %s", fmt);
214 p += sprintf(p, "\nverext = %s", priv->version_str);
215 p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
216 p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
217 p += sprintf(p, "media_state=\"%s\"\n",
218 (!priv->media_connected ? "Disconnected" : "Connected"));
219 p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
220 netdev->dev_addr[0], netdev->dev_addr[1],
221 netdev->dev_addr[2], netdev->dev_addr[3],
222 netdev->dev_addr[4], netdev->dev_addr[5]);
223
224 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
225 p += sprintf(p, "multicast_count=\"%d\"\n",
226 netdev_mc_count(netdev));
227 p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
228 p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
229 info.bssid[0], info.bssid[1],
230 info.bssid[2], info.bssid[3],
231 info.bssid[4], info.bssid[5]);
232 p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
233 p += sprintf(p, "region_code = \"%02x\"\n", info.region_code);
234
235 netdev_for_each_mc_addr(ha, netdev)
236 p += sprintf(p, "multicast_address[%d]="
237 "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++,
238 ha->addr[0], ha->addr[1],
239 ha->addr[2], ha->addr[3],
240 ha->addr[4], ha->addr[5]);
241 }
242
243 p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
244 p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
245 p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
246 p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
247 p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
248 p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
249 p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
250 p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
251 p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
252 ? "on" : "off"));
253 p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev))
254 ? "stopped" : "started"));
255
256 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
257 (unsigned long) p - page);
258
259free_and_exit:
260 free_page(page);
261 return ret;
262}
263
264/*
265 * Proc getlog file read handler.
266 *
267 * This function is called when the 'getlog' file is opened for reading
268 * It prints the following log information -
269 * - Number of multicast Tx frames
270 * - Number of failed packets
271 * - Number of Tx retries
272 * - Number of multicast Tx retries
273 * - Number of duplicate frames
274 * - Number of RTS successes
275 * - Number of RTS failures
276 * - Number of ACK failures
277 * - Number of fragmented Rx frames
278 * - Number of multicast Rx frames
279 * - Number of FCS errors
280 * - Number of Tx frames
281 * - WEP ICV error counts
282 */
283static ssize_t
284mwifiex_getlog_read(struct file *file, char __user *ubuf,
285 size_t count, loff_t *ppos)
286{
287 struct mwifiex_private *priv =
288 (struct mwifiex_private *) file->private_data;
289 unsigned long page = get_zeroed_page(GFP_KERNEL);
290 char *p = (char *) page;
291 ssize_t ret = 0;
292 struct mwifiex_ds_get_stats stats;
293
294 if (!p)
295 return -ENOMEM;
296
297 memset(&stats, 0, sizeof(stats));
298 ret = mwifiex_get_stats_info(priv, &stats);
299 if (ret)
300 goto free_and_exit;
301
302 p += sprintf(p, "\n"
303 "mcasttxframe %u\n"
304 "failed %u\n"
305 "retry %u\n"
306 "multiretry %u\n"
307 "framedup %u\n"
308 "rtssuccess %u\n"
309 "rtsfailure %u\n"
310 "ackfailure %u\n"
311 "rxfrag %u\n"
312 "mcastrxframe %u\n"
313 "fcserror %u\n"
314 "txframe %u\n"
315 "wepicverrcnt-1 %u\n"
316 "wepicverrcnt-2 %u\n"
317 "wepicverrcnt-3 %u\n"
318 "wepicverrcnt-4 %u\n",
319 stats.mcast_tx_frame,
320 stats.failed,
321 stats.retry,
322 stats.multi_retry,
323 stats.frame_dup,
324 stats.rts_success,
325 stats.rts_failure,
326 stats.ack_failure,
327 stats.rx_frag,
328 stats.mcast_rx_frame,
329 stats.fcs_error,
330 stats.tx_frame,
331 stats.wep_icv_error[0],
332 stats.wep_icv_error[1],
333 stats.wep_icv_error[2],
334 stats.wep_icv_error[3]);
335
336
337 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
338 (unsigned long) p - page);
339
340free_and_exit:
341 free_page(page);
342 return ret;
343}
344
345static struct mwifiex_debug_info info;
346
347/*
348 * Proc debug file read handler.
349 *
350 * This function is called when the 'debug' file is opened for reading
351 * It prints the following log information -
352 * - Interrupt count
353 * - WMM AC VO packets count
354 * - WMM AC VI packets count
355 * - WMM AC BE packets count
356 * - WMM AC BK packets count
357 * - Maximum Tx buffer size
358 * - Tx buffer size
359 * - Current Tx buffer size
360 * - Power Save mode
361 * - Power Save state
362 * - Deep Sleep status
363 * - Device wakeup required status
364 * - Number of wakeup tries
365 * - Host Sleep configured status
366 * - Host Sleep activated status
367 * - Number of Tx timeouts
368 * - Number of command timeouts
369 * - Last timed out command ID
370 * - Last timed out command action
371 * - Last command ID
372 * - Last command action
373 * - Last command index
374 * - Last command response ID
375 * - Last command response index
376 * - Last event
377 * - Last event index
378 * - Number of host to card command failures
379 * - Number of sleep confirm command failures
380 * - Number of host to card data failure
381 * - Number of deauthentication events
382 * - Number of disassociation events
383 * - Number of link lost events
384 * - Number of deauthentication commands
385 * - Number of association success commands
386 * - Number of association failure commands
387 * - Number of commands sent
388 * - Number of data packets sent
389 * - Number of command responses received
390 * - Number of events received
391 * - Tx BA stream table (TID, RA)
392 * - Rx reorder table (TID, TA, Start window, Window size, Buffer)
393 */
394static ssize_t
395mwifiex_debug_read(struct file *file, char __user *ubuf,
396 size_t count, loff_t *ppos)
397{
398 struct mwifiex_private *priv =
399 (struct mwifiex_private *) file->private_data;
400 struct mwifiex_debug_data *d = &items[0];
401 unsigned long page = get_zeroed_page(GFP_KERNEL);
402 char *p = (char *) page;
403 ssize_t ret = 0;
404 size_t size, addr;
405 long val;
406 int i, j;
407
408 if (!p)
409 return -ENOMEM;
410
411 ret = mwifiex_get_debug_info(priv, &info);
412 if (ret)
413 goto free_and_exit;
414
415 for (i = 0; i < num_of_items; i++) {
416 p += sprintf(p, "%s=", d[i].name);
417
418 size = d[i].size / d[i].num;
419
420 if (i < (num_of_items - 3))
421 addr = d[i].addr + (size_t) &info;
422 else /* The last 3 items are struct mwifiex_adapter variables */
423 addr = d[i].addr + (size_t) priv->adapter;
424
425 for (j = 0; j < d[i].num; j++) {
426 switch (size) {
427 case 1:
428 val = *((u8 *) addr);
429 break;
430 case 2:
431 val = *((u16 *) addr);
432 break;
433 case 4:
434 val = *((u32 *) addr);
435 break;
436 case 8:
437 val = *((long long *) addr);
438 break;
439 default:
440 val = -1;
441 break;
442 }
443
444 p += sprintf(p, "%#lx ", val);
445 addr += size;
446 }
447
448 p += sprintf(p, "\n");
449 }
450
451 if (info.tx_tbl_num) {
452 p += sprintf(p, "Tx BA stream table:\n");
453 for (i = 0; i < info.tx_tbl_num; i++)
454 p += sprintf(p, "tid = %d, "
455 "ra = %02x:%02x:%02x:%02x:%02x:%02x\n",
456 info.tx_tbl[i].tid, info.tx_tbl[i].ra[0],
457 info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2],
458 info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4],
459 info.tx_tbl[i].ra[5]);
460 }
461
462 if (info.rx_tbl_num) {
463 p += sprintf(p, "Rx reorder table:\n");
464 for (i = 0; i < info.rx_tbl_num; i++) {
465
466 p += sprintf(p, "tid = %d, "
467 "ta = %02x:%02x:%02x:%02x:%02x:%02x, "
468 "start_win = %d, "
469 "win_size = %d, buffer: ",
470 info.rx_tbl[i].tid,
471 info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1],
472 info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3],
473 info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5],
474 info.rx_tbl[i].start_win,
475 info.rx_tbl[i].win_size);
476
477 for (j = 0; j < info.rx_tbl[i].win_size; j++)
478 p += sprintf(p, "%c ",
479 info.rx_tbl[i].buffer[j] ?
480 '1' : '0');
481
482 p += sprintf(p, "\n");
483 }
484 }
485
486 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
487 (unsigned long) p - page);
488
489free_and_exit:
490 free_page(page);
491 return ret;
492}
493
494static u32 saved_reg_type, saved_reg_offset, saved_reg_value;
495
496/*
497 * Proc regrdwr file write handler.
498 *
499 * This function is called when the 'regrdwr' file is opened for writing
500 *
501 * This function can be used to write to a register.
502 */
503static ssize_t
504mwifiex_regrdwr_write(struct file *file,
505 const char __user *ubuf, size_t count, loff_t *ppos)
506{
507 unsigned long addr = get_zeroed_page(GFP_KERNEL);
508 char *buf = (char *) addr;
509 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
510 int ret = 0;
511 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
512
513 if (!buf)
514 return -ENOMEM;
515
516
517 if (copy_from_user(buf, ubuf, buf_size)) {
518 ret = -EFAULT;
519 goto done;
520 }
521
522 sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);
523
524 if (reg_type == 0 || reg_offset == 0) {
525 ret = -EINVAL;
526 goto done;
527 } else {
528 saved_reg_type = reg_type;
529 saved_reg_offset = reg_offset;
530 saved_reg_value = reg_value;
531 ret = count;
532 }
533done:
534 free_page(addr);
535 return ret;
536}
537
538/*
539 * Proc regrdwr file read handler.
540 *
541 * This function is called when the 'regrdwr' file is opened for reading
542 *
543 * This function can be used to read from a register.
544 */
545static ssize_t
546mwifiex_regrdwr_read(struct file *file, char __user *ubuf,
547 size_t count, loff_t *ppos)
548{
549 struct mwifiex_private *priv =
550 (struct mwifiex_private *) file->private_data;
551 unsigned long addr = get_zeroed_page(GFP_KERNEL);
552 char *buf = (char *) addr;
553 int pos = 0, ret = 0;
554 u32 reg_value;
555
556 if (!buf)
557 return -ENOMEM;
558
559 if (!saved_reg_type) {
560 /* No command has been given */
561 pos += snprintf(buf, PAGE_SIZE, "0");
562 goto done;
563 }
564 /* Set command has been given */
565 if (saved_reg_value != UINT_MAX) {
566 ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset,
567 saved_reg_value);
568
569 pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n",
570 saved_reg_type, saved_reg_offset,
571 saved_reg_value);
572
573 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
574
575 goto done;
576 }
577 /* Get command has been given */
578 ret = mwifiex_reg_read(priv, saved_reg_type,
579 saved_reg_offset, &reg_value);
580 if (ret) {
581 ret = -EINVAL;
582 goto done;
583 }
584
585 pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type,
586 saved_reg_offset, reg_value);
587
588 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
589
590done:
591 free_page(addr);
592 return ret;
593}
594
595static u32 saved_offset = -1, saved_bytes = -1;
596
597/*
598 * Proc rdeeprom file write handler.
599 *
600 * This function is called when the 'rdeeprom' file is opened for writing
601 *
602 * This function can be used to write to a RDEEPROM location.
603 */
604static ssize_t
605mwifiex_rdeeprom_write(struct file *file,
606 const char __user *ubuf, size_t count, loff_t *ppos)
607{
608 unsigned long addr = get_zeroed_page(GFP_KERNEL);
609 char *buf = (char *) addr;
610 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
611 int ret = 0;
612 int offset = -1, bytes = -1;
613
614 if (!buf)
615 return -ENOMEM;
616
617
618 if (copy_from_user(buf, ubuf, buf_size)) {
619 ret = -EFAULT;
620 goto done;
621 }
622
623 sscanf(buf, "%d %d", &offset, &bytes);
624
625 if (offset == -1 || bytes == -1) {
626 ret = -EINVAL;
627 goto done;
628 } else {
629 saved_offset = offset;
630 saved_bytes = bytes;
631 ret = count;
632 }
633done:
634 free_page(addr);
635 return ret;
636}
637
638/*
639 * Proc rdeeprom read write handler.
640 *
641 * This function is called when the 'rdeeprom' file is opened for reading
642 *
643 * This function can be used to read from a RDEEPROM location.
644 */
645static ssize_t
646mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
647 size_t count, loff_t *ppos)
648{
649 struct mwifiex_private *priv =
650 (struct mwifiex_private *) file->private_data;
651 unsigned long addr = get_zeroed_page(GFP_KERNEL);
652 char *buf = (char *) addr;
653 int pos = 0, ret = 0, i = 0;
654 u8 value[MAX_EEPROM_DATA];
655
656 if (!buf)
657 return -ENOMEM;
658
659 if (saved_offset == -1) {
660 /* No command has been given */
661 pos += snprintf(buf, PAGE_SIZE, "0");
662 goto done;
663 }
664
665 /* Get command has been given */
666 ret = mwifiex_eeprom_read(priv, (u16) saved_offset,
667 (u16) saved_bytes, value);
668 if (ret) {
669 ret = -EINVAL;
670 goto done;
671 }
672
673 pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
674
675 for (i = 0; i < saved_bytes; i++)
676 pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]);
677
678 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
679
680done:
681 free_page(addr);
682 return ret;
683}
684
685
686#define MWIFIEX_DFS_ADD_FILE(name) do { \
687 if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
688 priv, &mwifiex_dfs_##name##_fops)) \
689 return; \
690} while (0);
691
692#define MWIFIEX_DFS_FILE_OPS(name) \
693static const struct file_operations mwifiex_dfs_##name##_fops = { \
694 .read = mwifiex_##name##_read, \
695 .write = mwifiex_##name##_write, \
696 .open = mwifiex_open_generic, \
697};
698
699#define MWIFIEX_DFS_FILE_READ_OPS(name) \
700static const struct file_operations mwifiex_dfs_##name##_fops = { \
701 .read = mwifiex_##name##_read, \
702 .open = mwifiex_open_generic, \
703};
704
705#define MWIFIEX_DFS_FILE_WRITE_OPS(name) \
706static const struct file_operations mwifiex_dfs_##name##_fops = { \
707 .write = mwifiex_##name##_write, \
708 .open = mwifiex_open_generic, \
709};
710
711
712MWIFIEX_DFS_FILE_READ_OPS(info);
713MWIFIEX_DFS_FILE_READ_OPS(debug);
714MWIFIEX_DFS_FILE_READ_OPS(getlog);
715MWIFIEX_DFS_FILE_OPS(regrdwr);
716MWIFIEX_DFS_FILE_OPS(rdeeprom);
717
718/*
719 * This function creates the debug FS directory structure and the files.
720 */
721void
722mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
723{
724 if (!mwifiex_dfs_dir || !priv)
725 return;
726
727 priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
728 mwifiex_dfs_dir);
729
730 if (!priv->dfs_dev_dir)
731 return;
732
733 MWIFIEX_DFS_ADD_FILE(info);
734 MWIFIEX_DFS_ADD_FILE(debug);
735 MWIFIEX_DFS_ADD_FILE(getlog);
736 MWIFIEX_DFS_ADD_FILE(regrdwr);
737 MWIFIEX_DFS_ADD_FILE(rdeeprom);
738
739 return;
740}
741
742/*
743 * This function removes the debug FS directory structure and the files.
744 */
745void
746mwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
747{
748 if (!priv)
749 return;
750
751 debugfs_remove_recursive(priv->dfs_dev_dir);
752 return;
753}
754
755/*
756 * This function creates the top level proc directory.
757 */
758void
759mwifiex_debugfs_init(void)
760{
761 if (!mwifiex_dfs_dir)
762 mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL);
763}
764
765/*
766 * This function removes the top level proc directory.
767 */
768void
769mwifiex_debugfs_remove(void)
770{
771 if (mwifiex_dfs_dir)
772 debugfs_remove(mwifiex_dfs_dir);
773}
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
new file mode 100644
index 000000000000..c3c15f9e757e
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -0,0 +1,153 @@
1/*
2 * Marvell Wireless LAN device driver: generic data structures and APIs
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_DECL_H_
21#define _MWIFIEX_DECL_H_
22
23#undef pr_fmt
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#include <linux/wait.h>
27#include <linux/timer.h>
28#include <linux/ieee80211.h>
29
30
31#define MWIFIEX_MAX_BSS_NUM (1)
32
33#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */
34
35#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
36#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
37
38#define MWIFIEX_AMPDU_DEF_TXWINSIZE 32
39#define MWIFIEX_AMPDU_DEF_RXWINSIZE 16
40#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff
41
42#define MWIFIEX_RATE_INDEX_HRDSSS0 0
43#define MWIFIEX_RATE_INDEX_HRDSSS3 3
44#define MWIFIEX_RATE_INDEX_OFDM0 4
45#define MWIFIEX_RATE_INDEX_OFDM7 11
46#define MWIFIEX_RATE_INDEX_MCS0 12
47
48#define MWIFIEX_RATE_BITMAP_OFDM0 16
49#define MWIFIEX_RATE_BITMAP_OFDM7 23
50#define MWIFIEX_RATE_BITMAP_MCS0 32
51#define MWIFIEX_RATE_BITMAP_MCS127 159
52
53#define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024)
54
55#define MWIFIEX_RTS_MIN_VALUE (0)
56#define MWIFIEX_RTS_MAX_VALUE (2347)
57#define MWIFIEX_FRAG_MIN_VALUE (256)
58#define MWIFIEX_FRAG_MAX_VALUE (2346)
59
60#define MWIFIEX_SDIO_BLOCK_SIZE 256
61
62#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
63
64enum mwifiex_error_code {
65 MWIFIEX_ERROR_NO_ERROR = 0,
66 MWIFIEX_ERROR_FW_NOT_READY = 0x00000001,
67 MWIFIEX_ERROR_FW_BUSY,
68 MWIFIEX_ERROR_FW_CMDRESP,
69 MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001,
70 MWIFIEX_ERROR_PKT_TIMEOUT,
71 MWIFIEX_ERROR_CMD_INVALID,
72 MWIFIEX_ERROR_CMD_TIMEOUT,
73 MWIFIEX_ERROR_CMD_DNLD_FAIL,
74 MWIFIEX_ERROR_CMD_CANCEL,
75 MWIFIEX_ERROR_CMD_RESP_FAIL,
76 MWIFIEX_ERROR_ASSOC_FAIL,
77 MWIFIEX_ERROR_EVENT_UNKNOWN,
78 MWIFIEX_ERROR_INVALID_PARAMETER,
79};
80
81enum mwifiex_bss_type {
82 MWIFIEX_BSS_TYPE_STA = 0,
83 MWIFIEX_BSS_TYPE_UAP = 1,
84 MWIFIEX_BSS_TYPE_ANY = 0xff,
85};
86
87enum mwifiex_bss_role {
88 MWIFIEX_BSS_ROLE_STA = 0,
89 MWIFIEX_BSS_ROLE_UAP = 1,
90 MWIFIEX_BSS_ROLE_ANY = 0xff,
91};
92
93#define BSS_ROLE_BIT_MASK BIT(0)
94
95#define GET_BSS_ROLE(priv) ((priv)->bss_role & BSS_ROLE_BIT_MASK)
96
97enum mwifiex_data_frame_type {
98 MWIFIEX_DATA_FRAME_TYPE_ETH_II = 0,
99 MWIFIEX_DATA_FRAME_TYPE_802_11,
100};
101
102struct mwifiex_fw_image {
103 u8 *helper_buf;
104 u32 helper_len;
105 u8 *fw_buf;
106 u32 fw_len;
107};
108
109struct mwifiex_802_11_ssid {
110 u32 ssid_len;
111 u8 ssid[IEEE80211_MAX_SSID_LEN];
112};
113
114struct mwifiex_wait_queue {
115 u32 bss_index;
116 wait_queue_head_t *wait;
117 u16 *condition;
118 u32 start_time;
119 int status;
120 u32 enabled;
121};
122
123struct mwifiex_rxinfo {
124 u8 bss_index;
125 struct sk_buff *parent;
126 u8 use_count;
127};
128
129struct mwifiex_txinfo {
130 u32 status_code;
131 u8 flags;
132 u8 bss_index;
133};
134
135struct mwifiex_bss_attr {
136 u32 bss_type;
137 u32 frame_type;
138 u32 active;
139 u32 bss_priority;
140 u32 bss_num;
141};
142
143enum mwifiex_wmm_ac_e {
144 WMM_AC_BK,
145 WMM_AC_BE,
146 WMM_AC_VI,
147 WMM_AC_VO
148} __packed;
149
150struct mwifiex_device {
151 struct mwifiex_bss_attr bss_attr[MWIFIEX_MAX_BSS_NUM];
152};
153#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
new file mode 100644
index 000000000000..2b938115b26a
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -0,0 +1,1229 @@
1/*
2 * Marvell Wireless LAN device driver: Firmware specific macros & structures
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_FW_H_
21#define _MWIFIEX_FW_H_
22
23#include <linux/if_ether.h>
24
25
26#define INTF_HEADER_LEN 4
27
28struct rfc_1042_hdr {
29 u8 llc_dsap;
30 u8 llc_ssap;
31 u8 llc_ctrl;
32 u8 snap_oui[3];
33 u16 snap_type;
34};
35
36struct rx_packet_hdr {
37 struct ethhdr eth803_hdr;
38 struct rfc_1042_hdr rfc1042_hdr;
39};
40
41struct tx_packet_hdr {
42 struct ethhdr eth803_hdr;
43 struct rfc_1042_hdr rfc1042_hdr;
44};
45
46#define B_SUPPORTED_RATES 5
47#define G_SUPPORTED_RATES 9
48#define BG_SUPPORTED_RATES 13
49#define A_SUPPORTED_RATES 9
50#define HOSTCMD_SUPPORTED_RATES 14
51#define N_SUPPORTED_RATES 3
52#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN)
53
54#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11))
55#define IS_SUPPORT_MULTI_BANDS(adapter) \
56 (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
57#define GET_FW_DEFAULT_BANDS(adapter) \
58 ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS)
59
60extern u8 supported_rates_b[B_SUPPORTED_RATES];
61extern u8 supported_rates_g[G_SUPPORTED_RATES];
62extern u8 supported_rates_bg[BG_SUPPORTED_RATES];
63extern u8 supported_rates_a[A_SUPPORTED_RATES];
64extern u8 supported_rates_n[N_SUPPORTED_RATES];
65
66#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
67
68#define KEY_INFO_ENABLED 0x01
69enum KEY_TYPE_ID {
70 KEY_TYPE_ID_WEP = 0,
71 KEY_TYPE_ID_TKIP,
72 KEY_TYPE_ID_AES,
73 KEY_TYPE_ID_WAPI,
74};
75
76enum KEY_INFO_WEP {
77 KEY_INFO_WEP_MCAST = 0x01,
78 KEY_INFO_WEP_UNICAST = 0x02,
79 KEY_INFO_WEP_ENABLED = 0x04
80};
81
82enum KEY_INFO_TKIP {
83 KEY_INFO_TKIP_MCAST = 0x01,
84 KEY_INFO_TKIP_UNICAST = 0x02,
85 KEY_INFO_TKIP_ENABLED = 0x04
86};
87
88enum KEY_INFO_AES {
89 KEY_INFO_AES_MCAST = 0x01,
90 KEY_INFO_AES_UNICAST = 0x02,
91 KEY_INFO_AES_ENABLED = 0x04
92};
93
94#define WAPI_KEY_LEN 50
95
96enum KEY_INFO_WAPI {
97 KEY_INFO_WAPI_MCAST = 0x01,
98 KEY_INFO_WAPI_UNICAST = 0x02,
99 KEY_INFO_WAPI_ENABLED = 0x04
100};
101
102#define MAX_POLL_TRIES 100
103
104#define MAX_MULTI_INTERFACE_POLL_TRIES 1000
105
106#define MAX_FIRMWARE_POLL_TRIES 100
107
108#define FIRMWARE_READY 0xfedc
109
110enum MWIFIEX_802_11_PRIVACY_FILTER {
111 MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL,
112 MWIFIEX_802_11_PRIV_FILTER_8021X_WEP
113};
114
115enum MWIFIEX_802_11_WEP_STATUS {
116 MWIFIEX_802_11_WEP_ENABLED,
117 MWIFIEX_802_11_WEP_DISABLED,
118};
119
120#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF)))
121
122#define PROPRIETARY_TLV_BASE_ID 0x0100
123#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
124#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1)
125#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2)
126#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10)
127#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16)
128#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18)
129#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
130#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
131#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
132#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
133#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
134#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
135#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
136#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113)
137#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114)
138
139#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
140
141#define SSN_MASK 0xfff0
142
143#define BA_RESULT_SUCCESS 0x0
144#define BA_RESULT_TIMEOUT 0x2
145
146#define IS_BASTREAM_SETUP(ptr) (ptr->ba_status)
147
148#define BA_STREAM_NOT_ALLOWED 0xff
149
150#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \
151 priv->adapter->config_bands & BAND_AN) \
152 && priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
153#define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\
154 BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS)
155
156#define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096
157#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192
158#define NON_GREENFIELD_STAS 0x04
159
160#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
161
162/* dev_cap bitmap
163 * BIT
164 * 0-16 reserved
165 * 17 IEEE80211_HT_CAP_SUP_WIDTH_20_40
166 * 18-22 reserved
167 * 23 IEEE80211_HT_CAP_SGI_20
168 * 24 IEEE80211_HT_CAP_SGI_40
169 * 25 IEEE80211_HT_CAP_TX_STBC
170 * 26 IEEE80211_HT_CAP_RX_STBC
171 * 27-28 reserved
172 * 29 IEEE80211_HT_CAP_GRN_FLD
173 * 30-31 reserved
174 */
175#define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & BIT(17))
176#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23))
177#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24))
178#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25))
179#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26))
180#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
181
182#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
183#define RESETHT_EXTCAP_RDG(HTExtCap) (HTExtCap &= ~BIT(11))
184#define SETHT_MCS32(x) (x[4] |= 1)
185
186#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
187
188#define LLC_SNAP_LEN 8
189
190#define MOD_CLASS_HR_DSSS 0x03
191#define MOD_CLASS_OFDM 0x07
192#define MOD_CLASS_HT 0x08
193#define HT_BW_20 0
194#define HT_BW_40 1
195
196#define HostCmd_CMD_GET_HW_SPEC 0x0003
197#define HostCmd_CMD_802_11_SCAN 0x0006
198#define HostCmd_CMD_802_11_GET_LOG 0x000b
199#define HostCmd_CMD_MAC_MULTICAST_ADR 0x0010
200#define HostCmd_CMD_802_11_EEPROM_ACCESS 0x0059
201#define HostCmd_CMD_802_11_ASSOCIATE 0x0012
202#define HostCmd_CMD_802_11_SNMP_MIB 0x0016
203#define HostCmd_CMD_MAC_REG_ACCESS 0x0019
204#define HostCmd_CMD_BBP_REG_ACCESS 0x001a
205#define HostCmd_CMD_RF_REG_ACCESS 0x001b
206#define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad
207#define HostCmd_CMD_802_11_RF_CHANNEL 0x001d
208#define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024
209#define HostCmd_CMD_MAC_CONTROL 0x0028
210#define HostCmd_CMD_802_11_AD_HOC_START 0x002b
211#define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c
212#define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040
213#define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D
214#define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b
215#define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e
216#define HostCmd_CMD_802_11_BG_SCAN_QUERY 0x006c
217#define HostCmd_CMD_WMM_GET_STATUS 0x0071
218#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
219#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
220#define HostCmd_CMD_VERSION_EXT 0x0097
221#define HostCmd_CMD_RSSI_INFO 0x00a4
222#define HostCmd_CMD_FUNC_INIT 0x00a9
223#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa
224#define HostCmd_CMD_11N_CFG 0x00cd
225#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
226#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
227#define HostCmd_CMD_11N_DELBA 0x00d0
228#define HostCmd_CMD_RECONFIGURE_TX_BUFF 0x00d9
229#define HostCmd_CMD_AMSDU_AGGR_CTRL 0x00df
230#define HostCmd_CMD_TXPWR_CFG 0x00d1
231#define HostCmd_CMD_TX_RATE_CFG 0x00d6
232#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4
233#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
234#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
235#define HostCmd_CMD_SET_BSS_MODE 0x00f7
236
237
238enum ENH_PS_MODES {
239 EN_PS = 1,
240 DIS_PS = 2,
241 EN_AUTO_DS = 3,
242 DIS_AUTO_DS = 4,
243 SLEEP_CONFIRM = 5,
244 GET_PS = 0,
245 EN_AUTO_PS = 0xff,
246 DIS_AUTO_PS = 0xfe,
247};
248
249#define HostCmd_RET_BIT 0x8000
250#define HostCmd_ACT_GEN_GET 0x0000
251#define HostCmd_ACT_GEN_SET 0x0001
252#define HostCmd_RESULT_OK 0x0000
253
254#define HostCmd_ACT_MAC_RX_ON 0x0001
255#define HostCmd_ACT_MAC_TX_ON 0x0002
256#define HostCmd_ACT_MAC_WEP_ENABLE 0x0008
257#define HostCmd_ACT_MAC_ETHERNETII_ENABLE 0x0010
258#define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE 0x0080
259#define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100
260#define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON 0x2000
261
262#define HostCmd_BSS_MODE_IBSS 0x0002
263#define HostCmd_BSS_MODE_ANY 0x0003
264
265#define HostCmd_SCAN_RADIO_TYPE_BG 0
266#define HostCmd_SCAN_RADIO_TYPE_A 1
267
268#define HOST_SLEEP_CFG_CANCEL 0xffffffff
269#define HOST_SLEEP_CFG_COND_DEF 0x0000000f
270#define HOST_SLEEP_CFG_GPIO_DEF 0xff
271#define HOST_SLEEP_CFG_GAP_DEF 0
272
273#define CMD_F_HOSTCMD (1 << 0)
274#define CMD_F_CANCELED (1 << 1)
275
276#define HostCmd_CMD_ID_MASK 0x0fff
277
278#define HostCmd_SEQ_NUM_MASK 0x00ff
279
280#define HostCmd_BSS_NUM_MASK 0x0f00
281
282#define HostCmd_BSS_TYPE_MASK 0xf000
283
284#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) { \
285 (((seq) & 0x00ff) | \
286 (((num) & 0x000f) << 8)) | \
287 (((type) & 0x000f) << 12); }
288
289#define HostCmd_GET_SEQ_NO(seq) \
290 ((seq) & HostCmd_SEQ_NUM_MASK)
291
292#define HostCmd_GET_BSS_NO(seq) \
293 (((seq) & HostCmd_BSS_NUM_MASK) >> 8)
294
295#define HostCmd_GET_BSS_TYPE(seq) \
296 (((seq) & HostCmd_BSS_TYPE_MASK) >> 12)
297
298#define EVENT_DUMMY_HOST_WAKEUP_SIGNAL 0x00000001
299#define EVENT_LINK_LOST 0x00000003
300#define EVENT_LINK_SENSED 0x00000004
301#define EVENT_MIB_CHANGED 0x00000006
302#define EVENT_INIT_DONE 0x00000007
303#define EVENT_DEAUTHENTICATED 0x00000008
304#define EVENT_DISASSOCIATED 0x00000009
305#define EVENT_PS_AWAKE 0x0000000a
306#define EVENT_PS_SLEEP 0x0000000b
307#define EVENT_MIC_ERR_MULTICAST 0x0000000d
308#define EVENT_MIC_ERR_UNICAST 0x0000000e
309#define EVENT_DEEP_SLEEP_AWAKE 0x00000010
310#define EVENT_ADHOC_BCN_LOST 0x00000011
311
312#define EVENT_WMM_STATUS_CHANGE 0x00000017
313#define EVENT_BG_SCAN_REPORT 0x00000018
314#define EVENT_RSSI_LOW 0x00000019
315#define EVENT_SNR_LOW 0x0000001a
316#define EVENT_MAX_FAIL 0x0000001b
317#define EVENT_RSSI_HIGH 0x0000001c
318#define EVENT_SNR_HIGH 0x0000001d
319#define EVENT_IBSS_COALESCED 0x0000001e
320#define EVENT_DATA_RSSI_LOW 0x00000024
321#define EVENT_DATA_SNR_LOW 0x00000025
322#define EVENT_DATA_RSSI_HIGH 0x00000026
323#define EVENT_DATA_SNR_HIGH 0x00000027
324#define EVENT_LINK_QUALITY 0x00000028
325#define EVENT_PORT_RELEASE 0x0000002b
326#define EVENT_PRE_BEACON_LOST 0x00000031
327#define EVENT_ADDBA 0x00000033
328#define EVENT_DELBA 0x00000034
329#define EVENT_BA_STREAM_TIEMOUT 0x00000037
330#define EVENT_AMSDU_AGGR_CTRL 0x00000042
331#define EVENT_WEP_ICV_ERR 0x00000046
332#define EVENT_HS_ACT_REQ 0x00000047
333#define EVENT_BW_CHANGE 0x00000048
334
335#define EVENT_HOSTWAKE_STAIE 0x0000004d
336
337#define EVENT_ID_MASK 0xffff
338#define BSS_NUM_MASK 0xf
339
340#define EVENT_GET_BSS_NUM(event_cause) \
341 (((event_cause) >> 16) & BSS_NUM_MASK)
342
343#define EVENT_GET_BSS_TYPE(event_cause) \
344 (((event_cause) >> 24) & 0x00ff)
345
346struct mwifiex_ie_types_header {
347 __le16 type;
348 __le16 len;
349} __packed;
350
351struct mwifiex_ie_types_data {
352 struct mwifiex_ie_types_header header;
353 u8 data[1];
354} __packed;
355
356#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01
357#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08
358
359struct txpd {
360 u8 bss_type;
361 u8 bss_num;
362 __le16 tx_pkt_length;
363 __le16 tx_pkt_offset;
364 __le16 tx_pkt_type;
365 __le32 tx_control;
366 u8 priority;
367 u8 flags;
368 u8 pkt_delay_2ms;
369 u8 reserved1;
370} __packed;
371
372struct rxpd {
373 u8 bss_type;
374 u8 bss_num;
375 u16 rx_pkt_length;
376 u16 rx_pkt_offset;
377 u16 rx_pkt_type;
378 u16 seq_num;
379 u8 priority;
380 u8 rx_rate;
381 s8 snr;
382 s8 nf;
383 /* Ht Info [Bit 0] RxRate format: LG=0, HT=1
384 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
385 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */
386 u8 ht_info;
387 u8 reserved;
388} __packed;
389
390enum mwifiex_chan_scan_mode_bitmasks {
391 MWIFIEX_PASSIVE_SCAN = BIT(0),
392 MWIFIEX_DISABLE_CHAN_FILT = BIT(1),
393};
394
395#define SECOND_CHANNEL_BELOW 0x30
396#define SECOND_CHANNEL_ABOVE 0x10
397struct mwifiex_chan_scan_param_set {
398 u8 radio_type;
399 u8 chan_number;
400 u8 chan_scan_mode_bitmap;
401 __le16 min_scan_time;
402 __le16 max_scan_time;
403} __packed;
404
405struct mwifiex_ie_types_chan_list_param_set {
406 struct mwifiex_ie_types_header header;
407 struct mwifiex_chan_scan_param_set chan_scan_param[1];
408} __packed;
409
410struct chan_band_param_set {
411 u8 radio_type;
412 u8 chan_number;
413};
414
415struct mwifiex_ie_types_chan_band_list_param_set {
416 struct mwifiex_ie_types_header header;
417 struct chan_band_param_set chan_band_param[1];
418} __packed;
419
420struct mwifiex_ie_types_rates_param_set {
421 struct mwifiex_ie_types_header header;
422 u8 rates[1];
423} __packed;
424
425struct mwifiex_ie_types_ssid_param_set {
426 struct mwifiex_ie_types_header header;
427 u8 ssid[1];
428} __packed;
429
430struct mwifiex_ie_types_num_probes {
431 struct mwifiex_ie_types_header header;
432 __le16 num_probes;
433} __packed;
434
435struct mwifiex_ie_types_wildcard_ssid_params {
436 struct mwifiex_ie_types_header header;
437 u8 max_ssid_length;
438 u8 ssid[1];
439} __packed;
440
441#define TSF_DATA_SIZE 8
442struct mwifiex_ie_types_tsf_timestamp {
443 struct mwifiex_ie_types_header header;
444 u8 tsf_data[1];
445} __packed;
446
447struct mwifiex_cf_param_set {
448 u8 cfp_cnt;
449 u8 cfp_period;
450 u16 cfp_max_duration;
451 u16 cfp_duration_remaining;
452} __packed;
453
454struct mwifiex_ibss_param_set {
455 u16 atim_window;
456} __packed;
457
458struct mwifiex_ie_types_ss_param_set {
459 struct mwifiex_ie_types_header header;
460 union {
461 struct mwifiex_cf_param_set cf_param_set[1];
462 struct mwifiex_ibss_param_set ibss_param_set[1];
463 } cf_ibss;
464} __packed;
465
466struct mwifiex_fh_param_set {
467 u16 dwell_time;
468 u8 hop_set;
469 u8 hop_pattern;
470 u8 hop_index;
471} __packed;
472
473struct mwifiex_ds_param_set {
474 u8 current_chan;
475} __packed;
476
477struct mwifiex_ie_types_phy_param_set {
478 struct mwifiex_ie_types_header header;
479 union {
480 struct mwifiex_fh_param_set fh_param_set[1];
481 struct mwifiex_ds_param_set ds_param_set[1];
482 } fh_ds;
483} __packed;
484
485struct mwifiex_ie_types_auth_type {
486 struct mwifiex_ie_types_header header;
487 __le16 auth_type;
488} __packed;
489
490struct mwifiex_ie_types_vendor_param_set {
491 struct mwifiex_ie_types_header header;
492 u8 ie[MWIFIEX_MAX_VSIE_LEN];
493};
494
495struct mwifiex_ie_types_rsn_param_set {
496 struct mwifiex_ie_types_header header;
497 u8 rsn_ie[1];
498} __packed;
499
500#define KEYPARAMSET_FIXED_LEN 6
501
502struct mwifiex_ie_type_key_param_set {
503 __le16 type;
504 __le16 length;
505 __le16 key_type_id;
506 __le16 key_info;
507 __le16 key_len;
508 u8 key[50];
509} __packed;
510
511struct host_cmd_ds_802_11_key_material {
512 __le16 action;
513 struct mwifiex_ie_type_key_param_set key_param_set;
514} __packed;
515
516struct host_cmd_ds_gen {
517 u16 command;
518 u16 size;
519 u16 seq_num;
520 u16 result;
521};
522
523#define S_DS_GEN sizeof(struct host_cmd_ds_gen)
524
525enum sleep_resp_ctrl {
526 RESP_NOT_NEEDED = 0,
527 RESP_NEEDED,
528};
529
530struct mwifiex_ps_param {
531 __le16 null_pkt_interval;
532 __le16 multiple_dtims;
533 __le16 bcn_miss_timeout;
534 __le16 local_listen_interval;
535 __le16 adhoc_wake_period;
536 __le16 mode;
537 __le16 delay_to_ps;
538};
539
540#define BITMAP_AUTO_DS 0x01
541#define BITMAP_STA_PS 0x10
542
543struct mwifiex_ie_types_auto_ds_param {
544 struct mwifiex_ie_types_header header;
545 __le16 deep_sleep_timeout;
546} __packed;
547
548struct mwifiex_ie_types_ps_param {
549 struct mwifiex_ie_types_header header;
550 struct mwifiex_ps_param param;
551} __packed;
552
553struct host_cmd_ds_802_11_ps_mode_enh {
554 __le16 action;
555
556 union {
557 struct mwifiex_ps_param opt_ps;
558 __le16 ps_bitmap;
559 } params;
560} __packed;
561
562struct host_cmd_ds_get_hw_spec {
563 __le16 hw_if_version;
564 __le16 version;
565 __le16 reserved;
566 __le16 num_of_mcast_adr;
567 u8 permanent_addr[ETH_ALEN];
568 __le16 region_code;
569 __le16 number_of_antenna;
570 __le32 fw_release_number;
571 __le32 reserved_1;
572 __le32 reserved_2;
573 __le32 reserved_3;
574 __le32 fw_cap_info;
575 __le32 dot_11n_dev_cap;
576 u8 dev_mcs_support;
577 __le16 mp_end_port; /* SDIO only, reserved for other interfacces */
578 __le16 reserved_4;
579} __packed;
580
581struct host_cmd_ds_802_11_rssi_info {
582 __le16 action;
583 __le16 ndata;
584 __le16 nbcn;
585 __le16 reserved[9];
586 long long reserved_1;
587};
588
589struct host_cmd_ds_802_11_rssi_info_rsp {
590 __le16 action;
591 __le16 ndata;
592 __le16 nbcn;
593 __le16 data_rssi_last;
594 __le16 data_nf_last;
595 __le16 data_rssi_avg;
596 __le16 data_nf_avg;
597 __le16 bcn_rssi_last;
598 __le16 bcn_nf_last;
599 __le16 bcn_rssi_avg;
600 __le16 bcn_nf_avg;
601 long long tsf_bcn;
602};
603
604struct host_cmd_ds_802_11_mac_address {
605 __le16 action;
606 u8 mac_addr[ETH_ALEN];
607};
608
609struct host_cmd_ds_mac_control {
610 __le16 action;
611 __le16 reserved;
612};
613
614struct host_cmd_ds_mac_multicast_adr {
615 __le16 action;
616 __le16 num_of_adrs;
617 u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
618} __packed;
619
620struct host_cmd_ds_802_11_deauthenticate {
621 u8 mac_addr[ETH_ALEN];
622 __le16 reason_code;
623} __packed;
624
625struct host_cmd_ds_802_11_associate {
626 u8 peer_sta_addr[ETH_ALEN];
627 __le16 cap_info_bitmap;
628 __le16 listen_interval;
629 __le16 beacon_period;
630 u8 dtim_period;
631} __packed;
632
633struct ieee_types_assoc_rsp {
634 __le16 cap_info_bitmap;
635 __le16 status_code;
636 __le16 a_id;
637 u8 ie_buffer[1];
638} __packed;
639
640struct host_cmd_ds_802_11_associate_rsp {
641 struct ieee_types_assoc_rsp assoc_rsp;
642} __packed;
643
644struct ieee_types_cf_param_set {
645 u8 element_id;
646 u8 len;
647 u8 cfp_cnt;
648 u8 cfp_period;
649 u16 cfp_max_duration;
650 u16 cfp_duration_remaining;
651} __packed;
652
653struct ieee_types_ibss_param_set {
654 u8 element_id;
655 u8 len;
656 __le16 atim_window;
657} __packed;
658
659union ieee_types_ss_param_set {
660 struct ieee_types_cf_param_set cf_param_set;
661 struct ieee_types_ibss_param_set ibss_param_set;
662} __packed;
663
664struct ieee_types_fh_param_set {
665 u8 element_id;
666 u8 len;
667 __le16 dwell_time;
668 u8 hop_set;
669 u8 hop_pattern;
670 u8 hop_index;
671} __packed;
672
673struct ieee_types_ds_param_set {
674 u8 element_id;
675 u8 len;
676 u8 current_chan;
677} __packed;
678
679union ieee_types_phy_param_set {
680 struct ieee_types_fh_param_set fh_param_set;
681 struct ieee_types_ds_param_set ds_param_set;
682} __packed;
683
684struct host_cmd_ds_802_11_ad_hoc_start {
685 u8 ssid[IEEE80211_MAX_SSID_LEN];
686 u8 bss_mode;
687 __le16 beacon_period;
688 u8 dtim_period;
689 union ieee_types_ss_param_set ss_param_set;
690 union ieee_types_phy_param_set phy_param_set;
691 u16 reserved1;
692 __le16 cap_info_bitmap;
693 u8 DataRate[HOSTCMD_SUPPORTED_RATES];
694} __packed;
695
696struct host_cmd_ds_802_11_ad_hoc_result {
697 u8 pad[3];
698 u8 bssid[ETH_ALEN];
699} __packed;
700
701struct adhoc_bss_desc {
702 u8 bssid[ETH_ALEN];
703 u8 ssid[IEEE80211_MAX_SSID_LEN];
704 u8 bss_mode;
705 __le16 beacon_period;
706 u8 dtim_period;
707 u8 time_stamp[8];
708 u8 local_time[8];
709 union ieee_types_phy_param_set phy_param_set;
710 union ieee_types_ss_param_set ss_param_set;
711 __le16 cap_info_bitmap;
712 u8 data_rates[HOSTCMD_SUPPORTED_RATES];
713
714 /*
715 * DO NOT ADD ANY FIELDS TO THIS STRUCTURE.
716 * It is used in the Adhoc join command and will cause a
717 * binary layout mismatch with the firmware
718 */
719} __packed;
720
721struct host_cmd_ds_802_11_ad_hoc_join {
722 struct adhoc_bss_desc bss_descriptor;
723 u16 reserved1;
724 u16 reserved2;
725} __packed;
726
727struct host_cmd_ds_802_11_get_log {
728 __le32 mcast_tx_frame;
729 __le32 failed;
730 __le32 retry;
731 __le32 multi_retry;
732 __le32 frame_dup;
733 __le32 rts_success;
734 __le32 rts_failure;
735 __le32 ack_failure;
736 __le32 rx_frag;
737 __le32 mcast_rx_frame;
738 __le32 fcs_error;
739 __le32 tx_frame;
740 __le32 reserved;
741 __le32 wep_icv_err_cnt[4];
742};
743
744struct host_cmd_ds_tx_rate_query {
745 u8 tx_rate;
746 /* Ht Info [Bit 0] RxRate format: LG=0, HT=1
747 * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1
748 * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */
749 u8 ht_info;
750} __packed;
751
752enum Host_Sleep_Action {
753 HS_CONFIGURE = 0x0001,
754 HS_ACTIVATE = 0x0002,
755};
756
757struct mwifiex_hs_config_param {
758 __le32 conditions;
759 u8 gpio;
760 u8 gap;
761} __packed;
762
763struct hs_activate_param {
764 u16 resp_ctrl;
765} __packed;
766
767struct host_cmd_ds_802_11_hs_cfg_enh {
768 __le16 action;
769
770 union {
771 struct mwifiex_hs_config_param hs_config;
772 struct hs_activate_param hs_activate;
773 } params;
774} __packed;
775
776enum SNMP_MIB_INDEX {
777 OP_RATE_SET_I = 1,
778 DTIM_PERIOD_I = 3,
779 RTS_THRESH_I = 5,
780 SHORT_RETRY_LIM_I = 6,
781 LONG_RETRY_LIM_I = 7,
782 FRAG_THRESH_I = 8,
783 DOT11D_I = 9,
784};
785
786#define MAX_SNMP_BUF_SIZE 128
787
788struct host_cmd_ds_802_11_snmp_mib {
789 __le16 query_type;
790 __le16 oid;
791 __le16 buf_size;
792 u8 value[1];
793} __packed;
794
795struct mwifiex_rate_scope {
796 __le16 type;
797 __le16 length;
798 __le16 hr_dsss_rate_bitmap;
799 __le16 ofdm_rate_bitmap;
800 __le16 ht_mcs_rate_bitmap[8];
801} __packed;
802
803struct mwifiex_rate_drop_pattern {
804 __le16 type;
805 __le16 length;
806 __le32 rate_drop_mode;
807} __packed;
808
809struct host_cmd_ds_tx_rate_cfg {
810 __le16 action;
811 __le16 cfg_index;
812} __packed;
813
814struct mwifiex_power_group {
815 u8 modulation_class;
816 u8 first_rate_code;
817 u8 last_rate_code;
818 s8 power_step;
819 s8 power_min;
820 s8 power_max;
821 u8 ht_bandwidth;
822 u8 reserved;
823} __packed;
824
825struct mwifiex_types_power_group {
826 u16 type;
827 u16 length;
828} __packed;
829
830struct host_cmd_ds_txpwr_cfg {
831 __le16 action;
832 __le16 cfg_index;
833 __le32 mode;
834} __packed;
835
836#define MWIFIEX_USER_SCAN_CHAN_MAX 50
837
838#define MWIFIEX_MAX_SSID_LIST_LENGTH 10
839
840struct mwifiex_scan_cmd_config {
841 /*
842 * BSS Type to be sent in the firmware command
843 *
844 * Field can be used to restrict the types of networks returned in the
845 * scan. Valid settings are:
846 *
847 * - MWIFIEX_SCAN_MODE_BSS (infrastructure)
848 * - MWIFIEX_SCAN_MODE_IBSS (adhoc)
849 * - MWIFIEX_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure)
850 */
851 u8 bss_mode;
852
853 /* Specific BSSID used to filter scan results in the firmware */
854 u8 specific_bssid[ETH_ALEN];
855
856 /* Length of TLVs sent in command starting at tlvBuffer */
857 u32 tlv_buf_len;
858
859 /*
860 * SSID TLV(s) and ChanList TLVs to be sent in the firmware command
861 *
862 * TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
863 * WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
864 */
865 u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
866 here */
867} __packed;
868
869struct mwifiex_user_scan_chan {
870 u8 chan_number;
871 u8 radio_type;
872 u8 scan_type;
873 u8 reserved;
874 u32 scan_time;
875} __packed;
876
877struct mwifiex_user_scan_ssid {
878 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
879 u8 max_len;
880} __packed;
881
882struct mwifiex_user_scan_cfg {
883 /*
884 * Flag set to keep the previous scan table intact
885 *
886 * If set, the scan results will accumulate, replacing any previous
887 * matched entries for a BSS with the new scan data
888 */
889 u8 keep_previous_scan;
890 /*
891 * BSS mode to be sent in the firmware command
892 *
893 * Field can be used to restrict the types of networks returned in the
894 * scan. Valid settings are:
895 *
896 * - MWIFIEX_SCAN_MODE_BSS (infrastructure)
897 * - MWIFIEX_SCAN_MODE_IBSS (adhoc)
898 * - MWIFIEX_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure)
899 */
900 u8 bss_mode;
901 /* Configure the number of probe requests for active chan scans */
902 u8 num_probes;
903 u8 reserved;
904 /* BSSID filter sent in the firmware command to limit the results */
905 u8 specific_bssid[ETH_ALEN];
906 /* SSID filter list used in the to limit the scan results */
907 struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH];
908 /* Variable number (fixed maximum) of channels to scan up */
909 struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
910} __packed;
911
912struct ie_body {
913 u8 grp_key_oui[4];
914 u8 ptk_cnt[2];
915 u8 ptk_body[4];
916} __packed;
917
918struct host_cmd_ds_802_11_scan {
919 u8 bss_mode;
920 u8 bssid[ETH_ALEN];
921 u8 tlv_buffer[1];
922} __packed;
923
924struct host_cmd_ds_802_11_scan_rsp {
925 __le16 bss_descript_size;
926 u8 number_of_sets;
927 u8 bss_desc_and_tlv_buffer[1];
928} __packed;
929
930struct host_cmd_ds_802_11_bg_scan_query {
931 u8 flush;
932} __packed;
933
934struct host_cmd_ds_802_11_bg_scan_query_rsp {
935 u32 report_condition;
936 struct host_cmd_ds_802_11_scan_rsp scan_resp;
937} __packed;
938
939struct mwifiex_ietypes_domain_param_set {
940 struct mwifiex_ie_types_header header;
941 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
942 struct ieee80211_country_ie_triplet triplet[1];
943} __packed;
944
945struct host_cmd_ds_802_11d_domain_info {
946 __le16 action;
947 struct mwifiex_ietypes_domain_param_set domain;
948} __packed;
949
950struct host_cmd_ds_802_11d_domain_info_rsp {
951 __le16 action;
952 struct mwifiex_ietypes_domain_param_set domain;
953} __packed;
954
955struct host_cmd_ds_11n_addba_req {
956 u8 add_req_result;
957 u8 peer_mac_addr[ETH_ALEN];
958 u8 dialog_token;
959 __le16 block_ack_param_set;
960 __le16 block_ack_tmo;
961 __le16 ssn;
962} __packed;
963
964struct host_cmd_ds_11n_addba_rsp {
965 u8 add_rsp_result;
966 u8 peer_mac_addr[ETH_ALEN];
967 u8 dialog_token;
968 __le16 status_code;
969 __le16 block_ack_param_set;
970 __le16 block_ack_tmo;
971 __le16 ssn;
972} __packed;
973
974struct host_cmd_ds_11n_delba {
975 u8 del_result;
976 u8 peer_mac_addr[ETH_ALEN];
977 __le16 del_ba_param_set;
978 __le16 reason_code;
979 u8 reserved;
980} __packed;
981
982struct host_cmd_ds_11n_batimeout {
983 u8 tid;
984 u8 peer_mac_addr[ETH_ALEN];
985 u8 origninator;
986} __packed;
987
988struct host_cmd_ds_11n_cfg {
989 __le16 action;
990 __le16 ht_tx_cap;
991 __le16 ht_tx_info;
992} __packed;
993
994struct host_cmd_ds_txbuf_cfg {
995 __le16 action;
996 __le16 buff_size;
997 __le16 mp_end_port; /* SDIO only, reserved for other interfacces */
998 __le16 reserved3;
999} __packed;
1000
1001struct host_cmd_ds_amsdu_aggr_ctrl {
1002 __le16 action;
1003 __le16 enable;
1004 __le16 curr_buf_size;
1005} __packed;
1006
1007struct mwifiex_ie_types_wmm_param_set {
1008 struct mwifiex_ie_types_header header;
1009 u8 wmm_ie[1];
1010};
1011
1012struct mwifiex_ie_types_wmm_queue_status {
1013 struct mwifiex_ie_types_header header;
1014 u8 queue_index;
1015 u8 disabled;
1016 u16 medium_time;
1017 u8 flow_required;
1018 u8 flow_created;
1019 u32 reserved;
1020};
1021
1022struct ieee_types_vendor_header {
1023 u8 element_id;
1024 u8 len;
1025 u8 oui[3];
1026 u8 oui_type;
1027 u8 oui_subtype;
1028 u8 version;
1029} __packed;
1030
1031struct ieee_types_wmm_ac_parameters {
1032 u8 aci_aifsn_bitmap;
1033 u8 ecw_bitmap;
1034 __le16 tx_op_limit;
1035} __packed;
1036
1037struct ieee_types_wmm_parameter {
1038 /*
1039 * WMM Parameter IE - Vendor Specific Header:
1040 * element_id [221/0xdd]
1041 * Len [24]
1042 * Oui [00:50:f2]
1043 * OuiType [2]
1044 * OuiSubType [1]
1045 * Version [1]
1046 */
1047 struct ieee_types_vendor_header vend_hdr;
1048 u8 qos_info_bitmap;
1049 u8 reserved;
1050 struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_MAX_QUEUES];
1051} __packed;
1052
1053struct ieee_types_wmm_info {
1054
1055 /*
1056 * WMM Info IE - Vendor Specific Header:
1057 * element_id [221/0xdd]
1058 * Len [7]
1059 * Oui [00:50:f2]
1060 * OuiType [2]
1061 * OuiSubType [0]
1062 * Version [1]
1063 */
1064 struct ieee_types_vendor_header vend_hdr;
1065
1066 u8 qos_info_bitmap;
1067} __packed;
1068
1069struct host_cmd_ds_wmm_get_status {
1070 u8 queue_status_tlv[sizeof(struct mwifiex_ie_types_wmm_queue_status) *
1071 IEEE80211_MAX_QUEUES];
1072 u8 wmm_param_tlv[sizeof(struct ieee_types_wmm_parameter) + 2];
1073} __packed;
1074
1075struct mwifiex_wmm_ac_status {
1076 u8 disabled;
1077 u8 flow_required;
1078 u8 flow_created;
1079};
1080
1081struct mwifiex_ie_types_htcap {
1082 struct mwifiex_ie_types_header header;
1083 struct ieee80211_ht_cap ht_cap;
1084} __packed;
1085
1086struct mwifiex_ie_types_htinfo {
1087 struct mwifiex_ie_types_header header;
1088 struct ieee80211_ht_info ht_info;
1089} __packed;
1090
1091struct mwifiex_ie_types_2040bssco {
1092 struct mwifiex_ie_types_header header;
1093 u8 bss_co_2040;
1094} __packed;
1095
1096struct mwifiex_ie_types_extcap {
1097 struct mwifiex_ie_types_header header;
1098 u8 ext_cap;
1099} __packed;
1100
1101struct host_cmd_ds_mac_reg_access {
1102 __le16 action;
1103 __le16 offset;
1104 __le32 value;
1105} __packed;
1106
1107struct host_cmd_ds_bbp_reg_access {
1108 __le16 action;
1109 __le16 offset;
1110 u8 value;
1111 u8 reserved[3];
1112} __packed;
1113
1114struct host_cmd_ds_rf_reg_access {
1115 __le16 action;
1116 __le16 offset;
1117 u8 value;
1118 u8 reserved[3];
1119} __packed;
1120
1121struct host_cmd_ds_pmic_reg_access {
1122 __le16 action;
1123 __le16 offset;
1124 u8 value;
1125 u8 reserved[3];
1126} __packed;
1127
1128struct host_cmd_ds_802_11_eeprom_access {
1129 __le16 action;
1130
1131 __le16 offset;
1132 __le16 byte_count;
1133 u8 value;
1134} __packed;
1135
1136struct host_cmd_ds_802_11_rf_channel {
1137 __le16 action;
1138 __le16 current_channel;
1139 __le16 rf_type;
1140 __le16 reserved;
1141 u8 reserved_1[32];
1142} __packed;
1143
1144struct host_cmd_ds_version_ext {
1145 u8 version_str_sel;
1146 char version_str[128];
1147} __packed;
1148
1149struct host_cmd_ds_802_11_ibss_status {
1150 __le16 action;
1151 __le16 enable;
1152 u8 bssid[ETH_ALEN];
1153 __le16 beacon_interval;
1154 __le16 atim_window;
1155 __le16 use_g_rate_protect;
1156} __packed;
1157
1158#define CONNECTION_TYPE_INFRA 0
1159#define CONNECTION_TYPE_ADHOC 1
1160
1161struct host_cmd_ds_set_bss_mode {
1162 u8 con_type;
1163} __packed;
1164
1165struct host_cmd_ds_command {
1166 __le16 command;
1167 __le16 size;
1168 __le16 seq_num;
1169 __le16 result;
1170 union {
1171 struct host_cmd_ds_get_hw_spec hw_spec;
1172 struct host_cmd_ds_mac_control mac_ctrl;
1173 struct host_cmd_ds_802_11_mac_address mac_addr;
1174 struct host_cmd_ds_mac_multicast_adr mc_addr;
1175 struct host_cmd_ds_802_11_get_log get_log;
1176 struct host_cmd_ds_802_11_rssi_info rssi_info;
1177 struct host_cmd_ds_802_11_rssi_info_rsp rssi_info_rsp;
1178 struct host_cmd_ds_802_11_snmp_mib smib;
1179 struct host_cmd_ds_802_11_rf_channel rf_channel;
1180 struct host_cmd_ds_tx_rate_query tx_rate;
1181 struct host_cmd_ds_tx_rate_cfg tx_rate_cfg;
1182 struct host_cmd_ds_txpwr_cfg txp_cfg;
1183 struct host_cmd_ds_802_11_ps_mode_enh psmode_enh;
1184 struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg;
1185 struct host_cmd_ds_802_11_scan scan;
1186 struct host_cmd_ds_802_11_scan_rsp scan_resp;
1187 struct host_cmd_ds_802_11_bg_scan_query bg_scan_query;
1188 struct host_cmd_ds_802_11_bg_scan_query_rsp bg_scan_query_resp;
1189 struct host_cmd_ds_802_11_associate associate;
1190 struct host_cmd_ds_802_11_associate_rsp associate_rsp;
1191 struct host_cmd_ds_802_11_deauthenticate deauth;
1192 struct host_cmd_ds_802_11_ad_hoc_start adhoc_start;
1193 struct host_cmd_ds_802_11_ad_hoc_result adhoc_result;
1194 struct host_cmd_ds_802_11_ad_hoc_join adhoc_join;
1195 struct host_cmd_ds_802_11d_domain_info domain_info;
1196 struct host_cmd_ds_802_11d_domain_info_rsp domain_info_resp;
1197 struct host_cmd_ds_11n_addba_req add_ba_req;
1198 struct host_cmd_ds_11n_addba_rsp add_ba_rsp;
1199 struct host_cmd_ds_11n_delba del_ba;
1200 struct host_cmd_ds_txbuf_cfg tx_buf;
1201 struct host_cmd_ds_amsdu_aggr_ctrl amsdu_aggr_ctrl;
1202 struct host_cmd_ds_11n_cfg htcfg;
1203 struct host_cmd_ds_wmm_get_status get_wmm_status;
1204 struct host_cmd_ds_802_11_key_material key_material;
1205 struct host_cmd_ds_version_ext verext;
1206 struct host_cmd_ds_802_11_ibss_status ibss_coalescing;
1207 struct host_cmd_ds_mac_reg_access mac_reg;
1208 struct host_cmd_ds_bbp_reg_access bbp_reg;
1209 struct host_cmd_ds_rf_reg_access rf_reg;
1210 struct host_cmd_ds_pmic_reg_access pmic_reg;
1211 struct host_cmd_ds_set_bss_mode bss_mode;
1212 struct host_cmd_ds_802_11_eeprom_access eeprom;
1213 } params;
1214} __packed;
1215
1216struct mwifiex_opt_sleep_confirm {
1217 __le16 command;
1218 __le16 size;
1219 __le16 seq_num;
1220 __le16 result;
1221 __le16 action;
1222 __le16 resp_ctrl;
1223} __packed;
1224
1225struct mwifiex_opt_sleep_confirm_buffer {
1226 u8 hdr[4];
1227 struct mwifiex_opt_sleep_confirm ps_cfm_sleep;
1228} __packed;
1229#endif /* !_MWIFIEX_FW_H_ */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
new file mode 100644
index 000000000000..8189862da1f9
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -0,0 +1,662 @@
1/*
2 * Marvell Wireless LAN device driver: HW/FW Initialization
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * This function adds a BSS priority table to the table list.
30 *
31 * The function allocates a new BSS priority table node and adds it to
32 * the end of BSS priority table list, kept in driver memory.
33 */
34static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
35{
36 struct mwifiex_adapter *adapter = priv->adapter;
37 struct mwifiex_bss_prio_node *bss_prio;
38 int status = 0;
39 unsigned long flags;
40
41 bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
42 if (!bss_prio) {
43 dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
44 __func__);
45 return -1;
46 }
47
48 bss_prio->priv = priv;
49 INIT_LIST_HEAD(&bss_prio->list);
50 if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
51 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
52 bss_prio;
53
54 spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
55 .bss_prio_lock, flags);
56 list_add_tail(&bss_prio->list,
57 &adapter->bss_prio_tbl[priv->bss_priority]
58 .bss_prio_head);
59 spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
60 .bss_prio_lock, flags);
61
62 return status;
63}
64
65/*
66 * This function initializes the private structure and sets default
67 * values to the members.
68 *
69 * Additionally, it also initializes all the locks and sets up all the
70 * lists.
71 */
72static int mwifiex_init_priv(struct mwifiex_private *priv)
73{
74 u32 i;
75 int ret = 0;
76
77 priv->media_connected = false;
78 memset(priv->curr_addr, 0xff, ETH_ALEN);
79
80 priv->pkt_tx_ctrl = 0;
81 priv->bss_mode = NL80211_IFTYPE_STATION;
82 priv->data_rate = 0; /* Initially indicate the rate as auto */
83 priv->is_data_rate_auto = true;
84 priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
85 priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
86
87 priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
88 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
89 priv->sec_info.encryption_mode = 0;
90 for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
91 memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key));
92 priv->wep_key_curr_index = 0;
93 priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
94 HostCmd_ACT_MAC_ETHERNETII_ENABLE;
95
96 priv->beacon_period = 100; /* beacon interval */ ;
97 priv->attempted_bss_desc = NULL;
98 memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
99 priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;
100
101 memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
102 memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
103 memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
104 priv->assoc_rsp_size = 0;
105 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
106 priv->atim_window = 0;
107 priv->adhoc_state = ADHOC_IDLE;
108 priv->tx_power_level = 0;
109 priv->max_tx_power_level = 0;
110 priv->min_tx_power_level = 0;
111 priv->tx_rate = 0;
112 priv->rxpd_htinfo = 0;
113 priv->rxpd_rate = 0;
114 priv->rate_bitmap = 0;
115 priv->data_rssi_last = 0;
116 priv->data_rssi_avg = 0;
117 priv->data_nf_avg = 0;
118 priv->data_nf_last = 0;
119 priv->bcn_rssi_last = 0;
120 priv->bcn_rssi_avg = 0;
121 priv->bcn_nf_avg = 0;
122 priv->bcn_nf_last = 0;
123 memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
124 memset(&priv->aes_key, 0, sizeof(priv->aes_key));
125 priv->wpa_ie_len = 0;
126 priv->wpa_is_gtk_set = false;
127
128 memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf));
129 priv->assoc_tlv_buf_len = 0;
130 memset(&priv->wps, 0, sizeof(priv->wps));
131 memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
132 priv->gen_ie_buf_len = 0;
133 memset(priv->vs_ie, 0, sizeof(priv->vs_ie));
134
135 priv->wmm_required = true;
136 priv->wmm_enabled = false;
137 priv->wmm_qosinfo = 0;
138 priv->curr_bcn_buf = NULL;
139 priv->curr_bcn_size = 0;
140
141 priv->scan_block = false;
142
143 ret = mwifiex_add_bss_prio_tbl(priv);
144
145 return ret;
146}
147
148/*
149 * This function allocates buffers for members of the adapter
150 * structure.
151 *
152 * The memory allocated includes scan table, command buffers, and
153 * sleep confirm command buffer. In addition, the queues are
154 * also initialized.
155 */
156static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
157{
158 int ret = 0;
159 u32 buf_size;
160 struct mwifiex_bssdescriptor *temp_scan_table;
161
162 /* Allocate buffer to store the BSSID list */
163 buf_size = sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP;
164 temp_scan_table = kzalloc(buf_size, GFP_KERNEL);
165 if (!temp_scan_table) {
166 dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n",
167 __func__);
168 return -1;
169 }
170
171 adapter->scan_table = temp_scan_table;
172
173 /* Allocate command buffer */
174 ret = mwifiex_alloc_cmd_buffer(adapter);
175 if (ret) {
176 dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n",
177 __func__);
178 return -1;
179 }
180
181 adapter->sleep_cfm =
182 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm_buffer)
183 + INTF_HEADER_LEN);
184
185 if (!adapter->sleep_cfm) {
186 dev_err(adapter->dev, "%s: failed to alloc sleep cfm"
187 " cmd buffer\n", __func__);
188 return -1;
189 }
190 skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);
191
192 return 0;
193}
194
195/*
196 * This function initializes the adapter structure and sets default
197 * values to the members of adapter.
198 *
199 * This also initializes the WMM related parameters in the driver private
200 * structures.
201 */
202static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
203{
204 struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf = NULL;
205
206 skb_put(adapter->sleep_cfm, sizeof(sleep_cfm_buf->ps_cfm_sleep));
207 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm_buffer *)
208 (adapter->sleep_cfm->data);
209
210 adapter->cmd_sent = false;
211 adapter->data_sent = true;
212 adapter->cmd_resp_received = false;
213 adapter->event_received = false;
214 adapter->data_received = false;
215
216 adapter->surprise_removed = false;
217
218 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
219
220 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
221 adapter->ps_state = PS_STATE_AWAKE;
222 adapter->need_to_wakeup = false;
223
224 adapter->scan_mode = HostCmd_BSS_MODE_ANY;
225 adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
226 adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
227 adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
228
229 adapter->num_in_scan_table = 0;
230 memset(adapter->scan_table, 0,
231 (sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP));
232 adapter->scan_probes = 1;
233
234 memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf));
235 adapter->bcn_buf_end = adapter->bcn_buf;
236
237 adapter->multiple_dtim = 1;
238
239 adapter->local_listen_interval = 0; /* default value in firmware
240 will be used */
241
242 adapter->is_deep_sleep = false;
243
244 adapter->delay_null_pkt = false;
245 adapter->delay_to_ps = 1000;
246 adapter->enhanced_ps_mode = PS_MODE_AUTO;
247
248 adapter->gen_null_pkt = false; /* Disable NULL Pkg generation by
249 default */
250 adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by
251 default */
252 adapter->pm_wakeup_card_req = false;
253
254 adapter->pm_wakeup_fw_try = false;
255
256 adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
257 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
258 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
259
260 adapter->is_hs_configured = false;
261 adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF);
262 adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF;
263 adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF;
264 adapter->hs_activated = false;
265
266 memset(adapter->event_body, 0, sizeof(adapter->event_body));
267 adapter->hw_dot_11n_dev_cap = 0;
268 adapter->hw_dev_mcs_support = 0;
269 adapter->chan_offset = 0;
270 adapter->adhoc_11n_enabled = false;
271
272 mwifiex_wmm_init(adapter);
273
274 if (adapter->sleep_cfm) {
275 memset(&sleep_cfm_buf->ps_cfm_sleep, 0,
276 adapter->sleep_cfm->len);
277 sleep_cfm_buf->ps_cfm_sleep.command =
278 cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
279 sleep_cfm_buf->ps_cfm_sleep.size =
280 cpu_to_le16(adapter->sleep_cfm->len);
281 sleep_cfm_buf->ps_cfm_sleep.result = 0;
282 sleep_cfm_buf->ps_cfm_sleep.action = cpu_to_le16(SLEEP_CONFIRM);
283 sleep_cfm_buf->ps_cfm_sleep.resp_ctrl =
284 cpu_to_le16(RESP_NEEDED);
285 }
286 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
287 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
288 adapter->tx_lock_flag = false;
289 adapter->null_pkt_interval = 0;
290 adapter->fw_bands = 0;
291 adapter->config_bands = 0;
292 adapter->adhoc_start_band = 0;
293 adapter->scan_channels = NULL;
294 adapter->fw_release_number = 0;
295 adapter->fw_cap_info = 0;
296 memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf));
297 adapter->event_cause = 0;
298 adapter->region_code = 0;
299 adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
300 adapter->adhoc_awake_period = 0;
301 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
302 adapter->arp_filter_size = 0;
303
304 return;
305}
306
307/*
308 * This function frees the adapter structure.
309 *
310 * The freeing operation is done recursively, by canceling all
311 * pending commands, freeing the member buffers previously
312 * allocated (command buffers, scan table buffer, sleep confirm
313 * command buffer), stopping the timers and calling the cleanup
314 * routines for every interface, before the actual adapter
315 * structure is freed.
316 */
317static void
318mwifiex_free_adapter(struct mwifiex_adapter *adapter)
319{
320 if (!adapter) {
321 pr_err("%s: adapter is NULL\n", __func__);
322 return;
323 }
324
325 mwifiex_cancel_all_pending_cmd(adapter);
326
327 /* Free lock variables */
328 mwifiex_free_lock_list(adapter);
329
330 /* Free command buffer */
331 dev_dbg(adapter->dev, "info: free cmd buffer\n");
332 mwifiex_free_cmd_buffer(adapter);
333
334 del_timer(&adapter->cmd_timer);
335
336 dev_dbg(adapter->dev, "info: free scan table\n");
337 kfree(adapter->scan_table);
338 adapter->scan_table = NULL;
339
340 adapter->if_ops.cleanup_if(adapter);
341
342 dev_kfree_skb_any(adapter->sleep_cfm);
343
344 return;
345}
346
347/*
348 * This function intializes the lock variables and
349 * the list heads.
350 */
351int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
352{
353 struct mwifiex_private *priv = NULL;
354 s32 i = 0;
355 u32 j = 0;
356
357 spin_lock_init(&adapter->mwifiex_lock);
358 spin_lock_init(&adapter->int_lock);
359 spin_lock_init(&adapter->main_proc_lock);
360 spin_lock_init(&adapter->mwifiex_cmd_lock);
361 for (i = 0; i < adapter->priv_num; i++) {
362 if (adapter->priv[i]) {
363 priv = adapter->priv[i];
364 spin_lock_init(&priv->rx_pkt_lock);
365 spin_lock_init(&priv->wmm.ra_list_spinlock);
366 spin_lock_init(&priv->curr_bcn_buf_lock);
367 }
368 }
369
370 /* Initialize cmd_free_q */
371 INIT_LIST_HEAD(&adapter->cmd_free_q);
372 /* Initialize cmd_pending_q */
373 INIT_LIST_HEAD(&adapter->cmd_pending_q);
374 /* Initialize scan_pending_q */
375 INIT_LIST_HEAD(&adapter->scan_pending_q);
376
377 spin_lock_init(&adapter->cmd_free_q_lock);
378 spin_lock_init(&adapter->cmd_pending_q_lock);
379 spin_lock_init(&adapter->scan_pending_q_lock);
380
381 for (i = 0; i < adapter->priv_num; ++i) {
382 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
383 adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
384 spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
385 }
386
387 for (i = 0; i < adapter->priv_num; i++) {
388 if (!adapter->priv[i])
389 continue;
390 priv = adapter->priv[i];
391 for (j = 0; j < MAX_NUM_TID; ++j) {
392 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
393 spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock);
394 }
395 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
396 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
397
398 spin_lock_init(&priv->tx_ba_stream_tbl_lock);
399 spin_lock_init(&priv->rx_reorder_tbl_lock);
400 }
401
402 return 0;
403}
404
405/*
406 * This function releases the lock variables and frees the locks and
407 * associated locks.
408 */
409void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
410{
411 struct mwifiex_private *priv = NULL;
412 s32 i = 0;
413 s32 j = 0;
414
415 /* Free lists */
416 list_del(&adapter->cmd_free_q);
417 list_del(&adapter->cmd_pending_q);
418 list_del(&adapter->scan_pending_q);
419
420 for (i = 0; i < adapter->priv_num; i++)
421 list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
422
423 for (i = 0; i < adapter->priv_num; i++) {
424 if (adapter->priv[i]) {
425 priv = adapter->priv[i];
426 for (j = 0; j < MAX_NUM_TID; ++j)
427 list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
428 list_del(&priv->tx_ba_stream_tbl_ptr);
429 list_del(&priv->rx_reorder_tbl_ptr);
430 }
431 }
432
433 return;
434}
435
436/*
437 * This function initializes the firmware.
438 *
439 * The following operations are performed sequentially -
440 * - Allocate adapter structure
441 * - Initialize the adapter structure
442 * - Initialize the private structure
443 * - Add BSS priority tables to the adapter structure
444 * - For each interface, send the init commands to firmware
445 * - Send the first command in command pending queue, if available
446 */
447int mwifiex_init_fw(struct mwifiex_adapter *adapter)
448{
449 int ret = 0;
450 struct mwifiex_private *priv = NULL;
451 u8 i = 0;
452 u8 first_sta = true;
453 int is_cmd_pend_q_empty;
454 unsigned long flags;
455
456 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
457
458 /* Allocate memory for member of adapter structure */
459 ret = mwifiex_allocate_adapter(adapter);
460 if (ret)
461 return -1;
462
463 /* Initialize adapter structure */
464 mwifiex_init_adapter(adapter);
465
466 for (i = 0; i < adapter->priv_num; i++) {
467 if (adapter->priv[i]) {
468 priv = adapter->priv[i];
469
470 /* Initialize private structure */
471 ret = mwifiex_init_priv(priv);
472 if (ret)
473 return -1;
474 }
475 }
476 for (i = 0; i < adapter->priv_num; i++) {
477 if (adapter->priv[i]) {
478 ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta);
479 if (ret == -1)
480 return -1;
481
482 first_sta = false;
483 }
484 }
485
486 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
487 is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
488 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
489 if (!is_cmd_pend_q_empty) {
490 /* Send the first command in queue and return */
491 if (mwifiex_main_process(adapter) != -1)
492 ret = -EINPROGRESS;
493 } else {
494 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
495 }
496
497 return ret;
498}
499
500/*
501 * This function deletes the BSS priority tables.
502 *
503 * The function traverses through all the allocated BSS priority nodes
504 * in every BSS priority table and frees them.
505 */
506static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
507{
508 int i;
509 struct mwifiex_adapter *adapter = priv->adapter;
510 struct mwifiex_bss_prio_node *bssprio_node = NULL, *tmp_node = NULL,
511 **cur = NULL;
512 struct list_head *head;
513 spinlock_t *lock;
514 unsigned long flags;
515
516 for (i = 0; i < adapter->priv_num; ++i) {
517 head = &adapter->bss_prio_tbl[i].bss_prio_head;
518 cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
519 lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
520 dev_dbg(adapter->dev, "info: delete BSS priority table,"
521 " index = %d, i = %d, head = %p, cur = %p\n",
522 priv->bss_index, i, head, *cur);
523 if (*cur) {
524 spin_lock_irqsave(lock, flags);
525 if (list_empty(head)) {
526 spin_unlock_irqrestore(lock, flags);
527 continue;
528 }
529 bssprio_node = list_first_entry(head,
530 struct mwifiex_bss_prio_node, list);
531 spin_unlock_irqrestore(lock, flags);
532
533 list_for_each_entry_safe(bssprio_node, tmp_node, head,
534 list) {
535 if (bssprio_node->priv == priv) {
536 dev_dbg(adapter->dev, "info: Delete "
537 "node %p, next = %p\n",
538 bssprio_node, tmp_node);
539 spin_lock_irqsave(lock, flags);
540 list_del(&bssprio_node->list);
541 spin_unlock_irqrestore(lock, flags);
542 kfree(bssprio_node);
543 }
544 }
545 *cur = (struct mwifiex_bss_prio_node *)head;
546 }
547 }
548}
549
550/*
551 * This function is used to shutdown the driver.
552 *
553 * The following operations are performed sequentially -
554 * - Check if already shut down
555 * - Make sure the main process has stopped
556 * - Clean up the Tx and Rx queues
557 * - Delete BSS priority tables
558 * - Free the adapter
559 * - Notify completion
560 */
561int
562mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
563{
564 int ret = -EINPROGRESS;
565 struct mwifiex_private *priv = NULL;
566 s32 i = 0;
567 unsigned long flags;
568
569 /* mwifiex already shutdown */
570 if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
571 return 0;
572
573 adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING;
574 /* wait for mwifiex_process to complete */
575 if (adapter->mwifiex_processing) {
576 dev_warn(adapter->dev, "main process is still running\n");
577 return ret;
578 }
579
580 /* shut down mwifiex */
581 dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
582
583 /* Clean up Tx/Rx queues and delete BSS priority table */
584 for (i = 0; i < adapter->priv_num; i++) {
585 if (adapter->priv[i]) {
586 priv = adapter->priv[i];
587
588 mwifiex_clean_txrx(priv);
589 mwifiex_delete_bss_prio_tbl(priv);
590 }
591 }
592
593 spin_lock_irqsave(&adapter->mwifiex_lock, flags);
594
595 /* Free adapter structure */
596 mwifiex_free_adapter(adapter);
597
598 spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);
599
600 /* Notify completion */
601 ret = mwifiex_shutdown_fw_complete(adapter);
602
603 return ret;
604}
605
606/*
607 * This function downloads the firmware to the card.
608 *
609 * The actual download is preceded by two sanity checks -
610 * - Check if firmware is already running
611 * - Check if the interface is the winner to download the firmware
612 *
613 * ...and followed by another -
614 * - Check if the firmware is downloaded successfully
615 *
616 * After download is successfully completed, the host interrupts are enabled.
617 */
618int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
619 struct mwifiex_fw_image *pmfw)
620{
621 int ret = 0;
622 u32 poll_num = 1;
623 int winner;
624
625 /* Check if firmware is already running */
626 ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner);
627 if (!ret) {
628 dev_notice(adapter->dev,
629 "WLAN FW already running! Skip FW download\n");
630 goto done;
631 }
632 poll_num = MAX_FIRMWARE_POLL_TRIES;
633
634 /* Check if we are the winner for downloading FW */
635 if (!winner) {
636 dev_notice(adapter->dev,
637 "Other interface already running!"
638 " Skip FW download\n");
639 poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
640 goto poll_fw;
641 }
642 if (pmfw) {
643 /* Download firmware with helper */
644 ret = adapter->if_ops.prog_fw(adapter, pmfw);
645 if (ret) {
646 dev_err(adapter->dev, "prog_fw failed ret=%#x\n", ret);
647 return ret;
648 }
649 }
650
651poll_fw:
652 /* Check if the firmware is downloaded successfully or not */
653 ret = adapter->if_ops.check_fw_status(adapter, poll_num, NULL);
654 if (ret) {
655 dev_err(adapter->dev, "FW failed to be active in time\n");
656 return -1;
657 }
658done:
659 /* re-enable host interrupt for mwifiex after fw dnld is successful */
660 adapter->if_ops.enable_int(adapter);
661 return ret;
662}
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
new file mode 100644
index 000000000000..703a6d12ebf3
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -0,0 +1,411 @@
1/*
2 * Marvell Wireless LAN device driver: ioctl data structures & APIs
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_IOCTL_H_
21#define _MWIFIEX_IOCTL_H_
22
23#include <net/mac80211.h>
24
25enum {
26 MWIFIEX_SCAN_MODE_UNCHANGED = 0,
27 MWIFIEX_SCAN_MODE_BSS,
28 MWIFIEX_SCAN_MODE_IBSS,
29 MWIFIEX_SCAN_MODE_ANY
30};
31
32enum {
33 MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
34 MWIFIEX_SCAN_TYPE_ACTIVE,
35 MWIFIEX_SCAN_TYPE_PASSIVE
36};
37
38struct mwifiex_get_scan_table_fixed {
39 u8 bssid[ETH_ALEN];
40 u8 channel;
41 u8 rssi;
42 long long network_tsf;
43};
44
45struct mwifiex_scan_time_params {
46 u32 specific_scan_time;
47 u32 active_scan_time;
48 u32 passive_scan_time;
49};
50
51struct mwifiex_user_scan {
52 u32 scan_cfg_len;
53 u8 scan_cfg_buf[1];
54};
55
56struct mwifiex_scan_req {
57 u32 scan_mode;
58 u32 scan_type;
59 struct mwifiex_802_11_ssid scan_ssid;
60 struct mwifiex_scan_time_params scan_time;
61 struct mwifiex_user_scan user_scan;
62};
63
64struct mwifiex_scan_resp {
65 u32 num_in_scan_table;
66 u8 *scan_table;
67};
68
69#define MWIFIEX_PROMISC_MODE 1
70#define MWIFIEX_MULTICAST_MODE 2
71#define MWIFIEX_ALL_MULTI_MODE 4
72#define MWIFIEX_MAX_MULTICAST_LIST_SIZE 32
73
74struct mwifiex_multicast_list {
75 u32 mode;
76 u32 num_multicast_addr;
77 u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
78};
79
80#define MWIFIEX_MAX_CHANNEL_NUM 128
81
82struct mwifiex_chan_freq {
83 u32 channel;
84 u32 freq;
85};
86
87struct mwifiex_chan_list {
88 u32 num_of_chan;
89 struct mwifiex_chan_freq cf[MWIFIEX_MAX_CHANNEL_NUM];
90};
91
92struct mwifiex_ssid_bssid {
93 struct mwifiex_802_11_ssid ssid;
94 u8 bssid[ETH_ALEN];
95};
96
97enum {
98 BAND_B = 1,
99 BAND_G = 2,
100 BAND_A = 4,
101 BAND_GN = 8,
102 BAND_AN = 16,
103};
104
105#define NO_SEC_CHANNEL 0
106#define SEC_CHANNEL_ABOVE 1
107#define SEC_CHANNEL_BELOW 3
108
109struct mwifiex_ds_band_cfg {
110 u32 config_bands;
111 u32 adhoc_start_band;
112 u32 adhoc_channel;
113 u32 sec_chan_offset;
114};
115
116enum {
117 ADHOC_IDLE,
118 ADHOC_STARTED,
119 ADHOC_JOINED,
120 ADHOC_COALESCED
121};
122
123struct mwifiex_ds_get_stats {
124 u32 mcast_tx_frame;
125 u32 failed;
126 u32 retry;
127 u32 multi_retry;
128 u32 frame_dup;
129 u32 rts_success;
130 u32 rts_failure;
131 u32 ack_failure;
132 u32 rx_frag;
133 u32 mcast_rx_frame;
134 u32 fcs_error;
135 u32 tx_frame;
136 u32 wep_icv_error[4];
137};
138
139#define BCN_RSSI_LAST_MASK 0x00000001
140#define BCN_RSSI_AVG_MASK 0x00000002
141#define DATA_RSSI_LAST_MASK 0x00000004
142#define DATA_RSSI_AVG_MASK 0x00000008
143#define BCN_SNR_LAST_MASK 0x00000010
144#define BCN_SNR_AVG_MASK 0x00000020
145#define DATA_SNR_LAST_MASK 0x00000040
146#define DATA_SNR_AVG_MASK 0x00000080
147#define BCN_NF_LAST_MASK 0x00000100
148#define BCN_NF_AVG_MASK 0x00000200
149#define DATA_NF_LAST_MASK 0x00000400
150#define DATA_NF_AVG_MASK 0x00000800
151#define ALL_RSSI_INFO_MASK 0x00000fff
152
153struct mwifiex_ds_get_signal {
154 /*
155 * Bit0: Last Beacon RSSI, Bit1: Average Beacon RSSI,
156 * Bit2: Last Data RSSI, Bit3: Average Data RSSI,
157 * Bit4: Last Beacon SNR, Bit5: Average Beacon SNR,
158 * Bit6: Last Data SNR, Bit7: Average Data SNR,
159 * Bit8: Last Beacon NF, Bit9: Average Beacon NF,
160 * Bit10: Last Data NF, Bit11: Average Data NF
161 */
162 u16 selector;
163 s16 bcn_rssi_last;
164 s16 bcn_rssi_avg;
165 s16 data_rssi_last;
166 s16 data_rssi_avg;
167 s16 bcn_snr_last;
168 s16 bcn_snr_avg;
169 s16 data_snr_last;
170 s16 data_snr_avg;
171 s16 bcn_nf_last;
172 s16 bcn_nf_avg;
173 s16 data_nf_last;
174 s16 data_nf_avg;
175};
176
177struct mwifiex_fw_info {
178 u32 fw_ver;
179 u8 mac_addr[ETH_ALEN];
180};
181
182#define MWIFIEX_MAX_VER_STR_LEN 128
183
184struct mwifiex_ver_ext {
185 u32 version_str_sel;
186 char version_str[MWIFIEX_MAX_VER_STR_LEN];
187};
188
189struct mwifiex_bss_info {
190 u32 bss_mode;
191 struct mwifiex_802_11_ssid ssid;
192 u32 scan_table_idx;
193 u32 bss_chan;
194 u32 region_code;
195 u32 media_connected;
196 u32 max_power_level;
197 u32 min_power_level;
198 u32 adhoc_state;
199 signed int bcn_nf_last;
200 u32 wep_status;
201 u32 is_hs_configured;
202 u32 is_deep_sleep;
203 u8 bssid[ETH_ALEN];
204};
205
206#define MAX_NUM_TID 8
207
208#define MAX_RX_WINSIZE 64
209
210struct mwifiex_ds_rx_reorder_tbl {
211 u16 tid;
212 u8 ta[ETH_ALEN];
213 u32 start_win;
214 u32 win_size;
215 u32 buffer[MAX_RX_WINSIZE];
216};
217
218struct mwifiex_ds_tx_ba_stream_tbl {
219 u16 tid;
220 u8 ra[ETH_ALEN];
221};
222
223#define DBG_CMD_NUM 5
224
225struct mwifiex_debug_info {
226 u32 int_counter;
227 u32 packets_out[MAX_NUM_TID];
228 u32 max_tx_buf_size;
229 u32 tx_buf_size;
230 u32 curr_tx_buf_size;
231 u32 tx_tbl_num;
232 struct mwifiex_ds_tx_ba_stream_tbl
233 tx_tbl[MWIFIEX_MAX_TX_BASTREAM_SUPPORTED];
234 u32 rx_tbl_num;
235 struct mwifiex_ds_rx_reorder_tbl rx_tbl
236 [MWIFIEX_MAX_RX_BASTREAM_SUPPORTED];
237 u16 ps_mode;
238 u32 ps_state;
239 u8 is_deep_sleep;
240 u8 pm_wakeup_card_req;
241 u32 pm_wakeup_fw_try;
242 u8 is_hs_configured;
243 u8 hs_activated;
244 u32 num_cmd_host_to_card_failure;
245 u32 num_cmd_sleep_cfm_host_to_card_failure;
246 u32 num_tx_host_to_card_failure;
247 u32 num_event_deauth;
248 u32 num_event_disassoc;
249 u32 num_event_link_lost;
250 u32 num_cmd_deauth;
251 u32 num_cmd_assoc_success;
252 u32 num_cmd_assoc_failure;
253 u32 num_tx_timeout;
254 u32 num_cmd_timeout;
255 u16 timeout_cmd_id;
256 u16 timeout_cmd_act;
257 u16 last_cmd_id[DBG_CMD_NUM];
258 u16 last_cmd_act[DBG_CMD_NUM];
259 u16 last_cmd_index;
260 u16 last_cmd_resp_id[DBG_CMD_NUM];
261 u16 last_cmd_resp_index;
262 u16 last_event[DBG_CMD_NUM];
263 u16 last_event_index;
264 u8 data_sent;
265 u8 cmd_sent;
266 u8 cmd_resp_received;
267 u8 event_received;
268};
269
270#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000
271#define MWIFIEX_MAX_KEY_LENGTH 32
272#define WAPI_RXPN_LEN 16
273
274struct mwifiex_ds_encrypt_key {
275 u32 key_disable;
276 u32 key_index;
277 u32 key_len;
278 u8 key_material[MWIFIEX_MAX_KEY_LENGTH];
279 u8 mac_addr[ETH_ALEN];
280 u32 is_wapi_key;
281 u8 wapi_rxpn[WAPI_RXPN_LEN];
282};
283
284struct mwifiex_rate_cfg {
285 u32 action;
286 u32 is_rate_auto;
287 u32 rate;
288};
289
290struct mwifiex_data_rate {
291 u32 tx_data_rate;
292 u32 rx_data_rate;
293};
294
295struct mwifiex_power_cfg {
296 u32 is_power_auto;
297 u32 power_level;
298};
299
300struct mwifiex_ds_hs_cfg {
301 u32 is_invoke_hostcmd;
302 /* Bit0: non-unicast data
303 * Bit1: unicast data
304 * Bit2: mac events
305 * Bit3: magic packet
306 */
307 u32 conditions;
308 u32 gpio;
309 u32 gap;
310};
311
312#define DEEP_SLEEP_ON 1
313#define DEEP_SLEEP_OFF 0
314
315#define DEEP_SLEEP_IDLE_TIME 100
316
317struct mwifiex_ds_auto_ds {
318 u16 auto_ds;
319 u16 idle_time;
320};
321
322#define PS_MODE_UNCHANGED 0
323#define PS_MODE_AUTO 1
324#define PS_MODE_POLL 2
325#define PS_MODE_NULL 3
326
327
328struct mwifiex_ds_pm_cfg {
329 union {
330 u32 ps_mode;
331 struct mwifiex_ds_hs_cfg hs_cfg;
332 struct mwifiex_ds_auto_ds auto_deep_sleep;
333 u32 sleep_period;
334 } param;
335};
336
337struct mwifiex_ioctl_wmm_queue_status_ac {
338 u8 wmm_acm;
339 u8 flow_required;
340 u8 flow_created;
341 u8 disabled;
342};
343
344struct mwifiex_ds_wmm_queue_status {
345 struct mwifiex_ioctl_wmm_queue_status_ac
346 ac_status[IEEE80211_MAX_QUEUES];
347};
348
349struct mwifiex_ds_11n_tx_cfg {
350 u16 tx_htcap;
351 u16 tx_htinfo;
352};
353
354struct mwifiex_ds_11n_amsdu_aggr_ctrl {
355 u16 enable;
356 u16 curr_buf_size;
357};
358
359#define MWIFIEX_NUM_OF_CMD_BUFFER 20
360#define MWIFIEX_SIZE_OF_CMD_BUFFER 2048
361
362enum {
363 MWIFIEX_IE_TYPE_GEN_IE = 0,
364 MWIFIEX_IE_TYPE_ARP_FILTER,
365};
366
367enum {
368 MWIFIEX_REG_MAC = 1,
369 MWIFIEX_REG_BBP,
370 MWIFIEX_REG_RF,
371 MWIFIEX_REG_PMIC,
372 MWIFIEX_REG_CAU,
373};
374
375struct mwifiex_ds_reg_rw {
376 __le32 type;
377 __le32 offset;
378 __le32 value;
379};
380
381#define MAX_EEPROM_DATA 256
382
383struct mwifiex_ds_read_eeprom {
384 __le16 offset;
385 __le16 byte_count;
386 u8 value[MAX_EEPROM_DATA];
387};
388
389struct mwifiex_ds_misc_gen_ie {
390 u32 type;
391 u32 len;
392 u8 ie_data[IW_CUSTOM_MAX];
393};
394
395struct mwifiex_ds_misc_cmd {
396 u32 len;
397 u8 cmd[MWIFIEX_SIZE_OF_CMD_BUFFER];
398};
399
400#define MWIFIEX_MAX_VSIE_LEN (256)
401#define MWIFIEX_MAX_VSIE_NUM (8)
402#define MWIFIEX_VSIE_MASK_SCAN 0x01
403#define MWIFIEX_VSIE_MASK_ASSOC 0x02
404#define MWIFIEX_VSIE_MASK_ADHOC 0x04
405
406enum {
407 MWIFIEX_FUNC_INIT = 1,
408 MWIFIEX_FUNC_SHUTDOWN,
409};
410
411#endif /* !_MWIFIEX_IOCTL_H_ */
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
new file mode 100644
index 000000000000..7a9e0b5962ed
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -0,0 +1,1462 @@
1/*
2 * Marvell Wireless LAN device driver: association and ad-hoc start/join
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
29
30/*
31 * Append a generic IE as a pass through TLV to a TLV buffer.
32 *
33 * This function is called from the network join command preparation routine.
34 *
35 * If the IE buffer has been setup by the application, this routine appends
36 * the buffer as a pass through TLV type to the request.
37 */
38static int
39mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
40{
41 int ret_len = 0;
42 struct mwifiex_ie_types_header ie_header;
43
44 /* Null Checks */
45 if (!buffer)
46 return 0;
47 if (!(*buffer))
48 return 0;
49
50 /*
51 * If there is a generic ie buffer setup, append it to the return
52 * parameter buffer pointer.
53 */
54 if (priv->gen_ie_buf_len) {
55 dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n",
56 __func__, priv->gen_ie_buf_len, *buffer);
57
58 /* Wrap the generic IE buffer with a pass through TLV type */
59 ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
60 ie_header.len = cpu_to_le16(priv->gen_ie_buf_len);
61 memcpy(*buffer, &ie_header, sizeof(ie_header));
62
63 /* Increment the return size and the return buffer pointer
64 param */
65 *buffer += sizeof(ie_header);
66 ret_len += sizeof(ie_header);
67
68 /* Copy the generic IE buffer to the output buffer, advance
69 pointer */
70 memcpy(*buffer, priv->gen_ie_buf, priv->gen_ie_buf_len);
71
72 /* Increment the return size and the return buffer pointer
73 param */
74 *buffer += priv->gen_ie_buf_len;
75 ret_len += priv->gen_ie_buf_len;
76
77 /* Reset the generic IE buffer */
78 priv->gen_ie_buf_len = 0;
79 }
80
81 /* return the length appended to the buffer */
82 return ret_len;
83}
84
85/*
86 * Append TSF tracking info from the scan table for the target AP.
87 *
88 * This function is called from the network join command preparation routine.
89 *
90 * The TSF table TSF sent to the firmware contains two TSF values:
91 * - The TSF of the target AP from its previous beacon/probe response
92 * - The TSF timestamp of our local MAC at the time we observed the
93 * beacon/probe response.
94 *
95 * The firmware uses the timestamp values to set an initial TSF value
96 * in the MAC for the new association after a reassociation attempt.
97 */
98static int
99mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
100 struct mwifiex_bssdescriptor *bss_desc)
101{
102 struct mwifiex_ie_types_tsf_timestamp tsf_tlv;
103 long long tsf_val;
104
105 /* Null Checks */
106 if (buffer == NULL)
107 return 0;
108 if (*buffer == NULL)
109 return 0;
110
111 memset(&tsf_tlv, 0x00, sizeof(struct mwifiex_ie_types_tsf_timestamp));
112
113 tsf_tlv.header.type = cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
114 tsf_tlv.header.len = cpu_to_le16(2 * sizeof(tsf_val));
115
116 memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header));
117 *buffer += sizeof(tsf_tlv.header);
118
119 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
120 *buffer += sizeof(tsf_val);
121
122 memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val));
123
124 dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - "
125 "%016llx\n", __func__, tsf_val, bss_desc->network_tsf);
126
127 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
128 *buffer += sizeof(tsf_val);
129
130 return sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val));
131}
132
133/*
134 * This function finds out the common rates between rate1 and rate2.
135 *
136 * It will fill common rates in rate1 as output if found.
137 *
138 * NOTE: Setting the MSB of the basic rates needs to be taken
139 * care of, either before or after calling this function.
140 */
141static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
142 u32 rate1_size, u8 *rate2, u32 rate2_size)
143{
144 int ret = 0;
145 u8 *ptr = rate1;
146 u8 *tmp = NULL;
147 u32 i, j;
148
149 tmp = kmalloc(rate1_size, GFP_KERNEL);
150 if (!tmp) {
151 dev_err(priv->adapter->dev, "failed to alloc tmp buf\n");
152 return -ENOMEM;
153 }
154
155 memcpy(tmp, rate1, rate1_size);
156 memset(rate1, 0, rate1_size);
157
158 for (i = 0; rate2[i] && i < rate2_size; i++) {
159 for (j = 0; tmp[j] && j < rate1_size; j++) {
160 /* Check common rate, excluding the bit for
161 basic rate */
162 if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
163 *rate1++ = tmp[j];
164 break;
165 }
166 }
167 }
168
169 dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n",
170 priv->data_rate);
171
172 if (!priv->is_data_rate_auto) {
173 while (*ptr) {
174 if ((*ptr & 0x7f) == priv->data_rate) {
175 ret = 0;
176 goto done;
177 }
178 ptr++;
179 }
180 dev_err(priv->adapter->dev, "previously set fixed data rate %#x"
181 " is not compatible with the network\n",
182 priv->data_rate);
183
184 ret = -1;
185 goto done;
186 }
187
188 ret = 0;
189done:
190 kfree(tmp);
191 return ret;
192}
193
194/*
195 * This function creates the intersection of the rates supported by a
196 * target BSS and our adapter settings for use in an assoc/join command.
197 */
198static int
199mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
200 struct mwifiex_bssdescriptor *bss_desc,
201 u8 *out_rates, u32 *out_rates_size)
202{
203 u8 card_rates[MWIFIEX_SUPPORTED_RATES];
204 u32 card_rates_size = 0;
205
206 /* Copy AP supported rates */
207 memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES);
208 /* Get the STA supported rates */
209 card_rates_size = mwifiex_get_active_data_rates(priv, card_rates);
210 /* Get the common rates between AP and STA supported rates */
211 if (mwifiex_get_common_rates(priv, out_rates, MWIFIEX_SUPPORTED_RATES,
212 card_rates, card_rates_size)) {
213 *out_rates_size = 0;
214 dev_err(priv->adapter->dev, "%s: cannot get common rates\n",
215 __func__);
216 return -1;
217 }
218
219 *out_rates_size =
220 min_t(size_t, strlen(out_rates), MWIFIEX_SUPPORTED_RATES);
221
222 return 0;
223}
224
225/*
226 * This function updates the scan entry TSF timestamps to reflect
227 * a new association.
228 */
229static void
230mwifiex_update_tsf_timestamps(struct mwifiex_private *priv,
231 struct mwifiex_bssdescriptor *new_bss_desc)
232{
233 struct mwifiex_adapter *adapter = priv->adapter;
234 u32 table_idx;
235 long long new_tsf_base;
236 signed long long tsf_delta;
237
238 memcpy(&new_tsf_base, new_bss_desc->time_stamp, sizeof(new_tsf_base));
239
240 tsf_delta = new_tsf_base - new_bss_desc->network_tsf;
241
242 dev_dbg(adapter->dev, "info: TSF: update TSF timestamps, "
243 "0x%016llx -> 0x%016llx\n",
244 new_bss_desc->network_tsf, new_tsf_base);
245
246 for (table_idx = 0; table_idx < adapter->num_in_scan_table;
247 table_idx++)
248 adapter->scan_table[table_idx].network_tsf += tsf_delta;
249}
250
251/*
252 * This function appends a WAPI IE.
253 *
254 * This function is called from the network join command preparation routine.
255 *
256 * If the IE buffer has been setup by the application, this routine appends
257 * the buffer as a WAPI TLV type to the request.
258 */
259static int
260mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
261{
262 int retLen = 0;
263 struct mwifiex_ie_types_header ie_header;
264
265 /* Null Checks */
266 if (buffer == NULL)
267 return 0;
268 if (*buffer == NULL)
269 return 0;
270
271 /*
272 * If there is a wapi ie buffer setup, append it to the return
273 * parameter buffer pointer.
274 */
275 if (priv->wapi_ie_len) {
276 dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n",
277 priv->wapi_ie_len, *buffer);
278
279 /* Wrap the generic IE buffer with a pass through TLV type */
280 ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
281 ie_header.len = cpu_to_le16(priv->wapi_ie_len);
282 memcpy(*buffer, &ie_header, sizeof(ie_header));
283
284 /* Increment the return size and the return buffer pointer
285 param */
286 *buffer += sizeof(ie_header);
287 retLen += sizeof(ie_header);
288
289 /* Copy the wapi IE buffer to the output buffer, advance
290 pointer */
291 memcpy(*buffer, priv->wapi_ie, priv->wapi_ie_len);
292
293 /* Increment the return size and the return buffer pointer
294 param */
295 *buffer += priv->wapi_ie_len;
296 retLen += priv->wapi_ie_len;
297
298 }
299 /* return the length appended to the buffer */
300 return retLen;
301}
302
303/*
304 * This function appends rsn ie tlv for wpa/wpa2 security modes.
305 * It is called from the network join command preparation routine.
306 */
307static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
308 u8 **buffer)
309{
310 struct mwifiex_ie_types_rsn_param_set *rsn_ie_tlv;
311 int rsn_ie_len;
312
313 if (!buffer || !(*buffer))
314 return 0;
315
316 rsn_ie_tlv = (struct mwifiex_ie_types_rsn_param_set *) (*buffer);
317 rsn_ie_tlv->header.type = cpu_to_le16((u16) priv->wpa_ie[0]);
318 rsn_ie_tlv->header.type = cpu_to_le16(
319 le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
320 rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
321 rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
322 & 0x00FF);
323 if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
324 memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
325 le16_to_cpu(rsn_ie_tlv->header.len));
326 else
327 return -1;
328
329 rsn_ie_len = sizeof(rsn_ie_tlv->header) +
330 le16_to_cpu(rsn_ie_tlv->header.len);
331 *buffer += rsn_ie_len;
332
333 return rsn_ie_len;
334}
335
336/*
337 * This function prepares command for association.
338 *
339 * This sets the following parameters -
340 * - Peer MAC address
341 * - Listen interval
342 * - Beacon interval
343 * - Capability information
344 *
345 * ...and the following TLVs, as required -
346 * - SSID TLV
347 * - PHY TLV
348 * - SS TLV
349 * - Rates TLV
350 * - Authentication TLV
351 * - Channel TLV
352 * - WPA/WPA2 IE
353 * - 11n TLV
354 * - Vendor specific TLV
355 * - WMM TLV
356 * - WAPI IE
357 * - Generic IE
358 * - TSF TLV
359 *
360 * Preparation also includes -
361 * - Setting command ID and proper size
362 * - Ensuring correct endian-ness
363 */
364int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
365 struct host_cmd_ds_command *cmd,
366 void *data_buf)
367{
368 struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate;
369 struct mwifiex_bssdescriptor *bss_desc;
370 struct mwifiex_ie_types_ssid_param_set *ssid_tlv;
371 struct mwifiex_ie_types_phy_param_set *phy_tlv;
372 struct mwifiex_ie_types_ss_param_set *ss_tlv;
373 struct mwifiex_ie_types_rates_param_set *rates_tlv;
374 struct mwifiex_ie_types_auth_type *auth_tlv;
375 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
376 u8 rates[MWIFIEX_SUPPORTED_RATES];
377 u32 rates_size;
378 u16 tmp_cap;
379 u8 *pos;
380 int rsn_ie_len = 0;
381
382 bss_desc = (struct mwifiex_bssdescriptor *) data_buf;
383 pos = (u8 *) assoc;
384
385 mwifiex_cfg_tx_buf(priv, bss_desc);
386
387 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
388
389 /* Save so we know which BSS Desc to use in the response handler */
390 priv->attempted_bss_desc = bss_desc;
391
392 memcpy(assoc->peer_sta_addr,
393 bss_desc->mac_address, sizeof(assoc->peer_sta_addr));
394 pos += sizeof(assoc->peer_sta_addr);
395
396 /* Set the listen interval */
397 assoc->listen_interval = cpu_to_le16(priv->listen_interval);
398 /* Set the beacon period */
399 assoc->beacon_period = cpu_to_le16(bss_desc->beacon_period);
400
401 pos += sizeof(assoc->cap_info_bitmap);
402 pos += sizeof(assoc->listen_interval);
403 pos += sizeof(assoc->beacon_period);
404 pos += sizeof(assoc->dtim_period);
405
406 ssid_tlv = (struct mwifiex_ie_types_ssid_param_set *) pos;
407 ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
408 ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
409 memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
410 le16_to_cpu(ssid_tlv->header.len));
411 pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
412
413 phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
414 phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
415 phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
416 memcpy(&phy_tlv->fh_ds.ds_param_set,
417 &bss_desc->phy_param_set.ds_param_set.current_chan,
418 sizeof(phy_tlv->fh_ds.ds_param_set));
419 pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
420
421 ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
422 ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
423 ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
424 pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
425
426 /* Get the common rates supported between the driver and the BSS Desc */
427 if (mwifiex_setup_rates_from_bssdesc
428 (priv, bss_desc, rates, &rates_size))
429 return -1;
430
431 /* Save the data rates into Current BSS state structure */
432 priv->curr_bss_params.num_of_rates = rates_size;
433 memcpy(&priv->curr_bss_params.data_rates, rates, rates_size);
434
435 /* Setup the Rates TLV in the association command */
436 rates_tlv = (struct mwifiex_ie_types_rates_param_set *) pos;
437 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
438 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
439 memcpy(rates_tlv->rates, rates, rates_size);
440 pos += sizeof(rates_tlv->header) + rates_size;
441 dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n",
442 rates_size);
443
444 /* Add the Authentication type to be used for Auth frames */
445 auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
446 auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
447 auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
448 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
449 auth_tlv->auth_type = cpu_to_le16(
450 (u16) priv->sec_info.authentication_mode);
451 else
452 auth_tlv->auth_type = cpu_to_le16(NL80211_AUTHTYPE_OPEN_SYSTEM);
453
454 pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
455
456 if (IS_SUPPORT_MULTI_BANDS(priv->adapter)
457 && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
458 && (!bss_desc->disable_11n)
459 && (priv->adapter->config_bands & BAND_GN
460 || priv->adapter->config_bands & BAND_AN)
461 && (bss_desc->bcn_ht_cap)
462 )
463 ) {
464 /* Append a channel TLV for the channel the attempted AP was
465 found on */
466 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
467 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
468 chan_tlv->header.len =
469 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
470
471 memset(chan_tlv->chan_scan_param, 0x00,
472 sizeof(struct mwifiex_chan_scan_param_set));
473 chan_tlv->chan_scan_param[0].chan_number =
474 (bss_desc->phy_param_set.ds_param_set.current_chan);
475 dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n",
476 chan_tlv->chan_scan_param[0].chan_number);
477
478 chan_tlv->chan_scan_param[0].radio_type =
479 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
480
481 dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n",
482 chan_tlv->chan_scan_param[0].radio_type);
483 pos += sizeof(chan_tlv->header) +
484 sizeof(struct mwifiex_chan_scan_param_set);
485 }
486
487 if (!priv->wps.session_enable) {
488 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
489 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
490
491 if (rsn_ie_len == -1)
492 return -1;
493 }
494
495 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
496 && (!bss_desc->disable_11n)
497 && (priv->adapter->config_bands & BAND_GN
498 || priv->adapter->config_bands & BAND_AN))
499 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
500
501 /* Append vendor specific IE TLV */
502 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
503
504 mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie,
505 bss_desc->bcn_ht_cap);
506 if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
507 mwifiex_cmd_append_wapi_ie(priv, &pos);
508
509
510 mwifiex_cmd_append_generic_ie(priv, &pos);
511
512 mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
513
514 cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
515
516 /* Set the Capability info at last */
517 tmp_cap = bss_desc->cap_info_bitmap;
518
519 if (priv->adapter->config_bands == BAND_B)
520 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
521
522 tmp_cap &= CAPINFO_MASK;
523 dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
524 tmp_cap, CAPINFO_MASK);
525 assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
526
527 return 0;
528}
529
530/*
531 * Association firmware command response handler
532 *
533 * The response buffer for the association command has the following
534 * memory layout.
535 *
536 * For cases where an association response was not received (indicated
537 * by the CapInfo and AId field):
538 *
539 * .------------------------------------------------------------.
540 * | Header(4 * sizeof(t_u16)): Standard command response hdr |
541 * .------------------------------------------------------------.
542 * | cap_info/Error Return(t_u16): |
543 * | 0xFFFF(-1): Internal error |
544 * | 0xFFFE(-2): Authentication unhandled message |
545 * | 0xFFFD(-3): Authentication refused |
546 * | 0xFFFC(-4): Timeout waiting for AP response |
547 * .------------------------------------------------------------.
548 * | status_code(t_u16): |
549 * | If cap_info is -1: |
550 * | An internal firmware failure prevented the |
551 * | command from being processed. The status_code |
552 * | will be set to 1. |
553 * | |
554 * | If cap_info is -2: |
555 * | An authentication frame was received but was |
556 * | not handled by the firmware. IEEE Status |
557 * | code for the failure is returned. |
558 * | |
559 * | If cap_info is -3: |
560 * | An authentication frame was received and the |
561 * | status_code is the IEEE Status reported in the |
562 * | response. |
563 * | |
564 * | If cap_info is -4: |
565 * | (1) Association response timeout |
566 * | (2) Authentication response timeout |
567 * .------------------------------------------------------------.
568 * | a_id(t_u16): 0xFFFF |
569 * .------------------------------------------------------------.
570 *
571 *
572 * For cases where an association response was received, the IEEE
573 * standard association response frame is returned:
574 *
575 * .------------------------------------------------------------.
576 * | Header(4 * sizeof(t_u16)): Standard command response hdr |
577 * .------------------------------------------------------------.
578 * | cap_info(t_u16): IEEE Capability |
579 * .------------------------------------------------------------.
580 * | status_code(t_u16): IEEE Status Code |
581 * .------------------------------------------------------------.
582 * | a_id(t_u16): IEEE Association ID |
583 * .------------------------------------------------------------.
584 * | IEEE IEs(variable): Any received IEs comprising the |
585 * | remaining portion of a received |
586 * | association response frame. |
587 * .------------------------------------------------------------.
588 *
589 * For simplistic handling, the status_code field can be used to determine
590 * an association success (0) or failure (non-zero).
591 */
592int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
593 struct host_cmd_ds_command *resp, void *wq_buf)
594{
595 int ret = 0;
596 struct mwifiex_wait_queue *wait_queue =
597 (struct mwifiex_wait_queue *) wq_buf;
598 struct ieee_types_assoc_rsp *assoc_rsp;
599 struct mwifiex_bssdescriptor *bss_desc;
600 u8 enable_data = true;
601
602 assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
603
604 priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
605 sizeof(priv->assoc_rsp_buf));
606
607 memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
608
609 if (le16_to_cpu(assoc_rsp->status_code)) {
610 priv->adapter->dbg.num_cmd_assoc_failure++;
611 dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, "
612 "status code = %d, error = 0x%x, a_id = 0x%x\n",
613 le16_to_cpu(assoc_rsp->status_code),
614 le16_to_cpu(assoc_rsp->cap_info_bitmap),
615 le16_to_cpu(assoc_rsp->a_id));
616
617 ret = -1;
618 goto done;
619 }
620
621 /* Send a Media Connected event, according to the Spec */
622 priv->media_connected = true;
623
624 priv->adapter->ps_state = PS_STATE_AWAKE;
625 priv->adapter->pps_uapsd_mode = false;
626 priv->adapter->tx_lock_flag = false;
627
628 /* Set the attempted BSSID Index to current */
629 bss_desc = priv->attempted_bss_desc;
630
631 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
632 bss_desc->ssid.ssid);
633
634 /* Make a copy of current BSSID descriptor */
635 memcpy(&priv->curr_bss_params.bss_descriptor,
636 bss_desc, sizeof(struct mwifiex_bssdescriptor));
637
638 /* Update curr_bss_params */
639 priv->curr_bss_params.bss_descriptor.channel
640 = bss_desc->phy_param_set.ds_param_set.current_chan;
641
642 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
643
644 /*
645 * Adjust the timestamps in the scan table to be relative to the newly
646 * associated AP's TSF
647 */
648 mwifiex_update_tsf_timestamps(priv, bss_desc);
649
650 if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
651 priv->curr_bss_params.wmm_enabled = true;
652 else
653 priv->curr_bss_params.wmm_enabled = false;
654
655 if ((priv->wmm_required || bss_desc->bcn_ht_cap)
656 && priv->curr_bss_params.wmm_enabled)
657 priv->wmm_enabled = true;
658 else
659 priv->wmm_enabled = false;
660
661 priv->curr_bss_params.wmm_uapsd_enabled = false;
662
663 if (priv->wmm_enabled)
664 priv->curr_bss_params.wmm_uapsd_enabled
665 = ((bss_desc->wmm_ie.qos_info_bitmap &
666 IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
667
668 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
669 priv->curr_pkt_filter);
670 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
671 priv->wpa_is_gtk_set = false;
672
673 if (priv->wmm_enabled) {
674 /* Don't re-enable carrier until we get the WMM_GET_STATUS
675 event */
676 enable_data = false;
677 } else {
678 /* Since WMM is not enabled, setup the queues with the
679 defaults */
680 mwifiex_wmm_setup_queue_priorities(priv, NULL);
681 mwifiex_wmm_setup_ac_downgrade(priv);
682 }
683
684 if (enable_data)
685 dev_dbg(priv->adapter->dev,
686 "info: post association, re-enabling data flow\n");
687
688 /* Reset SNR/NF/RSSI values */
689 priv->data_rssi_last = 0;
690 priv->data_nf_last = 0;
691 priv->data_rssi_avg = 0;
692 priv->data_nf_avg = 0;
693 priv->bcn_rssi_last = 0;
694 priv->bcn_nf_last = 0;
695 priv->bcn_rssi_avg = 0;
696 priv->bcn_nf_avg = 0;
697 priv->rxpd_rate = 0;
698 priv->rxpd_htinfo = 0;
699
700 mwifiex_save_curr_bcn(priv);
701
702 priv->adapter->dbg.num_cmd_assoc_success++;
703
704 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: associated\n");
705
706 /* Add the ra_list here for infra mode as there will be only 1 ra
707 always */
708 mwifiex_ralist_add(priv,
709 priv->curr_bss_params.bss_descriptor.mac_address);
710
711 if (!netif_carrier_ok(priv->netdev))
712 netif_carrier_on(priv->netdev);
713 if (netif_queue_stopped(priv->netdev))
714 netif_wake_queue(priv->netdev);
715
716 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
717 priv->scan_block = true;
718
719done:
720 /* Need to indicate IOCTL complete */
721 if (wait_queue) {
722 if (ret) {
723 if (assoc_rsp->status_code)
724 wait_queue->status =
725 le16_to_cpu(assoc_rsp->status_code);
726 else
727 wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL;
728 } else {
729 wait_queue->status = MWIFIEX_ERROR_NO_ERROR;
730 }
731 }
732
733 return ret;
734}
735
736/*
737 * This function prepares command for ad-hoc start.
738 *
739 * Driver will fill up SSID, BSS mode, IBSS parameters, physical
740 * parameters, probe delay, and capability information. Firmware
741 * will fill up beacon period, basic rates and operational rates.
742 *
743 * In addition, the following TLVs are added -
744 * - Channel TLV
745 * - Vendor specific IE
746 * - WPA/WPA2 IE
747 * - HT Capabilities IE
748 * - HT Information IE
749 *
750 * Preparation also includes -
751 * - Setting command ID and proper size
752 * - Ensuring correct endian-ness
753 */
754int
755mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
756 struct host_cmd_ds_command *cmd, void *data_buf)
757{
758 int ret = 0, rsn_ie_len = 0;
759 struct mwifiex_adapter *adapter = priv->adapter;
760 struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start =
761 &cmd->params.adhoc_start;
762 struct mwifiex_bssdescriptor *bss_desc;
763 u32 cmd_append_size = 0;
764 u32 i;
765 u16 tmp_cap;
766 uint16_t ht_cap_info;
767 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
768
769 struct mwifiex_ie_types_htcap *ht_cap;
770 struct mwifiex_ie_types_htinfo *ht_info;
771 u8 *pos = (u8 *) adhoc_start +
772 sizeof(struct host_cmd_ds_802_11_ad_hoc_start);
773
774 if (!adapter)
775 return -1;
776
777 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
778
779 bss_desc = &priv->curr_bss_params.bss_descriptor;
780 priv->attempted_bss_desc = bss_desc;
781
782 /*
783 * Fill in the parameters for 2 data structures:
784 * 1. struct host_cmd_ds_802_11_ad_hoc_start command
785 * 2. bss_desc
786 * Driver will fill up SSID, bss_mode,IBSS param, Physical Param,
787 * probe delay, and Cap info.
788 * Firmware will fill up beacon period, Basic rates
789 * and operational rates.
790 */
791
792 memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
793
794 memcpy(adhoc_start->ssid,
795 ((struct mwifiex_802_11_ssid *) data_buf)->ssid,
796 ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len);
797
798 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
799 adhoc_start->ssid);
800
801 memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
802 memcpy(bss_desc->ssid.ssid,
803 ((struct mwifiex_802_11_ssid *) data_buf)->ssid,
804 ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len);
805
806 bss_desc->ssid.ssid_len =
807 ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len;
808
809 /* Set the BSS mode */
810 adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
811 bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
812 adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
813 bss_desc->beacon_period = priv->beacon_period;
814
815 /* Set Physical param set */
816/* Parameter IE Id */
817#define DS_PARA_IE_ID 3
818/* Parameter IE length */
819#define DS_PARA_IE_LEN 1
820
821 adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
822 adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
823
824 if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
825 (priv, adapter->adhoc_start_band, (u16)
826 priv->adhoc_channel)) {
827 struct mwifiex_chan_freq_power *cfp;
828 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
829 adapter->adhoc_start_band, FIRST_VALID_CHANNEL);
830 if (cfp)
831 priv->adhoc_channel = (u8) cfp->channel;
832 }
833
834 if (!priv->adhoc_channel) {
835 dev_err(adapter->dev, "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
836 return -1;
837 }
838
839 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
840 priv->adhoc_channel);
841
842 priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
843 priv->curr_bss_params.band = adapter->adhoc_start_band;
844
845 bss_desc->channel = priv->adhoc_channel;
846 adhoc_start->phy_param_set.ds_param_set.current_chan =
847 priv->adhoc_channel;
848
849 memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
850 sizeof(union ieee_types_phy_param_set));
851
852 /* Set IBSS param set */
853/* IBSS parameter IE Id */
854#define IBSS_PARA_IE_ID 6
855/* IBSS parameter IE length */
856#define IBSS_PARA_IE_LEN 2
857
858 adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
859 adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
860 adhoc_start->ss_param_set.ibss_param_set.atim_window
861 = cpu_to_le16(priv->atim_window);
862 memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
863 sizeof(union ieee_types_ss_param_set));
864
865 /* Set Capability info */
866 bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
867 tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap);
868 tmp_cap &= ~WLAN_CAPABILITY_ESS;
869 tmp_cap |= WLAN_CAPABILITY_IBSS;
870
871 /* Set up privacy in bss_desc */
872 if (priv->sec_info.encryption_mode) {
873 /* Ad-Hoc capability privacy on */
874 dev_dbg(adapter->dev,
875 "info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
876 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
877 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
878 } else {
879 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status NOT set,"
880 " setting privacy to ACCEPT ALL\n");
881 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
882 }
883
884 memset(adhoc_start->DataRate, 0, sizeof(adhoc_start->DataRate));
885 mwifiex_get_active_data_rates(priv, adhoc_start->DataRate);
886 if ((adapter->adhoc_start_band & BAND_G) &&
887 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
888 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL,
889 HostCmd_ACT_GEN_SET,
890 0, NULL, &priv->curr_pkt_filter);
891
892 if (ret) {
893 dev_err(adapter->dev,
894 "ADHOC_S_CMD: G Protection config failed\n");
895 return -1;
896 }
897 }
898 /* Find the last non zero */
899 for (i = 0; i < sizeof(adhoc_start->DataRate) &&
900 adhoc_start->DataRate[i];
901 i++)
902 ;
903
904 priv->curr_bss_params.num_of_rates = i;
905
906 /* Copy the ad-hoc creating rates into Current BSS rate structure */
907 memcpy(&priv->curr_bss_params.data_rates,
908 &adhoc_start->DataRate, priv->curr_bss_params.num_of_rates);
909
910 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n",
911 adhoc_start->DataRate[0], adhoc_start->DataRate[1],
912 adhoc_start->DataRate[2], adhoc_start->DataRate[3]);
913
914 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
915
916 if (IS_SUPPORT_MULTI_BANDS(adapter)) {
917 /* Append a channel TLV */
918 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
919 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
920 chan_tlv->header.len =
921 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
922
923 memset(chan_tlv->chan_scan_param, 0x00,
924 sizeof(struct mwifiex_chan_scan_param_set));
925 chan_tlv->chan_scan_param[0].chan_number =
926 (u8) priv->curr_bss_params.bss_descriptor.channel;
927
928 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
929 chan_tlv->chan_scan_param[0].chan_number);
930
931 chan_tlv->chan_scan_param[0].radio_type
932 = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
933 if (adapter->adhoc_start_band & BAND_GN
934 || adapter->adhoc_start_band & BAND_AN) {
935 if (adapter->chan_offset == SEC_CHANNEL_ABOVE)
936 chan_tlv->chan_scan_param[0].radio_type |=
937 SECOND_CHANNEL_ABOVE;
938 else if (adapter->chan_offset == SEC_CHANNEL_BELOW)
939 chan_tlv->chan_scan_param[0].radio_type |=
940 SECOND_CHANNEL_BELOW;
941 }
942 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
943 chan_tlv->chan_scan_param[0].radio_type);
944 pos += sizeof(chan_tlv->header) +
945 sizeof(struct mwifiex_chan_scan_param_set);
946 cmd_append_size +=
947 sizeof(chan_tlv->header) +
948 sizeof(struct mwifiex_chan_scan_param_set);
949 }
950
951 /* Append vendor specific IE TLV */
952 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
953 MWIFIEX_VSIE_MASK_ADHOC, &pos);
954
955 if (priv->sec_info.wpa_enabled) {
956 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
957 if (rsn_ie_len == -1)
958 return -1;
959 cmd_append_size += rsn_ie_len;
960 }
961
962 if (adapter->adhoc_11n_enabled) {
963 {
964 ht_cap = (struct mwifiex_ie_types_htcap *) pos;
965 memset(ht_cap, 0,
966 sizeof(struct mwifiex_ie_types_htcap));
967 ht_cap->header.type =
968 cpu_to_le16(WLAN_EID_HT_CAPABILITY);
969 ht_cap->header.len =
970 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
971 ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info);
972
973 ht_cap_info |= IEEE80211_HT_CAP_SGI_20;
974 if (adapter->chan_offset) {
975 ht_cap_info |= IEEE80211_HT_CAP_SGI_40;
976 ht_cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
977 ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
978 SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
979 }
980
981 ht_cap->ht_cap.ampdu_params_info
982 = IEEE80211_HT_MAX_AMPDU_64K;
983 ht_cap->ht_cap.mcs.rx_mask[0] = 0xff;
984 pos += sizeof(struct mwifiex_ie_types_htcap);
985 cmd_append_size +=
986 sizeof(struct mwifiex_ie_types_htcap);
987 }
988 {
989 ht_info = (struct mwifiex_ie_types_htinfo *) pos;
990 memset(ht_info, 0,
991 sizeof(struct mwifiex_ie_types_htinfo));
992 ht_info->header.type =
993 cpu_to_le16(WLAN_EID_HT_INFORMATION);
994 ht_info->header.len =
995 cpu_to_le16(sizeof(struct ieee80211_ht_info));
996 ht_info->ht_info.control_chan =
997 (u8) priv->curr_bss_params.bss_descriptor.
998 channel;
999 if (adapter->chan_offset) {
1000 ht_info->ht_info.ht_param =
1001 adapter->chan_offset;
1002 ht_info->ht_info.ht_param |=
1003 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1004 }
1005 ht_info->ht_info.operation_mode =
1006 cpu_to_le16(NON_GREENFIELD_STAS);
1007 ht_info->ht_info.basic_set[0] = 0xff;
1008 pos += sizeof(struct mwifiex_ie_types_htinfo);
1009 cmd_append_size +=
1010 sizeof(struct mwifiex_ie_types_htinfo);
1011 }
1012 }
1013
1014 cmd->size = cpu_to_le16((u16)
1015 (sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
1016 + S_DS_GEN + cmd_append_size));
1017
1018 if (adapter->adhoc_start_band == BAND_B)
1019 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
1020 else
1021 tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
1022
1023 adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
1024
1025 return 0;
1026}
1027
1028/*
1029 * This function prepares command for ad-hoc join.
1030 *
1031 * Most of the parameters are set up by copying from the target BSS descriptor
1032 * from the scan response.
1033 *
1034 * In addition, the following TLVs are added -
1035 * - Channel TLV
1036 * - Vendor specific IE
1037 * - WPA/WPA2 IE
1038 * - 11n IE
1039 *
1040 * Preparation also includes -
1041 * - Setting command ID and proper size
1042 * - Ensuring correct endian-ness
1043 */
1044int
1045mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1046 struct host_cmd_ds_command *cmd, void *data_buf)
1047{
1048 int ret = 0, rsn_ie_len = 0;
1049 struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
1050 &cmd->params.adhoc_join;
1051 struct mwifiex_bssdescriptor *bss_desc =
1052 (struct mwifiex_bssdescriptor *) data_buf;
1053 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
1054 u32 cmd_append_size = 0;
1055 u16 tmp_cap;
1056 u32 i, rates_size = 0;
1057 u16 curr_pkt_filter;
1058 u8 *pos =
1059 (u8 *) adhoc_join +
1060 sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
1061
1062/* Use G protection */
1063#define USE_G_PROTECTION 0x02
1064 if (bss_desc->erp_flags & USE_G_PROTECTION) {
1065 curr_pkt_filter =
1066 priv->
1067 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1068
1069 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1070 HostCmd_ACT_GEN_SET, 0, NULL,
1071 &curr_pkt_filter);
1072 if (ret) {
1073 dev_err(priv->adapter->dev,
1074 "ADHOC_J_CMD: G Protection config failed\n");
1075 return -1;
1076 }
1077 }
1078
1079 priv->attempted_bss_desc = bss_desc;
1080
1081 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
1082
1083 adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
1084
1085 adhoc_join->bss_descriptor.beacon_period
1086 = cpu_to_le16(bss_desc->beacon_period);
1087
1088 memcpy(&adhoc_join->bss_descriptor.bssid,
1089 &bss_desc->mac_address, ETH_ALEN);
1090
1091 memcpy(&adhoc_join->bss_descriptor.ssid,
1092 &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
1093
1094 memcpy(&adhoc_join->bss_descriptor.phy_param_set,
1095 &bss_desc->phy_param_set,
1096 sizeof(union ieee_types_phy_param_set));
1097
1098 memcpy(&adhoc_join->bss_descriptor.ss_param_set,
1099 &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
1100
1101 tmp_cap = bss_desc->cap_info_bitmap;
1102
1103 tmp_cap &= CAPINFO_MASK;
1104
1105 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X"
1106 " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK);
1107
1108 /* Information on BSSID descriptor passed to FW */
1109 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n",
1110 adhoc_join->bss_descriptor.bssid,
1111 adhoc_join->bss_descriptor.ssid);
1112
1113 for (i = 0; bss_desc->supported_rates[i] &&
1114 i < MWIFIEX_SUPPORTED_RATES;
1115 i++)
1116 ;
1117 rates_size = i;
1118
1119 /* Copy Data Rates from the Rates recorded in scan response */
1120 memset(adhoc_join->bss_descriptor.data_rates, 0,
1121 sizeof(adhoc_join->bss_descriptor.data_rates));
1122 memcpy(adhoc_join->bss_descriptor.data_rates,
1123 bss_desc->supported_rates, rates_size);
1124
1125 /* Copy the adhoc join rates into Current BSS state structure */
1126 priv->curr_bss_params.num_of_rates = rates_size;
1127 memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
1128 rates_size);
1129
1130 /* Copy the channel information */
1131 priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
1132 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
1133
1134 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
1135 || priv->sec_info.wpa_enabled)
1136 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
1137
1138 if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
1139 /* Append a channel TLV */
1140 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
1141 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
1142 chan_tlv->header.len =
1143 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
1144
1145 memset(chan_tlv->chan_scan_param, 0x00,
1146 sizeof(struct mwifiex_chan_scan_param_set));
1147 chan_tlv->chan_scan_param[0].chan_number =
1148 (bss_desc->phy_param_set.ds_param_set.current_chan);
1149 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n",
1150 chan_tlv->chan_scan_param[0].chan_number);
1151
1152 chan_tlv->chan_scan_param[0].radio_type =
1153 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
1154
1155 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n",
1156 chan_tlv->chan_scan_param[0].radio_type);
1157 pos += sizeof(chan_tlv->header) +
1158 sizeof(struct mwifiex_chan_scan_param_set);
1159 cmd_append_size += sizeof(chan_tlv->header) +
1160 sizeof(struct mwifiex_chan_scan_param_set);
1161 }
1162
1163 if (priv->sec_info.wpa_enabled)
1164 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1165 if (rsn_ie_len == -1)
1166 return -1;
1167 cmd_append_size += rsn_ie_len;
1168
1169 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
1170 cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
1171 bss_desc, &pos);
1172
1173 /* Append vendor specific IE TLV */
1174 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1175 MWIFIEX_VSIE_MASK_ADHOC, &pos);
1176
1177 cmd->size = cpu_to_le16((u16)
1178 (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
1179 + S_DS_GEN + cmd_append_size));
1180
1181 adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
1182
1183 return ret;
1184}
1185
1186/*
1187 * This function handles the command response of ad-hoc start and
1188 * ad-hoc join.
1189 *
1190 * The function generates a device-connected event to notify
1191 * the applications, in case of successful ad-hoc start/join, and
1192 * saves the beacon buffer.
1193 */
1194int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1195 struct host_cmd_ds_command *resp, void *wq_buf)
1196{
1197 int ret = 0;
1198 struct mwifiex_wait_queue *wait_queue =
1199 (struct mwifiex_wait_queue *) wq_buf;
1200 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
1201 struct mwifiex_bssdescriptor *bss_desc;
1202 u16 command = le16_to_cpu(resp->command);
1203 u16 result = le16_to_cpu(resp->result);
1204
1205 adhoc_result = &resp->params.adhoc_result;
1206
1207 bss_desc = priv->attempted_bss_desc;
1208
1209 /* Join result code 0 --> SUCCESS */
1210 if (result) {
1211 dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
1212 if (priv->media_connected)
1213 mwifiex_reset_connect_state(priv);
1214
1215 memset(&priv->curr_bss_params.bss_descriptor,
1216 0x00, sizeof(struct mwifiex_bssdescriptor));
1217
1218 ret = -1;
1219 goto done;
1220 }
1221
1222 /* Send a Media Connected event, according to the Spec */
1223 priv->media_connected = true;
1224
1225 if (command == HostCmd_CMD_802_11_AD_HOC_START) {
1226 dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
1227 bss_desc->ssid.ssid);
1228
1229 /* Update the created network descriptor with the new BSSID */
1230 memcpy(bss_desc->mac_address,
1231 adhoc_result->bssid, ETH_ALEN);
1232
1233 priv->adhoc_state = ADHOC_STARTED;
1234 } else {
1235 /*
1236 * Now the join cmd should be successful.
1237 * If BSSID has changed use SSID to compare instead of BSSID
1238 */
1239 dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
1240 bss_desc->ssid.ssid);
1241
1242 /*
1243 * Make a copy of current BSSID descriptor, only needed for
1244 * join since the current descriptor is already being used
1245 * for adhoc start
1246 */
1247 memcpy(&priv->curr_bss_params.bss_descriptor,
1248 bss_desc, sizeof(struct mwifiex_bssdescriptor));
1249
1250 priv->adhoc_state = ADHOC_JOINED;
1251 }
1252
1253 dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
1254 priv->adhoc_channel);
1255 dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
1256 priv->curr_bss_params.bss_descriptor.mac_address);
1257
1258 if (!netif_carrier_ok(priv->netdev))
1259 netif_carrier_on(priv->netdev);
1260 if (netif_queue_stopped(priv->netdev))
1261 netif_wake_queue(priv->netdev);
1262
1263 mwifiex_save_curr_bcn(priv);
1264
1265done:
1266 /* Need to indicate IOCTL complete */
1267 if (wait_queue) {
1268 if (ret)
1269 wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL;
1270 else
1271 wait_queue->status = MWIFIEX_ERROR_NO_ERROR;
1272
1273 }
1274
1275 return ret;
1276}
1277
1278/*
1279 * This function associates to a specific BSS discovered in a scan.
1280 *
1281 * It clears any past association response stored for application
1282 * retrieval and calls the command preparation routine to send the
1283 * command to firmware.
1284 */
1285int mwifiex_associate(struct mwifiex_private *priv,
1286 void *wait_queue, struct mwifiex_bssdescriptor *bss_desc)
1287{
1288 int ret = 0;
1289 u8 current_bssid[ETH_ALEN];
1290
1291 /* Return error if the adapter or table entry is not marked as infra */
1292 if ((priv->bss_mode != NL80211_IFTYPE_STATION) ||
1293 (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
1294 return -1;
1295
1296 memcpy(&current_bssid,
1297 &priv->curr_bss_params.bss_descriptor.mac_address,
1298 sizeof(current_bssid));
1299
1300 /* Clear any past association response stored for application
1301 retrieval */
1302 priv->assoc_rsp_size = 0;
1303
1304 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE,
1305 HostCmd_ACT_GEN_SET, 0, wait_queue,
1306 bss_desc);
1307
1308 return ret;
1309}
1310
1311/*
1312 * This function starts an ad-hoc network.
1313 *
1314 * It calls the command preparation routine to send the command to firmware.
1315 */
1316int
1317mwifiex_adhoc_start(struct mwifiex_private *priv,
1318 void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid)
1319{
1320 int ret = 0;
1321
1322 dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
1323 priv->adhoc_channel);
1324 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1325 priv->curr_bss_params.bss_descriptor.channel);
1326 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
1327 priv->curr_bss_params.band);
1328
1329 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START,
1330 HostCmd_ACT_GEN_SET, 0, wait_queue,
1331 adhoc_ssid);
1332
1333 return ret;
1334}
1335
1336/*
1337 * This function joins an ad-hoc network found in a previous scan.
1338 *
1339 * It calls the command preparation routine to send the command to firmware,
1340 * if already not connected to the requested SSID.
1341 */
1342int mwifiex_adhoc_join(struct mwifiex_private *priv,
1343 void *wait_queue, struct mwifiex_bssdescriptor *bss_desc)
1344{
1345 int ret = 0;
1346
1347 dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
1348 priv->curr_bss_params.bss_descriptor.ssid.ssid);
1349 dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
1350 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
1351 dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
1352 bss_desc->ssid.ssid);
1353 dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
1354 bss_desc->ssid.ssid_len);
1355
1356 /* Check if the requested SSID is already joined */
1357 if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
1358 !mwifiex_ssid_cmp(&bss_desc->ssid,
1359 &priv->curr_bss_params.bss_descriptor.ssid) &&
1360 (priv->curr_bss_params.bss_descriptor.bss_mode ==
1361 NL80211_IFTYPE_ADHOC)) {
1362 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID"
1363 " is the same as current; not attempting to re-join\n");
1364 return -1;
1365 }
1366
1367 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1368 priv->curr_bss_params.bss_descriptor.channel);
1369 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
1370 priv->curr_bss_params.band);
1371
1372 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1373 HostCmd_ACT_GEN_SET, 0, wait_queue,
1374 bss_desc);
1375
1376 return ret;
1377}
1378
1379/*
1380 * This function deauthenticates/disconnects from infra network by sending
1381 * deauthentication request.
1382 */
1383static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv,
1384 struct mwifiex_wait_queue *wait,
1385 u8 *mac)
1386{
1387 u8 mac_address[ETH_ALEN];
1388 int ret = 0;
1389 u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1390
1391 if (mac) {
1392 if (!memcmp(mac, zero_mac, sizeof(zero_mac)))
1393 memcpy((u8 *) &mac_address,
1394 (u8 *) &priv->curr_bss_params.bss_descriptor.
1395 mac_address, ETH_ALEN);
1396 else
1397 memcpy((u8 *) &mac_address, (u8 *) mac, ETH_ALEN);
1398 } else {
1399 memcpy((u8 *) &mac_address, (u8 *) &priv->curr_bss_params.
1400 bss_descriptor.mac_address, ETH_ALEN);
1401 }
1402
1403 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1404 HostCmd_ACT_GEN_SET, 0, wait, &mac_address);
1405
1406 if (!ret && wait)
1407 ret = -EINPROGRESS;
1408
1409 return ret;
1410}
1411
1412/*
1413 * This function deauthenticates/disconnects from a BSS.
1414 *
1415 * In case of infra made, it sends deauthentication request, and
1416 * in case of ad-hoc mode, a stop network request is sent to the firmware.
1417 */
1418int mwifiex_deauthenticate(struct mwifiex_private *priv,
1419 struct mwifiex_wait_queue *wait, u8 *mac)
1420{
1421 int ret = 0;
1422
1423 if (priv->media_connected) {
1424 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
1425 ret = mwifiex_deauthenticate_infra(priv, wait, mac);
1426 } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
1427 ret = mwifiex_prepare_cmd(priv,
1428 HostCmd_CMD_802_11_AD_HOC_STOP,
1429 HostCmd_ACT_GEN_SET, 0, wait, NULL);
1430
1431 if (!ret && wait)
1432 ret = -EINPROGRESS;
1433 }
1434 }
1435
1436 return ret;
1437}
1438
1439/*
1440 * This function converts band to radio type used in channel TLV.
1441 */
1442u8
1443mwifiex_band_to_radio_type(u8 band)
1444{
1445 u8 ret_radio_type;
1446
1447 switch (band) {
1448 case BAND_A:
1449 case BAND_AN:
1450 case BAND_A | BAND_AN:
1451 ret_radio_type = HostCmd_SCAN_RADIO_TYPE_A;
1452 break;
1453 case BAND_B:
1454 case BAND_G:
1455 case BAND_B | BAND_G:
1456 default:
1457 ret_radio_type = HostCmd_SCAN_RADIO_TYPE_BG;
1458 break;
1459 }
1460
1461 return ret_radio_type;
1462}
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
new file mode 100644
index 000000000000..ed89ca41a902
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -0,0 +1,1102 @@
1/*
2 * Marvell Wireless LAN device driver: major functions
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "main.h"
21#include "wmm.h"
22#include "cfg80211.h"
23#include "11n.h"
24
25#define VERSION "1.0"
26
27const char driver_version[] = "mwifiex " VERSION " (%s) ";
28
29struct mwifiex_adapter *g_adapter;
30EXPORT_SYMBOL_GPL(g_adapter);
31
32static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
33 {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
34};
35
36static int drv_mode = DRV_MODE_STA;
37
38static char fw_name[32] = DEFAULT_FW_NAME;
39
40/* Supported drv_mode table */
41static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
42 {
43 /* drv_mode */
44 .drv_mode = DRV_MODE_STA,
45 /* intf number */
46 .intf_num = ARRAY_SIZE(mwifiex_bss_sta),
47 /* bss_attr */
48 .bss_attr = mwifiex_bss_sta,
49 }
50 ,
51};
52
53/*
54 * This function registers the device and performs all the necessary
55 * initializations.
56 *
57 * The following initialization operations are performed -
58 * - Allocate adapter structure
59 * - Save interface specific operations table in adapter
60 * - Call interface specific initialization routine
61 * - Allocate private structures
62 * - Set default adapter structure parameters
63 * - Initialize locks
64 *
65 * In case of any errors during inittialization, this function also ensures
66 * proper cleanup before exiting.
67 */
68static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
69 struct mwifiex_device *mdevice, void **padapter)
70{
71 int ret = 0;
72 struct mwifiex_adapter *adapter = NULL;
73 u8 i = 0;
74
75 adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
76 /* Allocate memory for adapter structure */
77 if (!adapter)
78 return -1;
79
80 g_adapter = adapter;
81 adapter->card = card;
82
83 /* Save interface specific operations in adapter */
84 memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
85
86 /* card specific initialization has been deferred until now .. */
87 ret = adapter->if_ops.init_if(adapter);
88 if (ret)
89 goto error;
90
91 adapter->priv_num = 0;
92 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
93 adapter->priv[i] = NULL;
94
95 if (!mdevice->bss_attr[i].active)
96 continue;
97
98 /* For valid bss_attr,
99 allocate memory for private structure */
100 adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
101 GFP_KERNEL);
102 if (!adapter->priv[i]) {
103 dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
104 __func__, i);
105 goto error;
106 }
107
108 adapter->priv_num++;
109 memset(adapter->priv[i], 0,
110 sizeof(struct mwifiex_private));
111 adapter->priv[i]->adapter = adapter;
112 /* Save bss_type, frame_type & bss_priority */
113 adapter->priv[i]->bss_type = (u8) mdevice->bss_attr[i].bss_type;
114 adapter->priv[i]->frame_type =
115 (u8) mdevice->bss_attr[i].frame_type;
116 adapter->priv[i]->bss_priority =
117 (u8) mdevice->bss_attr[i].bss_priority;
118 if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
119 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
120 else if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_UAP)
121 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
122
123 /* Save bss_index & bss_num */
124 adapter->priv[i]->bss_index = i;
125 adapter->priv[i]->bss_num = mdevice->bss_attr[i].bss_num;
126 }
127
128 /* Initialize lock variables */
129 if (mwifiex_init_lock_list(adapter))
130 goto error;
131
132 init_timer(&adapter->cmd_timer);
133 adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
134 adapter->cmd_timer.data = (unsigned long) adapter;
135
136 /* Return pointer of struct mwifiex_adapter */
137 *padapter = adapter;
138 return 0;
139
140error:
141 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
142
143 /* Free lock variables */
144 mwifiex_free_lock_list(adapter);
145 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++)
146 kfree(adapter->priv[i]);
147 kfree(adapter);
148
149 return -1;
150}
151
152/*
153 * This function unregisters the device and performs all the necessary
154 * cleanups.
155 *
156 * The following cleanup operations are performed -
157 * - Free the timers
158 * - Free beacon buffers
159 * - Free private structures
160 * - Free adapter structure
161 */
162static int mwifiex_unregister(struct mwifiex_adapter *adapter)
163{
164 s32 i = 0;
165
166 del_timer(&adapter->cmd_timer);
167
168 /* Free private structures */
169 for (i = 0; i < adapter->priv_num; i++) {
170 if (adapter->priv[i]) {
171 mwifiex_free_curr_bcn(adapter->priv[i]);
172 kfree(adapter->priv[i]);
173 }
174 }
175
176 kfree(adapter);
177 return 0;
178}
179
180/*
181 * The main process.
182 *
183 * This function is the main procedure of the driver and handles various driver
184 * operations. It runs in a loop and provides the core functionalities.
185 *
186 * The main responsibilities of this function are -
187 * - Ensure concurrency control
188 * - Handle pending interrupts and call interrupt handlers
189 * - Wake up the card if required
190 * - Handle command responses and call response handlers
191 * - Handle events and call event handlers
192 * - Execute pending commands
193 * - Transmit pending data packets
194 */
195int mwifiex_main_process(struct mwifiex_adapter *adapter)
196{
197 int ret = 0;
198 unsigned long flags;
199
200 spin_lock_irqsave(&adapter->main_proc_lock, flags);
201
202 /* Check if already processing */
203 if (adapter->mwifiex_processing) {
204 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
205 goto exit_main_proc;
206 } else {
207 adapter->mwifiex_processing = true;
208 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
209 }
210process_start:
211 do {
212 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
213 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
214 break;
215
216 /* Handle pending interrupt if any */
217 if (adapter->int_status) {
218 if (adapter->hs_activated)
219 mwifiex_process_hs_config(adapter);
220 adapter->if_ops.process_int_status(adapter);
221 }
222
223 /* Need to wake up the card ? */
224 if ((adapter->ps_state == PS_STATE_SLEEP) &&
225 (adapter->pm_wakeup_card_req &&
226 !adapter->pm_wakeup_fw_try) &&
227 (is_command_pending(adapter)
228 || !mwifiex_wmm_lists_empty(adapter))) {
229 adapter->pm_wakeup_fw_try = true;
230 adapter->if_ops.wakeup(adapter);
231 continue;
232 }
233 if (IS_CARD_RX_RCVD(adapter)) {
234 adapter->pm_wakeup_fw_try = false;
235 if (adapter->ps_state == PS_STATE_SLEEP)
236 adapter->ps_state = PS_STATE_AWAKE;
237 } else {
238 /* We have tried to wakeup the card already */
239 if (adapter->pm_wakeup_fw_try)
240 break;
241 if (adapter->ps_state != PS_STATE_AWAKE ||
242 adapter->tx_lock_flag)
243 break;
244
245 if (adapter->scan_processing || adapter->data_sent
246 || mwifiex_wmm_lists_empty(adapter)) {
247 if (adapter->cmd_sent || adapter->curr_cmd
248 || (!is_command_pending(adapter)))
249 break;
250 }
251 }
252
253 /* Check for Cmd Resp */
254 if (adapter->cmd_resp_received) {
255 adapter->cmd_resp_received = false;
256 mwifiex_process_cmdresp(adapter);
257
258 /* call mwifiex back when init_fw is done */
259 if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
260 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
261 mwifiex_init_fw_complete(adapter);
262 }
263 }
264
265 /* Check for event */
266 if (adapter->event_received) {
267 adapter->event_received = false;
268 mwifiex_process_event(adapter);
269 }
270
271 /* Check if we need to confirm Sleep Request
272 received previously */
273 if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
274 if (!adapter->cmd_sent && !adapter->curr_cmd)
275 mwifiex_check_ps_cond(adapter);
276 }
277
278 /* * The ps_state may have been changed during processing of
279 * Sleep Request event.
280 */
281 if ((adapter->ps_state == PS_STATE_SLEEP)
282 || (adapter->ps_state == PS_STATE_PRE_SLEEP)
283 || (adapter->ps_state == PS_STATE_SLEEP_CFM)
284 || adapter->tx_lock_flag)
285 continue;
286
287 if (!adapter->cmd_sent && !adapter->curr_cmd) {
288 if (mwifiex_exec_next_cmd(adapter) == -1) {
289 ret = -1;
290 break;
291 }
292 }
293
294 if (!adapter->scan_processing && !adapter->data_sent &&
295 !mwifiex_wmm_lists_empty(adapter)) {
296 mwifiex_wmm_process_tx(adapter);
297 if (adapter->hs_activated) {
298 adapter->is_hs_configured = false;
299 mwifiex_hs_activated_event
300 (mwifiex_get_priv
301 (adapter, MWIFIEX_BSS_ROLE_ANY),
302 false);
303 }
304 }
305
306 if (adapter->delay_null_pkt && !adapter->cmd_sent &&
307 !adapter->curr_cmd && !is_command_pending(adapter)
308 && mwifiex_wmm_lists_empty(adapter)) {
309 if (!mwifiex_send_null_packet
310 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
311 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
312 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
313 adapter->delay_null_pkt = false;
314 adapter->ps_state = PS_STATE_SLEEP;
315 }
316 break;
317 }
318 } while (true);
319
320 if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
321 goto process_start;
322
323 spin_lock_irqsave(&adapter->main_proc_lock, flags);
324 adapter->mwifiex_processing = false;
325 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
326
327exit_main_proc:
328 if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
329 mwifiex_shutdown_drv(adapter);
330 return ret;
331}
332
333/*
334 * This function initializes the software.
335 *
336 * The main work includes allocating and initializing the adapter structure
337 * and initializing the private structures.
338 */
339static int
340mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex)
341{
342 int i;
343 struct mwifiex_device device;
344 struct mwifiex_drv_mode *drv_mode_ptr;
345
346 /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
347 drv_mode_ptr = NULL;
348 for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
349 if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
350 drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
351 break;
352 }
353 }
354
355 if (!drv_mode_ptr) {
356 pr_err("invalid drv_mode=%d\n", drv_mode);
357 return -1;
358 }
359
360 memset(&device, 0, sizeof(struct mwifiex_device));
361
362 for (i = 0; i < drv_mode_ptr->intf_num; i++) {
363 device.bss_attr[i].bss_type =
364 drv_mode_ptr->bss_attr[i].bss_type;
365 device.bss_attr[i].frame_type =
366 drv_mode_ptr->bss_attr[i].frame_type;
367 device.bss_attr[i].active = drv_mode_ptr->bss_attr[i].active;
368 device.bss_attr[i].bss_priority =
369 drv_mode_ptr->bss_attr[i].bss_priority;
370 device.bss_attr[i].bss_num = drv_mode_ptr->bss_attr[i].bss_num;
371 }
372
373 if (mwifiex_register(card, if_ops, &device, pmwifiex))
374 return -1;
375
376 return 0;
377}
378
379/*
380 * This function frees the adapter structure.
381 *
382 * Additionally, this closes the netlink socket, frees the timers
383 * and private structures.
384 */
385static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
386{
387 if (!adapter) {
388 pr_err("%s: adapter is NULL\n", __func__);
389 return;
390 }
391
392 mwifiex_unregister(adapter);
393 pr_debug("info: %s: free adapter\n", __func__);
394}
395
396/*
397 * This function initializes the hardware and firmware.
398 *
399 * The main initialization steps followed are -
400 * - Download the correct firmware to card
401 * - Allocate and initialize the adapter structure
402 * - Initialize the private structures
403 * - Issue the init commands to firmware
404 */
405static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
406{
407 int ret = 0;
408 int err;
409 struct mwifiex_fw_image fw;
410
411 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
412
413 switch (adapter->revision_id) {
414 case SD8787_W0:
415 case SD8787_W1:
416 strcpy(fw_name, SD8787_W1_FW_NAME);
417 break;
418 case SD8787_A0:
419 case SD8787_A1:
420 strcpy(fw_name, SD8787_AX_FW_NAME);
421 break;
422 default:
423 break;
424 }
425
426 err = request_firmware(&adapter->firmware, fw_name, adapter->dev);
427 if (err < 0) {
428 dev_err(adapter->dev, "request_firmware() returned"
429 " error code %#x\n", err);
430 ret = -1;
431 goto done;
432 }
433 fw.fw_buf = (u8 *) adapter->firmware->data;
434 fw.fw_len = adapter->firmware->size;
435
436 ret = mwifiex_dnld_fw(adapter, &fw);
437 if (ret == -1)
438 goto done;
439
440 dev_notice(adapter->dev, "WLAN FW is active\n");
441
442 adapter->init_wait_q_woken = false;
443 ret = mwifiex_init_fw(adapter);
444 if (ret == -1) {
445 goto done;
446 } else if (!ret) {
447 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
448 goto done;
449 }
450 /* Wait for mwifiex_init to complete */
451 wait_event_interruptible(adapter->init_wait_q,
452 adapter->init_wait_q_woken);
453 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) {
454 ret = -1;
455 goto done;
456 }
457 ret = 0;
458
459done:
460 if (adapter->firmware)
461 release_firmware(adapter->firmware);
462 if (ret)
463 ret = -1;
464 return ret;
465}
466
467/*
468 * This function fills a driver buffer.
469 *
470 * The function associates a given SKB with the provided driver buffer
471 * and also updates some of the SKB parameters, including IP header,
472 * priority and timestamp.
473 */
474static void
475mwifiex_fill_buffer(struct sk_buff *skb)
476{
477 struct ethhdr *eth = NULL;
478 struct iphdr *iph;
479 struct timeval tv;
480 u8 tid = 0;
481
482 eth = (struct ethhdr *) skb->data;
483 switch (eth->h_proto) {
484 case __constant_htons(ETH_P_IP):
485 iph = ip_hdr(skb);
486 tid = IPTOS_PREC(iph->tos);
487 pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
488 eth->h_proto, tid, skb->priority);
489 break;
490 case __constant_htons(ETH_P_ARP):
491 pr_debug("data: ARP packet: %04x\n", eth->h_proto);
492 default:
493 break;
494 }
495/* Offset for TOS field in the IP header */
496#define IPTOS_OFFSET 5
497 tid = (tid >> IPTOS_OFFSET);
498 skb->priority = tid;
499 /* Record the current time the packet was queued; used to
500 determine the amount of time the packet was queued in
501 the driver before it was sent to the firmware.
502 The delay is then sent along with the packet to the
503 firmware for aggregate delay calculation for stats and
504 MSDU lifetime expiry.
505 */
506 do_gettimeofday(&tv);
507 skb->tstamp = timeval_to_ktime(tv);
508 return;
509}
510
511/*
512 * CFG802.11 network device handler for open.
513 *
514 * Starts the data queue.
515 */
516static int
517mwifiex_open(struct net_device *dev)
518{
519 netif_start_queue(dev);
520 return 0;
521}
522
523/*
524 * CFG802.11 network device handler for close.
525 */
526static int
527mwifiex_close(struct net_device *dev)
528{
529 return 0;
530}
531
532/*
533 * CFG802.11 network device handler for data transmission.
534 */
535static int
536mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
537{
538 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
539 struct sk_buff *new_skb = NULL;
540 struct mwifiex_txinfo *tx_info;
541
542 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
543 jiffies, priv->bss_index);
544
545 if (priv->adapter->surprise_removed) {
546 kfree(skb);
547 priv->stats.tx_dropped++;
548 return 0;
549 }
550 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
551 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
552 kfree(skb);
553 priv->stats.tx_dropped++;
554 return 0;
555 }
556 if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
557 dev_dbg(priv->adapter->dev,
558 "data: Tx: insufficient skb headroom %d\n",
559 skb_headroom(skb));
560 /* Insufficient skb headroom - allocate a new skb */
561 new_skb =
562 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
563 if (unlikely(!new_skb)) {
564 dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
565 kfree(skb);
566 priv->stats.tx_dropped++;
567 return 0;
568 }
569 kfree_skb(skb);
570 skb = new_skb;
571 dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
572 skb_headroom(skb));
573 }
574
575 tx_info = MWIFIEX_SKB_TXCB(skb);
576 tx_info->bss_index = priv->bss_index;
577 mwifiex_fill_buffer(skb);
578
579 mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
580 atomic_inc(&priv->adapter->tx_pending);
581
582 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
583 netif_stop_queue(priv->netdev);
584 dev->trans_start = jiffies;
585 }
586
587 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
588
589 return 0;
590}
591
592/*
593 * CFG802.11 network device handler for setting MAC address.
594 */
595static int
596mwifiex_set_mac_address(struct net_device *dev, void *addr)
597{
598 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
599 struct sockaddr *hw_addr = (struct sockaddr *) addr;
600
601 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
602
603 if (mwifiex_request_set_mac_address(priv)) {
604 dev_err(priv->adapter->dev, "set MAC address failed\n");
605 return -EFAULT;
606 }
607 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
608
609 return 0;
610}
611
612/*
613 * CFG802.11 network device handler for setting multicast list.
614 */
615static void mwifiex_set_multicast_list(struct net_device *dev)
616{
617 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
618 mwifiex_request_set_multicast_list(priv, dev);
619}
620
621/*
622 * CFG802.11 network device handler for transmission timeout.
623 */
624static void
625mwifiex_tx_timeout(struct net_device *dev)
626{
627 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
628
629 dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
630 jiffies, priv->bss_index);
631 dev->trans_start = jiffies;
632 priv->num_tx_timeout++;
633}
634
635/*
636 * CFG802.11 network device handler for statistics retrieval.
637 */
638static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
639{
640 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
641
642 return &priv->stats;
643}
644
645/* Network device handlers */
646static const struct net_device_ops mwifiex_netdev_ops = {
647 .ndo_open = mwifiex_open,
648 .ndo_stop = mwifiex_close,
649 .ndo_start_xmit = mwifiex_hard_start_xmit,
650 .ndo_set_mac_address = mwifiex_set_mac_address,
651 .ndo_tx_timeout = mwifiex_tx_timeout,
652 .ndo_get_stats = mwifiex_get_stats,
653 .ndo_set_multicast_list = mwifiex_set_multicast_list,
654};
655
656/*
657 * This function initializes the private structure parameters.
658 *
659 * The following wait queues are initialized -
660 * - IOCTL wait queue
661 * - Command wait queue
662 * - Statistics wait queue
663 *
664 * ...and the following default parameters are set -
665 * - Current key index : Set to 0
666 * - Rate index : Set to auto
667 * - Media connected : Set to disconnected
668 * - Adhoc link sensed : Set to false
669 * - Nick name : Set to null
670 * - Number of Tx timeout : Set to 0
671 * - Device address : Set to current address
672 *
673 * In addition, the CFG80211 work queue is also created.
674 */
675static void
676mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
677{
678 dev->netdev_ops = &mwifiex_netdev_ops;
679 /* Initialize private structure */
680 init_waitqueue_head(&priv->ioctl_wait_q);
681 init_waitqueue_head(&priv->cmd_wait_q);
682 init_waitqueue_head(&priv->w_stats_wait_q);
683 priv->current_key_index = 0;
684 priv->media_connected = false;
685 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
686 priv->num_tx_timeout = 0;
687 priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
688 INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
689 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
690}
691
692/*
693 * This function adds a new logical interface.
694 *
695 * It allocates, initializes and registers the interface by performing
696 * the following opearations -
697 * - Allocate a new net device structure
698 * - Assign device name
699 * - Register the new device with CFG80211 subsystem
700 * - Initialize semaphore and private structure
701 * - Register the new device with kernel
702 * - Create the complete debug FS structure if configured
703 */
704static struct mwifiex_private *mwifiex_add_interface(
705 struct mwifiex_adapter *adapter,
706 u8 bss_index, u8 bss_type)
707{
708 struct net_device *dev = NULL;
709 struct mwifiex_private *priv = NULL;
710 void *mdev_priv = NULL;
711
712 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
713 ether_setup, 1);
714 if (!dev) {
715 dev_err(adapter->dev, "no memory available for netdevice\n");
716 goto error;
717 }
718 if (dev_alloc_name(dev, dev->name)) {
719 dev_err(adapter->dev, "unable to alloc name for netdevice\n");
720 goto error;
721 }
722
723 if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
724 adapter->priv[bss_index]) != 0) {
725 dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
726 goto error;
727 }
728 /* Save the priv pointer in netdev */
729 priv = adapter->priv[bss_index];
730 mdev_priv = netdev_priv(dev);
731 *((unsigned long *) mdev_priv) = (unsigned long) priv;
732
733 priv->netdev = dev;
734
735 sema_init(&priv->async_sem, 1);
736 priv->scan_pending_on_block = false;
737
738 mwifiex_init_priv_params(priv, dev);
739
740 SET_NETDEV_DEV(dev, adapter->dev);
741
742 /* Register network device */
743 if (register_netdev(dev)) {
744 dev_err(adapter->dev, "cannot register virtual network device\n");
745 goto error;
746 }
747
748 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
749#ifdef CONFIG_DEBUG_FS
750 mwifiex_dev_debugfs_init(priv);
751#endif
752 return priv;
753error:
754 if (dev)
755 free_netdev(dev);
756 return NULL;
757}
758
759/*
760 * This function removes a logical interface.
761 *
762 * It deregisters, resets and frees the interface by performing
763 * the following operations -
764 * - Disconnect the device if connected, send wireless event to
765 * notify applications.
766 * - Remove the debug FS structure if configured
767 * - Unregister the device from kernel
768 * - Free the net device structure
769 * - Cancel all works and destroy work queue
770 * - Unregister and free the wireless device from CFG80211 subsystem
771 */
772static void
773mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
774{
775 struct net_device *dev = NULL;
776 struct mwifiex_private *priv = adapter->priv[bss_index];
777
778 if (!priv)
779 return;
780 dev = priv->netdev;
781
782 if (priv->media_connected)
783 priv->media_connected = false;
784
785#ifdef CONFIG_DEBUG_FS
786 mwifiex_dev_debugfs_remove(priv);
787#endif
788 /* Last reference is our one */
789 dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
790 dev->name, netdev_refcnt_read(dev));
791
792 if (dev->reg_state == NETREG_REGISTERED)
793 unregister_netdev(dev);
794
795 /* Clear the priv in adapter */
796 priv->netdev = NULL;
797 if (dev)
798 free_netdev(dev);
799
800 cancel_work_sync(&priv->cfg_workqueue);
801 flush_workqueue(priv->workqueue);
802 destroy_workqueue(priv->workqueue);
803 wiphy_unregister(priv->wdev->wiphy);
804 wiphy_free(priv->wdev->wiphy);
805 kfree(priv->wdev);
806
807 return;
808}
809
810/*
811 * Sends IOCTL request to shutdown firmware.
812 *
813 * This function allocates the IOCTL request buffer, fills it
814 * with requisite parameters and calls the IOCTL handler.
815 */
816int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option)
817{
818 struct mwifiex_wait_queue *wait = NULL;
819 int status = 0;
820
821 /* Allocate an IOCTL request buffer */
822 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
823 if (!wait)
824 return -ENOMEM;
825
826 status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait,
827 MWIFIEX_FUNC_SHUTDOWN);
828
829 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
830
831 kfree(wait);
832 return status;
833}
834EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw);
835
836/*
837 * This function check if command is pending.
838 */
839int is_command_pending(struct mwifiex_adapter *adapter)
840{
841 unsigned long flags;
842 int is_cmd_pend_q_empty;
843
844 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
845 is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
846 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
847
848 return !is_cmd_pend_q_empty;
849}
850
851/*
852 * This function returns the correct private structure pointer based
853 * upon the BSS number.
854 */
855struct mwifiex_private *
856mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
857{
858 if (!adapter || (bss_index >= adapter->priv_num))
859 return NULL;
860 return adapter->priv[bss_index];
861}
862
863/*
864 * This is the main work queue function.
865 *
866 * It handles the main process, which in turn handles the complete
867 * driver operations.
868 */
869static void mwifiex_main_work_queue(struct work_struct *work)
870{
871 struct mwifiex_adapter *adapter =
872 container_of(work, struct mwifiex_adapter, main_work);
873
874 if (adapter->surprise_removed)
875 return;
876 mwifiex_main_process(adapter);
877}
878
879/*
880 * This function cancels all works in the queue and destroys
881 * the main workqueue.
882 */
883static void
884mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
885{
886 flush_workqueue(adapter->workqueue);
887 destroy_workqueue(adapter->workqueue);
888 adapter->workqueue = NULL;
889}
890
891/*
892 * This function adds the card.
893 *
894 * This function follows the following major steps to set up the device -
895 * - Initialize software. This includes probing the card, registering
896 * the interface operations table, and allocating/initializing the
897 * adapter structure
898 * - Set up the netlink socket
899 * - Create and start the main work queue
900 * - Register the device
901 * - Initialize firmware and hardware
902 * - Add logical interfaces
903 */
904int
905mwifiex_add_card(void *card, struct semaphore *sem,
906 struct mwifiex_if_ops *if_ops)
907{
908 int status = 0;
909 int i;
910 struct mwifiex_adapter *adapter = NULL;
911 struct mwifiex_drv_mode *drv_mode_info = &mwifiex_drv_mode_tbl[0];
912
913 if (down_interruptible(sem))
914 goto exit_sem_err;
915
916 if (mwifiex_init_sw(card, if_ops, (void **) &adapter)) {
917 pr_err("%s: software init failed\n", __func__);
918 goto err_init_sw;
919 }
920
921 adapter->drv_mode = drv_mode_info;
922
923 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
924 /* PnP and power profile */
925 adapter->surprise_removed = false;
926 init_waitqueue_head(&adapter->init_wait_q);
927 adapter->is_suspended = false;
928 adapter->hs_activated = false;
929 init_waitqueue_head(&adapter->hs_activate_wait_q);
930
931 /* Create workqueue */
932 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
933 if (!adapter->workqueue)
934 goto err_kmalloc;
935
936 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
937
938 /* Register the device. Fill up the private data structure with relevant
939 information from the card and request for the required IRQ. */
940 if (adapter->if_ops.register_dev(adapter)) {
941 pr_err("%s: failed to register mwifiex device\n", __func__);
942 goto err_registerdev;
943 }
944
945 /* Init FW and HW */
946 if (mwifiex_init_hw_fw(adapter)) {
947 pr_err("%s: firmware init failed\n", __func__);
948 goto err_init_fw;
949 }
950 /* Add interfaces */
951 for (i = 0; i < drv_mode_info->intf_num; i++) {
952 if (!mwifiex_add_interface(adapter, i,
953 adapter->drv_mode->bss_attr[i].bss_type)) {
954 status = -1;
955 break;
956 }
957 }
958 if (status)
959 goto err_add_intf;
960
961 up(sem);
962
963 return 0;
964
965err_add_intf:
966 for (i = 0; i < adapter->priv_num; i++)
967 mwifiex_remove_interface(adapter, i);
968err_init_fw:
969 /* Unregister device */
970 pr_debug("info: %s: unregister device\n", __func__);
971 adapter->if_ops.unregister_dev(adapter);
972err_registerdev:
973 adapter->surprise_removed = true;
974 mwifiex_terminate_workqueue(adapter);
975err_kmalloc:
976 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
977 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
978 pr_debug("info: %s: shutdown mwifiex\n", __func__);
979 adapter->init_wait_q_woken = false;
980 status = mwifiex_shutdown_drv(adapter);
981 if (status == -EINPROGRESS)
982 wait_event_interruptible(adapter->init_wait_q,
983 adapter->init_wait_q_woken);
984 }
985
986 mwifiex_free_adapter(adapter);
987
988err_init_sw:
989 up(sem);
990
991exit_sem_err:
992 return -1;
993}
994EXPORT_SYMBOL_GPL(mwifiex_add_card);
995
996/*
997 * This function removes the card.
998 *
999 * This function follows the following major steps to remove the device -
1000 * - Stop data traffic
1001 * - Shutdown firmware
1002 * - Remove the logical interfaces
1003 * - Terminate the work queue
1004 * - Unregister the device
1005 * - Free the adapter structure
1006 */
1007int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
1008{
1009 struct mwifiex_private *priv = NULL;
1010 int status;
1011 int i;
1012
1013 if (down_interruptible(sem))
1014 goto exit_sem_err;
1015
1016 if (!adapter)
1017 goto exit_remove;
1018
1019 adapter->surprise_removed = true;
1020
1021 /* Stop data */
1022 for (i = 0; i < adapter->priv_num; i++) {
1023 priv = adapter->priv[i];
1024 if (priv) {
1025 if (!netif_queue_stopped(priv->netdev))
1026 netif_stop_queue(priv->netdev);
1027 if (netif_carrier_ok(priv->netdev))
1028 netif_carrier_off(priv->netdev);
1029 }
1030 }
1031
1032 dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
1033 adapter->init_wait_q_woken = false;
1034 status = mwifiex_shutdown_drv(adapter);
1035 if (status == -EINPROGRESS)
1036 wait_event_interruptible(adapter->init_wait_q,
1037 adapter->init_wait_q_woken);
1038 dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
1039 if (atomic_read(&adapter->rx_pending) ||
1040 atomic_read(&adapter->tx_pending) ||
1041 atomic_read(&adapter->ioctl_pending)) {
1042 dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
1043 "ioctl_pending=%d\n",
1044 atomic_read(&adapter->rx_pending),
1045 atomic_read(&adapter->tx_pending),
1046 atomic_read(&adapter->ioctl_pending));
1047 }
1048
1049 /* Remove interface */
1050 for (i = 0; i < adapter->priv_num; i++)
1051 mwifiex_remove_interface(adapter, i);
1052
1053 mwifiex_terminate_workqueue(adapter);
1054
1055 /* Unregister device */
1056 dev_dbg(adapter->dev, "info: unregister device\n");
1057 adapter->if_ops.unregister_dev(adapter);
1058 /* Free adapter structure */
1059 dev_dbg(adapter->dev, "info: free adapter\n");
1060 mwifiex_free_adapter(adapter);
1061
1062exit_remove:
1063 up(sem);
1064exit_sem_err:
1065 return 0;
1066}
1067EXPORT_SYMBOL_GPL(mwifiex_remove_card);
1068
1069/*
1070 * This function initializes the module.
1071 *
1072 * The debug FS is also initialized if configured.
1073 */
1074static int
1075mwifiex_init_module(void)
1076{
1077#ifdef CONFIG_DEBUG_FS
1078 mwifiex_debugfs_init();
1079#endif
1080 return 0;
1081}
1082
1083/*
1084 * This function cleans up the module.
1085 *
1086 * The debug FS is removed if available.
1087 */
1088static void
1089mwifiex_cleanup_module(void)
1090{
1091#ifdef CONFIG_DEBUG_FS
1092 mwifiex_debugfs_remove();
1093#endif
1094}
1095
1096module_init(mwifiex_init_module);
1097module_exit(mwifiex_cleanup_module);
1098
1099MODULE_AUTHOR("Marvell International Ltd.");
1100MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
1101MODULE_VERSION(VERSION);
1102MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
new file mode 100644
index 000000000000..43ff149de9db
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -0,0 +1,1058 @@
1/*
2 * Marvell Wireless LAN device driver: major data structures and prototypes
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_MAIN_H_
21#define _MWIFIEX_MAIN_H_
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/sched.h>
26#include <linux/semaphore.h>
27#include <linux/ip.h>
28#include <linux/skbuff.h>
29#include <linux/if_arp.h>
30#include <linux/etherdevice.h>
31#include <net/sock.h>
32#include <net/lib80211.h>
33#include <linux/firmware.h>
34#include <linux/ctype.h>
35
36#include "decl.h"
37#include "ioctl.h"
38#include "util.h"
39#include "fw.h"
40
41extern const char driver_version[];
42extern struct mwifiex_adapter *g_adapter;
43
44enum {
45 MWIFIEX_NO_WAIT,
46 MWIFIEX_IOCTL_WAIT,
47 MWIFIEX_CMD_WAIT,
48 MWIFIEX_PROC_WAIT,
49 MWIFIEX_WSTATS_WAIT
50};
51
52#define DRV_MODE_STA 0x1
53
54#define SD8787_W0 0x30
55#define SD8787_W1 0x31
56#define SD8787_A0 0x40
57#define SD8787_A1 0x41
58
59#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
60#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin"
61#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin"
62
63struct mwifiex_drv_mode {
64 u16 drv_mode;
65 u16 intf_num;
66 struct mwifiex_bss_attr *bss_attr;
67};
68
69
70#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
71
72#define MWIFIEX_TIMER_10S 10000
73#define MWIFIEX_TIMER_1S 1000
74
75#define MAX_TX_PENDING 60
76
77#define MWIFIEX_UPLD_SIZE (2312)
78
79#define MAX_EVENT_SIZE 1024
80
81#define ARP_FILTER_MAX_BUF_SIZE 68
82
83#define MWIFIEX_KEY_BUFFER_SIZE 16
84#define MWIFIEX_DEFAULT_LISTEN_INTERVAL 10
85#define MWIFIEX_MAX_REGION_CODE 7
86
87#define DEFAULT_BCN_AVG_FACTOR 8
88#define DEFAULT_DATA_AVG_FACTOR 8
89
90#define FIRST_VALID_CHANNEL 0xff
91#define DEFAULT_AD_HOC_CHANNEL 6
92#define DEFAULT_AD_HOC_CHANNEL_A 36
93
94#define DEFAULT_BCN_MISS_TIMEOUT 5
95
96#define MAX_SCAN_BEACON_BUFFER 8000
97
98#define SCAN_BEACON_ENTRY_PAD 6
99
100#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 200
101#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 200
102#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 110
103
104#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))
105
106#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
107
108#define RSN_GTK_OUI_OFFSET 2
109
110#define MWIFIEX_OUI_NOT_PRESENT 0
111#define MWIFIEX_OUI_PRESENT 1
112
113#define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \
114 adapter->event_received || \
115 adapter->data_received)
116
117#define MWIFIEX_TYPE_CMD 1
118#define MWIFIEX_TYPE_DATA 0
119#define MWIFIEX_TYPE_EVENT 3
120
121#define DBG_CMD_NUM 5
122
123#define MAX_BITMAP_RATES_SIZE 10
124
125#define MAX_CHANNEL_BAND_BG 14
126
127#define MAX_FREQUENCY_BAND_BG 2484
128
129struct mwifiex_dbg {
130 u32 num_cmd_host_to_card_failure;
131 u32 num_cmd_sleep_cfm_host_to_card_failure;
132 u32 num_tx_host_to_card_failure;
133 u32 num_event_deauth;
134 u32 num_event_disassoc;
135 u32 num_event_link_lost;
136 u32 num_cmd_deauth;
137 u32 num_cmd_assoc_success;
138 u32 num_cmd_assoc_failure;
139 u32 num_tx_timeout;
140 u32 num_cmd_timeout;
141 u16 timeout_cmd_id;
142 u16 timeout_cmd_act;
143 u16 last_cmd_id[DBG_CMD_NUM];
144 u16 last_cmd_act[DBG_CMD_NUM];
145 u16 last_cmd_index;
146 u16 last_cmd_resp_id[DBG_CMD_NUM];
147 u16 last_cmd_resp_index;
148 u16 last_event[DBG_CMD_NUM];
149 u16 last_event_index;
150};
151
152enum MWIFIEX_HARDWARE_STATUS {
153 MWIFIEX_HW_STATUS_READY,
154 MWIFIEX_HW_STATUS_INITIALIZING,
155 MWIFIEX_HW_STATUS_FW_READY,
156 MWIFIEX_HW_STATUS_INIT_DONE,
157 MWIFIEX_HW_STATUS_RESET,
158 MWIFIEX_HW_STATUS_CLOSING,
159 MWIFIEX_HW_STATUS_NOT_READY
160};
161
162enum MWIFIEX_802_11_POWER_MODE {
163 MWIFIEX_802_11_POWER_MODE_CAM,
164 MWIFIEX_802_11_POWER_MODE_PSP
165};
166
167struct mwifiex_tx_param {
168 u32 next_pkt_len;
169};
170
171enum MWIFIEX_PS_STATE {
172 PS_STATE_AWAKE,
173 PS_STATE_PRE_SLEEP,
174 PS_STATE_SLEEP_CFM,
175 PS_STATE_SLEEP
176};
177
178struct mwifiex_add_ba_param {
179 u32 tx_win_size;
180 u32 rx_win_size;
181 u32 timeout;
182};
183
184struct mwifiex_tx_aggr {
185 u8 ampdu_user;
186 u8 ampdu_ap;
187 u8 amsdu;
188};
189
190struct mwifiex_ra_list_tbl {
191 struct list_head list;
192 struct sk_buff_head skb_head;
193 u8 ra[ETH_ALEN];
194 u32 total_pkts_size;
195 u32 is_11n_enabled;
196};
197
198struct mwifiex_tid_tbl {
199 struct list_head ra_list;
200 /* spin lock for tid table */
201 spinlock_t tid_tbl_lock;
202 struct mwifiex_ra_list_tbl *ra_list_curr;
203};
204
205#define WMM_HIGHEST_PRIORITY 7
206#define HIGH_PRIO_TID 7
207#define LOW_PRIO_TID 0
208
209struct mwifiex_wmm_desc {
210 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID];
211 u32 packets_out[MAX_NUM_TID];
212 /* spin lock to protect ra_list */
213 spinlock_t ra_list_spinlock;
214 struct mwifiex_wmm_ac_status ac_status[IEEE80211_MAX_QUEUES];
215 enum mwifiex_wmm_ac_e ac_down_graded_vals[IEEE80211_MAX_QUEUES];
216 u32 drv_pkt_delay_max;
217 u8 queue_priority[IEEE80211_MAX_QUEUES];
218 u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */
219
220};
221
222struct mwifiex_802_11_security {
223 u8 wpa_enabled;
224 u8 wpa2_enabled;
225 u8 wapi_enabled;
226 u8 wapi_key_on;
227 enum MWIFIEX_802_11_WEP_STATUS wep_status;
228 u32 authentication_mode;
229 u32 encryption_mode;
230};
231
232struct ieee_types_header {
233 u8 element_id;
234 u8 len;
235} __packed;
236
237struct ieee_obss_scan_param {
238 u16 obss_scan_passive_dwell;
239 u16 obss_scan_active_dwell;
240 u16 bss_chan_width_trigger_scan_int;
241 u16 obss_scan_passive_total;
242 u16 obss_scan_active_total;
243 u16 bss_width_chan_trans_delay;
244 u16 obss_scan_active_threshold;
245} __packed;
246
247struct ieee_types_obss_scan_param {
248 struct ieee_types_header ieee_hdr;
249 struct ieee_obss_scan_param obss_scan;
250} __packed;
251
252#define MWIFIEX_SUPPORTED_RATES 14
253
254#define MWIFIEX_SUPPORTED_RATES_EXT 32
255
256#define IEEE_MAX_IE_SIZE 256
257
258struct ieee_types_vendor_specific {
259 struct ieee_types_vendor_header vend_hdr;
260 u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
261} __packed;
262
263struct ieee_types_generic {
264 struct ieee_types_header ieee_hdr;
265 u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)];
266} __packed;
267
268struct mwifiex_bssdescriptor {
269 u8 mac_address[ETH_ALEN];
270 struct mwifiex_802_11_ssid ssid;
271 u32 privacy;
272 s32 rssi;
273 u32 channel;
274 u32 freq;
275 u16 beacon_period;
276 u8 erp_flags;
277 u32 bss_mode;
278 u8 supported_rates[MWIFIEX_SUPPORTED_RATES];
279 u8 data_rates[MWIFIEX_SUPPORTED_RATES];
280 /* Network band.
281 * BAND_B(0x01): 'b' band
282 * BAND_G(0x02): 'g' band
283 * BAND_A(0X04): 'a' band
284 */
285 u16 bss_band;
286 long long network_tsf;
287 u8 time_stamp[8];
288 union ieee_types_phy_param_set phy_param_set;
289 union ieee_types_ss_param_set ss_param_set;
290 u16 cap_info_bitmap;
291 struct ieee_types_wmm_parameter wmm_ie;
292 u8 disable_11n;
293 struct ieee80211_ht_cap *bcn_ht_cap;
294 u16 ht_cap_offset;
295 struct ieee80211_ht_info *bcn_ht_info;
296 u16 ht_info_offset;
297 u8 *bcn_bss_co_2040;
298 u16 bss_co_2040_offset;
299 u8 *bcn_ext_cap;
300 u16 ext_cap_offset;
301 struct ieee_types_obss_scan_param *bcn_obss_scan;
302 u16 overlap_bss_offset;
303 struct ieee_types_vendor_specific *bcn_wpa_ie;
304 u16 wpa_offset;
305 struct ieee_types_generic *bcn_rsn_ie;
306 u16 rsn_offset;
307 struct ieee_types_generic *bcn_wapi_ie;
308 u16 wapi_offset;
309 u8 *beacon_buf;
310 u32 beacon_buf_size;
311 u32 beacon_buf_size_max;
312
313};
314
315struct mwifiex_current_bss_params {
316 struct mwifiex_bssdescriptor bss_descriptor;
317 u8 wmm_enabled;
318 u8 wmm_uapsd_enabled;
319 u8 band;
320 u32 num_of_rates;
321 u8 data_rates[MWIFIEX_SUPPORTED_RATES];
322};
323
324struct mwifiex_sleep_params {
325 u16 sp_error;
326 u16 sp_offset;
327 u16 sp_stable_time;
328 u8 sp_cal_control;
329 u8 sp_ext_sleep_clk;
330 u16 sp_reserved;
331};
332
333struct mwifiex_sleep_period {
334 u16 period;
335 u16 reserved;
336};
337
338struct mwifiex_wep_key {
339 u32 length;
340 u32 key_index;
341 u32 key_length;
342 u8 key_material[MWIFIEX_KEY_BUFFER_SIZE];
343};
344
345#define MAX_REGION_CHANNEL_NUM 2
346
347struct mwifiex_chan_freq_power {
348 u16 channel;
349 u32 freq;
350 u16 max_tx_power;
351 u8 unsupported;
352};
353
354enum state_11d_t {
355 DISABLE_11D = 0,
356 ENABLE_11D = 1,
357};
358
359#define MWIFIEX_MAX_TRIPLET_802_11D 83
360
361struct mwifiex_802_11d_domain_reg {
362 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
363 u8 no_of_triplet;
364 struct ieee80211_country_ie_triplet
365 triplet[MWIFIEX_MAX_TRIPLET_802_11D];
366};
367
368struct mwifiex_vendor_spec_cfg_ie {
369 u16 mask;
370 u16 flag;
371 u8 ie[MWIFIEX_MAX_VSIE_LEN];
372};
373
374struct wps {
375 u8 session_enable;
376};
377
378struct mwifiex_adapter;
379struct mwifiex_private;
380
381struct mwifiex_private {
382 struct mwifiex_adapter *adapter;
383 u8 bss_index;
384 u8 bss_type;
385 u8 bss_role;
386 u8 bss_priority;
387 u8 bss_num;
388 u8 frame_type;
389 u8 curr_addr[ETH_ALEN];
390 u8 media_connected;
391 u32 num_tx_timeout;
392 struct net_device *netdev;
393 struct net_device_stats stats;
394 u16 curr_pkt_filter;
395 u32 bss_mode;
396 u32 pkt_tx_ctrl;
397 u16 tx_power_level;
398 u8 max_tx_power_level;
399 u8 min_tx_power_level;
400 u8 tx_rate;
401 u8 tx_htinfo;
402 u8 rxpd_htinfo;
403 u8 rxpd_rate;
404 u16 rate_bitmap;
405 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
406 u32 data_rate;
407 u8 is_data_rate_auto;
408 u16 bcn_avg_factor;
409 u16 data_avg_factor;
410 s16 data_rssi_last;
411 s16 data_nf_last;
412 s16 data_rssi_avg;
413 s16 data_nf_avg;
414 s16 bcn_rssi_last;
415 s16 bcn_nf_last;
416 s16 bcn_rssi_avg;
417 s16 bcn_nf_avg;
418 struct mwifiex_bssdescriptor *attempted_bss_desc;
419 struct mwifiex_802_11_ssid prev_ssid;
420 u8 prev_bssid[ETH_ALEN];
421 struct mwifiex_current_bss_params curr_bss_params;
422 u16 beacon_period;
423 u16 listen_interval;
424 u16 atim_window;
425 u8 adhoc_channel;
426 u8 adhoc_is_link_sensed;
427 u8 adhoc_state;
428 struct mwifiex_802_11_security sec_info;
429 struct mwifiex_wep_key wep_key[NUM_WEP_KEYS];
430 u16 wep_key_curr_index;
431 u8 wpa_ie[256];
432 u8 wpa_ie_len;
433 u8 wpa_is_gtk_set;
434 struct host_cmd_ds_802_11_key_material aes_key;
435 u8 wapi_ie[256];
436 u8 wapi_ie_len;
437 u8 wmm_required;
438 u8 wmm_enabled;
439 u8 wmm_qosinfo;
440 struct mwifiex_wmm_desc wmm;
441 struct list_head tx_ba_stream_tbl_ptr;
442 /* spin lock for tx_ba_stream_tbl_ptr queue */
443 spinlock_t tx_ba_stream_tbl_lock;
444 struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID];
445 struct mwifiex_add_ba_param add_ba_param;
446 u16 rx_seq[MAX_NUM_TID];
447 struct list_head rx_reorder_tbl_ptr;
448 /* spin lock for rx_reorder_tbl_ptr queue */
449 spinlock_t rx_reorder_tbl_lock;
450 /* spin lock for Rx packets */
451 spinlock_t rx_pkt_lock;
452
453#define MWIFIEX_ASSOC_RSP_BUF_SIZE 500
454 u8 assoc_rsp_buf[MWIFIEX_ASSOC_RSP_BUF_SIZE];
455 u32 assoc_rsp_size;
456
457#define MWIFIEX_GENIE_BUF_SIZE 256
458 u8 gen_ie_buf[MWIFIEX_GENIE_BUF_SIZE];
459 u8 gen_ie_buf_len;
460
461 struct mwifiex_vendor_spec_cfg_ie vs_ie[MWIFIEX_MAX_VSIE_NUM];
462
463#define MWIFIEX_ASSOC_TLV_BUF_SIZE 256
464 u8 assoc_tlv_buf[MWIFIEX_ASSOC_TLV_BUF_SIZE];
465 u8 assoc_tlv_buf_len;
466
467 u8 *curr_bcn_buf;
468 u32 curr_bcn_size;
469 /* spin lock for beacon buffer */
470 spinlock_t curr_bcn_buf_lock;
471 u16 ioctl_wait_q_woken;
472 wait_queue_head_t ioctl_wait_q;
473 u16 cmd_wait_q_woken;
474 wait_queue_head_t cmd_wait_q;
475 struct wireless_dev *wdev;
476 struct mwifiex_chan_freq_power cfp;
477 char version_str[128];
478#ifdef CONFIG_DEBUG_FS
479 struct dentry *dfs_dev_dir;
480#endif
481 u8 nick_name[16];
482 struct iw_statistics w_stats;
483 u16 w_stats_wait_q_woken;
484 wait_queue_head_t w_stats_wait_q;
485 u16 current_key_index;
486 struct semaphore async_sem;
487 u8 scan_pending_on_block;
488 u8 report_scan_result;
489 struct cfg80211_scan_request *scan_request;
490 int scan_result_status;
491 bool assoc_request;
492 u16 assoc_result;
493 bool ibss_join_request;
494 u16 ibss_join_result;
495 bool disconnect;
496 u8 cfg_bssid[6];
497 struct workqueue_struct *workqueue;
498 struct work_struct cfg_workqueue;
499 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
500 struct wps wps;
501 u8 scan_block;
502};
503
504enum mwifiex_ba_status {
505 BA_STREAM_NOT_SETUP = 0,
506 BA_STREAM_SETUP_INPROGRESS,
507 BA_STREAM_SETUP_COMPLETE
508};
509
510struct mwifiex_tx_ba_stream_tbl {
511 struct list_head list;
512 int tid;
513 u8 ra[ETH_ALEN];
514 enum mwifiex_ba_status ba_status;
515};
516
517struct mwifiex_rx_reorder_tbl;
518
519struct reorder_tmr_cnxt {
520 struct timer_list timer;
521 struct mwifiex_rx_reorder_tbl *ptr;
522 struct mwifiex_private *priv;
523};
524
525struct mwifiex_rx_reorder_tbl {
526 struct list_head list;
527 int tid;
528 u8 ta[ETH_ALEN];
529 int start_win;
530 int win_size;
531 void **rx_reorder_ptr;
532 struct reorder_tmr_cnxt timer_context;
533};
534
535struct mwifiex_bss_prio_node {
536 struct list_head list;
537 struct mwifiex_private *priv;
538};
539
540struct mwifiex_bss_prio_tbl {
541 struct list_head bss_prio_head;
542 /* spin lock for bss priority */
543 spinlock_t bss_prio_lock;
544 struct mwifiex_bss_prio_node *bss_prio_cur;
545};
546
547struct cmd_ctrl_node {
548 struct list_head list;
549 struct mwifiex_private *priv;
550 u32 cmd_oid;
551 u32 cmd_flag;
552 struct sk_buff *cmd_skb;
553 struct sk_buff *resp_skb;
554 void *data_buf;
555 void *wq_buf;
556 struct sk_buff *skb;
557};
558
559struct mwifiex_if_ops {
560 int (*init_if) (struct mwifiex_adapter *);
561 void (*cleanup_if) (struct mwifiex_adapter *);
562 int (*check_fw_status) (struct mwifiex_adapter *, u32, int *);
563 int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
564 int (*register_dev) (struct mwifiex_adapter *);
565 void (*unregister_dev) (struct mwifiex_adapter *);
566 int (*enable_int) (struct mwifiex_adapter *);
567 int (*process_int_status) (struct mwifiex_adapter *);
568 int (*host_to_card) (struct mwifiex_adapter *, u8,
569 u8 *payload, u32 pkt_len,
570 struct mwifiex_tx_param *);
571 int (*wakeup) (struct mwifiex_adapter *);
572 int (*wakeup_complete) (struct mwifiex_adapter *);
573
574 void (*update_mp_end_port) (struct mwifiex_adapter *, u16);
575 void (*cleanup_mpa_buf) (struct mwifiex_adapter *);
576};
577
578struct mwifiex_adapter {
579 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
580 u8 priv_num;
581 struct mwifiex_drv_mode *drv_mode;
582 const struct firmware *firmware;
583 struct device *dev;
584 bool surprise_removed;
585 u32 fw_release_number;
586 u32 revision_id;
587 u16 init_wait_q_woken;
588 wait_queue_head_t init_wait_q;
589 void *card;
590 struct mwifiex_if_ops if_ops;
591 atomic_t rx_pending;
592 atomic_t tx_pending;
593 atomic_t ioctl_pending;
594 struct workqueue_struct *workqueue;
595 struct work_struct main_work;
596 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
597 /* spin lock for init/shutdown */
598 spinlock_t mwifiex_lock;
599 /* spin lock for main process */
600 spinlock_t main_proc_lock;
601 u32 mwifiex_processing;
602 u16 max_tx_buf_size;
603 u16 tx_buf_size;
604 u16 curr_tx_buf_size;
605 u32 ioport;
606 enum MWIFIEX_HARDWARE_STATUS hw_status;
607 u16 number_of_antenna;
608 u32 fw_cap_info;
609 /* spin lock for interrupt handling */
610 spinlock_t int_lock;
611 u8 int_status;
612 u32 event_cause;
613 struct sk_buff *event_skb;
614 u8 upld_buf[MWIFIEX_UPLD_SIZE];
615 u8 data_sent;
616 u8 cmd_sent;
617 u8 cmd_resp_received;
618 u8 event_received;
619 u8 data_received;
620 u16 seq_num;
621 struct cmd_ctrl_node *cmd_pool;
622 struct cmd_ctrl_node *curr_cmd;
623 /* spin lock for command */
624 spinlock_t mwifiex_cmd_lock;
625 u32 num_cmd_timeout;
626 u16 last_init_cmd;
627 struct timer_list cmd_timer;
628 struct list_head cmd_free_q;
629 /* spin lock for cmd_free_q */
630 spinlock_t cmd_free_q_lock;
631 struct list_head cmd_pending_q;
632 /* spin lock for cmd_pending_q */
633 spinlock_t cmd_pending_q_lock;
634 struct list_head scan_pending_q;
635 /* spin lock for scan_pending_q */
636 spinlock_t scan_pending_q_lock;
637 u32 scan_processing;
638 u16 region_code;
639 struct mwifiex_802_11d_domain_reg domain_reg;
640 struct mwifiex_bssdescriptor *scan_table;
641 u32 num_in_scan_table;
642 u16 scan_probes;
643 u32 scan_mode;
644 u16 specific_scan_time;
645 u16 active_scan_time;
646 u16 passive_scan_time;
647 u8 bcn_buf[MAX_SCAN_BEACON_BUFFER];
648 u8 *bcn_buf_end;
649 u8 fw_bands;
650 u8 adhoc_start_band;
651 u8 config_bands;
652 struct mwifiex_chan_scan_param_set *scan_channels;
653 u8 tx_lock_flag;
654 struct mwifiex_sleep_params sleep_params;
655 struct mwifiex_sleep_period sleep_period;
656 u16 ps_mode;
657 u32 ps_state;
658 u8 need_to_wakeup;
659 u16 multiple_dtim;
660 u16 local_listen_interval;
661 u16 null_pkt_interval;
662 struct sk_buff *sleep_cfm;
663 u16 bcn_miss_time_out;
664 u16 adhoc_awake_period;
665 u8 is_deep_sleep;
666 u8 delay_null_pkt;
667 u16 delay_to_ps;
668 u16 enhanced_ps_mode;
669 u8 pm_wakeup_card_req;
670 u16 gen_null_pkt;
671 u16 pps_uapsd_mode;
672 u32 pm_wakeup_fw_try;
673 u8 is_hs_configured;
674 struct mwifiex_hs_config_param hs_cfg;
675 u8 hs_activated;
676 u16 hs_activate_wait_q_woken;
677 wait_queue_head_t hs_activate_wait_q;
678 bool is_suspended;
679 u8 event_body[MAX_EVENT_SIZE];
680 u32 hw_dot_11n_dev_cap;
681 u8 hw_dev_mcs_support;
682 u8 adhoc_11n_enabled;
683 u8 chan_offset;
684 struct mwifiex_dbg dbg;
685 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
686 u32 arp_filter_size;
687};
688
689int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
690void mwifiex_free_lock_list(struct mwifiex_adapter *adapter);
691
692int mwifiex_init_fw(struct mwifiex_adapter *adapter);
693
694int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
695
696int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter);
697
698int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter);
699
700int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
701
702int mwifiex_recv_complete(struct mwifiex_adapter *,
703 struct sk_buff *skb,
704 int status);
705
706int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
707
708int mwifiex_process_event(struct mwifiex_adapter *adapter);
709
710int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter,
711 struct mwifiex_wait_queue *ioctl_wq,
712 int status);
713
714int mwifiex_prepare_cmd(struct mwifiex_private *priv,
715 uint16_t cmd_no,
716 u16 cmd_action,
717 u32 cmd_oid,
718 void *wait_queue, void *data_buf);
719
720void mwifiex_cmd_timeout_func(unsigned long function_context);
721
722int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter,
723 struct mwifiex_wait_queue *wait_queue,
724 u32 func_init_shutdown);
725int mwifiex_get_debug_info(struct mwifiex_private *,
726 struct mwifiex_debug_info *);
727
728int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter);
729int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter);
730void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter);
731void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
732 struct mwifiex_wait_queue *ioctl_wq);
733
734void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
735 struct cmd_ctrl_node *cmd_node);
736
737void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
738 struct cmd_ctrl_node *cmd_node,
739 u32 addtail);
740
741int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter);
742int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter);
743int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
744 struct sk_buff *skb);
745int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
746 struct mwifiex_tx_param *tx_param);
747int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags);
748int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
749 struct sk_buff *skb, int status);
750int mwifiex_recv_packet_complete(struct mwifiex_adapter *,
751 struct sk_buff *skb, int status);
752void mwifiex_clean_txrx(struct mwifiex_private *priv);
753u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv);
754void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter);
755void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *,
756 u32);
757int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
758 struct host_cmd_ds_command *cmd,
759 u16 cmd_action, uint16_t ps_bitmap,
760 void *data_buf);
761int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
762 struct host_cmd_ds_command *resp,
763 void *data_buf);
764void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
765void mwifiex_hs_activated_event(struct mwifiex_private *priv,
766 u8 activated);
767int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
768 struct host_cmd_ds_command *resp);
769int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
770 struct sk_buff *skb);
771int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
772 u16 cmd_action, u32 cmd_oid,
773 void *data_buf, void *cmd_buf);
774int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
775 void *cmd_buf, void *ioctl);
776int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
777 struct sk_buff *skb);
778int mwifiex_process_sta_event(struct mwifiex_private *);
779void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
780int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
781int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue,
782 u16 action,
783 const struct mwifiex_user_scan_cfg
784 *user_scan_in, struct mwifiex_scan_resp *);
785int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv,
786 struct host_cmd_ds_command *cmd,
787 void *data_buf);
788void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
789 struct cmd_ctrl_node *cmd_node);
790int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
791 struct host_cmd_ds_command *resp,
792 void *wait_queue);
793s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
794 struct mwifiex_802_11_ssid *ssid, u8 *bssid,
795 u32 mode);
796s32 mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
797 u32 mode);
798int mwifiex_find_best_network(struct mwifiex_private *priv,
799 struct mwifiex_ssid_bssid *req_ssid_bssid);
800s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
801 struct mwifiex_802_11_ssid *ssid2);
802int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue,
803 struct mwifiex_bssdescriptor *bss_desc);
804int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
805 struct host_cmd_ds_command
806 *cmd, void *data_buf);
807int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
808 struct host_cmd_ds_command *resp,
809 void *wait_queue);
810void mwifiex_reset_connect_state(struct mwifiex_private *priv);
811void mwifiex_2040_coex_event(struct mwifiex_private *priv);
812u8 mwifiex_band_to_radio_type(u8 band);
813int mwifiex_deauthenticate(struct mwifiex_private *priv,
814 struct mwifiex_wait_queue *wait_queue,
815 u8 *mac);
816int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue,
817 struct mwifiex_802_11_ssid *adhoc_ssid);
818int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue,
819 struct mwifiex_bssdescriptor *bss_desc);
820int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
821 struct host_cmd_ds_command *cmd,
822 void *data_buf);
823int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
824 struct host_cmd_ds_command *cmd,
825 void *data_buf);
826int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
827 struct host_cmd_ds_command *resp,
828 void *wait_queue);
829int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv,
830 struct host_cmd_ds_command *cmd,
831 void *data_buf);
832struct mwifiex_chan_freq_power *
833 mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
834 struct mwifiex_private *priv,
835 u8 band, u16 channel);
836struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
837 struct mwifiex_private *priv,
838 u8 band, u32 freq);
839u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index,
840 u8 ht_info);
841u32 mwifiex_find_freq_from_band_chan(u8, u8);
842int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
843 u8 **buffer);
844u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index,
845 u8 ht_info);
846u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv,
847 u8 *rates);
848u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates);
849u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate);
850u8 mwifiex_is_rate_auto(struct mwifiex_private *priv);
851int mwifiex_get_rate_index(struct mwifiex_adapter *adapter,
852 u16 *rateBitmap, int size);
853extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE];
854void mwifiex_save_curr_bcn(struct mwifiex_private *priv);
855void mwifiex_free_curr_bcn(struct mwifiex_private *priv);
856int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
857 struct host_cmd_ds_command *cmd);
858int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
859 struct host_cmd_ds_command *resp);
860int is_command_pending(struct mwifiex_adapter *adapter);
861
862/*
863 * This function checks if the queuing is RA based or not.
864 */
865static inline u8
866mwifiex_queuing_ra_based(struct mwifiex_private *priv)
867{
868 /*
869 * Currently we assume if we are in Infra, then DA=RA. This might not be
870 * true in the future
871 */
872 if ((priv->bss_mode == NL80211_IFTYPE_STATION) &&
873 (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA))
874 return false;
875
876 return true;
877}
878
879/*
880 * This function copies rates.
881 */
882static inline u32
883mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len)
884{
885 int i;
886
887 for (i = 0; i < len && src[i]; i++, pos++) {
888 if (pos >= MWIFIEX_SUPPORTED_RATES)
889 break;
890 dest[pos] = src[i];
891 }
892
893 return pos;
894}
895
896/*
897 * This function returns the correct private structure pointer based
898 * upon the BSS type and BSS number.
899 */
900static inline struct mwifiex_private *
901mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
902 u32 bss_num, u32 bss_type)
903{
904 int i;
905
906 for (i = 0; i < adapter->priv_num; i++) {
907 if (adapter->priv[i]) {
908 if ((adapter->priv[i]->bss_num == bss_num)
909 && (adapter->priv[i]->bss_type == bss_type))
910 break;
911 }
912 }
913 return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
914}
915
916/*
917 * This function returns the first available private structure pointer
918 * based upon the BSS role.
919 */
920static inline struct mwifiex_private *
921mwifiex_get_priv(struct mwifiex_adapter *adapter,
922 enum mwifiex_bss_role bss_role)
923{
924 int i;
925
926 for (i = 0; i < adapter->priv_num; i++) {
927 if (adapter->priv[i]) {
928 if (bss_role == MWIFIEX_BSS_ROLE_ANY ||
929 GET_BSS_ROLE(adapter->priv[i]) == bss_role)
930 break;
931 }
932 }
933
934 return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
935}
936
937/*
938 * This function returns the driver private structure of a network device.
939 */
940static inline struct mwifiex_private *
941mwifiex_netdev_get_priv(struct net_device *dev)
942{
943 return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
944}
945
946struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue(
947 struct mwifiex_private *,
948 u8 wait_option);
949struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
950 *adapter, u8 bss_index);
951int mwifiex_shutdown_fw(struct mwifiex_private *, u8);
952
953int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *);
954int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
955
956void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
957 int maxlen);
958int mwifiex_request_set_mac_address(struct mwifiex_private *priv);
959void mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
960 struct net_device *dev);
961int mwifiex_request_ioctl(struct mwifiex_private *priv,
962 struct mwifiex_wait_queue *req,
963 int, u8 wait_option);
964int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *);
965int mwifiex_bss_start(struct mwifiex_private *priv,
966 u8 wait_option,
967 struct mwifiex_ssid_bssid *ssid_bssid);
968int mwifiex_set_hs_params(struct mwifiex_private *priv,
969 u16 action, u8 wait_option,
970 struct mwifiex_ds_hs_cfg *hscfg);
971int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option);
972int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
973void mwifiex_process_ioctl_resp(struct mwifiex_private *priv,
974 struct mwifiex_wait_queue *req);
975u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option);
976int mwifiex_get_signal_info(struct mwifiex_private *priv,
977 u8 wait_option,
978 struct mwifiex_ds_get_signal *signal);
979int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
980 struct mwifiex_rate_cfg *rate);
981int mwifiex_get_channel_list(struct mwifiex_private *priv,
982 u8 wait_option,
983 struct mwifiex_chan_list *chanlist);
984int mwifiex_get_scan_table(struct mwifiex_private *priv,
985 u8 wait_option,
986 struct mwifiex_scan_resp *scanresp);
987int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option);
988int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option,
989 struct mwifiex_ssid_bssid *ssid_bssid);
990int mwifiex_request_scan(struct mwifiex_private *priv,
991 u8 wait_option,
992 struct mwifiex_802_11_ssid *req_ssid);
993int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
994 struct mwifiex_user_scan_cfg *scan_req);
995int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel);
996int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
997
998int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel);
999
1000int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
1001 int key_len, u8 key_index, int disable);
1002
1003int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
1004
1005int mwifiex_get_ver_ext(struct mwifiex_private *priv);
1006
1007int mwifiex_get_stats_info(struct mwifiex_private *priv,
1008 struct mwifiex_ds_get_stats *log);
1009
1010int mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
1011 u32 reg_offset, u32 reg_value);
1012
1013int mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
1014 u32 reg_offset, u32 *value);
1015
1016int mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
1017 u8 *value);
1018
1019int mwifiex_set_11n_httx_cfg(struct mwifiex_private *priv, int data);
1020
1021int mwifiex_get_11n_httx_cfg(struct mwifiex_private *priv, int *data);
1022
1023int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index);
1024
1025int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index);
1026
1027int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on);
1028
1029int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter,
1030 char *version, int max_len);
1031
1032int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm);
1033
1034int mwifiex_main_process(struct mwifiex_adapter *);
1035
1036int mwifiex_bss_ioctl_channel(struct mwifiex_private *,
1037 u16 action,
1038 struct mwifiex_chan_freq_power *cfp);
1039int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *,
1040 struct mwifiex_wait_queue *,
1041 struct mwifiex_ssid_bssid *);
1042int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *,
1043 u16 action,
1044 struct mwifiex_ds_band_cfg *);
1045int mwifiex_snmp_mib_ioctl(struct mwifiex_private *,
1046 struct mwifiex_wait_queue *,
1047 u32 cmd_oid, u16 action, u32 *value);
1048int mwifiex_get_bss_info(struct mwifiex_private *,
1049 struct mwifiex_bss_info *);
1050
1051#ifdef CONFIG_DEBUG_FS
1052void mwifiex_debugfs_init(void);
1053void mwifiex_debugfs_remove(void);
1054
1055void mwifiex_dev_debugfs_init(struct mwifiex_private *priv);
1056void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv);
1057#endif
1058#endif /* !_MWIFIEX_MAIN_H_ */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
new file mode 100644
index 000000000000..6bb52d0e6cfa
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -0,0 +1,3097 @@
1/*
2 * Marvell Wireless LAN device driver: scan ioctl and command handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "11n.h"
26#include "cfg80211.h"
27
28/* The maximum number of channels the firmware can scan per command */
29#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14
30
31#define MWIFIEX_CHANNELS_PER_SCAN_CMD 4
32
33/* Memory needed to store a max sized Channel List TLV for a firmware scan */
34#define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \
35 + (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN \
36 *sizeof(struct mwifiex_chan_scan_param_set)))
37
38/* Memory needed to store supported rate */
39#define RATE_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_rates_param_set) \
40 + HOSTCMD_SUPPORTED_RATES)
41
42/* Memory needed to store a max number/size WildCard SSID TLV for a firmware
43 scan */
44#define WILDCARD_SSID_TLV_MAX_SIZE \
45 (MWIFIEX_MAX_SSID_LIST_LENGTH * \
46 (sizeof(struct mwifiex_ie_types_wildcard_ssid_params) \
47 + IEEE80211_MAX_SSID_LEN))
48
49/* Maximum memory needed for a mwifiex_scan_cmd_config with all TLVs at max */
50#define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config) \
51 + sizeof(struct mwifiex_ie_types_num_probes) \
52 + sizeof(struct mwifiex_ie_types_htcap) \
53 + CHAN_TLV_MAX_SIZE \
54 + RATE_TLV_MAX_SIZE \
55 + WILDCARD_SSID_TLV_MAX_SIZE)
56
57
58union mwifiex_scan_cmd_config_tlv {
59 /* Scan configuration (variable length) */
60 struct mwifiex_scan_cmd_config config;
61 /* Max allocated block */
62 u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
63};
64
65enum cipher_suite {
66 CIPHER_SUITE_TKIP,
67 CIPHER_SUITE_CCMP,
68 CIPHER_SUITE_MAX
69};
70static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = {
71 { 0x00, 0x50, 0xf2, 0x02 }, /* TKIP */
72 { 0x00, 0x50, 0xf2, 0x04 }, /* AES */
73};
74static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = {
75 { 0x00, 0x0f, 0xac, 0x02 }, /* TKIP */
76 { 0x00, 0x0f, 0xac, 0x04 }, /* AES */
77};
78
79/*
80 * This function parses a given IE for a given OUI.
81 *
82 * This is used to parse a WPA/RSN IE to find if it has
83 * a given oui in PTK.
84 */
85static u8
86mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
87{
88 u8 count;
89
90 count = iebody->ptk_cnt[0];
91
92 /* There could be multiple OUIs for PTK hence
93 1) Take the length.
94 2) Check all the OUIs for AES.
95 3) If one of them is AES then pass success. */
96 while (count) {
97 if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
98 return MWIFIEX_OUI_PRESENT;
99
100 --count;
101 if (count)
102 iebody = (struct ie_body *) ((u8 *) iebody +
103 sizeof(iebody->ptk_body));
104 }
105
106 pr_debug("info: %s: OUI is not found in PTK\n", __func__);
107 return MWIFIEX_OUI_NOT_PRESENT;
108}
109
110/*
111 * This function checks if a given OUI is present in a RSN IE.
112 *
113 * The function first checks if a RSN IE is present or not in the
114 * BSS descriptor. It tries to locate the OUI only if such an IE is
115 * present.
116 */
117static u8
118mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
119{
120 u8 *oui = NULL;
121 struct ie_body *iebody = NULL;
122 u8 ret = MWIFIEX_OUI_NOT_PRESENT;
123
124 if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
125 ieee_hdr.element_id == WLAN_EID_RSN))) {
126 iebody = (struct ie_body *)
127 (((u8 *) bss_desc->bcn_rsn_ie->data) +
128 RSN_GTK_OUI_OFFSET);
129 oui = &mwifiex_rsn_oui[cipher][0];
130 ret = mwifiex_search_oui_in_ie(iebody, oui);
131 if (ret)
132 return ret;
133 }
134 return ret;
135}
136
137/*
138 * This function checks if a given OUI is present in a WPA IE.
139 *
140 * The function first checks if a WPA IE is present or not in the
141 * BSS descriptor. It tries to locate the OUI only if such an IE is
142 * present.
143 */
144static u8
145mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
146{
147 u8 *oui = NULL;
148 struct ie_body *iebody = NULL;
149 u8 ret = MWIFIEX_OUI_NOT_PRESENT;
150
151 if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).
152 vend_hdr.element_id == WLAN_EID_WPA))) {
153 iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
154 oui = &mwifiex_wpa_oui[cipher][0];
155 ret = mwifiex_search_oui_in_ie(iebody, oui);
156 if (ret)
157 return ret;
158 }
159 return ret;
160}
161
162/*
163 * This function compares two SSIDs and checks if they match.
164 */
165s32
166mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
167 struct mwifiex_802_11_ssid *ssid2)
168{
169 if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
170 return -1;
171 return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
172}
173
174/*
175 * Sends IOCTL request to get the best BSS.
176 *
177 * This function allocates the IOCTL request buffer, fills it
178 * with requisite parameters and calls the IOCTL handler.
179 */
180int mwifiex_find_best_bss(struct mwifiex_private *priv,
181 u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid)
182{
183 struct mwifiex_wait_queue *wait = NULL;
184 struct mwifiex_ssid_bssid tmp_ssid_bssid;
185 int ret = 0;
186 u8 *mac = NULL;
187
188 if (!ssid_bssid)
189 return -1;
190
191 /* Allocate wait request buffer */
192 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
193 if (!wait)
194 return -ENOMEM;
195
196 memcpy(&tmp_ssid_bssid, ssid_bssid,
197 sizeof(struct mwifiex_ssid_bssid));
198 ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid);
199
200 if (!ret) {
201 memcpy(ssid_bssid, &tmp_ssid_bssid,
202 sizeof(struct mwifiex_ssid_bssid));
203 mac = (u8 *) &ssid_bssid->bssid;
204 dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s,"
205 " %pM\n", ssid_bssid->ssid.ssid, mac);
206 }
207
208 kfree(wait);
209 return ret;
210}
211
212/*
213 * Sends IOCTL request to start a scan with user configurations.
214 *
215 * This function allocates the IOCTL request buffer, fills it
216 * with requisite parameters and calls the IOCTL handler.
217 *
218 * Upon completion, it also generates a wireless event to notify
219 * applications.
220 */
221int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
222 struct mwifiex_user_scan_cfg *scan_req)
223{
224 struct mwifiex_wait_queue *wait = NULL;
225 int status = 0;
226 u8 wait_option = MWIFIEX_IOCTL_WAIT;
227
228 /* Allocate an IOCTL request buffer */
229 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
230 if (!wait)
231 return -ENOMEM;
232
233 status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET,
234 scan_req, NULL);
235
236 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
237
238 if (wait && (status != -EINPROGRESS))
239 kfree(wait);
240 return status;
241}
242
243/*
244 * This function checks if wapi is enabled in driver and scanned network is
245 * compatible with it.
246 */
247static bool
248mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
249 struct mwifiex_bssdescriptor *bss_desc)
250{
251 if (priv->sec_info.wapi_enabled &&
252 (bss_desc->bcn_wapi_ie &&
253 ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id ==
254 WLAN_EID_BSS_AC_ACCESS_DELAY))) {
255 return true;
256 }
257 return false;
258}
259
260/*
261 * This function checks if driver is configured with no security mode and
262 * scanned network is compatible with it.
263 */
264static bool
265mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
266 struct mwifiex_bssdescriptor *bss_desc)
267{
268 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
269 && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
270 && ((!bss_desc->bcn_wpa_ie) ||
271 ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
272 WLAN_EID_WPA))
273 && ((!bss_desc->bcn_rsn_ie) ||
274 ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
275 WLAN_EID_RSN))
276 && !priv->sec_info.encryption_mode
277 && !bss_desc->privacy) {
278 return true;
279 }
280 return false;
281}
282
283/*
284 * This function checks if static WEP is enabled in driver and scanned network
285 * is compatible with it.
286 */
287static bool
288mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
289 struct mwifiex_bssdescriptor *bss_desc)
290{
291 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
292 && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
293 && bss_desc->privacy) {
294 return true;
295 }
296 return false;
297}
298
299/*
300 * This function checks if wpa is enabled in driver and scanned network is
301 * compatible with it.
302 */
303static bool
304mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
305 struct mwifiex_bssdescriptor *bss_desc,
306 int index)
307{
308 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
309 && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
310 && ((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
311 element_id == WLAN_EID_WPA))
312 /*
313 * Privacy bit may NOT be set in some APs like
314 * LinkSys WRT54G && bss_desc->privacy
315 */
316 ) {
317 dev_dbg(priv->adapter->dev, "info: %s: WPA: index=%d"
318 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
319 "EncMode=%#x privacy=%#x\n", __func__, index,
320 (bss_desc->bcn_wpa_ie) ?
321 (*(bss_desc->bcn_wpa_ie)).
322 vend_hdr.element_id : 0,
323 (bss_desc->bcn_rsn_ie) ?
324 (*(bss_desc->bcn_rsn_ie)).
325 ieee_hdr.element_id : 0,
326 (priv->sec_info.wep_status ==
327 MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
328 (priv->sec_info.wpa_enabled) ? "e" : "d",
329 (priv->sec_info.wpa2_enabled) ? "e" : "d",
330 priv->sec_info.encryption_mode,
331 bss_desc->privacy);
332 return true;
333 }
334 return false;
335}
336
337/*
338 * This function checks if wpa2 is enabled in driver and scanned network is
339 * compatible with it.
340 */
341static bool
342mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
343 struct mwifiex_bssdescriptor *bss_desc,
344 int index)
345{
346 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
347 && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled
348 && ((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
349 element_id == WLAN_EID_RSN))
350 /*
351 * Privacy bit may NOT be set in some APs like
352 * LinkSys WRT54G && bss_desc->privacy
353 */
354 ) {
355 dev_dbg(priv->adapter->dev, "info: %s: WPA2: index=%d"
356 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
357 "EncMode=%#x privacy=%#x\n", __func__, index,
358 (bss_desc->bcn_wpa_ie) ?
359 (*(bss_desc->bcn_wpa_ie)).
360 vend_hdr.element_id : 0,
361 (bss_desc->bcn_rsn_ie) ?
362 (*(bss_desc->bcn_rsn_ie)).
363 ieee_hdr.element_id : 0,
364 (priv->sec_info.wep_status ==
365 MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
366 (priv->sec_info.wpa_enabled) ? "e" : "d",
367 (priv->sec_info.wpa2_enabled) ? "e" : "d",
368 priv->sec_info.encryption_mode,
369 bss_desc->privacy);
370 return true;
371 }
372 return false;
373}
374
375/*
376 * This function checks if adhoc AES is enabled in driver and scanned network is
377 * compatible with it.
378 */
379static bool
380mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
381 struct mwifiex_bssdescriptor *bss_desc)
382{
383 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
384 && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
385 && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
386 element_id != WLAN_EID_WPA))
387 && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
388 element_id != WLAN_EID_RSN))
389 && !priv->sec_info.encryption_mode
390 && bss_desc->privacy) {
391 return true;
392 }
393 return false;
394}
395
396/*
397 * This function checks if dynamic WEP is enabled in driver and scanned network
398 * is compatible with it.
399 */
400static bool
401mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
402 struct mwifiex_bssdescriptor *bss_desc,
403 int index)
404{
405 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
406 && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
407 && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
408 element_id != WLAN_EID_WPA))
409 && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
410 element_id != WLAN_EID_RSN))
411 && priv->sec_info.encryption_mode
412 && bss_desc->privacy) {
413 dev_dbg(priv->adapter->dev, "info: %s: dynamic "
414 "WEP: index=%d wpa_ie=%#x wpa2_ie=%#x "
415 "EncMode=%#x privacy=%#x\n",
416 __func__, index,
417 (bss_desc->bcn_wpa_ie) ?
418 (*(bss_desc->bcn_wpa_ie)).
419 vend_hdr.element_id : 0,
420 (bss_desc->bcn_rsn_ie) ?
421 (*(bss_desc->bcn_rsn_ie)).
422 ieee_hdr.element_id : 0,
423 priv->sec_info.encryption_mode,
424 bss_desc->privacy);
425 return true;
426 }
427 return false;
428}
429
430/*
431 * This function checks if a scanned network is compatible with the driver
432 * settings.
433 *
434 * WEP WPA WPA2 ad-hoc encrypt Network
435 * enabled enabled enabled AES mode Privacy WPA WPA2 Compatible
436 * 0 0 0 0 NONE 0 0 0 yes No security
437 * 0 1 0 0 x 1x 1 x yes WPA (disable
438 * HT if no AES)
439 * 0 0 1 0 x 1x x 1 yes WPA2 (disable
440 * HT if no AES)
441 * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES
442 * 1 0 0 0 NONE 1 0 0 yes Static WEP
443 * (disable HT)
444 * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP
445 *
446 * Compatibility is not matched while roaming, except for mode.
447 */
448static s32
449mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
450{
451 struct mwifiex_adapter *adapter = priv->adapter;
452 struct mwifiex_bssdescriptor *bss_desc;
453
454 bss_desc = &adapter->scan_table[index];
455 bss_desc->disable_11n = false;
456
457 /* Don't check for compatibility if roaming */
458 if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
459 && (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
460 return index;
461
462 if (priv->wps.session_enable) {
463 dev_dbg(adapter->dev,
464 "info: return success directly in WPS period\n");
465 return index;
466 }
467
468 if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
469 dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
470 return index;
471 }
472
473 if (bss_desc->bss_mode == mode) {
474 if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
475 /* No security */
476 return index;
477 } else if (mwifiex_is_network_compatible_for_static_wep(priv,
478 bss_desc)) {
479 /* Static WEP enabled */
480 dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
481 bss_desc->disable_11n = true;
482 return index;
483 } else if (mwifiex_is_network_compatible_for_wpa(priv, bss_desc,
484 index)) {
485 /* WPA enabled */
486 if (((priv->adapter->config_bands & BAND_GN
487 || priv->adapter->config_bands & BAND_AN)
488 && bss_desc->bcn_ht_cap)
489 && !mwifiex_is_wpa_oui_present(bss_desc,
490 CIPHER_SUITE_CCMP)) {
491
492 if (mwifiex_is_wpa_oui_present(bss_desc,
493 CIPHER_SUITE_TKIP)) {
494 dev_dbg(adapter->dev,
495 "info: Disable 11n if AES "
496 "is not supported by AP\n");
497 bss_desc->disable_11n = true;
498 } else {
499 return -1;
500 }
501 }
502 return index;
503 } else if (mwifiex_is_network_compatible_for_wpa2(priv,
504 bss_desc, index)) {
505 /* WPA2 enabled */
506 if (((priv->adapter->config_bands & BAND_GN
507 || priv->adapter->config_bands & BAND_AN)
508 && bss_desc->bcn_ht_cap)
509 && !mwifiex_is_rsn_oui_present(bss_desc,
510 CIPHER_SUITE_CCMP)) {
511
512 if (mwifiex_is_rsn_oui_present(bss_desc,
513 CIPHER_SUITE_TKIP)) {
514 dev_dbg(adapter->dev,
515 "info: Disable 11n if AES "
516 "is not supported by AP\n");
517 bss_desc->disable_11n = true;
518 } else {
519 return -1;
520 }
521 }
522 return index;
523 } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
524 bss_desc)) {
525 /* Ad-hoc AES enabled */
526 return index;
527 } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
528 bss_desc, index)) {
529 /* Dynamic WEP enabled */
530 return index;
531 }
532
533 /* Security doesn't match */
534 dev_dbg(adapter->dev, "info: %s: failed: index=%d "
535 "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
536 "=%#x privacy=%#x\n",
537 __func__, index,
538 (bss_desc->bcn_wpa_ie) ?
539 (*(bss_desc->bcn_wpa_ie)).vend_hdr.
540 element_id : 0,
541 (bss_desc->bcn_rsn_ie) ?
542 (*(bss_desc->bcn_rsn_ie)).ieee_hdr.
543 element_id : 0,
544 (priv->sec_info.wep_status ==
545 MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
546 (priv->sec_info.wpa_enabled) ? "e" : "d",
547 (priv->sec_info.wpa2_enabled) ? "e" : "d",
548 priv->sec_info.encryption_mode, bss_desc->privacy);
549 return -1;
550 }
551
552 /* Mode doesn't match */
553 return -1;
554}
555
556/*
557 * This function finds the best SSID in the scan list.
558 *
559 * It searches the scan table for the best SSID that also matches the current
560 * adapter network preference (mode, security etc.).
561 */
562static s32
563mwifiex_find_best_network_in_list(struct mwifiex_private *priv)
564{
565 struct mwifiex_adapter *adapter = priv->adapter;
566 u32 mode = priv->bss_mode;
567 s32 best_net = -1;
568 s32 best_rssi = 0;
569 u32 i;
570
571 dev_dbg(adapter->dev, "info: num of BSSIDs = %d\n",
572 adapter->num_in_scan_table);
573
574 for (i = 0; i < adapter->num_in_scan_table; i++) {
575 switch (mode) {
576 case NL80211_IFTYPE_STATION:
577 case NL80211_IFTYPE_ADHOC:
578 if (mwifiex_is_network_compatible(priv, i, mode) >= 0) {
579 if (SCAN_RSSI(adapter->scan_table[i].rssi) >
580 best_rssi) {
581 best_rssi = SCAN_RSSI(adapter->
582 scan_table[i].rssi);
583 best_net = i;
584 }
585 }
586 break;
587 case NL80211_IFTYPE_UNSPECIFIED:
588 default:
589 if (SCAN_RSSI(adapter->scan_table[i].rssi) >
590 best_rssi) {
591 best_rssi = SCAN_RSSI(adapter->scan_table[i].
592 rssi);
593 best_net = i;
594 }
595 break;
596 }
597 }
598
599 return best_net;
600}
601
602/*
603 * This function creates a channel list for the driver to scan, based
604 * on region/band information.
605 *
606 * This routine is used for any scan that is not provided with a
607 * specific channel list to scan.
608 */
609static void
610mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
611 const struct mwifiex_user_scan_cfg
612 *user_scan_in,
613 struct mwifiex_chan_scan_param_set
614 *scan_chan_list,
615 u8 filtered_scan)
616{
617 enum ieee80211_band band;
618 struct ieee80211_supported_band *sband;
619 struct ieee80211_channel *ch;
620 struct mwifiex_adapter *adapter = priv->adapter;
621 int chan_idx = 0, i;
622 u8 scan_type;
623
624 for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
625
626 if (!priv->wdev->wiphy->bands[band])
627 continue;
628
629 sband = priv->wdev->wiphy->bands[band];
630
631 for (i = 0; (i < sband->n_channels) ; i++, chan_idx++) {
632 ch = &sband->channels[i];
633 if (ch->flags & IEEE80211_CHAN_DISABLED)
634 continue;
635 scan_chan_list[chan_idx].radio_type = band;
636 scan_type = ch->flags & IEEE80211_CHAN_PASSIVE_SCAN;
637 if (user_scan_in &&
638 user_scan_in->chan_list[0].scan_time)
639 scan_chan_list[chan_idx].max_scan_time =
640 cpu_to_le16((u16) user_scan_in->
641 chan_list[0].scan_time);
642 else if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
643 scan_chan_list[chan_idx].max_scan_time =
644 cpu_to_le16(adapter->passive_scan_time);
645 else
646 scan_chan_list[chan_idx].max_scan_time =
647 cpu_to_le16(adapter->active_scan_time);
648 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
649 scan_chan_list[chan_idx].chan_scan_mode_bitmap
650 |= MWIFIEX_PASSIVE_SCAN;
651 else
652 scan_chan_list[chan_idx].chan_scan_mode_bitmap
653 &= ~MWIFIEX_PASSIVE_SCAN;
654 scan_chan_list[chan_idx].chan_number =
655 (u32) ch->hw_value;
656 if (filtered_scan) {
657 scan_chan_list[chan_idx].max_scan_time =
658 cpu_to_le16(adapter->specific_scan_time);
659 scan_chan_list[chan_idx].chan_scan_mode_bitmap
660 |= MWIFIEX_DISABLE_CHAN_FILT;
661 }
662 }
663
664 }
665}
666
667/*
668 * This function constructs and sends multiple scan config commands to
669 * the firmware.
670 *
671 * Previous routines in the code flow have created a scan command configuration
672 * with any requested TLVs. This function splits the channel TLV into maximum
673 * channels supported per scan lists and sends the portion of the channel TLV,
674 * along with the other TLVs, to the firmware.
675 */
676static int
677mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf,
678 u32 max_chan_per_scan, u8 filtered_scan,
679 struct mwifiex_scan_cmd_config *scan_cfg_out,
680 struct mwifiex_ie_types_chan_list_param_set
681 *chan_tlv_out,
682 struct mwifiex_chan_scan_param_set *scan_chan_list)
683{
684 int ret = 0;
685 struct mwifiex_chan_scan_param_set *tmp_chan_list;
686 struct mwifiex_chan_scan_param_set *start_chan;
687
688 u32 tlv_idx;
689 u32 total_scan_time;
690 u32 done_early;
691
692 if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
693 dev_dbg(priv->adapter->dev,
694 "info: Scan: Null detect: %p, %p, %p\n",
695 scan_cfg_out, chan_tlv_out, scan_chan_list);
696 return -1;
697 }
698
699 chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
700
701 /* Set the temp channel struct pointer to the start of the desired
702 list */
703 tmp_chan_list = scan_chan_list;
704
705 /* Loop through the desired channel list, sending a new firmware scan
706 commands for each max_chan_per_scan channels (or for 1,6,11
707 individually if configured accordingly) */
708 while (tmp_chan_list->chan_number) {
709
710 tlv_idx = 0;
711 total_scan_time = 0;
712 chan_tlv_out->header.len = 0;
713 start_chan = tmp_chan_list;
714 done_early = false;
715
716 /*
717 * Construct the Channel TLV for the scan command. Continue to
718 * insert channel TLVs until:
719 * - the tlv_idx hits the maximum configured per scan command
720 * - the next channel to insert is 0 (end of desired channel
721 * list)
722 * - done_early is set (controlling individual scanning of
723 * 1,6,11)
724 */
725 while (tlv_idx < max_chan_per_scan
726 && tmp_chan_list->chan_number && !done_early) {
727
728 dev_dbg(priv->adapter->dev,
729 "info: Scan: Chan(%3d), Radio(%d),"
730 " Mode(%d, %d), Dur(%d)\n",
731 tmp_chan_list->chan_number,
732 tmp_chan_list->radio_type,
733 tmp_chan_list->chan_scan_mode_bitmap
734 & MWIFIEX_PASSIVE_SCAN,
735 (tmp_chan_list->chan_scan_mode_bitmap
736 & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
737 le16_to_cpu(tmp_chan_list->max_scan_time));
738
739 /* Copy the current channel TLV to the command being
740 prepared */
741 memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
742 tmp_chan_list,
743 sizeof(chan_tlv_out->chan_scan_param));
744
745 /* Increment the TLV header length by the size
746 appended */
747 chan_tlv_out->header.len =
748 cpu_to_le16(le16_to_cpu(chan_tlv_out->header.len) +
749 (sizeof(chan_tlv_out->chan_scan_param)));
750
751 /*
752 * The tlv buffer length is set to the number of bytes
753 * of the between the channel tlv pointer and the start
754 * of the tlv buffer. This compensates for any TLVs
755 * that were appended before the channel list.
756 */
757 scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
758 scan_cfg_out->tlv_buf);
759
760 /* Add the size of the channel tlv header and the data
761 length */
762 scan_cfg_out->tlv_buf_len +=
763 (sizeof(chan_tlv_out->header)
764 + le16_to_cpu(chan_tlv_out->header.len));
765
766 /* Increment the index to the channel tlv we are
767 constructing */
768 tlv_idx++;
769
770 /* Count the total scan time per command */
771 total_scan_time +=
772 le16_to_cpu(tmp_chan_list->max_scan_time);
773
774 done_early = false;
775
776 /* Stop the loop if the *current* channel is in the
777 1,6,11 set and we are not filtering on a BSSID
778 or SSID. */
779 if (!filtered_scan && (tmp_chan_list->chan_number == 1
780 || tmp_chan_list->chan_number == 6
781 || tmp_chan_list->chan_number == 11))
782 done_early = true;
783
784 /* Increment the tmp pointer to the next channel to
785 be scanned */
786 tmp_chan_list++;
787
788 /* Stop the loop if the *next* channel is in the 1,6,11
789 set. This will cause it to be the only channel
790 scanned on the next interation */
791 if (!filtered_scan && (tmp_chan_list->chan_number == 1
792 || tmp_chan_list->chan_number == 6
793 || tmp_chan_list->chan_number == 11))
794 done_early = true;
795 }
796
797 /* The total scan time should be less than scan command timeout
798 value */
799 if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
800 dev_err(priv->adapter->dev, "total scan time %dms"
801 " is over limit (%dms), scan skipped\n",
802 total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME);
803 ret = -1;
804 break;
805 }
806
807 priv->adapter->scan_channels = start_chan;
808
809 /* Send the scan command to the firmware with the specified
810 cfg */
811 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN,
812 HostCmd_ACT_GEN_SET,
813 0, wait_buf, scan_cfg_out);
814 if (ret)
815 break;
816 }
817
818 if (ret)
819 return -1;
820
821 return 0;
822}
823
824/*
825 * This function constructs a scan command configuration structure to use
826 * in scan commands.
827 *
828 * Application layer or other functions can invoke network scanning
829 * with a scan configuration supplied in a user scan configuration structure.
830 * This structure is used as the basis of one or many scan command configuration
831 * commands that are sent to the command processing module and eventually to the
832 * firmware.
833 *
834 * This function creates a scan command configuration structure based on the
835 * following user supplied parameters (if present):
836 * - SSID filter
837 * - BSSID filter
838 * - Number of Probes to be sent
839 * - Channel list
840 *
841 * If the SSID or BSSID filter is not present, the filter is disabled/cleared.
842 * If the number of probes is not set, adapter default setting is used.
843 */
844static void
845mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
846 const struct mwifiex_user_scan_cfg *user_scan_in,
847 struct mwifiex_scan_cmd_config *scan_cfg_out,
848 struct mwifiex_ie_types_chan_list_param_set
849 **chan_list_out,
850 struct mwifiex_chan_scan_param_set
851 *scan_chan_list,
852 u8 *max_chan_per_scan, u8 *filtered_scan,
853 u8 *scan_current_only)
854{
855 struct mwifiex_adapter *adapter = priv->adapter;
856 struct mwifiex_ie_types_num_probes *num_probes_tlv;
857 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
858 struct mwifiex_ie_types_rates_param_set *rates_tlv;
859 const u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
860 u8 *tlv_pos;
861 u32 num_probes;
862 u32 ssid_len;
863 u32 chan_idx;
864 u32 scan_type;
865 u16 scan_dur;
866 u8 channel;
867 u8 radio_type;
868 u32 ssid_idx;
869 u8 ssid_filter;
870 u8 rates[MWIFIEX_SUPPORTED_RATES];
871 u32 rates_size;
872 struct mwifiex_ie_types_htcap *ht_cap;
873
874 /* The tlv_buf_len is calculated for each scan command. The TLVs added
875 in this routine will be preserved since the routine that sends the
876 command will append channelTLVs at *chan_list_out. The difference
877 between the *chan_list_out and the tlv_buf start will be used to
878 calculate the size of anything we add in this routine. */
879 scan_cfg_out->tlv_buf_len = 0;
880
881 /* Running tlv pointer. Assigned to chan_list_out at end of function
882 so later routines know where channels can be added to the command
883 buf */
884 tlv_pos = scan_cfg_out->tlv_buf;
885
886 /* Initialize the scan as un-filtered; the flag is later set to TRUE
887 below if a SSID or BSSID filter is sent in the command */
888 *filtered_scan = false;
889
890 /* Initialize the scan as not being only on the current channel. If
891 the channel list is customized, only contains one channel, and is
892 the active channel, this is set true and data flow is not halted. */
893 *scan_current_only = false;
894
895 if (user_scan_in) {
896
897 /* Default the ssid_filter flag to TRUE, set false under
898 certain wildcard conditions and qualified by the existence
899 of an SSID list before marking the scan as filtered */
900 ssid_filter = true;
901
902 /* Set the BSS type scan filter, use Adapter setting if
903 unset */
904 scan_cfg_out->bss_mode =
905 (user_scan_in->bss_mode ? (u8) user_scan_in->
906 bss_mode : (u8) adapter->scan_mode);
907
908 /* Set the number of probes to send, use Adapter setting
909 if unset */
910 num_probes =
911 (user_scan_in->num_probes ? user_scan_in->
912 num_probes : adapter->scan_probes);
913
914 /*
915 * Set the BSSID filter to the incoming configuration,
916 * if non-zero. If not set, it will remain disabled
917 * (all zeros).
918 */
919 memcpy(scan_cfg_out->specific_bssid,
920 user_scan_in->specific_bssid,
921 sizeof(scan_cfg_out->specific_bssid));
922
923 for (ssid_idx = 0;
924 ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list))
925 && (*user_scan_in->ssid_list[ssid_idx].ssid
926 || user_scan_in->ssid_list[ssid_idx].max_len));
927 ssid_idx++) {
928
929 ssid_len = strlen(user_scan_in->ssid_list[ssid_idx].
930 ssid) + 1;
931
932 wildcard_ssid_tlv =
933 (struct mwifiex_ie_types_wildcard_ssid_params *)
934 tlv_pos;
935 wildcard_ssid_tlv->header.type =
936 cpu_to_le16(TLV_TYPE_WILDCARDSSID);
937 wildcard_ssid_tlv->header.len = cpu_to_le16(
938 (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
939 max_ssid_length)));
940 wildcard_ssid_tlv->max_ssid_length =
941 user_scan_in->ssid_list[ssid_idx].max_len;
942
943 memcpy(wildcard_ssid_tlv->ssid,
944 user_scan_in->ssid_list[ssid_idx].ssid,
945 ssid_len);
946
947 tlv_pos += (sizeof(wildcard_ssid_tlv->header)
948 + le16_to_cpu(wildcard_ssid_tlv->header.len));
949
950 dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n",
951 ssid_idx, wildcard_ssid_tlv->ssid,
952 wildcard_ssid_tlv->max_ssid_length);
953
954 /* Empty wildcard ssid with a maxlen will match many or
955 potentially all SSIDs (maxlen == 32), therefore do
956 not treat the scan as
957 filtered. */
958 if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
959 ssid_filter = false;
960
961 }
962
963 /*
964 * The default number of channels sent in the command is low to
965 * ensure the response buffer from the firmware does not
966 * truncate scan results. That is not an issue with an SSID
967 * or BSSID filter applied to the scan results in the firmware.
968 */
969 if ((ssid_idx && ssid_filter)
970 || memcmp(scan_cfg_out->specific_bssid, &zero_mac,
971 sizeof(zero_mac)))
972 *filtered_scan = true;
973 } else {
974 scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
975 num_probes = adapter->scan_probes;
976 }
977
978 /*
979 * If a specific BSSID or SSID is used, the number of channels in the
980 * scan command will be increased to the absolute maximum.
981 */
982 if (*filtered_scan)
983 *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
984 else
985 *max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD;
986
987 /* If the input config or adapter has the number of Probes set,
988 add tlv */
989 if (num_probes) {
990
991 dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
992 num_probes);
993
994 num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
995 num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
996 num_probes_tlv->header.len =
997 cpu_to_le16(sizeof(num_probes_tlv->num_probes));
998 num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
999
1000 tlv_pos += sizeof(num_probes_tlv->header) +
1001 le16_to_cpu(num_probes_tlv->header.len);
1002
1003 }
1004
1005 /* Append rates tlv */
1006 memset(rates, 0, sizeof(rates));
1007
1008 rates_size = mwifiex_get_supported_rates(priv, rates);
1009
1010 rates_tlv = (struct mwifiex_ie_types_rates_param_set *) tlv_pos;
1011 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
1012 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
1013 memcpy(rates_tlv->rates, rates, rates_size);
1014 tlv_pos += sizeof(rates_tlv->header) + rates_size;
1015
1016 dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
1017
1018 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
1019 && (priv->adapter->config_bands & BAND_GN
1020 || priv->adapter->config_bands & BAND_AN)) {
1021 ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
1022 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
1023 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
1024 ht_cap->header.len =
1025 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
1026 mwifiex_fill_cap_info(priv, ht_cap);
1027 tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
1028 }
1029
1030 /* Append vendor specific IE TLV */
1031 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
1032
1033 /*
1034 * Set the output for the channel TLV to the address in the tlv buffer
1035 * past any TLVs that were added in this function (SSID, num_probes).
1036 * Channel TLVs will be added past this for each scan command,
1037 * preserving the TLVs that were previously added.
1038 */
1039 *chan_list_out =
1040 (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
1041
1042 if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
1043
1044 dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
1045
1046 for (chan_idx = 0;
1047 chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX
1048 && user_scan_in->chan_list[chan_idx].chan_number;
1049 chan_idx++) {
1050
1051 channel = user_scan_in->chan_list[chan_idx].chan_number;
1052 (scan_chan_list + chan_idx)->chan_number = channel;
1053
1054 radio_type =
1055 user_scan_in->chan_list[chan_idx].radio_type;
1056 (scan_chan_list + chan_idx)->radio_type = radio_type;
1057
1058 scan_type = user_scan_in->chan_list[chan_idx].scan_type;
1059
1060 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1061 (scan_chan_list +
1062 chan_idx)->chan_scan_mode_bitmap
1063 |= MWIFIEX_PASSIVE_SCAN;
1064 else
1065 (scan_chan_list +
1066 chan_idx)->chan_scan_mode_bitmap
1067 &= ~MWIFIEX_PASSIVE_SCAN;
1068
1069 if (user_scan_in->chan_list[chan_idx].scan_time) {
1070 scan_dur = (u16) user_scan_in->
1071 chan_list[chan_idx].scan_time;
1072 } else {
1073 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1074 scan_dur = adapter->passive_scan_time;
1075 else if (*filtered_scan)
1076 scan_dur = adapter->specific_scan_time;
1077 else
1078 scan_dur = adapter->active_scan_time;
1079 }
1080
1081 (scan_chan_list + chan_idx)->min_scan_time =
1082 cpu_to_le16(scan_dur);
1083 (scan_chan_list + chan_idx)->max_scan_time =
1084 cpu_to_le16(scan_dur);
1085 }
1086
1087 /* Check if we are only scanning the current channel */
1088 if ((chan_idx == 1)
1089 && (user_scan_in->chan_list[0].chan_number
1090 == priv->curr_bss_params.bss_descriptor.channel)) {
1091 *scan_current_only = true;
1092 dev_dbg(adapter->dev,
1093 "info: Scan: Scanning current channel only\n");
1094 }
1095
1096 } else {
1097 dev_dbg(adapter->dev,
1098 "info: Scan: Creating full region channel list\n");
1099 mwifiex_scan_create_channel_list(priv, user_scan_in,
1100 scan_chan_list,
1101 *filtered_scan);
1102 }
1103}
1104
1105/*
1106 * This function inspects the scan response buffer for pointers to
1107 * expected TLVs.
1108 *
1109 * TLVs can be included at the end of the scan response BSS information.
1110 *
1111 * Data in the buffer is parsed pointers to TLVs that can potentially
1112 * be passed back in the response.
1113 */
1114static void
1115mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1116 struct mwifiex_ie_types_data *tlv,
1117 u32 tlv_buf_size, u32 req_tlv_type,
1118 struct mwifiex_ie_types_data **tlv_data)
1119{
1120 struct mwifiex_ie_types_data *current_tlv;
1121 u32 tlv_buf_left;
1122 u32 tlv_type;
1123 u32 tlv_len;
1124
1125 current_tlv = tlv;
1126 tlv_buf_left = tlv_buf_size;
1127 *tlv_data = NULL;
1128
1129 dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
1130 tlv_buf_size);
1131
1132 while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
1133
1134 tlv_type = le16_to_cpu(current_tlv->header.type);
1135 tlv_len = le16_to_cpu(current_tlv->header.len);
1136
1137 if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
1138 dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n");
1139 break;
1140 }
1141
1142 if (req_tlv_type == tlv_type) {
1143 switch (tlv_type) {
1144 case TLV_TYPE_TSFTIMESTAMP:
1145 dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
1146 "timestamp TLV, len = %d\n", tlv_len);
1147 *tlv_data = (struct mwifiex_ie_types_data *)
1148 current_tlv;
1149 break;
1150 case TLV_TYPE_CHANNELBANDLIST:
1151 dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
1152 " band list TLV, len = %d\n", tlv_len);
1153 *tlv_data = (struct mwifiex_ie_types_data *)
1154 current_tlv;
1155 break;
1156 default:
1157 dev_err(adapter->dev,
1158 "SCAN_RESP: unhandled TLV = %d\n",
1159 tlv_type);
1160 /* Give up, this seems corrupted */
1161 return;
1162 }
1163 }
1164
1165 if (*tlv_data)
1166 break;
1167
1168
1169 tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
1170 current_tlv =
1171 (struct mwifiex_ie_types_data *) (current_tlv->data +
1172 tlv_len);
1173
1174 } /* while */
1175}
1176
1177/*
1178 * This function interprets a BSS scan response returned from the firmware.
1179 *
1180 * The various fixed fields and IEs are parsed and passed back for a BSS
1181 * probe response or beacon from scan command. Information is recorded as
1182 * needed in the scan table for that entry.
1183 *
1184 * The following IE types are recognized and parsed -
1185 * - SSID
1186 * - Supported rates
1187 * - FH parameters set
1188 * - DS parameters set
1189 * - CF parameters set
1190 * - IBSS parameters set
1191 * - ERP information
1192 * - Extended supported rates
1193 * - Vendor specific (221)
1194 * - RSN IE
1195 * - WAPI IE
1196 * - HT capability
1197 * - HT operation
1198 * - BSS Coexistence 20/40
1199 * - Extended capability
1200 * - Overlapping BSS scan parameters
1201 */
1202static int
1203mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1204 struct mwifiex_bssdescriptor *bss_entry,
1205 u8 **beacon_info, u32 *bytes_left)
1206{
1207 int ret = 0;
1208 u8 element_id;
1209 struct ieee_types_fh_param_set *fh_param_set;
1210 struct ieee_types_ds_param_set *ds_param_set;
1211 struct ieee_types_cf_param_set *cf_param_set;
1212 struct ieee_types_ibss_param_set *ibss_param_set;
1213 __le16 beacon_interval;
1214 __le16 capabilities;
1215 u8 *current_ptr;
1216 u8 *rate;
1217 u8 element_len;
1218 u16 total_ie_len;
1219 u8 bytes_to_copy;
1220 u8 rate_size;
1221 u16 beacon_size;
1222 u8 found_data_rate_ie;
1223 u32 bytes_left_for_current_beacon;
1224 struct ieee_types_vendor_specific *vendor_ie;
1225 const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
1226 const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
1227
1228 found_data_rate_ie = false;
1229 rate_size = 0;
1230 beacon_size = 0;
1231
1232 if (*bytes_left >= sizeof(beacon_size)) {
1233 /* Extract & convert beacon size from the command buffer */
1234 memcpy(&beacon_size, *beacon_info, sizeof(beacon_size));
1235 *bytes_left -= sizeof(beacon_size);
1236 *beacon_info += sizeof(beacon_size);
1237 }
1238
1239 if (!beacon_size || beacon_size > *bytes_left) {
1240 *beacon_info += *bytes_left;
1241 *bytes_left = 0;
1242 return -1;
1243 }
1244
1245 /* Initialize the current working beacon pointer for this BSS
1246 iteration */
1247 current_ptr = *beacon_info;
1248
1249 /* Advance the return beacon pointer past the current beacon */
1250 *beacon_info += beacon_size;
1251 *bytes_left -= beacon_size;
1252
1253 bytes_left_for_current_beacon = beacon_size;
1254
1255 memcpy(bss_entry->mac_address, current_ptr, ETH_ALEN);
1256 dev_dbg(adapter->dev, "info: InterpretIE: AP MAC Addr: %pM\n",
1257 bss_entry->mac_address);
1258
1259 current_ptr += ETH_ALEN;
1260 bytes_left_for_current_beacon -= ETH_ALEN;
1261
1262 if (bytes_left_for_current_beacon < 12) {
1263 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1264 return -1;
1265 }
1266
1267 /*
1268 * Next 4 fields are RSSI, time stamp, beacon interval,
1269 * and capability information
1270 */
1271
1272 /* RSSI is 1 byte long */
1273 bss_entry->rssi = (s32) (*current_ptr);
1274 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", *current_ptr);
1275 current_ptr += 1;
1276 bytes_left_for_current_beacon -= 1;
1277
1278 /*
1279 * The RSSI is not part of the beacon/probe response. After we have
1280 * advanced current_ptr past the RSSI field, save the remaining
1281 * data for use at the application layer
1282 */
1283 bss_entry->beacon_buf = current_ptr;
1284 bss_entry->beacon_buf_size = bytes_left_for_current_beacon;
1285
1286 /* Time stamp is 8 bytes long */
1287 memcpy(bss_entry->time_stamp, current_ptr, 8);
1288 current_ptr += 8;
1289 bytes_left_for_current_beacon -= 8;
1290
1291 /* Beacon interval is 2 bytes long */
1292 memcpy(&beacon_interval, current_ptr, 2);
1293 bss_entry->beacon_period = le16_to_cpu(beacon_interval);
1294 current_ptr += 2;
1295 bytes_left_for_current_beacon -= 2;
1296
1297 /* Capability information is 2 bytes long */
1298 memcpy(&capabilities, current_ptr, 2);
1299 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1300 capabilities);
1301 bss_entry->cap_info_bitmap = le16_to_cpu(capabilities);
1302 current_ptr += 2;
1303 bytes_left_for_current_beacon -= 2;
1304
1305 /* Rest of the current buffer are IE's */
1306 dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
1307 bytes_left_for_current_beacon);
1308
1309 if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
1310 dev_dbg(adapter->dev, "info: InterpretIE: AP WEP enabled\n");
1311 bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
1312 } else {
1313 bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
1314 }
1315
1316 if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
1317 bss_entry->bss_mode = NL80211_IFTYPE_ADHOC;
1318 else
1319 bss_entry->bss_mode = NL80211_IFTYPE_STATION;
1320
1321
1322 /* Process variable IE */
1323 while (bytes_left_for_current_beacon >= 2) {
1324 element_id = *current_ptr;
1325 element_len = *(current_ptr + 1);
1326 total_ie_len = element_len + sizeof(struct ieee_types_header);
1327
1328 if (bytes_left_for_current_beacon < total_ie_len) {
1329 dev_err(adapter->dev, "err: InterpretIE: in processing"
1330 " IE, bytes left < IE length\n");
1331 bytes_left_for_current_beacon = 0;
1332 ret = -1;
1333 continue;
1334 }
1335 switch (element_id) {
1336 case WLAN_EID_SSID:
1337 bss_entry->ssid.ssid_len = element_len;
1338 memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
1339 element_len);
1340 dev_dbg(adapter->dev, "info: InterpretIE: ssid: %-32s\n",
1341 bss_entry->ssid.ssid);
1342 break;
1343
1344 case WLAN_EID_SUPP_RATES:
1345 memcpy(bss_entry->data_rates, current_ptr + 2,
1346 element_len);
1347 memcpy(bss_entry->supported_rates, current_ptr + 2,
1348 element_len);
1349 rate_size = element_len;
1350 found_data_rate_ie = true;
1351 break;
1352
1353 case WLAN_EID_FH_PARAMS:
1354 fh_param_set =
1355 (struct ieee_types_fh_param_set *) current_ptr;
1356 memcpy(&bss_entry->phy_param_set.fh_param_set,
1357 fh_param_set,
1358 sizeof(struct ieee_types_fh_param_set));
1359 break;
1360
1361 case WLAN_EID_DS_PARAMS:
1362 ds_param_set =
1363 (struct ieee_types_ds_param_set *) current_ptr;
1364
1365 bss_entry->channel = ds_param_set->current_chan;
1366
1367 memcpy(&bss_entry->phy_param_set.ds_param_set,
1368 ds_param_set,
1369 sizeof(struct ieee_types_ds_param_set));
1370 break;
1371
1372 case WLAN_EID_CF_PARAMS:
1373 cf_param_set =
1374 (struct ieee_types_cf_param_set *) current_ptr;
1375 memcpy(&bss_entry->ss_param_set.cf_param_set,
1376 cf_param_set,
1377 sizeof(struct ieee_types_cf_param_set));
1378 break;
1379
1380 case WLAN_EID_IBSS_PARAMS:
1381 ibss_param_set =
1382 (struct ieee_types_ibss_param_set *)
1383 current_ptr;
1384 memcpy(&bss_entry->ss_param_set.ibss_param_set,
1385 ibss_param_set,
1386 sizeof(struct ieee_types_ibss_param_set));
1387 break;
1388
1389 case WLAN_EID_ERP_INFO:
1390 bss_entry->erp_flags = *(current_ptr + 2);
1391 break;
1392
1393 case WLAN_EID_EXT_SUPP_RATES:
1394 /*
1395 * Only process extended supported rate
1396 * if data rate is already found.
1397 * Data rate IE should come before
1398 * extended supported rate IE
1399 */
1400 if (found_data_rate_ie) {
1401 if ((element_len + rate_size) >
1402 MWIFIEX_SUPPORTED_RATES)
1403 bytes_to_copy =
1404 (MWIFIEX_SUPPORTED_RATES -
1405 rate_size);
1406 else
1407 bytes_to_copy = element_len;
1408
1409 rate = (u8 *) bss_entry->data_rates;
1410 rate += rate_size;
1411 memcpy(rate, current_ptr + 2, bytes_to_copy);
1412
1413 rate = (u8 *) bss_entry->supported_rates;
1414 rate += rate_size;
1415 memcpy(rate, current_ptr + 2, bytes_to_copy);
1416 }
1417 break;
1418
1419 case WLAN_EID_VENDOR_SPECIFIC:
1420 vendor_ie = (struct ieee_types_vendor_specific *)
1421 current_ptr;
1422
1423 if (!memcmp
1424 (vendor_ie->vend_hdr.oui, wpa_oui,
1425 sizeof(wpa_oui))) {
1426 bss_entry->bcn_wpa_ie =
1427 (struct ieee_types_vendor_specific *)
1428 current_ptr;
1429 bss_entry->wpa_offset = (u16) (current_ptr -
1430 bss_entry->beacon_buf);
1431 } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
1432 sizeof(wmm_oui))) {
1433 if (total_ie_len ==
1434 sizeof(struct ieee_types_wmm_parameter)
1435 || total_ie_len ==
1436 sizeof(struct ieee_types_wmm_info))
1437 /*
1438 * Only accept and copy the WMM IE if
1439 * it matches the size expected for the
1440 * WMM Info IE or the WMM Parameter IE.
1441 */
1442 memcpy((u8 *) &bss_entry->wmm_ie,
1443 current_ptr, total_ie_len);
1444 }
1445 break;
1446 case WLAN_EID_RSN:
1447 bss_entry->bcn_rsn_ie =
1448 (struct ieee_types_generic *) current_ptr;
1449 bss_entry->rsn_offset = (u16) (current_ptr -
1450 bss_entry->beacon_buf);
1451 break;
1452 case WLAN_EID_BSS_AC_ACCESS_DELAY:
1453 bss_entry->bcn_wapi_ie =
1454 (struct ieee_types_generic *) current_ptr;
1455 bss_entry->wapi_offset = (u16) (current_ptr -
1456 bss_entry->beacon_buf);
1457 break;
1458 case WLAN_EID_HT_CAPABILITY:
1459 bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
1460 (current_ptr +
1461 sizeof(struct ieee_types_header));
1462 bss_entry->ht_cap_offset = (u16) (current_ptr +
1463 sizeof(struct ieee_types_header) -
1464 bss_entry->beacon_buf);
1465 break;
1466 case WLAN_EID_HT_INFORMATION:
1467 bss_entry->bcn_ht_info = (struct ieee80211_ht_info *)
1468 (current_ptr +
1469 sizeof(struct ieee_types_header));
1470 bss_entry->ht_info_offset = (u16) (current_ptr +
1471 sizeof(struct ieee_types_header) -
1472 bss_entry->beacon_buf);
1473 break;
1474 case WLAN_EID_BSS_COEX_2040:
1475 bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr +
1476 sizeof(struct ieee_types_header));
1477 bss_entry->bss_co_2040_offset = (u16) (current_ptr +
1478 sizeof(struct ieee_types_header) -
1479 bss_entry->beacon_buf);
1480 break;
1481 case WLAN_EID_EXT_CAPABILITY:
1482 bss_entry->bcn_ext_cap = (u8 *) (current_ptr +
1483 sizeof(struct ieee_types_header));
1484 bss_entry->ext_cap_offset = (u16) (current_ptr +
1485 sizeof(struct ieee_types_header) -
1486 bss_entry->beacon_buf);
1487 break;
1488 case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
1489 bss_entry->bcn_obss_scan =
1490 (struct ieee_types_obss_scan_param *)
1491 current_ptr;
1492 bss_entry->overlap_bss_offset = (u16) (current_ptr -
1493 bss_entry->beacon_buf);
1494 break;
1495 default:
1496 break;
1497 }
1498
1499 current_ptr += element_len + 2;
1500
1501 /* Need to account for IE ID and IE Len */
1502 bytes_left_for_current_beacon -= (element_len + 2);
1503
1504 } /* while (bytes_left_for_current_beacon > 2) */
1505 return ret;
1506}
1507
1508/*
1509 * This function adjusts the pointers used in beacon buffers to reflect
1510 * shifts.
1511 *
1512 * The memory allocated for beacon buffers is of fixed sizes where all the
1513 * saved beacons must be stored. New beacons are added in the free portion
1514 * of this memory, space permitting; while duplicate beacon buffers are
1515 * placed at the same start location. However, since duplicate beacon
1516 * buffers may not match the size of the old one, all the following buffers
1517 * in the memory must be shifted to either make space, or to fill up freed
1518 * up space.
1519 *
1520 * This function is used to update the beacon buffer pointers that are past
1521 * an existing beacon buffer that is updated with a new one of different
1522 * size. The pointers are shifted by a fixed amount, either forward or
1523 * backward.
1524 *
1525 * the following pointers in every affected beacon buffers are changed, if
1526 * present -
1527 * - WPA IE pointer
1528 * - RSN IE pointer
1529 * - WAPI IE pointer
1530 * - HT capability IE pointer
1531 * - HT information IE pointer
1532 * - BSS coexistence 20/40 IE pointer
1533 * - Extended capability IE pointer
1534 * - Overlapping BSS scan parameter IE pointer
1535 */
1536static void
1537mwifiex_adjust_beacon_buffer_ptrs(struct mwifiex_private *priv, u8 advance,
1538 u8 *bcn_store, u32 rem_bcn_size,
1539 u32 num_of_ent)
1540{
1541 struct mwifiex_adapter *adapter = priv->adapter;
1542 u32 adj_idx;
1543 for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
1544 if (adapter->scan_table[adj_idx].beacon_buf > bcn_store) {
1545
1546 if (advance)
1547 adapter->scan_table[adj_idx].beacon_buf +=
1548 rem_bcn_size;
1549 else
1550 adapter->scan_table[adj_idx].beacon_buf -=
1551 rem_bcn_size;
1552
1553 if (adapter->scan_table[adj_idx].bcn_wpa_ie)
1554 adapter->scan_table[adj_idx].bcn_wpa_ie =
1555 (struct ieee_types_vendor_specific *)
1556 (adapter->scan_table[adj_idx].beacon_buf +
1557 adapter->scan_table[adj_idx].wpa_offset);
1558 if (adapter->scan_table[adj_idx].bcn_rsn_ie)
1559 adapter->scan_table[adj_idx].bcn_rsn_ie =
1560 (struct ieee_types_generic *)
1561 (adapter->scan_table[adj_idx].beacon_buf +
1562 adapter->scan_table[adj_idx].rsn_offset);
1563 if (adapter->scan_table[adj_idx].bcn_wapi_ie)
1564 adapter->scan_table[adj_idx].bcn_wapi_ie =
1565 (struct ieee_types_generic *)
1566 (adapter->scan_table[adj_idx].beacon_buf +
1567 adapter->scan_table[adj_idx].wapi_offset);
1568 if (adapter->scan_table[adj_idx].bcn_ht_cap)
1569 adapter->scan_table[adj_idx].bcn_ht_cap =
1570 (struct ieee80211_ht_cap *)
1571 (adapter->scan_table[adj_idx].beacon_buf +
1572 adapter->scan_table[adj_idx].ht_cap_offset);
1573
1574 if (adapter->scan_table[adj_idx].bcn_ht_info)
1575 adapter->scan_table[adj_idx].bcn_ht_info =
1576 (struct ieee80211_ht_info *)
1577 (adapter->scan_table[adj_idx].beacon_buf +
1578 adapter->scan_table[adj_idx].ht_info_offset);
1579 if (adapter->scan_table[adj_idx].bcn_bss_co_2040)
1580 adapter->scan_table[adj_idx].bcn_bss_co_2040 =
1581 (u8 *)
1582 (adapter->scan_table[adj_idx].beacon_buf +
1583 adapter->scan_table[adj_idx].bss_co_2040_offset);
1584 if (adapter->scan_table[adj_idx].bcn_ext_cap)
1585 adapter->scan_table[adj_idx].bcn_ext_cap =
1586 (u8 *)
1587 (adapter->scan_table[adj_idx].beacon_buf +
1588 adapter->scan_table[adj_idx].ext_cap_offset);
1589 if (adapter->scan_table[adj_idx].bcn_obss_scan)
1590 adapter->scan_table[adj_idx].bcn_obss_scan =
1591 (struct ieee_types_obss_scan_param *)
1592 (adapter->scan_table[adj_idx].beacon_buf +
1593 adapter->scan_table[adj_idx].overlap_bss_offset);
1594 }
1595 }
1596}
1597
1598/*
1599 * This function updates the pointers used in beacon buffer for given bss
1600 * descriptor to reflect shifts
1601 *
1602 * Following pointers are updated
1603 * - WPA IE pointer
1604 * - RSN IE pointer
1605 * - WAPI IE pointer
1606 * - HT capability IE pointer
1607 * - HT information IE pointer
1608 * - BSS coexistence 20/40 IE pointer
1609 * - Extended capability IE pointer
1610 * - Overlapping BSS scan parameter IE pointer
1611 */
1612static void
1613mwifiex_update_beacon_buffer_ptrs(struct mwifiex_bssdescriptor *beacon)
1614{
1615 if (beacon->bcn_wpa_ie)
1616 beacon->bcn_wpa_ie = (struct ieee_types_vendor_specific *)
1617 (beacon->beacon_buf + beacon->wpa_offset);
1618 if (beacon->bcn_rsn_ie)
1619 beacon->bcn_rsn_ie = (struct ieee_types_generic *)
1620 (beacon->beacon_buf + beacon->rsn_offset);
1621 if (beacon->bcn_wapi_ie)
1622 beacon->bcn_wapi_ie = (struct ieee_types_generic *)
1623 (beacon->beacon_buf + beacon->wapi_offset);
1624 if (beacon->bcn_ht_cap)
1625 beacon->bcn_ht_cap = (struct ieee80211_ht_cap *)
1626 (beacon->beacon_buf + beacon->ht_cap_offset);
1627 if (beacon->bcn_ht_info)
1628 beacon->bcn_ht_info = (struct ieee80211_ht_info *)
1629 (beacon->beacon_buf + beacon->ht_info_offset);
1630 if (beacon->bcn_bss_co_2040)
1631 beacon->bcn_bss_co_2040 = (u8 *) (beacon->beacon_buf +
1632 beacon->bss_co_2040_offset);
1633 if (beacon->bcn_ext_cap)
1634 beacon->bcn_ext_cap = (u8 *) (beacon->beacon_buf +
1635 beacon->ext_cap_offset);
1636 if (beacon->bcn_obss_scan)
1637 beacon->bcn_obss_scan = (struct ieee_types_obss_scan_param *)
1638 (beacon->beacon_buf + beacon->overlap_bss_offset);
1639}
1640
1641/*
1642 * This function stores a beacon or probe response for a BSS returned
1643 * in the scan.
1644 *
1645 * This stores a new scan response or an update for a previous scan response.
1646 * New entries need to verify that they do not exceed the total amount of
1647 * memory allocated for the table.
1648 *
1649 * Replacement entries need to take into consideration the amount of space
1650 * currently allocated for the beacon/probe response and adjust the entry
1651 * as needed.
1652 *
1653 * A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved
1654 * for an entry in case it is a beacon since a probe response for the
1655 * network will by larger per the standard. This helps to reduce the
1656 * amount of memory copying to fit a new probe response into an entry
1657 * already occupied by a network's previously stored beacon.
1658 */
1659static void
1660mwifiex_ret_802_11_scan_store_beacon(struct mwifiex_private *priv,
1661 u32 beacon_idx, u32 num_of_ent,
1662 struct mwifiex_bssdescriptor *new_beacon)
1663{
1664 struct mwifiex_adapter *adapter = priv->adapter;
1665 u8 *bcn_store;
1666 u32 new_bcn_size;
1667 u32 old_bcn_size;
1668 u32 bcn_space;
1669
1670 if (adapter->scan_table[beacon_idx].beacon_buf) {
1671
1672 new_bcn_size = new_beacon->beacon_buf_size;
1673 old_bcn_size = adapter->scan_table[beacon_idx].beacon_buf_size;
1674 bcn_space = adapter->scan_table[beacon_idx].beacon_buf_size_max;
1675 bcn_store = adapter->scan_table[beacon_idx].beacon_buf;
1676
1677 /* Set the max to be the same as current entry unless changed
1678 below */
1679 new_beacon->beacon_buf_size_max = bcn_space;
1680 if (new_bcn_size == old_bcn_size) {
1681 /*
1682 * Beacon is the same size as the previous entry.
1683 * Replace the previous contents with the scan result
1684 */
1685 memcpy(bcn_store, new_beacon->beacon_buf,
1686 new_beacon->beacon_buf_size);
1687
1688 } else if (new_bcn_size <= bcn_space) {
1689 /*
1690 * New beacon size will fit in the amount of space
1691 * we have previously allocated for it
1692 */
1693
1694 /* Copy the new beacon buffer entry over the old one */
1695 memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
1696
1697 /*
1698 * If the old beacon size was less than the maximum
1699 * we had alloted for the entry, and the new entry
1700 * is even smaller, reset the max size to the old
1701 * beacon entry and compress the storage space
1702 * (leaving a new pad space of (old_bcn_size -
1703 * new_bcn_size).
1704 */
1705 if (old_bcn_size < bcn_space
1706 && new_bcn_size <= old_bcn_size) {
1707 /*
1708 * Old Beacon size is smaller than the alloted
1709 * storage size. Shrink the alloted storage
1710 * space.
1711 */
1712 dev_dbg(adapter->dev, "info: AppControl:"
1713 " smaller duplicate beacon "
1714 "(%d), old = %d, new = %d, space = %d,"
1715 "left = %d\n",
1716 beacon_idx, old_bcn_size, new_bcn_size,
1717 bcn_space,
1718 (int)(sizeof(adapter->bcn_buf) -
1719 (adapter->bcn_buf_end -
1720 adapter->bcn_buf)));
1721
1722 /*
1723 * memmove (since the memory overlaps) the
1724 * data after the beacon we just stored to the
1725 * end of the current beacon. This cleans up
1726 * any unused space the old larger beacon was
1727 * using in the buffer
1728 */
1729 memmove(bcn_store + old_bcn_size,
1730 bcn_store + bcn_space,
1731 adapter->bcn_buf_end - (bcn_store +
1732 bcn_space));
1733
1734 /*
1735 * Decrement the end pointer by the difference
1736 * between the old larger size and the new
1737 * smaller size since we are using less space
1738 * due to the new beacon being smaller
1739 */
1740 adapter->bcn_buf_end -=
1741 (bcn_space - old_bcn_size);
1742
1743 /* Set the maximum storage size to the old
1744 beacon size */
1745 new_beacon->beacon_buf_size_max = old_bcn_size;
1746
1747 /* Adjust beacon buffer pointers that are past
1748 the current */
1749 mwifiex_adjust_beacon_buffer_ptrs(priv, 0,
1750 bcn_store, (bcn_space - old_bcn_size),
1751 num_of_ent);
1752 }
1753 } else if (adapter->bcn_buf_end + (new_bcn_size - bcn_space)
1754 < (adapter->bcn_buf + sizeof(adapter->bcn_buf))) {
1755 /*
1756 * Beacon is larger than space previously allocated
1757 * (bcn_space) and there is enough space left in the
1758 * beaconBuffer to store the additional data
1759 */
1760 dev_dbg(adapter->dev, "info: AppControl:"
1761 " larger duplicate beacon (%d), "
1762 "old = %d, new = %d, space = %d, left = %d\n",
1763 beacon_idx, old_bcn_size, new_bcn_size,
1764 bcn_space,
1765 (int)(sizeof(adapter->bcn_buf) -
1766 (adapter->bcn_buf_end -
1767 adapter->bcn_buf)));
1768
1769 /*
1770 * memmove (since the memory overlaps) the data
1771 * after the beacon we just stored to the end of
1772 * the current beacon. This moves the data for
1773 * the beacons after this further in memory to
1774 * make space for the new larger beacon we are
1775 * about to copy in.
1776 */
1777 memmove(bcn_store + new_bcn_size,
1778 bcn_store + bcn_space,
1779 adapter->bcn_buf_end - (bcn_store + bcn_space));
1780
1781 /* Copy the new beacon buffer entry over the old one */
1782 memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
1783
1784 /* Move the beacon end pointer by the amount of new
1785 beacon data we are adding */
1786 adapter->bcn_buf_end += (new_bcn_size - bcn_space);
1787
1788 /*
1789 * This entry is bigger than the alloted max space
1790 * previously reserved. Increase the max space to
1791 * be equal to the new beacon size
1792 */
1793 new_beacon->beacon_buf_size_max = new_bcn_size;
1794
1795 /* Adjust beacon buffer pointers that are past the
1796 current */
1797 mwifiex_adjust_beacon_buffer_ptrs(priv, 1, bcn_store,
1798 (new_bcn_size - bcn_space),
1799 num_of_ent);
1800 } else {
1801 /*
1802 * Beacon is larger than the previously allocated space,
1803 * but there is not enough free space to store the
1804 * additional data.
1805 */
1806 dev_err(adapter->dev, "AppControl: larger duplicate "
1807 " beacon (%d), old = %d new = %d, space = %d,"
1808 " left = %d\n", beacon_idx, old_bcn_size,
1809 new_bcn_size, bcn_space,
1810 (int)(sizeof(adapter->bcn_buf) -
1811 (adapter->bcn_buf_end - adapter->bcn_buf)));
1812
1813 /* Storage failure, keep old beacon intact */
1814 new_beacon->beacon_buf_size = old_bcn_size;
1815 if (new_beacon->bcn_wpa_ie)
1816 new_beacon->wpa_offset =
1817 adapter->scan_table[beacon_idx].
1818 wpa_offset;
1819 if (new_beacon->bcn_rsn_ie)
1820 new_beacon->rsn_offset =
1821 adapter->scan_table[beacon_idx].
1822 rsn_offset;
1823 if (new_beacon->bcn_wapi_ie)
1824 new_beacon->wapi_offset =
1825 adapter->scan_table[beacon_idx].
1826 wapi_offset;
1827 if (new_beacon->bcn_ht_cap)
1828 new_beacon->ht_cap_offset =
1829 adapter->scan_table[beacon_idx].
1830 ht_cap_offset;
1831 if (new_beacon->bcn_ht_info)
1832 new_beacon->ht_info_offset =
1833 adapter->scan_table[beacon_idx].
1834 ht_info_offset;
1835 if (new_beacon->bcn_bss_co_2040)
1836 new_beacon->bss_co_2040_offset =
1837 adapter->scan_table[beacon_idx].
1838 bss_co_2040_offset;
1839 if (new_beacon->bcn_ext_cap)
1840 new_beacon->ext_cap_offset =
1841 adapter->scan_table[beacon_idx].
1842 ext_cap_offset;
1843 if (new_beacon->bcn_obss_scan)
1844 new_beacon->overlap_bss_offset =
1845 adapter->scan_table[beacon_idx].
1846 overlap_bss_offset;
1847 }
1848 /* Point the new entry to its permanent storage space */
1849 new_beacon->beacon_buf = bcn_store;
1850 mwifiex_update_beacon_buffer_ptrs(new_beacon);
1851 } else {
1852 /*
1853 * No existing beacon data exists for this entry, check to see
1854 * if we can fit it in the remaining space
1855 */
1856 if (adapter->bcn_buf_end + new_beacon->beacon_buf_size +
1857 SCAN_BEACON_ENTRY_PAD < (adapter->bcn_buf +
1858 sizeof(adapter->bcn_buf))) {
1859
1860 /*
1861 * Copy the beacon buffer data from the local entry to
1862 * the adapter dev struct buffer space used to store
1863 * the raw beacon data for each entry in the scan table
1864 */
1865 memcpy(adapter->bcn_buf_end, new_beacon->beacon_buf,
1866 new_beacon->beacon_buf_size);
1867
1868 /* Update the beacon ptr to point to the table save
1869 area */
1870 new_beacon->beacon_buf = adapter->bcn_buf_end;
1871 new_beacon->beacon_buf_size_max =
1872 (new_beacon->beacon_buf_size +
1873 SCAN_BEACON_ENTRY_PAD);
1874
1875 mwifiex_update_beacon_buffer_ptrs(new_beacon);
1876
1877 /* Increment the end pointer by the size reserved */
1878 adapter->bcn_buf_end += new_beacon->beacon_buf_size_max;
1879
1880 dev_dbg(adapter->dev, "info: AppControl: beacon[%02d]"
1881 " sz=%03d, used = %04d, left = %04d\n",
1882 beacon_idx,
1883 new_beacon->beacon_buf_size,
1884 (int)(adapter->bcn_buf_end - adapter->bcn_buf),
1885 (int)(sizeof(adapter->bcn_buf) -
1886 (adapter->bcn_buf_end -
1887 adapter->bcn_buf)));
1888 } else {
1889 /* No space for new beacon */
1890 dev_dbg(adapter->dev, "info: AppControl: no space for"
1891 " beacon (%d): %pM sz=%03d, left=%03d\n",
1892 beacon_idx, new_beacon->mac_address,
1893 new_beacon->beacon_buf_size,
1894 (int)(sizeof(adapter->bcn_buf) -
1895 (adapter->bcn_buf_end -
1896 adapter->bcn_buf)));
1897
1898 /* Storage failure; clear storage records for this
1899 bcn */
1900 new_beacon->beacon_buf = NULL;
1901 new_beacon->beacon_buf_size = 0;
1902 new_beacon->beacon_buf_size_max = 0;
1903 new_beacon->bcn_wpa_ie = NULL;
1904 new_beacon->wpa_offset = 0;
1905 new_beacon->bcn_rsn_ie = NULL;
1906 new_beacon->rsn_offset = 0;
1907 new_beacon->bcn_wapi_ie = NULL;
1908 new_beacon->wapi_offset = 0;
1909 new_beacon->bcn_ht_cap = NULL;
1910 new_beacon->ht_cap_offset = 0;
1911 new_beacon->bcn_ht_info = NULL;
1912 new_beacon->ht_info_offset = 0;
1913 new_beacon->bcn_bss_co_2040 = NULL;
1914 new_beacon->bss_co_2040_offset = 0;
1915 new_beacon->bcn_ext_cap = NULL;
1916 new_beacon->ext_cap_offset = 0;
1917 new_beacon->bcn_obss_scan = NULL;
1918 new_beacon->overlap_bss_offset = 0;
1919 }
1920 }
1921}
1922
1923/*
1924 * This function restores a beacon buffer of the current BSS descriptor.
1925 */
1926static void mwifiex_restore_curr_bcn(struct mwifiex_private *priv)
1927{
1928 struct mwifiex_adapter *adapter = priv->adapter;
1929 struct mwifiex_bssdescriptor *curr_bss =
1930 &priv->curr_bss_params.bss_descriptor;
1931 unsigned long flags;
1932
1933 if (priv->curr_bcn_buf &&
1934 ((adapter->bcn_buf_end + priv->curr_bcn_size) <
1935 (adapter->bcn_buf + sizeof(adapter->bcn_buf)))) {
1936 spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
1937
1938 /* restore the current beacon buffer */
1939 memcpy(adapter->bcn_buf_end, priv->curr_bcn_buf,
1940 priv->curr_bcn_size);
1941 curr_bss->beacon_buf = adapter->bcn_buf_end;
1942 curr_bss->beacon_buf_size = priv->curr_bcn_size;
1943 adapter->bcn_buf_end += priv->curr_bcn_size;
1944
1945 /* adjust the pointers in the current BSS descriptor */
1946 if (curr_bss->bcn_wpa_ie)
1947 curr_bss->bcn_wpa_ie =
1948 (struct ieee_types_vendor_specific *)
1949 (curr_bss->beacon_buf +
1950 curr_bss->wpa_offset);
1951
1952 if (curr_bss->bcn_rsn_ie)
1953 curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
1954 (curr_bss->beacon_buf +
1955 curr_bss->rsn_offset);
1956
1957 if (curr_bss->bcn_ht_cap)
1958 curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
1959 (curr_bss->beacon_buf +
1960 curr_bss->ht_cap_offset);
1961
1962 if (curr_bss->bcn_ht_info)
1963 curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
1964 (curr_bss->beacon_buf +
1965 curr_bss->ht_info_offset);
1966
1967 if (curr_bss->bcn_bss_co_2040)
1968 curr_bss->bcn_bss_co_2040 =
1969 (u8 *) (curr_bss->beacon_buf +
1970 curr_bss->bss_co_2040_offset);
1971
1972 if (curr_bss->bcn_ext_cap)
1973 curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
1974 curr_bss->ext_cap_offset);
1975
1976 if (curr_bss->bcn_obss_scan)
1977 curr_bss->bcn_obss_scan =
1978 (struct ieee_types_obss_scan_param *)
1979 (curr_bss->beacon_buf +
1980 curr_bss->overlap_bss_offset);
1981
1982 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1983
1984 dev_dbg(adapter->dev, "info: current beacon restored %d\n",
1985 priv->curr_bcn_size);
1986 } else {
1987 dev_warn(adapter->dev,
1988 "curr_bcn_buf not saved or bcn_buf has no space\n");
1989 }
1990}
1991
1992/*
1993 * This function post processes the scan table after a new scan command has
1994 * completed.
1995 *
1996 * It inspects each entry of the scan table and tries to find an entry that
1997 * matches with our current associated/joined network from the scan. If
1998 * one is found, the stored copy of the BSS descriptor of our current network
1999 * is updated.
2000 *
2001 * It also debug dumps the current scan table contents after processing is over.
2002 */
2003static void
2004mwifiex_process_scan_results(struct mwifiex_private *priv)
2005{
2006 struct mwifiex_adapter *adapter = priv->adapter;
2007 s32 j;
2008 u32 i;
2009 unsigned long flags;
2010
2011 if (priv->media_connected) {
2012
2013 j = mwifiex_find_ssid_in_list(priv, &priv->curr_bss_params.
2014 bss_descriptor.ssid,
2015 priv->curr_bss_params.
2016 bss_descriptor.mac_address,
2017 priv->bss_mode);
2018
2019 if (j >= 0) {
2020 spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
2021 priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
2022 priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
2023 priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
2024 priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
2025 priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
2026 priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
2027 priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
2028 priv->curr_bss_params.bss_descriptor.ht_cap_offset =
2029 0;
2030 priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
2031 priv->curr_bss_params.bss_descriptor.ht_info_offset =
2032 0;
2033 priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
2034 NULL;
2035 priv->curr_bss_params.bss_descriptor.
2036 bss_co_2040_offset = 0;
2037 priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
2038 priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
2039 priv->curr_bss_params.bss_descriptor.
2040 bcn_obss_scan = NULL;
2041 priv->curr_bss_params.bss_descriptor.
2042 overlap_bss_offset = 0;
2043 priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
2044 priv->curr_bss_params.bss_descriptor.beacon_buf_size =
2045 0;
2046 priv->curr_bss_params.bss_descriptor.
2047 beacon_buf_size_max = 0;
2048
2049 dev_dbg(adapter->dev, "info: Found current ssid/bssid"
2050 " in list @ index #%d\n", j);
2051 /* Make a copy of current BSSID descriptor */
2052 memcpy(&priv->curr_bss_params.bss_descriptor,
2053 &adapter->scan_table[j],
2054 sizeof(priv->curr_bss_params.bss_descriptor));
2055
2056 mwifiex_save_curr_bcn(priv);
2057 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
2058
2059 } else {
2060 mwifiex_restore_curr_bcn(priv);
2061 }
2062 }
2063
2064 for (i = 0; i < adapter->num_in_scan_table; i++)
2065 dev_dbg(adapter->dev, "info: scan:(%02d) %pM "
2066 "RSSI[%03d], SSID[%s]\n",
2067 i, adapter->scan_table[i].mac_address,
2068 (s32) adapter->scan_table[i].rssi,
2069 adapter->scan_table[i].ssid.ssid);
2070}
2071
2072/*
2073 * This function converts radio type scan parameter to a band configuration
2074 * to be used in join command.
2075 */
2076static u8
2077mwifiex_radio_type_to_band(u8 radio_type)
2078{
2079 u8 ret_band;
2080
2081 switch (radio_type) {
2082 case HostCmd_SCAN_RADIO_TYPE_A:
2083 ret_band = BAND_A;
2084 break;
2085 case HostCmd_SCAN_RADIO_TYPE_BG:
2086 default:
2087 ret_band = BAND_G;
2088 break;
2089 }
2090
2091 return ret_band;
2092}
2093
2094/*
2095 * This function deletes a specific indexed entry from the scan table.
2096 *
2097 * This also compacts the remaining entries and adjusts any buffering
2098 * of beacon/probe response data if needed.
2099 */
2100static void
2101mwifiex_scan_delete_table_entry(struct mwifiex_private *priv, s32 table_idx)
2102{
2103 struct mwifiex_adapter *adapter = priv->adapter;
2104 u32 del_idx;
2105 u32 beacon_buf_adj;
2106 u8 *beacon_buf;
2107
2108 /*
2109 * Shift the saved beacon buffer data for the scan table back over the
2110 * entry being removed. Update the end of buffer pointer. Save the
2111 * deleted buffer allocation size for pointer adjustments for entries
2112 * compacted after the deleted index.
2113 */
2114 beacon_buf_adj = adapter->scan_table[table_idx].beacon_buf_size_max;
2115
2116 dev_dbg(adapter->dev, "info: Scan: Delete Entry %d, beacon buffer "
2117 "removal = %d bytes\n", table_idx, beacon_buf_adj);
2118
2119 /* Check if the table entry had storage allocated for its beacon */
2120 if (beacon_buf_adj) {
2121 beacon_buf = adapter->scan_table[table_idx].beacon_buf;
2122
2123 /*
2124 * Remove the entry's buffer space, decrement the table end
2125 * pointer by the amount we are removing
2126 */
2127 adapter->bcn_buf_end -= beacon_buf_adj;
2128
2129 dev_dbg(adapter->dev, "info: scan: delete entry %d,"
2130 " compact data: %p <- %p (sz = %d)\n",
2131 table_idx, beacon_buf,
2132 beacon_buf + beacon_buf_adj,
2133 (int)(adapter->bcn_buf_end - beacon_buf));
2134
2135 /*
2136 * Compact data storage. Copy all data after the deleted
2137 * entry's end address (beacon_buf + beacon_buf_adj) back
2138 * to the original start address (beacon_buf).
2139 *
2140 * Scan table entries affected by the move will have their
2141 * entry pointer adjusted below.
2142 *
2143 * Use memmove since the dest/src memory regions overlap.
2144 */
2145 memmove(beacon_buf, beacon_buf + beacon_buf_adj,
2146 adapter->bcn_buf_end - beacon_buf);
2147 }
2148
2149 dev_dbg(adapter->dev,
2150 "info: Scan: Delete Entry %d, num_in_scan_table = %d\n",
2151 table_idx, adapter->num_in_scan_table);
2152
2153 /* Shift all of the entries after the table_idx back by one, compacting
2154 the table and removing the requested entry */
2155 for (del_idx = table_idx; (del_idx + 1) < adapter->num_in_scan_table;
2156 del_idx++) {
2157 /* Copy the next entry over this one */
2158 memcpy(adapter->scan_table + del_idx,
2159 adapter->scan_table + del_idx + 1,
2160 sizeof(struct mwifiex_bssdescriptor));
2161
2162 /*
2163 * Adjust this entry's pointer to its beacon buffer based on
2164 * the removed/compacted entry from the deleted index. Don't
2165 * decrement if the buffer pointer is NULL (no data stored for
2166 * this entry).
2167 */
2168 if (adapter->scan_table[del_idx].beacon_buf) {
2169 adapter->scan_table[del_idx].beacon_buf -=
2170 beacon_buf_adj;
2171 if (adapter->scan_table[del_idx].bcn_wpa_ie)
2172 adapter->scan_table[del_idx].bcn_wpa_ie =
2173 (struct ieee_types_vendor_specific *)
2174 (adapter->scan_table[del_idx].
2175 beacon_buf +
2176 adapter->scan_table[del_idx].
2177 wpa_offset);
2178 if (adapter->scan_table[del_idx].bcn_rsn_ie)
2179 adapter->scan_table[del_idx].bcn_rsn_ie =
2180 (struct ieee_types_generic *)
2181 (adapter->scan_table[del_idx].
2182 beacon_buf +
2183 adapter->scan_table[del_idx].
2184 rsn_offset);
2185 if (adapter->scan_table[del_idx].bcn_wapi_ie)
2186 adapter->scan_table[del_idx].bcn_wapi_ie =
2187 (struct ieee_types_generic *)
2188 (adapter->scan_table[del_idx].beacon_buf
2189 + adapter->scan_table[del_idx].
2190 wapi_offset);
2191 if (adapter->scan_table[del_idx].bcn_ht_cap)
2192 adapter->scan_table[del_idx].bcn_ht_cap =
2193 (struct ieee80211_ht_cap *)
2194 (adapter->scan_table[del_idx].beacon_buf
2195 + adapter->scan_table[del_idx].
2196 ht_cap_offset);
2197
2198 if (adapter->scan_table[del_idx].bcn_ht_info)
2199 adapter->scan_table[del_idx].bcn_ht_info =
2200 (struct ieee80211_ht_info *)
2201 (adapter->scan_table[del_idx].beacon_buf
2202 + adapter->scan_table[del_idx].
2203 ht_info_offset);
2204 if (adapter->scan_table[del_idx].bcn_bss_co_2040)
2205 adapter->scan_table[del_idx].bcn_bss_co_2040 =
2206 (u8 *)
2207 (adapter->scan_table[del_idx].beacon_buf
2208 + adapter->scan_table[del_idx].
2209 bss_co_2040_offset);
2210 if (adapter->scan_table[del_idx].bcn_ext_cap)
2211 adapter->scan_table[del_idx].bcn_ext_cap =
2212 (u8 *)
2213 (adapter->scan_table[del_idx].beacon_buf
2214 + adapter->scan_table[del_idx].
2215 ext_cap_offset);
2216 if (adapter->scan_table[del_idx].bcn_obss_scan)
2217 adapter->scan_table[del_idx].
2218 bcn_obss_scan =
2219 (struct ieee_types_obss_scan_param *)
2220 (adapter->scan_table[del_idx].beacon_buf
2221 + adapter->scan_table[del_idx].
2222 overlap_bss_offset);
2223 }
2224 }
2225
2226 /* The last entry is invalid now that it has been deleted or moved
2227 back */
2228 memset(adapter->scan_table + adapter->num_in_scan_table - 1,
2229 0x00, sizeof(struct mwifiex_bssdescriptor));
2230
2231 adapter->num_in_scan_table--;
2232}
2233
2234/*
2235 * This function deletes all occurrences of a given SSID from the scan table.
2236 *
2237 * This iterates through the scan table and deletes all entries that match
2238 * the given SSID. It also compacts the remaining scan table entries.
2239 */
2240static int
2241mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv,
2242 struct mwifiex_802_11_ssid *del_ssid)
2243{
2244 int ret = -1;
2245 s32 table_idx;
2246
2247 dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n",
2248 del_ssid->ssid);
2249
2250 /* If the requested SSID is found in the table, delete it. Then keep
2251 searching the table for multiple entires for the SSID until no
2252 more are found */
2253 while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL,
2254 NL80211_IFTYPE_UNSPECIFIED)) >= 0) {
2255 dev_dbg(priv->adapter->dev,
2256 "info: Scan: Delete SSID Entry: Found Idx = %d\n",
2257 table_idx);
2258 ret = 0;
2259 mwifiex_scan_delete_table_entry(priv, table_idx);
2260 }
2261
2262 return ret;
2263}
2264
2265/*
2266 * This is an internal function used to start a scan based on an input
2267 * configuration.
2268 *
2269 * This uses the input user scan configuration information when provided in
2270 * order to send the appropriate scan commands to firmware to populate or
2271 * update the internal driver scan table.
2272 */
2273int mwifiex_scan_networks(struct mwifiex_private *priv,
2274 void *wait_buf, u16 action,
2275 const struct mwifiex_user_scan_cfg *user_scan_in,
2276 struct mwifiex_scan_resp *scan_resp)
2277{
2278 int ret = 0;
2279 struct mwifiex_adapter *adapter = priv->adapter;
2280 struct cmd_ctrl_node *cmd_node = NULL;
2281 union mwifiex_scan_cmd_config_tlv *scan_cfg_out = NULL;
2282 struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
2283 u32 buf_size;
2284 struct mwifiex_chan_scan_param_set *scan_chan_list;
2285 u8 keep_previous_scan;
2286 u8 filtered_scan;
2287 u8 scan_current_chan_only;
2288 u8 max_chan_per_scan;
2289 unsigned long flags;
2290
2291 if (action == HostCmd_ACT_GEN_GET) {
2292 if (scan_resp) {
2293 scan_resp->scan_table = (u8 *) adapter->scan_table;
2294 scan_resp->num_in_scan_table =
2295 adapter->num_in_scan_table;
2296 } else {
2297 ret = -1;
2298 }
2299 return ret;
2300 }
2301
2302 if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) {
2303 dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
2304 return ret;
2305 }
2306
2307 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
2308 adapter->scan_processing = true;
2309 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
2310
2311 if (priv->scan_block && action == HostCmd_ACT_GEN_SET) {
2312 dev_dbg(adapter->dev,
2313 "cmd: Scan is blocked during association...\n");
2314 return ret;
2315 }
2316
2317 scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
2318 GFP_KERNEL);
2319 if (!scan_cfg_out) {
2320 dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
2321 return -1;
2322 }
2323
2324 buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
2325 MWIFIEX_USER_SCAN_CHAN_MAX;
2326 scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
2327 if (!scan_chan_list) {
2328 dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
2329 kfree(scan_cfg_out);
2330 return -1;
2331 }
2332
2333 keep_previous_scan = false;
2334
2335 mwifiex_scan_setup_scan_config(priv, user_scan_in,
2336 &scan_cfg_out->config, &chan_list_out,
2337 scan_chan_list, &max_chan_per_scan,
2338 &filtered_scan, &scan_current_chan_only);
2339
2340 if (user_scan_in)
2341 keep_previous_scan = user_scan_in->keep_previous_scan;
2342
2343
2344 if (!keep_previous_scan) {
2345 memset(adapter->scan_table, 0x00,
2346 sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
2347 adapter->num_in_scan_table = 0;
2348 adapter->bcn_buf_end = adapter->bcn_buf;
2349 }
2350
2351 ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan,
2352 filtered_scan, &scan_cfg_out->config,
2353 chan_list_out, scan_chan_list);
2354
2355 /* Get scan command from scan_pending_q and put to cmd_pending_q */
2356 if (!ret) {
2357 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2358 if (!list_empty(&adapter->scan_pending_q)) {
2359 cmd_node = list_first_entry(&adapter->scan_pending_q,
2360 struct cmd_ctrl_node, list);
2361 list_del(&cmd_node->list);
2362 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
2363 flags);
2364 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
2365 true);
2366 } else {
2367 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
2368 flags);
2369 }
2370 ret = -EINPROGRESS;
2371 } else {
2372 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
2373 adapter->scan_processing = true;
2374 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
2375 }
2376
2377 kfree(scan_cfg_out);
2378 kfree(scan_chan_list);
2379 return ret;
2380}
2381
2382/*
2383 * This function prepares a scan command to be sent to the firmware.
2384 *
2385 * This uses the scan command configuration sent to the command processing
2386 * module in command preparation stage to configure a scan command structure
2387 * to send to firmware.
2388 *
2389 * The fixed fields specifying the BSS type and BSSID filters as well as a
2390 * variable number/length of TLVs are sent in the command to firmware.
2391 *
2392 * Preparation also includes -
2393 * - Setting command ID, and proper size
2394 * - Ensuring correct endian-ness
2395 */
2396int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv,
2397 struct host_cmd_ds_command *cmd, void *data_buf)
2398{
2399 struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
2400 struct mwifiex_scan_cmd_config *scan_cfg;
2401
2402 scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf;
2403
2404 /* Set fixed field variables in scan command */
2405 scan_cmd->bss_mode = scan_cfg->bss_mode;
2406 memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
2407 sizeof(scan_cmd->bssid));
2408 memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
2409
2410 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
2411
2412 /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
2413 cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
2414 + sizeof(scan_cmd->bssid)
2415 + scan_cfg->tlv_buf_len + S_DS_GEN));
2416
2417 return 0;
2418}
2419
2420/*
2421 * This function handles the command response of scan.
2422 *
2423 * The response buffer for the scan command has the following
2424 * memory layout:
2425 *
2426 * .-------------------------------------------------------------.
2427 * | Header (4 * sizeof(t_u16)): Standard command response hdr |
2428 * .-------------------------------------------------------------.
2429 * | BufSize (t_u16) : sizeof the BSS Description data |
2430 * .-------------------------------------------------------------.
2431 * | NumOfSet (t_u8) : Number of BSS Descs returned |
2432 * .-------------------------------------------------------------.
2433 * | BSSDescription data (variable, size given in BufSize) |
2434 * .-------------------------------------------------------------.
2435 * | TLV data (variable, size calculated using Header->Size, |
2436 * | BufSize and sizeof the fixed fields above) |
2437 * .-------------------------------------------------------------.
2438 */
2439int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2440 struct host_cmd_ds_command *resp, void *wq_buf)
2441{
2442 int ret = 0;
2443 struct mwifiex_adapter *adapter = priv->adapter;
2444 struct mwifiex_wait_queue *wait_queue = NULL;
2445 struct cmd_ctrl_node *cmd_node = NULL;
2446 struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL;
2447 struct mwifiex_bssdescriptor *bss_new_entry = NULL;
2448 struct mwifiex_ie_types_data *tlv_data;
2449 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
2450 u8 *bss_info;
2451 u32 scan_resp_size;
2452 u32 bytes_left;
2453 u32 num_in_table;
2454 u32 bss_idx;
2455 u32 idx;
2456 u32 tlv_buf_size;
2457 long long tsf_val;
2458 struct mwifiex_chan_freq_power *cfp;
2459 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
2460 struct chan_band_param_set *chan_band;
2461 u8 band;
2462 u8 is_bgscan_resp;
2463 unsigned long flags;
2464
2465 is_bgscan_resp = (le16_to_cpu(resp->command)
2466 == HostCmd_CMD_802_11_BG_SCAN_QUERY);
2467 if (is_bgscan_resp)
2468 scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
2469 else
2470 scan_rsp = &resp->params.scan_resp;
2471
2472
2473 if (scan_rsp->number_of_sets > IW_MAX_AP) {
2474 dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
2475 scan_rsp->number_of_sets);
2476 ret = -1;
2477 goto done;
2478 }
2479
2480 bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
2481 dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
2482 bytes_left);
2483
2484 scan_resp_size = le16_to_cpu(resp->size);
2485
2486 dev_dbg(adapter->dev,
2487 "info: SCAN_RESP: returned %d APs before parsing\n",
2488 scan_rsp->number_of_sets);
2489
2490 num_in_table = adapter->num_in_scan_table;
2491 bss_info = scan_rsp->bss_desc_and_tlv_buffer;
2492
2493 /*
2494 * The size of the TLV buffer is equal to the entire command response
2495 * size (scan_resp_size) minus the fixed fields (sizeof()'s), the
2496 * BSS Descriptions (bss_descript_size as bytesLef) and the command
2497 * response header (S_DS_GEN)
2498 */
2499 tlv_buf_size = scan_resp_size - (bytes_left
2500 + sizeof(scan_rsp->bss_descript_size)
2501 + sizeof(scan_rsp->number_of_sets)
2502 + S_DS_GEN);
2503
2504 tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
2505 bss_desc_and_tlv_buffer +
2506 bytes_left);
2507
2508 /* Search the TLV buffer space in the scan response for any valid
2509 TLVs */
2510 mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
2511 TLV_TYPE_TSFTIMESTAMP,
2512 (struct mwifiex_ie_types_data **)
2513 &tsf_tlv);
2514
2515 /* Search the TLV buffer space in the scan response for any valid
2516 TLVs */
2517 mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
2518 TLV_TYPE_CHANNELBANDLIST,
2519 (struct mwifiex_ie_types_data **)
2520 &chan_band_tlv);
2521
2522 /*
2523 * Process each scan response returned (scan_rsp->number_of_sets).
2524 * Save the information in the bss_new_entry and then insert into the
2525 * driver scan table either as an update to an existing entry
2526 * or as an addition at the end of the table
2527 */
2528 bss_new_entry = kzalloc(sizeof(struct mwifiex_bssdescriptor),
2529 GFP_KERNEL);
2530 if (!bss_new_entry) {
2531 dev_err(adapter->dev, " failed to alloc bss_new_entry\n");
2532 return -1;
2533 }
2534
2535 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
2536 /* Zero out the bss_new_entry we are about to store info in */
2537 memset(bss_new_entry, 0x00,
2538 sizeof(struct mwifiex_bssdescriptor));
2539
2540 if (mwifiex_interpret_bss_desc_with_ie(adapter, bss_new_entry,
2541 &bss_info,
2542 &bytes_left)) {
2543 /* Error parsing/interpreting scan response, skipped */
2544 dev_err(adapter->dev, "SCAN_RESP: "
2545 "mwifiex_interpret_bss_desc_with_ie "
2546 "returned ERROR\n");
2547 continue;
2548 }
2549
2550 /* Process the data fields and IEs returned for this BSS */
2551 dev_dbg(adapter->dev, "info: SCAN_RESP: BSSID = %pM\n",
2552 bss_new_entry->mac_address);
2553
2554 /* Search the scan table for the same bssid */
2555 for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) {
2556 if (memcmp(bss_new_entry->mac_address,
2557 adapter->scan_table[bss_idx].mac_address,
2558 sizeof(bss_new_entry->mac_address))) {
2559 continue;
2560 }
2561 /*
2562 * If the SSID matches as well, it is a
2563 * duplicate of this entry. Keep the bss_idx
2564 * set to this entry so we replace the old
2565 * contents in the table
2566 */
2567 if ((bss_new_entry->ssid.ssid_len
2568 == adapter->scan_table[bss_idx]. ssid.ssid_len)
2569 && (!memcmp(bss_new_entry->ssid.ssid,
2570 adapter->scan_table[bss_idx].ssid.ssid,
2571 bss_new_entry->ssid.ssid_len))) {
2572 dev_dbg(adapter->dev, "info: SCAN_RESP:"
2573 " duplicate of index: %d\n", bss_idx);
2574 break;
2575 }
2576 }
2577 /*
2578 * If the bss_idx is equal to the number of entries in
2579 * the table, the new entry was not a duplicate; append
2580 * it to the scan table
2581 */
2582 if (bss_idx == num_in_table) {
2583 /* Range check the bss_idx, keep it limited to
2584 the last entry */
2585 if (bss_idx == IW_MAX_AP)
2586 bss_idx--;
2587 else
2588 num_in_table++;
2589 }
2590
2591 /*
2592 * Save the beacon/probe response returned for later application
2593 * retrieval. Duplicate beacon/probe responses are updated if
2594 * possible
2595 */
2596 mwifiex_ret_802_11_scan_store_beacon(priv, bss_idx,
2597 num_in_table, bss_new_entry);
2598 /*
2599 * If the TSF TLV was appended to the scan results, save this
2600 * entry's TSF value in the networkTSF field.The networkTSF is
2601 * the firmware's TSF value at the time the beacon or probe
2602 * response was received.
2603 */
2604 if (tsf_tlv) {
2605 memcpy(&tsf_val, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE]
2606 , sizeof(tsf_val));
2607 memcpy(&bss_new_entry->network_tsf, &tsf_val,
2608 sizeof(bss_new_entry->network_tsf));
2609 }
2610 band = BAND_G;
2611 if (chan_band_tlv) {
2612 chan_band = &chan_band_tlv->chan_band_param[idx];
2613 band = mwifiex_radio_type_to_band(chan_band->radio_type
2614 & (BIT(0) | BIT(1)));
2615 }
2616
2617 /* Save the band designation for this entry for use in join */
2618 bss_new_entry->bss_band = band;
2619 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
2620 (u8) bss_new_entry->bss_band,
2621 (u16)bss_new_entry->channel);
2622
2623 if (cfp)
2624 bss_new_entry->freq = cfp->freq;
2625 else
2626 bss_new_entry->freq = 0;
2627
2628 /* Copy the locally created bss_new_entry to the scan table */
2629 memcpy(&adapter->scan_table[bss_idx], bss_new_entry,
2630 sizeof(adapter->scan_table[bss_idx]));
2631
2632 }
2633
2634 dev_dbg(adapter->dev,
2635 "info: SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
2636 scan_rsp->number_of_sets,
2637 num_in_table - adapter->num_in_scan_table, num_in_table);
2638
2639 /* Update the total number of BSSIDs in the scan table */
2640 adapter->num_in_scan_table = num_in_table;
2641
2642 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2643 if (list_empty(&adapter->scan_pending_q)) {
2644 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
2645 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
2646 adapter->scan_processing = false;
2647 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
2648 /*
2649 * Process the resulting scan table:
2650 * - Remove any bad ssids
2651 * - Update our current BSS information from scan data
2652 */
2653 mwifiex_process_scan_results(priv);
2654
2655 /* Need to indicate IOCTL complete */
2656 wait_queue = (struct mwifiex_wait_queue *) wq_buf;
2657 if (wait_queue) {
2658 wait_queue->status = MWIFIEX_ERROR_NO_ERROR;
2659
2660 /* Indicate ioctl complete */
2661 mwifiex_ioctl_complete(adapter,
2662 (struct mwifiex_wait_queue *) wait_queue, 0);
2663 }
2664 if (priv->report_scan_result)
2665 priv->report_scan_result = false;
2666 if (priv->scan_pending_on_block) {
2667 priv->scan_pending_on_block = false;
2668 up(&priv->async_sem);
2669 }
2670
2671 } else {
2672 /* Get scan command from scan_pending_q and put to
2673 cmd_pending_q */
2674 cmd_node = list_first_entry(&adapter->scan_pending_q,
2675 struct cmd_ctrl_node, list);
2676 list_del(&cmd_node->list);
2677 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
2678
2679 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
2680 }
2681
2682done:
2683 kfree((u8 *) bss_new_entry);
2684 return ret;
2685}
2686
2687/*
2688 * This function prepares command for background scan query.
2689 *
2690 * Preparation includes -
2691 * - Setting command ID and proper size
2692 * - Setting background scan flush parameter
2693 * - Ensuring correct endian-ness
2694 */
2695int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv,
2696 struct host_cmd_ds_command *cmd,
2697 void *data_buf)
2698{
2699 struct host_cmd_ds_802_11_bg_scan_query *bg_query =
2700 &cmd->params.bg_scan_query;
2701
2702 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
2703 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
2704 + S_DS_GEN);
2705
2706 bg_query->flush = 1;
2707
2708 return 0;
2709}
2710
2711/*
2712 * This function finds a SSID in the scan table.
2713 *
2714 * A BSSID may optionally be provided to qualify the SSID.
2715 * For non-Auto mode, further check is made to make sure the
2716 * BSS found in the scan table is compatible with the current
2717 * settings of the driver.
2718 */
2719s32
2720mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
2721 struct mwifiex_802_11_ssid *ssid, u8 *bssid,
2722 u32 mode)
2723{
2724 struct mwifiex_adapter *adapter = priv->adapter;
2725 s32 net = -1, j;
2726 u8 best_rssi = 0;
2727 u32 i;
2728
2729 dev_dbg(adapter->dev, "info: num of entries in table = %d\n",
2730 adapter->num_in_scan_table);
2731
2732 /*
2733 * Loop through the table until the maximum is reached or until a match
2734 * is found based on the bssid field comparison
2735 */
2736 for (i = 0;
2737 i < adapter->num_in_scan_table && (!bssid || (bssid && net < 0));
2738 i++) {
2739 if (!mwifiex_ssid_cmp(&adapter->scan_table[i].ssid, ssid) &&
2740 (!bssid
2741 || !memcmp(adapter->scan_table[i].mac_address, bssid,
2742 ETH_ALEN))
2743 &&
2744 (mwifiex_get_cfp_by_band_and_channel_from_cfg80211
2745 (priv, (u8) adapter->scan_table[i].bss_band,
2746 (u16) adapter->scan_table[i].channel))) {
2747 switch (mode) {
2748 case NL80211_IFTYPE_STATION:
2749 case NL80211_IFTYPE_ADHOC:
2750 j = mwifiex_is_network_compatible(priv, i,
2751 mode);
2752
2753 if (j >= 0) {
2754 if (SCAN_RSSI
2755 (adapter->scan_table[i].rssi) >
2756 best_rssi) {
2757 best_rssi = SCAN_RSSI(adapter->
2758 scan_table
2759 [i].rssi);
2760 net = i;
2761 }
2762 } else {
2763 if (net == -1)
2764 net = j;
2765 }
2766 break;
2767 case NL80211_IFTYPE_UNSPECIFIED:
2768 default:
2769 /*
2770 * Do not check compatibility if the mode
2771 * requested is Auto/Unknown. Allows generic
2772 * find to work without verifying against the
2773 * Adapter security settings
2774 */
2775 if (SCAN_RSSI(adapter->scan_table[i].rssi) >
2776 best_rssi) {
2777 best_rssi = SCAN_RSSI(adapter->
2778 scan_table[i].rssi);
2779 net = i;
2780 }
2781 break;
2782 }
2783 }
2784 }
2785
2786 return net;
2787}
2788
2789/*
2790 * This function finds a specific compatible BSSID in the scan list.
2791 *
2792 * This function loops through the scan table looking for a compatible
2793 * match. If a BSSID matches, but the BSS is found to be not compatible
2794 * the function ignores it and continues to search through the rest of
2795 * the entries in case there is an AP with multiple SSIDs assigned to
2796 * the same BSSID.
2797 */
2798s32
2799mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
2800 u32 mode)
2801{
2802 struct mwifiex_adapter *adapter = priv->adapter;
2803 s32 net = -1;
2804 u32 i;
2805
2806 if (!bssid)
2807 return -1;
2808
2809 dev_dbg(adapter->dev, "info: FindBSSID: Num of BSSIDs = %d\n",
2810 adapter->num_in_scan_table);
2811
2812 /*
2813 * Look through the scan table for a compatible match. The ret return
2814 * variable will be equal to the index in the scan table (greater
2815 * than zero) if the network is compatible. The loop will continue
2816 * past a matched bssid that is not compatible in case there is an
2817 * AP with multiple SSIDs assigned to the same BSSID
2818 */
2819 for (i = 0; net < 0 && i < adapter->num_in_scan_table; i++) {
2820 if (!memcmp
2821 (adapter->scan_table[i].mac_address, bssid, ETH_ALEN)
2822 && mwifiex_get_cfp_by_band_and_channel_from_cfg80211
2823 (priv,
2824 (u8) adapter->
2825 scan_table[i].
2826 bss_band,
2827 (u16) adapter->
2828 scan_table[i].
2829 channel)) {
2830 switch (mode) {
2831 case NL80211_IFTYPE_STATION:
2832 case NL80211_IFTYPE_ADHOC:
2833 net = mwifiex_is_network_compatible(priv, i,
2834 mode);
2835 break;
2836 default:
2837 net = i;
2838 break;
2839 }
2840 }
2841 }
2842
2843 return net;
2844}
2845
2846/*
2847 * This function inserts scan command node to the scan pending queue.
2848 */
2849void
2850mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
2851 struct cmd_ctrl_node *cmd_node)
2852{
2853 struct mwifiex_adapter *adapter = priv->adapter;
2854 unsigned long flags;
2855
2856 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2857 list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
2858 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
2859}
2860
2861/*
2862 * This function finds an AP with specific ssid in the scan list.
2863 */
2864int mwifiex_find_best_network(struct mwifiex_private *priv,
2865 struct mwifiex_ssid_bssid *req_ssid_bssid)
2866{
2867 struct mwifiex_adapter *adapter = priv->adapter;
2868 struct mwifiex_bssdescriptor *req_bss;
2869 s32 i;
2870
2871 memset(req_ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
2872
2873 i = mwifiex_find_best_network_in_list(priv);
2874
2875 if (i >= 0) {
2876 req_bss = &adapter->scan_table[i];
2877 memcpy(&req_ssid_bssid->ssid, &req_bss->ssid,
2878 sizeof(struct mwifiex_802_11_ssid));
2879 memcpy((u8 *) &req_ssid_bssid->bssid,
2880 (u8 *) &req_bss->mac_address, ETH_ALEN);
2881
2882 /* Make sure we are in the right mode */
2883 if (priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
2884 priv->bss_mode = req_bss->bss_mode;
2885 }
2886
2887 if (!req_ssid_bssid->ssid.ssid_len)
2888 return -1;
2889
2890 dev_dbg(adapter->dev, "info: Best network found = [%s], "
2891 "[%pM]\n", req_ssid_bssid->ssid.ssid,
2892 req_ssid_bssid->bssid);
2893
2894 return 0;
2895}
2896
2897/*
2898 * This function sends a scan command for all available channels to the
2899 * firmware, filtered on a specific SSID.
2900 */
2901static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2902 void *wait_buf, u16 action,
2903 struct mwifiex_802_11_ssid *req_ssid,
2904 struct mwifiex_scan_resp *scan_resp)
2905{
2906 struct mwifiex_adapter *adapter = priv->adapter;
2907 int ret = 0;
2908 struct mwifiex_user_scan_cfg *scan_cfg;
2909
2910 if (!req_ssid)
2911 return -1;
2912
2913 if (action == HostCmd_ACT_GEN_GET) {
2914 if (scan_resp) {
2915 scan_resp->scan_table =
2916 (u8 *) &priv->curr_bss_params.bss_descriptor;
2917 scan_resp->num_in_scan_table =
2918 adapter->num_in_scan_table;
2919 } else {
2920 ret = -1;
2921 }
2922 return ret;
2923 }
2924
2925 if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) {
2926 dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
2927 return ret;
2928 }
2929
2930 if (priv->scan_block && action == HostCmd_ACT_GEN_SET) {
2931 dev_dbg(adapter->dev,
2932 "cmd: Scan is blocked during association...\n");
2933 return ret;
2934 }
2935
2936 mwifiex_scan_delete_ssid_table_entry(priv, req_ssid);
2937
2938 scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
2939 if (!scan_cfg) {
2940 dev_err(adapter->dev, "failed to alloc scan_cfg\n");
2941 return -1;
2942 }
2943
2944 memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
2945 req_ssid->ssid_len);
2946 scan_cfg->keep_previous_scan = true;
2947
2948 ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL);
2949
2950 kfree(scan_cfg);
2951 return ret;
2952}
2953
2954/*
2955 * Sends IOCTL request to start a scan.
2956 *
2957 * This function allocates the IOCTL request buffer, fills it
2958 * with requisite parameters and calls the IOCTL handler.
2959 *
2960 * Scan command can be issued for both normal scan and specific SSID
2961 * scan, depending upon whether an SSID is provided or not.
2962 */
2963int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option,
2964 struct mwifiex_802_11_ssid *req_ssid)
2965{
2966 int ret = 0;
2967 struct mwifiex_wait_queue *wait = NULL;
2968 int status = 0;
2969
2970 if (down_interruptible(&priv->async_sem)) {
2971 dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
2972 __func__);
2973 return -1;
2974 }
2975 priv->scan_pending_on_block = true;
2976
2977 /* Allocate wait request buffer */
2978 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
2979 if (!wait) {
2980 ret = -1;
2981 goto done;
2982 }
2983
2984 if (req_ssid && req_ssid->ssid_len != 0)
2985 /* Specific SSID scan */
2986 status = mwifiex_scan_specific_ssid(priv, wait,
2987 HostCmd_ACT_GEN_SET,
2988 req_ssid, NULL);
2989 else
2990 /* Normal scan */
2991 status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET,
2992 NULL, NULL);
2993 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
2994 if (status == -1)
2995 ret = -1;
2996done:
2997 if ((wait) && (status != -EINPROGRESS))
2998 kfree(wait);
2999 if (ret == -1) {
3000 priv->scan_pending_on_block = false;
3001 up(&priv->async_sem);
3002 }
3003 return ret;
3004}
3005
3006/*
3007 * This function appends the vendor specific IE TLV to a buffer.
3008 */
3009int
3010mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
3011 u16 vsie_mask, u8 **buffer)
3012{
3013 int id, ret_len = 0;
3014 struct mwifiex_ie_types_vendor_param_set *vs_param_set;
3015
3016 if (!buffer)
3017 return 0;
3018 if (!(*buffer))
3019 return 0;
3020
3021 /*
3022 * Traverse through the saved vendor specific IE array and append
3023 * the selected(scan/assoc/adhoc) IE as TLV to the command
3024 */
3025 for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
3026 if (priv->vs_ie[id].mask & vsie_mask) {
3027 vs_param_set =
3028 (struct mwifiex_ie_types_vendor_param_set *)
3029 *buffer;
3030 vs_param_set->header.type =
3031 cpu_to_le16(TLV_TYPE_PASSTHROUGH);
3032 vs_param_set->header.len =
3033 cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
3034 & 0x00FF) + 2);
3035 memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
3036 le16_to_cpu(vs_param_set->header.len));
3037 *buffer += le16_to_cpu(vs_param_set->header.len) +
3038 sizeof(struct mwifiex_ie_types_header);
3039 ret_len += le16_to_cpu(vs_param_set->header.len) +
3040 sizeof(struct mwifiex_ie_types_header);
3041 }
3042 }
3043 return ret_len;
3044}
3045
3046/*
3047 * This function saves a beacon buffer of the current BSS descriptor.
3048 *
3049 * The current beacon buffer is saved so that it can be restored in the
3050 * following cases that makes the beacon buffer not to contain the current
3051 * ssid's beacon buffer.
3052 * - The current ssid was not found somehow in the last scan.
3053 * - The current ssid was the last entry of the scan table and overloaded.
3054 */
3055void
3056mwifiex_save_curr_bcn(struct mwifiex_private *priv)
3057{
3058 struct mwifiex_bssdescriptor *curr_bss =
3059 &priv->curr_bss_params.bss_descriptor;
3060
3061 /* save the beacon buffer if it is not saved or updated */
3062 if ((priv->curr_bcn_buf == NULL) ||
3063 (priv->curr_bcn_size != curr_bss->beacon_buf_size) ||
3064 (memcmp(priv->curr_bcn_buf, curr_bss->beacon_buf,
3065 curr_bss->beacon_buf_size))) {
3066
3067 kfree(priv->curr_bcn_buf);
3068 priv->curr_bcn_buf = NULL;
3069
3070 priv->curr_bcn_size = curr_bss->beacon_buf_size;
3071 if (!priv->curr_bcn_size)
3072 return;
3073
3074 priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size,
3075 GFP_KERNEL);
3076 if (!priv->curr_bcn_buf) {
3077 dev_err(priv->adapter->dev,
3078 "failed to alloc curr_bcn_buf\n");
3079 } else {
3080 memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
3081 curr_bss->beacon_buf_size);
3082 dev_dbg(priv->adapter->dev,
3083 "info: current beacon saved %d\n",
3084 priv->curr_bcn_size);
3085 }
3086 }
3087}
3088
3089/*
3090 * This function frees the current BSS descriptor beacon buffer.
3091 */
3092void
3093mwifiex_free_curr_bcn(struct mwifiex_private *priv)
3094{
3095 kfree(priv->curr_bcn_buf);
3096 priv->curr_bcn_buf = NULL;
3097}
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
new file mode 100644
index 000000000000..f21e5cd19839
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -0,0 +1,1770 @@
1/*
2 * Marvell Wireless LAN device driver: SDIO specific handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include <linux/firmware.h>
21
22#include "decl.h"
23#include "ioctl.h"
24#include "util.h"
25#include "fw.h"
26#include "main.h"
27#include "wmm.h"
28#include "11n.h"
29#include "sdio.h"
30
31
32#define SDIO_VERSION "1.0"
33
34static struct mwifiex_if_ops sdio_ops;
35
36static struct semaphore add_remove_card_sem;
37
38/*
39 * SDIO probe.
40 *
41 * This function probes an mwifiex device and registers it. It allocates
42 * the card structure, enables SDIO function number and initiates the
43 * device registration and initialization procedure by adding a logical
44 * interface.
45 */
46static int
47mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
48{
49 int ret = 0;
50 struct sdio_mmc_card *card = NULL;
51
52 pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
53 func->vendor, func->device, func->class, func->num);
54
55 card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
56 if (!card) {
57 pr_err("%s: failed to alloc memory\n", __func__);
58 return -ENOMEM;
59 }
60
61 card->func = func;
62
63 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
64
65 sdio_claim_host(func);
66 ret = sdio_enable_func(func);
67 sdio_release_host(func);
68
69 if (ret) {
70 pr_err("%s: failed to enable function\n", __func__);
71 return -EIO;
72 }
73
74 if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops)) {
75 pr_err("%s: add card failed\n", __func__);
76 kfree(card);
77 sdio_claim_host(func);
78 ret = sdio_disable_func(func);
79 sdio_release_host(func);
80 ret = -1;
81 }
82
83 return ret;
84}
85
86/*
87 * SDIO remove.
88 *
89 * This function removes the interface and frees up the card structure.
90 */
91static void
92mwifiex_sdio_remove(struct sdio_func *func)
93{
94 struct sdio_mmc_card *card;
95
96 pr_debug("info: SDIO func num=%d\n", func->num);
97
98 if (func) {
99 card = sdio_get_drvdata(func);
100 if (card) {
101 mwifiex_remove_card(card->adapter,
102 &add_remove_card_sem);
103 kfree(card);
104 }
105 }
106}
107
108/*
109 * SDIO suspend.
110 *
111 * Kernel needs to suspend all functions separately. Therefore all
112 * registered functions must have drivers with suspend and resume
113 * methods. Failing that the kernel simply removes the whole card.
114 *
115 * If already not suspended, this function allocates and sends a host
116 * sleep activate request to the firmware and turns off the traffic.
117 */
118static int mwifiex_sdio_suspend(struct device *dev)
119{
120 struct sdio_func *func = dev_to_sdio_func(dev);
121 struct sdio_mmc_card *card;
122 struct mwifiex_adapter *adapter = NULL;
123 mmc_pm_flag_t pm_flag = 0;
124 int hs_actived = 0;
125 int i;
126 int ret = 0;
127
128 if (func) {
129 pm_flag = sdio_get_host_pm_caps(func);
130 pr_debug("cmd: %s: suspend: PM flag = 0x%x\n",
131 sdio_func_id(func), pm_flag);
132 if (!(pm_flag & MMC_PM_KEEP_POWER)) {
133 pr_err("%s: cannot remain alive while host is"
134 " suspended\n", sdio_func_id(func));
135 return -ENOSYS;
136 }
137
138 card = sdio_get_drvdata(func);
139 if (!card || !card->adapter) {
140 pr_err("suspend: invalid card or adapter\n");
141 return 0;
142 }
143 } else {
144 pr_err("suspend: sdio_func is not specified\n");
145 return 0;
146 }
147
148 adapter = card->adapter;
149
150 /* Enable the Host Sleep */
151 hs_actived = mwifiex_enable_hs(adapter);
152 if (hs_actived) {
153 pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
154 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
155 }
156
157 /* Indicate device suspended */
158 adapter->is_suspended = true;
159
160 for (i = 0; i < adapter->priv_num; i++)
161 netif_carrier_off(adapter->priv[i]->netdev);
162
163 return ret;
164}
165
166/*
167 * SDIO resume.
168 *
169 * Kernel needs to suspend all functions separately. Therefore all
170 * registered functions must have drivers with suspend and resume
171 * methods. Failing that the kernel simply removes the whole card.
172 *
173 * If already not resumed, this function turns on the traffic and
174 * sends a host sleep cancel request to the firmware.
175 */
176static int mwifiex_sdio_resume(struct device *dev)
177{
178 struct sdio_func *func = dev_to_sdio_func(dev);
179 struct sdio_mmc_card *card;
180 struct mwifiex_adapter *adapter = NULL;
181 mmc_pm_flag_t pm_flag = 0;
182 int i;
183
184 if (func) {
185 pm_flag = sdio_get_host_pm_caps(func);
186 card = sdio_get_drvdata(func);
187 if (!card || !card->adapter) {
188 pr_err("resume: invalid card or adapter\n");
189 return 0;
190 }
191 } else {
192 pr_err("resume: sdio_func is not specified\n");
193 return 0;
194 }
195
196 adapter = card->adapter;
197
198 if (!adapter->is_suspended) {
199 dev_warn(adapter->dev, "device already resumed\n");
200 return 0;
201 }
202
203 adapter->is_suspended = false;
204
205 for (i = 0; i < adapter->priv_num; i++)
206 if (adapter->priv[i]->media_connected)
207 netif_carrier_on(adapter->priv[i]->netdev);
208
209 /* Disable Host Sleep */
210 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
211 MWIFIEX_NO_WAIT);
212
213 return 0;
214}
215
216/* Device ID for SD8787 */
217#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119)
218
219/* WLAN IDs */
220static const struct sdio_device_id mwifiex_ids[] = {
221 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)},
222 {},
223};
224
225MODULE_DEVICE_TABLE(sdio, mwifiex_ids);
226
227static const struct dev_pm_ops mwifiex_sdio_pm_ops = {
228 .suspend = mwifiex_sdio_suspend,
229 .resume = mwifiex_sdio_resume,
230};
231
232static struct sdio_driver mwifiex_sdio = {
233 .name = "mwifiex_sdio",
234 .id_table = mwifiex_ids,
235 .probe = mwifiex_sdio_probe,
236 .remove = mwifiex_sdio_remove,
237 .drv = {
238 .owner = THIS_MODULE,
239 .pm = &mwifiex_sdio_pm_ops,
240 }
241};
242
243/*
244 * This function writes data into SDIO card register.
245 */
246static int
247mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
248{
249 struct sdio_mmc_card *card = adapter->card;
250 int ret = -1;
251
252 sdio_claim_host(card->func);
253 sdio_writeb(card->func, (u8) data, reg, &ret);
254 sdio_release_host(card->func);
255
256 return ret;
257}
258
259/*
260 * This function reads data from SDIO card register.
261 */
262static int
263mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
264{
265 struct sdio_mmc_card *card = adapter->card;
266 int ret = -1;
267 u8 val;
268
269 sdio_claim_host(card->func);
270 val = sdio_readb(card->func, reg, &ret);
271 sdio_release_host(card->func);
272
273 *data = val;
274
275 return ret;
276}
277
278/*
279 * This function writes multiple data into SDIO card memory.
280 *
281 * This does not work in suspended mode.
282 */
283static int
284mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
285 u8 *buffer, u32 pkt_len, u32 port, u32 timeout)
286{
287 struct sdio_mmc_card *card = adapter->card;
288 int ret = -1;
289 u8 blk_mode =
290 (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
291 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
292 u32 blk_cnt =
293 (blk_mode ==
294 BLOCK_MODE) ? (pkt_len /
295 MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len;
296 u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
297
298 if (adapter->is_suspended) {
299 dev_err(adapter->dev,
300 "%s: not allowed while suspended\n", __func__);
301 return -1;
302 }
303
304 sdio_claim_host(card->func);
305
306 if (!sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size))
307 ret = 0;
308
309 sdio_release_host(card->func);
310
311 return ret;
312}
313
314/*
315 * This function reads multiple data from SDIO card memory.
316 */
317static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter,
318 u8 *buffer, u32 len,
319 u32 port, u32 timeout, u8 claim)
320{
321 struct sdio_mmc_card *card = adapter->card;
322 int ret = -1;
323 u8 blk_mode =
324 (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
325 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
326 u32 blk_cnt =
327 (blk_mode ==
328 BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len;
329 u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
330
331 if (claim)
332 sdio_claim_host(card->func);
333
334 if (!sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size))
335 ret = 0;
336
337 if (claim)
338 sdio_release_host(card->func);
339
340 return ret;
341}
342
343/*
344 * This function wakes up the card.
345 *
346 * A host power up command is written to the card configuration
347 * register to wake up the card.
348 */
349static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
350{
351 int ret;
352
353 dev_dbg(adapter->dev, "event: wakeup device...\n");
354 ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP);
355
356 return ret;
357}
358
359/*
360 * This function is called after the card has woken up.
361 *
362 * The card configuration register is reset.
363 */
364static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
365{
366 int ret;
367
368 dev_dbg(adapter->dev, "cmd: wakeup device completed\n");
369 ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, 0);
370
371 return ret;
372}
373
374/*
375 * This function initializes the IO ports.
376 *
377 * The following operations are performed -
378 * - Read the IO ports (0, 1 and 2)
379 * - Set host interrupt Reset-To-Read to clear
380 * - Set auto re-enable interrupt
381 */
382static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
383{
384 u32 reg;
385
386 adapter->ioport = 0;
387
388 /* Read the IO port */
389 if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg))
390 adapter->ioport |= (reg & 0xff);
391 else
392 return -1;
393
394 if (!mwifiex_read_reg(adapter, IO_PORT_1_REG, &reg))
395 adapter->ioport |= ((reg & 0xff) << 8);
396 else
397 return -1;
398
399 if (!mwifiex_read_reg(adapter, IO_PORT_2_REG, &reg))
400 adapter->ioport |= ((reg & 0xff) << 16);
401 else
402 return -1;
403
404 pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
405
406 /* Set Host interrupt reset to read to clear */
407 if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg))
408 mwifiex_write_reg(adapter, HOST_INT_RSR_REG,
409 reg | SDIO_INT_MASK);
410 else
411 return -1;
412
413 /* Dnld/Upld ready set to auto reset */
414 if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, &reg))
415 mwifiex_write_reg(adapter, CARD_MISC_CFG_REG,
416 reg | AUTO_RE_ENABLE_INT);
417 else
418 return -1;
419
420 return 0;
421}
422
423/*
424 * This function sends data to the card.
425 */
426static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
427 u8 *payload, u32 pkt_len, u32 port)
428{
429 u32 i = 0;
430 int ret = 0;
431
432 do {
433 ret = mwifiex_write_data_sync(adapter, payload, pkt_len,
434 port, 0);
435 if (ret) {
436 i++;
437 dev_err(adapter->dev, "host_to_card, write iomem"
438 " (%d) failed: %d\n", i, ret);
439 if (mwifiex_write_reg(adapter,
440 CONFIGURATION_REG, 0x04))
441 dev_err(adapter->dev, "write CFG reg failed\n");
442
443 ret = -1;
444 if (i > MAX_WRITE_IOMEM_RETRY)
445 return ret;
446 }
447 } while (ret == -1);
448
449 return ret;
450}
451
452/*
453 * This function gets the read port.
454 *
455 * If control port bit is set in MP read bitmap, the control port
456 * is returned, otherwise the current read port is returned and
457 * the value is increased (provided it does not reach the maximum
458 * limit, in which case it is reset to 1)
459 */
460static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
461{
462 struct sdio_mmc_card *card = adapter->card;
463 u16 rd_bitmap = card->mp_rd_bitmap;
464
465 dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap);
466
467 if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
468 return -1;
469
470 if (card->mp_rd_bitmap & CTRL_PORT_MASK) {
471 card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
472 *port = CTRL_PORT;
473 dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
474 *port, card->mp_rd_bitmap);
475 } else {
476 if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
477 card->mp_rd_bitmap &=
478 (u16) (~(1 << card->curr_rd_port));
479 *port = card->curr_rd_port;
480
481 if (++card->curr_rd_port == MAX_PORT)
482 card->curr_rd_port = 1;
483 } else {
484 return -1;
485 }
486
487 dev_dbg(adapter->dev,
488 "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
489 *port, rd_bitmap, card->mp_rd_bitmap);
490 }
491 return 0;
492}
493
494/*
495 * This function gets the write port for data.
496 *
497 * The current write port is returned if available and the value is
498 * increased (provided it does not reach the maximum limit, in which
499 * case it is reset to 1)
500 */
501static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
502{
503 struct sdio_mmc_card *card = adapter->card;
504 u16 wr_bitmap = card->mp_wr_bitmap;
505
506 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap);
507
508 if (!(wr_bitmap & card->mp_data_port_mask))
509 return -1;
510
511 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
512 card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port));
513 *port = card->curr_wr_port;
514 if (++card->curr_wr_port == card->mp_end_port)
515 card->curr_wr_port = 1;
516 } else {
517 adapter->data_sent = true;
518 return -EBUSY;
519 }
520
521 if (*port == CTRL_PORT) {
522 dev_err(adapter->dev, "invalid data port=%d cur port=%d"
523 " mp_wr_bitmap=0x%04x -> 0x%04x\n",
524 *port, card->curr_wr_port, wr_bitmap,
525 card->mp_wr_bitmap);
526 return -1;
527 }
528
529 dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
530 *port, wr_bitmap, card->mp_wr_bitmap);
531
532 return 0;
533}
534
535/*
536 * This function polls the card status.
537 */
538static int
539mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
540{
541 u32 tries;
542 u32 cs = 0;
543
544 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
545 if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs))
546 break;
547 else if ((cs & bits) == bits)
548 return 0;
549
550 udelay(10);
551 }
552
553 dev_err(adapter->dev, "poll card status failed, tries = %d\n",
554 tries);
555 return -1;
556}
557
558/*
559 * This function reads the firmware status.
560 */
561static int
562mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
563{
564 u32 fws0 = 0, fws1 = 0;
565
566 if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0))
567 return -1;
568
569 if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1))
570 return -1;
571
572 *dat = (u16) ((fws1 << 8) | fws0);
573
574 return 0;
575}
576
577/*
578 * This function disables the host interrupt.
579 *
580 * The host interrupt mask is read, the disable bit is reset and
581 * written back to the card host interrupt mask register.
582 */
583static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
584{
585 u32 host_int_mask = 0;
586
587 /* Read back the host_int_mask register */
588 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
589 return -1;
590
591 /* Update with the mask and write back to the register */
592 host_int_mask &= ~HOST_INT_DISABLE;
593
594 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
595 dev_err(adapter->dev, "disable host interrupt failed\n");
596 return -1;
597 }
598
599 return 0;
600}
601
602/*
603 * This function enables the host interrupt.
604 *
605 * The host interrupt enable mask is written to the card
606 * host interrupt mask register.
607 */
608static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
609{
610 /* Simply write the mask to the register */
611 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) {
612 dev_err(adapter->dev, "enable host interrupt failed\n");
613 return -1;
614 }
615 return 0;
616}
617
618/*
619 * This function sends a data buffer to the card.
620 */
621static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
622 u32 *type, u8 *buffer,
623 u32 npayload, u32 ioport)
624{
625 int ret = 0;
626 u32 nb;
627
628 if (!buffer) {
629 dev_err(adapter->dev, "%s: buffer is NULL\n", __func__);
630 return -1;
631 }
632
633 ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1);
634
635 if (ret) {
636 dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__,
637 ret);
638 return -1;
639 }
640
641 nb = le16_to_cpu(*(__le16 *) (buffer));
642 if (nb > npayload) {
643 dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n",
644 __func__, nb, npayload);
645 return -1;
646 }
647
648 *type = le16_to_cpu(*(__le16 *) (buffer + 2));
649
650 return ret;
651}
652
653/*
654 * This function downloads the firmware to the card.
655 *
656 * Firmware is downloaded to the card in blocks. Every block download
657 * is tested for CRC errors, and retried a number of times before
658 * returning failure.
659 */
660static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
661 struct mwifiex_fw_image *fw)
662{
663 int ret = 0;
664 u8 *firmware = fw->fw_buf;
665 u32 firmware_len = fw->fw_len;
666 u32 offset = 0;
667 u32 base0, base1;
668 u8 *fwbuf;
669 u16 len = 0;
670 u32 txlen = 0, tx_blocks = 0, tries = 0;
671 u32 i = 0;
672
673 if (!firmware_len) {
674 dev_err(adapter->dev, "firmware image not found!"
675 " Terminating download\n");
676 return -1;
677 }
678
679 dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n",
680 firmware_len);
681
682 /* Assume that the allocated buffer is 8-byte aligned */
683 fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL);
684 if (!fwbuf) {
685 dev_err(adapter->dev, "unable to alloc buffer for firmware."
686 " Terminating download\n");
687 return -1;
688 }
689
690 /* Perform firmware data transfer */
691 do {
692 /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY
693 bits */
694 ret = mwifiex_sdio_poll_card_status(adapter, CARD_IO_READY |
695 DN_LD_CARD_RDY);
696 if (ret) {
697 dev_err(adapter->dev, "FW download with helper:"
698 " poll status timeout @ %d\n", offset);
699 goto done;
700 }
701
702 /* More data? */
703 if (offset >= firmware_len)
704 break;
705
706 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
707 ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0,
708 &base0);
709 if (ret) {
710 dev_err(adapter->dev, "dev BASE0 register read"
711 " failed: base0=0x%04X(%d). Terminating "
712 "download\n", base0, base0);
713 goto done;
714 }
715 ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1,
716 &base1);
717 if (ret) {
718 dev_err(adapter->dev, "dev BASE1 register read"
719 " failed: base1=0x%04X(%d). Terminating "
720 "download\n", base1, base1);
721 goto done;
722 }
723 len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff));
724
725 if (len)
726 break;
727
728 udelay(10);
729 }
730
731 if (!len) {
732 break;
733 } else if (len > MWIFIEX_UPLD_SIZE) {
734 dev_err(adapter->dev, "FW download failed @ %d,"
735 " invalid length %d\n", offset, len);
736 ret = -1;
737 goto done;
738 }
739
740 txlen = len;
741
742 if (len & BIT(0)) {
743 i++;
744 if (i > MAX_WRITE_IOMEM_RETRY) {
745 dev_err(adapter->dev, "FW download failed @"
746 " %d, over max retry count\n", offset);
747 ret = -1;
748 goto done;
749 }
750 dev_err(adapter->dev, "CRC indicated by the helper:"
751 " len = 0x%04X, txlen = %d\n", len, txlen);
752 len &= ~BIT(0);
753 /* Setting this to 0 to resend from same offset */
754 txlen = 0;
755 } else {
756 i = 0;
757
758 /* Set blocksize to transfer - checking for last
759 block */
760 if (firmware_len - offset < txlen)
761 txlen = firmware_len - offset;
762
763 tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE -
764 1) / MWIFIEX_SDIO_BLOCK_SIZE;
765
766 /* Copy payload to buffer */
767 memmove(fwbuf, &firmware[offset], txlen);
768 }
769
770 ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks *
771 MWIFIEX_SDIO_BLOCK_SIZE,
772 adapter->ioport, 0);
773 if (ret) {
774 dev_err(adapter->dev, "FW download, write iomem (%d)"
775 " failed @ %d\n", i, offset);
776 if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
777 dev_err(adapter->dev, "write CFG reg failed\n");
778
779 ret = -1;
780 goto done;
781 }
782
783 offset += txlen;
784 } while (true);
785
786 dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n",
787 offset);
788
789 ret = 0;
790done:
791 kfree(fwbuf);
792 return ret;
793}
794
795/*
796 * This function checks the firmware status in card.
797 *
798 * The winner interface is also determined by this function.
799 */
800static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
801 u32 poll_num, int *winner)
802{
803 int ret = 0;
804 u16 firmware_stat;
805 u32 tries;
806 u32 winner_status;
807
808 /* Wait for firmware initialization event */
809 for (tries = 0; tries < poll_num; tries++) {
810 ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
811 if (ret)
812 continue;
813 if (firmware_stat == FIRMWARE_READY) {
814 ret = 0;
815 break;
816 } else {
817 mdelay(100);
818 ret = -1;
819 }
820 }
821
822 if (winner && ret) {
823 if (mwifiex_read_reg
824 (adapter, CARD_FW_STATUS0_REG, &winner_status))
825 winner_status = 0;
826
827 if (winner_status)
828 *winner = 0;
829 else
830 *winner = 1;
831 }
832 return ret;
833}
834
835/*
836 * This function reads the interrupt status from card.
837 */
838static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
839{
840 struct sdio_mmc_card *card = adapter->card;
841 u32 sdio_ireg = 0;
842 unsigned long flags;
843
844 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS,
845 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0,
846 0)) {
847 dev_err(adapter->dev, "read mp_regs failed\n");
848 return;
849 }
850
851 sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
852 if (sdio_ireg) {
853 /*
854 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
855 * Clear the interrupt status register
856 */
857 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
858 spin_lock_irqsave(&adapter->int_lock, flags);
859 adapter->int_status |= sdio_ireg;
860 spin_unlock_irqrestore(&adapter->int_lock, flags);
861 }
862
863 return;
864}
865
866/*
867 * SDIO interrupt handler.
868 *
869 * This function reads the interrupt status from firmware and assigns
870 * the main process in workqueue which will handle the interrupt.
871 */
872static void
873mwifiex_sdio_interrupt(struct sdio_func *func)
874{
875 struct mwifiex_adapter *adapter;
876 struct sdio_mmc_card *card;
877
878 card = sdio_get_drvdata(func);
879 if (!card || !card->adapter) {
880 pr_debug("int: func=%p card=%p adapter=%p\n",
881 func, card, card ? card->adapter : NULL);
882 return;
883 }
884 adapter = card->adapter;
885
886 if (adapter->surprise_removed)
887 return;
888
889 if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
890 adapter->ps_state = PS_STATE_AWAKE;
891
892 mwifiex_interrupt_status(adapter);
893 queue_work(adapter->workqueue, &adapter->main_work);
894
895 return;
896}
897
898/*
899 * This function decodes a received packet.
900 *
901 * Based on the type, the packet is treated as either a data, or
902 * a command response, or an event, and the correct handler
903 * function is invoked.
904 */
905static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
906 struct sk_buff *skb, u32 upld_typ)
907{
908 u8 *cmd_buf;
909
910 skb_pull(skb, INTF_HEADER_LEN);
911
912 switch (upld_typ) {
913 case MWIFIEX_TYPE_DATA:
914 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
915 mwifiex_handle_rx_packet(adapter, skb);
916 break;
917
918 case MWIFIEX_TYPE_CMD:
919 dev_dbg(adapter->dev, "info: --- Rx: Cmd Response ---\n");
920 /* take care of curr_cmd = NULL case */
921 if (!adapter->curr_cmd) {
922 cmd_buf = adapter->upld_buf;
923
924 if (adapter->ps_state == PS_STATE_SLEEP_CFM)
925 mwifiex_process_sleep_confirm_resp(adapter,
926 skb->data, skb->len);
927
928 memcpy(cmd_buf, skb->data, min_t(u32,
929 MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
930
931 dev_kfree_skb_any(skb);
932 } else {
933 adapter->cmd_resp_received = true;
934 adapter->curr_cmd->resp_skb = skb;
935 }
936 break;
937
938 case MWIFIEX_TYPE_EVENT:
939 dev_dbg(adapter->dev, "info: --- Rx: Event ---\n");
940 adapter->event_cause = *(u32 *) skb->data;
941
942 skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN);
943
944 if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE))
945 memcpy(adapter->event_body, skb->data, skb->len);
946
947 /* event cause has been saved to adapter->event_cause */
948 adapter->event_received = true;
949 adapter->event_skb = skb;
950
951 break;
952
953 default:
954 dev_err(adapter->dev, "unknown upload type %#x\n", upld_typ);
955 dev_kfree_skb_any(skb);
956 break;
957 }
958
959 return 0;
960}
961
962/*
963 * This function transfers received packets from card to driver, performing
964 * aggregation if required.
965 *
966 * For data received on control port, or if aggregation is disabled, the
967 * received buffers are uploaded as separate packets. However, if aggregation
968 * is enabled and required, the buffers are copied onto an aggregation buffer,
969 * provided there is space left, processed and finally uploaded.
970 */
971static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
972 struct sk_buff *skb, u8 port)
973{
974 struct sdio_mmc_card *card = adapter->card;
975 s32 f_do_rx_aggr = 0;
976 s32 f_do_rx_cur = 0;
977 s32 f_aggr_cur = 0;
978 struct sk_buff *skb_deaggr;
979 u32 pind = 0;
980 u32 pkt_len, pkt_type = 0;
981 u8 *curr_ptr;
982 u32 rx_len = skb->len;
983
984 if (port == CTRL_PORT) {
985 /* Read the command Resp without aggr */
986 dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
987 "response\n", __func__);
988
989 f_do_rx_cur = 1;
990 goto rx_curr_single;
991 }
992
993 if (!card->mpa_rx.enabled) {
994 dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n",
995 __func__);
996
997 f_do_rx_cur = 1;
998 goto rx_curr_single;
999 }
1000
1001 if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) {
1002 /* Some more data RX pending */
1003 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
1004
1005 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1006 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) {
1007 f_aggr_cur = 1;
1008 } else {
1009 /* No room in Aggr buf, do rx aggr now */
1010 f_do_rx_aggr = 1;
1011 f_do_rx_cur = 1;
1012 }
1013 } else {
1014 /* Rx aggr not in progress */
1015 f_aggr_cur = 1;
1016 }
1017
1018 } else {
1019 /* No more data RX pending */
1020 dev_dbg(adapter->dev, "info: %s: last packet\n", __func__);
1021
1022 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1023 f_do_rx_aggr = 1;
1024 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len))
1025 f_aggr_cur = 1;
1026 else
1027 /* No room in Aggr buf, do rx aggr now */
1028 f_do_rx_cur = 1;
1029 } else {
1030 f_do_rx_cur = 1;
1031 }
1032 }
1033
1034 if (f_aggr_cur) {
1035 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1036 /* Curr pkt can be aggregated */
1037 MP_RX_AGGR_SETUP(card, skb, port);
1038
1039 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
1040 MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
1041 dev_dbg(adapter->dev, "info: %s: aggregated packet "
1042 "limit reached\n", __func__);
1043 /* No more pkts allowed in Aggr buf, rx it */
1044 f_do_rx_aggr = 1;
1045 }
1046 }
1047
1048 if (f_do_rx_aggr) {
1049 /* do aggr RX now */
1050 dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
1051 card->mpa_rx.pkt_cnt);
1052
1053 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
1054 card->mpa_rx.buf_len,
1055 (adapter->ioport | 0x1000 |
1056 (card->mpa_rx.ports << 4)) +
1057 card->mpa_rx.start_port, 0, 1))
1058 return -1;
1059
1060 curr_ptr = card->mpa_rx.buf;
1061
1062 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1063
1064 /* get curr PKT len & type */
1065 pkt_len = *(u16 *) &curr_ptr[0];
1066 pkt_type = *(u16 *) &curr_ptr[2];
1067
1068 /* copy pkt to deaggr buf */
1069 skb_deaggr = card->mpa_rx.skb_arr[pind];
1070
1071 if ((pkt_type == MWIFIEX_TYPE_DATA) && (pkt_len <=
1072 card->mpa_rx.len_arr[pind])) {
1073
1074 memcpy(skb_deaggr->data, curr_ptr, pkt_len);
1075
1076 skb_trim(skb_deaggr, pkt_len);
1077
1078 /* Process de-aggr packet */
1079 mwifiex_decode_rx_packet(adapter, skb_deaggr,
1080 pkt_type);
1081 } else {
1082 dev_err(adapter->dev, "wrong aggr pkt:"
1083 " type=%d len=%d max_len=%d\n",
1084 pkt_type, pkt_len,
1085 card->mpa_rx.len_arr[pind]);
1086 dev_kfree_skb_any(skb_deaggr);
1087 }
1088 curr_ptr += card->mpa_rx.len_arr[pind];
1089 }
1090 MP_RX_AGGR_BUF_RESET(card);
1091 }
1092
1093rx_curr_single:
1094 if (f_do_rx_cur) {
1095 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
1096 port, rx_len);
1097
1098 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1099 skb->data, skb->len,
1100 adapter->ioport + port))
1101 return -1;
1102
1103 mwifiex_decode_rx_packet(adapter, skb, pkt_type);
1104 }
1105
1106 return 0;
1107}
1108
1109/*
1110 * This function checks the current interrupt status.
1111 *
1112 * The following interrupts are checked and handled by this function -
1113 * - Data sent
1114 * - Command sent
1115 * - Packets received
1116 *
1117 * Since the firmware does not generate download ready interrupt if the
1118 * port updated is command port only, command sent interrupt checking
1119 * should be done manually, and for every SDIO interrupt.
1120 *
1121 * In case of Rx packets received, the packets are uploaded from card to
1122 * host and processed accordingly.
1123 */
1124static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1125{
1126 struct sdio_mmc_card *card = adapter->card;
1127 int ret = 0;
1128 u8 sdio_ireg;
1129 struct sk_buff *skb = NULL;
1130 u8 port = CTRL_PORT;
1131 u32 len_reg_l, len_reg_u;
1132 u32 rx_blocks;
1133 u16 rx_len;
1134 unsigned long flags;
1135
1136 spin_lock_irqsave(&adapter->int_lock, flags);
1137 sdio_ireg = adapter->int_status;
1138 adapter->int_status = 0;
1139 spin_unlock_irqrestore(&adapter->int_lock, flags);
1140
1141 if (!sdio_ireg)
1142 return ret;
1143
1144 if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
1145 card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
1146 card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
1147 dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
1148 card->mp_wr_bitmap);
1149 if (adapter->data_sent &&
1150 (card->mp_wr_bitmap & card->mp_data_port_mask)) {
1151 dev_dbg(adapter->dev,
1152 "info: <--- Tx DONE Interrupt --->\n");
1153 adapter->data_sent = false;
1154 }
1155 }
1156
1157 /* As firmware will not generate download ready interrupt if the port
1158 updated is command port only, cmd_sent should be done for any SDIO
1159 interrupt. */
1160 if (adapter->cmd_sent) {
1161 /* Check if firmware has attach buffer at command port and
1162 update just that in wr_bit_map. */
1163 card->mp_wr_bitmap |=
1164 (u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
1165 if (card->mp_wr_bitmap & CTRL_PORT_MASK)
1166 adapter->cmd_sent = false;
1167 }
1168
1169 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
1170 adapter->cmd_sent, adapter->data_sent);
1171 if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
1172 card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
1173 card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
1174 dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
1175 card->mp_rd_bitmap);
1176
1177 while (true) {
1178 ret = mwifiex_get_rd_port(adapter, &port);
1179 if (ret) {
1180 dev_dbg(adapter->dev,
1181 "info: no more rd_port available\n");
1182 break;
1183 }
1184 len_reg_l = RD_LEN_P0_L + (port << 1);
1185 len_reg_u = RD_LEN_P0_U + (port << 1);
1186 rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
1187 rx_len |= (u16) card->mp_regs[len_reg_l];
1188 dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
1189 port, rx_len);
1190 rx_blocks =
1191 (rx_len + MWIFIEX_SDIO_BLOCK_SIZE -
1192 1) / MWIFIEX_SDIO_BLOCK_SIZE;
1193 if (rx_len <= INTF_HEADER_LEN
1194 || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
1195 MWIFIEX_RX_DATA_BUF_SIZE) {
1196 dev_err(adapter->dev, "invalid rx_len=%d\n",
1197 rx_len);
1198 return -1;
1199 }
1200 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1201
1202 skb = dev_alloc_skb(rx_len);
1203
1204 if (!skb) {
1205 dev_err(adapter->dev, "%s: failed to alloc skb",
1206 __func__);
1207 return -1;
1208 }
1209
1210 skb_put(skb, rx_len);
1211
1212 dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
1213 rx_len, skb->len);
1214
1215 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
1216 port)) {
1217 u32 cr = 0;
1218
1219 dev_err(adapter->dev, "card_to_host_mpa failed:"
1220 " int status=%#x\n", sdio_ireg);
1221 if (mwifiex_read_reg(adapter,
1222 CONFIGURATION_REG, &cr))
1223 dev_err(adapter->dev,
1224 "read CFG reg failed\n");
1225
1226 dev_dbg(adapter->dev,
1227 "info: CFG reg val = %d\n", cr);
1228 if (mwifiex_write_reg(adapter,
1229 CONFIGURATION_REG,
1230 (cr | 0x04)))
1231 dev_err(adapter->dev,
1232 "write CFG reg failed\n");
1233
1234 dev_dbg(adapter->dev, "info: write success\n");
1235 if (mwifiex_read_reg(adapter,
1236 CONFIGURATION_REG, &cr))
1237 dev_err(adapter->dev,
1238 "read CFG reg failed\n");
1239
1240 dev_dbg(adapter->dev,
1241 "info: CFG reg val =%x\n", cr);
1242 dev_kfree_skb_any(skb);
1243 return -1;
1244 }
1245 }
1246 }
1247
1248 return 0;
1249}
1250
1251/*
1252 * This function aggregates transmission buffers in driver and downloads
1253 * the aggregated packet to card.
1254 *
1255 * The individual packets are aggregated by copying into an aggregation
1256 * buffer and then downloaded to the card. Previous unsent packets in the
1257 * aggregation buffer are pre-copied first before new packets are added.
1258 * Aggregation is done till there is space left in the aggregation buffer,
1259 * or till new packets are available.
1260 *
1261 * The function will only download the packet to the card when aggregation
1262 * stops, otherwise it will just aggregate the packet in aggregation buffer
1263 * and return.
1264 */
1265static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1266 u8 *payload, u32 pkt_len, u8 port,
1267 u32 next_pkt_len)
1268{
1269 struct sdio_mmc_card *card = adapter->card;
1270 int ret = 0;
1271 s32 f_send_aggr_buf = 0;
1272 s32 f_send_cur_buf = 0;
1273 s32 f_precopy_cur_buf = 0;
1274 s32 f_postcopy_cur_buf = 0;
1275
1276 if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) {
1277 dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
1278 __func__);
1279
1280 f_send_cur_buf = 1;
1281 goto tx_curr_single;
1282 }
1283
1284 if (next_pkt_len) {
1285 /* More pkt in TX queue */
1286 dev_dbg(adapter->dev, "info: %s: more packets in queue.\n",
1287 __func__);
1288
1289 if (MP_TX_AGGR_IN_PROGRESS(card)) {
1290 if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &&
1291 MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
1292 f_precopy_cur_buf = 1;
1293
1294 if (!(card->mp_wr_bitmap &
1295 (1 << card->curr_wr_port))
1296 || !MP_TX_AGGR_BUF_HAS_ROOM(
1297 card, next_pkt_len))
1298 f_send_aggr_buf = 1;
1299 } else {
1300 /* No room in Aggr buf, send it */
1301 f_send_aggr_buf = 1;
1302
1303 if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) ||
1304 !(card->mp_wr_bitmap &
1305 (1 << card->curr_wr_port)))
1306 f_send_cur_buf = 1;
1307 else
1308 f_postcopy_cur_buf = 1;
1309 }
1310 } else {
1311 if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)
1312 && (card->mp_wr_bitmap & (1 << card->curr_wr_port)))
1313 f_precopy_cur_buf = 1;
1314 else
1315 f_send_cur_buf = 1;
1316 }
1317 } else {
1318 /* Last pkt in TX queue */
1319 dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n",
1320 __func__);
1321
1322 if (MP_TX_AGGR_IN_PROGRESS(card)) {
1323 /* some packs in Aggr buf already */
1324 f_send_aggr_buf = 1;
1325
1326 if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len))
1327 f_precopy_cur_buf = 1;
1328 else
1329 /* No room in Aggr buf, send it */
1330 f_send_cur_buf = 1;
1331 } else {
1332 f_send_cur_buf = 1;
1333 }
1334 }
1335
1336 if (f_precopy_cur_buf) {
1337 dev_dbg(adapter->dev, "data: %s: precopy current buffer\n",
1338 __func__);
1339 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
1340
1341 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
1342 MP_TX_AGGR_PORT_LIMIT_REACHED(card))
1343 /* No more pkts allowed in Aggr buf, send it */
1344 f_send_aggr_buf = 1;
1345 }
1346
1347 if (f_send_aggr_buf) {
1348 dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
1349 __func__,
1350 card->mpa_tx.start_port, card->mpa_tx.ports);
1351 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
1352 card->mpa_tx.buf_len,
1353 (adapter->ioport | 0x1000 |
1354 (card->mpa_tx.ports << 4)) +
1355 card->mpa_tx.start_port);
1356
1357 MP_TX_AGGR_BUF_RESET(card);
1358 }
1359
1360tx_curr_single:
1361 if (f_send_cur_buf) {
1362 dev_dbg(adapter->dev, "data: %s: send current buffer %d\n",
1363 __func__, port);
1364 ret = mwifiex_write_data_to_card(adapter, payload, pkt_len,
1365 adapter->ioport + port);
1366 }
1367
1368 if (f_postcopy_cur_buf) {
1369 dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n",
1370 __func__);
1371 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
1372 }
1373
1374 return ret;
1375}
1376
1377/*
1378 * This function downloads data from driver to card.
1379 *
1380 * Both commands and data packets are transferred to the card by this
1381 * function.
1382 *
1383 * This function adds the SDIO specific header to the front of the buffer
1384 * before transferring. The header contains the length of the packet and
1385 * the type. The firmware handles the packets based upon this set type.
1386 */
1387static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1388 u8 type, u8 *payload, u32 pkt_len,
1389 struct mwifiex_tx_param *tx_param)
1390{
1391 struct sdio_mmc_card *card = adapter->card;
1392 int ret = 0;
1393 u32 buf_block_len;
1394 u32 blk_size;
1395 u8 port = CTRL_PORT;
1396
1397 /* Allocate buffer and copy payload */
1398 blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
1399 buf_block_len = (pkt_len + blk_size - 1) / blk_size;
1400 *(u16 *) &payload[0] = (u16) pkt_len;
1401 *(u16 *) &payload[2] = type;
1402
1403 /*
1404 * This is SDIO specific header
1405 * u16 length,
1406 * u16 type (MWIFIEX_TYPE_DATA = 0, MWIFIEX_TYPE_CMD = 1,
1407 * MWIFIEX_TYPE_EVENT = 3)
1408 */
1409 if (type == MWIFIEX_TYPE_DATA) {
1410 ret = mwifiex_get_wr_port_data(adapter, &port);
1411 if (ret) {
1412 dev_err(adapter->dev, "%s: no wr_port available\n",
1413 __func__);
1414 return ret;
1415 }
1416 } else {
1417 adapter->cmd_sent = true;
1418 /* Type must be MWIFIEX_TYPE_CMD */
1419
1420 if (pkt_len <= INTF_HEADER_LEN ||
1421 pkt_len > MWIFIEX_UPLD_SIZE)
1422 dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
1423 __func__, payload, pkt_len);
1424 }
1425
1426 /* Transfer data to card */
1427 pkt_len = buf_block_len * blk_size;
1428
1429 if (tx_param)
1430 ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
1431 port, tx_param->next_pkt_len);
1432 else
1433 ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
1434 port, 0);
1435
1436 if (ret) {
1437 if (type == MWIFIEX_TYPE_CMD)
1438 adapter->cmd_sent = false;
1439 if (type == MWIFIEX_TYPE_DATA)
1440 adapter->data_sent = false;
1441 } else {
1442 if (type == MWIFIEX_TYPE_DATA) {
1443 if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port)))
1444 adapter->data_sent = true;
1445 else
1446 adapter->data_sent = false;
1447 }
1448 }
1449
1450 return ret;
1451}
1452
1453/*
1454 * This function allocates the MPA Tx and Rx buffers.
1455 */
1456static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
1457 u32 mpa_tx_buf_size, u32 mpa_rx_buf_size)
1458{
1459 struct sdio_mmc_card *card = adapter->card;
1460 int ret = 0;
1461
1462 card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL);
1463 if (!card->mpa_tx.buf) {
1464 dev_err(adapter->dev, "could not alloc buffer for MP-A TX\n");
1465 ret = -1;
1466 goto error;
1467 }
1468
1469 card->mpa_tx.buf_size = mpa_tx_buf_size;
1470
1471 card->mpa_rx.buf = kzalloc(mpa_rx_buf_size, GFP_KERNEL);
1472 if (!card->mpa_rx.buf) {
1473 dev_err(adapter->dev, "could not alloc buffer for MP-A RX\n");
1474 ret = -1;
1475 goto error;
1476 }
1477
1478 card->mpa_rx.buf_size = mpa_rx_buf_size;
1479
1480error:
1481 if (ret) {
1482 kfree(card->mpa_tx.buf);
1483 kfree(card->mpa_rx.buf);
1484 }
1485
1486 return ret;
1487}
1488
1489/*
1490 * This function unregisters the SDIO device.
1491 *
1492 * The SDIO IRQ is released, the function is disabled and driver
1493 * data is set to null.
1494 */
1495static void
1496mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
1497{
1498 struct sdio_mmc_card *card = adapter->card;
1499
1500 if (adapter->card) {
1501 /* Release the SDIO IRQ */
1502 sdio_claim_host(card->func);
1503 sdio_release_irq(card->func);
1504 sdio_disable_func(card->func);
1505 sdio_release_host(card->func);
1506 sdio_set_drvdata(card->func, NULL);
1507 }
1508}
1509
1510/*
1511 * This function registers the SDIO device.
1512 *
1513 * SDIO IRQ is claimed, block size is set and driver data is initialized.
1514 */
1515static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1516{
1517 int ret = 0;
1518 struct sdio_mmc_card *card = adapter->card;
1519 struct sdio_func *func = card->func;
1520
1521 /* save adapter pointer in card */
1522 card->adapter = adapter;
1523
1524 sdio_claim_host(func);
1525
1526 /* Request the SDIO IRQ */
1527 ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
1528 if (ret) {
1529 pr_err("claim irq failed: ret=%d\n", ret);
1530 goto disable_func;
1531 }
1532
1533 /* Set block size */
1534 ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
1535 if (ret) {
1536 pr_err("cannot set SDIO block size\n");
1537 ret = -1;
1538 goto release_irq;
1539 }
1540
1541 sdio_release_host(func);
1542 sdio_set_drvdata(func, card);
1543
1544 adapter->dev = &func->dev;
1545
1546 return 0;
1547
1548release_irq:
1549 sdio_release_irq(func);
1550disable_func:
1551 sdio_disable_func(func);
1552 sdio_release_host(func);
1553 adapter->card = NULL;
1554
1555 return -1;
1556}
1557
1558/*
1559 * This function initializes the SDIO driver.
1560 *
1561 * The following initializations steps are followed -
1562 * - Read the Host interrupt status register to acknowledge
1563 * the first interrupt got from bootloader
1564 * - Disable host interrupt mask register
1565 * - Get SDIO port
1566 * - Get revision ID
1567 * - Initialize SDIO variables in card
1568 * - Allocate MP registers
1569 * - Allocate MPA Tx and Rx buffers
1570 */
1571static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1572{
1573 struct sdio_mmc_card *card = adapter->card;
1574 int ret;
1575 u32 sdio_ireg = 0;
1576
1577 /*
1578 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
1579 * from the bootloader. If we don't do this we get a interrupt
1580 * as soon as we register the irq.
1581 */
1582 mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg);
1583
1584 /* Disable host interrupt mask register for SDIO */
1585 mwifiex_sdio_disable_host_int(adapter);
1586
1587 /* Get SDIO ioport */
1588 mwifiex_init_sdio_ioport(adapter);
1589
1590 /* Get revision ID */
1591#define REV_ID_REG 0x5c
1592 mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id);
1593
1594 /* Initialize SDIO variables in card */
1595 card->mp_rd_bitmap = 0;
1596 card->mp_wr_bitmap = 0;
1597 card->curr_rd_port = 1;
1598 card->curr_wr_port = 1;
1599
1600 card->mp_data_port_mask = DATA_PORT_MASK;
1601
1602 card->mpa_tx.buf_len = 0;
1603 card->mpa_tx.pkt_cnt = 0;
1604 card->mpa_tx.start_port = 0;
1605
1606 card->mpa_tx.enabled = 0;
1607 card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
1608
1609 card->mpa_rx.buf_len = 0;
1610 card->mpa_rx.pkt_cnt = 0;
1611 card->mpa_rx.start_port = 0;
1612
1613 card->mpa_rx.enabled = 0;
1614 card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
1615
1616 /* Allocate buffers for SDIO MP-A */
1617 card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL);
1618 if (!card->mp_regs) {
1619 dev_err(adapter->dev, "failed to alloc mp_regs\n");
1620 return -1;
1621 }
1622
1623 ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
1624 SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
1625 SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
1626 if (ret) {
1627 dev_err(adapter->dev, "failed to alloc sdio mp-a buffers\n");
1628 kfree(card->mp_regs);
1629 return -1;
1630 }
1631
1632 return ret;
1633}
1634
1635/*
1636 * This function resets the MPA Tx and Rx buffers.
1637 */
1638static void mwifiex_cleanup_mpa_buf(struct mwifiex_adapter *adapter)
1639{
1640 struct sdio_mmc_card *card = adapter->card;
1641
1642 MP_TX_AGGR_BUF_RESET(card);
1643 MP_RX_AGGR_BUF_RESET(card);
1644}
1645
1646/*
1647 * This function cleans up the allocated card buffers.
1648 *
1649 * The following are freed by this function -
1650 * - MP registers
1651 * - MPA Tx buffer
1652 * - MPA Rx buffer
1653 */
1654static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
1655{
1656 struct sdio_mmc_card *card = adapter->card;
1657
1658 kfree(card->mp_regs);
1659 kfree(card->mpa_tx.buf);
1660 kfree(card->mpa_rx.buf);
1661}
1662
1663/*
1664 * This function updates the MP end port in card.
1665 */
1666static void
1667mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1668{
1669 struct sdio_mmc_card *card = adapter->card;
1670 int i;
1671
1672 card->mp_end_port = port;
1673
1674 card->mp_data_port_mask = DATA_PORT_MASK;
1675
1676 for (i = 1; i <= MAX_PORT - card->mp_end_port; i++)
1677 card->mp_data_port_mask &= ~(1 << (MAX_PORT - i));
1678
1679 card->curr_wr_port = 1;
1680
1681 dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
1682 port, card->mp_data_port_mask);
1683}
1684
1685static struct mwifiex_if_ops sdio_ops = {
1686 .init_if = mwifiex_init_sdio,
1687 .cleanup_if = mwifiex_cleanup_sdio,
1688 .check_fw_status = mwifiex_check_fw_status,
1689 .prog_fw = mwifiex_prog_fw_w_helper,
1690 .register_dev = mwifiex_register_dev,
1691 .unregister_dev = mwifiex_unregister_dev,
1692 .enable_int = mwifiex_sdio_enable_host_int,
1693 .process_int_status = mwifiex_process_int_status,
1694 .host_to_card = mwifiex_sdio_host_to_card,
1695 .wakeup = mwifiex_pm_wakeup_card,
1696 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
1697
1698 /* SDIO specific */
1699 .update_mp_end_port = mwifiex_update_mp_end_port,
1700 .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
1701};
1702
1703/*
1704 * This function initializes the SDIO driver.
1705 *
1706 * This initiates the semaphore and registers the device with
1707 * SDIO bus.
1708 */
1709static int
1710mwifiex_sdio_init_module(void)
1711{
1712 int ret;
1713
1714 sema_init(&add_remove_card_sem, 1);
1715
1716 ret = sdio_register_driver(&mwifiex_sdio);
1717
1718 return ret;
1719}
1720
1721/*
1722 * This function cleans up the SDIO driver.
1723 *
1724 * The following major steps are followed for cleanup -
1725 * - Resume the device if its suspended
1726 * - Disconnect the device if connected
1727 * - Shutdown the firmware
1728 * - Unregister the device from SDIO bus.
1729 */
1730static void
1731mwifiex_sdio_cleanup_module(void)
1732{
1733 struct mwifiex_adapter *adapter = g_adapter;
1734 int i;
1735
1736 if (down_interruptible(&add_remove_card_sem))
1737 goto exit_sem_err;
1738
1739 if (!adapter || !adapter->priv_num)
1740 goto exit;
1741
1742 if (adapter->is_suspended)
1743 mwifiex_sdio_resume(adapter->dev);
1744
1745 for (i = 0; i < adapter->priv_num; i++)
1746 if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) &&
1747 adapter->priv[i]->media_connected)
1748 mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT,
1749 NULL);
1750
1751 if (!adapter->surprise_removed)
1752 mwifiex_shutdown_fw(mwifiex_get_priv
1753 (adapter, MWIFIEX_BSS_ROLE_ANY),
1754 MWIFIEX_CMD_WAIT);
1755
1756exit:
1757 up(&add_remove_card_sem);
1758
1759exit_sem_err:
1760 sdio_unregister_driver(&mwifiex_sdio);
1761}
1762
1763module_init(mwifiex_sdio_init_module);
1764module_exit(mwifiex_sdio_cleanup_module);
1765
1766MODULE_AUTHOR("Marvell International Ltd.");
1767MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
1768MODULE_VERSION(SDIO_VERSION);
1769MODULE_LICENSE("GPL v2");
1770MODULE_FIRMWARE("sd8787.bin");
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
new file mode 100644
index 000000000000..a0e9bc5253e0
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -0,0 +1,305 @@
1/*
2 * Marvell Wireless LAN device driver: SDIO specific definitions
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_SDIO_H
21#define _MWIFIEX_SDIO_H
22
23
24#include <linux/mmc/sdio.h>
25#include <linux/mmc/sdio_ids.h>
26#include <linux/mmc/sdio_func.h>
27#include <linux/mmc/card.h>
28
29#include "main.h"
30
31#define BLOCK_MODE 1
32#define BYTE_MODE 0
33
34#define REG_PORT 0
35#define RD_BITMAP_L 0x04
36#define RD_BITMAP_U 0x05
37#define WR_BITMAP_L 0x06
38#define WR_BITMAP_U 0x07
39#define RD_LEN_P0_L 0x08
40#define RD_LEN_P0_U 0x09
41
42#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff
43
44#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000
45
46#define CTRL_PORT 0
47#define CTRL_PORT_MASK 0x0001
48#define DATA_PORT_MASK 0xfffe
49
50#define MAX_MP_REGS 64
51#define MAX_PORT 16
52
53#define SDIO_MP_AGGR_DEF_PKT_LIMIT 8
54
55#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (4096) /* 4K */
56
57/* Multi port RX aggregation buffer size */
58#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (4096) /* 4K */
59
60/* Misc. Config Register : Auto Re-enable interrupts */
61#define AUTO_RE_ENABLE_INT BIT(4)
62
63/* Host Control Registers */
64/* Host Control Registers : I/O port 0 */
65#define IO_PORT_0_REG 0x78
66/* Host Control Registers : I/O port 1 */
67#define IO_PORT_1_REG 0x79
68/* Host Control Registers : I/O port 2 */
69#define IO_PORT_2_REG 0x7A
70
71/* Host Control Registers : Configuration */
72#define CONFIGURATION_REG 0x00
73/* Host Control Registers : Host without Command 53 finish host*/
74#define HOST_TO_CARD_EVENT (0x1U << 3)
75/* Host Control Registers : Host without Command 53 finish host */
76#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2)
77/* Host Control Registers : Host power up */
78#define HOST_POWER_UP (0x1U << 1)
79/* Host Control Registers : Host power down */
80#define HOST_POWER_DOWN (0x1U << 0)
81
82/* Host Control Registers : Host interrupt mask */
83#define HOST_INT_MASK_REG 0x02
84/* Host Control Registers : Upload host interrupt mask */
85#define UP_LD_HOST_INT_MASK (0x1U)
86/* Host Control Registers : Download host interrupt mask */
87#define DN_LD_HOST_INT_MASK (0x2U)
88/* Enable Host interrupt mask */
89#define HOST_INT_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
90/* Disable Host interrupt mask */
91#define HOST_INT_DISABLE 0xff
92
93/* Host Control Registers : Host interrupt status */
94#define HOST_INTSTATUS_REG 0x03
95/* Host Control Registers : Upload host interrupt status */
96#define UP_LD_HOST_INT_STATUS (0x1U)
97/* Host Control Registers : Download host interrupt status */
98#define DN_LD_HOST_INT_STATUS (0x2U)
99
100/* Host Control Registers : Host interrupt RSR */
101#define HOST_INT_RSR_REG 0x01
102/* Host Control Registers : Upload host interrupt RSR */
103#define UP_LD_HOST_INT_RSR (0x1U)
104#define SDIO_INT_MASK 0x3F
105
106/* Host Control Registers : Host interrupt status */
107#define HOST_INT_STATUS_REG 0x28
108/* Host Control Registers : Upload CRC error */
109#define UP_LD_CRC_ERR (0x1U << 2)
110/* Host Control Registers : Upload restart */
111#define UP_LD_RESTART (0x1U << 1)
112/* Host Control Registers : Download restart */
113#define DN_LD_RESTART (0x1U << 0)
114
115/* Card Control Registers : Card status register */
116#define CARD_STATUS_REG 0x30
117/* Card Control Registers : Card I/O ready */
118#define CARD_IO_READY (0x1U << 3)
119/* Card Control Registers : CIS card ready */
120#define CIS_CARD_RDY (0x1U << 2)
121/* Card Control Registers : Upload card ready */
122#define UP_LD_CARD_RDY (0x1U << 1)
123/* Card Control Registers : Download card ready */
124#define DN_LD_CARD_RDY (0x1U << 0)
125
126/* Card Control Registers : Host interrupt mask register */
127#define HOST_INTERRUPT_MASK_REG 0x34
128/* Card Control Registers : Host power interrupt mask */
129#define HOST_POWER_INT_MASK (0x1U << 3)
130/* Card Control Registers : Abort card interrupt mask */
131#define ABORT_CARD_INT_MASK (0x1U << 2)
132/* Card Control Registers : Upload card interrupt mask */
133#define UP_LD_CARD_INT_MASK (0x1U << 1)
134/* Card Control Registers : Download card interrupt mask */
135#define DN_LD_CARD_INT_MASK (0x1U << 0)
136
137/* Card Control Registers : Card interrupt status register */
138#define CARD_INTERRUPT_STATUS_REG 0x38
139/* Card Control Registers : Power up interrupt */
140#define POWER_UP_INT (0x1U << 4)
141/* Card Control Registers : Power down interrupt */
142#define POWER_DOWN_INT (0x1U << 3)
143
144/* Card Control Registers : Card interrupt RSR register */
145#define CARD_INTERRUPT_RSR_REG 0x3c
146/* Card Control Registers : Power up RSR */
147#define POWER_UP_RSR (0x1U << 4)
148/* Card Control Registers : Power down RSR */
149#define POWER_DOWN_RSR (0x1U << 3)
150
151/* Card Control Registers : Miscellaneous Configuration Register */
152#define CARD_MISC_CFG_REG 0x6C
153
154/* Host F1 read base 0 */
155#define HOST_F1_RD_BASE_0 0x0040
156/* Host F1 read base 1 */
157#define HOST_F1_RD_BASE_1 0x0041
158/* Host F1 card ready */
159#define HOST_F1_CARD_RDY 0x0020
160
161/* Firmware status 0 register */
162#define CARD_FW_STATUS0_REG 0x60
163/* Firmware status 1 register */
164#define CARD_FW_STATUS1_REG 0x61
165/* Rx length register */
166#define CARD_RX_LEN_REG 0x62
167/* Rx unit register */
168#define CARD_RX_UNIT_REG 0x63
169
170/* Event header Len*/
171#define MWIFIEX_EVENT_HEADER_LEN 8
172
173/* Max retry number of CMD53 write */
174#define MAX_WRITE_IOMEM_RETRY 2
175
176/* SDIO Tx aggregation in progress ? */
177#define MP_TX_AGGR_IN_PROGRESS(a) (a->mpa_tx.pkt_cnt > 0)
178
179/* SDIO Tx aggregation buffer room for next packet ? */
180#define MP_TX_AGGR_BUF_HAS_ROOM(a, len) ((a->mpa_tx.buf_len+len) \
181 <= a->mpa_tx.buf_size)
182
183/* Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */
184#define MP_TX_AGGR_BUF_PUT(a, payload, pkt_len, port) do { \
185 memmove(&a->mpa_tx.buf[a->mpa_tx.buf_len], \
186 payload, pkt_len); \
187 a->mpa_tx.buf_len += pkt_len; \
188 if (!a->mpa_tx.pkt_cnt) \
189 a->mpa_tx.start_port = port; \
190 if (a->mpa_tx.start_port <= port) \
191 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \
192 else \
193 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT - \
194 a->mp_end_port))); \
195 a->mpa_tx.pkt_cnt++; \
196} while (0);
197
198/* SDIO Tx aggregation limit ? */
199#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \
200 (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit)
201
202/* SDIO Tx aggregation port limit ? */
203#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port < \
204 a->mpa_tx.start_port) && (((MAX_PORT - \
205 a->mpa_tx.start_port) + a->curr_wr_port) >= \
206 SDIO_MP_AGGR_DEF_PKT_LIMIT))
207
208/* Reset SDIO Tx aggregation buffer parameters */
209#define MP_TX_AGGR_BUF_RESET(a) do { \
210 a->mpa_tx.pkt_cnt = 0; \
211 a->mpa_tx.buf_len = 0; \
212 a->mpa_tx.ports = 0; \
213 a->mpa_tx.start_port = 0; \
214} while (0);
215
216/* SDIO Rx aggregation limit ? */
217#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \
218 (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit)
219
220/* SDIO Tx aggregation port limit ? */
221#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port < \
222 a->mpa_rx.start_port) && (((MAX_PORT - \
223 a->mpa_rx.start_port) + a->curr_rd_port) >= \
224 SDIO_MP_AGGR_DEF_PKT_LIMIT))
225
226/* SDIO Rx aggregation in progress ? */
227#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0)
228
229/* SDIO Rx aggregation buffer room for next packet ? */
230#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \
231 ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size)
232
233/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
234#define MP_RX_AGGR_SETUP(a, skb, port) do { \
235 a->mpa_rx.buf_len += skb->len; \
236 if (!a->mpa_rx.pkt_cnt) \
237 a->mpa_rx.start_port = port; \
238 if (a->mpa_rx.start_port <= port) \
239 a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt)); \
240 else \
241 a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1)); \
242 a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb; \
243 a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len; \
244 a->mpa_rx.pkt_cnt++; \
245} while (0);
246
247/* Reset SDIO Rx aggregation buffer parameters */
248#define MP_RX_AGGR_BUF_RESET(a) do { \
249 a->mpa_rx.pkt_cnt = 0; \
250 a->mpa_rx.buf_len = 0; \
251 a->mpa_rx.ports = 0; \
252 a->mpa_rx.start_port = 0; \
253} while (0);
254
255
256/* data structure for SDIO MPA TX */
257struct mwifiex_sdio_mpa_tx {
258 /* multiport tx aggregation buffer pointer */
259 u8 *buf;
260 u32 buf_len;
261 u32 pkt_cnt;
262 u16 ports;
263 u16 start_port;
264 u8 enabled;
265 u32 buf_size;
266 u32 pkt_aggr_limit;
267};
268
269struct mwifiex_sdio_mpa_rx {
270 u8 *buf;
271 u32 buf_len;
272 u32 pkt_cnt;
273 u16 ports;
274 u16 start_port;
275
276 struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
277 u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
278
279 u8 enabled;
280 u32 buf_size;
281 u32 pkt_aggr_limit;
282};
283
284int mwifiex_bus_register(void);
285void mwifiex_bus_unregister(void);
286
287struct sdio_mmc_card {
288 struct sdio_func *func;
289 struct mwifiex_adapter *adapter;
290
291 u16 mp_rd_bitmap;
292 u16 mp_wr_bitmap;
293
294 u16 mp_end_port;
295 u16 mp_data_port_mask;
296
297 u8 curr_rd_port;
298 u8 curr_wr_port;
299
300 u8 *mp_regs;
301
302 struct mwifiex_sdio_mpa_tx mpa_tx;
303 struct mwifiex_sdio_mpa_rx mpa_rx;
304};
305#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
new file mode 100644
index 000000000000..6fff26153e26
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -0,0 +1,1226 @@
1/*
2 * Marvell Wireless LAN device driver: station command handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * This function prepares command to set/get RSSI information.
30 *
31 * Preparation includes -
32 * - Setting command ID, action and proper size
33 * - Setting data/beacon average factors
34 * - Resetting SNR/NF/RSSI values in private structure
35 * - Ensuring correct endian-ness
36 */
37static int
38mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv,
39 struct host_cmd_ds_command *cmd, u16 cmd_action)
40{
41 cmd->command = cpu_to_le16(HostCmd_CMD_RSSI_INFO);
42 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rssi_info) +
43 S_DS_GEN);
44 cmd->params.rssi_info.action = cpu_to_le16(cmd_action);
45 cmd->params.rssi_info.ndata = cpu_to_le16(priv->data_avg_factor);
46 cmd->params.rssi_info.nbcn = cpu_to_le16(priv->bcn_avg_factor);
47
48 /* Reset SNR/NF/RSSI values in private structure */
49 priv->data_rssi_last = 0;
50 priv->data_nf_last = 0;
51 priv->data_rssi_avg = 0;
52 priv->data_nf_avg = 0;
53 priv->bcn_rssi_last = 0;
54 priv->bcn_nf_last = 0;
55 priv->bcn_rssi_avg = 0;
56 priv->bcn_nf_avg = 0;
57
58 return 0;
59}
60
61/*
62 * This function prepares command to set MAC control.
63 *
64 * Preparation includes -
65 * - Setting command ID, action and proper size
66 * - Ensuring correct endian-ness
67 */
68static int mwifiex_cmd_mac_control(struct mwifiex_private *priv,
69 struct host_cmd_ds_command *cmd,
70 u16 cmd_action, void *data_buf)
71{
72 struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl;
73 u16 action = *((u16 *) data_buf);
74
75 if (cmd_action != HostCmd_ACT_GEN_SET) {
76 dev_err(priv->adapter->dev,
77 "mac_control: only support set cmd\n");
78 return -1;
79 }
80
81 cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
82 cmd->size =
83 cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN);
84 mac_ctrl->action = cpu_to_le16(action);
85
86 return 0;
87}
88
89/*
90 * This function prepares command to set/get SNMP MIB.
91 *
92 * Preparation includes -
93 * - Setting command ID, action and proper size
94 * - Setting SNMP MIB OID number and value
95 * (as required)
96 * - Ensuring correct endian-ness
97 *
98 * The following SNMP MIB OIDs are supported -
99 * - FRAG_THRESH_I : Fragmentation threshold
100 * - RTS_THRESH_I : RTS threshold
101 * - SHORT_RETRY_LIM_I : Short retry limit
102 * - DOT11D_I : 11d support
103 */
104static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
105 struct host_cmd_ds_command *cmd,
106 u16 cmd_action, u32 cmd_oid,
107 void *data_buf)
108{
109 struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib;
110 u32 ul_temp;
111
112 dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
113 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
114 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
115 - 1 + S_DS_GEN);
116
117 if (cmd_action == HostCmd_ACT_GEN_GET) {
118 snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
119 snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
120 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
121 + MAX_SNMP_BUF_SIZE);
122 }
123
124 switch (cmd_oid) {
125 case FRAG_THRESH_I:
126 snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I);
127 if (cmd_action == HostCmd_ACT_GEN_SET) {
128 snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
129 snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
130 ul_temp = *((u32 *) data_buf);
131 *((__le16 *) (snmp_mib->value)) =
132 cpu_to_le16((u16) ul_temp);
133 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
134 + sizeof(u16));
135 }
136 break;
137 case RTS_THRESH_I:
138 snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I);
139 if (cmd_action == HostCmd_ACT_GEN_SET) {
140 snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
141 snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
142 ul_temp = *((u32 *) data_buf);
143 *(__le16 *) (snmp_mib->value) =
144 cpu_to_le16((u16) ul_temp);
145 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
146 + sizeof(u16));
147 }
148 break;
149
150 case SHORT_RETRY_LIM_I:
151 snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I);
152 if (cmd_action == HostCmd_ACT_GEN_SET) {
153 snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
154 snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
155 ul_temp = (*(u32 *) data_buf);
156 *((__le16 *) (snmp_mib->value)) =
157 cpu_to_le16((u16) ul_temp);
158 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
159 + sizeof(u16));
160 }
161 break;
162 case DOT11D_I:
163 snmp_mib->oid = cpu_to_le16((u16) DOT11D_I);
164 if (cmd_action == HostCmd_ACT_GEN_SET) {
165 snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
166 snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
167 ul_temp = *(u32 *) data_buf;
168 *((__le16 *) (snmp_mib->value)) =
169 cpu_to_le16((u16) ul_temp);
170 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
171 + sizeof(u16));
172 }
173 break;
174 default:
175 break;
176 }
177 dev_dbg(priv->adapter->dev,
178 "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
179 " Value=0x%x\n",
180 cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
181 le16_to_cpu(*(__le16 *) snmp_mib->value));
182 return 0;
183}
184
185/*
186 * This function prepares command to get log.
187 *
188 * Preparation includes -
189 * - Setting command ID and proper size
190 * - Ensuring correct endian-ness
191 */
192static int
193mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv,
194 struct host_cmd_ds_command *cmd)
195{
196 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
197 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) +
198 S_DS_GEN);
199 return 0;
200}
201
202/*
203 * This function prepares command to set/get Tx data rate configuration.
204 *
205 * Preparation includes -
206 * - Setting command ID, action and proper size
207 * - Setting configuration index, rate scope and rate drop pattern
208 * parameters (as required)
209 * - Ensuring correct endian-ness
210 */
211static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
212 struct host_cmd_ds_command *cmd,
213 u16 cmd_action, void *data_buf)
214{
215 struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg;
216 struct mwifiex_rate_scope *rate_scope;
217 struct mwifiex_rate_drop_pattern *rate_drop;
218 u16 *pbitmap_rates = (u16 *) data_buf;
219
220 u32 i;
221
222 cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
223
224 rate_cfg->action = cpu_to_le16(cmd_action);
225 rate_cfg->cfg_index = 0;
226
227 rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg +
228 sizeof(struct host_cmd_ds_tx_rate_cfg));
229 rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE);
230 rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) -
231 sizeof(struct mwifiex_ie_types_header));
232 if (pbitmap_rates != NULL) {
233 rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]);
234 rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]);
235 for (i = 0;
236 i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16);
237 i++)
238 rate_scope->ht_mcs_rate_bitmap[i] =
239 cpu_to_le16(pbitmap_rates[2 + i]);
240 } else {
241 rate_scope->hr_dsss_rate_bitmap =
242 cpu_to_le16(priv->bitmap_rates[0]);
243 rate_scope->ofdm_rate_bitmap =
244 cpu_to_le16(priv->bitmap_rates[1]);
245 for (i = 0;
246 i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16);
247 i++)
248 rate_scope->ht_mcs_rate_bitmap[i] =
249 cpu_to_le16(priv->bitmap_rates[2 + i]);
250 }
251
252 rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
253 sizeof(struct mwifiex_rate_scope));
254 rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
255 rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
256 rate_drop->rate_drop_mode = 0;
257
258 cmd->size =
259 cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_tx_rate_cfg) +
260 sizeof(struct mwifiex_rate_scope) +
261 sizeof(struct mwifiex_rate_drop_pattern));
262
263 return 0;
264}
265
266/*
267 * This function prepares command to set/get Tx power configuration.
268 *
269 * Preparation includes -
270 * - Setting command ID, action and proper size
271 * - Setting Tx power mode, power group TLV
272 * (as required)
273 * - Ensuring correct endian-ness
274 */
275static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv,
276 struct host_cmd_ds_command *cmd,
277 u16 cmd_action, void *data_buf)
278{
279 struct mwifiex_types_power_group *pg_tlv = NULL;
280 struct host_cmd_ds_txpwr_cfg *txp = NULL;
281 struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg;
282
283 cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
284 cmd->size =
285 cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg));
286 switch (cmd_action) {
287 case HostCmd_ACT_GEN_SET:
288 txp = (struct host_cmd_ds_txpwr_cfg *) data_buf;
289 if (txp->mode) {
290 pg_tlv = (struct mwifiex_types_power_group
291 *) ((unsigned long) data_buf +
292 sizeof(struct host_cmd_ds_txpwr_cfg));
293 memmove(cmd_txp_cfg, data_buf,
294 sizeof(struct host_cmd_ds_txpwr_cfg) +
295 sizeof(struct mwifiex_types_power_group) +
296 pg_tlv->length);
297
298 pg_tlv = (struct mwifiex_types_power_group *) ((u8 *)
299 cmd_txp_cfg +
300 sizeof(struct host_cmd_ds_txpwr_cfg));
301 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) +
302 sizeof(struct mwifiex_types_power_group) +
303 pg_tlv->length);
304 } else {
305 memmove(cmd_txp_cfg, data_buf,
306 sizeof(struct host_cmd_ds_txpwr_cfg));
307 }
308 cmd_txp_cfg->action = cpu_to_le16(cmd_action);
309 break;
310 case HostCmd_ACT_GEN_GET:
311 cmd_txp_cfg->action = cpu_to_le16(cmd_action);
312 break;
313 }
314
315 return 0;
316}
317
318/*
319 * This function prepares command to set Host Sleep configuration.
320 *
321 * Preparation includes -
322 * - Setting command ID and proper size
323 * - Setting Host Sleep action, conditions, ARP filters
324 * (as required)
325 * - Ensuring correct endian-ness
326 */
327static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
328 struct host_cmd_ds_command *cmd,
329 u16 cmd_action,
330 struct mwifiex_hs_config_param *data_buf)
331{
332 struct mwifiex_adapter *adapter = priv->adapter;
333 struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg;
334 u16 hs_activate = false;
335
336 if (data_buf == NULL)
337 /* New Activate command */
338 hs_activate = true;
339 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
340
341 if (!hs_activate &&
342 (data_buf->conditions
343 != cpu_to_le32(HOST_SLEEP_CFG_CANCEL))
344 && ((adapter->arp_filter_size > 0)
345 && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
346 dev_dbg(adapter->dev,
347 "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
348 adapter->arp_filter_size);
349 memcpy(((u8 *) hs_cfg) +
350 sizeof(struct host_cmd_ds_802_11_hs_cfg_enh),
351 adapter->arp_filter, adapter->arp_filter_size);
352 cmd->size = cpu_to_le16(adapter->arp_filter_size +
353 sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
354 + S_DS_GEN);
355 } else {
356 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct
357 host_cmd_ds_802_11_hs_cfg_enh));
358 }
359 if (hs_activate) {
360 hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
361 hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED;
362 } else {
363 hs_cfg->action = cpu_to_le16(HS_CONFIGURE);
364 hs_cfg->params.hs_config.conditions = data_buf->conditions;
365 hs_cfg->params.hs_config.gpio = data_buf->gpio;
366 hs_cfg->params.hs_config.gap = data_buf->gap;
367 dev_dbg(adapter->dev,
368 "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
369 hs_cfg->params.hs_config.conditions,
370 hs_cfg->params.hs_config.gpio,
371 hs_cfg->params.hs_config.gap);
372 }
373
374 return 0;
375}
376
377/*
378 * This function prepares command to set/get MAC address.
379 *
380 * Preparation includes -
381 * - Setting command ID, action and proper size
382 * - Setting MAC address (for SET only)
383 * - Ensuring correct endian-ness
384 */
385static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv,
386 struct host_cmd_ds_command *cmd,
387 u16 cmd_action)
388{
389 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
390 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_mac_address) +
391 S_DS_GEN);
392 cmd->result = 0;
393
394 cmd->params.mac_addr.action = cpu_to_le16(cmd_action);
395
396 if (cmd_action == HostCmd_ACT_GEN_SET)
397 memcpy(cmd->params.mac_addr.mac_addr, priv->curr_addr,
398 ETH_ALEN);
399 return 0;
400}
401
402/*
403 * This function prepares command to set MAC multicast address.
404 *
405 * Preparation includes -
406 * - Setting command ID, action and proper size
407 * - Setting MAC multicast address
408 * - Ensuring correct endian-ness
409 */
410static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv,
411 struct host_cmd_ds_command *cmd,
412 u16 cmd_action, void *data_buf)
413{
414 struct mwifiex_multicast_list *mcast_list =
415 (struct mwifiex_multicast_list *) data_buf;
416 struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr;
417
418 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) +
419 S_DS_GEN);
420 cmd->command = cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
421
422 mcast_addr->action = cpu_to_le16(cmd_action);
423 mcast_addr->num_of_adrs =
424 cpu_to_le16((u16) mcast_list->num_multicast_addr);
425 memcpy(mcast_addr->mac_list, mcast_list->mac_list,
426 mcast_list->num_multicast_addr * ETH_ALEN);
427
428 return 0;
429}
430
431/*
432 * This function prepares command to deauthenticate.
433 *
434 * Preparation includes -
435 * - Setting command ID and proper size
436 * - Setting AP MAC address and reason code
437 * - Ensuring correct endian-ness
438 */
439static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv,
440 struct host_cmd_ds_command *cmd,
441 void *data_buf)
442{
443 struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth;
444
445 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
446 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_deauthenticate)
447 + S_DS_GEN);
448
449 /* Set AP MAC address */
450 memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN);
451
452 dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr);
453
454 deauth->reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
455
456 return 0;
457}
458
459/*
460 * This function prepares command to stop Ad-Hoc network.
461 *
462 * Preparation includes -
463 * - Setting command ID and proper size
464 * - Ensuring correct endian-ness
465 */
466static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv,
467 struct host_cmd_ds_command *cmd)
468{
469 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
470 cmd->size = cpu_to_le16(S_DS_GEN);
471 return 0;
472}
473
474/*
475 * This function sets WEP key(s) to key parameter TLV(s).
476 *
477 * Multi-key parameter TLVs are supported, so we can send multiple
478 * WEP keys in a single buffer.
479 */
480static int
481mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
482 struct mwifiex_ie_type_key_param_set *key_param_set,
483 u16 *key_param_len)
484{
485 int cur_key_param_len = 0;
486 u8 i;
487
488 /* Multi-key_param_set TLV is supported */
489 for (i = 0; i < NUM_WEP_KEYS; i++) {
490 if ((priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP40) ||
491 (priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP104)) {
492 key_param_set->type =
493 cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
494/* Key_param_set WEP fixed length */
495#define KEYPARAMSET_WEP_FIXED_LEN 8
496 key_param_set->length = cpu_to_le16((u16)
497 (priv->wep_key[i].
498 key_length +
499 KEYPARAMSET_WEP_FIXED_LEN));
500 key_param_set->key_type_id =
501 cpu_to_le16(KEY_TYPE_ID_WEP);
502 key_param_set->key_info =
503 cpu_to_le16(KEY_INFO_WEP_ENABLED |
504 KEY_INFO_WEP_UNICAST |
505 KEY_INFO_WEP_MCAST);
506 key_param_set->key_len =
507 cpu_to_le16(priv->wep_key[i].key_length);
508 /* Set WEP key index */
509 key_param_set->key[0] = i;
510 /* Set default Tx key flag */
511 if (i ==
512 (priv->
513 wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
514 key_param_set->key[1] = 1;
515 else
516 key_param_set->key[1] = 0;
517 memmove(&key_param_set->key[2],
518 priv->wep_key[i].key_material,
519 priv->wep_key[i].key_length);
520
521 cur_key_param_len = priv->wep_key[i].key_length +
522 KEYPARAMSET_WEP_FIXED_LEN +
523 sizeof(struct mwifiex_ie_types_header);
524 *key_param_len += (u16) cur_key_param_len;
525 key_param_set =
526 (struct mwifiex_ie_type_key_param_set *)
527 ((u8 *)key_param_set +
528 cur_key_param_len);
529 } else if (!priv->wep_key[i].key_length) {
530 continue;
531 } else {
532 dev_err(priv->adapter->dev,
533 "key%d Length = %d is incorrect\n",
534 (i + 1), priv->wep_key[i].key_length);
535 return -1;
536 }
537 }
538
539 return 0;
540}
541
542/*
543 * This function prepares command to set/get/reset network key(s).
544 *
545 * Preparation includes -
546 * - Setting command ID, action and proper size
547 * - Setting WEP keys, WAPI keys or WPA keys along with required
548 * encryption (TKIP, AES) (as required)
549 * - Ensuring correct endian-ness
550 */
551static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
552 struct host_cmd_ds_command *cmd,
553 u16 cmd_action,
554 u32 cmd_oid, void *data_buf)
555{
556 struct host_cmd_ds_802_11_key_material *key_material =
557 &cmd->params.key_material;
558 struct mwifiex_ds_encrypt_key *enc_key =
559 (struct mwifiex_ds_encrypt_key *) data_buf;
560 u16 key_param_len = 0;
561 int ret = 0;
562 const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
563
564 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
565 key_material->action = cpu_to_le16(cmd_action);
566
567 if (cmd_action == HostCmd_ACT_GEN_GET) {
568 cmd->size =
569 cpu_to_le16(sizeof(key_material->action) + S_DS_GEN);
570 return ret;
571 }
572
573 if (!enc_key) {
574 memset(&key_material->key_param_set, 0,
575 (NUM_WEP_KEYS *
576 sizeof(struct mwifiex_ie_type_key_param_set)));
577 ret = mwifiex_set_keyparamset_wep(priv,
578 &key_material->key_param_set,
579 &key_param_len);
580 cmd->size = cpu_to_le16(key_param_len +
581 sizeof(key_material->action) + S_DS_GEN);
582 return ret;
583 } else
584 memset(&key_material->key_param_set, 0,
585 sizeof(struct mwifiex_ie_type_key_param_set));
586 if (enc_key->is_wapi_key) {
587 dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n");
588 key_material->key_param_set.key_type_id =
589 cpu_to_le16(KEY_TYPE_ID_WAPI);
590 if (cmd_oid == KEY_INFO_ENABLED)
591 key_material->key_param_set.key_info =
592 cpu_to_le16(KEY_INFO_WAPI_ENABLED);
593 else
594 key_material->key_param_set.key_info =
595 cpu_to_le16(!KEY_INFO_WAPI_ENABLED);
596
597 key_material->key_param_set.key[0] = enc_key->key_index;
598 if (!priv->sec_info.wapi_key_on)
599 key_material->key_param_set.key[1] = 1;
600 else
601 /* set 0 when re-key */
602 key_material->key_param_set.key[1] = 0;
603
604 if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) {
605 /* WAPI pairwise key: unicast */
606 key_material->key_param_set.key_info |=
607 cpu_to_le16(KEY_INFO_WAPI_UNICAST);
608 } else { /* WAPI group key: multicast */
609 key_material->key_param_set.key_info |=
610 cpu_to_le16(KEY_INFO_WAPI_MCAST);
611 priv->sec_info.wapi_key_on = true;
612 }
613
614 key_material->key_param_set.type =
615 cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
616 key_material->key_param_set.key_len =
617 cpu_to_le16(WAPI_KEY_LEN);
618 memcpy(&key_material->key_param_set.key[2],
619 enc_key->key_material, enc_key->key_len);
620 memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
621 enc_key->wapi_rxpn, WAPI_RXPN_LEN);
622 key_material->key_param_set.length =
623 cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
624
625 key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
626 sizeof(struct mwifiex_ie_types_header);
627 cmd->size = cpu_to_le16(key_param_len +
628 sizeof(key_material->action) + S_DS_GEN);
629 return ret;
630 }
631 if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
632 dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
633 key_material->key_param_set.key_type_id =
634 cpu_to_le16(KEY_TYPE_ID_AES);
635 if (cmd_oid == KEY_INFO_ENABLED)
636 key_material->key_param_set.key_info =
637 cpu_to_le16(KEY_INFO_AES_ENABLED);
638 else
639 key_material->key_param_set.key_info =
640 cpu_to_le16(!KEY_INFO_AES_ENABLED);
641
642 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
643 /* AES pairwise key: unicast */
644 key_material->key_param_set.key_info |=
645 cpu_to_le16(KEY_INFO_AES_UNICAST);
646 else /* AES group key: multicast */
647 key_material->key_param_set.key_info |=
648 cpu_to_le16(KEY_INFO_AES_MCAST);
649 } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
650 dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
651 key_material->key_param_set.key_type_id =
652 cpu_to_le16(KEY_TYPE_ID_TKIP);
653 key_material->key_param_set.key_info =
654 cpu_to_le16(KEY_INFO_TKIP_ENABLED);
655
656 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
657 /* TKIP pairwise key: unicast */
658 key_material->key_param_set.key_info |=
659 cpu_to_le16(KEY_INFO_TKIP_UNICAST);
660 else /* TKIP group key: multicast */
661 key_material->key_param_set.key_info |=
662 cpu_to_le16(KEY_INFO_TKIP_MCAST);
663 }
664
665 if (key_material->key_param_set.key_type_id) {
666 key_material->key_param_set.type =
667 cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
668 key_material->key_param_set.key_len =
669 cpu_to_le16((u16) enc_key->key_len);
670 memcpy(key_material->key_param_set.key, enc_key->key_material,
671 enc_key->key_len);
672 key_material->key_param_set.length =
673 cpu_to_le16((u16) enc_key->key_len +
674 KEYPARAMSET_FIXED_LEN);
675
676 key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
677 + sizeof(struct mwifiex_ie_types_header);
678
679 cmd->size = cpu_to_le16(key_param_len +
680 sizeof(key_material->action) + S_DS_GEN);
681 }
682
683 return ret;
684}
685
686/*
687 * This function prepares command to set/get 11d domain information.
688 *
689 * Preparation includes -
690 * - Setting command ID, action and proper size
691 * - Setting domain information fields (for SET only)
692 * - Ensuring correct endian-ness
693 */
694static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv,
695 struct host_cmd_ds_command *cmd,
696 u16 cmd_action)
697{
698 struct mwifiex_adapter *adapter = priv->adapter;
699 struct host_cmd_ds_802_11d_domain_info *domain_info =
700 &cmd->params.domain_info;
701 struct mwifiex_ietypes_domain_param_set *domain =
702 &domain_info->domain;
703 u8 no_of_triplet = adapter->domain_reg.no_of_triplet;
704
705 dev_dbg(adapter->dev, "info: 11D: no_of_triplet=0x%x\n", no_of_triplet);
706
707 cmd->command = cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
708 domain_info->action = cpu_to_le16(cmd_action);
709 if (cmd_action == HostCmd_ACT_GEN_GET) {
710 cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
711 return 0;
712 }
713
714 /* Set domain info fields */
715 domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY);
716 memcpy(domain->country_code, adapter->domain_reg.country_code,
717 sizeof(domain->country_code));
718
719 domain->header.len = cpu_to_le16((no_of_triplet *
720 sizeof(struct ieee80211_country_ie_triplet)) +
721 sizeof(domain->country_code));
722
723 if (no_of_triplet) {
724 memcpy(domain->triplet, adapter->domain_reg.triplet,
725 no_of_triplet *
726 sizeof(struct ieee80211_country_ie_triplet));
727
728 cmd->size = cpu_to_le16(sizeof(domain_info->action) +
729 le16_to_cpu(domain->header.len) +
730 sizeof(struct mwifiex_ie_types_header)
731 + S_DS_GEN);
732 } else {
733 cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
734 }
735
736 return 0;
737}
738
739/*
740 * This function prepares command to set/get RF channel.
741 *
742 * Preparation includes -
743 * - Setting command ID, action and proper size
744 * - Setting RF type and current RF channel (for SET only)
745 * - Ensuring correct endian-ness
746 */
747static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv,
748 struct host_cmd_ds_command *cmd,
749 u16 cmd_action, void *data_buf)
750{
751 struct host_cmd_ds_802_11_rf_channel *rf_chan =
752 &cmd->params.rf_channel;
753 uint16_t rf_type = le16_to_cpu(rf_chan->rf_type);
754
755 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
756 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rf_channel)
757 + S_DS_GEN);
758
759 if (cmd_action == HostCmd_ACT_GEN_SET) {
760 if ((priv->adapter->adhoc_start_band & BAND_A)
761 || (priv->adapter->adhoc_start_band & BAND_AN))
762 rf_chan->rf_type =
763 cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A);
764
765 rf_type = le16_to_cpu(rf_chan->rf_type);
766 SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset);
767 rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf));
768 }
769 rf_chan->action = cpu_to_le16(cmd_action);
770 return 0;
771}
772
773/*
774 * This function prepares command to set/get IBSS coalescing status.
775 *
776 * Preparation includes -
777 * - Setting command ID, action and proper size
778 * - Setting status to enable or disable (for SET only)
779 * - Ensuring correct endian-ness
780 */
781static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv,
782 struct host_cmd_ds_command *cmd,
783 u16 cmd_action, void *data_buf)
784{
785 struct host_cmd_ds_802_11_ibss_status *ibss_coal =
786 &(cmd->params.ibss_coalescing);
787 u16 enable = 0;
788
789 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
790 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) +
791 S_DS_GEN);
792 cmd->result = 0;
793 ibss_coal->action = cpu_to_le16(cmd_action);
794
795 switch (cmd_action) {
796 case HostCmd_ACT_GEN_SET:
797 if (data_buf != NULL)
798 enable = *(u16 *) data_buf;
799 ibss_coal->enable = cpu_to_le16(enable);
800 break;
801
802 /* In other case.. Nothing to do */
803 case HostCmd_ACT_GEN_GET:
804 default:
805 break;
806 }
807
808 return 0;
809}
810
811/*
812 * This function prepares command to set/get register value.
813 *
814 * Preparation includes -
815 * - Setting command ID, action and proper size
816 * - Setting register offset (for both GET and SET) and
817 * register value (for SET only)
818 * - Ensuring correct endian-ness
819 *
820 * The following type of registers can be accessed with this function -
821 * - MAC register
822 * - BBP register
823 * - RF register
824 * - PMIC register
825 * - CAU register
826 * - EEPROM
827 */
828static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
829 u16 cmd_action, void *data_buf)
830{
831 struct mwifiex_ds_reg_rw *reg_rw;
832
833 reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
834 switch (le16_to_cpu(cmd->command)) {
835 case HostCmd_CMD_MAC_REG_ACCESS:
836 {
837 struct host_cmd_ds_mac_reg_access *mac_reg;
838
839 cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
840 mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd->
841 params.mac_reg;
842 mac_reg->action = cpu_to_le16(cmd_action);
843 mac_reg->offset =
844 cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
845 mac_reg->value = reg_rw->value;
846 break;
847 }
848 case HostCmd_CMD_BBP_REG_ACCESS:
849 {
850 struct host_cmd_ds_bbp_reg_access *bbp_reg;
851
852 cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
853 bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd->
854 params.bbp_reg;
855 bbp_reg->action = cpu_to_le16(cmd_action);
856 bbp_reg->offset =
857 cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
858 bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
859 break;
860 }
861 case HostCmd_CMD_RF_REG_ACCESS:
862 {
863 struct host_cmd_ds_rf_reg_access *rf_reg;
864
865 cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
866 rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
867 params.rf_reg;
868 rf_reg->action = cpu_to_le16(cmd_action);
869 rf_reg->offset =
870 cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
871 rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
872 break;
873 }
874 case HostCmd_CMD_PMIC_REG_ACCESS:
875 {
876 struct host_cmd_ds_pmic_reg_access *pmic_reg;
877
878 cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
879 pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd->
880 params.pmic_reg;
881 pmic_reg->action = cpu_to_le16(cmd_action);
882 pmic_reg->offset =
883 cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
884 pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
885 break;
886 }
887 case HostCmd_CMD_CAU_REG_ACCESS:
888 {
889 struct host_cmd_ds_rf_reg_access *cau_reg;
890
891 cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
892 cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
893 params.rf_reg;
894 cau_reg->action = cpu_to_le16(cmd_action);
895 cau_reg->offset =
896 cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
897 cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
898 break;
899 }
900 case HostCmd_CMD_802_11_EEPROM_ACCESS:
901 {
902 struct mwifiex_ds_read_eeprom *rd_eeprom =
903 (struct mwifiex_ds_read_eeprom *) data_buf;
904 struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom =
905 (struct host_cmd_ds_802_11_eeprom_access *)
906 &cmd->params.eeprom;
907
908 cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
909 cmd_eeprom->action = cpu_to_le16(cmd_action);
910 cmd_eeprom->offset = rd_eeprom->offset;
911 cmd_eeprom->byte_count = rd_eeprom->byte_count;
912 cmd_eeprom->value = 0;
913 break;
914 }
915 default:
916 return -1;
917 }
918
919 return 0;
920}
921
922/*
923 * This function prepares the commands before sending them to the firmware.
924 *
925 * This is a generic function which calls specific command preparation
926 * routines based upon the command number.
927 */
928int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
929 u16 cmd_action, u32 cmd_oid,
930 void *data_buf, void *cmd_buf)
931{
932 struct host_cmd_ds_command *cmd_ptr =
933 (struct host_cmd_ds_command *) cmd_buf;
934 int ret = 0;
935
936 /* Prepare command */
937 switch (cmd_no) {
938 case HostCmd_CMD_GET_HW_SPEC:
939 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
940 break;
941 case HostCmd_CMD_MAC_CONTROL:
942 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
943 data_buf);
944 break;
945 case HostCmd_CMD_802_11_MAC_ADDRESS:
946 ret = mwifiex_cmd_802_11_mac_address(priv, cmd_ptr,
947 cmd_action);
948 break;
949 case HostCmd_CMD_MAC_MULTICAST_ADR:
950 ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action,
951 data_buf);
952 break;
953 case HostCmd_CMD_TX_RATE_CFG:
954 ret = mwifiex_cmd_tx_rate_cfg(priv, cmd_ptr, cmd_action,
955 data_buf);
956 break;
957 case HostCmd_CMD_TXPWR_CFG:
958 ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action,
959 data_buf);
960 break;
961 case HostCmd_CMD_802_11_PS_MODE_ENH:
962 ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action,
963 (uint16_t)cmd_oid, data_buf);
964 break;
965 case HostCmd_CMD_802_11_HS_CFG_ENH:
966 ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action,
967 (struct mwifiex_hs_config_param *) data_buf);
968 break;
969 case HostCmd_CMD_802_11_SCAN:
970 ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf);
971 break;
972 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
973 ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr,
974 data_buf);
975 break;
976 case HostCmd_CMD_802_11_ASSOCIATE:
977 ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf);
978 break;
979 case HostCmd_CMD_802_11_DEAUTHENTICATE:
980 ret = mwifiex_cmd_802_11_deauthenticate(priv, cmd_ptr,
981 data_buf);
982 break;
983 case HostCmd_CMD_802_11_AD_HOC_START:
984 ret = mwifiex_cmd_802_11_ad_hoc_start(priv, cmd_ptr,
985 data_buf);
986 break;
987 case HostCmd_CMD_802_11_GET_LOG:
988 ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr);
989 break;
990 case HostCmd_CMD_802_11_AD_HOC_JOIN:
991 ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr,
992 data_buf);
993 break;
994 case HostCmd_CMD_802_11_AD_HOC_STOP:
995 ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr);
996 break;
997 case HostCmd_CMD_RSSI_INFO:
998 ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action);
999 break;
1000 case HostCmd_CMD_802_11_SNMP_MIB:
1001 ret = mwifiex_cmd_802_11_snmp_mib(priv, cmd_ptr, cmd_action,
1002 cmd_oid, data_buf);
1003 break;
1004 case HostCmd_CMD_802_11_TX_RATE_QUERY:
1005 cmd_ptr->command =
1006 cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
1007 cmd_ptr->size =
1008 cpu_to_le16(sizeof(struct host_cmd_ds_tx_rate_query) +
1009 S_DS_GEN);
1010 priv->tx_rate = 0;
1011 ret = 0;
1012 break;
1013 case HostCmd_CMD_VERSION_EXT:
1014 cmd_ptr->command = cpu_to_le16(cmd_no);
1015 cmd_ptr->params.verext.version_str_sel =
1016 (u8) (*((u32 *) data_buf));
1017 memcpy(&cmd_ptr->params, data_buf,
1018 sizeof(struct host_cmd_ds_version_ext));
1019 cmd_ptr->size =
1020 cpu_to_le16(sizeof(struct host_cmd_ds_version_ext) +
1021 S_DS_GEN);
1022 ret = 0;
1023 break;
1024 case HostCmd_CMD_802_11_RF_CHANNEL:
1025 ret = mwifiex_cmd_802_11_rf_channel(priv, cmd_ptr, cmd_action,
1026 data_buf);
1027 break;
1028 case HostCmd_CMD_FUNC_INIT:
1029 if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
1030 priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
1031 cmd_ptr->command = cpu_to_le16(cmd_no);
1032 cmd_ptr->size = cpu_to_le16(S_DS_GEN);
1033 break;
1034 case HostCmd_CMD_FUNC_SHUTDOWN:
1035 priv->adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
1036 cmd_ptr->command = cpu_to_le16(cmd_no);
1037 cmd_ptr->size = cpu_to_le16(S_DS_GEN);
1038 break;
1039 case HostCmd_CMD_11N_ADDBA_REQ:
1040 ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf);
1041 break;
1042 case HostCmd_CMD_11N_DELBA:
1043 ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf);
1044 break;
1045 case HostCmd_CMD_11N_ADDBA_RSP:
1046 ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf);
1047 break;
1048 case HostCmd_CMD_802_11_KEY_MATERIAL:
1049 ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr,
1050 cmd_action, cmd_oid,
1051 data_buf);
1052 break;
1053 case HostCmd_CMD_802_11D_DOMAIN_INFO:
1054 ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr,
1055 cmd_action);
1056 break;
1057 case HostCmd_CMD_RECONFIGURE_TX_BUFF:
1058 ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action,
1059 data_buf);
1060 break;
1061 case HostCmd_CMD_AMSDU_AGGR_CTRL:
1062 ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action,
1063 data_buf);
1064 break;
1065 case HostCmd_CMD_11N_CFG:
1066 ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action,
1067 data_buf);
1068 break;
1069 case HostCmd_CMD_WMM_GET_STATUS:
1070 dev_dbg(priv->adapter->dev,
1071 "cmd: WMM: WMM_GET_STATUS cmd sent\n");
1072 cmd_ptr->command = cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
1073 cmd_ptr->size =
1074 cpu_to_le16(sizeof(struct host_cmd_ds_wmm_get_status) +
1075 S_DS_GEN);
1076 ret = 0;
1077 break;
1078 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
1079 ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr,
1080 cmd_action, data_buf);
1081 break;
1082 case HostCmd_CMD_MAC_REG_ACCESS:
1083 case HostCmd_CMD_BBP_REG_ACCESS:
1084 case HostCmd_CMD_RF_REG_ACCESS:
1085 case HostCmd_CMD_PMIC_REG_ACCESS:
1086 case HostCmd_CMD_CAU_REG_ACCESS:
1087 case HostCmd_CMD_802_11_EEPROM_ACCESS:
1088 ret = mwifiex_cmd_reg_access(cmd_ptr, cmd_action, data_buf);
1089 break;
1090 case HostCmd_CMD_SET_BSS_MODE:
1091 cmd_ptr->command = cpu_to_le16(cmd_no);
1092 if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
1093 cmd_ptr->params.bss_mode.con_type =
1094 CONNECTION_TYPE_ADHOC;
1095 else if (priv->bss_mode == NL80211_IFTYPE_STATION)
1096 cmd_ptr->params.bss_mode.con_type =
1097 CONNECTION_TYPE_INFRA;
1098 cmd_ptr->size = cpu_to_le16(sizeof(struct
1099 host_cmd_ds_set_bss_mode) + S_DS_GEN);
1100 ret = 0;
1101 break;
1102 default:
1103 dev_err(priv->adapter->dev,
1104 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
1105 ret = -1;
1106 break;
1107 }
1108 return ret;
1109}
1110
1111/*
1112 * This function issues commands to initialize firmware.
1113 *
1114 * This is called after firmware download to bring the card to
1115 * working state.
1116 *
1117 * The following commands are issued sequentially -
1118 * - Function init (for first interface only)
1119 * - Read MAC address (for first interface only)
1120 * - Reconfigure Tx buffer size (for first interface only)
1121 * - Enable auto deep sleep (for first interface only)
1122 * - Get Tx rate
1123 * - Get Tx power
1124 * - Set IBSS coalescing status
1125 * - Set AMSDU aggregation control
1126 * - Set 11d control
1127 * - Set MAC control (this must be the last command to initialize firmware)
1128 */
1129int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1130{
1131 int ret = 0;
1132 u16 enable = true;
1133 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
1134 struct mwifiex_ds_auto_ds auto_ds;
1135 enum state_11d_t state_11d;
1136
1137 if (first_sta) {
1138
1139 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT,
1140 HostCmd_ACT_GEN_SET, 0, NULL, NULL);
1141 if (ret)
1142 return -1;
1143 /* Read MAC address from HW */
1144 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC,
1145 HostCmd_ACT_GEN_GET, 0, NULL, NULL);
1146 if (ret)
1147 return -1;
1148
1149 /* Reconfigure tx buf size */
1150 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
1151 HostCmd_ACT_GEN_SET, 0, NULL,
1152 &priv->adapter->tx_buf_size);
1153 if (ret)
1154 return -1;
1155
1156 /* Enable IEEE PS by default */
1157 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1158 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1159 EN_AUTO_PS, BITMAP_STA_PS, NULL,
1160 NULL);
1161 if (ret)
1162 return -1;
1163 }
1164
1165 /* get tx rate */
1166 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1167 HostCmd_ACT_GEN_GET, 0, NULL, NULL);
1168 if (ret)
1169 return -1;
1170 priv->data_rate = 0;
1171
1172 /* get tx power */
1173 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG,
1174 HostCmd_ACT_GEN_GET, 0, NULL, NULL);
1175 if (ret)
1176 return -1;
1177
1178 /* set ibss coalescing_status */
1179 ret = mwifiex_prepare_cmd(priv,
1180 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
1181 HostCmd_ACT_GEN_SET, 0, NULL, &enable);
1182 if (ret)
1183 return -1;
1184
1185 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
1186 amsdu_aggr_ctrl.enable = true;
1187 /* Send request to firmware */
1188 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
1189 HostCmd_ACT_GEN_SET, 0, NULL,
1190 (void *) &amsdu_aggr_ctrl);
1191 if (ret)
1192 return -1;
1193 /* MAC Control must be the last command in init_fw */
1194 /* set MAC Control */
1195 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1196 HostCmd_ACT_GEN_SET, 0, NULL,
1197 &priv->curr_pkt_filter);
1198 if (ret)
1199 return -1;
1200
1201 if (first_sta) {
1202 /* Enable auto deep sleep */
1203 auto_ds.auto_ds = DEEP_SLEEP_ON;
1204 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
1205 ret = mwifiex_prepare_cmd(priv,
1206 HostCmd_CMD_802_11_PS_MODE_ENH,
1207 EN_AUTO_PS, BITMAP_AUTO_DS, NULL,
1208 &auto_ds);
1209 if (ret)
1210 return -1;
1211 }
1212
1213 /* Send cmd to FW to enable/disable 11D function */
1214 state_11d = ENABLE_11D;
1215 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
1216 HostCmd_ACT_GEN_SET, DOT11D_I,
1217 NULL, &state_11d);
1218 if (ret)
1219 dev_err(priv->adapter->dev, "11D: failed to enable 11D\n");
1220
1221 /* set last_init_cmd */
1222 priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB;
1223 ret = -EINPROGRESS;
1224
1225 return ret;
1226}
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
new file mode 100644
index 000000000000..74add45b99b6
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -0,0 +1,983 @@
1/*
2 * Marvell Wireless LAN device driver: station command response handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28
29/*
30 * This function handles the command response error case.
31 *
32 * For scan response error, the function cancels all the pending
33 * scan commands and generates an event to inform the applications
34 * of the scan completion.
35 *
36 * For Power Save command failure, we do not retry enter PS
37 * command in case of Ad-hoc mode.
38 *
39 * For all other response errors, the current command buffer is freed
40 * and returned to the free command queue.
41 */
42static void
43mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
44 struct host_cmd_ds_command *resp,
45 struct mwifiex_wait_queue *wq_buf)
46{
47 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
48 struct mwifiex_adapter *adapter = priv->adapter;
49 struct host_cmd_ds_802_11_ps_mode_enh *pm;
50 unsigned long flags;
51
52 dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n",
53 resp->command, resp->result);
54 if (wq_buf)
55 wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP;
56
57 switch (le16_to_cpu(resp->command)) {
58 case HostCmd_CMD_802_11_PS_MODE_ENH:
59 pm = &resp->params.psmode_enh;
60 dev_err(adapter->dev, "PS_MODE_ENH cmd failed: "
61 "result=0x%x action=0x%X\n",
62 resp->result, le16_to_cpu(pm->action));
63 /* We do not re-try enter-ps command in ad-hoc mode. */
64 if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
65 (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
66 priv->bss_mode == NL80211_IFTYPE_ADHOC)
67 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
68
69 break;
70 case HostCmd_CMD_802_11_SCAN:
71 /* Cancel all pending scan command */
72 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
73 list_for_each_entry_safe(cmd_node, tmp_node,
74 &adapter->scan_pending_q, list) {
75 list_del(&cmd_node->list);
76 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
77 flags);
78 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
79 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
80 }
81 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
82
83 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
84 adapter->scan_processing = false;
85 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
86 if (priv->report_scan_result)
87 priv->report_scan_result = false;
88 if (priv->scan_pending_on_block) {
89 priv->scan_pending_on_block = false;
90 up(&priv->async_sem);
91 }
92 break;
93
94 case HostCmd_CMD_MAC_CONTROL:
95 break;
96
97 default:
98 break;
99 }
100 /* Handling errors here */
101 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
102
103 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
104 adapter->curr_cmd = NULL;
105 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
106
107 return;
108}
109
110/*
111 * This function handles the command response of get RSSI info.
112 *
113 * Handling includes changing the header fields into CPU format
114 * and saving the following parameters in driver -
115 * - Last data and beacon RSSI value
116 * - Average data and beacon RSSI value
117 * - Last data and beacon NF value
118 * - Average data and beacon NF value
119 *
120 * The parameters are send to the application as well, along with
121 * calculated SNR values.
122 */
123static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
124 struct host_cmd_ds_command *resp,
125 void *data_buf)
126{
127 struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
128 &resp->params.rssi_info_rsp;
129 struct mwifiex_ds_get_signal *signal = NULL;
130
131 priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
132 priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
133
134 priv->data_rssi_avg = le16_to_cpu(rssi_info_rsp->data_rssi_avg);
135 priv->data_nf_avg = le16_to_cpu(rssi_info_rsp->data_nf_avg);
136
137 priv->bcn_rssi_last = le16_to_cpu(rssi_info_rsp->bcn_rssi_last);
138 priv->bcn_nf_last = le16_to_cpu(rssi_info_rsp->bcn_nf_last);
139
140 priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg);
141 priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg);
142
143 /* Need to indicate IOCTL complete */
144 if (data_buf) {
145 signal = (struct mwifiex_ds_get_signal *) data_buf;
146 memset(signal, 0, sizeof(struct mwifiex_ds_get_signal));
147
148 signal->selector = ALL_RSSI_INFO_MASK;
149
150 /* RSSI */
151 signal->bcn_rssi_last = priv->bcn_rssi_last;
152 signal->bcn_rssi_avg = priv->bcn_rssi_avg;
153 signal->data_rssi_last = priv->data_rssi_last;
154 signal->data_rssi_avg = priv->data_rssi_avg;
155
156 /* SNR */
157 signal->bcn_snr_last =
158 CAL_SNR(priv->bcn_rssi_last, priv->bcn_nf_last);
159 signal->bcn_snr_avg =
160 CAL_SNR(priv->bcn_rssi_avg, priv->bcn_nf_avg);
161 signal->data_snr_last =
162 CAL_SNR(priv->data_rssi_last, priv->data_nf_last);
163 signal->data_snr_avg =
164 CAL_SNR(priv->data_rssi_avg, priv->data_nf_avg);
165
166 /* NF */
167 signal->bcn_nf_last = priv->bcn_nf_last;
168 signal->bcn_nf_avg = priv->bcn_nf_avg;
169 signal->data_nf_last = priv->data_nf_last;
170 signal->data_nf_avg = priv->data_nf_avg;
171 }
172
173 return 0;
174}
175
176/*
177 * This function handles the command response of set/get SNMP
178 * MIB parameters.
179 *
180 * Handling includes changing the header fields into CPU format
181 * and saving the parameter in driver.
182 *
183 * The following parameters are supported -
184 * - Fragmentation threshold
185 * - RTS threshold
186 * - Short retry limit
187 */
188static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
189 struct host_cmd_ds_command *resp,
190 void *data_buf)
191{
192 struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
193 u16 oid = le16_to_cpu(smib->oid);
194 u16 query_type = le16_to_cpu(smib->query_type);
195 u32 ul_temp;
196
197 dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x,"
198 " query_type = %#x, buf size = %#x\n",
199 oid, query_type, le16_to_cpu(smib->buf_size));
200 if (query_type == HostCmd_ACT_GEN_GET) {
201 ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
202 if (data_buf)
203 *(u32 *)data_buf = ul_temp;
204 switch (oid) {
205 case FRAG_THRESH_I:
206 dev_dbg(priv->adapter->dev,
207 "info: SNMP_RESP: FragThsd =%u\n", ul_temp);
208 break;
209 case RTS_THRESH_I:
210 dev_dbg(priv->adapter->dev,
211 "info: SNMP_RESP: RTSThsd =%u\n", ul_temp);
212 break;
213 case SHORT_RETRY_LIM_I:
214 dev_dbg(priv->adapter->dev,
215 "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp);
216 break;
217 default:
218 break;
219 }
220 }
221
222 return 0;
223}
224
225/*
226 * This function handles the command response of get log request
227 *
228 * Handling includes changing the header fields into CPU format
229 * and sending the received parameters to application.
230 */
231static int mwifiex_ret_get_log(struct mwifiex_private *priv,
232 struct host_cmd_ds_command *resp,
233 void *data_buf)
234{
235 struct host_cmd_ds_802_11_get_log *get_log =
236 (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log;
237 struct mwifiex_ds_get_stats *stats = NULL;
238
239 if (data_buf) {
240 stats = (struct mwifiex_ds_get_stats *) data_buf;
241 stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame);
242 stats->failed = le32_to_cpu(get_log->failed);
243 stats->retry = le32_to_cpu(get_log->retry);
244 stats->multi_retry = le32_to_cpu(get_log->multi_retry);
245 stats->frame_dup = le32_to_cpu(get_log->frame_dup);
246 stats->rts_success = le32_to_cpu(get_log->rts_success);
247 stats->rts_failure = le32_to_cpu(get_log->rts_failure);
248 stats->ack_failure = le32_to_cpu(get_log->ack_failure);
249 stats->rx_frag = le32_to_cpu(get_log->rx_frag);
250 stats->mcast_rx_frame = le32_to_cpu(get_log->mcast_rx_frame);
251 stats->fcs_error = le32_to_cpu(get_log->fcs_error);
252 stats->tx_frame = le32_to_cpu(get_log->tx_frame);
253 stats->wep_icv_error[0] =
254 le32_to_cpu(get_log->wep_icv_err_cnt[0]);
255 stats->wep_icv_error[1] =
256 le32_to_cpu(get_log->wep_icv_err_cnt[1]);
257 stats->wep_icv_error[2] =
258 le32_to_cpu(get_log->wep_icv_err_cnt[2]);
259 stats->wep_icv_error[3] =
260 le32_to_cpu(get_log->wep_icv_err_cnt[3]);
261 }
262
263 return 0;
264}
265
266/*
267 * This function handles the command response of set/get Tx rate
268 * configurations.
269 *
270 * Handling includes changing the header fields into CPU format
271 * and saving the following parameters in driver -
272 * - DSSS rate bitmap
273 * - OFDM rate bitmap
274 * - HT MCS rate bitmaps
275 *
276 * Based on the new rate bitmaps, the function re-evaluates if
277 * auto data rate has been activated. If not, it sends another
278 * query to the firmware to get the current Tx data rate and updates
279 * the driver value.
280 */
281static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
282 struct host_cmd_ds_command *resp,
283 void *data_buf)
284{
285 struct mwifiex_adapter *adapter = priv->adapter;
286 struct mwifiex_rate_cfg *ds_rate = NULL;
287 struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg;
288 struct mwifiex_rate_scope *rate_scope;
289 struct mwifiex_ie_types_header *head = NULL;
290 u16 tlv, tlv_buf_len;
291 u8 *tlv_buf;
292 u32 i;
293 int ret = 0;
294
295 tlv_buf = (u8 *) ((u8 *) rate_cfg) +
296 sizeof(struct host_cmd_ds_tx_rate_cfg);
297 tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16));
298
299 while (tlv_buf && tlv_buf_len > 0) {
300 tlv = (*tlv_buf);
301 tlv = tlv | (*(tlv_buf + 1) << 8);
302
303 switch (tlv) {
304 case TLV_TYPE_RATE_SCOPE:
305 rate_scope = (struct mwifiex_rate_scope *) tlv_buf;
306 priv->bitmap_rates[0] =
307 le16_to_cpu(rate_scope->hr_dsss_rate_bitmap);
308 priv->bitmap_rates[1] =
309 le16_to_cpu(rate_scope->ofdm_rate_bitmap);
310 for (i = 0;
311 i <
312 sizeof(rate_scope->ht_mcs_rate_bitmap) /
313 sizeof(u16); i++)
314 priv->bitmap_rates[2 + i] =
315 le16_to_cpu(rate_scope->
316 ht_mcs_rate_bitmap[i]);
317 break;
318 /* Add RATE_DROP tlv here */
319 }
320
321 head = (struct mwifiex_ie_types_header *) tlv_buf;
322 tlv_buf += le16_to_cpu(head->len) + sizeof(*head);
323 tlv_buf_len -= le16_to_cpu(head->len);
324 }
325
326 priv->is_data_rate_auto = mwifiex_is_rate_auto(priv);
327
328 if (priv->is_data_rate_auto)
329 priv->data_rate = 0;
330 else
331 ret = mwifiex_prepare_cmd(priv,
332 HostCmd_CMD_802_11_TX_RATE_QUERY,
333 HostCmd_ACT_GEN_GET, 0, NULL, NULL);
334
335 if (data_buf) {
336 ds_rate = (struct mwifiex_rate_cfg *) data_buf;
337 if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
338 if (priv->is_data_rate_auto) {
339 ds_rate->is_rate_auto = 1;
340 } else {
341 ds_rate->rate =
342 mwifiex_get_rate_index(adapter,
343 priv->
344 bitmap_rates,
345 sizeof(priv->
346 bitmap_rates));
347 if (ds_rate->rate >=
348 MWIFIEX_RATE_BITMAP_OFDM0
349 && ds_rate->rate <=
350 MWIFIEX_RATE_BITMAP_OFDM7)
351 ds_rate->rate -=
352 (MWIFIEX_RATE_BITMAP_OFDM0 -
353 MWIFIEX_RATE_INDEX_OFDM0);
354 if (ds_rate->rate >=
355 MWIFIEX_RATE_BITMAP_MCS0
356 && ds_rate->rate <=
357 MWIFIEX_RATE_BITMAP_MCS127)
358 ds_rate->rate -=
359 (MWIFIEX_RATE_BITMAP_MCS0 -
360 MWIFIEX_RATE_INDEX_MCS0);
361 }
362 }
363 }
364
365 return ret;
366}
367
368/*
369 * This function handles the command response of get Tx power level.
370 *
371 * Handling includes saving the maximum and minimum Tx power levels
372 * in driver, as well as sending the values to user.
373 */
374static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
375{
376 int length = -1, max_power = -1, min_power = -1;
377 struct mwifiex_types_power_group *pg_tlv_hdr = NULL;
378 struct mwifiex_power_group *pg = NULL;
379
380 if (data_buf) {
381 pg_tlv_hdr =
382 (struct mwifiex_types_power_group *) ((u8 *) data_buf
383 + sizeof(struct host_cmd_ds_txpwr_cfg));
384 pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr +
385 sizeof(struct mwifiex_types_power_group));
386 length = pg_tlv_hdr->length;
387 if (length > 0) {
388 max_power = pg->power_max;
389 min_power = pg->power_min;
390 length -= sizeof(struct mwifiex_power_group);
391 }
392 while (length) {
393 pg++;
394 if (max_power < pg->power_max)
395 max_power = pg->power_max;
396
397 if (min_power > pg->power_min)
398 min_power = pg->power_min;
399
400 length -= sizeof(struct mwifiex_power_group);
401 }
402 if (pg_tlv_hdr->length > 0) {
403 priv->min_tx_power_level = (u8) min_power;
404 priv->max_tx_power_level = (u8) max_power;
405 }
406 } else {
407 return -1;
408 }
409
410 return 0;
411}
412
413/*
414 * This function handles the command response of set/get Tx power
415 * configurations.
416 *
417 * Handling includes changing the header fields into CPU format
418 * and saving the current Tx power level in driver.
419 */
420static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
421 struct host_cmd_ds_command *resp,
422 void *data_buf)
423{
424 struct mwifiex_adapter *adapter = priv->adapter;
425 struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg;
426 struct mwifiex_types_power_group *pg_tlv_hdr = NULL;
427 struct mwifiex_power_group *pg = NULL;
428 u16 action = le16_to_cpu(txp_cfg->action);
429
430 switch (action) {
431 case HostCmd_ACT_GEN_GET:
432 {
433 pg_tlv_hdr =
434 (struct mwifiex_types_power_group *) ((u8 *)
435 txp_cfg +
436 sizeof
437 (struct
438 host_cmd_ds_txpwr_cfg));
439 pg = (struct mwifiex_power_group *) ((u8 *)
440 pg_tlv_hdr +
441 sizeof(struct
442 mwifiex_types_power_group));
443 if (adapter->hw_status ==
444 MWIFIEX_HW_STATUS_INITIALIZING)
445 mwifiex_get_power_level(priv, txp_cfg);
446 priv->tx_power_level = (u16) pg->power_min;
447 break;
448 }
449 case HostCmd_ACT_GEN_SET:
450 if (le32_to_cpu(txp_cfg->mode)) {
451 pg_tlv_hdr =
452 (struct mwifiex_types_power_group *) ((u8 *)
453 txp_cfg +
454 sizeof
455 (struct
456 host_cmd_ds_txpwr_cfg));
457 pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr
458 +
459 sizeof(struct
460 mwifiex_types_power_group));
461 if (pg->power_max == pg->power_min)
462 priv->tx_power_level = (u16) pg->power_min;
463 }
464 break;
465 default:
466 dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n",
467 action);
468 return 0;
469 }
470 dev_dbg(adapter->dev,
471 "info: Current TxPower Level = %d, Max Power=%d, Min Power=%d\n",
472 priv->tx_power_level, priv->max_tx_power_level,
473 priv->min_tx_power_level);
474
475 return 0;
476}
477
478/*
479 * This function handles the command response of set/get MAC address.
480 *
481 * Handling includes saving the MAC address in driver.
482 */
483static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv,
484 struct host_cmd_ds_command *resp)
485{
486 struct host_cmd_ds_802_11_mac_address *cmd_mac_addr =
487 &resp->params.mac_addr;
488
489 memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN);
490
491 dev_dbg(priv->adapter->dev,
492 "info: set mac address: %pM\n", priv->curr_addr);
493
494 return 0;
495}
496
497/*
498 * This function handles the command response of set/get MAC multicast
499 * address.
500 */
501static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv,
502 struct host_cmd_ds_command *resp)
503{
504 return 0;
505}
506
507/*
508 * This function handles the command response of get Tx rate query.
509 *
510 * Handling includes changing the header fields into CPU format
511 * and saving the Tx rate and HT information parameters in driver.
512 *
513 * Both rate configuration and current data rate can be retrieved
514 * with this request.
515 */
516static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv,
517 struct host_cmd_ds_command *resp)
518{
519 struct mwifiex_adapter *adapter = priv->adapter;
520
521 priv->tx_rate = resp->params.tx_rate.tx_rate;
522 priv->tx_htinfo = resp->params.tx_rate.ht_info;
523 if (!priv->is_data_rate_auto)
524 priv->data_rate =
525 mwifiex_index_to_data_rate(adapter, priv->tx_rate,
526 priv->tx_htinfo);
527
528 return 0;
529}
530
531/*
532 * This function handles the command response of a deauthenticate
533 * command.
534 *
535 * If the deauthenticated MAC matches the current BSS MAC, the connection
536 * state is reset.
537 */
538static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
539 struct host_cmd_ds_command *resp)
540{
541 struct mwifiex_adapter *adapter = priv->adapter;
542
543 adapter->dbg.num_cmd_deauth++;
544 if (!memcmp(resp->params.deauth.mac_addr,
545 &priv->curr_bss_params.bss_descriptor.mac_address,
546 sizeof(resp->params.deauth.mac_addr)))
547 mwifiex_reset_connect_state(priv);
548
549 return 0;
550}
551
552/*
553 * This function handles the command response of ad-hoc stop.
554 *
555 * The function resets the connection state in driver.
556 */
557static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
558 struct host_cmd_ds_command *resp)
559{
560 mwifiex_reset_connect_state(priv);
561 return 0;
562}
563
564/*
565 * This function handles the command response of set/get key material.
566 *
567 * Handling includes updating the driver parameters to reflect the
568 * changes.
569 */
570static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
571 struct host_cmd_ds_command *resp)
572{
573 struct host_cmd_ds_802_11_key_material *key =
574 &resp->params.key_material;
575
576 if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
577 if ((le16_to_cpu(key->key_param_set.key_info) &
578 KEY_INFO_TKIP_MCAST)) {
579 dev_dbg(priv->adapter->dev, "info: key: GTK is set\n");
580 priv->wpa_is_gtk_set = true;
581 priv->scan_block = false;
582 }
583 }
584
585 memset(priv->aes_key.key_param_set.key, 0,
586 sizeof(key->key_param_set.key));
587 priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
588 memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
589 le16_to_cpu(priv->aes_key.key_param_set.key_len));
590
591 return 0;
592}
593
594/*
595 * This function handles the command response of get 11d domain information.
596 */
597static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
598 struct host_cmd_ds_command *resp)
599{
600 struct host_cmd_ds_802_11d_domain_info_rsp *domain_info =
601 &resp->params.domain_info_resp;
602 struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain;
603 u16 action = le16_to_cpu(domain_info->action);
604 u8 no_of_triplet = 0;
605
606 no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) -
607 IEEE80211_COUNTRY_STRING_LEN) /
608 sizeof(struct ieee80211_country_ie_triplet));
609
610 dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:"
611 " no_of_triplet=%d\n", no_of_triplet);
612
613 if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) {
614 dev_warn(priv->adapter->dev,
615 "11D: invalid number of triplets %d "
616 "returned!!\n", no_of_triplet);
617 return -1;
618 }
619
620 switch (action) {
621 case HostCmd_ACT_GEN_SET: /* Proc Set Action */
622 break;
623 case HostCmd_ACT_GEN_GET:
624 break;
625 default:
626 dev_err(priv->adapter->dev,
627 "11D: invalid action:%d\n", domain_info->action);
628 return -1;
629 }
630
631 return 0;
632}
633
634/*
635 * This function handles the command response of get RF channel.
636 *
637 * Handling includes changing the header fields into CPU format
638 * and saving the new channel in driver.
639 */
640static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv,
641 struct host_cmd_ds_command *resp,
642 void *data_buf)
643{
644 struct host_cmd_ds_802_11_rf_channel *rf_channel =
645 &resp->params.rf_channel;
646 u16 new_channel = le16_to_cpu(rf_channel->current_channel);
647
648 if (priv->curr_bss_params.bss_descriptor.channel != new_channel) {
649 dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n",
650 priv->curr_bss_params.bss_descriptor.channel,
651 new_channel);
652 /* Update the channel again */
653 priv->curr_bss_params.bss_descriptor.channel = new_channel;
654 }
655 if (data_buf)
656 *((u16 *)data_buf) = new_channel;
657
658 return 0;
659}
660
661/*
662 * This function handles the command response of get extended version.
663 *
664 * Handling includes forming the extended version string and sending it
665 * to application.
666 */
667static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
668 struct host_cmd_ds_command *resp,
669 void *data_buf)
670{
671 struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext;
672 struct host_cmd_ds_version_ext *version_ext = NULL;
673
674 if (data_buf) {
675 version_ext = (struct host_cmd_ds_version_ext *)data_buf;
676 version_ext->version_str_sel = ver_ext->version_str_sel;
677 memcpy(version_ext->version_str, ver_ext->version_str,
678 sizeof(char) * 128);
679 memcpy(priv->version_str, ver_ext->version_str, 128);
680 }
681 return 0;
682}
683
684/*
685 * This function handles the command response of register access.
686 *
687 * The register value and offset are returned to the user. For EEPROM
688 * access, the byte count is also returned.
689 */
690static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
691 void *data_buf)
692{
693 struct mwifiex_ds_reg_rw *reg_rw = NULL;
694 struct mwifiex_ds_read_eeprom *eeprom = NULL;
695
696 if (data_buf) {
697 reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
698 eeprom = (struct mwifiex_ds_read_eeprom *) data_buf;
699 switch (type) {
700 case HostCmd_CMD_MAC_REG_ACCESS:
701 {
702 struct host_cmd_ds_mac_reg_access *reg;
703 reg = (struct host_cmd_ds_mac_reg_access *)
704 &resp->params.mac_reg;
705 reg_rw->offset = cpu_to_le32(
706 (u32) le16_to_cpu(reg->offset));
707 reg_rw->value = reg->value;
708 break;
709 }
710 case HostCmd_CMD_BBP_REG_ACCESS:
711 {
712 struct host_cmd_ds_bbp_reg_access *reg;
713 reg = (struct host_cmd_ds_bbp_reg_access *)
714 &resp->params.bbp_reg;
715 reg_rw->offset = cpu_to_le32(
716 (u32) le16_to_cpu(reg->offset));
717 reg_rw->value = cpu_to_le32((u32) reg->value);
718 break;
719 }
720
721 case HostCmd_CMD_RF_REG_ACCESS:
722 {
723 struct host_cmd_ds_rf_reg_access *reg;
724 reg = (struct host_cmd_ds_rf_reg_access *)
725 &resp->params.rf_reg;
726 reg_rw->offset = cpu_to_le32(
727 (u32) le16_to_cpu(reg->offset));
728 reg_rw->value = cpu_to_le32((u32) reg->value);
729 break;
730 }
731 case HostCmd_CMD_PMIC_REG_ACCESS:
732 {
733 struct host_cmd_ds_pmic_reg_access *reg;
734 reg = (struct host_cmd_ds_pmic_reg_access *)
735 &resp->params.pmic_reg;
736 reg_rw->offset = cpu_to_le32(
737 (u32) le16_to_cpu(reg->offset));
738 reg_rw->value = cpu_to_le32((u32) reg->value);
739 break;
740 }
741 case HostCmd_CMD_CAU_REG_ACCESS:
742 {
743 struct host_cmd_ds_rf_reg_access *reg;
744 reg = (struct host_cmd_ds_rf_reg_access *)
745 &resp->params.rf_reg;
746 reg_rw->offset = cpu_to_le32(
747 (u32) le16_to_cpu(reg->offset));
748 reg_rw->value = cpu_to_le32((u32) reg->value);
749 break;
750 }
751 case HostCmd_CMD_802_11_EEPROM_ACCESS:
752 {
753 struct host_cmd_ds_802_11_eeprom_access
754 *cmd_eeprom =
755 (struct host_cmd_ds_802_11_eeprom_access
756 *) &resp->params.eeprom;
757 pr_debug("info: EEPROM read len=%x\n",
758 cmd_eeprom->byte_count);
759 if (le16_to_cpu(eeprom->byte_count) <
760 le16_to_cpu(
761 cmd_eeprom->byte_count)) {
762 eeprom->byte_count = cpu_to_le16(0);
763 pr_debug("info: EEPROM read "
764 "length is too big\n");
765 return -1;
766 }
767 eeprom->offset = cmd_eeprom->offset;
768 eeprom->byte_count = cmd_eeprom->byte_count;
769 if (le16_to_cpu(eeprom->byte_count) > 0)
770 memcpy(&eeprom->value,
771 &cmd_eeprom->value,
772 le16_to_cpu(eeprom->byte_count));
773
774 break;
775 }
776 default:
777 return -1;
778 }
779 }
780 return 0;
781}
782
783/*
784 * This function handles the command response of get IBSS coalescing status.
785 *
786 * If the received BSSID is different than the current one, the current BSSID,
787 * beacon interval, ATIM window and ERP information are updated, along with
788 * changing the ad-hoc state accordingly.
789 */
790static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
791 struct host_cmd_ds_command *resp)
792{
793 struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
794 &(resp->params.ibss_coalescing);
795 u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
796
797 if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
798 return 0;
799
800 dev_dbg(priv->adapter->dev,
801 "info: new BSSID %pM\n", ibss_coal_resp->bssid);
802
803 /* If rsp has NULL BSSID, Just return..... No Action */
804 if (!memcmp(ibss_coal_resp->bssid, zero_mac, ETH_ALEN)) {
805 dev_warn(priv->adapter->dev, "new BSSID is NULL\n");
806 return 0;
807 }
808
809 /* If BSSID is diff, modify current BSS parameters */
810 if (memcmp(priv->curr_bss_params.bss_descriptor.mac_address,
811 ibss_coal_resp->bssid, ETH_ALEN)) {
812 /* BSSID */
813 memcpy(priv->curr_bss_params.bss_descriptor.mac_address,
814 ibss_coal_resp->bssid, ETH_ALEN);
815
816 /* Beacon Interval */
817 priv->curr_bss_params.bss_descriptor.beacon_period
818 = le16_to_cpu(ibss_coal_resp->beacon_interval);
819
820 /* ERP Information */
821 priv->curr_bss_params.bss_descriptor.erp_flags =
822 (u8) le16_to_cpu(ibss_coal_resp->use_g_rate_protect);
823
824 priv->adhoc_state = ADHOC_COALESCED;
825 }
826
827 return 0;
828}
829
830/*
831 * This function handles the command responses.
832 *
833 * This is a generic function, which calls command specific
834 * response handlers based on the command ID.
835 */
836int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
837 u16 cmdresp_no, void *cmd_buf, void *wq_buf)
838{
839 int ret = 0;
840 struct mwifiex_adapter *adapter = priv->adapter;
841 struct host_cmd_ds_command *resp =
842 (struct host_cmd_ds_command *) cmd_buf;
843 struct mwifiex_wait_queue *wait_queue =
844 (struct mwifiex_wait_queue *) wq_buf;
845 void *data_buf = adapter->curr_cmd->data_buf;
846
847 /* If the command is not successful, cleanup and return failure */
848 if (resp->result != HostCmd_RESULT_OK) {
849 mwifiex_process_cmdresp_error(priv, resp, wait_queue);
850 return -1;
851 }
852 /* Command successful, handle response */
853 switch (cmdresp_no) {
854 case HostCmd_CMD_GET_HW_SPEC:
855 ret = mwifiex_ret_get_hw_spec(priv, resp);
856 break;
857 case HostCmd_CMD_MAC_CONTROL:
858 break;
859 case HostCmd_CMD_802_11_MAC_ADDRESS:
860 ret = mwifiex_ret_802_11_mac_address(priv, resp);
861 break;
862 case HostCmd_CMD_MAC_MULTICAST_ADR:
863 ret = mwifiex_ret_mac_multicast_adr(priv, resp);
864 break;
865 case HostCmd_CMD_TX_RATE_CFG:
866 ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf);
867 break;
868 case HostCmd_CMD_802_11_SCAN:
869 ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue);
870 wait_queue = NULL;
871 adapter->curr_cmd->wq_buf = NULL;
872 break;
873 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
874 ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue);
875 dev_dbg(adapter->dev,
876 "info: CMD_RESP: BG_SCAN result is ready!\n");
877 break;
878 case HostCmd_CMD_TXPWR_CFG:
879 ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf);
880 break;
881 case HostCmd_CMD_802_11_PS_MODE_ENH:
882 ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf);
883 break;
884 case HostCmd_CMD_802_11_HS_CFG_ENH:
885 ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
886 break;
887 case HostCmd_CMD_802_11_ASSOCIATE:
888 ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue);
889 break;
890 case HostCmd_CMD_802_11_DEAUTHENTICATE:
891 ret = mwifiex_ret_802_11_deauthenticate(priv, resp);
892 break;
893 case HostCmd_CMD_802_11_AD_HOC_START:
894 case HostCmd_CMD_802_11_AD_HOC_JOIN:
895 ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue);
896 break;
897 case HostCmd_CMD_802_11_AD_HOC_STOP:
898 ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp);
899 break;
900 case HostCmd_CMD_802_11_GET_LOG:
901 ret = mwifiex_ret_get_log(priv, resp, data_buf);
902 break;
903 case HostCmd_CMD_RSSI_INFO:
904 ret = mwifiex_ret_802_11_rssi_info(priv, resp, data_buf);
905 break;
906 case HostCmd_CMD_802_11_SNMP_MIB:
907 ret = mwifiex_ret_802_11_snmp_mib(priv, resp, data_buf);
908 break;
909 case HostCmd_CMD_802_11_TX_RATE_QUERY:
910 ret = mwifiex_ret_802_11_tx_rate_query(priv, resp);
911 break;
912 case HostCmd_CMD_802_11_RF_CHANNEL:
913 ret = mwifiex_ret_802_11_rf_channel(priv, resp, data_buf);
914 break;
915 case HostCmd_CMD_VERSION_EXT:
916 ret = mwifiex_ret_ver_ext(priv, resp, data_buf);
917 break;
918 case HostCmd_CMD_FUNC_INIT:
919 case HostCmd_CMD_FUNC_SHUTDOWN:
920 break;
921 case HostCmd_CMD_802_11_KEY_MATERIAL:
922 ret = mwifiex_ret_802_11_key_material(priv, resp);
923 break;
924 case HostCmd_CMD_802_11D_DOMAIN_INFO:
925 ret = mwifiex_ret_802_11d_domain_info(priv, resp);
926 break;
927 case HostCmd_CMD_11N_ADDBA_REQ:
928 ret = mwifiex_ret_11n_addba_req(priv, resp);
929 break;
930 case HostCmd_CMD_11N_DELBA:
931 ret = mwifiex_ret_11n_delba(priv, resp);
932 break;
933 case HostCmd_CMD_11N_ADDBA_RSP:
934 ret = mwifiex_ret_11n_addba_resp(priv, resp);
935 break;
936 case HostCmd_CMD_RECONFIGURE_TX_BUFF:
937 adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
938 tx_buf.buff_size);
939 adapter->tx_buf_size = (adapter->tx_buf_size /
940 MWIFIEX_SDIO_BLOCK_SIZE) *
941 MWIFIEX_SDIO_BLOCK_SIZE;
942 adapter->curr_tx_buf_size = adapter->tx_buf_size;
943 dev_dbg(adapter->dev,
944 "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n",
945 adapter->max_tx_buf_size, adapter->tx_buf_size);
946
947 if (adapter->if_ops.update_mp_end_port)
948 adapter->if_ops.update_mp_end_port(adapter,
949 le16_to_cpu(resp->
950 params.
951 tx_buf.
952 mp_end_port));
953 break;
954 case HostCmd_CMD_AMSDU_AGGR_CTRL:
955 ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf);
956 break;
957 case HostCmd_CMD_WMM_GET_STATUS:
958 ret = mwifiex_ret_wmm_get_status(priv, resp);
959 break;
960 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
961 ret = mwifiex_ret_ibss_coalescing_status(priv, resp);
962 break;
963 case HostCmd_CMD_MAC_REG_ACCESS:
964 case HostCmd_CMD_BBP_REG_ACCESS:
965 case HostCmd_CMD_RF_REG_ACCESS:
966 case HostCmd_CMD_PMIC_REG_ACCESS:
967 case HostCmd_CMD_CAU_REG_ACCESS:
968 case HostCmd_CMD_802_11_EEPROM_ACCESS:
969 ret = mwifiex_ret_reg_access(cmdresp_no, resp, data_buf);
970 break;
971 case HostCmd_CMD_SET_BSS_MODE:
972 break;
973 case HostCmd_CMD_11N_CFG:
974 ret = mwifiex_ret_11n_cfg(priv, resp, data_buf);
975 break;
976 default:
977 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
978 resp->command);
979 break;
980 }
981
982 return ret;
983}
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
new file mode 100644
index 000000000000..936d7c175e75
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -0,0 +1,405 @@
1/*
2 * Marvell Wireless LAN device driver: station event handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * This function resets the connection state.
30 *
31 * The function is invoked after receiving a disconnect event from firmware,
32 * and performs the following actions -
33 * - Set media status to disconnected
34 * - Clean up Tx and Rx packets
35 * - Resets SNR/NF/RSSI value in driver
36 * - Resets security configurations in driver
37 * - Enables auto data rate
38 * - Saves the previous SSID and BSSID so that they can
39 * be used for re-association, if required
40 * - Erases current SSID and BSSID information
41 * - Sends a disconnect event to upper layers/applications.
42 */
43void
44mwifiex_reset_connect_state(struct mwifiex_private *priv)
45{
46 struct mwifiex_adapter *adapter = priv->adapter;
47
48 if (!priv->media_connected)
49 return;
50
51 dev_dbg(adapter->dev, "info: handles disconnect event\n");
52
53 priv->media_connected = false;
54
55 priv->scan_block = false;
56
57 /* Free Tx and Rx packets, report disconnect to upper layer */
58 mwifiex_clean_txrx(priv);
59
60 /* Reset SNR/NF/RSSI values */
61 priv->data_rssi_last = 0;
62 priv->data_nf_last = 0;
63 priv->data_rssi_avg = 0;
64 priv->data_nf_avg = 0;
65 priv->bcn_rssi_last = 0;
66 priv->bcn_nf_last = 0;
67 priv->bcn_rssi_avg = 0;
68 priv->bcn_nf_avg = 0;
69 priv->rxpd_rate = 0;
70 priv->rxpd_htinfo = 0;
71 priv->sec_info.wpa_enabled = false;
72 priv->sec_info.wpa2_enabled = false;
73 priv->wpa_ie_len = 0;
74
75 priv->sec_info.wapi_enabled = false;
76 priv->wapi_ie_len = 0;
77 priv->sec_info.wapi_key_on = false;
78
79 priv->sec_info.encryption_mode = 0;
80
81 /* Enable auto data rate */
82 priv->is_data_rate_auto = true;
83 priv->data_rate = 0;
84
85 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
86 priv->adhoc_state = ADHOC_IDLE;
87 priv->adhoc_is_link_sensed = false;
88 }
89
90 /*
91 * Memorize the previous SSID and BSSID so
92 * it could be used for re-assoc
93 */
94
95 dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n",
96 priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
97
98 dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n",
99 priv->curr_bss_params.bss_descriptor.ssid.ssid,
100 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
101
102 memcpy(&priv->prev_ssid,
103 &priv->curr_bss_params.bss_descriptor.ssid,
104 sizeof(struct mwifiex_802_11_ssid));
105
106 memcpy(priv->prev_bssid,
107 priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
108
109 /* Need to erase the current SSID and BSSID info */
110 memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params));
111
112 adapter->tx_lock_flag = false;
113 adapter->pps_uapsd_mode = false;
114
115 if (adapter->num_cmd_timeout && adapter->curr_cmd)
116 return;
117 priv->media_connected = false;
118 if (!priv->disconnect) {
119 priv->disconnect = 1;
120 dev_dbg(adapter->dev, "info: successfully disconnected from"
121 " %pM: reason code %d\n", priv->cfg_bssid,
122 WLAN_REASON_DEAUTH_LEAVING);
123 cfg80211_disconnected(priv->netdev,
124 WLAN_REASON_DEAUTH_LEAVING, NULL, 0,
125 GFP_KERNEL);
126 queue_work(priv->workqueue, &priv->cfg_workqueue);
127 }
128 if (!netif_queue_stopped(priv->netdev))
129 netif_stop_queue(priv->netdev);
130 if (netif_carrier_ok(priv->netdev))
131 netif_carrier_off(priv->netdev);
132 /* Reset wireless stats signal info */
133 priv->w_stats.qual.level = 0;
134 priv->w_stats.qual.noise = 0;
135}
136
137/*
138 * This function handles events generated by firmware.
139 *
140 * This is a generic function and handles all events.
141 *
142 * Event specific routines are called by this function based
143 * upon the generated event cause.
144 *
145 * For the following events, the function just forwards them to upper
146 * layers, optionally recording the change -
147 * - EVENT_LINK_SENSED
148 * - EVENT_MIC_ERR_UNICAST
149 * - EVENT_MIC_ERR_MULTICAST
150 * - EVENT_PORT_RELEASE
151 * - EVENT_RSSI_LOW
152 * - EVENT_SNR_LOW
153 * - EVENT_MAX_FAIL
154 * - EVENT_RSSI_HIGH
155 * - EVENT_SNR_HIGH
156 * - EVENT_DATA_RSSI_LOW
157 * - EVENT_DATA_SNR_LOW
158 * - EVENT_DATA_RSSI_HIGH
159 * - EVENT_DATA_SNR_HIGH
160 * - EVENT_LINK_QUALITY
161 * - EVENT_PRE_BEACON_LOST
162 * - EVENT_IBSS_COALESCED
163 * - EVENT_WEP_ICV_ERR
164 * - EVENT_BW_CHANGE
165 * - EVENT_HOSTWAKE_STAIE
166 *
167 * For the following events, no action is taken -
168 * - EVENT_MIB_CHANGED
169 * - EVENT_INIT_DONE
170 * - EVENT_DUMMY_HOST_WAKEUP_SIGNAL
171 *
172 * Rest of the supported events requires driver handling -
173 * - EVENT_DEAUTHENTICATED
174 * - EVENT_DISASSOCIATED
175 * - EVENT_LINK_LOST
176 * - EVENT_PS_SLEEP
177 * - EVENT_PS_AWAKE
178 * - EVENT_DEEP_SLEEP_AWAKE
179 * - EVENT_HS_ACT_REQ
180 * - EVENT_ADHOC_BCN_LOST
181 * - EVENT_BG_SCAN_REPORT
182 * - EVENT_WMM_STATUS_CHANGE
183 * - EVENT_ADDBA
184 * - EVENT_DELBA
185 * - EVENT_BA_STREAM_TIEMOUT
186 * - EVENT_AMSDU_AGGR_CTRL
187 */
188int mwifiex_process_sta_event(struct mwifiex_private *priv)
189{
190 struct mwifiex_adapter *adapter = priv->adapter;
191 int ret = 0;
192 u32 eventcause = adapter->event_cause;
193
194 switch (eventcause) {
195 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
196 dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL,"
197 " ignoring it\n");
198 break;
199 case EVENT_LINK_SENSED:
200 dev_dbg(adapter->dev, "event: LINK_SENSED\n");
201 if (!netif_carrier_ok(priv->netdev))
202 netif_carrier_on(priv->netdev);
203 if (netif_queue_stopped(priv->netdev))
204 netif_wake_queue(priv->netdev);
205 break;
206
207 case EVENT_DEAUTHENTICATED:
208 dev_dbg(adapter->dev, "event: Deauthenticated\n");
209 adapter->dbg.num_event_deauth++;
210 if (priv->media_connected)
211 mwifiex_reset_connect_state(priv);
212 break;
213
214 case EVENT_DISASSOCIATED:
215 dev_dbg(adapter->dev, "event: Disassociated\n");
216 adapter->dbg.num_event_disassoc++;
217 if (priv->media_connected)
218 mwifiex_reset_connect_state(priv);
219 break;
220
221 case EVENT_LINK_LOST:
222 dev_dbg(adapter->dev, "event: Link lost\n");
223 adapter->dbg.num_event_link_lost++;
224 if (priv->media_connected)
225 mwifiex_reset_connect_state(priv);
226 break;
227
228 case EVENT_PS_SLEEP:
229 dev_dbg(adapter->dev, "info: EVENT: SLEEP\n");
230
231 adapter->ps_state = PS_STATE_PRE_SLEEP;
232
233 mwifiex_check_ps_cond(adapter);
234 break;
235
236 case EVENT_PS_AWAKE:
237 dev_dbg(adapter->dev, "info: EVENT: AWAKE\n");
238 if (!adapter->pps_uapsd_mode &&
239 priv->media_connected &&
240 adapter->sleep_period.period) {
241 adapter->pps_uapsd_mode = true;
242 dev_dbg(adapter->dev,
243 "event: PPS/UAPSD mode activated\n");
244 }
245 adapter->tx_lock_flag = false;
246 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
247 if (mwifiex_check_last_packet_indication(priv)) {
248 if (!adapter->data_sent) {
249 if (!mwifiex_send_null_packet(priv,
250 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET
251 |
252 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
253 adapter->ps_state =
254 PS_STATE_SLEEP;
255 return 0;
256 }
257 }
258 }
259 adapter->ps_state = PS_STATE_AWAKE;
260 adapter->pm_wakeup_card_req = false;
261 adapter->pm_wakeup_fw_try = false;
262
263 break;
264
265 case EVENT_DEEP_SLEEP_AWAKE:
266 adapter->if_ops.wakeup_complete(adapter);
267 dev_dbg(adapter->dev, "event: DS_AWAKE\n");
268 if (adapter->is_deep_sleep)
269 adapter->is_deep_sleep = false;
270 break;
271
272 case EVENT_HS_ACT_REQ:
273 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n");
274 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH,
275 0, 0, NULL, NULL);
276 break;
277
278 case EVENT_MIC_ERR_UNICAST:
279 dev_dbg(adapter->dev, "event: UNICAST MIC ERROR\n");
280 break;
281
282 case EVENT_MIC_ERR_MULTICAST:
283 dev_dbg(adapter->dev, "event: MULTICAST MIC ERROR\n");
284 break;
285 case EVENT_MIB_CHANGED:
286 case EVENT_INIT_DONE:
287 break;
288
289 case EVENT_ADHOC_BCN_LOST:
290 dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n");
291 priv->adhoc_is_link_sensed = false;
292 mwifiex_clean_txrx(priv);
293 if (!netif_queue_stopped(priv->netdev))
294 netif_stop_queue(priv->netdev);
295 if (netif_carrier_ok(priv->netdev))
296 netif_carrier_off(priv->netdev);
297 break;
298
299 case EVENT_BG_SCAN_REPORT:
300 dev_dbg(adapter->dev, "event: BGS_REPORT\n");
301 /* Clear the previous scan result */
302 memset(adapter->scan_table, 0x00,
303 sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
304 adapter->num_in_scan_table = 0;
305 adapter->bcn_buf_end = adapter->bcn_buf;
306 ret = mwifiex_prepare_cmd(priv,
307 HostCmd_CMD_802_11_BG_SCAN_QUERY,
308 HostCmd_ACT_GEN_GET, 0, NULL, NULL);
309 break;
310
311 case EVENT_PORT_RELEASE:
312 dev_dbg(adapter->dev, "event: PORT RELEASE\n");
313 break;
314
315 case EVENT_WMM_STATUS_CHANGE:
316 dev_dbg(adapter->dev, "event: WMM status changed\n");
317 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS,
318 0, 0, NULL, NULL);
319 break;
320
321 case EVENT_RSSI_LOW:
322 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n");
323 break;
324 case EVENT_SNR_LOW:
325 dev_dbg(adapter->dev, "event: Beacon SNR_LOW\n");
326 break;
327 case EVENT_MAX_FAIL:
328 dev_dbg(adapter->dev, "event: MAX_FAIL\n");
329 break;
330 case EVENT_RSSI_HIGH:
331 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n");
332 break;
333 case EVENT_SNR_HIGH:
334 dev_dbg(adapter->dev, "event: Beacon SNR_HIGH\n");
335 break;
336 case EVENT_DATA_RSSI_LOW:
337 dev_dbg(adapter->dev, "event: Data RSSI_LOW\n");
338 break;
339 case EVENT_DATA_SNR_LOW:
340 dev_dbg(adapter->dev, "event: Data SNR_LOW\n");
341 break;
342 case EVENT_DATA_RSSI_HIGH:
343 dev_dbg(adapter->dev, "event: Data RSSI_HIGH\n");
344 break;
345 case EVENT_DATA_SNR_HIGH:
346 dev_dbg(adapter->dev, "event: Data SNR_HIGH\n");
347 break;
348 case EVENT_LINK_QUALITY:
349 dev_dbg(adapter->dev, "event: Link Quality\n");
350 break;
351 case EVENT_PRE_BEACON_LOST:
352 dev_dbg(adapter->dev, "event: Pre-Beacon Lost\n");
353 break;
354 case EVENT_IBSS_COALESCED:
355 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n");
356 ret = mwifiex_prepare_cmd(priv,
357 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
358 HostCmd_ACT_GEN_GET, 0, NULL, NULL);
359 break;
360 case EVENT_ADDBA:
361 dev_dbg(adapter->dev, "event: ADDBA Request\n");
362 mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP,
363 HostCmd_ACT_GEN_SET, 0, NULL,
364 adapter->event_body);
365 break;
366 case EVENT_DELBA:
367 dev_dbg(adapter->dev, "event: DELBA Request\n");
368 mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
369 break;
370 case EVENT_BA_STREAM_TIEMOUT:
371 dev_dbg(adapter->dev, "event: BA Stream timeout\n");
372 mwifiex_11n_ba_stream_timeout(priv,
373 (struct host_cmd_ds_11n_batimeout
374 *)
375 adapter->event_body);
376 break;
377 case EVENT_AMSDU_AGGR_CTRL:
378 dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n",
379 *(u16 *) adapter->event_body);
380 adapter->tx_buf_size =
381 min(adapter->curr_tx_buf_size,
382 le16_to_cpu(*(__le16 *) adapter->event_body));
383 dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
384 adapter->tx_buf_size);
385 break;
386
387 case EVENT_WEP_ICV_ERR:
388 dev_dbg(adapter->dev, "event: WEP ICV error\n");
389 break;
390
391 case EVENT_BW_CHANGE:
392 dev_dbg(adapter->dev, "event: BW Change\n");
393 break;
394
395 case EVENT_HOSTWAKE_STAIE:
396 dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
397 break;
398 default:
399 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
400 eventcause);
401 break;
402 }
403
404 return ret;
405}
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
new file mode 100644
index 000000000000..b163507b1fe0
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -0,0 +1,2360 @@
1/*
2 * Marvell Wireless LAN device driver: functions for station ioctl
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27#include "cfg80211.h"
28
29/*
30 * Copies the multicast address list from device to driver.
31 *
32 * This function does not validate the destination memory for
33 * size, and the calling function must ensure enough memory is
34 * available.
35 */
36static int
37mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
38 struct net_device *dev)
39{
40 int i = 0;
41 struct netdev_hw_addr *ha;
42
43 netdev_for_each_mc_addr(ha, dev)
44 memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN);
45
46 return i;
47}
48
49/*
50 * Allocate and fills a wait queue with proper parameters.
51 *
52 * This function needs to be called before an IOCTL request can be made.
53 * It can handle the following wait options:
54 * MWIFIEX_NO_WAIT - Waiting is disabled
55 * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue
56 * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue
57 * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue
58 */
59struct mwifiex_wait_queue *
60mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv,
61 u8 wait_option)
62{
63 struct mwifiex_wait_queue *wait = NULL;
64
65 wait = (struct mwifiex_wait_queue *)
66 kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC);
67 if (!wait) {
68 dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n",
69 __func__);
70 return wait;
71 }
72
73 wait->bss_index = priv->bss_index;
74
75 switch (wait_option) {
76 case MWIFIEX_NO_WAIT:
77 wait->enabled = 0;
78 break;
79 case MWIFIEX_IOCTL_WAIT:
80 priv->ioctl_wait_q_woken = false;
81 wait->start_time = jiffies;
82 wait->wait = &priv->ioctl_wait_q;
83 wait->condition = &priv->ioctl_wait_q_woken;
84 wait->enabled = 1;
85 break;
86 case MWIFIEX_CMD_WAIT:
87 priv->cmd_wait_q_woken = false;
88 wait->start_time = jiffies;
89 wait->wait = &priv->cmd_wait_q;
90 wait->condition = &priv->cmd_wait_q_woken;
91 wait->enabled = 1;
92 break;
93 case MWIFIEX_WSTATS_WAIT:
94 priv->w_stats_wait_q_woken = false;
95 wait->start_time = jiffies;
96 wait->wait = &priv->w_stats_wait_q;
97 wait->condition = &priv->w_stats_wait_q_woken;
98 wait->enabled = 1;
99 break;
100 }
101
102 return wait;
103}
104
105/*
106 * Wait queue completion handler.
107 *
108 * This function waits on a particular wait queue.
109 * For NO_WAIT option, it returns immediately. It also cancels the
110 * pending IOCTL request after waking up, in case of errors.
111 */
112static void
113mwifiex_wait_ioctl_complete(struct mwifiex_private *priv,
114 struct mwifiex_wait_queue *wait,
115 u8 wait_option)
116{
117 bool cancel_flag = false;
118
119 switch (wait_option) {
120 case MWIFIEX_NO_WAIT:
121 break;
122 case MWIFIEX_IOCTL_WAIT:
123 wait_event_interruptible(priv->ioctl_wait_q,
124 priv->ioctl_wait_q_woken);
125 if (!priv->ioctl_wait_q_woken)
126 cancel_flag = true;
127 break;
128 case MWIFIEX_CMD_WAIT:
129 wait_event_interruptible(priv->cmd_wait_q,
130 priv->cmd_wait_q_woken);
131 if (!priv->cmd_wait_q_woken)
132 cancel_flag = true;
133 break;
134 case MWIFIEX_WSTATS_WAIT:
135 wait_event_interruptible(priv->w_stats_wait_q,
136 priv->w_stats_wait_q_woken);
137 if (!priv->w_stats_wait_q_woken)
138 cancel_flag = true;
139 break;
140 }
141 if (cancel_flag) {
142 mwifiex_cancel_pending_ioctl(priv->adapter, wait);
143 dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n",
144 wait, wait_option);
145 }
146
147 return;
148}
149
150/*
151 * The function waits for the request to complete and issues the
152 * completion handler, if required.
153 */
154int mwifiex_request_ioctl(struct mwifiex_private *priv,
155 struct mwifiex_wait_queue *wait,
156 int status, u8 wait_option)
157{
158 switch (status) {
159 case -EINPROGRESS:
160 dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n",
161 wait, wait_option);
162 atomic_inc(&priv->adapter->ioctl_pending);
163 /* Status pending, wake up main process */
164 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
165
166 /* Wait for completion */
167 if (wait_option) {
168 mwifiex_wait_ioctl_complete(priv, wait, wait_option);
169 status = wait->status;
170 }
171 break;
172 case 0:
173 case -1:
174 case -EBUSY:
175 default:
176 break;
177 }
178 return status;
179}
180EXPORT_SYMBOL_GPL(mwifiex_request_ioctl);
181
182/*
183 * IOCTL request handler to set/get MAC address.
184 *
185 * This function prepares the correct firmware command and
186 * issues it to get the extended version information.
187 */
188static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv,
189 struct mwifiex_wait_queue *wait,
190 u8 action, u8 *mac)
191{
192 int ret = 0;
193
194 if ((action == HostCmd_ACT_GEN_GET) && mac) {
195 memcpy(mac, priv->curr_addr, ETH_ALEN);
196 return 0;
197 }
198
199 /* Send request to firmware */
200 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
201 action, 0, wait, mac);
202 if (!ret)
203 ret = -EINPROGRESS;
204
205 return ret;
206}
207
208/*
209 * Sends IOCTL request to set MAC address.
210 *
211 * This function allocates the IOCTL request buffer, fills it
212 * with requisite parameters and calls the IOCTL handler.
213 */
214int mwifiex_request_set_mac_address(struct mwifiex_private *priv)
215{
216 struct mwifiex_wait_queue *wait = NULL;
217 int status = 0;
218 u8 wait_option = MWIFIEX_CMD_WAIT;
219
220 /* Allocate wait buffer */
221 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
222 if (!wait)
223 return -ENOMEM;
224
225 status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET,
226 NULL);
227
228 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
229 if (!status)
230 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
231 else
232 dev_err(priv->adapter->dev, "set mac address failed: status=%d"
233 " error_code=%#x\n", status, wait->status);
234
235 kfree(wait);
236 return status;
237}
238
239/*
240 * IOCTL request handler to set multicast list.
241 *
242 * This function prepares the correct firmware command and
243 * issues it to set the multicast list.
244 *
245 * This function can be used to enable promiscuous mode, or enable all
246 * multicast packets, or to enable selective multicast.
247 */
248static int
249mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv,
250 struct mwifiex_wait_queue *wait,
251 u16 action,
252 struct mwifiex_multicast_list *mcast_list)
253{
254 int ret = 0;
255 u16 old_pkt_filter;
256
257 old_pkt_filter = priv->curr_pkt_filter;
258 if (action == HostCmd_ACT_GEN_GET)
259 return -1;
260
261 if (mcast_list->mode == MWIFIEX_PROMISC_MODE) {
262 dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n");
263 priv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
264 priv->curr_pkt_filter &=
265 ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
266 } else {
267 /* Multicast */
268 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
269 if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) {
270 dev_dbg(priv->adapter->dev,
271 "info: Enabling All Multicast!\n");
272 priv->curr_pkt_filter |=
273 HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
274 } else {
275 priv->curr_pkt_filter &=
276 ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
277 if (mcast_list->num_multicast_addr) {
278 dev_dbg(priv->adapter->dev,
279 "info: Set multicast list=%d\n",
280 mcast_list->num_multicast_addr);
281 /* Set multicast addresses to firmware */
282 if (old_pkt_filter == priv->curr_pkt_filter) {
283 /* Send request to firmware */
284 ret = mwifiex_prepare_cmd(priv,
285 HostCmd_CMD_MAC_MULTICAST_ADR,
286 action, 0, wait, mcast_list);
287 if (!ret)
288 ret = -EINPROGRESS;
289 } else {
290 /* Send request to firmware */
291 ret = mwifiex_prepare_cmd(priv,
292 HostCmd_CMD_MAC_MULTICAST_ADR,
293 action, 0, NULL,
294 mcast_list);
295 }
296 }
297 }
298 }
299 dev_dbg(priv->adapter->dev,
300 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
301 old_pkt_filter, priv->curr_pkt_filter);
302 if (old_pkt_filter != priv->curr_pkt_filter) {
303 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action,
304 0, wait, &priv->curr_pkt_filter);
305 if (!ret)
306 ret = -EINPROGRESS;
307 }
308
309 return ret;
310}
311
312/*
313 * Sends IOCTL request to set multicast list.
314 *
315 * This function allocates the IOCTL request buffer, fills it
316 * with requisite parameters and calls the IOCTL handler.
317 */
318void
319mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
320 struct net_device *dev)
321{
322 struct mwifiex_wait_queue *wait = NULL;
323 struct mwifiex_multicast_list mcast_list;
324 u8 wait_option = MWIFIEX_NO_WAIT;
325 int status = 0;
326
327 /* Allocate wait buffer */
328 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
329 if (!wait)
330 return;
331
332 if (dev->flags & IFF_PROMISC) {
333 mcast_list.mode = MWIFIEX_PROMISC_MODE;
334 } else if (dev->flags & IFF_ALLMULTI ||
335 netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
336 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
337 } else {
338 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
339 if (netdev_mc_count(dev))
340 mcast_list.num_multicast_addr =
341 mwifiex_copy_mcast_addr(&mcast_list, dev);
342 }
343 status = mwifiex_bss_ioctl_multicast_list(priv, wait,
344 HostCmd_ACT_GEN_SET,
345 &mcast_list);
346
347 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
348 if (wait && status != -EINPROGRESS)
349 kfree(wait);
350
351 return;
352}
353
354/*
355 * IOCTL request handler to disconnect from a BSS/IBSS.
356 */
357static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv,
358 struct mwifiex_wait_queue *wait, u8 *mac)
359{
360 return mwifiex_deauthenticate(priv, wait, mac);
361}
362
363/*
364 * Sends IOCTL request to disconnect from a BSS.
365 *
366 * This function allocates the IOCTL request buffer, fills it
367 * with requisite parameters and calls the IOCTL handler.
368 */
369int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac)
370{
371 struct mwifiex_wait_queue *wait = NULL;
372 int status = 0;
373
374 /* Allocate wait buffer */
375 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
376 if (!wait)
377 return -ENOMEM;
378
379 status = mwifiex_bss_ioctl_stop(priv, wait, mac);
380
381 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
382
383 kfree(wait);
384 return status;
385}
386EXPORT_SYMBOL_GPL(mwifiex_disconnect);
387
388/*
389 * IOCTL request handler to join a BSS/IBSS.
390 *
391 * In Ad-Hoc mode, the IBSS is created if not found in scan list.
392 * In both Ad-Hoc and infra mode, an deauthentication is performed
393 * first.
394 */
395static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv,
396 struct mwifiex_wait_queue *wait,
397 struct mwifiex_ssid_bssid *ssid_bssid)
398{
399 int ret = 0;
400 struct mwifiex_adapter *adapter = priv->adapter;
401 s32 i = -1;
402
403 priv->scan_block = false;
404 if (!ssid_bssid)
405 return -1;
406
407 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
408 /* Infra mode */
409 ret = mwifiex_deauthenticate(priv, NULL, NULL);
410 if (ret)
411 return ret;
412
413 /* Search for the requested SSID in the scan table */
414 if (ssid_bssid->ssid.ssid_len)
415 i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid,
416 NULL, NL80211_IFTYPE_STATION);
417 else
418 i = mwifiex_find_bssid_in_list(priv,
419 (u8 *) &ssid_bssid->bssid,
420 NL80211_IFTYPE_STATION);
421 if (i < 0)
422 return -1;
423
424 dev_dbg(adapter->dev,
425 "info: SSID found in scan list ... associating...\n");
426
427 /* Clear any past association response stored for
428 * application retrieval */
429 priv->assoc_rsp_size = 0;
430 ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]);
431 if (ret)
432 return ret;
433 } else {
434 /* Adhoc mode */
435 /* If the requested SSID matches current SSID, return */
436 if (ssid_bssid->ssid.ssid_len &&
437 (!mwifiex_ssid_cmp
438 (&priv->curr_bss_params.bss_descriptor.ssid,
439 &ssid_bssid->ssid)))
440 return 0;
441
442 /* Exit Adhoc mode first */
443 dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
444 ret = mwifiex_deauthenticate(priv, NULL, NULL);
445 if (ret)
446 return ret;
447
448 priv->adhoc_is_link_sensed = false;
449
450 /* Search for the requested network in the scan table */
451 if (ssid_bssid->ssid.ssid_len)
452 i = mwifiex_find_ssid_in_list(priv,
453 &ssid_bssid->ssid, NULL,
454 NL80211_IFTYPE_ADHOC);
455 else
456 i = mwifiex_find_bssid_in_list(priv,
457 (u8 *)&ssid_bssid->bssid,
458 NL80211_IFTYPE_ADHOC);
459
460 if (i >= 0) {
461 dev_dbg(adapter->dev, "info: network found in scan"
462 " list. Joining...\n");
463 ret = mwifiex_adhoc_join(priv, wait,
464 &adapter->scan_table[i]);
465 if (ret)
466 return ret;
467 } else { /* i >= 0 */
468 dev_dbg(adapter->dev, "info: Network not found in "
469 "the list, creating adhoc with ssid = %s\n",
470 ssid_bssid->ssid.ssid);
471 ret = mwifiex_adhoc_start(priv, wait,
472 &ssid_bssid->ssid);
473 if (ret)
474 return ret;
475 }
476 }
477
478 if (!ret)
479 ret = -EINPROGRESS;
480
481 return ret;
482}
483
484/*
485 * Sends IOCTL request to connect with a BSS.
486 *
487 * This function allocates the IOCTL request buffer, fills it
488 * with requisite parameters and calls the IOCTL handler.
489 */
490int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option,
491 struct mwifiex_ssid_bssid *ssid_bssid)
492{
493 struct mwifiex_wait_queue *wait = NULL;
494 struct mwifiex_ssid_bssid tmp_ssid_bssid;
495 int status = 0;
496
497 /* Stop the O.S. TX queue if needed */
498 if (!netif_queue_stopped(priv->netdev))
499 netif_stop_queue(priv->netdev);
500
501 /* Allocate wait buffer */
502 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
503 if (!wait)
504 return -ENOMEM;
505
506 if (ssid_bssid)
507 memcpy(&tmp_ssid_bssid, ssid_bssid,
508 sizeof(struct mwifiex_ssid_bssid));
509 status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid);
510
511 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
512
513 kfree(wait);
514 return status;
515}
516
517/*
518 * IOCTL request handler to set host sleep configuration.
519 *
520 * This function prepares the correct firmware command and
521 * issues it.
522 */
523static int
524mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv,
525 struct mwifiex_wait_queue *wait,
526 u16 action, struct mwifiex_ds_hs_cfg *hs_cfg)
527{
528 struct mwifiex_adapter *adapter = priv->adapter;
529 int status = 0;
530 u32 prev_cond = 0;
531
532 switch (action) {
533 case HostCmd_ACT_GEN_SET:
534 if (adapter->pps_uapsd_mode) {
535 dev_dbg(adapter->dev, "info: Host Sleep IOCTL"
536 " is blocked in UAPSD/PPS mode\n");
537 status = -1;
538 break;
539 }
540 if (hs_cfg->is_invoke_hostcmd) {
541 if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) {
542 if (!adapter->is_hs_configured)
543 /* Already cancelled */
544 break;
545 /* Save previous condition */
546 prev_cond = le32_to_cpu(adapter->hs_cfg
547 .conditions);
548 adapter->hs_cfg.conditions =
549 cpu_to_le32(hs_cfg->conditions);
550 } else if (hs_cfg->conditions) {
551 adapter->hs_cfg.conditions =
552 cpu_to_le32(hs_cfg->conditions);
553 adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
554 if (hs_cfg->gap)
555 adapter->hs_cfg.gap = (u8)hs_cfg->gap;
556 } else if (adapter->hs_cfg.conditions ==
557 cpu_to_le32(
558 HOST_SLEEP_CFG_CANCEL)) {
559 /* Return failure if no parameters for HS
560 enable */
561 status = -1;
562 break;
563 }
564 status = mwifiex_prepare_cmd(priv,
565 HostCmd_CMD_802_11_HS_CFG_ENH,
566 HostCmd_ACT_GEN_SET,
567 0, wait, &adapter->hs_cfg);
568 if (!status)
569 status = -EINPROGRESS;
570 if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL)
571 /* Restore previous condition */
572 adapter->hs_cfg.conditions =
573 cpu_to_le32(prev_cond);
574 } else {
575 adapter->hs_cfg.conditions =
576 cpu_to_le32(hs_cfg->conditions);
577 adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
578 adapter->hs_cfg.gap = (u8)hs_cfg->gap;
579 }
580 break;
581 case HostCmd_ACT_GEN_GET:
582 hs_cfg->conditions = le32_to_cpu(adapter->hs_cfg.conditions);
583 hs_cfg->gpio = adapter->hs_cfg.gpio;
584 hs_cfg->gap = adapter->hs_cfg.gap;
585 break;
586 default:
587 status = -1;
588 break;
589 }
590
591 return status;
592}
593
594/*
595 * Sends IOCTL request to set Host Sleep parameters.
596 *
597 * This function allocates the IOCTL request buffer, fills it
598 * with requisite parameters and calls the IOCTL handler.
599 */
600int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
601 u8 wait_option,
602 struct mwifiex_ds_hs_cfg *hscfg)
603{
604 int ret = 0;
605 struct mwifiex_wait_queue *wait = NULL;
606
607 if (!hscfg)
608 return -ENOMEM;
609
610 /* Allocate wait buffer */
611 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
612 if (!wait)
613 return -ENOMEM;
614
615 ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg);
616
617 ret = mwifiex_request_ioctl(priv, wait, ret, wait_option);
618
619 if (wait && (ret != -EINPROGRESS))
620 kfree(wait);
621 return ret;
622}
623
624/*
625 * Sends IOCTL request to cancel the existing Host Sleep configuration.
626 *
627 * This function allocates the IOCTL request buffer, fills it
628 * with requisite parameters and calls the IOCTL handler.
629 */
630int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option)
631{
632 int ret = 0;
633 struct mwifiex_ds_hs_cfg hscfg;
634
635 /* Cancel Host Sleep */
636 hscfg.conditions = HOST_SLEEP_CFG_CANCEL;
637 hscfg.is_invoke_hostcmd = true;
638 ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
639 wait_option, &hscfg);
640
641 return ret;
642}
643EXPORT_SYMBOL_GPL(mwifiex_cancel_hs);
644
645/*
646 * Sends IOCTL request to cancel the existing Host Sleep configuration.
647 *
648 * This function allocates the IOCTL request buffer, fills it
649 * with requisite parameters and calls the IOCTL handler.
650 */
651int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
652{
653 struct mwifiex_ds_hs_cfg hscfg;
654
655 if (adapter->hs_activated) {
656 dev_dbg(adapter->dev, "cmd: HS Already actived\n");
657 return true;
658 }
659
660 /* Enable Host Sleep */
661 adapter->hs_activate_wait_q_woken = false;
662
663 memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param));
664 hscfg.is_invoke_hostcmd = true;
665
666 if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
667 MWIFIEX_BSS_ROLE_STA),
668 HostCmd_ACT_GEN_SET,
669 MWIFIEX_IOCTL_WAIT, &hscfg)) {
670 dev_err(adapter->dev, "IOCTL request HS enable failed\n");
671 return false;
672 }
673
674 wait_event_interruptible(adapter->hs_activate_wait_q,
675 adapter->hs_activate_wait_q_woken);
676
677 return true;
678}
679EXPORT_SYMBOL_GPL(mwifiex_enable_hs);
680
681/*
682 * IOCTL request handler to get signal information.
683 *
684 * This function prepares the correct firmware command and
685 * issues it to get the signal (RSSI) information.
686 *
687 * This only works in the connected mode.
688 */
689static int mwifiex_get_info_signal(struct mwifiex_private *priv,
690 struct mwifiex_wait_queue *wait,
691 struct mwifiex_ds_get_signal *signal)
692{
693 int ret = 0;
694
695 if (!wait) {
696 dev_err(priv->adapter->dev, "WAIT information is not present\n");
697 return -1;
698 }
699
700 /* Signal info can be obtained only if connected */
701 if (!priv->media_connected) {
702 dev_dbg(priv->adapter->dev,
703 "info: Can not get signal in disconnected state\n");
704 return -1;
705 }
706
707 /* Send request to firmware */
708 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO,
709 HostCmd_ACT_GEN_GET, 0, wait, signal);
710
711 if (!ret)
712 ret = -EINPROGRESS;
713
714 return ret;
715}
716
717/*
718 * IOCTL request handler to get statistics.
719 *
720 * This function prepares the correct firmware command and
721 * issues it to get the statistics (RSSI) information.
722 */
723static int mwifiex_get_info_stats(struct mwifiex_private *priv,
724 struct mwifiex_wait_queue *wait,
725 struct mwifiex_ds_get_stats *log)
726{
727 int ret = 0;
728
729 if (!wait) {
730 dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n");
731 return -1;
732 }
733
734 /* Send request to firmware */
735 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG,
736 HostCmd_ACT_GEN_GET, 0, wait, log);
737
738 if (!ret)
739 ret = -EINPROGRESS;
740
741 return ret;
742}
743
744/*
745 * IOCTL request handler to get BSS information.
746 *
747 * This function collates the information from different driver structures
748 * to send to the user.
749 */
750int mwifiex_get_bss_info(struct mwifiex_private *priv,
751 struct mwifiex_bss_info *info)
752{
753 struct mwifiex_adapter *adapter = priv->adapter;
754 struct mwifiex_bssdescriptor *bss_desc;
755 s32 tbl_idx = 0;
756
757 if (!info)
758 return -1;
759
760 /* Get current BSS info */
761 bss_desc = &priv->curr_bss_params.bss_descriptor;
762
763 /* BSS mode */
764 info->bss_mode = priv->bss_mode;
765
766 /* SSID */
767 memcpy(&info->ssid, &bss_desc->ssid,
768 sizeof(struct mwifiex_802_11_ssid));
769
770 /* BSSID */
771 memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN);
772
773 /* Channel */
774 info->bss_chan = bss_desc->channel;
775
776 /* Region code */
777 info->region_code = adapter->region_code;
778
779 /* Scan table index if connected */
780 info->scan_table_idx = 0;
781 if (priv->media_connected) {
782 tbl_idx =
783 mwifiex_find_ssid_in_list(priv, &bss_desc->ssid,
784 bss_desc->mac_address,
785 priv->bss_mode);
786 if (tbl_idx >= 0)
787 info->scan_table_idx = tbl_idx;
788 }
789
790 /* Connection status */
791 info->media_connected = priv->media_connected;
792
793 /* Tx power information */
794 info->max_power_level = priv->max_tx_power_level;
795 info->min_power_level = priv->min_tx_power_level;
796
797 /* AdHoc state */
798 info->adhoc_state = priv->adhoc_state;
799
800 /* Last beacon NF */
801 info->bcn_nf_last = priv->bcn_nf_last;
802
803 /* wep status */
804 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
805 info->wep_status = true;
806 else
807 info->wep_status = false;
808
809 info->is_hs_configured = adapter->is_hs_configured;
810 info->is_deep_sleep = adapter->is_deep_sleep;
811
812 return 0;
813}
814
815/*
816 * IOCTL request handler to get extended version information.
817 *
818 * This function prepares the correct firmware command and
819 * issues it to get the extended version information.
820 */
821static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv,
822 struct mwifiex_wait_queue *wait,
823 struct mwifiex_ver_ext *ver_ext)
824{
825 int ret = 0;
826
827 /* Send request to firmware */
828 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT,
829 HostCmd_ACT_GEN_GET, 0, wait, ver_ext);
830 if (!ret)
831 ret = -EINPROGRESS;
832
833 return ret;
834}
835
836/*
837 * IOCTL request handler to set/get SNMP MIB parameters.
838 *
839 * This function prepares the correct firmware command and
840 * issues it.
841 *
842 * Currently the following parameters are supported -
843 * Set/get RTS Threshold
844 * Set/get fragmentation threshold
845 * Set/get retry count
846 */
847int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv,
848 struct mwifiex_wait_queue *wait,
849 u32 cmd_oid, u16 action, u32 *value)
850{
851 int ret = 0;
852
853 if (!value)
854 return -1;
855
856 /* Send request to firmware */
857 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
858 action, cmd_oid, wait, value);
859
860 if (!ret)
861 ret = -EINPROGRESS;
862
863 return ret;
864}
865
866/*
867 * IOCTL request handler to set/get band configurations.
868 *
869 * For SET operation, it performs extra checks to make sure the Ad-Hoc
870 * band and channel are compatible. Otherwise it returns an error.
871 *
872 * For GET operation, this function retrieves the following information -
873 * - Infra bands
874 * - Ad-hoc band
875 * - Ad-hoc channel
876 * - Secondary channel offset
877 */
878int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv,
879 u16 action,
880 struct mwifiex_ds_band_cfg *radio_cfg)
881{
882 struct mwifiex_adapter *adapter = priv->adapter;
883 u8 infra_band = 0;
884 u8 adhoc_band = 0;
885 u32 adhoc_channel = 0;
886
887 if (action == HostCmd_ACT_GEN_GET) {
888 /* Infra Bands */
889 radio_cfg->config_bands = adapter->config_bands;
890 /* Adhoc Band */
891 radio_cfg->adhoc_start_band = adapter->adhoc_start_band;
892 /* Adhoc channel */
893 radio_cfg->adhoc_channel = priv->adhoc_channel;
894 /* Secondary channel offset */
895 radio_cfg->sec_chan_offset = adapter->chan_offset;
896 return 0;
897 }
898
899 /* For action = SET */
900 infra_band = (u8) radio_cfg->config_bands;
901 adhoc_band = (u8) radio_cfg->adhoc_start_band;
902 adhoc_channel = radio_cfg->adhoc_channel;
903
904 /* SET Infra band */
905 if ((infra_band | adapter->fw_bands) & ~adapter->fw_bands)
906 return -1;
907
908 adapter->config_bands = infra_band;
909
910 /* SET Ad-hoc Band */
911 if ((adhoc_band | adapter->fw_bands) & ~adapter->fw_bands)
912 return -1;
913
914 if (adhoc_band)
915 adapter->adhoc_start_band = adhoc_band;
916 adapter->chan_offset = (u8) radio_cfg->sec_chan_offset;
917 /*
918 * If no adhoc_channel is supplied verify if the existing adhoc
919 * channel compiles with new adhoc_band
920 */
921 if (!adhoc_channel) {
922 if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
923 (priv, adapter->adhoc_start_band,
924 priv->adhoc_channel)) {
925 /* Pass back the default channel */
926 radio_cfg->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
927 if ((adapter->adhoc_start_band & BAND_A)
928 || (adapter->adhoc_start_band & BAND_AN))
929 radio_cfg->adhoc_channel =
930 DEFAULT_AD_HOC_CHANNEL_A;
931 }
932 } else { /* Retrurn error if adhoc_band and
933 adhoc_channel combination is invalid */
934 if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
935 (priv, adapter->adhoc_start_band, (u16) adhoc_channel))
936 return -1;
937 priv->adhoc_channel = (u8) adhoc_channel;
938 }
939 if ((adhoc_band & BAND_GN) || (adhoc_band & BAND_AN))
940 adapter->adhoc_11n_enabled = true;
941 else
942 adapter->adhoc_11n_enabled = false;
943
944 return 0;
945}
946
947/*
948 * IOCTL request handler to set/get active channel.
949 *
950 * This function performs validity checking on channel/frequency
951 * compatibility and returns failure if not valid.
952 */
953int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action,
954 struct mwifiex_chan_freq_power *chan)
955{
956 struct mwifiex_adapter *adapter = priv->adapter;
957 struct mwifiex_chan_freq_power *cfp = NULL;
958
959 if (!chan)
960 return -1;
961
962 if (action == HostCmd_ACT_GEN_GET) {
963 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
964 priv->curr_bss_params.band,
965 (u16) priv->curr_bss_params.bss_descriptor.
966 channel);
967 chan->channel = cfp->channel;
968 chan->freq = cfp->freq;
969
970 return 0;
971 }
972 if (!chan->channel && !chan->freq)
973 return -1;
974 if (adapter->adhoc_start_band & BAND_AN)
975 adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
976 else if (adapter->adhoc_start_band & BAND_A)
977 adapter->adhoc_start_band = BAND_G | BAND_B;
978 if (chan->channel) {
979 if (chan->channel <= MAX_CHANNEL_BAND_BG)
980 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
981 (priv, 0, (u16) chan->channel);
982 if (!cfp) {
983 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
984 (priv, BAND_A, (u16) chan->channel);
985 if (cfp) {
986 if (adapter->adhoc_11n_enabled)
987 adapter->adhoc_start_band = BAND_A
988 | BAND_AN;
989 else
990 adapter->adhoc_start_band = BAND_A;
991 }
992 }
993 } else {
994 if (chan->freq <= MAX_FREQUENCY_BAND_BG)
995 cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
996 priv, 0, chan->freq);
997 if (!cfp) {
998 cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211
999 (priv, BAND_A, chan->freq);
1000 if (cfp) {
1001 if (adapter->adhoc_11n_enabled)
1002 adapter->adhoc_start_band = BAND_A
1003 | BAND_AN;
1004 else
1005 adapter->adhoc_start_band = BAND_A;
1006 }
1007 }
1008 }
1009 if (!cfp || !cfp->channel) {
1010 dev_err(adapter->dev, "invalid channel/freq\n");
1011 return -1;
1012 }
1013 priv->adhoc_channel = (u8) cfp->channel;
1014 chan->channel = cfp->channel;
1015 chan->freq = cfp->freq;
1016
1017 return 0;
1018}
1019
1020/*
1021 * IOCTL request handler to set/get Ad-Hoc channel.
1022 *
1023 * This function prepares the correct firmware command and
1024 * issues it to set or get the ad-hoc channel.
1025 */
1026static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
1027 struct mwifiex_wait_queue *wait,
1028 u16 action, u16 *channel)
1029{
1030 int ret = 0;
1031
1032 if (action == HostCmd_ACT_GEN_GET) {
1033 if (!priv->media_connected) {
1034 *channel = priv->adhoc_channel;
1035 return ret;
1036 }
1037 } else {
1038 priv->adhoc_channel = (u8) *channel;
1039 }
1040
1041 /* Send request to firmware */
1042 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL,
1043 action, 0, wait, channel);
1044 if (!ret)
1045 ret = -EINPROGRESS;
1046
1047 return ret;
1048}
1049
1050/*
1051 * IOCTL request handler to find a particular BSS.
1052 *
1053 * The BSS can be searched with either a BSSID or a SSID. If none of
1054 * these are provided, just the best BSS (best RSSI) is returned.
1055 */
1056int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
1057 struct mwifiex_wait_queue *wait,
1058 struct mwifiex_ssid_bssid *ssid_bssid)
1059{
1060 struct mwifiex_adapter *adapter = priv->adapter;
1061 int ret = 0;
1062 struct mwifiex_bssdescriptor *bss_desc;
1063 u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1064 u8 mac[ETH_ALEN];
1065 int i = 0;
1066
1067 if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) {
1068 i = mwifiex_find_bssid_in_list(priv,
1069 (u8 *) ssid_bssid->bssid,
1070 priv->bss_mode);
1071 if (i < 0) {
1072 memcpy(mac, ssid_bssid->bssid, sizeof(mac));
1073 dev_err(adapter->dev, "cannot find bssid %pM\n", mac);
1074 return -1;
1075 }
1076 bss_desc = &adapter->scan_table[i];
1077 memcpy(&ssid_bssid->ssid, &bss_desc->ssid,
1078 sizeof(struct mwifiex_802_11_ssid));
1079 } else if (ssid_bssid->ssid.ssid_len) {
1080 i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL,
1081 priv->bss_mode);
1082 if (i < 0) {
1083 dev_err(adapter->dev, "cannot find ssid %s\n",
1084 ssid_bssid->ssid.ssid);
1085 return -1;
1086 }
1087 bss_desc = &adapter->scan_table[i];
1088 memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN);
1089 } else {
1090 ret = mwifiex_find_best_network(priv, ssid_bssid);
1091 }
1092
1093 return ret;
1094}
1095
1096/*
1097 * IOCTL request handler to change Ad-Hoc channel.
1098 *
1099 * This function allocates the IOCTL request buffer, fills it
1100 * with requisite parameters and calls the IOCTL handler.
1101 *
1102 * The function follows the following steps to perform the change -
1103 * - Get current IBSS information
1104 * - Get current channel
1105 * - If no change is required, return
1106 * - If not connected, change channel and return
1107 * - If connected,
1108 * - Disconnect
1109 * - Change channel
1110 * - Perform specific SSID scan with same SSID
1111 * - Start/Join the IBSS
1112 */
1113int
1114mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
1115{
1116 int ret = 0;
1117 int status = 0;
1118 struct mwifiex_bss_info bss_info;
1119 struct mwifiex_wait_queue *wait = NULL;
1120 u8 wait_option = MWIFIEX_IOCTL_WAIT;
1121 struct mwifiex_ssid_bssid ssid_bssid;
1122 u16 curr_chan = 0;
1123
1124 memset(&bss_info, 0, sizeof(bss_info));
1125
1126 /* Get BSS information */
1127 if (mwifiex_get_bss_info(priv, &bss_info))
1128 return -1;
1129
1130 /* Allocate wait buffer */
1131 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1132 if (!wait)
1133 return -ENOMEM;
1134
1135 /* Get current channel */
1136 status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET,
1137 &curr_chan);
1138
1139 if (mwifiex_request_ioctl(priv, wait, status, wait_option)) {
1140 ret = -1;
1141 goto done;
1142 }
1143 if (curr_chan == channel) {
1144 ret = 0;
1145 goto done;
1146 }
1147 dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n",
1148 curr_chan, channel);
1149
1150 if (!bss_info.media_connected) {
1151 ret = 0;
1152 goto done;
1153 }
1154
1155 /* Do disonnect */
1156 memset(&ssid_bssid, 0, ETH_ALEN);
1157 status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid);
1158
1159 if (mwifiex_request_ioctl(priv, wait, status, wait_option)) {
1160 ret = -1;
1161 goto done;
1162 }
1163
1164 status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET,
1165 (u16 *) &channel);
1166
1167 if (mwifiex_request_ioctl(priv, wait, status, wait_option)) {
1168 ret = -1;
1169 goto done;
1170 }
1171
1172 /* Do specific SSID scanning */
1173 if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) {
1174 ret = -1;
1175 goto done;
1176 }
1177 /* Start/Join Adhoc network */
1178 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
1179 memcpy(&ssid_bssid.ssid, &bss_info.ssid,
1180 sizeof(struct mwifiex_802_11_ssid));
1181
1182 status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid);
1183
1184 if (mwifiex_request_ioctl(priv, wait, status, wait_option))
1185 ret = -1;
1186
1187done:
1188 kfree(wait);
1189 return ret;
1190}
1191
1192/*
1193 * IOCTL request handler to get rate.
1194 *
1195 * This function prepares the correct firmware command and
1196 * issues it to get the current rate if it is connected,
1197 * otherwise, the function returns the lowest supported rate
1198 * for the band.
1199 */
1200static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
1201 struct mwifiex_wait_queue *wait,
1202 struct mwifiex_rate_cfg *rate_cfg)
1203{
1204 struct mwifiex_adapter *adapter = priv->adapter;
1205 int ret = 0;
1206
1207 rate_cfg->is_rate_auto = priv->is_data_rate_auto;
1208 if (!priv->media_connected) {
1209 switch (adapter->config_bands) {
1210 case BAND_B:
1211 /* Return the lowest supported rate for B band */
1212 rate_cfg->rate = supported_rates_b[0] & 0x7f;
1213 break;
1214 case BAND_G:
1215 case BAND_G | BAND_GN:
1216 /* Return the lowest supported rate for G band */
1217 rate_cfg->rate = supported_rates_g[0] & 0x7f;
1218 break;
1219 case BAND_B | BAND_G:
1220 case BAND_A | BAND_B | BAND_G:
1221 case BAND_A | BAND_B:
1222 case BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN:
1223 case BAND_B | BAND_G | BAND_GN:
1224 /* Return the lowest supported rate for BG band */
1225 rate_cfg->rate = supported_rates_bg[0] & 0x7f;
1226 break;
1227 case BAND_A:
1228 case BAND_A | BAND_G:
1229 case BAND_A | BAND_G | BAND_AN | BAND_GN:
1230 case BAND_A | BAND_AN:
1231 /* Return the lowest supported rate for A band */
1232 rate_cfg->rate = supported_rates_a[0] & 0x7f;
1233 break;
1234 case BAND_GN:
1235 /* Return the lowest supported rate for N band */
1236 rate_cfg->rate = supported_rates_n[0] & 0x7f;
1237 break;
1238 default:
1239 dev_warn(adapter->dev, "invalid band %#x\n",
1240 adapter->config_bands);
1241 break;
1242 }
1243 } else {
1244 /* Send request to firmware */
1245 ret = mwifiex_prepare_cmd(priv,
1246 HostCmd_CMD_802_11_TX_RATE_QUERY,
1247 HostCmd_ACT_GEN_GET, 0, wait, NULL);
1248 if (!ret)
1249 ret = -EINPROGRESS;
1250 }
1251
1252 return ret;
1253}
1254
1255/*
1256 * IOCTL request handler to set rate.
1257 *
1258 * This function prepares the correct firmware command and
1259 * issues it to set the current rate.
1260 *
1261 * The function also performs validation checking on the supplied value.
1262 */
1263static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
1264 struct mwifiex_wait_queue *wait,
1265 struct mwifiex_rate_cfg *rate_cfg)
1266{
1267 u8 rates[MWIFIEX_SUPPORTED_RATES];
1268 u8 *rate = NULL;
1269 int rate_index = 0;
1270 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
1271 u32 i = 0;
1272 int ret = 0;
1273 struct mwifiex_adapter *adapter = priv->adapter;
1274
1275 if (rate_cfg->is_rate_auto) {
1276 memset(bitmap_rates, 0, sizeof(bitmap_rates));
1277 /* Support all HR/DSSS rates */
1278 bitmap_rates[0] = 0x000F;
1279 /* Support all OFDM rates */
1280 bitmap_rates[1] = 0x00FF;
1281 /* Support all HT-MCSs rate */
1282 for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates) - 3; i++)
1283 bitmap_rates[i + 2] = 0xFFFF;
1284 bitmap_rates[9] = 0x3FFF;
1285 } else {
1286 memset(rates, 0, sizeof(rates));
1287 mwifiex_get_active_data_rates(priv, rates);
1288 rate = rates;
1289 for (i = 0; (rate[i] && i < MWIFIEX_SUPPORTED_RATES); i++) {
1290 dev_dbg(adapter->dev, "info: rate=%#x wanted=%#x\n",
1291 rate[i], rate_cfg->rate);
1292 if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f))
1293 break;
1294 }
1295 if (!rate[i] || (i == MWIFIEX_SUPPORTED_RATES)) {
1296 dev_err(adapter->dev, "fixed data rate %#x is out "
1297 "of range\n", rate_cfg->rate);
1298 return -1;
1299 }
1300 memset(bitmap_rates, 0, sizeof(bitmap_rates));
1301
1302 rate_index =
1303 mwifiex_data_rate_to_index(adapter, rate_cfg->rate);
1304
1305 /* Only allow b/g rates to be set */
1306 if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 &&
1307 rate_index <= MWIFIEX_RATE_INDEX_HRDSSS3) {
1308 bitmap_rates[0] = 1 << rate_index;
1309 } else {
1310 rate_index -= 1; /* There is a 0x00 in the table */
1311 if (rate_index >= MWIFIEX_RATE_INDEX_OFDM0 &&
1312 rate_index <= MWIFIEX_RATE_INDEX_OFDM7)
1313 bitmap_rates[1] = 1 << (rate_index -
1314 MWIFIEX_RATE_INDEX_OFDM0);
1315 }
1316 }
1317
1318 /* Send request to firmware */
1319 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG,
1320 HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates);
1321 if (!ret)
1322 ret = -EINPROGRESS;
1323
1324 return ret;
1325}
1326
1327/*
1328 * IOCTL request handler to set/get rate.
1329 *
1330 * This function can be used to set/get either the rate value or the
1331 * rate index.
1332 */
1333static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
1334 struct mwifiex_wait_queue *wait,
1335 struct mwifiex_rate_cfg *rate_cfg)
1336{
1337 int status = 0;
1338
1339 if (!rate_cfg)
1340 return -1;
1341
1342 if (rate_cfg->action == HostCmd_ACT_GEN_GET)
1343 status = mwifiex_rate_ioctl_get_rate_value(
1344 priv, wait, rate_cfg);
1345 else
1346 status = mwifiex_rate_ioctl_set_rate_value(
1347 priv, wait, rate_cfg);
1348
1349 return status;
1350}
1351
1352/*
1353 * Sends IOCTL request to get the data rate.
1354 *
1355 * This function allocates the IOCTL request buffer, fills it
1356 * with requisite parameters and calls the IOCTL handler.
1357 */
1358int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
1359 struct mwifiex_rate_cfg *rate)
1360{
1361 int ret = 0;
1362 struct mwifiex_wait_queue *wait = NULL;
1363 u8 wait_option = MWIFIEX_IOCTL_WAIT;
1364
1365 /* Allocate wait buffer */
1366 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1367 if (!wait)
1368 return -ENOMEM;
1369
1370 memset(rate, 0, sizeof(struct mwifiex_rate_cfg));
1371 rate->action = HostCmd_ACT_GEN_GET;
1372 ret = mwifiex_rate_ioctl_cfg(priv, wait, rate);
1373
1374 ret = mwifiex_request_ioctl(priv, wait, ret, wait_option);
1375 if (!ret) {
1376 if (rate && rate->is_rate_auto)
1377 rate->rate = mwifiex_index_to_data_rate(priv->adapter,
1378 priv->tx_rate, priv->tx_htinfo);
1379 else if (rate)
1380 rate->rate = priv->data_rate;
1381 } else {
1382 ret = -1;
1383 }
1384
1385 kfree(wait);
1386 return ret;
1387}
1388
1389/*
1390 * IOCTL request handler to set tx power configuration.
1391 *
1392 * This function prepares the correct firmware command and
1393 * issues it.
1394 *
1395 * For non-auto power mode, all the following power groups are set -
1396 * - Modulation class HR/DSSS
1397 * - Modulation class OFDM
1398 * - Modulation class HTBW20
1399 * - Modulation class HTBW40
1400 */
1401static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv,
1402 struct mwifiex_wait_queue *wait,
1403 struct mwifiex_power_cfg *power_cfg)
1404{
1405 int ret = 0;
1406 struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL;
1407 struct mwifiex_types_power_group *pg_tlv = NULL;
1408 struct mwifiex_power_group *pg = NULL;
1409 u8 *buf = NULL;
1410 u16 dbm = 0;
1411
1412 if (!power_cfg->is_power_auto) {
1413 dbm = (u16) power_cfg->power_level;
1414 if ((dbm < priv->min_tx_power_level) ||
1415 (dbm > priv->max_tx_power_level)) {
1416 dev_err(priv->adapter->dev, "txpower value %d dBm"
1417 " is out of range (%d dBm-%d dBm)\n",
1418 dbm, priv->min_tx_power_level,
1419 priv->max_tx_power_level);
1420 return -1;
1421 }
1422 }
1423 buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
1424 if (!buf) {
1425 dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
1426 __func__);
1427 return -1;
1428 }
1429
1430 txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
1431 txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
1432 if (!power_cfg->is_power_auto) {
1433 txp_cfg->mode = cpu_to_le32(1);
1434 pg_tlv = (struct mwifiex_types_power_group *) (buf +
1435 sizeof(struct host_cmd_ds_txpwr_cfg));
1436 pg_tlv->type = TLV_TYPE_POWER_GROUP;
1437 pg_tlv->length = 4 * sizeof(struct mwifiex_power_group);
1438 pg = (struct mwifiex_power_group *) (buf +
1439 sizeof(struct host_cmd_ds_txpwr_cfg) +
1440 sizeof(struct mwifiex_types_power_group));
1441 /* Power group for modulation class HR/DSSS */
1442 pg->first_rate_code = 0x00;
1443 pg->last_rate_code = 0x03;
1444 pg->modulation_class = MOD_CLASS_HR_DSSS;
1445 pg->power_step = 0;
1446 pg->power_min = (s8) dbm;
1447 pg->power_max = (s8) dbm;
1448 pg++;
1449 /* Power group for modulation class OFDM */
1450 pg->first_rate_code = 0x00;
1451 pg->last_rate_code = 0x07;
1452 pg->modulation_class = MOD_CLASS_OFDM;
1453 pg->power_step = 0;
1454 pg->power_min = (s8) dbm;
1455 pg->power_max = (s8) dbm;
1456 pg++;
1457 /* Power group for modulation class HTBW20 */
1458 pg->first_rate_code = 0x00;
1459 pg->last_rate_code = 0x20;
1460 pg->modulation_class = MOD_CLASS_HT;
1461 pg->power_step = 0;
1462 pg->power_min = (s8) dbm;
1463 pg->power_max = (s8) dbm;
1464 pg->ht_bandwidth = HT_BW_20;
1465 pg++;
1466 /* Power group for modulation class HTBW40 */
1467 pg->first_rate_code = 0x00;
1468 pg->last_rate_code = 0x20;
1469 pg->modulation_class = MOD_CLASS_HT;
1470 pg->power_step = 0;
1471 pg->power_min = (s8) dbm;
1472 pg->power_max = (s8) dbm;
1473 pg->ht_bandwidth = HT_BW_40;
1474 }
1475 /* Send request to firmware */
1476 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG,
1477 HostCmd_ACT_GEN_SET, 0, wait, buf);
1478 if (!ret)
1479 ret = -EINPROGRESS;
1480 kfree(buf);
1481
1482 return ret;
1483}
1484
1485/*
1486 * IOCTL request handler to get power save mode.
1487 *
1488 * This function prepares the correct firmware command and
1489 * issues it.
1490 */
1491static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv,
1492 struct mwifiex_wait_queue *wait,
1493 u32 *ps_mode, u16 action)
1494{
1495 int ret = 0;
1496 struct mwifiex_adapter *adapter = priv->adapter;
1497 u16 sub_cmd;
1498
1499 if (action == HostCmd_ACT_GEN_SET) {
1500 if (*ps_mode)
1501 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1502 else
1503 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
1504 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
1505 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1506 sub_cmd, BITMAP_STA_PS, wait, NULL);
1507 if ((!ret) && (sub_cmd == DIS_AUTO_PS))
1508 ret = mwifiex_prepare_cmd(priv,
1509 HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS,
1510 0, NULL, NULL);
1511 } else {
1512 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1513 GET_PS, 0, wait, NULL);
1514 }
1515
1516 if (!ret)
1517 ret = -EINPROGRESS;
1518
1519 return ret;
1520}
1521
1522/*
1523 * IOCTL request handler to set/reset WPA IE.
1524 *
1525 * The supplied WPA IE is treated as a opaque buffer. Only the first field
1526 * is checked to determine WPA version. If buffer length is zero, the existing
1527 * WPA IE is reset.
1528 */
1529static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
1530 u8 *ie_data_ptr, u16 ie_len)
1531{
1532 if (ie_len) {
1533 if (ie_len > sizeof(priv->wpa_ie)) {
1534 dev_err(priv->adapter->dev,
1535 "failed to copy WPA IE, too big\n");
1536 return -1;
1537 }
1538 memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
1539 priv->wpa_ie_len = (u8) ie_len;
1540 dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n",
1541 priv->wpa_ie_len, priv->wpa_ie[0]);
1542
1543 if (priv->wpa_ie[0] == WLAN_EID_WPA) {
1544 priv->sec_info.wpa_enabled = true;
1545 } else if (priv->wpa_ie[0] == WLAN_EID_RSN) {
1546 priv->sec_info.wpa2_enabled = true;
1547 } else {
1548 priv->sec_info.wpa_enabled = false;
1549 priv->sec_info.wpa2_enabled = false;
1550 }
1551 } else {
1552 memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie));
1553 priv->wpa_ie_len = 0;
1554 dev_dbg(priv->adapter->dev, "info: reset wpa_ie_len=%d IE=%#x\n",
1555 priv->wpa_ie_len, priv->wpa_ie[0]);
1556 priv->sec_info.wpa_enabled = false;
1557 priv->sec_info.wpa2_enabled = false;
1558 }
1559
1560 return 0;
1561}
1562
1563/*
1564 * IOCTL request handler to set/reset WAPI IE.
1565 *
1566 * The supplied WAPI IE is treated as a opaque buffer. Only the first field
1567 * is checked to internally enable WAPI. If buffer length is zero, the existing
1568 * WAPI IE is reset.
1569 */
1570static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
1571 u8 *ie_data_ptr, u16 ie_len)
1572{
1573 if (ie_len) {
1574 if (ie_len > sizeof(priv->wapi_ie)) {
1575 dev_dbg(priv->adapter->dev,
1576 "info: failed to copy WAPI IE, too big\n");
1577 return -1;
1578 }
1579 memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
1580 priv->wapi_ie_len = ie_len;
1581 dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n",
1582 priv->wapi_ie_len, priv->wapi_ie[0]);
1583
1584 if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY)
1585 priv->sec_info.wapi_enabled = true;
1586 } else {
1587 memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie));
1588 priv->wapi_ie_len = ie_len;
1589 dev_dbg(priv->adapter->dev,
1590 "info: Reset wapi_ie_len=%d IE=%#x\n",
1591 priv->wapi_ie_len, priv->wapi_ie[0]);
1592 priv->sec_info.wapi_enabled = false;
1593 }
1594 return 0;
1595}
1596
1597/*
1598 * IOCTL request handler to set WAPI key.
1599 *
1600 * This function prepares the correct firmware command and
1601 * issues it.
1602 */
1603static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter,
1604 struct mwifiex_wait_queue *wait,
1605 struct mwifiex_ds_encrypt_key *encrypt_key)
1606{
1607 int ret = 0;
1608 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
1609
1610 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1611 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
1612 wait, encrypt_key);
1613 if (!ret)
1614 ret = -EINPROGRESS;
1615
1616 return ret;
1617}
1618
1619/*
1620 * IOCTL request handler to set WEP network key.
1621 *
1622 * This function prepares the correct firmware command and
1623 * issues it, after validation checks.
1624 */
1625static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter,
1626 struct mwifiex_wait_queue *wait,
1627 struct mwifiex_ds_encrypt_key *encrypt_key)
1628{
1629 int ret = 0;
1630 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
1631 struct mwifiex_wep_key *wep_key = NULL;
1632 int index;
1633
1634 if (priv->wep_key_curr_index >= NUM_WEP_KEYS)
1635 priv->wep_key_curr_index = 0;
1636 wep_key = &priv->wep_key[priv->wep_key_curr_index];
1637 index = encrypt_key->key_index;
1638 if (encrypt_key->key_disable) {
1639 priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
1640 } else if (!encrypt_key->key_len) {
1641 /* Copy the required key as the current key */
1642 wep_key = &priv->wep_key[index];
1643 if (!wep_key->key_length) {
1644 dev_err(adapter->dev,
1645 "key not set, so cannot enable it\n");
1646 return -1;
1647 }
1648 priv->wep_key_curr_index = (u16) index;
1649 priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
1650 } else {
1651 wep_key = &priv->wep_key[index];
1652 /* Cleanup */
1653 memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
1654 /* Copy the key in the driver */
1655 memcpy(wep_key->key_material,
1656 encrypt_key->key_material,
1657 encrypt_key->key_len);
1658 wep_key->key_index = index;
1659 wep_key->key_length = encrypt_key->key_len;
1660 priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
1661 }
1662 if (wep_key->key_length) {
1663 /* Send request to firmware */
1664 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1665 HostCmd_ACT_GEN_SET, 0, NULL, NULL);
1666 if (ret)
1667 return ret;
1668 }
1669 if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
1670 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
1671 else
1672 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1673
1674 /* Send request to firmware */
1675 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1676 HostCmd_ACT_GEN_SET, 0, wait,
1677 &priv->curr_pkt_filter);
1678 if (!ret)
1679 ret = -EINPROGRESS;
1680
1681 return ret;
1682}
1683
1684/*
1685 * IOCTL request handler to set WPA key.
1686 *
1687 * This function prepares the correct firmware command and
1688 * issues it, after validation checks.
1689 *
1690 * Current driver only supports key length of up to 32 bytes.
1691 *
1692 * This function can also be used to disable a currently set key.
1693 */
1694static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter,
1695 struct mwifiex_wait_queue *wait,
1696 struct mwifiex_ds_encrypt_key *encrypt_key)
1697{
1698 int ret = 0;
1699 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
1700 u8 remove_key = false;
1701 struct host_cmd_ds_802_11_key_material *ibss_key;
1702
1703 /* Current driver only supports key length of up to 32 bytes */
1704 if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) {
1705 dev_err(adapter->dev, "key length too long\n");
1706 return -1;
1707 }
1708
1709 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
1710 /*
1711 * IBSS/WPA-None uses only one key (Group) for both receiving
1712 * and sending unicast and multicast packets.
1713 */
1714 /* Send the key as PTK to firmware */
1715 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
1716 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1717 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
1718 NULL, encrypt_key);
1719 if (ret)
1720 return ret;
1721
1722 ibss_key = &priv->aes_key;
1723 memset(ibss_key, 0,
1724 sizeof(struct host_cmd_ds_802_11_key_material));
1725 /* Copy the key in the driver */
1726 memcpy(ibss_key->key_param_set.key, encrypt_key->key_material,
1727 encrypt_key->key_len);
1728 memcpy(&ibss_key->key_param_set.key_len, &encrypt_key->key_len,
1729 sizeof(ibss_key->key_param_set.key_len));
1730 ibss_key->key_param_set.key_type_id
1731 = cpu_to_le16(KEY_TYPE_ID_TKIP);
1732 ibss_key->key_param_set.key_info
1733 = cpu_to_le16(KEY_INFO_TKIP_ENABLED);
1734
1735 /* Send the key as GTK to firmware */
1736 encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST;
1737 }
1738
1739 if (!encrypt_key->key_index)
1740 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
1741
1742 if (remove_key)
1743 /* Send request to firmware */
1744 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1745 HostCmd_ACT_GEN_SET,
1746 !(KEY_INFO_ENABLED),
1747 wait, encrypt_key);
1748 else
1749 /* Send request to firmware */
1750 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1751 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
1752 wait, encrypt_key);
1753
1754 if (!ret)
1755 ret = -EINPROGRESS;
1756
1757 return ret;
1758}
1759
1760/*
1761 * IOCTL request handler to set/get network keys.
1762 *
1763 * This is a generic key handling function which supports WEP, WPA
1764 * and WAPI.
1765 */
1766static int
1767mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv,
1768 struct mwifiex_wait_queue *wait,
1769 struct mwifiex_ds_encrypt_key *encrypt_key)
1770{
1771 int status = 0;
1772 struct mwifiex_adapter *adapter = priv->adapter;
1773
1774 if (encrypt_key->is_wapi_key)
1775 status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait,
1776 encrypt_key);
1777 else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104)
1778 status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait,
1779 encrypt_key);
1780 else
1781 status = mwifiex_sec_ioctl_set_wep_key(adapter, wait,
1782 encrypt_key);
1783 return status;
1784}
1785
1786/*
1787 * This function returns the driver version.
1788 */
1789int
1790mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
1791 int max_len)
1792{
1793 union {
1794 u32 l;
1795 u8 c[4];
1796 } ver;
1797 char fw_ver[32];
1798
1799 ver.l = adapter->fw_release_number;
1800 sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
1801
1802 snprintf(version, max_len, driver_version, fw_ver);
1803
1804 dev_dbg(adapter->dev, "info: MWIFIEX VERSION: %s\n", version);
1805
1806 return 0;
1807}
1808
1809/*
1810 * Sends IOCTL request to set Tx power. It can be set to either auto
1811 * or a fixed value.
1812 *
1813 * This function allocates the IOCTL request buffer, fills it
1814 * with requisite parameters and calls the IOCTL handler.
1815 */
1816int
1817mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm)
1818{
1819 struct mwifiex_power_cfg power_cfg;
1820 struct mwifiex_wait_queue *wait = NULL;
1821 int status = 0;
1822 int ret = 0;
1823
1824 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
1825 if (!wait)
1826 return -ENOMEM;
1827
1828 if (type == NL80211_TX_POWER_FIXED) {
1829 power_cfg.is_power_auto = 0;
1830 power_cfg.power_level = dbm;
1831 } else {
1832 power_cfg.is_power_auto = 1;
1833 }
1834 status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg);
1835
1836 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
1837
1838 kfree(wait);
1839 return ret;
1840}
1841
1842/*
1843 * Sends IOCTL request to get scan table.
1844 *
1845 * This function allocates the IOCTL request buffer, fills it
1846 * with requisite parameters and calls the IOCTL handler.
1847 */
1848int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option,
1849 struct mwifiex_scan_resp *scan_resp)
1850{
1851 struct mwifiex_wait_queue *wait = NULL;
1852 struct mwifiex_scan_resp scan;
1853 int status = 0;
1854
1855 /* Allocate wait buffer */
1856 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1857 if (!wait)
1858 return -ENOMEM;
1859
1860 status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET,
1861 NULL, &scan);
1862
1863 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
1864 if (!status) {
1865 if (scan_resp)
1866 memcpy(scan_resp, &scan,
1867 sizeof(struct mwifiex_scan_resp));
1868 }
1869
1870 if (wait && (status != -EINPROGRESS))
1871 kfree(wait);
1872 return status;
1873}
1874
1875/*
1876 * Sends IOCTL request to get signal information.
1877 *
1878 * This function allocates the IOCTL request buffer, fills it
1879 * with requisite parameters and calls the IOCTL handler.
1880 */
1881int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option,
1882 struct mwifiex_ds_get_signal *signal)
1883{
1884 struct mwifiex_ds_get_signal info;
1885 struct mwifiex_wait_queue *wait = NULL;
1886 int status = 0;
1887
1888 /* Allocate wait buffer */
1889 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1890 if (!wait)
1891 return -ENOMEM;
1892
1893 info.selector = ALL_RSSI_INFO_MASK;
1894
1895 status = mwifiex_get_info_signal(priv, wait, &info);
1896
1897 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
1898 if (!status) {
1899 if (signal)
1900 memcpy(signal, &info,
1901 sizeof(struct mwifiex_ds_get_signal));
1902 if (info.selector & BCN_RSSI_AVG_MASK)
1903 priv->w_stats.qual.level = info.bcn_rssi_avg;
1904 if (info.selector & BCN_NF_AVG_MASK)
1905 priv->w_stats.qual.noise = info.bcn_nf_avg;
1906 }
1907
1908 if (wait && (status != -EINPROGRESS))
1909 kfree(wait);
1910 return status;
1911}
1912
1913/*
1914 * Sends IOCTL request to set encoding parameters.
1915 *
1916 * This function allocates the IOCTL request buffer, fills it
1917 * with requisite parameters and calls the IOCTL handler.
1918 */
1919int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
1920 int key_len, u8 key_index, int disable)
1921{
1922 struct mwifiex_wait_queue *wait = NULL;
1923 struct mwifiex_ds_encrypt_key encrypt_key;
1924 int status = 0;
1925 int ret = 0;
1926
1927 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
1928 if (!wait)
1929 return -ENOMEM;
1930
1931 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
1932 encrypt_key.key_len = key_len;
1933 if (!disable) {
1934 encrypt_key.key_index = key_index;
1935 if (key_len)
1936 memcpy(encrypt_key.key_material, key, key_len);
1937 } else {
1938 encrypt_key.key_disable = true;
1939 }
1940
1941 status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key);
1942
1943 if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT))
1944 ret = -EFAULT;
1945
1946 kfree(wait);
1947 return ret;
1948}
1949
1950/*
1951 * Sends IOCTL request to set power management parameters.
1952 *
1953 * This function allocates the IOCTL request buffer, fills it
1954 * with requisite parameters and calls the IOCTL handler.
1955 */
1956int
1957mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on)
1958{
1959 int ret = 0;
1960 int status = 0;
1961 struct mwifiex_wait_queue *wait = NULL;
1962 u32 ps_mode;
1963
1964 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
1965 if (!wait)
1966 return -ENOMEM;
1967
1968 ps_mode = power_on;
1969 status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode,
1970 HostCmd_ACT_GEN_SET);
1971
1972 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
1973
1974 kfree(wait);
1975 return ret;
1976}
1977
1978/*
1979 * Sends IOCTL request to get extended version.
1980 *
1981 * This function allocates the IOCTL request buffer, fills it
1982 * with requisite parameters and calls the IOCTL handler.
1983 */
1984int
1985mwifiex_get_ver_ext(struct mwifiex_private *priv)
1986{
1987 struct mwifiex_ver_ext ver_ext;
1988 struct mwifiex_wait_queue *wait = NULL;
1989 int status = 0;
1990 int ret = 0;
1991 u8 wait_option = MWIFIEX_IOCTL_WAIT;
1992
1993 /* Allocate wait buffer */
1994 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1995 if (!wait)
1996 return -ENOMEM;
1997
1998 /* get fw version */
1999 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
2000 status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext);
2001
2002 ret = mwifiex_request_ioctl(priv, wait, status, wait_option);
2003
2004 if (ret)
2005 ret = -1;
2006
2007 kfree(wait);
2008 return ret;
2009}
2010
2011/*
2012 * Sends IOCTL request to get statistics information.
2013 *
2014 * This function allocates the IOCTL request buffer, fills it
2015 * with requisite parameters and calls the IOCTL handler.
2016 */
2017int
2018mwifiex_get_stats_info(struct mwifiex_private *priv,
2019 struct mwifiex_ds_get_stats *log)
2020{
2021 int ret = 0;
2022 int status = 0;
2023 struct mwifiex_wait_queue *wait = NULL;
2024 struct mwifiex_ds_get_stats get_log;
2025 u8 wait_option = MWIFIEX_IOCTL_WAIT;
2026
2027 /* Allocate wait buffer */
2028 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
2029 if (!wait)
2030 return -ENOMEM;
2031
2032 memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats));
2033 status = mwifiex_get_info_stats(priv, wait, &get_log);
2034
2035 /* Send IOCTL request to MWIFIEX */
2036 ret = mwifiex_request_ioctl(priv, wait, status, wait_option);
2037 if (!ret) {
2038 if (log)
2039 memcpy(log, &get_log, sizeof(struct
2040 mwifiex_ds_get_stats));
2041 priv->w_stats.discard.fragment = get_log.fcs_error;
2042 priv->w_stats.discard.retries = get_log.retry;
2043 priv->w_stats.discard.misc = get_log.ack_failure;
2044 }
2045
2046 kfree(wait);
2047 return ret;
2048}
2049
2050/*
2051 * IOCTL request handler to read/write register.
2052 *
2053 * This function prepares the correct firmware command and
2054 * issues it.
2055 *
2056 * Access to the following registers are supported -
2057 * - MAC
2058 * - BBP
2059 * - RF
2060 * - PMIC
2061 * - CAU
2062 */
2063static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
2064 struct mwifiex_wait_queue *wait,
2065 struct mwifiex_ds_reg_rw *reg_rw,
2066 u16 action)
2067{
2068 int ret = 0;
2069 u16 cmd_no;
2070
2071 switch (le32_to_cpu(reg_rw->type)) {
2072 case MWIFIEX_REG_MAC:
2073 cmd_no = HostCmd_CMD_MAC_REG_ACCESS;
2074 break;
2075 case MWIFIEX_REG_BBP:
2076 cmd_no = HostCmd_CMD_BBP_REG_ACCESS;
2077 break;
2078 case MWIFIEX_REG_RF:
2079 cmd_no = HostCmd_CMD_RF_REG_ACCESS;
2080 break;
2081 case MWIFIEX_REG_PMIC:
2082 cmd_no = HostCmd_CMD_PMIC_REG_ACCESS;
2083 break;
2084 case MWIFIEX_REG_CAU:
2085 cmd_no = HostCmd_CMD_CAU_REG_ACCESS;
2086 break;
2087 default:
2088 return -1;
2089 }
2090
2091 /* Send request to firmware */
2092 ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw);
2093
2094 if (!ret)
2095 ret = -EINPROGRESS;
2096
2097 return ret;
2098}
2099
2100/*
2101 * Sends IOCTL request to write to a register.
2102 *
2103 * This function allocates the IOCTL request buffer, fills it
2104 * with requisite parameters and calls the IOCTL handler.
2105 */
2106int
2107mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
2108 u32 reg_offset, u32 reg_value)
2109{
2110 int ret = 0;
2111 int status = 0;
2112 struct mwifiex_wait_queue *wait = NULL;
2113 struct mwifiex_ds_reg_rw reg_rw;
2114
2115 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
2116 if (!wait)
2117 return -ENOMEM;
2118
2119 reg_rw.type = cpu_to_le32(reg_type);
2120 reg_rw.offset = cpu_to_le32(reg_offset);
2121 reg_rw.value = cpu_to_le32(reg_value);
2122 status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, &reg_rw,
2123 HostCmd_ACT_GEN_SET);
2124
2125 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
2126
2127 kfree(wait);
2128 return ret;
2129}
2130
2131/*
2132 * Sends IOCTL request to read from a register.
2133 *
2134 * This function allocates the IOCTL request buffer, fills it
2135 * with requisite parameters and calls the IOCTL handler.
2136 */
2137int
2138mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
2139 u32 reg_offset, u32 *value)
2140{
2141 int ret = 0;
2142 int status = 0;
2143 struct mwifiex_wait_queue *wait = NULL;
2144 struct mwifiex_ds_reg_rw reg_rw;
2145
2146 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
2147 if (!wait)
2148 return -ENOMEM;
2149
2150 reg_rw.type = cpu_to_le32(reg_type);
2151 reg_rw.offset = cpu_to_le32(reg_offset);
2152 status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, &reg_rw,
2153 HostCmd_ACT_GEN_GET);
2154
2155 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
2156 if (ret)
2157 goto done;
2158
2159 *value = le32_to_cpu(reg_rw.value);
2160
2161done:
2162 kfree(wait);
2163 return ret;
2164}
2165
2166/*
2167 * IOCTL request handler to read EEPROM.
2168 *
2169 * This function prepares the correct firmware command and
2170 * issues it.
2171 */
2172static int
2173mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv,
2174 struct mwifiex_wait_queue *wait,
2175 struct mwifiex_ds_read_eeprom *rd_eeprom)
2176{
2177 int ret = 0;
2178
2179 /* Send request to firmware */
2180 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
2181 HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom);
2182
2183 if (!ret)
2184 ret = -EINPROGRESS;
2185
2186 return ret;
2187}
2188
2189/*
2190 * Sends IOCTL request to read from EEPROM.
2191 *
2192 * This function allocates the IOCTL request buffer, fills it
2193 * with requisite parameters and calls the IOCTL handler.
2194 */
2195int
2196mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
2197 u8 *value)
2198{
2199 int ret = 0;
2200 int status = 0;
2201 struct mwifiex_wait_queue *wait = NULL;
2202 struct mwifiex_ds_read_eeprom rd_eeprom;
2203
2204 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
2205 if (!wait)
2206 return -ENOMEM;
2207
2208 rd_eeprom.offset = cpu_to_le16((u16) offset);
2209 rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
2210 status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom);
2211
2212 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
2213 if (ret)
2214 goto done;
2215
2216 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
2217done:
2218 kfree(wait);
2219 return ret;
2220}
2221
2222/*
2223 * This function sets a generic IE. In addition to generic IE, it can
2224 * also handle WPA, WPA2 and WAPI IEs.
2225 */
2226static int
2227mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
2228 u16 ie_len)
2229{
2230 int ret = 0;
2231 struct ieee_types_vendor_header *pvendor_ie;
2232 const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };
2233 const u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
2234
2235 /* If the passed length is zero, reset the buffer */
2236 if (!ie_len) {
2237 priv->gen_ie_buf_len = 0;
2238 priv->wps.session_enable = false;
2239
2240 return 0;
2241 } else if (!ie_data_ptr) {
2242 return -1;
2243 }
2244 pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
2245 /* Test to see if it is a WPA IE, if not, then it is a gen IE */
2246 if (((pvendor_ie->element_id == WLAN_EID_WPA)
2247 && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui))))
2248 || (pvendor_ie->element_id == WLAN_EID_RSN)) {
2249
2250 /* IE is a WPA/WPA2 IE so call set_wpa function */
2251 ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
2252 priv->wps.session_enable = false;
2253
2254 return ret;
2255 } else if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) {
2256 /* IE is a WAPI IE so call set_wapi function */
2257 ret = mwifiex_set_wapi_ie(priv, ie_data_ptr, ie_len);
2258
2259 return ret;
2260 }
2261 /*
2262 * Verify that the passed length is not larger than the
2263 * available space remaining in the buffer
2264 */
2265 if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) {
2266
2267 /* Test to see if it is a WPS IE, if so, enable
2268 * wps session flag
2269 */
2270 pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
2271 if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC)
2272 && (!memcmp(pvendor_ie->oui, wps_oui,
2273 sizeof(wps_oui)))) {
2274 priv->wps.session_enable = true;
2275 dev_dbg(priv->adapter->dev,
2276 "info: WPS Session Enabled.\n");
2277 }
2278
2279 /* Append the passed data to the end of the
2280 genIeBuffer */
2281 memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
2282 ie_len);
2283 /* Increment the stored buffer length by the
2284 size passed */
2285 priv->gen_ie_buf_len += ie_len;
2286 } else {
2287 /* Passed data does not fit in the remaining
2288 buffer space */
2289 ret = -1;
2290 }
2291
2292 /* Return 0, or -1 for error case */
2293 return ret;
2294}
2295
2296/*
2297 * IOCTL request handler to set/get generic IE.
2298 *
2299 * In addition to various generic IEs, this function can also be
2300 * used to set the ARP filter.
2301 */
2302static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
2303 struct mwifiex_ds_misc_gen_ie *gen_ie,
2304 u16 action)
2305{
2306 struct mwifiex_adapter *adapter = priv->adapter;
2307
2308 switch (gen_ie->type) {
2309 case MWIFIEX_IE_TYPE_GEN_IE:
2310 if (action == HostCmd_ACT_GEN_GET) {
2311 gen_ie->len = priv->wpa_ie_len;
2312 memcpy(gen_ie->ie_data, priv->wpa_ie, gen_ie->len);
2313 } else {
2314 mwifiex_set_gen_ie_helper(priv, gen_ie->ie_data,
2315 (u16) gen_ie->len);
2316 }
2317 break;
2318 case MWIFIEX_IE_TYPE_ARP_FILTER:
2319 memset(adapter->arp_filter, 0, sizeof(adapter->arp_filter));
2320 if (gen_ie->len > ARP_FILTER_MAX_BUF_SIZE) {
2321 adapter->arp_filter_size = 0;
2322 dev_err(adapter->dev, "invalid ARP filter size\n");
2323 return -1;
2324 } else {
2325 memcpy(adapter->arp_filter, gen_ie->ie_data,
2326 gen_ie->len);
2327 adapter->arp_filter_size = gen_ie->len;
2328 }
2329 break;
2330 default:
2331 dev_err(adapter->dev, "invalid IE type\n");
2332 return -1;
2333 }
2334 return 0;
2335}
2336
2337/*
2338 * Sends IOCTL request to set a generic IE.
2339 *
2340 * This function allocates the IOCTL request buffer, fills it
2341 * with requisite parameters and calls the IOCTL handler.
2342 */
2343int
2344mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
2345{
2346 struct mwifiex_ds_misc_gen_ie gen_ie;
2347 int status = 0;
2348
2349 if (ie_len > IW_CUSTOM_MAX)
2350 return -EFAULT;
2351
2352 gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE;
2353 gen_ie.len = ie_len;
2354 memcpy(gen_ie.ie_data, ie, ie_len);
2355 status = mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET);
2356 if (status)
2357 return -EFAULT;
2358
2359 return 0;
2360}
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
new file mode 100644
index 000000000000..8282679e64fd
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -0,0 +1,182 @@
1/*
2 * Marvell Wireless LAN device driver: station RX data handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "11n_aggr.h"
26#include "11n_rxreorder.h"
27
28/*
29 * This function processes the received packet and forwards it
30 * to kernel/upper layer.
31 *
32 * This function parses through the received packet and determines
33 * if it is a debug packet or normal packet.
34 *
35 * For non-debug packets, the function chops off unnecessary leading
36 * header bytes, reconstructs the packet as an ethernet frame or
37 * 802.2/llc/snap frame as required, and sends it to kernel/upper layer.
38 *
39 * The completion callback is called after processing in complete.
40 */
41int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
42 struct sk_buff *skb)
43{
44 int ret = 0;
45 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
46 struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
47 struct rx_packet_hdr *rx_pkt_hdr;
48 struct rxpd *local_rx_pd;
49 int hdr_chop;
50 struct ethhdr *eth_hdr;
51 u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
52
53 local_rx_pd = (struct rxpd *) (skb->data);
54
55 rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd +
56 local_rx_pd->rx_pkt_offset);
57
58 if (!memcmp(&rx_pkt_hdr->rfc1042_hdr,
59 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
60 /*
61 * Replace the 803 header and rfc1042 header (llc/snap) with an
62 * EthernetII header, keep the src/dst and snap_type
63 * (ethertype).
64 * The firmware only passes up SNAP frames converting
65 * all RX Data from 802.11 to 802.2/LLC/SNAP frames.
66 * To create the Ethernet II, just move the src, dst address
67 * right before the snap_type.
68 */
69 eth_hdr = (struct ethhdr *)
70 ((u8 *) &rx_pkt_hdr->eth803_hdr
71 + sizeof(rx_pkt_hdr->eth803_hdr) +
72 sizeof(rx_pkt_hdr->rfc1042_hdr)
73 - sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
74 - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
75 - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
76
77 memcpy(eth_hdr->h_source, rx_pkt_hdr->eth803_hdr.h_source,
78 sizeof(eth_hdr->h_source));
79 memcpy(eth_hdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
80 sizeof(eth_hdr->h_dest));
81
82 /* Chop off the rxpd + the excess memory from the 802.2/llc/snap
83 header that was removed. */
84 hdr_chop = (u8 *) eth_hdr - (u8 *) local_rx_pd;
85 } else {
86 /* Chop off the rxpd */
87 hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr -
88 (u8 *) local_rx_pd;
89 }
90
91 /* Chop off the leading header bytes so the it points to the start of
92 either the reconstructed EthII frame or the 802.2/llc/snap frame */
93 skb_pull(skb, hdr_chop);
94
95 priv->rxpd_rate = local_rx_pd->rx_rate;
96
97 priv->rxpd_htinfo = local_rx_pd->ht_info;
98
99 ret = mwifiex_recv_packet(adapter, skb);
100 if (ret == -1)
101 dev_err(adapter->dev, "recv packet failed\n");
102
103 return ret;
104}
105
106/*
107 * This function processes the received buffer.
108 *
109 * The function looks into the RxPD and performs sanity tests on the
110 * received buffer to ensure its a valid packet, before processing it
111 * further. If the packet is determined to be aggregated, it is
112 * de-aggregated accordingly. Non-unicast packets are sent directly to
113 * the kernel/upper layers. Unicast packets are handed over to the
114 * Rx reordering routine if 11n is enabled.
115 *
116 * The completion callback is called after processing in complete.
117 */
118int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
119 struct sk_buff *skb)
120{
121 int ret = 0;
122 struct rxpd *local_rx_pd;
123 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
124 struct rx_packet_hdr *rx_pkt_hdr;
125 u8 ta[ETH_ALEN];
126 u16 rx_pkt_type = 0;
127 struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
128
129 local_rx_pd = (struct rxpd *) (skb->data);
130 rx_pkt_type = local_rx_pd->rx_pkt_type;
131
132 rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd +
133 local_rx_pd->rx_pkt_offset);
134
135 if ((local_rx_pd->rx_pkt_offset + local_rx_pd->rx_pkt_length) >
136 (u16) skb->len) {
137 dev_err(adapter->dev, "wrong rx packet: len=%d,"
138 " rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len,
139 local_rx_pd->rx_pkt_offset, local_rx_pd->rx_pkt_length);
140 priv->stats.rx_dropped++;
141 dev_kfree_skb_any(skb);
142 return ret;
143 }
144 if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) {
145 mwifiex_11n_deaggregate_pkt(priv, skb);
146 return ret;
147 }
148 /*
149 * If the packet is not an unicast packet then send the packet
150 * directly to os. Don't pass thru rx reordering
151 */
152 if (!IS_11N_ENABLED(priv) ||
153 memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) {
154 mwifiex_process_rx_packet(adapter, skb);
155 return ret;
156 }
157
158 if (mwifiex_queuing_ra_based(priv)) {
159 memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
160 } else {
161 if (rx_pkt_type != PKT_TYPE_BAR)
162 priv->rx_seq[local_rx_pd->priority] =
163 local_rx_pd->seq_num;
164 memcpy(ta, priv->curr_bss_params.bss_descriptor.mac_address,
165 ETH_ALEN);
166 }
167
168 /* Reorder and send to OS */
169 ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num,
170 local_rx_pd->priority, ta,
171 (u8) local_rx_pd->rx_pkt_type,
172 (void *) skb);
173
174 if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
175 if (priv && (ret == -1))
176 priv->stats.rx_dropped++;
177
178 dev_kfree_skb_any(skb);
179 }
180
181 return ret;
182}
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
new file mode 100644
index 000000000000..e8db6bd021c6
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -0,0 +1,202 @@
1/*
2 * Marvell Wireless LAN device driver: station TX data handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26
27/*
28 * This function fills the TxPD for tx packets.
29 *
30 * The Tx buffer received by this function should already have the
31 * header space allocated for TxPD.
32 *
33 * This function inserts the TxPD in between interface header and actual
34 * data and adjusts the buffer pointers accordingly.
35 *
36 * The following TxPD fields are set by this function, as required -
37 * - BSS number
38 * - Tx packet length and offset
39 * - Priority
40 * - Packet delay
41 * - Priority specific Tx control
42 * - Flags
43 */
44void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
45 struct sk_buff *skb)
46{
47 struct mwifiex_adapter *adapter = priv->adapter;
48 struct txpd *local_tx_pd;
49 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
50
51 if (!skb->len) {
52 dev_err(adapter->dev, "Tx: bad packet length: %d\n",
53 skb->len);
54 tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID;
55 return skb->data;
56 }
57
58 BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN));
59 skb_push(skb, sizeof(*local_tx_pd));
60
61 local_tx_pd = (struct txpd *) skb->data;
62 memset(local_tx_pd, 0, sizeof(struct txpd));
63 local_tx_pd->bss_num = priv->bss_num;
64 local_tx_pd->bss_type = priv->bss_type;
65 local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len -
66 sizeof(struct txpd)));
67
68 local_tx_pd->priority = (u8) skb->priority;
69 local_tx_pd->pkt_delay_2ms =
70 mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
71
72 if (local_tx_pd->priority <
73 ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
74 /*
75 * Set the priority specific tx_control field, setting of 0 will
76 * cause the default value to be used later in this function
77 */
78 local_tx_pd->tx_control =
79 cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd->
80 priority]);
81
82 if (adapter->pps_uapsd_mode) {
83 if (mwifiex_check_last_packet_indication(priv)) {
84 adapter->tx_lock_flag = true;
85 local_tx_pd->flags =
86 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET;
87 }
88 }
89
90 /* Offset of actual data */
91 local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
92
93 /* make space for INTF_HEADER_LEN */
94 skb_push(skb, INTF_HEADER_LEN);
95
96 if (!local_tx_pd->tx_control)
97 /* TxCtrl set by user or default */
98 local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
99
100 return skb->data;
101}
102
103/*
104 * This function tells firmware to send a NULL data packet.
105 *
106 * The function creates a NULL data packet with TxPD and sends to the
107 * firmware for transmission, with highest priority setting.
108 */
109int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
110{
111 struct mwifiex_adapter *adapter = priv->adapter;
112 struct txpd *local_tx_pd;
113/* sizeof(struct txpd) + Interface specific header */
114#define NULL_PACKET_HDR 64
115 u32 data_len = NULL_PACKET_HDR;
116 struct sk_buff *skb = NULL;
117 int ret = 0;
118 struct mwifiex_txinfo *tx_info = NULL;
119
120 if (adapter->surprise_removed)
121 return -1;
122
123 if (!priv->media_connected)
124 return -1;
125
126 if (adapter->data_sent)
127 return -1;
128
129 skb = dev_alloc_skb(data_len);
130 if (!skb)
131 return -1;
132
133 tx_info = MWIFIEX_SKB_TXCB(skb);
134 tx_info->bss_index = priv->bss_index;
135 skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN);
136 skb_push(skb, sizeof(struct txpd));
137
138 local_tx_pd = (struct txpd *) skb->data;
139 local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
140 local_tx_pd->flags = flags;
141 local_tx_pd->priority = WMM_HIGHEST_PRIORITY;
142 local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
143 local_tx_pd->bss_num = priv->bss_num;
144 local_tx_pd->bss_type = priv->bss_type;
145
146 skb_push(skb, INTF_HEADER_LEN);
147
148 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
149 skb->data, skb->len, NULL);
150 switch (ret) {
151 case -EBUSY:
152 adapter->data_sent = true;
153 /* Fall through FAILURE handling */
154 case -1:
155 dev_kfree_skb_any(skb);
156 dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n",
157 __func__, ret);
158 adapter->dbg.num_tx_host_to_card_failure++;
159 break;
160 case 0:
161 dev_kfree_skb_any(skb);
162 dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n",
163 __func__);
164 adapter->tx_lock_flag = true;
165 break;
166 case -EINPROGRESS:
167 break;
168 default:
169 break;
170 }
171
172 return ret;
173}
174
175/*
176 * This function checks if we need to send last packet indication.
177 */
178u8
179mwifiex_check_last_packet_indication(struct mwifiex_private *priv)
180{
181 struct mwifiex_adapter *adapter = priv->adapter;
182 u8 ret = false;
183 u8 prop_ps = true;
184
185 if (!adapter->sleep_period.period)
186 return ret;
187 if (mwifiex_wmm_lists_empty(adapter)) {
188 if ((priv->curr_bss_params.wmm_uapsd_enabled &&
189 priv->wmm_qosinfo) || prop_ps)
190 ret = true;
191 }
192
193 if (ret && !adapter->cmd_sent && !adapter->curr_cmd
194 && !is_command_pending(adapter)) {
195 adapter->delay_null_pkt = false;
196 ret = true;
197 } else {
198 ret = false;
199 adapter->delay_null_pkt = true;
200 }
201 return ret;
202}
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
new file mode 100644
index 000000000000..f06923cb1c4b
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -0,0 +1,202 @@
1/*
2 * Marvell Wireless LAN device driver: generic TX/RX data handling
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26
27/*
28 * This function processes the received buffer.
29 *
30 * Main responsibility of this function is to parse the RxPD to
31 * identify the correct interface this packet is headed for and
32 * forwarding it to the associated handling function, where the
33 * packet will be further processed and sent to kernel/upper layer
34 * if required.
35 */
36int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
37 struct sk_buff *skb)
38{
39 int ret = 0;
40 struct mwifiex_private *priv =
41 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
42 struct rxpd *local_rx_pd;
43 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
44
45 local_rx_pd = (struct rxpd *) (skb->data);
46 /* Get the BSS number from rxpd, get corresponding priv */
47 priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
48 BSS_NUM_MASK, local_rx_pd->bss_type);
49 if (!priv)
50 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
51
52 rx_info->bss_index = priv->bss_index;
53 ret = mwifiex_process_sta_rx_packet(adapter, skb);
54
55 return ret;
56}
57EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
58
59/*
60 * This function sends a packet to device.
61 *
62 * It processes the packet to add the TxPD, checks condition and
63 * sends the processed packet to firmware for transmission.
64 *
65 * On successful completion, the function calls the completion callback
66 * and logs the time.
67 */
68int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
69 struct mwifiex_tx_param *tx_param)
70{
71 int ret = -1;
72 struct mwifiex_adapter *adapter = priv->adapter;
73 u8 *head_ptr = NULL;
74 struct txpd *local_tx_pd = NULL;
75
76 head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb);
77 if (head_ptr) {
78 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
79 local_tx_pd =
80 (struct txpd *) (head_ptr + INTF_HEADER_LEN);
81
82 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
83 skb->data, skb->len, tx_param);
84 }
85
86 switch (ret) {
87 case -EBUSY:
88 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
89 (adapter->pps_uapsd_mode) &&
90 (adapter->tx_lock_flag)) {
91 priv->adapter->tx_lock_flag = false;
92 local_tx_pd->flags = 0;
93 }
94 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
95 break;
96 case -1:
97 adapter->data_sent = false;
98 dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
99 ret);
100 adapter->dbg.num_tx_host_to_card_failure++;
101 mwifiex_write_data_complete(adapter, skb, ret);
102 break;
103 case -EINPROGRESS:
104 adapter->data_sent = false;
105 break;
106 case 0:
107 mwifiex_write_data_complete(adapter, skb, ret);
108 break;
109 default:
110 break;
111 }
112
113 return ret;
114}
115
116/*
117 * Packet send completion callback handler.
118 *
119 * It either frees the buffer directly or forwards it to another
120 * completion callback which checks conditions, updates statistics,
121 * wakes up stalled traffic queue if required, and then frees the buffer.
122 */
123int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
124 struct sk_buff *skb, int status)
125{
126 struct mwifiex_private *priv = NULL, *tpriv = NULL;
127 struct mwifiex_txinfo *tx_info = NULL;
128 int i;
129
130 if (!skb)
131 return 0;
132
133 tx_info = MWIFIEX_SKB_TXCB(skb);
134 priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index);
135 if (!priv)
136 goto done;
137
138 priv->netdev->trans_start = jiffies;
139 if (!status) {
140 priv->stats.tx_packets++;
141 priv->stats.tx_bytes += skb->len;
142 } else {
143 priv->stats.tx_errors++;
144 }
145 atomic_dec(&adapter->tx_pending);
146
147 for (i = 0; i < adapter->priv_num; i++) {
148
149 tpriv = adapter->priv[i];
150
151 if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA)
152 && (tpriv->media_connected)) {
153 if (netif_queue_stopped(tpriv->netdev))
154 netif_wake_queue(tpriv->netdev);
155 }
156 }
157done:
158 dev_kfree_skb_any(skb);
159
160 return 0;
161}
162
163/*
164 * Packet receive completion callback handler.
165 *
166 * This function calls another completion callback handler which
167 * updates the statistics, and optionally updates the parent buffer
168 * use count before freeing the received packet.
169 */
170int mwifiex_recv_packet_complete(struct mwifiex_adapter *adapter,
171 struct sk_buff *skb, int status)
172{
173 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
174 struct mwifiex_rxinfo *rx_info_parent = NULL;
175 struct mwifiex_private *priv;
176 struct sk_buff *skb_parent = NULL;
177 unsigned long flags;
178
179 priv = adapter->priv[rx_info->bss_index];
180
181 if (priv && (status == -1))
182 priv->stats.rx_dropped++;
183
184 if (rx_info->parent) {
185 skb_parent = rx_info->parent;
186 rx_info_parent = MWIFIEX_SKB_RXCB(skb_parent);
187
188 spin_lock_irqsave(&priv->rx_pkt_lock, flags);
189 --rx_info_parent->use_count;
190
191 if (!rx_info_parent->use_count) {
192 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
193 dev_kfree_skb_any(skb_parent);
194 } else {
195 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
196 }
197 } else {
198 dev_kfree_skb_any(skb);
199 }
200
201 return 0;
202}
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
new file mode 100644
index 000000000000..205022aa52f5
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -0,0 +1,252 @@
1/*
2 * Marvell Wireless LAN device driver: utility functions
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28/*
29 * Firmware initialization complete callback handler.
30 *
31 * This function wakes up the function waiting on the init
32 * wait queue for the firmware initialization to complete.
33 */
34int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter)
35{
36
37 adapter->init_wait_q_woken = true;
38 wake_up_interruptible(&adapter->init_wait_q);
39 return 0;
40}
41
42/*
43 * Firmware shutdown complete callback handler.
44 *
45 * This function sets the hardware status to not ready and wakes up
46 * the function waiting on the init wait queue for the firmware
47 * shutdown to complete.
48 */
49int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
50{
51 adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
52 adapter->init_wait_q_woken = true;
53 wake_up_interruptible(&adapter->init_wait_q);
54 return 0;
55}
56
57/*
58 * IOCTL request handler to send function init/shutdown command
59 * to firmware.
60 *
61 * This function prepares the correct firmware command and
62 * issues it.
63 */
64int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter,
65 struct mwifiex_wait_queue *wait,
66 u32 func_init_shutdown)
67{
68 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
69 int ret;
70 u16 cmd;
71
72 if (func_init_shutdown == MWIFIEX_FUNC_INIT) {
73 cmd = HostCmd_CMD_FUNC_INIT;
74 } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) {
75 cmd = HostCmd_CMD_FUNC_SHUTDOWN;
76 } else {
77 dev_err(adapter->dev, "unsupported parameter\n");
78 return -1;
79 }
80
81 /* Send command to firmware */
82 ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET,
83 0, wait, NULL);
84
85 if (!ret)
86 ret = -EINPROGRESS;
87
88 return ret;
89}
90
91/*
92 * IOCTL request handler to set/get debug information.
93 *
94 * This function collates/sets the information from/to different driver
95 * structures.
96 */
97int mwifiex_get_debug_info(struct mwifiex_private *priv,
98 struct mwifiex_debug_info *info)
99{
100 struct mwifiex_adapter *adapter = priv->adapter;
101
102 if (info) {
103 memcpy(info->packets_out,
104 priv->wmm.packets_out,
105 sizeof(priv->wmm.packets_out));
106 info->max_tx_buf_size = (u32) adapter->max_tx_buf_size;
107 info->tx_buf_size = (u32) adapter->tx_buf_size;
108 info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(
109 priv, info->rx_tbl);
110 info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(
111 priv, info->tx_tbl);
112 info->ps_mode = adapter->ps_mode;
113 info->ps_state = adapter->ps_state;
114 info->is_deep_sleep = adapter->is_deep_sleep;
115 info->pm_wakeup_card_req = adapter->pm_wakeup_card_req;
116 info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
117 info->is_hs_configured = adapter->is_hs_configured;
118 info->hs_activated = adapter->hs_activated;
119 info->num_cmd_host_to_card_failure
120 = adapter->dbg.num_cmd_host_to_card_failure;
121 info->num_cmd_sleep_cfm_host_to_card_failure
122 = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
123 info->num_tx_host_to_card_failure
124 = adapter->dbg.num_tx_host_to_card_failure;
125 info->num_event_deauth = adapter->dbg.num_event_deauth;
126 info->num_event_disassoc = adapter->dbg.num_event_disassoc;
127 info->num_event_link_lost = adapter->dbg.num_event_link_lost;
128 info->num_cmd_deauth = adapter->dbg.num_cmd_deauth;
129 info->num_cmd_assoc_success =
130 adapter->dbg.num_cmd_assoc_success;
131 info->num_cmd_assoc_failure =
132 adapter->dbg.num_cmd_assoc_failure;
133 info->num_tx_timeout = adapter->dbg.num_tx_timeout;
134 info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
135 info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
136 info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
137 memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
138 sizeof(adapter->dbg.last_cmd_id));
139 memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act,
140 sizeof(adapter->dbg.last_cmd_act));
141 info->last_cmd_index = adapter->dbg.last_cmd_index;
142 memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id,
143 sizeof(adapter->dbg.last_cmd_resp_id));
144 info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index;
145 memcpy(info->last_event, adapter->dbg.last_event,
146 sizeof(adapter->dbg.last_event));
147 info->last_event_index = adapter->dbg.last_event_index;
148 info->data_sent = adapter->data_sent;
149 info->cmd_sent = adapter->cmd_sent;
150 info->cmd_resp_received = adapter->cmd_resp_received;
151 }
152
153 return 0;
154}
155
156/*
157 * This function processes the received packet before sending it to the
158 * kernel.
159 *
160 * It extracts the SKB from the received buffer and sends it to kernel.
161 * In case the received buffer does not contain the data in SKB format,
162 * the function creates a blank SKB, fills it with the data from the
163 * received buffer and then sends this new SKB to the kernel.
164 */
165int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
166{
167 struct mwifiex_rxinfo *rx_info = NULL;
168 struct mwifiex_private *priv = NULL;
169
170 if (!skb)
171 return -1;
172
173 rx_info = MWIFIEX_SKB_RXCB(skb);
174 priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
175 if (!priv)
176 return -1;
177
178 skb->dev = priv->netdev;
179 skb->protocol = eth_type_trans(skb, priv->netdev);
180 skb->ip_summed = CHECKSUM_NONE;
181 priv->stats.rx_bytes += skb->len;
182 priv->stats.rx_packets++;
183 if (in_interrupt())
184 netif_rx(skb);
185 else
186 netif_rx_ni(skb);
187
188 return 0;
189}
190
191/*
192 * Receive packet completion callback handler.
193 *
194 * This function updates the statistics and frees the buffer SKB.
195 */
196int mwifiex_recv_complete(struct mwifiex_adapter *adapter,
197 struct sk_buff *skb, int status)
198{
199 struct mwifiex_private *priv = NULL;
200 struct mwifiex_rxinfo *rx_info = NULL;
201
202 if (!skb)
203 return 0;
204
205 rx_info = MWIFIEX_SKB_RXCB(skb);
206 priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
207
208 if (priv && (status == -1))
209 priv->stats.rx_dropped++;
210
211 dev_kfree_skb_any(skb);
212
213 return 0;
214}
215
216/*
217 * IOCTL completion callback handler.
218 *
219 * This function is called when a pending IOCTL is completed.
220 *
221 * If work queue support is enabled, the function wakes up the
222 * corresponding waiting function. Otherwise, it processes the
223 * IOCTL response and frees the response buffer.
224 */
225int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter,
226 struct mwifiex_wait_queue *wait_queue,
227 int status)
228{
229 enum mwifiex_error_code status_code =
230 (enum mwifiex_error_code) wait_queue->status;
231
232 atomic_dec(&adapter->ioctl_pending);
233
234 dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d,"
235 " status_code=%#x\n", status, status_code);
236
237 if (wait_queue->enabled) {
238 *wait_queue->condition = true;
239 wait_queue->status = status;
240 if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT))
241 dev_err(adapter->dev, "cmd timeout\n");
242 else
243 wake_up_interruptible(wait_queue->wait);
244 } else {
245 if (status)
246 dev_err(adapter->dev, "cmd failed: status_code=%#x\n",
247 status_code);
248 kfree(wait_queue);
249 }
250
251 return 0;
252}
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
new file mode 100644
index 000000000000..9506afc6c0e4
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -0,0 +1,32 @@
1/*
2 * Marvell Wireless LAN device driver: utility functions
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_UTIL_H_
21#define _MWIFIEX_UTIL_H_
22
23static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
24{
25 return (struct mwifiex_rxinfo *)skb->cb;
26}
27
28static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
29{
30 return (struct mwifiex_txinfo *)skb->cb;
31}
32#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
new file mode 100644
index 000000000000..1cfbc6bed692
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -0,0 +1,1237 @@
1/*
2 * Marvell Wireless LAN device driver: WMM
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26#include "11n.h"
27
28
29/* Maximum value FW can accept for driver delay in packet transmission */
30#define DRV_PKT_DELAY_TO_FW_MAX 512
31
32
33#define WMM_QUEUED_PACKET_LOWER_LIMIT 180
34
35#define WMM_QUEUED_PACKET_UPPER_LIMIT 200
36
37/* Offset for TOS field in the IP header */
38#define IPTOS_OFFSET 5
39
40/* WMM information IE */
41static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07,
42 0x00, 0x50, 0xf2, 0x02,
43 0x00, 0x01, 0x00
44};
45
46static const u8 wmm_aci_to_qidx_map[] = { WMM_AC_BE,
47 WMM_AC_BK,
48 WMM_AC_VI,
49 WMM_AC_VO
50};
51
52static u8 tos_to_tid[] = {
53 /* TID DSCP_P2 DSCP_P1 DSCP_P0 WMM_AC */
54 0x01, /* 0 1 0 AC_BK */
55 0x02, /* 0 0 0 AC_BK */
56 0x00, /* 0 0 1 AC_BE */
57 0x03, /* 0 1 1 AC_BE */
58 0x04, /* 1 0 0 AC_VI */
59 0x05, /* 1 0 1 AC_VI */
60 0x06, /* 1 1 0 AC_VO */
61 0x07 /* 1 1 1 AC_VO */
62};
63
64/*
65 * This table inverses the tos_to_tid operation to get a priority
66 * which is in sequential order, and can be compared.
67 * Use this to compare the priority of two different TIDs.
68 */
69static u8 tos_to_tid_inv[] = {
70 0x02, /* from tos_to_tid[2] = 0 */
71 0x00, /* from tos_to_tid[0] = 1 */
72 0x01, /* from tos_to_tid[1] = 2 */
73 0x03,
74 0x04,
75 0x05,
76 0x06,
77 0x07};
78
79static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} };
80
81/*
82 * This function debug prints the priority parameters for a WMM AC.
83 */
84static void
85mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param)
86{
87 const char *ac_str[] = { "BK", "BE", "VI", "VO" };
88
89 pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, "
90 "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n",
91 ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap
92 & MWIFIEX_ACI) >> 5]],
93 (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5,
94 (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4,
95 ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN,
96 ac_param->ecw_bitmap & MWIFIEX_ECW_MIN,
97 (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4,
98 le16_to_cpu(ac_param->tx_op_limit));
99}
100
101/*
102 * This function allocates a route address list.
103 *
104 * The function also initializes the list with the provided RA.
105 */
106static struct mwifiex_ra_list_tbl *
107mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
108{
109 struct mwifiex_ra_list_tbl *ra_list;
110
111 ra_list = kzalloc(sizeof(struct mwifiex_ra_list_tbl), GFP_ATOMIC);
112
113 if (!ra_list) {
114 dev_err(adapter->dev, "%s: failed to alloc ra_list\n",
115 __func__);
116 return NULL;
117 }
118 INIT_LIST_HEAD(&ra_list->list);
119 skb_queue_head_init(&ra_list->skb_head);
120
121 memcpy(ra_list->ra, ra, ETH_ALEN);
122
123 ra_list->total_pkts_size = 0;
124
125 dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
126
127 return ra_list;
128}
129
130/*
131 * This function allocates and adds a RA list for all TIDs
132 * with the given RA.
133 */
134void
135mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
136{
137 int i;
138 struct mwifiex_ra_list_tbl *ra_list;
139 struct mwifiex_adapter *adapter = priv->adapter;
140
141 for (i = 0; i < MAX_NUM_TID; ++i) {
142 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra);
143 dev_dbg(adapter->dev, "info: created ra_list %p\n", ra_list);
144
145 if (!ra_list)
146 break;
147
148 if (!mwifiex_queuing_ra_based(priv))
149 ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
150 else
151 ra_list->is_11n_enabled = false;
152
153 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n",
154 ra_list, ra_list->is_11n_enabled);
155
156 list_add_tail(&ra_list->list,
157 &priv->wmm.tid_tbl_ptr[i].ra_list);
158
159 if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
160 priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
161 }
162}
163
164/*
165 * This function sets the WMM queue priorities to their default values.
166 */
167static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
168{
169 /* Default queue priorities: VO->VI->BE->BK */
170 priv->wmm.queue_priority[0] = WMM_AC_VO;
171 priv->wmm.queue_priority[1] = WMM_AC_VI;
172 priv->wmm.queue_priority[2] = WMM_AC_BE;
173 priv->wmm.queue_priority[3] = WMM_AC_BK;
174}
175
176/*
177 * This function map ACs to TIDs.
178 */
179static void
180mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv,
181 u8 queue_priority[])
182{
183 int i;
184
185 for (i = 0; i < 4; ++i) {
186 tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1];
187 tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0];
188 }
189}
190
191/*
192 * This function initializes WMM priority queues.
193 */
194void
195mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
196 struct ieee_types_wmm_parameter *wmm_ie)
197{
198 u16 cw_min, avg_back_off, tmp[4];
199 u32 i, j, num_ac;
200 u8 ac_idx;
201
202 if (!wmm_ie || !priv->wmm_enabled) {
203 /* WMM is not enabled, just set the defaults and return */
204 mwifiex_wmm_default_queue_priorities(priv);
205 return;
206 }
207
208 dev_dbg(priv->adapter->dev, "info: WMM Parameter IE: version=%d, "
209 "qos_info Parameter Set Count=%d, Reserved=%#x\n",
210 wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap &
211 IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK,
212 wmm_ie->reserved);
213
214 for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) {
215 cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap &
216 MWIFIEX_ECW_MIN)) - 1;
217 avg_back_off = (cw_min >> 1) +
218 (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap &
219 MWIFIEX_AIFSN);
220
221 ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac].
222 aci_aifsn_bitmap &
223 MWIFIEX_ACI) >> 5];
224 priv->wmm.queue_priority[ac_idx] = ac_idx;
225 tmp[ac_idx] = avg_back_off;
226
227 dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n",
228 (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap &
229 MWIFIEX_ECW_MAX) >> 4)) - 1,
230 cw_min, avg_back_off);
231 mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]);
232 }
233
234 /* Bubble sort */
235 for (i = 0; i < num_ac; i++) {
236 for (j = 1; j < num_ac - i; j++) {
237 if (tmp[j - 1] > tmp[j]) {
238 swap(tmp[j - 1], tmp[j]);
239 swap(priv->wmm.queue_priority[j - 1],
240 priv->wmm.queue_priority[j]);
241 } else if (tmp[j - 1] == tmp[j]) {
242 if (priv->wmm.queue_priority[j - 1]
243 < priv->wmm.queue_priority[j])
244 swap(priv->wmm.queue_priority[j - 1],
245 priv->wmm.queue_priority[j]);
246 }
247 }
248 }
249
250 mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority);
251}
252
253/*
254 * This function evaluates whether or not an AC is to be downgraded.
255 *
256 * In case the AC is not enabled, the highest AC is returned that is
257 * enabled and does not require admission control.
258 */
259static enum mwifiex_wmm_ac_e
260mwifiex_wmm_eval_downgrade_ac(struct mwifiex_private *priv,
261 enum mwifiex_wmm_ac_e eval_ac)
262{
263 int down_ac;
264 enum mwifiex_wmm_ac_e ret_ac;
265 struct mwifiex_wmm_ac_status *ac_status;
266
267 ac_status = &priv->wmm.ac_status[eval_ac];
268
269 if (!ac_status->disabled)
270 /* Okay to use this AC, its enabled */
271 return eval_ac;
272
273 /* Setup a default return value of the lowest priority */
274 ret_ac = WMM_AC_BK;
275
276 /*
277 * Find the highest AC that is enabled and does not require
278 * admission control. The spec disallows downgrading to an AC,
279 * which is enabled due to a completed admission control.
280 * Unadmitted traffic is not to be sent on an AC with admitted
281 * traffic.
282 */
283 for (down_ac = WMM_AC_BK; down_ac < eval_ac; down_ac++) {
284 ac_status = &priv->wmm.ac_status[down_ac];
285
286 if (!ac_status->disabled && !ac_status->flow_required)
287 /* AC is enabled and does not require admission
288 control */
289 ret_ac = (enum mwifiex_wmm_ac_e) down_ac;
290 }
291
292 return ret_ac;
293}
294
295/*
296 * This function downgrades WMM priority queue.
297 */
298void
299mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv)
300{
301 int ac_val;
302
303 dev_dbg(priv->adapter->dev, "info: WMM: AC Priorities:"
304 "BK(0), BE(1), VI(2), VO(3)\n");
305
306 if (!priv->wmm_enabled) {
307 /* WMM is not enabled, default priorities */
308 for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++)
309 priv->wmm.ac_down_graded_vals[ac_val] =
310 (enum mwifiex_wmm_ac_e) ac_val;
311 } else {
312 for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
313 priv->wmm.ac_down_graded_vals[ac_val]
314 = mwifiex_wmm_eval_downgrade_ac(priv,
315 (enum mwifiex_wmm_ac_e) ac_val);
316 dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n",
317 ac_val, priv->wmm.ac_down_graded_vals[ac_val]);
318 }
319 }
320}
321
322/*
323 * This function converts the IP TOS field to an WMM AC
324 * Queue assignment.
325 */
326static enum mwifiex_wmm_ac_e
327mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos)
328{
329 /* Map of TOS UP values to WMM AC */
330 const enum mwifiex_wmm_ac_e tos_to_ac[] = { WMM_AC_BE,
331 WMM_AC_BK,
332 WMM_AC_BK,
333 WMM_AC_BE,
334 WMM_AC_VI,
335 WMM_AC_VI,
336 WMM_AC_VO,
337 WMM_AC_VO
338 };
339
340 if (tos >= ARRAY_SIZE(tos_to_ac))
341 return WMM_AC_BE;
342
343 return tos_to_ac[tos];
344}
345
346/*
347 * This function evaluates a given TID and downgrades it to a lower
348 * TID if the WMM Parameter IE received from the AP indicates that the
349 * AP is disabled (due to call admission control (ACM bit). Mapping
350 * of TID to AC is taken care of internally.
351 */
352static u8
353mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
354{
355 enum mwifiex_wmm_ac_e ac, ac_down;
356 u8 new_tid;
357
358 ac = mwifiex_wmm_convert_tos_to_ac(priv->adapter, tid);
359 ac_down = priv->wmm.ac_down_graded_vals[ac];
360
361 /* Send the index to tid array, picking from the array will be
362 * taken care by dequeuing function
363 */
364 new_tid = ac_to_tid[ac_down][tid % 2];
365
366 return new_tid;
367}
368
369/*
370 * This function initializes the WMM state information and the
371 * WMM data path queues.
372 */
373void
374mwifiex_wmm_init(struct mwifiex_adapter *adapter)
375{
376 int i, j;
377 struct mwifiex_private *priv;
378
379 for (j = 0; j < adapter->priv_num; ++j) {
380 priv = adapter->priv[j];
381 if (!priv)
382 continue;
383
384 for (i = 0; i < MAX_NUM_TID; ++i) {
385 priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i];
386 priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i];
387 priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
388 priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
389 }
390
391 priv->aggr_prio_tbl[6].amsdu
392 = priv->aggr_prio_tbl[6].ampdu_ap
393 = priv->aggr_prio_tbl[6].ampdu_user
394 = BA_STREAM_NOT_ALLOWED;
395
396 priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap
397 = priv->aggr_prio_tbl[7].ampdu_user
398 = BA_STREAM_NOT_ALLOWED;
399
400 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
401 priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
402 priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
403 }
404}
405
406/*
407 * This function checks if WMM Tx queue is empty.
408 */
409int
410mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
411{
412 int i, j;
413 struct mwifiex_private *priv;
414
415 for (j = 0; j < adapter->priv_num; ++j) {
416 priv = adapter->priv[j];
417 if (priv) {
418 for (i = 0; i < MAX_NUM_TID; i++)
419 if (!mwifiex_wmm_is_ra_list_empty(adapter,
420 &priv->wmm.tid_tbl_ptr[i].ra_list))
421 return false;
422 }
423 }
424
425 return true;
426}
427
428/*
429 * This function deletes all packets in an RA list node.
430 *
431 * The packet sent completion callback handler are called with
432 * status failure, after they are dequeued to ensure proper
433 * cleanup. The RA list node itself is freed at the end.
434 */
435static void
436mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
437 struct mwifiex_ra_list_tbl *ra_list)
438{
439 struct mwifiex_adapter *adapter = priv->adapter;
440 struct sk_buff *skb, *tmp;
441
442 skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
443 mwifiex_write_data_complete(adapter, skb, -1);
444}
445
446/*
447 * This function deletes all packets in an RA list.
448 *
449 * Each nodes in the RA list are freed individually first, and then
450 * the RA list itself is freed.
451 */
452static void
453mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv,
454 struct list_head *ra_list_head)
455{
456 struct mwifiex_ra_list_tbl *ra_list;
457
458 list_for_each_entry(ra_list, ra_list_head, list)
459 mwifiex_wmm_del_pkts_in_ralist_node(priv, ra_list);
460}
461
462/*
463 * This function deletes all packets in all RA lists.
464 */
465static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
466{
467 int i;
468
469 for (i = 0; i < MAX_NUM_TID; i++)
470 mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].
471 ra_list);
472}
473
474/*
475 * This function deletes all route addresses from all RA lists.
476 */
477static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
478{
479 struct mwifiex_ra_list_tbl *ra_list, *tmp_node;
480 int i;
481
482 for (i = 0; i < MAX_NUM_TID; ++i) {
483 dev_dbg(priv->adapter->dev,
484 "info: ra_list: freeing buf for tid %d\n", i);
485 list_for_each_entry_safe(ra_list, tmp_node,
486 &priv->wmm.tid_tbl_ptr[i].ra_list, list) {
487 list_del(&ra_list->list);
488 kfree(ra_list);
489 }
490
491 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list);
492
493 priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
494 }
495}
496
497/*
498 * This function cleans up the Tx and Rx queues.
499 *
500 * Cleanup includes -
501 * - All packets in RA lists
502 * - All entries in Rx reorder table
503 * - All entries in Tx BA stream table
504 * - MPA buffer (if required)
505 * - All RA lists
506 */
507void
508mwifiex_clean_txrx(struct mwifiex_private *priv)
509{
510 unsigned long flags;
511
512 mwifiex_11n_cleanup_reorder_tbl(priv);
513 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
514
515 mwifiex_wmm_cleanup_queues(priv);
516 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
517
518 if (priv->adapter->if_ops.cleanup_mpa_buf)
519 priv->adapter->if_ops.cleanup_mpa_buf(priv->adapter);
520
521 mwifiex_wmm_delete_all_ralist(priv);
522 memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid));
523
524 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
525}
526
527/*
528 * This function retrieves a particular RA list node, matching with the
529 * given TID and RA address.
530 */
531static struct mwifiex_ra_list_tbl *
532mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
533 u8 *ra_addr)
534{
535 struct mwifiex_ra_list_tbl *ra_list;
536
537 list_for_each_entry(ra_list, &priv->wmm.tid_tbl_ptr[tid].ra_list,
538 list) {
539 if (!memcmp(ra_list->ra, ra_addr, ETH_ALEN))
540 return ra_list;
541 }
542
543 return NULL;
544}
545
546/*
547 * This function retrieves an RA list node for a given TID and
548 * RA address pair.
549 *
550 * If no such node is found, a new node is added first and then
551 * retrieved.
552 */
553static struct mwifiex_ra_list_tbl *
554mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr)
555{
556 struct mwifiex_ra_list_tbl *ra_list;
557
558 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra_addr);
559 if (ra_list)
560 return ra_list;
561 mwifiex_ralist_add(priv, ra_addr);
562
563 return mwifiex_wmm_get_ralist_node(priv, tid, ra_addr);
564}
565
566/*
567 * This function checks if a particular RA list node exists in a given TID
568 * table index.
569 */
570int
571mwifiex_is_ralist_valid(struct mwifiex_private *priv,
572 struct mwifiex_ra_list_tbl *ra_list, int ptr_index)
573{
574 struct mwifiex_ra_list_tbl *rlist;
575
576 list_for_each_entry(rlist, &priv->wmm.tid_tbl_ptr[ptr_index].ra_list,
577 list) {
578 if (rlist == ra_list)
579 return true;
580 }
581
582 return false;
583}
584
585/*
586 * This function adds a packet to WMM queue.
587 *
588 * In disconnected state the packet is immediately dropped and the
589 * packet send completion callback is called with status failure.
590 *
591 * Otherwise, the correct RA list node is located and the packet
592 * is queued at the list tail.
593 */
594void
595mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
596 struct sk_buff *skb)
597{
598 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
599 struct mwifiex_private *priv = adapter->priv[tx_info->bss_index];
600 u32 tid;
601 struct mwifiex_ra_list_tbl *ra_list;
602 u8 ra[ETH_ALEN], tid_down;
603 unsigned long flags;
604
605 if (!priv->media_connected) {
606 dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
607 mwifiex_write_data_complete(adapter, skb, -1);
608 return;
609 }
610
611 tid = skb->priority;
612
613 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
614
615 tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
616
617 /* In case of infra as we have already created the list during
618 association we just don't have to call get_queue_raptr, we will
619 have only 1 raptr for a tid in case of infra */
620 if (!mwifiex_queuing_ra_based(priv)) {
621 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
622 ra_list = list_first_entry(
623 &priv->wmm.tid_tbl_ptr[tid_down].ra_list,
624 struct mwifiex_ra_list_tbl, list);
625 else
626 ra_list = NULL;
627 } else {
628 memcpy(ra, skb->data, ETH_ALEN);
629 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra);
630 }
631
632 if (!ra_list) {
633 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
634 mwifiex_write_data_complete(adapter, skb, -1);
635 return;
636 }
637
638 skb_queue_tail(&ra_list->skb_head, skb);
639
640 ra_list->total_pkts_size += skb->len;
641
642 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
643}
644
645/*
646 * This function processes the get WMM status command response from firmware.
647 *
648 * The response may contain multiple TLVs -
649 * - AC Queue status TLVs
650 * - Current WMM Parameter IE TLV
651 * - Admission Control action frame TLVs
652 *
653 * This function parses the TLVs and then calls further specific functions
654 * to process any changes in the queue prioritize or state.
655 */
656int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
657 const struct host_cmd_ds_command *resp)
658{
659 u8 *curr = (u8 *) &resp->params.get_wmm_status;
660 uint16_t resp_len = le16_to_cpu(resp->size), tlv_len;
661 int valid = true;
662
663 struct mwifiex_ie_types_data *tlv_hdr;
664 struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus;
665 struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
666 struct mwifiex_wmm_ac_status *ac_status;
667
668 dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n",
669 resp_len);
670
671 while ((resp_len >= sizeof(tlv_hdr->header)) && valid) {
672 tlv_hdr = (struct mwifiex_ie_types_data *) curr;
673 tlv_len = le16_to_cpu(tlv_hdr->header.len);
674
675 switch (le16_to_cpu(tlv_hdr->header.type)) {
676 case TLV_TYPE_WMMQSTATUS:
677 tlv_wmm_qstatus =
678 (struct mwifiex_ie_types_wmm_queue_status *)
679 tlv_hdr;
680 dev_dbg(priv->adapter->dev,
681 "info: CMD_RESP: WMM_GET_STATUS:"
682 " QSTATUS TLV: %d, %d, %d\n",
683 tlv_wmm_qstatus->queue_index,
684 tlv_wmm_qstatus->flow_required,
685 tlv_wmm_qstatus->disabled);
686
687 ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus->
688 queue_index];
689 ac_status->disabled = tlv_wmm_qstatus->disabled;
690 ac_status->flow_required =
691 tlv_wmm_qstatus->flow_required;
692 ac_status->flow_created = tlv_wmm_qstatus->flow_created;
693 break;
694
695 case WLAN_EID_VENDOR_SPECIFIC:
696 /*
697 * Point the regular IEEE IE 2 bytes into the Marvell IE
698 * and setup the IEEE IE type and length byte fields
699 */
700
701 wmm_param_ie =
702 (struct ieee_types_wmm_parameter *) (curr +
703 2);
704 wmm_param_ie->vend_hdr.len = (u8) tlv_len;
705 wmm_param_ie->vend_hdr.element_id =
706 WLAN_EID_VENDOR_SPECIFIC;
707
708 dev_dbg(priv->adapter->dev,
709 "info: CMD_RESP: WMM_GET_STATUS:"
710 " WMM Parameter Set Count: %d\n",
711 wmm_param_ie->qos_info_bitmap &
712 IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK);
713
714 memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
715 wmm_ie, wmm_param_ie,
716 wmm_param_ie->vend_hdr.len + 2);
717
718 break;
719
720 default:
721 valid = false;
722 break;
723 }
724
725 curr += (tlv_len + sizeof(tlv_hdr->header));
726 resp_len -= (tlv_len + sizeof(tlv_hdr->header));
727 }
728
729 mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
730 mwifiex_wmm_setup_ac_downgrade(priv);
731
732 return 0;
733}
734
735/*
736 * Callback handler from the command module to allow insertion of a WMM TLV.
737 *
738 * If the BSS we are associating to supports WMM, this function adds the
739 * required WMM Information IE to the association request command buffer in
740 * the form of a Marvell extended IEEE IE.
741 */
742u32
743mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
744 u8 **assoc_buf,
745 struct ieee_types_wmm_parameter *wmm_ie,
746 struct ieee80211_ht_cap *ht_cap)
747{
748 struct mwifiex_ie_types_wmm_param_set *wmm_tlv;
749 u32 ret_len = 0;
750
751 /* Null checks */
752 if (!assoc_buf)
753 return 0;
754 if (!(*assoc_buf))
755 return 0;
756
757 if (!wmm_ie)
758 return 0;
759
760 dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:"
761 "bss->wmmIe=0x%x\n",
762 wmm_ie->vend_hdr.element_id);
763
764 if ((priv->wmm_required
765 || (ht_cap && (priv->adapter->config_bands & BAND_GN
766 || priv->adapter->config_bands & BAND_AN))
767 )
768 && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) {
769 wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf;
770 wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]);
771 wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]);
772 memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2],
773 le16_to_cpu(wmm_tlv->header.len));
774 if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD)
775 memcpy((u8 *) (wmm_tlv->wmm_ie
776 + le16_to_cpu(wmm_tlv->header.len)
777 - sizeof(priv->wmm_qosinfo)),
778 &priv->wmm_qosinfo,
779 sizeof(priv->wmm_qosinfo));
780
781 ret_len = sizeof(wmm_tlv->header)
782 + le16_to_cpu(wmm_tlv->header.len);
783
784 *assoc_buf += ret_len;
785 }
786
787 return ret_len;
788}
789
790/*
791 * This function computes the time delay in the driver queues for a
792 * given packet.
793 *
794 * When the packet is received at the OS/Driver interface, the current
795 * time is set in the packet structure. The difference between the present
796 * time and that received time is computed in this function and limited
797 * based on pre-compiled limits in the driver.
798 */
799u8
800mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
801 const struct sk_buff *skb)
802{
803 u8 ret_val = 0;
804 struct timeval out_tstamp, in_tstamp;
805 u32 queue_delay;
806
807 do_gettimeofday(&out_tstamp);
808 in_tstamp = ktime_to_timeval(skb->tstamp);
809
810 queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000;
811 queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000;
812
813 /*
814 * Queue delay is passed as a uint8 in units of 2ms (ms shifted
815 * by 1). Min value (other than 0) is therefore 2ms, max is 510ms.
816 *
817 * Pass max value if queue_delay is beyond the uint8 range
818 */
819 ret_val = (u8) (min(queue_delay, priv->wmm.drv_pkt_delay_max) >> 1);
820
821 dev_dbg(priv->adapter->dev, "data: WMM: Pkt Delay: %d ms,"
822 " %d ms sent to FW\n", queue_delay, ret_val);
823
824 return ret_val;
825}
826
827/*
828 * This function retrieves the highest priority RA list table pointer.
829 */
830static struct mwifiex_ra_list_tbl *
831mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
832 struct mwifiex_private **priv, int *tid)
833{
834 struct mwifiex_private *priv_tmp;
835 struct mwifiex_ra_list_tbl *ptr, *head;
836 struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
837 struct mwifiex_tid_tbl *tid_ptr;
838 int is_list_empty;
839 unsigned long flags;
840 int i, j;
841
842 for (j = adapter->priv_num - 1; j >= 0; --j) {
843 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
844 flags);
845 is_list_empty = list_empty(&adapter->bss_prio_tbl[j]
846 .bss_prio_head);
847 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
848 flags);
849 if (is_list_empty)
850 continue;
851
852 if (adapter->bss_prio_tbl[j].bss_prio_cur ==
853 (struct mwifiex_bss_prio_node *)
854 &adapter->bss_prio_tbl[j].bss_prio_head) {
855 bssprio_node =
856 list_first_entry(&adapter->bss_prio_tbl[j]
857 .bss_prio_head,
858 struct mwifiex_bss_prio_node,
859 list);
860 bssprio_head = bssprio_node;
861 } else {
862 bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
863 bssprio_head = bssprio_node;
864 }
865
866 do {
867 priv_tmp = bssprio_node->priv;
868
869 for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) {
870
871 tid_ptr = &(priv_tmp)->wmm.
872 tid_tbl_ptr[tos_to_tid[i]];
873
874 spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
875 flags);
876 is_list_empty =
877 list_empty(&adapter->bss_prio_tbl[j]
878 .bss_prio_head);
879 spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock,
880 flags);
881 if (is_list_empty)
882 continue;
883
884 /*
885 * Always choose the next ra we transmitted
886 * last time, this way we pick the ra's in
887 * round robin fashion.
888 */
889 ptr = list_first_entry(
890 &tid_ptr->ra_list_curr->list,
891 struct mwifiex_ra_list_tbl,
892 list);
893
894 head = ptr;
895 if (ptr == (struct mwifiex_ra_list_tbl *)
896 &tid_ptr->ra_list) {
897 /* Get next ra */
898 ptr = list_first_entry(&ptr->list,
899 struct mwifiex_ra_list_tbl, list);
900 head = ptr;
901 }
902
903 do {
904 is_list_empty =
905 skb_queue_empty(&ptr->skb_head);
906 if (!is_list_empty) {
907 *priv = priv_tmp;
908 *tid = tos_to_tid[i];
909 return ptr;
910 }
911 /* Get next ra */
912 ptr = list_first_entry(&ptr->list,
913 struct mwifiex_ra_list_tbl,
914 list);
915 if (ptr ==
916 (struct mwifiex_ra_list_tbl *)
917 &tid_ptr->ra_list)
918 ptr = list_first_entry(
919 &ptr->list,
920 struct mwifiex_ra_list_tbl,
921 list);
922 } while (ptr != head);
923 }
924
925 /* Get next bss priority node */
926 bssprio_node = list_first_entry(&bssprio_node->list,
927 struct mwifiex_bss_prio_node,
928 list);
929
930 if (bssprio_node ==
931 (struct mwifiex_bss_prio_node *)
932 &adapter->bss_prio_tbl[j].bss_prio_head)
933 /* Get next bss priority node */
934 bssprio_node = list_first_entry(
935 &bssprio_node->list,
936 struct mwifiex_bss_prio_node,
937 list);
938 } while (bssprio_node != bssprio_head);
939 }
940 return NULL;
941}
942
943/*
944 * This function gets the number of packets in the Tx queue of a
945 * particular RA list.
946 */
947static int
948mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
949 struct mwifiex_ra_list_tbl *ptr, int max_buf_size)
950{
951 int count = 0, total_size = 0;
952 struct sk_buff *skb, *tmp;
953
954 skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
955 total_size += skb->len;
956 if (total_size < max_buf_size)
957 ++count;
958 else
959 break;
960 }
961
962 return count;
963}
964
965/*
966 * This function sends a single packet to firmware for transmission.
967 */
968static void
969mwifiex_send_single_packet(struct mwifiex_private *priv,
970 struct mwifiex_ra_list_tbl *ptr, int ptr_index,
971 unsigned long ra_list_flags)
972 __releases(&priv->wmm.ra_list_spinlock)
973{
974 struct sk_buff *skb, *skb_next;
975 struct mwifiex_tx_param tx_param;
976 struct mwifiex_adapter *adapter = priv->adapter;
977 int status = 0;
978 struct mwifiex_txinfo *tx_info;
979
980 if (skb_queue_empty(&ptr->skb_head)) {
981 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
982 ra_list_flags);
983 dev_dbg(adapter->dev, "data: nothing to send\n");
984 return;
985 }
986
987 skb = skb_dequeue(&ptr->skb_head);
988
989 tx_info = MWIFIEX_SKB_TXCB(skb);
990 dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
991
992 ptr->total_pkts_size -= skb->len;
993
994 if (!skb_queue_empty(&ptr->skb_head))
995 skb_next = skb_peek(&ptr->skb_head);
996 else
997 skb_next = NULL;
998
999 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
1000
1001 tx_param.next_pkt_len = ((skb_next) ? skb_next->len +
1002 sizeof(struct txpd) : 0);
1003
1004 status = mwifiex_process_tx(priv, skb, &tx_param);
1005
1006 if (status == -EBUSY) {
1007 /* Queue the packet back at the head */
1008 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
1009
1010 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1011 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1012 ra_list_flags);
1013 mwifiex_write_data_complete(adapter, skb, -1);
1014 return;
1015 }
1016
1017 skb_queue_tail(&ptr->skb_head, skb);
1018
1019 ptr->total_pkts_size += skb->len;
1020 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
1021 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1022 ra_list_flags);
1023 } else {
1024 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
1025 if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1026 priv->wmm.packets_out[ptr_index]++;
1027 priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
1028 }
1029 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
1030 list_first_entry(
1031 &adapter->bss_prio_tbl[priv->bss_priority]
1032 .bss_prio_cur->list,
1033 struct mwifiex_bss_prio_node,
1034 list);
1035 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1036 ra_list_flags);
1037 }
1038}
1039
1040/*
1041 * This function checks if the first packet in the given RA list
1042 * is already processed or not.
1043 */
1044static int
1045mwifiex_is_ptr_processed(struct mwifiex_private *priv,
1046 struct mwifiex_ra_list_tbl *ptr)
1047{
1048 struct sk_buff *skb;
1049 struct mwifiex_txinfo *tx_info;
1050
1051 if (skb_queue_empty(&ptr->skb_head))
1052 return false;
1053
1054 skb = skb_peek(&ptr->skb_head);
1055
1056 tx_info = MWIFIEX_SKB_TXCB(skb);
1057 if (tx_info->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT)
1058 return true;
1059
1060 return false;
1061}
1062
1063/*
1064 * This function sends a single processed packet to firmware for
1065 * transmission.
1066 */
1067static void
1068mwifiex_send_processed_packet(struct mwifiex_private *priv,
1069 struct mwifiex_ra_list_tbl *ptr, int ptr_index,
1070 unsigned long ra_list_flags)
1071 __releases(&priv->wmm.ra_list_spinlock)
1072{
1073 struct mwifiex_tx_param tx_param;
1074 struct mwifiex_adapter *adapter = priv->adapter;
1075 int ret = -1;
1076 struct sk_buff *skb, *skb_next;
1077 struct mwifiex_txinfo *tx_info;
1078
1079 if (skb_queue_empty(&ptr->skb_head)) {
1080 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1081 ra_list_flags);
1082 return;
1083 }
1084
1085 skb = skb_dequeue(&ptr->skb_head);
1086
1087 if (!skb_queue_empty(&ptr->skb_head))
1088 skb_next = skb_peek(&ptr->skb_head);
1089 else
1090 skb_next = NULL;
1091
1092 tx_info = MWIFIEX_SKB_TXCB(skb);
1093
1094 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
1095 tx_param.next_pkt_len =
1096 ((skb_next) ? skb_next->len +
1097 sizeof(struct txpd) : 0);
1098 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
1099 skb->data, skb->len, &tx_param);
1100 switch (ret) {
1101 case -EBUSY:
1102 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
1103 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
1104
1105 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1106 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1107 ra_list_flags);
1108 mwifiex_write_data_complete(adapter, skb, -1);
1109 return;
1110 }
1111
1112 skb_queue_tail(&ptr->skb_head, skb);
1113
1114 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
1115 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1116 ra_list_flags);
1117 break;
1118 case -1:
1119 adapter->data_sent = false;
1120 dev_err(adapter->dev, "host_to_card failed: %#x\n", ret);
1121 adapter->dbg.num_tx_host_to_card_failure++;
1122 mwifiex_write_data_complete(adapter, skb, ret);
1123 break;
1124 case -EINPROGRESS:
1125 adapter->data_sent = false;
1126 default:
1127 break;
1128 }
1129 if (ret != -EBUSY) {
1130 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
1131 if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1132 priv->wmm.packets_out[ptr_index]++;
1133 priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
1134 }
1135 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
1136 list_first_entry(
1137 &adapter->bss_prio_tbl[priv->bss_priority]
1138 .bss_prio_cur->list,
1139 struct mwifiex_bss_prio_node,
1140 list);
1141 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1142 ra_list_flags);
1143 }
1144}
1145
1146/*
1147 * This function dequeues a packet from the highest priority list
1148 * and transmits it.
1149 */
1150static int
1151mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1152{
1153 struct mwifiex_ra_list_tbl *ptr;
1154 struct mwifiex_private *priv = NULL;
1155 int ptr_index = 0;
1156 u8 ra[ETH_ALEN];
1157 int tid_del = 0, tid = 0;
1158 unsigned long flags;
1159
1160 ptr = mwifiex_wmm_get_highest_priolist_ptr(adapter, &priv, &ptr_index);
1161 if (!ptr)
1162 return -1;
1163
1164 tid = mwifiex_get_tid(priv->adapter, ptr);
1165
1166 dev_dbg(adapter->dev, "data: tid=%d\n", tid);
1167
1168 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
1169 if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1170 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
1171 return -1;
1172 }
1173
1174 if (mwifiex_is_ptr_processed(priv, ptr)) {
1175 mwifiex_send_processed_packet(priv, ptr, ptr_index, flags);
1176 /* ra_list_spinlock has been freed in
1177 mwifiex_send_processed_packet() */
1178 return 0;
1179 }
1180
1181 if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid)
1182 || ((priv->sec_info.wpa_enabled
1183 || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)
1184 ) {
1185 mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
1186 /* ra_list_spinlock has been freed in
1187 mwifiex_send_single_packet() */
1188 } else {
1189 if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) {
1190 if (mwifiex_is_ba_stream_avail(priv)) {
1191 mwifiex_11n_create_tx_ba_stream_tbl(priv,
1192 ptr->ra, tid,
1193 BA_STREAM_SETUP_INPROGRESS);
1194 mwifiex_send_addba(priv, tid, ptr->ra);
1195 } else if (mwifiex_find_stream_to_delete
1196 (priv, ptr, tid, &tid_del, ra)) {
1197 mwifiex_11n_create_tx_ba_stream_tbl(priv,
1198 ptr->ra, tid,
1199 BA_STREAM_SETUP_INPROGRESS);
1200 mwifiex_send_delba(priv, tid_del, ra, 1);
1201 }
1202 }
1203/* Minimum number of AMSDU */
1204#define MIN_NUM_AMSDU 2
1205 if (mwifiex_is_amsdu_allowed(priv, ptr, tid) &&
1206 (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >=
1207 MIN_NUM_AMSDU))
1208 mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
1209 ptr_index, flags);
1210 /* ra_list_spinlock has been freed in
1211 mwifiex_11n_aggregate_pkt() */
1212 else
1213 mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
1214 /* ra_list_spinlock has been freed in
1215 mwifiex_send_single_packet() */
1216 }
1217 return 0;
1218}
1219
1220/*
1221 * This function transmits the highest priority packet awaiting in the
1222 * WMM Queues.
1223 */
1224void
1225mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
1226{
1227 do {
1228 /* Check if busy */
1229 if (adapter->data_sent || adapter->tx_lock_flag)
1230 break;
1231
1232 if (mwifiex_dequeue_tx_packet(adapter))
1233 break;
1234 } while (true);
1235
1236 return;
1237}
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
new file mode 100644
index 000000000000..241f1b0b77f9
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -0,0 +1,112 @@
1/*
2 * Marvell Wireless LAN device driver: WMM
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#ifndef _MWIFIEX_WMM_H_
21#define _MWIFIEX_WMM_H_
22
23enum ieee_types_wmm_aciaifsn_bitmasks {
24 MWIFIEX_AIFSN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
25 MWIFIEX_ACM = BIT(4),
26 MWIFIEX_ACI = (BIT(5) | BIT(6)),
27};
28
29enum ieee_types_wmm_ecw_bitmasks {
30 MWIFIEX_ECW_MIN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
31 MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
32};
33
34/*
35 * This function retrieves the TID of the given RA list.
36 */
37static inline int
38mwifiex_get_tid(struct mwifiex_adapter *adapter,
39 struct mwifiex_ra_list_tbl *ptr)
40{
41 struct sk_buff *skb;
42
43 if (skb_queue_empty(&ptr->skb_head))
44 return 0;
45
46 skb = skb_peek(&ptr->skb_head);
47
48 return skb->priority;
49}
50
51/*
52 * This function gets the length of a list.
53 */
54static inline int
55mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head)
56{
57 struct list_head *pos;
58 int count = 0;
59
60 list_for_each(pos, head)
61 ++count;
62
63 return count;
64}
65
66/*
67 * This function checks if a RA list is empty or not.
68 */
69static inline u8
70mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter,
71 struct list_head *ra_list_hhead)
72{
73 struct mwifiex_ra_list_tbl *ra_list;
74 int is_list_empty;
75
76 list_for_each_entry(ra_list, ra_list_hhead, list) {
77 is_list_empty = skb_queue_empty(&ra_list->skb_head);
78 if (!is_list_empty)
79 return false;
80 }
81
82 return true;
83}
84
85void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
86 struct sk_buff *skb);
87void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
88
89int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
90void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter);
91int mwifiex_is_ralist_valid(struct mwifiex_private *priv,
92 struct mwifiex_ra_list_tbl *ra_list, int tid);
93
94u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
95 const struct sk_buff *skb);
96void mwifiex_wmm_init(struct mwifiex_adapter *adapter);
97
98extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
99 u8 **assoc_buf,
100 struct ieee_types_wmm_parameter
101 *wmmie,
102 struct ieee80211_ht_cap
103 *htcap);
104
105void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
106 struct ieee_types_wmm_parameter
107 *wmm_ie);
108void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv);
109extern int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
110 const struct host_cmd_ds_command *resp);
111
112#endif /* !_MWIFIEX_WMM_H_ */
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index c1ceb4b23971..8913180a7bd3 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -63,6 +63,7 @@ MODULE_PARM_DESC(ap_mode_default,
63#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38 63#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
64#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c 64#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
65#define MWL8K_A2H_INT_DUMMY (1 << 20) 65#define MWL8K_A2H_INT_DUMMY (1 << 20)
66#define MWL8K_A2H_INT_BA_WATCHDOG (1 << 14)
66#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11) 67#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
67#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10) 68#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
68#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7) 69#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
@@ -82,10 +83,14 @@ MODULE_PARM_DESC(ap_mode_default,
82 MWL8K_A2H_INT_MAC_EVENT | \ 83 MWL8K_A2H_INT_MAC_EVENT | \
83 MWL8K_A2H_INT_OPC_DONE | \ 84 MWL8K_A2H_INT_OPC_DONE | \
84 MWL8K_A2H_INT_RX_READY | \ 85 MWL8K_A2H_INT_RX_READY | \
85 MWL8K_A2H_INT_TX_DONE) 86 MWL8K_A2H_INT_TX_DONE | \
87 MWL8K_A2H_INT_BA_WATCHDOG)
86 88
87#define MWL8K_RX_QUEUES 1 89#define MWL8K_RX_QUEUES 1
88#define MWL8K_TX_QUEUES 4 90#define MWL8K_TX_WMM_QUEUES 4
91#define MWL8K_MAX_AMPDU_QUEUES 8
92#define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
93#define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
89 94
90struct rxd_ops { 95struct rxd_ops {
91 int rxd_size; 96 int rxd_size;
@@ -134,6 +139,21 @@ struct mwl8k_tx_queue {
134 struct sk_buff **skb; 139 struct sk_buff **skb;
135}; 140};
136 141
142enum {
143 AMPDU_NO_STREAM,
144 AMPDU_STREAM_NEW,
145 AMPDU_STREAM_IN_PROGRESS,
146 AMPDU_STREAM_ACTIVE,
147};
148
149struct mwl8k_ampdu_stream {
150 struct ieee80211_sta *sta;
151 u8 tid;
152 u8 state;
153 u8 idx;
154 u8 txq_idx; /* index of this stream in priv->txq */
155};
156
137struct mwl8k_priv { 157struct mwl8k_priv {
138 struct ieee80211_hw *hw; 158 struct ieee80211_hw *hw;
139 struct pci_dev *pdev; 159 struct pci_dev *pdev;
@@ -160,6 +180,12 @@ struct mwl8k_priv {
160 u32 ap_macids_supported; 180 u32 ap_macids_supported;
161 u32 sta_macids_supported; 181 u32 sta_macids_supported;
162 182
183 /* Ampdu stream information */
184 u8 num_ampdu_queues;
185 spinlock_t stream_lock;
186 struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
187 struct work_struct watchdog_ba_handle;
188
163 /* firmware access */ 189 /* firmware access */
164 struct mutex fw_mutex; 190 struct mutex fw_mutex;
165 struct task_struct *fw_mutex_owner; 191 struct task_struct *fw_mutex_owner;
@@ -191,7 +217,8 @@ struct mwl8k_priv {
191 int pending_tx_pkts; 217 int pending_tx_pkts;
192 218
193 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 219 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
194 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 220 struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
221 u32 txq_offset[MWL8K_MAX_TX_QUEUES];
195 222
196 bool radio_on; 223 bool radio_on;
197 bool radio_short_preamble; 224 bool radio_short_preamble;
@@ -224,7 +251,7 @@ struct mwl8k_priv {
224 * preserve the queue configurations so they can be restored if/when 251 * preserve the queue configurations so they can be restored if/when
225 * the firmware image is swapped. 252 * the firmware image is swapped.
226 */ 253 */
227 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES]; 254 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
228 255
229 /* async firmware loading state */ 256 /* async firmware loading state */
230 unsigned fw_state; 257 unsigned fw_state;
@@ -265,6 +292,7 @@ struct mwl8k_vif {
265struct mwl8k_sta { 292struct mwl8k_sta {
266 /* Index into station database. Returned by UPDATE_STADB. */ 293 /* Index into station database. Returned by UPDATE_STADB. */
267 u8 peer_id; 294 u8 peer_id;
295 u8 is_ampdu_allowed;
268}; 296};
269#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) 297#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
270 298
@@ -352,10 +380,12 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
352#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 380#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
353#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */ 381#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
354#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 382#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
383#define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205
355#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ 384#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
356#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ 385#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
357#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ 386#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
358#define MWL8K_CMD_UPDATE_STADB 0x1123 387#define MWL8K_CMD_UPDATE_STADB 0x1123
388#define MWL8K_CMD_BASTREAM 0x1125
359 389
360static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) 390static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
361{ 391{
@@ -395,6 +425,8 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
395 MWL8K_CMDNAME(SET_NEW_STN); 425 MWL8K_CMDNAME(SET_NEW_STN);
396 MWL8K_CMDNAME(UPDATE_ENCRYPTION); 426 MWL8K_CMDNAME(UPDATE_ENCRYPTION);
397 MWL8K_CMDNAME(UPDATE_STADB); 427 MWL8K_CMDNAME(UPDATE_STADB);
428 MWL8K_CMDNAME(BASTREAM);
429 MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
398 default: 430 default:
399 snprintf(buf, bufsize, "0x%x", cmd); 431 snprintf(buf, bufsize, "0x%x", cmd);
400 } 432 }
@@ -1127,6 +1159,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
1127 struct mwl8k_rx_queue *rxq = priv->rxq + index; 1159 struct mwl8k_rx_queue *rxq = priv->rxq + index;
1128 int i; 1160 int i;
1129 1161
1162 if (rxq->rxd == NULL)
1163 return;
1164
1130 for (i = 0; i < MWL8K_RX_DESCS; i++) { 1165 for (i = 0; i < MWL8K_RX_DESCS; i++) {
1131 if (rxq->buf[i].skb != NULL) { 1166 if (rxq->buf[i].skb != NULL) {
1132 pci_unmap_single(priv->pdev, 1167 pci_unmap_single(priv->pdev,
@@ -1319,7 +1354,7 @@ struct mwl8k_tx_desc {
1319 __le16 pkt_len; 1354 __le16 pkt_len;
1320 __u8 dest_MAC_addr[ETH_ALEN]; 1355 __u8 dest_MAC_addr[ETH_ALEN];
1321 __le32 next_txd_phys_addr; 1356 __le32 next_txd_phys_addr;
1322 __le32 reserved; 1357 __le32 timestamp;
1323 __le16 rate_info; 1358 __le16 rate_info;
1324 __u8 peer_id; 1359 __u8 peer_id;
1325 __u8 tx_frag_cnt; 1360 __u8 tx_frag_cnt;
@@ -1383,7 +1418,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1383 struct mwl8k_priv *priv = hw->priv; 1418 struct mwl8k_priv *priv = hw->priv;
1384 int i; 1419 int i;
1385 1420
1386 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 1421 for (i = 0; i < mwl8k_tx_queues(priv); i++) {
1387 struct mwl8k_tx_queue *txq = priv->txq + i; 1422 struct mwl8k_tx_queue *txq = priv->txq + i;
1388 int fw_owned = 0; 1423 int fw_owned = 0;
1389 int drv_owned = 0; 1424 int drv_owned = 0;
@@ -1484,6 +1519,54 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1484 MWL8K_TXD_STATUS_OK_RETRY | \ 1519 MWL8K_TXD_STATUS_OK_RETRY | \
1485 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1520 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1486 1521
1522static int mwl8k_tid_queue_mapping(u8 tid)
1523{
1524 BUG_ON(tid > 7);
1525
1526 switch (tid) {
1527 case 0:
1528 case 3:
1529 return IEEE80211_AC_BE;
1530 break;
1531 case 1:
1532 case 2:
1533 return IEEE80211_AC_BK;
1534 break;
1535 case 4:
1536 case 5:
1537 return IEEE80211_AC_VI;
1538 break;
1539 case 6:
1540 case 7:
1541 return IEEE80211_AC_VO;
1542 break;
1543 default:
1544 return -1;
1545 break;
1546 }
1547}
1548
1549/* The firmware will fill in the rate information
1550 * for each packet that gets queued in the hardware
1551 * in this structure
1552 */
1553
1554struct rateinfo {
1555 __le16 format:1;
1556 __le16 short_gi:1;
1557 __le16 band_width:1;
1558 __le16 rate_id_mcs:6;
1559 __le16 adv_coding:2;
1560 __le16 antenna:2;
1561 __le16 act_sub_chan:2;
1562 __le16 preamble_type:1;
1563 __le16 power_id:4;
1564 __le16 antenna2:1;
1565 __le16 reserved:1;
1566 __le16 tx_bf_frame:1;
1567 __le16 green_field:1;
1568} __packed;
1569
1487static int 1570static int
1488mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) 1571mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1489{ 1572{
@@ -1500,6 +1583,11 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1500 struct sk_buff *skb; 1583 struct sk_buff *skb;
1501 struct ieee80211_tx_info *info; 1584 struct ieee80211_tx_info *info;
1502 u32 status; 1585 u32 status;
1586 struct ieee80211_sta *sta;
1587 struct mwl8k_sta *sta_info = NULL;
1588 u16 rate_info;
1589 struct rateinfo *rate;
1590 struct ieee80211_hdr *wh;
1503 1591
1504 tx = txq->head; 1592 tx = txq->head;
1505 tx_desc = txq->txd + tx; 1593 tx_desc = txq->txd + tx;
@@ -1528,11 +1616,34 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1528 1616
1529 mwl8k_remove_dma_header(skb, tx_desc->qos_control); 1617 mwl8k_remove_dma_header(skb, tx_desc->qos_control);
1530 1618
1619 wh = (struct ieee80211_hdr *) skb->data;
1620
1531 /* Mark descriptor as unused */ 1621 /* Mark descriptor as unused */
1532 tx_desc->pkt_phys_addr = 0; 1622 tx_desc->pkt_phys_addr = 0;
1533 tx_desc->pkt_len = 0; 1623 tx_desc->pkt_len = 0;
1534 1624
1535 info = IEEE80211_SKB_CB(skb); 1625 info = IEEE80211_SKB_CB(skb);
1626 if (ieee80211_is_data(wh->frame_control)) {
1627 sta = info->control.sta;
1628 if (sta) {
1629 sta_info = MWL8K_STA(sta);
1630 BUG_ON(sta_info == NULL);
1631 rate_info = le16_to_cpu(tx_desc->rate_info);
1632 rate = (struct rateinfo *)&rate_info;
1633 /* If rate is < 6.5 Mpbs for an ht station
1634 * do not form an ampdu. If the station is a
1635 * legacy station (format = 0), do not form an
1636 * ampdu
1637 */
1638 if (rate->rate_id_mcs < 1 ||
1639 rate->format == 0) {
1640 sta_info->is_ampdu_allowed = false;
1641 } else {
1642 sta_info->is_ampdu_allowed = true;
1643 }
1644 }
1645 }
1646
1536 ieee80211_tx_info_clear_status(info); 1647 ieee80211_tx_info_clear_status(info);
1537 1648
1538 /* Rate control is happening in the firmware. 1649 /* Rate control is happening in the firmware.
@@ -1549,7 +1660,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1549 processed++; 1660 processed++;
1550 } 1661 }
1551 1662
1552 if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) 1663 if (index < MWL8K_TX_WMM_QUEUES && processed && priv->radio_on &&
1664 !mutex_is_locked(&priv->fw_mutex))
1553 ieee80211_wake_queue(hw, index); 1665 ieee80211_wake_queue(hw, index);
1554 1666
1555 return processed; 1667 return processed;
@@ -1561,6 +1673,9 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1561 struct mwl8k_priv *priv = hw->priv; 1673 struct mwl8k_priv *priv = hw->priv;
1562 struct mwl8k_tx_queue *txq = priv->txq + index; 1674 struct mwl8k_tx_queue *txq = priv->txq + index;
1563 1675
1676 if (txq->txd == NULL)
1677 return;
1678
1564 mwl8k_txq_reclaim(hw, index, INT_MAX, 1); 1679 mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1565 1680
1566 kfree(txq->skb); 1681 kfree(txq->skb);
@@ -1572,12 +1687,81 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1572 txq->txd = NULL; 1687 txq->txd = NULL;
1573} 1688}
1574 1689
1690/* caller must hold priv->stream_lock when calling the stream functions */
1691struct mwl8k_ampdu_stream *
1692mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
1693{
1694 struct mwl8k_ampdu_stream *stream;
1695 struct mwl8k_priv *priv = hw->priv;
1696 int i;
1697
1698 for (i = 0; i < priv->num_ampdu_queues; i++) {
1699 stream = &priv->ampdu[i];
1700 if (stream->state == AMPDU_NO_STREAM) {
1701 stream->sta = sta;
1702 stream->state = AMPDU_STREAM_NEW;
1703 stream->tid = tid;
1704 stream->idx = i;
1705 stream->txq_idx = MWL8K_TX_WMM_QUEUES + i;
1706 wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
1707 sta->addr, tid);
1708 return stream;
1709 }
1710 }
1711 return NULL;
1712}
1713
1714static int
1715mwl8k_start_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
1716{
1717 int ret;
1718
1719 /* if the stream has already been started, don't start it again */
1720 if (stream->state != AMPDU_STREAM_NEW)
1721 return 0;
1722 ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0);
1723 if (ret)
1724 wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: "
1725 "%d\n", stream->sta->addr, stream->tid, ret);
1726 else
1727 wiphy_debug(hw->wiphy, "Started stream for %pM %d\n",
1728 stream->sta->addr, stream->tid);
1729 return ret;
1730}
1731
1732static void
1733mwl8k_remove_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
1734{
1735 wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr,
1736 stream->tid);
1737 memset(stream, 0, sizeof(*stream));
1738}
1739
1740static struct mwl8k_ampdu_stream *
1741mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
1742{
1743 struct mwl8k_priv *priv = hw->priv;
1744 int i;
1745
1746 for (i = 0 ; i < priv->num_ampdu_queues; i++) {
1747 struct mwl8k_ampdu_stream *stream;
1748 stream = &priv->ampdu[i];
1749 if (stream->state == AMPDU_NO_STREAM)
1750 continue;
1751 if (!memcmp(stream->sta->addr, addr, ETH_ALEN) &&
1752 stream->tid == tid)
1753 return stream;
1754 }
1755 return NULL;
1756}
1757
1575static void 1758static void
1576mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) 1759mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1577{ 1760{
1578 struct mwl8k_priv *priv = hw->priv; 1761 struct mwl8k_priv *priv = hw->priv;
1579 struct ieee80211_tx_info *tx_info; 1762 struct ieee80211_tx_info *tx_info;
1580 struct mwl8k_vif *mwl8k_vif; 1763 struct mwl8k_vif *mwl8k_vif;
1764 struct ieee80211_sta *sta;
1581 struct ieee80211_hdr *wh; 1765 struct ieee80211_hdr *wh;
1582 struct mwl8k_tx_queue *txq; 1766 struct mwl8k_tx_queue *txq;
1583 struct mwl8k_tx_desc *tx; 1767 struct mwl8k_tx_desc *tx;
@@ -1585,6 +1769,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1585 u32 txstatus; 1769 u32 txstatus;
1586 u8 txdatarate; 1770 u8 txdatarate;
1587 u16 qos; 1771 u16 qos;
1772 int txpriority;
1773 u8 tid = 0;
1774 struct mwl8k_ampdu_stream *stream = NULL;
1775 bool start_ba_session = false;
1776 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1588 1777
1589 wh = (struct ieee80211_hdr *)skb->data; 1778 wh = (struct ieee80211_hdr *)skb->data;
1590 if (ieee80211_is_data_qos(wh->frame_control)) 1779 if (ieee80211_is_data_qos(wh->frame_control))
@@ -1600,6 +1789,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1600 wh = &((struct mwl8k_dma_data *)skb->data)->wh; 1789 wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1601 1790
1602 tx_info = IEEE80211_SKB_CB(skb); 1791 tx_info = IEEE80211_SKB_CB(skb);
1792 sta = tx_info->control.sta;
1603 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1793 mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1604 1794
1605 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1795 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -1627,12 +1817,90 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1627 qos |= MWL8K_QOS_ACK_POLICY_NORMAL; 1817 qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
1628 } 1818 }
1629 1819
1820 /* Queue ADDBA request in the respective data queue. While setting up
1821 * the ampdu stream, mac80211 queues further packets for that
1822 * particular ra/tid pair. However, packets piled up in the hardware
1823 * for that ra/tid pair will still go out. ADDBA request and the
1824 * related data packets going out from different queues asynchronously
1825 * will cause a shift in the receiver window which might result in
1826 * ampdu packets getting dropped at the receiver after the stream has
1827 * been setup.
1828 */
1829 if (unlikely(ieee80211_is_action(wh->frame_control) &&
1830 mgmt->u.action.category == WLAN_CATEGORY_BACK &&
1831 mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
1832 priv->ap_fw)) {
1833 u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
1834 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1835 index = mwl8k_tid_queue_mapping(tid);
1836 }
1837
1838 txpriority = index;
1839
1840 if (ieee80211_is_data_qos(wh->frame_control) &&
1841 skb->protocol != cpu_to_be16(ETH_P_PAE) &&
1842 sta->ht_cap.ht_supported && priv->ap_fw) {
1843 tid = qos & 0xf;
1844 spin_lock(&priv->stream_lock);
1845 stream = mwl8k_lookup_stream(hw, sta->addr, tid);
1846 if (stream != NULL) {
1847 if (stream->state == AMPDU_STREAM_ACTIVE) {
1848 txpriority = stream->txq_idx;
1849 index = stream->txq_idx;
1850 } else if (stream->state == AMPDU_STREAM_NEW) {
1851 /* We get here if the driver sends us packets
1852 * after we've initiated a stream, but before
1853 * our ampdu_action routine has been called
1854 * with IEEE80211_AMPDU_TX_START to get the SSN
1855 * for the ADDBA request. So this packet can
1856 * go out with no risk of sequence number
1857 * mismatch. No special handling is required.
1858 */
1859 } else {
1860 /* Drop packets that would go out after the
1861 * ADDBA request was sent but before the ADDBA
1862 * response is received. If we don't do this,
1863 * the recipient would probably receive it
1864 * after the ADDBA request with SSN 0. This
1865 * will cause the recipient's BA receive window
1866 * to shift, which would cause the subsequent
1867 * packets in the BA stream to be discarded.
1868 * mac80211 queues our packets for us in this
1869 * case, so this is really just a safety check.
1870 */
1871 wiphy_warn(hw->wiphy,
1872 "Cannot send packet while ADDBA "
1873 "dialog is underway.\n");
1874 spin_unlock(&priv->stream_lock);
1875 dev_kfree_skb(skb);
1876 return;
1877 }
1878 } else {
1879 /* Defer calling mwl8k_start_stream so that the current
1880 * skb can go out before the ADDBA request. This
1881 * prevents sequence number mismatch at the recepient
1882 * as described above.
1883 */
1884 if (MWL8K_STA(sta)->is_ampdu_allowed) {
1885 stream = mwl8k_add_stream(hw, sta, tid);
1886 if (stream != NULL)
1887 start_ba_session = true;
1888 }
1889 }
1890 spin_unlock(&priv->stream_lock);
1891 }
1892
1630 dma = pci_map_single(priv->pdev, skb->data, 1893 dma = pci_map_single(priv->pdev, skb->data,
1631 skb->len, PCI_DMA_TODEVICE); 1894 skb->len, PCI_DMA_TODEVICE);
1632 1895
1633 if (pci_dma_mapping_error(priv->pdev, dma)) { 1896 if (pci_dma_mapping_error(priv->pdev, dma)) {
1634 wiphy_debug(hw->wiphy, 1897 wiphy_debug(hw->wiphy,
1635 "failed to dma map skb, dropping TX frame.\n"); 1898 "failed to dma map skb, dropping TX frame.\n");
1899 if (start_ba_session) {
1900 spin_lock(&priv->stream_lock);
1901 mwl8k_remove_stream(hw, stream);
1902 spin_unlock(&priv->stream_lock);
1903 }
1636 dev_kfree_skb(skb); 1904 dev_kfree_skb(skb);
1637 return; 1905 return;
1638 } 1906 }
@@ -1641,12 +1909,22 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1641 1909
1642 txq = priv->txq + index; 1910 txq = priv->txq + index;
1643 1911
1912 if (index >= MWL8K_TX_WMM_QUEUES && txq->len >= MWL8K_TX_DESCS) {
1913 /* This is the case in which the tx packet is destined for an
1914 * AMPDU queue and that AMPDU queue is full. Because we don't
1915 * start and stop the AMPDU queues, we must drop these packets.
1916 */
1917 dev_kfree_skb(skb);
1918 spin_unlock_bh(&priv->tx_lock);
1919 return;
1920 }
1921
1644 BUG_ON(txq->skb[txq->tail] != NULL); 1922 BUG_ON(txq->skb[txq->tail] != NULL);
1645 txq->skb[txq->tail] = skb; 1923 txq->skb[txq->tail] = skb;
1646 1924
1647 tx = txq->txd + txq->tail; 1925 tx = txq->txd + txq->tail;
1648 tx->data_rate = txdatarate; 1926 tx->data_rate = txdatarate;
1649 tx->tx_priority = index; 1927 tx->tx_priority = txpriority;
1650 tx->qos_control = cpu_to_le16(qos); 1928 tx->qos_control = cpu_to_le16(qos);
1651 tx->pkt_phys_addr = cpu_to_le32(dma); 1929 tx->pkt_phys_addr = cpu_to_le32(dma);
1652 tx->pkt_len = cpu_to_le16(skb->len); 1930 tx->pkt_len = cpu_to_le16(skb->len);
@@ -1665,12 +1943,20 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1665 if (txq->tail == MWL8K_TX_DESCS) 1943 if (txq->tail == MWL8K_TX_DESCS)
1666 txq->tail = 0; 1944 txq->tail = 0;
1667 1945
1668 if (txq->head == txq->tail) 1946 if (txq->head == txq->tail && index < MWL8K_TX_WMM_QUEUES)
1669 ieee80211_stop_queue(hw, index); 1947 ieee80211_stop_queue(hw, index);
1670 1948
1671 mwl8k_tx_start(priv); 1949 mwl8k_tx_start(priv);
1672 1950
1673 spin_unlock_bh(&priv->tx_lock); 1951 spin_unlock_bh(&priv->tx_lock);
1952
1953 /* Initiate the ampdu session here */
1954 if (start_ba_session) {
1955 spin_lock(&priv->stream_lock);
1956 if (mwl8k_start_stream(hw, stream))
1957 mwl8k_remove_stream(hw, stream);
1958 spin_unlock(&priv->stream_lock);
1959 }
1674} 1960}
1675 1961
1676 1962
@@ -1868,7 +2154,7 @@ struct mwl8k_cmd_get_hw_spec_sta {
1868 __u8 mcs_bitmap[16]; 2154 __u8 mcs_bitmap[16];
1869 __le32 rx_queue_ptr; 2155 __le32 rx_queue_ptr;
1870 __le32 num_tx_queues; 2156 __le32 num_tx_queues;
1871 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 2157 __le32 tx_queue_ptrs[MWL8K_TX_WMM_QUEUES];
1872 __le32 caps2; 2158 __le32 caps2;
1873 __le32 num_tx_desc_per_queue; 2159 __le32 num_tx_desc_per_queue;
1874 __le32 total_rxd; 2160 __le32 total_rxd;
@@ -1974,8 +2260,8 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1974 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); 2260 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1975 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 2261 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1976 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); 2262 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1977 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 2263 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
1978 for (i = 0; i < MWL8K_TX_QUEUES; i++) 2264 for (i = 0; i < mwl8k_tx_queues(priv); i++)
1979 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); 2265 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1980 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 2266 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1981 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 2267 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
@@ -2017,13 +2303,16 @@ struct mwl8k_cmd_get_hw_spec_ap {
2017 __le32 wcbbase2; 2303 __le32 wcbbase2;
2018 __le32 wcbbase3; 2304 __le32 wcbbase3;
2019 __le32 fw_api_version; 2305 __le32 fw_api_version;
2306 __le32 caps;
2307 __le32 num_of_ampdu_queues;
2308 __le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES];
2020} __packed; 2309} __packed;
2021 2310
2022static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) 2311static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2023{ 2312{
2024 struct mwl8k_priv *priv = hw->priv; 2313 struct mwl8k_priv *priv = hw->priv;
2025 struct mwl8k_cmd_get_hw_spec_ap *cmd; 2314 struct mwl8k_cmd_get_hw_spec_ap *cmd;
2026 int rc; 2315 int rc, i;
2027 u32 api_version; 2316 u32 api_version;
2028 2317
2029 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2318 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2055,27 +2344,31 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
2055 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 2344 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
2056 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 2345 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
2057 priv->hw_rev = cmd->hw_rev; 2346 priv->hw_rev = cmd->hw_rev;
2058 mwl8k_setup_2ghz_band(hw); 2347 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
2059 priv->ap_macids_supported = 0x000000ff; 2348 priv->ap_macids_supported = 0x000000ff;
2060 priv->sta_macids_supported = 0x00000000; 2349 priv->sta_macids_supported = 0x00000000;
2061 2350 priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
2062 off = le32_to_cpu(cmd->wcbbase0) & 0xffff; 2351 if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
2063 iowrite32(priv->txq[0].txd_dma, priv->sram + off); 2352 wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
2064 2353 " but we only support %d.\n",
2354 priv->num_ampdu_queues,
2355 MWL8K_MAX_AMPDU_QUEUES);
2356 priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES;
2357 }
2065 off = le32_to_cpu(cmd->rxwrptr) & 0xffff; 2358 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
2066 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2359 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2067 2360
2068 off = le32_to_cpu(cmd->rxrdptr) & 0xffff; 2361 off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
2069 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); 2362 iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
2070 2363
2071 off = le32_to_cpu(cmd->wcbbase1) & 0xffff; 2364 priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff;
2072 iowrite32(priv->txq[1].txd_dma, priv->sram + off); 2365 priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
2366 priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
2367 priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
2073 2368
2074 off = le32_to_cpu(cmd->wcbbase2) & 0xffff; 2369 for (i = 0; i < priv->num_ampdu_queues; i++)
2075 iowrite32(priv->txq[2].txd_dma, priv->sram + off); 2370 priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] =
2076 2371 le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff;
2077 off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
2078 iowrite32(priv->txq[3].txd_dma, priv->sram + off);
2079 } 2372 }
2080 2373
2081done: 2374done:
@@ -2098,12 +2391,20 @@ struct mwl8k_cmd_set_hw_spec {
2098 __le32 caps; 2391 __le32 caps;
2099 __le32 rx_queue_ptr; 2392 __le32 rx_queue_ptr;
2100 __le32 num_tx_queues; 2393 __le32 num_tx_queues;
2101 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 2394 __le32 tx_queue_ptrs[MWL8K_MAX_TX_QUEUES];
2102 __le32 flags; 2395 __le32 flags;
2103 __le32 num_tx_desc_per_queue; 2396 __le32 num_tx_desc_per_queue;
2104 __le32 total_rxd; 2397 __le32 total_rxd;
2105} __packed; 2398} __packed;
2106 2399
2400/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause
2401 * packets to expire 500 ms after the timestamp in the tx descriptor. That is,
2402 * the packets that are queued for more than 500ms, will be dropped in the
2403 * hardware. This helps minimizing the issues caused due to head-of-line
2404 * blocking where a slow client can hog the bandwidth and affect traffic to a
2405 * faster client.
2406 */
2407#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400
2107#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 2408#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
2108#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 2409#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
2109#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 2410#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
@@ -2124,7 +2425,7 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
2124 2425
2125 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 2426 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
2126 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); 2427 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
2127 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 2428 cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
2128 2429
2129 /* 2430 /*
2130 * Mac80211 stack has Q0 as highest priority and Q3 as lowest in 2431 * Mac80211 stack has Q0 as highest priority and Q3 as lowest in
@@ -2132,8 +2433,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
2132 * in that order. Map Q3 of mac80211 to Q0 of firmware so that the 2433 * in that order. Map Q3 of mac80211 to Q0 of firmware so that the
2133 * priority is interpreted the right way in firmware. 2434 * priority is interpreted the right way in firmware.
2134 */ 2435 */
2135 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 2436 for (i = 0; i < mwl8k_tx_queues(priv); i++) {
2136 int j = MWL8K_TX_QUEUES - 1 - i; 2437 int j = mwl8k_tx_queues(priv) - 1 - i;
2137 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma); 2438 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma);
2138 } 2439 }
2139 2440
@@ -3123,6 +3424,65 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
3123} 3424}
3124 3425
3125/* 3426/*
3427 * CMD_GET_WATCHDOG_BITMAP.
3428 */
3429struct mwl8k_cmd_get_watchdog_bitmap {
3430 struct mwl8k_cmd_pkt header;
3431 u8 bitmap;
3432} __packed;
3433
3434static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
3435{
3436 struct mwl8k_cmd_get_watchdog_bitmap *cmd;
3437 int rc;
3438
3439 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3440 if (cmd == NULL)
3441 return -ENOMEM;
3442
3443 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP);
3444 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3445
3446 rc = mwl8k_post_cmd(hw, &cmd->header);
3447 if (!rc)
3448 *bitmap = cmd->bitmap;
3449
3450 kfree(cmd);
3451
3452 return rc;
3453}
3454
3455#define INVALID_BA 0xAA
3456static void mwl8k_watchdog_ba_events(struct work_struct *work)
3457{
3458 int rc;
3459 u8 bitmap = 0, stream_index;
3460 struct mwl8k_ampdu_stream *streams;
3461 struct mwl8k_priv *priv =
3462 container_of(work, struct mwl8k_priv, watchdog_ba_handle);
3463
3464 rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap);
3465 if (rc)
3466 return;
3467
3468 if (bitmap == INVALID_BA)
3469 return;
3470
3471 /* the bitmap is the hw queue number. Map it to the ampdu queue. */
3472 stream_index = bitmap - MWL8K_TX_WMM_QUEUES;
3473
3474 BUG_ON(stream_index >= priv->num_ampdu_queues);
3475
3476 streams = &priv->ampdu[stream_index];
3477
3478 if (streams->state == AMPDU_STREAM_ACTIVE)
3479 ieee80211_stop_tx_ba_session(streams->sta, streams->tid);
3480
3481 return;
3482}
3483
3484
3485/*
3126 * CMD_BSS_START. 3486 * CMD_BSS_START.
3127 */ 3487 */
3128struct mwl8k_cmd_bss_start { 3488struct mwl8k_cmd_bss_start {
@@ -3151,6 +3511,152 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3151} 3511}
3152 3512
3153/* 3513/*
3514 * CMD_BASTREAM.
3515 */
3516
3517/*
3518 * UPSTREAM is tx direction
3519 */
3520#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00
3521#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01
3522
3523enum {
3524 MWL8K_BA_CREATE,
3525 MWL8K_BA_UPDATE,
3526 MWL8K_BA_DESTROY,
3527 MWL8K_BA_FLUSH,
3528 MWL8K_BA_CHECK,
3529} ba_stream_action_type;
3530
3531
3532struct mwl8k_create_ba_stream {
3533 __le32 flags;
3534 __le32 idle_thrs;
3535 __le32 bar_thrs;
3536 __le32 window_size;
3537 u8 peer_mac_addr[6];
3538 u8 dialog_token;
3539 u8 tid;
3540 u8 queue_id;
3541 u8 param_info;
3542 __le32 ba_context;
3543 u8 reset_seq_no_flag;
3544 __le16 curr_seq_no;
3545 u8 sta_src_mac_addr[6];
3546} __packed;
3547
3548struct mwl8k_destroy_ba_stream {
3549 __le32 flags;
3550 __le32 ba_context;
3551} __packed;
3552
3553struct mwl8k_cmd_bastream {
3554 struct mwl8k_cmd_pkt header;
3555 __le32 action;
3556 union {
3557 struct mwl8k_create_ba_stream create_params;
3558 struct mwl8k_destroy_ba_stream destroy_params;
3559 };
3560} __packed;
3561
3562static int
3563mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
3564{
3565 struct mwl8k_cmd_bastream *cmd;
3566 int rc;
3567
3568 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3569 if (cmd == NULL)
3570 return -ENOMEM;
3571
3572 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
3573 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3574
3575 cmd->action = cpu_to_le32(MWL8K_BA_CHECK);
3576
3577 cmd->create_params.queue_id = stream->idx;
3578 memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr,
3579 ETH_ALEN);
3580 cmd->create_params.tid = stream->tid;
3581
3582 cmd->create_params.flags =
3583 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
3584 cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
3585
3586 rc = mwl8k_post_cmd(hw, &cmd->header);
3587
3588 kfree(cmd);
3589
3590 return rc;
3591}
3592
3593static int
3594mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
3595 u8 buf_size)
3596{
3597 struct mwl8k_cmd_bastream *cmd;
3598 int rc;
3599
3600 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3601 if (cmd == NULL)
3602 return -ENOMEM;
3603
3604
3605 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
3606 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3607
3608 cmd->action = cpu_to_le32(MWL8K_BA_CREATE);
3609
3610 cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size);
3611 cmd->create_params.window_size = cpu_to_le32((u32)buf_size);
3612 cmd->create_params.queue_id = stream->idx;
3613
3614 memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN);
3615 cmd->create_params.tid = stream->tid;
3616 cmd->create_params.curr_seq_no = cpu_to_le16(0);
3617 cmd->create_params.reset_seq_no_flag = 1;
3618
3619 cmd->create_params.param_info =
3620 (stream->sta->ht_cap.ampdu_factor &
3621 IEEE80211_HT_AMPDU_PARM_FACTOR) |
3622 ((stream->sta->ht_cap.ampdu_density << 2) &
3623 IEEE80211_HT_AMPDU_PARM_DENSITY);
3624
3625 cmd->create_params.flags =
3626 cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
3627 BASTREAM_FLAG_DIRECTION_UPSTREAM);
3628
3629 rc = mwl8k_post_cmd(hw, &cmd->header);
3630
3631 wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
3632 stream->sta->addr, stream->tid);
3633 kfree(cmd);
3634
3635 return rc;
3636}
3637
3638static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
3639 struct mwl8k_ampdu_stream *stream)
3640{
3641 struct mwl8k_cmd_bastream *cmd;
3642
3643 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3644 if (cmd == NULL)
3645 return;
3646
3647 cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
3648 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3649 cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
3650
3651 cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
3652 mwl8k_post_cmd(hw, &cmd->header);
3653
3654 wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
3655
3656 kfree(cmd);
3657}
3658
3659/*
3154 * CMD_SET_NEW_STN. 3660 * CMD_SET_NEW_STN.
3155 */ 3661 */
3156struct mwl8k_cmd_set_new_stn { 3662struct mwl8k_cmd_set_new_stn {
@@ -3671,6 +4177,11 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
3671 tasklet_schedule(&priv->poll_rx_task); 4177 tasklet_schedule(&priv->poll_rx_task);
3672 } 4178 }
3673 4179
4180 if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
4181 status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
4182 ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
4183 }
4184
3674 if (status) 4185 if (status)
3675 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 4186 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3676 4187
@@ -3699,7 +4210,7 @@ static void mwl8k_tx_poll(unsigned long data)
3699 4210
3700 spin_lock_bh(&priv->tx_lock); 4211 spin_lock_bh(&priv->tx_lock);
3701 4212
3702 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4213 for (i = 0; i < mwl8k_tx_queues(priv); i++)
3703 limit -= mwl8k_txq_reclaim(hw, i, limit, 0); 4214 limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
3704 4215
3705 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { 4216 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
@@ -3829,6 +4340,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
3829 4340
3830 /* Stop finalize join worker */ 4341 /* Stop finalize join worker */
3831 cancel_work_sync(&priv->finalize_join_worker); 4342 cancel_work_sync(&priv->finalize_join_worker);
4343 cancel_work_sync(&priv->watchdog_ba_handle);
3832 if (priv->beacon_skb != NULL) 4344 if (priv->beacon_skb != NULL)
3833 dev_kfree_skb(priv->beacon_skb); 4345 dev_kfree_skb(priv->beacon_skb);
3834 4346
@@ -3837,7 +4349,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
3837 tasklet_disable(&priv->poll_rx_task); 4349 tasklet_disable(&priv->poll_rx_task);
3838 4350
3839 /* Return all skbs to mac80211 */ 4351 /* Return all skbs to mac80211 */
3840 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4352 for (i = 0; i < mwl8k_tx_queues(priv); i++)
3841 mwl8k_txq_reclaim(hw, i, INT_MAX, 1); 4353 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
3842} 4354}
3843 4355
@@ -3958,9 +4470,12 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
3958 conf->power_level = 18; 4470 conf->power_level = 18;
3959 4471
3960 if (priv->ap_fw) { 4472 if (priv->ap_fw) {
3961 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); 4473
3962 if (rc) 4474 if (conf->flags & IEEE80211_CONF_CHANGE_POWER) {
3963 goto out; 4475 rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
4476 if (rc)
4477 goto out;
4478 }
3964 4479
3965 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3); 4480 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
3966 if (rc) 4481 if (rc)
@@ -4312,6 +4827,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw,
4312 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); 4827 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
4313 if (ret >= 0) { 4828 if (ret >= 0) {
4314 MWL8K_STA(sta)->peer_id = ret; 4829 MWL8K_STA(sta)->peer_id = ret;
4830 if (sta->ht_cap.ht_supported)
4831 MWL8K_STA(sta)->is_ampdu_allowed = true;
4315 ret = 0; 4832 ret = 0;
4316 } 4833 }
4317 4834
@@ -4335,14 +4852,14 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
4335 4852
4336 rc = mwl8k_fw_lock(hw); 4853 rc = mwl8k_fw_lock(hw);
4337 if (!rc) { 4854 if (!rc) {
4338 BUG_ON(queue > MWL8K_TX_QUEUES - 1); 4855 BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1);
4339 memcpy(&priv->wmm_params[queue], params, sizeof(*params)); 4856 memcpy(&priv->wmm_params[queue], params, sizeof(*params));
4340 4857
4341 if (!priv->wmm_enabled) 4858 if (!priv->wmm_enabled)
4342 rc = mwl8k_cmd_set_wmm_mode(hw, 1); 4859 rc = mwl8k_cmd_set_wmm_mode(hw, 1);
4343 4860
4344 if (!rc) { 4861 if (!rc) {
4345 int q = MWL8K_TX_QUEUES - 1 - queue; 4862 int q = MWL8K_TX_WMM_QUEUES - 1 - queue;
4346 rc = mwl8k_cmd_set_edca_params(hw, q, 4863 rc = mwl8k_cmd_set_edca_params(hw, q,
4347 params->cw_min, 4864 params->cw_min,
4348 params->cw_max, 4865 params->cw_max,
@@ -4378,21 +4895,118 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
4378 return 0; 4895 return 0;
4379} 4896}
4380 4897
4898#define MAX_AMPDU_ATTEMPTS 5
4899
4381static int 4900static int
4382mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4901mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4383 enum ieee80211_ampdu_mlme_action action, 4902 enum ieee80211_ampdu_mlme_action action,
4384 struct ieee80211_sta *sta, u16 tid, u16 *ssn, 4903 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
4385 u8 buf_size) 4904 u8 buf_size)
4386{ 4905{
4906
4907 int i, rc = 0;
4908 struct mwl8k_priv *priv = hw->priv;
4909 struct mwl8k_ampdu_stream *stream;
4910 u8 *addr = sta->addr;
4911
4912 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
4913 return -ENOTSUPP;
4914
4915 spin_lock(&priv->stream_lock);
4916 stream = mwl8k_lookup_stream(hw, addr, tid);
4917
4387 switch (action) { 4918 switch (action) {
4388 case IEEE80211_AMPDU_RX_START: 4919 case IEEE80211_AMPDU_RX_START:
4389 case IEEE80211_AMPDU_RX_STOP: 4920 case IEEE80211_AMPDU_RX_STOP:
4390 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) 4921 break;
4391 return -ENOTSUPP; 4922 case IEEE80211_AMPDU_TX_START:
4392 return 0; 4923 /* By the time we get here the hw queues may contain outgoing
4924 * packets for this RA/TID that are not part of this BA
4925 * session. The hw will assign sequence numbers to these
4926 * packets as they go out. So if we query the hw for its next
4927 * sequence number and use that for the SSN here, it may end up
4928 * being wrong, which will lead to sequence number mismatch at
4929 * the recipient. To avoid this, we reset the sequence number
4930 * to O for the first MPDU in this BA stream.
4931 */
4932 *ssn = 0;
4933 if (stream == NULL) {
4934 /* This means that somebody outside this driver called
4935 * ieee80211_start_tx_ba_session. This is unexpected
4936 * because we do our own rate control. Just warn and
4937 * move on.
4938 */
4939 wiphy_warn(hw->wiphy, "Unexpected call to %s. "
4940 "Proceeding anyway.\n", __func__);
4941 stream = mwl8k_add_stream(hw, sta, tid);
4942 }
4943 if (stream == NULL) {
4944 wiphy_debug(hw->wiphy, "no free AMPDU streams\n");
4945 rc = -EBUSY;
4946 break;
4947 }
4948 stream->state = AMPDU_STREAM_IN_PROGRESS;
4949
4950 /* Release the lock before we do the time consuming stuff */
4951 spin_unlock(&priv->stream_lock);
4952 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
4953 rc = mwl8k_check_ba(hw, stream);
4954
4955 if (!rc)
4956 break;
4957 /*
4958 * HW queues take time to be flushed, give them
4959 * sufficient time
4960 */
4961
4962 msleep(1000);
4963 }
4964 spin_lock(&priv->stream_lock);
4965 if (rc) {
4966 wiphy_err(hw->wiphy, "Stream for tid %d busy after %d"
4967 " attempts\n", tid, MAX_AMPDU_ATTEMPTS);
4968 mwl8k_remove_stream(hw, stream);
4969 rc = -EBUSY;
4970 break;
4971 }
4972 ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
4973 break;
4974 case IEEE80211_AMPDU_TX_STOP:
4975 if (stream == NULL)
4976 break;
4977 if (stream->state == AMPDU_STREAM_ACTIVE) {
4978 spin_unlock(&priv->stream_lock);
4979 mwl8k_destroy_ba(hw, stream);
4980 spin_lock(&priv->stream_lock);
4981 }
4982 mwl8k_remove_stream(hw, stream);
4983 ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
4984 break;
4985 case IEEE80211_AMPDU_TX_OPERATIONAL:
4986 BUG_ON(stream == NULL);
4987 BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
4988 spin_unlock(&priv->stream_lock);
4989 rc = mwl8k_create_ba(hw, stream, buf_size);
4990 spin_lock(&priv->stream_lock);
4991 if (!rc)
4992 stream->state = AMPDU_STREAM_ACTIVE;
4993 else {
4994 spin_unlock(&priv->stream_lock);
4995 mwl8k_destroy_ba(hw, stream);
4996 spin_lock(&priv->stream_lock);
4997 wiphy_debug(hw->wiphy,
4998 "Failed adding stream for sta %pM tid %d\n",
4999 addr, tid);
5000 mwl8k_remove_stream(hw, stream);
5001 }
5002 break;
5003
4393 default: 5004 default:
4394 return -ENOTSUPP; 5005 rc = -ENOTSUPP;
4395 } 5006 }
5007
5008 spin_unlock(&priv->stream_lock);
5009 return rc;
4396} 5010}
4397 5011
4398static const struct ieee80211_ops mwl8k_ops = { 5012static const struct ieee80211_ops mwl8k_ops = {
@@ -4441,7 +5055,7 @@ enum {
4441 MWL8366, 5055 MWL8366,
4442}; 5056};
4443 5057
4444#define MWL8K_8366_AP_FW_API 1 5058#define MWL8K_8366_AP_FW_API 2
4445#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" 5059#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
4446#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) 5060#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
4447 5061
@@ -4607,6 +5221,23 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
4607 return rc; 5221 return rc;
4608} 5222}
4609 5223
5224static int mwl8k_init_txqs(struct ieee80211_hw *hw)
5225{
5226 struct mwl8k_priv *priv = hw->priv;
5227 int rc = 0;
5228 int i;
5229
5230 for (i = 0; i < mwl8k_tx_queues(priv); i++) {
5231 rc = mwl8k_txq_init(hw, i);
5232 if (rc)
5233 break;
5234 if (priv->ap_fw)
5235 iowrite32(priv->txq[i].txd_dma,
5236 priv->sram + priv->txq_offset[i]);
5237 }
5238 return rc;
5239}
5240
4610/* initialize hw after successfully loading a firmware image */ 5241/* initialize hw after successfully loading a firmware image */
4611static int mwl8k_probe_hw(struct ieee80211_hw *hw) 5242static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4612{ 5243{
@@ -4634,15 +5265,23 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4634 goto err_stop_firmware; 5265 goto err_stop_firmware;
4635 rxq_refill(hw, 0, INT_MAX); 5266 rxq_refill(hw, 0, INT_MAX);
4636 5267
4637 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 5268 /* For the sta firmware, we need to know the dma addresses of tx queues
4638 rc = mwl8k_txq_init(hw, i); 5269 * before sending MWL8K_CMD_GET_HW_SPEC. So we must initialize them
5270 * prior to issuing this command. But for the AP case, we learn the
5271 * total number of queues from the result CMD_GET_HW_SPEC, so for this
5272 * case we must initialize the tx queues after.
5273 */
5274 priv->num_ampdu_queues = 0;
5275 if (!priv->ap_fw) {
5276 rc = mwl8k_init_txqs(hw);
4639 if (rc) 5277 if (rc)
4640 goto err_free_queues; 5278 goto err_free_queues;
4641 } 5279 }
4642 5280
4643 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 5281 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
4644 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 5282 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4645 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY, 5283 iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
5284 MWL8K_A2H_INT_BA_WATCHDOG,
4646 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 5285 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
4647 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 5286 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
4648 5287
@@ -4653,6 +5292,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4653 goto err_free_queues; 5292 goto err_free_queues;
4654 } 5293 }
4655 5294
5295 memset(priv->ampdu, 0, sizeof(priv->ampdu));
5296
4656 /* 5297 /*
4657 * Temporarily enable interrupts. Initial firmware host 5298 * Temporarily enable interrupts. Initial firmware host
4658 * commands use interrupts and avoid polling. Disable 5299 * commands use interrupts and avoid polling. Disable
@@ -4664,6 +5305,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4664 if (priv->ap_fw) { 5305 if (priv->ap_fw) {
4665 rc = mwl8k_cmd_get_hw_spec_ap(hw); 5306 rc = mwl8k_cmd_get_hw_spec_ap(hw);
4666 if (!rc) 5307 if (!rc)
5308 rc = mwl8k_init_txqs(hw);
5309 if (!rc)
4667 rc = mwl8k_cmd_set_hw_spec(hw); 5310 rc = mwl8k_cmd_set_hw_spec(hw);
4668 } else { 5311 } else {
4669 rc = mwl8k_cmd_get_hw_spec_sta(hw); 5312 rc = mwl8k_cmd_get_hw_spec_sta(hw);
@@ -4705,7 +5348,7 @@ err_free_irq:
4705 free_irq(priv->pdev->irq, hw); 5348 free_irq(priv->pdev->irq, hw);
4706 5349
4707err_free_queues: 5350err_free_queues:
4708 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5351 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4709 mwl8k_txq_deinit(hw, i); 5352 mwl8k_txq_deinit(hw, i);
4710 mwl8k_rxq_deinit(hw, 0); 5353 mwl8k_rxq_deinit(hw, 0);
4711 5354
@@ -4727,7 +5370,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
4727 mwl8k_stop(hw); 5370 mwl8k_stop(hw);
4728 mwl8k_rxq_deinit(hw, 0); 5371 mwl8k_rxq_deinit(hw, 0);
4729 5372
4730 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5373 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4731 mwl8k_txq_deinit(hw, i); 5374 mwl8k_txq_deinit(hw, i);
4732 5375
4733 rc = mwl8k_init_firmware(hw, fw_image, false); 5376 rc = mwl8k_init_firmware(hw, fw_image, false);
@@ -4746,7 +5389,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
4746 if (rc) 5389 if (rc)
4747 goto fail; 5390 goto fail;
4748 5391
4749 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 5392 for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) {
4750 rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]); 5393 rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
4751 if (rc) 5394 if (rc)
4752 goto fail; 5395 goto fail;
@@ -4780,7 +5423,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4780 5423
4781 hw->channel_change_time = 10; 5424 hw->channel_change_time = 10;
4782 5425
4783 hw->queues = MWL8K_TX_QUEUES; 5426 hw->queues = MWL8K_TX_WMM_QUEUES;
4784 5427
4785 /* Set rssi values to dBm */ 5428 /* Set rssi values to dBm */
4786 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; 5429 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
@@ -4796,6 +5439,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4796 5439
4797 /* Finalize join worker */ 5440 /* Finalize join worker */
4798 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 5441 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
5442 /* Handle watchdog ba events */
5443 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);
4799 5444
4800 /* TX reclaim and RX tasklets. */ 5445 /* TX reclaim and RX tasklets. */
4801 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); 5446 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
@@ -4815,6 +5460,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4815 5460
4816 spin_lock_init(&priv->tx_lock); 5461 spin_lock_init(&priv->tx_lock);
4817 5462
5463 spin_lock_init(&priv->stream_lock);
5464
4818 priv->tx_wait = NULL; 5465 priv->tx_wait = NULL;
4819 5466
4820 rc = mwl8k_probe_hw(hw); 5467 rc = mwl8k_probe_hw(hw);
@@ -4836,7 +5483,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4836 return 0; 5483 return 0;
4837 5484
4838err_unprobe_hw: 5485err_unprobe_hw:
4839 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5486 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4840 mwl8k_txq_deinit(hw, i); 5487 mwl8k_txq_deinit(hw, i);
4841 mwl8k_rxq_deinit(hw, 0); 5488 mwl8k_rxq_deinit(hw, 0);
4842 5489
@@ -4995,10 +5642,10 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
4995 mwl8k_hw_reset(priv); 5642 mwl8k_hw_reset(priv);
4996 5643
4997 /* Return all skbs to mac80211 */ 5644 /* Return all skbs to mac80211 */
4998 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5645 for (i = 0; i < mwl8k_tx_queues(priv); i++)
4999 mwl8k_txq_reclaim(hw, i, INT_MAX, 1); 5646 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
5000 5647
5001 for (i = 0; i < MWL8K_TX_QUEUES; i++) 5648 for (i = 0; i < mwl8k_tx_queues(priv); i++)
5002 mwl8k_txq_deinit(hw, i); 5649 mwl8k_txq_deinit(hw, i);
5003 5650
5004 mwl8k_rxq_deinit(hw, 0); 5651 mwl8k_rxq_deinit(hw, 0);
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 329f3283697b..137a24e520da 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1368,8 +1368,10 @@ static void rt2400pci_tbtt_tasklet(unsigned long data)
1368static void rt2400pci_rxdone_tasklet(unsigned long data) 1368static void rt2400pci_rxdone_tasklet(unsigned long data)
1369{ 1369{
1370 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 1370 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1371 rt2x00pci_rxdone(rt2x00dev); 1371 if (rt2x00pci_rxdone(rt2x00dev))
1372 rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); 1372 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
1373 else
1374 rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
1373} 1375}
1374 1376
1375static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) 1377static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 58277878889e..198fc0a0d77c 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1500,8 +1500,10 @@ static void rt2500pci_tbtt_tasklet(unsigned long data)
1500static void rt2500pci_rxdone_tasklet(unsigned long data) 1500static void rt2500pci_rxdone_tasklet(unsigned long data)
1501{ 1501{
1502 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 1502 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1503 rt2x00pci_rxdone(rt2x00dev); 1503 if (rt2x00pci_rxdone(rt2x00dev))
1504 rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); 1504 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
1505 else
1506 rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
1505} 1507}
1506 1508
1507static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) 1509static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 979fe6596a2d..eac788160f55 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1796,7 +1796,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
1796 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 1796 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
1797 __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); 1797 __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
1798 } 1798 }
1799 __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
1800 __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); 1799 __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
1801 1800
1802 /* 1801 /*
@@ -1910,13 +1909,10 @@ static struct usb_device_id rt2500usb_device_table[] = {
1910 /* Belkin */ 1909 /* Belkin */
1911 { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) }, 1910 { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) },
1912 { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) }, 1911 { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) },
1913 { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt2500usb_ops) },
1914 /* Cisco Systems */ 1912 /* Cisco Systems */
1915 { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) }, 1913 { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) },
1916 { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) }, 1914 { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) },
1917 { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) }, 1915 { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) },
1918 /* CNet */
1919 { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt2500usb_ops) },
1920 /* Conceptronic */ 1916 /* Conceptronic */
1921 { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) }, 1917 { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) },
1922 /* D-LINK */ 1918 /* D-LINK */
@@ -1939,7 +1935,6 @@ static struct usb_device_id rt2500usb_device_table[] = {
1939 /* Ralink */ 1935 /* Ralink */
1940 { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, 1936 { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
1941 { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) }, 1937 { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) },
1942 { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) },
1943 { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, 1938 { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
1944 /* Sagem */ 1939 /* Sagem */
1945 { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) }, 1940 { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 8fbc5fa965e0..ce2010952886 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2104,6 +2104,59 @@ struct mac_iveiv_entry {
2104#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00) 2104#define EEPROM_TXPOWER_BG_2 FIELD16(0xff00)
2105 2105
2106/* 2106/*
2107 * EEPROM temperature compensation boundaries 802.11BG
2108 * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
2109 * reduced by (agc_step * -4)
2110 * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
2111 * reduced by (agc_step * -3)
2112 */
2113#define EEPROM_TSSI_BOUND_BG1 0x0037
2114#define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff)
2115#define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00)
2116
2117/*
2118 * EEPROM temperature compensation boundaries 802.11BG
2119 * MINUS2: If the actual TSSI is below this boundary, tx power needs to be
2120 * reduced by (agc_step * -2)
2121 * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
2122 * reduced by (agc_step * -1)
2123 */
2124#define EEPROM_TSSI_BOUND_BG2 0x0038
2125#define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff)
2126#define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00)
2127
2128/*
2129 * EEPROM temperature compensation boundaries 802.11BG
2130 * REF: Reference TSSI value, no tx power changes needed
2131 * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
2132 * increased by (agc_step * 1)
2133 */
2134#define EEPROM_TSSI_BOUND_BG3 0x0039
2135#define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff)
2136#define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00)
2137
2138/*
2139 * EEPROM temperature compensation boundaries 802.11BG
2140 * PLUS2: If the actual TSSI is above this boundary, tx power needs to be
2141 * increased by (agc_step * 2)
2142 * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
2143 * increased by (agc_step * 3)
2144 */
2145#define EEPROM_TSSI_BOUND_BG4 0x003a
2146#define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff)
2147#define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00)
2148
2149/*
2150 * EEPROM temperature compensation boundaries 802.11BG
2151 * PLUS4: If the actual TSSI is above this boundary, tx power needs to be
2152 * increased by (agc_step * 4)
2153 * AGC_STEP: Temperature compensation step.
2154 */
2155#define EEPROM_TSSI_BOUND_BG5 0x003b
2156#define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff)
2157#define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00)
2158
2159/*
2107 * EEPROM TXPOWER 802.11A 2160 * EEPROM TXPOWER 802.11A
2108 */ 2161 */
2109#define EEPROM_TXPOWER_A1 0x003c 2162#define EEPROM_TXPOWER_A1 0x003c
@@ -2113,6 +2166,59 @@ struct mac_iveiv_entry {
2113#define EEPROM_TXPOWER_A_2 FIELD16(0xff00) 2166#define EEPROM_TXPOWER_A_2 FIELD16(0xff00)
2114 2167
2115/* 2168/*
2169 * EEPROM temperature compensation boundaries 802.11A
2170 * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
2171 * reduced by (agc_step * -4)
2172 * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
2173 * reduced by (agc_step * -3)
2174 */
2175#define EEPROM_TSSI_BOUND_A1 0x006a
2176#define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff)
2177#define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00)
2178
2179/*
2180 * EEPROM temperature compensation boundaries 802.11A
2181 * MINUS2: If the actual TSSI is below this boundary, tx power needs to be
2182 * reduced by (agc_step * -2)
2183 * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
2184 * reduced by (agc_step * -1)
2185 */
2186#define EEPROM_TSSI_BOUND_A2 0x006b
2187#define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff)
2188#define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00)
2189
2190/*
2191 * EEPROM temperature compensation boundaries 802.11A
2192 * REF: Reference TSSI value, no tx power changes needed
2193 * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
2194 * increased by (agc_step * 1)
2195 */
2196#define EEPROM_TSSI_BOUND_A3 0x006c
2197#define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff)
2198#define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00)
2199
2200/*
2201 * EEPROM temperature compensation boundaries 802.11A
2202 * PLUS2: If the actual TSSI is above this boundary, tx power needs to be
2203 * increased by (agc_step * 2)
2204 * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
2205 * increased by (agc_step * 3)
2206 */
2207#define EEPROM_TSSI_BOUND_A4 0x006d
2208#define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff)
2209#define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00)
2210
2211/*
2212 * EEPROM temperature compensation boundaries 802.11A
2213 * PLUS4: If the actual TSSI is above this boundary, tx power needs to be
2214 * increased by (agc_step * 4)
2215 * AGC_STEP: Temperature compensation step.
2216 */
2217#define EEPROM_TSSI_BOUND_A5 0x006e
2218#define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff)
2219#define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00)
2220
2221/*
2116 * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode 2222 * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
2117 */ 2223 */
2118#define EEPROM_TXPOWER_BYRATE 0x006f 2224#define EEPROM_TXPOWER_BYRATE 0x006f
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index dbf74d07d947..6331c61957a3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -687,6 +687,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
687 mcs = real_mcs; 687 mcs = real_mcs;
688 } 688 }
689 689
690 if (aggr == 1 || ampdu == 1)
691 __set_bit(TXDONE_AMPDU, &txdesc.flags);
692
690 /* 693 /*
691 * Ralink has a retry mechanism using a global fallback 694 * Ralink has a retry mechanism using a global fallback
692 * table. We setup this fallback table to try the immediate 695 * table. We setup this fallback table to try the immediate
@@ -1813,17 +1816,131 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
1813 rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg); 1816 rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
1814} 1817}
1815 1818
1819static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
1820{
1821 u8 tssi_bounds[9];
1822 u8 current_tssi;
1823 u16 eeprom;
1824 u8 step;
1825 int i;
1826
1827 /*
1828 * Read TSSI boundaries for temperature compensation from
1829 * the EEPROM.
1830 *
1831 * Array idx 0 1 2 3 4 5 6 7 8
1832 * Matching Delta value -4 -3 -2 -1 0 +1 +2 +3 +4
1833 * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
1834 */
1835 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
1836 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
1837 tssi_bounds[0] = rt2x00_get_field16(eeprom,
1838 EEPROM_TSSI_BOUND_BG1_MINUS4);
1839 tssi_bounds[1] = rt2x00_get_field16(eeprom,
1840 EEPROM_TSSI_BOUND_BG1_MINUS3);
1841
1842 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
1843 tssi_bounds[2] = rt2x00_get_field16(eeprom,
1844 EEPROM_TSSI_BOUND_BG2_MINUS2);
1845 tssi_bounds[3] = rt2x00_get_field16(eeprom,
1846 EEPROM_TSSI_BOUND_BG2_MINUS1);
1847
1848 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
1849 tssi_bounds[4] = rt2x00_get_field16(eeprom,
1850 EEPROM_TSSI_BOUND_BG3_REF);
1851 tssi_bounds[5] = rt2x00_get_field16(eeprom,
1852 EEPROM_TSSI_BOUND_BG3_PLUS1);
1853
1854 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
1855 tssi_bounds[6] = rt2x00_get_field16(eeprom,
1856 EEPROM_TSSI_BOUND_BG4_PLUS2);
1857 tssi_bounds[7] = rt2x00_get_field16(eeprom,
1858 EEPROM_TSSI_BOUND_BG4_PLUS3);
1859
1860 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
1861 tssi_bounds[8] = rt2x00_get_field16(eeprom,
1862 EEPROM_TSSI_BOUND_BG5_PLUS4);
1863
1864 step = rt2x00_get_field16(eeprom,
1865 EEPROM_TSSI_BOUND_BG5_AGC_STEP);
1866 } else {
1867 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
1868 tssi_bounds[0] = rt2x00_get_field16(eeprom,
1869 EEPROM_TSSI_BOUND_A1_MINUS4);
1870 tssi_bounds[1] = rt2x00_get_field16(eeprom,
1871 EEPROM_TSSI_BOUND_A1_MINUS3);
1872
1873 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
1874 tssi_bounds[2] = rt2x00_get_field16(eeprom,
1875 EEPROM_TSSI_BOUND_A2_MINUS2);
1876 tssi_bounds[3] = rt2x00_get_field16(eeprom,
1877 EEPROM_TSSI_BOUND_A2_MINUS1);
1878
1879 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
1880 tssi_bounds[4] = rt2x00_get_field16(eeprom,
1881 EEPROM_TSSI_BOUND_A3_REF);
1882 tssi_bounds[5] = rt2x00_get_field16(eeprom,
1883 EEPROM_TSSI_BOUND_A3_PLUS1);
1884
1885 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
1886 tssi_bounds[6] = rt2x00_get_field16(eeprom,
1887 EEPROM_TSSI_BOUND_A4_PLUS2);
1888 tssi_bounds[7] = rt2x00_get_field16(eeprom,
1889 EEPROM_TSSI_BOUND_A4_PLUS3);
1890
1891 rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
1892 tssi_bounds[8] = rt2x00_get_field16(eeprom,
1893 EEPROM_TSSI_BOUND_A5_PLUS4);
1894
1895 step = rt2x00_get_field16(eeprom,
1896 EEPROM_TSSI_BOUND_A5_AGC_STEP);
1897 }
1898
1899 /*
1900 * Check if temperature compensation is supported.
1901 */
1902 if (tssi_bounds[4] == 0xff)
1903 return 0;
1904
1905 /*
1906 * Read current TSSI (BBP 49).
1907 */
1908 rt2800_bbp_read(rt2x00dev, 49, &current_tssi);
1909
1910 /*
1911 * Compare TSSI value (BBP49) with the compensation boundaries
1912 * from the EEPROM and increase or decrease tx power.
1913 */
1914 for (i = 0; i <= 3; i++) {
1915 if (current_tssi > tssi_bounds[i])
1916 break;
1917 }
1918
1919 if (i == 4) {
1920 for (i = 8; i >= 5; i--) {
1921 if (current_tssi < tssi_bounds[i])
1922 break;
1923 }
1924 }
1925
1926 return (i - 4) * step;
1927}
1928
1816static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, 1929static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
1817 enum ieee80211_band band) 1930 enum ieee80211_band band)
1818{ 1931{
1819 u16 eeprom; 1932 u16 eeprom;
1820 u8 comp_en; 1933 u8 comp_en;
1821 u8 comp_type; 1934 u8 comp_type;
1822 int comp_value; 1935 int comp_value = 0;
1823 1936
1824 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); 1937 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
1825 1938
1826 if (eeprom == 0xffff) 1939 /*
1940 * HT40 compensation not required.
1941 */
1942 if (eeprom == 0xffff ||
1943 !test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
1827 return 0; 1944 return 0;
1828 1945
1829 if (band == IEEE80211_BAND_2GHZ) { 1946 if (band == IEEE80211_BAND_2GHZ) {
@@ -1853,11 +1970,9 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
1853 return comp_value; 1970 return comp_value;
1854} 1971}
1855 1972
1856static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, 1973static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
1857 int is_rate_b, 1974 enum ieee80211_band band, int power_level,
1858 enum ieee80211_band band, 1975 u8 txpower, int delta)
1859 int power_level,
1860 u8 txpower)
1861{ 1976{
1862 u32 reg; 1977 u32 reg;
1863 u16 eeprom; 1978 u16 eeprom;
@@ -1865,14 +1980,10 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
1865 u8 eirp_txpower; 1980 u8 eirp_txpower;
1866 u8 eirp_txpower_criterion; 1981 u8 eirp_txpower_criterion;
1867 u8 reg_limit; 1982 u8 reg_limit;
1868 int bw_comp = 0;
1869 1983
1870 if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) 1984 if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
1871 return txpower; 1985 return txpower;
1872 1986
1873 if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
1874 bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band);
1875
1876 if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { 1987 if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) {
1877 /* 1988 /*
1878 * Check if eirp txpower exceed txpower_limit. 1989 * Check if eirp txpower exceed txpower_limit.
@@ -1895,18 +2006,19 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
1895 EEPROM_EIRP_MAX_TX_POWER_5GHZ); 2006 EEPROM_EIRP_MAX_TX_POWER_5GHZ);
1896 2007
1897 eirp_txpower = eirp_txpower_criterion + (txpower - criterion) + 2008 eirp_txpower = eirp_txpower_criterion + (txpower - criterion) +
1898 (is_rate_b ? 4 : 0) + bw_comp; 2009 (is_rate_b ? 4 : 0) + delta;
1899 2010
1900 reg_limit = (eirp_txpower > power_level) ? 2011 reg_limit = (eirp_txpower > power_level) ?
1901 (eirp_txpower - power_level) : 0; 2012 (eirp_txpower - power_level) : 0;
1902 } else 2013 } else
1903 reg_limit = 0; 2014 reg_limit = 0;
1904 2015
1905 return txpower + bw_comp - reg_limit; 2016 return txpower + delta - reg_limit;
1906} 2017}
1907 2018
1908static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, 2019static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1909 struct ieee80211_conf *conf) 2020 enum ieee80211_band band,
2021 int power_level)
1910{ 2022{
1911 u8 txpower; 2023 u8 txpower;
1912 u16 eeprom; 2024 u16 eeprom;
@@ -1914,8 +2026,17 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1914 u32 reg; 2026 u32 reg;
1915 u8 r1; 2027 u8 r1;
1916 u32 offset; 2028 u32 offset;
1917 enum ieee80211_band band = conf->channel->band; 2029 int delta;
1918 int power_level = conf->power_level; 2030
2031 /*
2032 * Calculate HT40 compensation delta
2033 */
2034 delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
2035
2036 /*
2037 * calculate temperature compensation delta
2038 */
2039 delta += rt2800_get_gain_calibration_delta(rt2x00dev);
1919 2040
1920 /* 2041 /*
1921 * set to normal bbp tx power control mode: +/- 0dBm 2042 * set to normal bbp tx power control mode: +/- 0dBm
@@ -1944,8 +2065,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1944 */ 2065 */
1945 txpower = rt2x00_get_field16(eeprom, 2066 txpower = rt2x00_get_field16(eeprom,
1946 EEPROM_TXPOWER_BYRATE_RATE0); 2067 EEPROM_TXPOWER_BYRATE_RATE0);
1947 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2068 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
1948 power_level, txpower); 2069 power_level, txpower, delta);
1949 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0, txpower); 2070 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0, txpower);
1950 2071
1951 /* 2072 /*
@@ -1955,8 +2076,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1955 */ 2076 */
1956 txpower = rt2x00_get_field16(eeprom, 2077 txpower = rt2x00_get_field16(eeprom,
1957 EEPROM_TXPOWER_BYRATE_RATE1); 2078 EEPROM_TXPOWER_BYRATE_RATE1);
1958 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2079 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
1959 power_level, txpower); 2080 power_level, txpower, delta);
1960 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1, txpower); 2081 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1, txpower);
1961 2082
1962 /* 2083 /*
@@ -1966,8 +2087,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1966 */ 2087 */
1967 txpower = rt2x00_get_field16(eeprom, 2088 txpower = rt2x00_get_field16(eeprom,
1968 EEPROM_TXPOWER_BYRATE_RATE2); 2089 EEPROM_TXPOWER_BYRATE_RATE2);
1969 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2090 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
1970 power_level, txpower); 2091 power_level, txpower, delta);
1971 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2, txpower); 2092 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2, txpower);
1972 2093
1973 /* 2094 /*
@@ -1977,8 +2098,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1977 */ 2098 */
1978 txpower = rt2x00_get_field16(eeprom, 2099 txpower = rt2x00_get_field16(eeprom,
1979 EEPROM_TXPOWER_BYRATE_RATE3); 2100 EEPROM_TXPOWER_BYRATE_RATE3);
1980 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2101 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
1981 power_level, txpower); 2102 power_level, txpower, delta);
1982 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower); 2103 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower);
1983 2104
1984 /* read the next four txpower values */ 2105 /* read the next four txpower values */
@@ -1993,8 +2114,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1993 */ 2114 */
1994 txpower = rt2x00_get_field16(eeprom, 2115 txpower = rt2x00_get_field16(eeprom,
1995 EEPROM_TXPOWER_BYRATE_RATE0); 2116 EEPROM_TXPOWER_BYRATE_RATE0);
1996 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2117 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
1997 power_level, txpower); 2118 power_level, txpower, delta);
1998 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4, txpower); 2119 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4, txpower);
1999 2120
2000 /* 2121 /*
@@ -2004,8 +2125,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
2004 */ 2125 */
2005 txpower = rt2x00_get_field16(eeprom, 2126 txpower = rt2x00_get_field16(eeprom,
2006 EEPROM_TXPOWER_BYRATE_RATE1); 2127 EEPROM_TXPOWER_BYRATE_RATE1);
2007 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2128 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
2008 power_level, txpower); 2129 power_level, txpower, delta);
2009 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5, txpower); 2130 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5, txpower);
2010 2131
2011 /* 2132 /*
@@ -2015,8 +2136,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
2015 */ 2136 */
2016 txpower = rt2x00_get_field16(eeprom, 2137 txpower = rt2x00_get_field16(eeprom,
2017 EEPROM_TXPOWER_BYRATE_RATE2); 2138 EEPROM_TXPOWER_BYRATE_RATE2);
2018 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2139 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
2019 power_level, txpower); 2140 power_level, txpower, delta);
2020 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6, txpower); 2141 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6, txpower);
2021 2142
2022 /* 2143 /*
@@ -2026,8 +2147,8 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
2026 */ 2147 */
2027 txpower = rt2x00_get_field16(eeprom, 2148 txpower = rt2x00_get_field16(eeprom,
2028 EEPROM_TXPOWER_BYRATE_RATE3); 2149 EEPROM_TXPOWER_BYRATE_RATE3);
2029 txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, 2150 txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
2030 power_level, txpower); 2151 power_level, txpower, delta);
2031 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7, txpower); 2152 rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7, txpower);
2032 2153
2033 rt2800_register_write(rt2x00dev, offset, reg); 2154 rt2800_register_write(rt2x00dev, offset, reg);
@@ -2037,6 +2158,13 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
2037 } 2158 }
2038} 2159}
2039 2160
2161void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
2162{
2163 rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band,
2164 rt2x00dev->tx_power);
2165}
2166EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
2167
2040static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, 2168static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
2041 struct rt2x00lib_conf *libconf) 2169 struct rt2x00lib_conf *libconf)
2042{ 2170{
@@ -2090,10 +2218,12 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
2090 if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { 2218 if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
2091 rt2800_config_channel(rt2x00dev, libconf->conf, 2219 rt2800_config_channel(rt2x00dev, libconf->conf,
2092 &libconf->rf, &libconf->channel); 2220 &libconf->rf, &libconf->channel);
2093 rt2800_config_txpower(rt2x00dev, libconf->conf); 2221 rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
2222 libconf->conf->power_level);
2094 } 2223 }
2095 if (flags & IEEE80211_CONF_CHANGE_POWER) 2224 if (flags & IEEE80211_CONF_CHANGE_POWER)
2096 rt2800_config_txpower(rt2x00dev, libconf->conf); 2225 rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
2226 libconf->conf->power_level);
2097 if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) 2227 if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
2098 rt2800_config_retry_limit(rt2x00dev, libconf); 2228 rt2800_config_retry_limit(rt2x00dev, libconf);
2099 if (flags & IEEE80211_CONF_CHANGE_PS) 2229 if (flags & IEEE80211_CONF_CHANGE_PS)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 0c92d86a36f4..f2d15941c71a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -181,6 +181,7 @@ void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
181void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); 181void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
182void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, 182void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
183 const u32 count); 183 const u32 count);
184void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
184 185
185int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); 186int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
186void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); 187void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 808073aa9dcc..adc3534254df 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -717,12 +717,13 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
717 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); 717 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
718} 718}
719 719
720static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) 720static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
721{ 721{
722 struct data_queue *queue; 722 struct data_queue *queue;
723 struct queue_entry *entry; 723 struct queue_entry *entry;
724 u32 status; 724 u32 status;
725 u8 qid; 725 u8 qid;
726 int max_tx_done = 16;
726 727
727 while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { 728 while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
728 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); 729 qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
@@ -759,7 +760,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
759 760
760 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 761 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
761 rt2800_txdone_entry(entry, status); 762 rt2800_txdone_entry(entry, status);
763
764 if (--max_tx_done == 0)
765 break;
762 } 766 }
767
768 return !max_tx_done;
763} 769}
764 770
765static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, 771static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
@@ -780,7 +786,9 @@ static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
780 786
781static void rt2800pci_txstatus_tasklet(unsigned long data) 787static void rt2800pci_txstatus_tasklet(unsigned long data)
782{ 788{
783 rt2800pci_txdone((struct rt2x00_dev *)data); 789 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
790 if (rt2800pci_txdone(rt2x00dev))
791 tasklet_schedule(&rt2x00dev->txstatus_tasklet);
784 792
785 /* 793 /*
786 * No need to enable the tx status interrupt here as we always 794 * No need to enable the tx status interrupt here as we always
@@ -806,8 +814,10 @@ static void rt2800pci_tbtt_tasklet(unsigned long data)
806static void rt2800pci_rxdone_tasklet(unsigned long data) 814static void rt2800pci_rxdone_tasklet(unsigned long data)
807{ 815{
808 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 816 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
809 rt2x00pci_rxdone(rt2x00dev); 817 if (rt2x00pci_rxdone(rt2x00dev))
810 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); 818 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
819 else
820 rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
811} 821}
812 822
813static void rt2800pci_autowake_tasklet(unsigned long data) 823static void rt2800pci_autowake_tasklet(unsigned long data)
@@ -1043,6 +1053,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
1043 .link_stats = rt2800_link_stats, 1053 .link_stats = rt2800_link_stats,
1044 .reset_tuner = rt2800_reset_tuner, 1054 .reset_tuner = rt2800_reset_tuner,
1045 .link_tuner = rt2800_link_tuner, 1055 .link_tuner = rt2800_link_tuner,
1056 .gain_calibration = rt2800_gain_calibration,
1046 .start_queue = rt2800pci_start_queue, 1057 .start_queue = rt2800pci_start_queue,
1047 .kick_queue = rt2800pci_kick_queue, 1058 .kick_queue = rt2800pci_kick_queue,
1048 .stop_queue = rt2800pci_stop_queue, 1059 .stop_queue = rt2800pci_stop_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 37509d019910..6ba31a0e8f78 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -564,7 +564,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
564 if (!modparam_nohwcrypt) 564 if (!modparam_nohwcrypt)
565 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 565 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
566 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); 566 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
567 __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
568 __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); 567 __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
569 568
570 /* 569 /*
@@ -630,6 +629,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
630 .link_stats = rt2800_link_stats, 629 .link_stats = rt2800_link_stats,
631 .reset_tuner = rt2800_reset_tuner, 630 .reset_tuner = rt2800_reset_tuner,
632 .link_tuner = rt2800_link_tuner, 631 .link_tuner = rt2800_link_tuner,
632 .gain_calibration = rt2800_gain_calibration,
633 .watchdog = rt2800usb_watchdog, 633 .watchdog = rt2800usb_watchdog,
634 .start_queue = rt2800usb_start_queue, 634 .start_queue = rt2800usb_start_queue,
635 .kick_queue = rt2x00usb_kick_queue, 635 .kick_queue = rt2x00usb_kick_queue,
@@ -882,6 +882,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
882 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, 882 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
883 /* Zyxel */ 883 /* Zyxel */
884 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, 884 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
885 { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) },
885#ifdef CONFIG_RT2800USB_RT33XX 886#ifdef CONFIG_RT2800USB_RT33XX
886 /* Ralink */ 887 /* Ralink */
887 { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, 888 { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7f10239f56a8..a2bd5feb9d5c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -348,6 +348,11 @@ struct link {
348 * to bring the device/driver back into the desired state. 348 * to bring the device/driver back into the desired state.
349 */ 349 */
350 struct delayed_work watchdog_work; 350 struct delayed_work watchdog_work;
351
352 /*
353 * Work structure for scheduling periodic AGC adjustments.
354 */
355 struct delayed_work agc_work;
351}; 356};
352 357
353enum rt2x00_delayed_flags { 358enum rt2x00_delayed_flags {
@@ -556,6 +561,7 @@ struct rt2x00lib_ops {
556 struct link_qual *qual); 561 struct link_qual *qual);
557 void (*link_tuner) (struct rt2x00_dev *rt2x00dev, 562 void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
558 struct link_qual *qual, const u32 count); 563 struct link_qual *qual, const u32 count);
564 void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
559 565
560 /* 566 /*
561 * Data queue handlers. 567 * Data queue handlers.
@@ -674,7 +680,6 @@ enum rt2x00_flags {
674 DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, 680 DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
675 DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, 681 DRIVER_SUPPORT_PRE_TBTT_INTERRUPT,
676 DRIVER_SUPPORT_LINK_TUNING, 682 DRIVER_SUPPORT_LINK_TUNING,
677 DRIVER_SUPPORT_WATCHDOG,
678 683
679 /* 684 /*
680 * Driver configuration 685 * Driver configuration
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index c92db3264741..66166ef037f5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -568,7 +568,6 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
568 blob->data = data; 568 blob->data = data;
569 data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name); 569 data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
570 data += sprintf(data, "version:\t%s\n", DRV_VERSION); 570 data += sprintf(data, "version:\t%s\n", DRV_VERSION);
571 data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
572 blob->size = strlen(blob->data); 571 blob->size = strlen(blob->data);
573 572
574 return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); 573 return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 84eb6ad36377..9bffe8438d1f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -27,6 +27,7 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/log2.h>
30 31
31#include "rt2x00.h" 32#include "rt2x00.h"
32#include "rt2x00lib.h" 33#include "rt2x00lib.h"
@@ -70,6 +71,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
70 */ 71 */
71 rt2x00queue_start_queues(rt2x00dev); 72 rt2x00queue_start_queues(rt2x00dev);
72 rt2x00link_start_tuner(rt2x00dev); 73 rt2x00link_start_tuner(rt2x00dev);
74 rt2x00link_start_agc(rt2x00dev);
73 75
74 /* 76 /*
75 * Start watchdog monitoring. 77 * Start watchdog monitoring.
@@ -92,6 +94,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
92 /* 94 /*
93 * Stop all queues 95 * Stop all queues
94 */ 96 */
97 rt2x00link_stop_agc(rt2x00dev);
95 rt2x00link_stop_tuner(rt2x00dev); 98 rt2x00link_stop_tuner(rt2x00dev);
96 rt2x00queue_stop_queues(rt2x00dev); 99 rt2x00queue_stop_queues(rt2x00dev);
97 rt2x00queue_flush_queues(rt2x00dev, true); 100 rt2x00queue_flush_queues(rt2x00dev, true);
@@ -350,10 +353,14 @@ void rt2x00lib_txdone(struct queue_entry *entry,
350 * which would allow the rc algorithm to better decide on 353 * which would allow the rc algorithm to better decide on
351 * which rates are suitable. 354 * which rates are suitable.
352 */ 355 */
353 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 356 if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
357 tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
354 tx_info->flags |= IEEE80211_TX_STAT_AMPDU; 358 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
355 tx_info->status.ampdu_len = 1; 359 tx_info->status.ampdu_len = 1;
356 tx_info->status.ampdu_ack_len = success ? 1 : 0; 360 tx_info->status.ampdu_ack_len = success ? 1 : 0;
361
362 if (!success)
363 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
357 } 364 }
358 365
359 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { 366 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
@@ -511,8 +518,6 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
511 (rxdesc.size > header_length) && 518 (rxdesc.size > header_length) &&
512 (rxdesc.dev_flags & RXDONE_L2PAD)) 519 (rxdesc.dev_flags & RXDONE_L2PAD))
513 rt2x00queue_remove_l2pad(entry->skb, header_length); 520 rt2x00queue_remove_l2pad(entry->skb, header_length);
514 else
515 rt2x00queue_align_payload(entry->skb, header_length);
516 521
517 /* Trim buffer to correct size */ 522 /* Trim buffer to correct size */
518 skb_trim(entry->skb, rxdesc.size); 523 skb_trim(entry->skb, rxdesc.size);
@@ -811,13 +816,18 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
811 */ 816 */
812 if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) { 817 if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) {
813 /* 818 /*
814 * Allocate txstatus fifo and tasklet, we use a size of 512 819 * Allocate the txstatus fifo. In the worst case the tx
815 * for the kfifo which is big enough to store 512/4=128 tx 820 * status fifo has to hold the tx status of all entries
816 * status reports. In the worst case (tx status for all tx 821 * in all tx queues. Hence, calculate the kfifo size as
817 * queues gets reported before we've got a chance to handle 822 * tx_queues * entry_num and round up to the nearest
818 * them) 24*4=384 tx status reports need to be cached. 823 * power of 2.
819 */ 824 */
820 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512, 825 int kfifo_size =
826 roundup_pow_of_two(rt2x00dev->ops->tx_queues *
827 rt2x00dev->ops->tx->entry_num *
828 sizeof(u32));
829
830 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
821 GFP_KERNEL); 831 GFP_KERNEL);
822 if (status) 832 if (status)
823 return status; 833 return status;
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index ae1219dffaae..e8c0c3e92c2f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -43,8 +43,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
43 43
44 txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ 44 txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */
45 45
46 txdesc->u.ht.stbc = 46 /*
47 (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; 47 * Only one STBC stream is supported for now.
48 */
49 if (tx_info->flags & IEEE80211_TX_CTL_STBC)
50 txdesc->u.ht.stbc = 1;
48 51
49 /* 52 /*
50 * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the 53 * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 2d94cbaf5f4a..88f2f9275528 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -32,6 +32,7 @@
32 */ 32 */
33#define WATCHDOG_INTERVAL round_jiffies_relative(HZ) 33#define WATCHDOG_INTERVAL round_jiffies_relative(HZ)
34#define LINK_TUNE_INTERVAL round_jiffies_relative(HZ) 34#define LINK_TUNE_INTERVAL round_jiffies_relative(HZ)
35#define AGC_INTERVAL round_jiffies_relative(4 * HZ)
35 36
36/* 37/*
37 * rt2x00_rate: Per rate device information 38 * rt2x00_rate: Per rate device information
@@ -119,16 +120,6 @@ void rt2x00queue_free_skb(struct queue_entry *entry);
119void rt2x00queue_align_frame(struct sk_buff *skb); 120void rt2x00queue_align_frame(struct sk_buff *skb);
120 121
121/** 122/**
122 * rt2x00queue_align_payload - Align 802.11 payload to 4-byte boundary
123 * @skb: The skb to align
124 * @header_length: Length of 802.11 header
125 *
126 * Align the 802.11 payload to a 4-byte boundary, this could
127 * mean the header is not aligned properly though.
128 */
129void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length);
130
131/**
132 * rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary 123 * rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary
133 * @skb: The skb to align 124 * @skb: The skb to align
134 * @header_length: Length of 802.11 header 125 * @header_length: Length of 802.11 header
@@ -281,6 +272,18 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev);
281void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev); 272void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev);
282 273
283/** 274/**
275 * rt2x00link_start_agc - Start periodic gain calibration
276 * @rt2x00dev: Pointer to &struct rt2x00_dev.
277 */
278void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev);
279
280/**
281 * rt2x00link_stop_agc - Stop periodic gain calibration
282 * @rt2x00dev: Pointer to &struct rt2x00_dev.
283 */
284void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev);
285
286/**
284 * rt2x00link_register - Initialize link tuning & watchdog functionality 287 * rt2x00link_register - Initialize link tuning & watchdog functionality
285 * @rt2x00dev: Pointer to &struct rt2x00_dev. 288 * @rt2x00dev: Pointer to &struct rt2x00_dev.
286 * 289 *
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 29abfdeb0b65..1435976b8779 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -413,12 +413,11 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
413{ 413{
414 struct link *link = &rt2x00dev->link; 414 struct link *link = &rt2x00dev->link;
415 415
416 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || 416 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
417 !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) 417 rt2x00dev->ops->lib->watchdog)
418 return; 418 ieee80211_queue_delayed_work(rt2x00dev->hw,
419 419 &link->watchdog_work,
420 ieee80211_queue_delayed_work(rt2x00dev->hw, 420 WATCHDOG_INTERVAL);
421 &link->watchdog_work, WATCHDOG_INTERVAL);
422} 421}
423 422
424void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) 423void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -447,8 +446,46 @@ static void rt2x00link_watchdog(struct work_struct *work)
447 WATCHDOG_INTERVAL); 446 WATCHDOG_INTERVAL);
448} 447}
449 448
449void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev)
450{
451 struct link *link = &rt2x00dev->link;
452
453 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
454 rt2x00dev->ops->lib->gain_calibration)
455 ieee80211_queue_delayed_work(rt2x00dev->hw,
456 &link->agc_work,
457 AGC_INTERVAL);
458}
459
460void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev)
461{
462 cancel_delayed_work_sync(&rt2x00dev->link.agc_work);
463}
464
465static void rt2x00link_agc(struct work_struct *work)
466{
467 struct rt2x00_dev *rt2x00dev =
468 container_of(work, struct rt2x00_dev, link.agc_work.work);
469 struct link *link = &rt2x00dev->link;
470
471 /*
472 * When the radio is shutting down we should
473 * immediately cease the watchdog monitoring.
474 */
475 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
476 return;
477
478 rt2x00dev->ops->lib->gain_calibration(rt2x00dev);
479
480 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
481 ieee80211_queue_delayed_work(rt2x00dev->hw,
482 &link->agc_work,
483 AGC_INTERVAL);
484}
485
450void rt2x00link_register(struct rt2x00_dev *rt2x00dev) 486void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
451{ 487{
488 INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc);
452 INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); 489 INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
453 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); 490 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
454} 491}
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 4dd82b0b0520..9649bd0cd718 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -60,14 +60,15 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
60} 60}
61EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); 61EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
62 62
63void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) 63bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
64{ 64{
65 struct data_queue *queue = rt2x00dev->rx; 65 struct data_queue *queue = rt2x00dev->rx;
66 struct queue_entry *entry; 66 struct queue_entry *entry;
67 struct queue_entry_priv_pci *entry_priv; 67 struct queue_entry_priv_pci *entry_priv;
68 struct skb_frame_desc *skbdesc; 68 struct skb_frame_desc *skbdesc;
69 int max_rx = 16;
69 70
70 while (1) { 71 while (--max_rx) {
71 entry = rt2x00queue_get_entry(queue, Q_INDEX); 72 entry = rt2x00queue_get_entry(queue, Q_INDEX);
72 entry_priv = entry->priv_data; 73 entry_priv = entry->priv_data;
73 74
@@ -93,6 +94,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
93 */ 94 */
94 rt2x00lib_rxdone(entry); 95 rt2x00lib_rxdone(entry);
95 } 96 }
97
98 return !max_rx;
96} 99}
97EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); 100EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
98 101
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 746ce8fe8cf4..07961b8b369a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -101,8 +101,11 @@ struct queue_entry_priv_pci {
101/** 101/**
102 * rt2x00pci_rxdone - Handle RX done events 102 * rt2x00pci_rxdone - Handle RX done events
103 * @rt2x00dev: Device pointer, see &struct rt2x00_dev. 103 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
104 *
105 * Returns true if there are still rx frames pending and false if all
106 * pending rx frames were processed.
104 */ 107 */
105void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); 108bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
106 109
107/* 110/*
108 * Device initialization handlers. 111 * Device initialization handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 4358051bfe1a..94b8bbb7ad80 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,19 +148,6 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
148 skb_trim(skb, frame_length); 148 skb_trim(skb, frame_length);
149} 149}
150 150
151void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
152{
153 unsigned int frame_length = skb->len;
154 unsigned int align = ALIGN_SIZE(skb, header_length);
155
156 if (!align)
157 return;
158
159 skb_push(skb, align);
160 memmove(skb->data, skb->data + align, frame_length);
161 skb_trim(skb, frame_length);
162}
163
164void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) 151void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
165{ 152{
166 unsigned int payload_length = skb->len - header_length; 153 unsigned int payload_length = skb->len - header_length;
@@ -495,8 +482,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
495 struct skb_frame_desc *skbdesc; 482 struct skb_frame_desc *skbdesc;
496 u8 rate_idx, rate_flags; 483 u8 rate_idx, rate_flags;
497 484
498 if (unlikely(rt2x00queue_full(queue))) 485 if (unlikely(rt2x00queue_full(queue))) {
486 ERROR(queue->rt2x00dev,
487 "Dropping frame due to full tx queue %d.\n", queue->qid);
499 return -ENOBUFS; 488 return -ENOBUFS;
489 }
500 490
501 if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, 491 if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
502 &entry->flags))) { 492 &entry->flags))) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 217861f8d95f..5db6a99fce7d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -217,6 +217,7 @@ enum txdone_entry_desc_flags {
217 TXDONE_FALLBACK, 217 TXDONE_FALLBACK,
218 TXDONE_FAILURE, 218 TXDONE_FAILURE,
219 TXDONE_EXCESSIVE_RETRY, 219 TXDONE_EXCESSIVE_RETRY,
220 TXDONE_AMPDU,
220}; 221};
221 222
222/** 223/**
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 77e8113b91e1..8ee1514a7943 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2313,8 +2313,10 @@ static void rt61pci_tbtt_tasklet(unsigned long data)
2313static void rt61pci_rxdone_tasklet(unsigned long data) 2313static void rt61pci_rxdone_tasklet(unsigned long data)
2314{ 2314{
2315 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; 2315 struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
2316 rt2x00pci_rxdone(rt2x00dev); 2316 if (rt2x00pci_rxdone(rt2x00dev))
2317 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); 2317 rt2x00pci_rxdone(rt2x00dev);
2318 else
2319 rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
2318} 2320}
2319 2321
2320static void rt61pci_autowake_tasklet(unsigned long data) 2322static void rt61pci_autowake_tasklet(unsigned long data)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 02f1148c577e..6593059f9c7e 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2209,7 +2209,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
2209 if (!modparam_nohwcrypt) 2209 if (!modparam_nohwcrypt)
2210 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 2210 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
2211 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); 2211 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
2212 __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
2213 2212
2214 /* 2213 /*
2215 * Set the rssi offset. 2214 * Set the rssi offset.
@@ -2407,7 +2406,6 @@ static struct usb_device_id rt73usb_device_table[] = {
2407 { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) }, 2406 { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) },
2408 { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) }, 2407 { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) },
2409 /* Belkin */ 2408 /* Belkin */
2410 { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) },
2411 { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) }, 2409 { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) },
2412 { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) }, 2410 { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) },
2413 { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) }, 2411 { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 0d7d93e1d398..4803f54842e4 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -432,7 +432,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
432 } 432 }
433 433
434 if (rtlpriv->dm.useramask) { 434 if (rtlpriv->dm.useramask) {
435 /* TODO we will differentiate adhoc and station futrue */ 435 /* TODO adhoc and station handled differently in the future */
436 tcb_desc->mac_id = 0; 436 tcb_desc->mac_id = 0;
437 437
438 if ((mac->mode == WIRELESS_MODE_N_24G) || 438 if ((mac->mode == WIRELESS_MODE_N_24G) ||
@@ -630,7 +630,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
630 const struct iphdr *ip; 630 const struct iphdr *ip;
631 631
632 if (!ieee80211_is_data(fc)) 632 if (!ieee80211_is_data(fc))
633 goto end; 633 return false;
634 634
635 if (ieee80211_is_nullfunc(fc)) 635 if (ieee80211_is_nullfunc(fc))
636 return true; 636 return true;
@@ -686,7 +686,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
686 return true; 686 return true;
687 } 687 }
688 688
689end:
690 return false; 689 return false;
691} 690}
692 691
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index e4f4aee8f298..8fed3c687619 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -35,7 +35,7 @@
35/*mutex for start & stop is must here. */ 35/*mutex for start & stop is must here. */
36static int rtl_op_start(struct ieee80211_hw *hw) 36static int rtl_op_start(struct ieee80211_hw *hw)
37{ 37{
38 int err = 0; 38 int err;
39 struct rtl_priv *rtlpriv = rtl_priv(hw); 39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 40 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
41 41
@@ -45,10 +45,8 @@ static int rtl_op_start(struct ieee80211_hw *hw)
45 return 0; 45 return 0;
46 mutex_lock(&rtlpriv->locks.conf_mutex); 46 mutex_lock(&rtlpriv->locks.conf_mutex);
47 err = rtlpriv->intf_ops->adapter_start(hw); 47 err = rtlpriv->intf_ops->adapter_start(hw);
48 if (err) 48 if (!err)
49 goto out; 49 rtl_watch_dog_timer_callback((unsigned long)hw);
50 rtl_watch_dog_timer_callback((unsigned long)hw);
51out:
52 mutex_unlock(&rtlpriv->locks.conf_mutex); 50 mutex_unlock(&rtlpriv->locks.conf_mutex);
53 return err; 51 return err;
54} 52}
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index 590f14f45a89..5d73c0f7012c 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -338,11 +338,11 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
338 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 338 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
339 u8 section_idx, i, Base; 339 u8 section_idx, i, Base;
340 u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used; 340 u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
341 bool bwordchanged, bresult = true; 341 bool wordchanged, result = true;
342 342
343 for (section_idx = 0; section_idx < 16; section_idx++) { 343 for (section_idx = 0; section_idx < 16; section_idx++) {
344 Base = section_idx * 8; 344 Base = section_idx * 8;
345 bwordchanged = false; 345 wordchanged = false;
346 346
347 for (i = 0; i < 8; i = i + 2) { 347 for (i = 0; i < 8; i = i + 2) {
348 if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] != 348 if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
@@ -351,11 +351,11 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
351 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i + 351 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
352 1])) { 352 1])) {
353 words_need++; 353 words_need++;
354 bwordchanged = true; 354 wordchanged = true;
355 } 355 }
356 } 356 }
357 357
358 if (bwordchanged == true) 358 if (wordchanged == true)
359 hdr_num++; 359 hdr_num++;
360 } 360 }
361 361
@@ -364,14 +364,14 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
364 364
365 if ((totalbytes + efuse_used) >= 365 if ((totalbytes + efuse_used) >=
366 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) 366 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))
367 bresult = false; 367 result = false;
368 368
369 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, 369 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
370 ("efuse_shadow_update_chk(): totalbytes(%#x), " 370 ("efuse_shadow_update_chk(): totalbytes(%#x), "
371 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", 371 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
372 totalbytes, hdr_num, words_need, efuse_used)); 372 totalbytes, hdr_num, words_need, efuse_used));
373 373
374 return bresult; 374 return result;
375} 375}
376 376
377void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, 377void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
@@ -394,7 +394,7 @@ void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
394 else if (type == 2) 394 else if (type == 2)
395 efuse_shadow_write_2byte(hw, offset, (u16) value); 395 efuse_shadow_write_2byte(hw, offset, (u16) value);
396 else if (type == 4) 396 else if (type == 4)
397 efuse_shadow_write_4byte(hw, offset, (u32) value); 397 efuse_shadow_write_4byte(hw, offset, value);
398 398
399} 399}
400 400
@@ -572,7 +572,7 @@ static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
572{ 572{
573 struct rtl_priv *rtlpriv = rtl_priv(hw); 573 struct rtl_priv *rtlpriv = rtl_priv(hw);
574 u8 tmpidx = 0; 574 u8 tmpidx = 0;
575 int bresult; 575 int result;
576 576
577 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, 577 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
578 (u8) (addr & 0xff)); 578 (u8) (addr & 0xff));
@@ -592,19 +592,18 @@ static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
592 592
593 if (tmpidx < 100) { 593 if (tmpidx < 100) {
594 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); 594 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
595 bresult = true; 595 result = true;
596 } else { 596 } else {
597 *data = 0xff; 597 *data = 0xff;
598 bresult = false; 598 result = false;
599 } 599 }
600 return bresult; 600 return result;
601} 601}
602 602
603static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) 603static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
604{ 604{
605 struct rtl_priv *rtlpriv = rtl_priv(hw); 605 struct rtl_priv *rtlpriv = rtl_priv(hw);
606 u8 tmpidx = 0; 606 u8 tmpidx = 0;
607 bool bresult;
608 607
609 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, 608 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
610 ("Addr = %x Data=%x\n", addr, data)); 609 ("Addr = %x Data=%x\n", addr, data));
@@ -626,11 +625,9 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
626 } 625 }
627 626
628 if (tmpidx < 100) 627 if (tmpidx < 100)
629 bresult = true; 628 return true;
630 else
631 bresult = false;
632 629
633 return bresult; 630 return false;
634} 631}
635 632
636static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) 633static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
@@ -681,11 +678,10 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
681{ 678{
682 u8 readstate = PG_STATE_HEADER; 679 u8 readstate = PG_STATE_HEADER;
683 680
684 bool bcontinual = true; 681 bool continual = true;
685 682
686 u8 efuse_data, word_cnts = 0; 683 u8 efuse_data, word_cnts = 0;
687 u16 efuse_addr = 0; 684 u16 efuse_addr = 0;
688 u8 hworden = 0;
689 u8 tmpdata[8]; 685 u8 tmpdata[8];
690 686
691 if (data == NULL) 687 if (data == NULL)
@@ -696,7 +692,7 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
696 memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); 692 memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
697 memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); 693 memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
698 694
699 while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) { 695 while (continual && (efuse_addr < EFUSE_MAX_SIZE)) {
700 if (readstate & PG_STATE_HEADER) { 696 if (readstate & PG_STATE_HEADER) {
701 if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) 697 if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
702 && (efuse_data != 0xFF)) 698 && (efuse_data != 0xFF))
@@ -705,9 +701,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
705 offset, tmpdata, 701 offset, tmpdata,
706 &readstate); 702 &readstate);
707 else 703 else
708 bcontinual = false; 704 continual = false;
709 } else if (readstate & PG_STATE_DATA) { 705 } else if (readstate & PG_STATE_DATA) {
710 efuse_word_enable_data_read(hworden, tmpdata, data); 706 efuse_word_enable_data_read(0, tmpdata, data);
711 efuse_addr = efuse_addr + (word_cnts * 2) + 1; 707 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
712 readstate = PG_STATE_HEADER; 708 readstate = PG_STATE_HEADER;
713 } 709 }
@@ -725,13 +721,13 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
725} 721}
726 722
727static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, 723static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
728 u8 efuse_data, u8 offset, int *bcontinual, 724 u8 efuse_data, u8 offset, int *continual,
729 u8 *write_state, struct pgpkt_struct *target_pkt, 725 u8 *write_state, struct pgpkt_struct *target_pkt,
730 int *repeat_times, int *bresult, u8 word_en) 726 int *repeat_times, int *result, u8 word_en)
731{ 727{
732 struct rtl_priv *rtlpriv = rtl_priv(hw); 728 struct rtl_priv *rtlpriv = rtl_priv(hw);
733 struct pgpkt_struct tmp_pkt; 729 struct pgpkt_struct tmp_pkt;
734 int bdataempty = true; 730 bool dataempty = true;
735 u8 originaldata[8 * sizeof(u8)]; 731 u8 originaldata[8 * sizeof(u8)];
736 u8 badworden = 0x0F; 732 u8 badworden = 0x0F;
737 u8 match_word_en, tmp_word_en; 733 u8 match_word_en, tmp_word_en;
@@ -751,10 +747,10 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
751 u16 address = *efuse_addr + 1 + tmpindex; 747 u16 address = *efuse_addr + 1 + tmpindex;
752 if (efuse_one_byte_read(hw, address, 748 if (efuse_one_byte_read(hw, address,
753 &efuse_data) && (efuse_data != 0xFF)) 749 &efuse_data) && (efuse_data != 0xFF))
754 bdataempty = false; 750 dataempty = false;
755 } 751 }
756 752
757 if (bdataempty == false) { 753 if (dataempty == false) {
758 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; 754 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
759 *write_state = PG_STATE_HEADER; 755 *write_state = PG_STATE_HEADER;
760 } else { 756 } else {
@@ -811,12 +807,12 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
811 target_pkt->offset = offset; 807 target_pkt->offset = offset;
812 target_pkt->word_en = tmp_word_en; 808 target_pkt->word_en = tmp_word_en;
813 } else 809 } else
814 *bcontinual = false; 810 *continual = false;
815 *write_state = PG_STATE_HEADER; 811 *write_state = PG_STATE_HEADER;
816 *repeat_times += 1; 812 *repeat_times += 1;
817 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { 813 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
818 *bcontinual = false; 814 *continual = false;
819 *bresult = false; 815 *result = false;
820 } 816 }
821 } else { 817 } else {
822 *efuse_addr += (2 * tmp_word_cnts) + 1; 818 *efuse_addr += (2 * tmp_word_cnts) + 1;
@@ -830,9 +826,9 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
830} 826}
831 827
832static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, 828static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
833 int *bcontinual, u8 *write_state, 829 int *continual, u8 *write_state,
834 struct pgpkt_struct target_pkt, 830 struct pgpkt_struct target_pkt,
835 int *repeat_times, int *bresult) 831 int *repeat_times, int *result)
836{ 832{
837 struct rtl_priv *rtlpriv = rtl_priv(hw); 833 struct rtl_priv *rtlpriv = rtl_priv(hw);
838 struct pgpkt_struct tmp_pkt; 834 struct pgpkt_struct tmp_pkt;
@@ -852,8 +848,8 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
852 *write_state = PG_STATE_HEADER; 848 *write_state = PG_STATE_HEADER;
853 *repeat_times += 1; 849 *repeat_times += 1;
854 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { 850 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
855 *bcontinual = false; 851 *continual = false;
856 *bresult = false; 852 *result = false;
857 } 853 }
858 } else { 854 } else {
859 tmp_pkt.offset = (tmp_header >> 4) & 0x0F; 855 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
@@ -884,8 +880,8 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
884 *write_state = PG_STATE_HEADER; 880 *write_state = PG_STATE_HEADER;
885 *repeat_times += 1; 881 *repeat_times += 1;
886 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { 882 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
887 *bcontinual = false; 883 *continual = false;
888 *bresult = false; 884 *result = false;
889 } 885 }
890 886
891 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 887 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
@@ -899,7 +895,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
899 struct rtl_priv *rtlpriv = rtl_priv(hw); 895 struct rtl_priv *rtlpriv = rtl_priv(hw);
900 struct pgpkt_struct target_pkt; 896 struct pgpkt_struct target_pkt;
901 u8 write_state = PG_STATE_HEADER; 897 u8 write_state = PG_STATE_HEADER;
902 int bcontinual = true, bdataempty = true, bresult = true; 898 int continual = true, dataempty = true, result = true;
903 u16 efuse_addr = 0; 899 u16 efuse_addr = 0;
904 u8 efuse_data; 900 u8 efuse_data;
905 u8 target_word_cnts = 0; 901 u8 target_word_cnts = 0;
@@ -923,11 +919,11 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
923 919
924 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n")); 920 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
925 921
926 while (bcontinual && (efuse_addr < 922 while (continual && (efuse_addr <
927 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { 923 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
928 924
929 if (write_state == PG_STATE_HEADER) { 925 if (write_state == PG_STATE_HEADER) {
930 bdataempty = true; 926 dataempty = true;
931 badworden = 0x0F; 927 badworden = 0x0F;
932 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 928 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
933 ("efuse PG_STATE_HEADER\n")); 929 ("efuse PG_STATE_HEADER\n"));
@@ -936,32 +932,30 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
936 (efuse_data != 0xFF)) 932 (efuse_data != 0xFF))
937 efuse_write_data_case1(hw, &efuse_addr, 933 efuse_write_data_case1(hw, &efuse_addr,
938 efuse_data, offset, 934 efuse_data, offset,
939 &bcontinual, 935 &continual,
940 &write_state, &target_pkt, 936 &write_state, &target_pkt,
941 &repeat_times, &bresult, 937 &repeat_times, &result,
942 word_en); 938 word_en);
943 else 939 else
944 efuse_write_data_case2(hw, &efuse_addr, 940 efuse_write_data_case2(hw, &efuse_addr,
945 &bcontinual, 941 &continual,
946 &write_state, 942 &write_state,
947 target_pkt, 943 target_pkt,
948 &repeat_times, 944 &repeat_times,
949 &bresult); 945 &result);
950 946
951 } else if (write_state == PG_STATE_DATA) { 947 } else if (write_state == PG_STATE_DATA) {
952 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 948 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
953 ("efuse PG_STATE_DATA\n")); 949 ("efuse PG_STATE_DATA\n"));
954 badworden = 0x0f;
955 badworden = 950 badworden =
956 efuse_word_enable_data_write(hw, efuse_addr + 1, 951 efuse_word_enable_data_write(hw, efuse_addr + 1,
957 target_pkt.word_en, 952 target_pkt.word_en,
958 target_pkt.data); 953 target_pkt.data);
959 954
960 if ((badworden & 0x0F) == 0x0F) { 955 if ((badworden & 0x0F) == 0x0F) {
961 bcontinual = false; 956 continual = false;
962 } else { 957 } else {
963 efuse_addr = 958 efuse_addr += (2 * target_word_cnts) + 1;
964 efuse_addr + (2 * target_word_cnts) + 1;
965 959
966 target_pkt.offset = offset; 960 target_pkt.offset = offset;
967 target_pkt.word_en = badworden; 961 target_pkt.word_en = badworden;
@@ -971,8 +965,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
971 write_state = PG_STATE_HEADER; 965 write_state = PG_STATE_HEADER;
972 repeat_times++; 966 repeat_times++;
973 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) { 967 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
974 bcontinual = false; 968 continual = false;
975 bresult = false; 969 result = false;
976 } 970 }
977 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 971 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
978 ("efuse PG_STATE_HEADER-3\n")); 972 ("efuse PG_STATE_HEADER-3\n"));
@@ -1072,13 +1066,13 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
1072 return badworden; 1066 return badworden;
1073} 1067}
1074 1068
1075static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) 1069static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
1076{ 1070{
1077 struct rtl_priv *rtlpriv = rtl_priv(hw); 1071 struct rtl_priv *rtlpriv = rtl_priv(hw);
1078 u8 tempval; 1072 u8 tempval;
1079 u16 tmpV16; 1073 u16 tmpV16;
1080 1074
1081 if (pwrstate == true) { 1075 if (pwrstate) {
1082 tmpV16 = rtl_read_word(rtlpriv, 1076 tmpV16 = rtl_read_word(rtlpriv,
1083 rtlpriv->cfg->maps[SYS_ISO_CTRL]); 1077 rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1084 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { 1078 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
@@ -1106,8 +1100,8 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
1106 } 1100 }
1107 } 1101 }
1108 1102
1109 if (pwrstate == true) { 1103 if (pwrstate) {
1110 if (bwrite == true) { 1104 if (write) {
1111 tempval = rtl_read_byte(rtlpriv, 1105 tempval = rtl_read_byte(rtlpriv,
1112 rtlpriv->cfg->maps[EFUSE_TEST] + 1106 rtlpriv->cfg->maps[EFUSE_TEST] +
1113 3); 1107 3);
@@ -1119,7 +1113,7 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
1119 } 1113 }
1120 1114
1121 } else { 1115 } else {
1122 if (bwrite == true) { 1116 if (write) {
1123 tempval = rtl_read_byte(rtlpriv, 1117 tempval = rtl_read_byte(rtlpriv,
1124 rtlpriv->cfg->maps[EFUSE_TEST] + 1118 rtlpriv->cfg->maps[EFUSE_TEST] +
1125 3); 1119 3);
@@ -1134,12 +1128,12 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
1134 1128
1135static u16 efuse_get_current_size(struct ieee80211_hw *hw) 1129static u16 efuse_get_current_size(struct ieee80211_hw *hw)
1136{ 1130{
1137 int bcontinual = true; 1131 int continual = true;
1138 u16 efuse_addr = 0; 1132 u16 efuse_addr = 0;
1139 u8 hoffset, hworden; 1133 u8 hoffset, hworden;
1140 u8 efuse_data, word_cnts; 1134 u8 efuse_data, word_cnts;
1141 1135
1142 while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) 1136 while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
1143 && (efuse_addr < EFUSE_MAX_SIZE)) { 1137 && (efuse_addr < EFUSE_MAX_SIZE)) {
1144 if (efuse_data != 0xFF) { 1138 if (efuse_data != 0xFF) {
1145 hoffset = (efuse_data >> 4) & 0x0F; 1139 hoffset = (efuse_data >> 4) & 0x0F;
@@ -1147,7 +1141,7 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw)
1147 word_cnts = efuse_calculate_word_cnts(hworden); 1141 word_cnts = efuse_calculate_word_cnts(hworden);
1148 efuse_addr = efuse_addr + (word_cnts * 2) + 1; 1142 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1149 } else { 1143 } else {
1150 bcontinual = false; 1144 continual = false;
1151 } 1145 }
1152 } 1146 }
1153 1147
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 5938f6ee21e4..fbde52d83424 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -113,32 +113,19 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
113 113
114 /*Set HW definition to determine if it supports ASPM. */ 114 /*Set HW definition to determine if it supports ASPM. */
115 switch (rtlpci->const_support_pciaspm) { 115 switch (rtlpci->const_support_pciaspm) {
116 case 0:{ 116 case 0:
117 /*Not support ASPM. */ 117 /*Not support ASPM. */
118 bool support_aspm = false; 118 ppsc->support_aspm = false;
119 ppsc->support_aspm = support_aspm; 119 break;
120 break; 120 case 1:
121 } 121 /*Support ASPM. */
122 case 1:{ 122 ppsc->support_aspm = true;
123 /*Support ASPM. */ 123 ppsc->support_backdoor = true;
124 bool support_aspm = true; 124 break;
125 bool support_backdoor = true;
126 ppsc->support_aspm = support_aspm;
127
128 /*if(priv->oem_id == RT_CID_TOSHIBA &&
129 !priv->ndis_adapter.amd_l1_patch)
130 support_backdoor = false; */
131
132 ppsc->support_backdoor = support_backdoor;
133
134 break;
135 }
136 case 2: 125 case 2:
137 /*ASPM value set by chipset. */ 126 /*ASPM value set by chipset. */
138 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { 127 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
139 bool support_aspm = true; 128 ppsc->support_aspm = true;
140 ppsc->support_aspm = support_aspm;
141 }
142 break; 129 break;
143 default: 130 default:
144 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 131 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -152,13 +139,11 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(
152 u8 value) 139 u8 value)
153{ 140{
154 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 141 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
155 bool bresult = false;
156 142
157 value |= 0x40; 143 value |= 0x40;
158
159 pci_write_config_byte(rtlpci->pdev, 0x80, value); 144 pci_write_config_byte(rtlpci->pdev, 0x80, value);
160 145
161 return bresult; 146 return false;
162} 147}
163 148
164/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ 149/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
@@ -166,14 +151,11 @@ static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
166{ 151{
167 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 152 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
168 u8 buffer; 153 u8 buffer;
169 bool bresult = false;
170 154
171 buffer = value; 155 buffer = value;
172
173 pci_write_config_byte(rtlpci->pdev, 0x81, value); 156 pci_write_config_byte(rtlpci->pdev, 0x81, value);
174 bresult = true;
175 157
176 return bresult; 158 return true;
177} 159}
178 160
179/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ 161/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
@@ -191,6 +173,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
191 u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. 173 u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
192 pcibridge_linkctrlreg; 174 pcibridge_linkctrlreg;
193 u16 aspmlevel = 0; 175 u16 aspmlevel = 0;
176 u8 tmp_u1b = 0;
194 177
195 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { 178 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
196 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, 179 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
@@ -204,11 +187,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
204 _rtl_pci_switch_clk_req(hw, 0x0); 187 _rtl_pci_switch_clk_req(hw, 0x0);
205 } 188 }
206 189
207 if (1) { 190 /*for promising device will in L0 state after an I/O. */
208 /*for promising device will in L0 state after an I/O. */ 191 pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
209 u8 tmp_u1b;
210 pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
211 }
212 192
213 /*Set corresponding value. */ 193 /*Set corresponding value. */
214 aspmlevel |= BIT(0) | BIT(1); 194 aspmlevel |= BIT(0) | BIT(1);
@@ -224,7 +204,6 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
224 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg); 204 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
225 205
226 udelay(50); 206 udelay(50);
227
228} 207}
229 208
230/* 209/*
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index 0caa81429726..12747b9c71e1 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -192,8 +192,8 @@ struct rtl_pci {
192 u8 const_devicepci_aspm_setting; 192 u8 const_devicepci_aspm_setting;
193 /*If it supports ASPM, Offset[560h] = 0x40, 193 /*If it supports ASPM, Offset[560h] = 0x40,
194 otherwise Offset[560h] = 0x00. */ 194 otherwise Offset[560h] = 0x00. */
195 bool b_support_aspm; 195 bool support_aspm;
196 bool b_support_backdoor; 196 bool support_backdoor;
197 197
198 /*QOS & EDCA */ 198 /*QOS & EDCA */
199 enum acm_method acm_method; 199 enum acm_method acm_method;
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 6b7e217b6b89..c8395fb0c050 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -63,7 +63,6 @@ EXPORT_SYMBOL(rtl_ps_enable_nic);
63 63
64bool rtl_ps_disable_nic(struct ieee80211_hw *hw) 64bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
65{ 65{
66 bool status = true;
67 struct rtl_priv *rtlpriv = rtl_priv(hw); 66 struct rtl_priv *rtlpriv = rtl_priv(hw);
68 67
69 /*<1> Stop all timer */ 68 /*<1> Stop all timer */
@@ -75,7 +74,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
75 /*<3> Disable Adapter */ 74 /*<3> Disable Adapter */
76 rtlpriv->cfg->ops->hw_disable(hw); 75 rtlpriv->cfg->ops->hw_disable(hw);
77 76
78 return status; 77 return true;
79} 78}
80EXPORT_SYMBOL(rtl_ps_disable_nic); 79EXPORT_SYMBOL(rtl_ps_disable_nic);
81 80
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 28a6ce3bc239..f107660f545d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -171,7 +171,6 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
171static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) 171static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
172{ 172{
173 struct rtl_priv *rtlpriv = rtl_priv(hw); 173 struct rtl_priv *rtlpriv = rtl_priv(hw);
174 int err = -EIO;
175 u32 counter = 0; 174 u32 counter = 0;
176 u32 value32; 175 u32 value32;
177 176
@@ -184,7 +183,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
184 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 183 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
185 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", 184 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
186 value32)); 185 value32));
187 goto exit; 186 return -EIO;
188 } 187 }
189 188
190 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 189 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
@@ -204,8 +203,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
204 ("Polling FW ready success!!" 203 ("Polling FW ready success!!"
205 " REG_MCUFWDL:0x%08x .\n", 204 " REG_MCUFWDL:0x%08x .\n",
206 value32)); 205 value32));
207 err = 0; 206 return 0;
208 goto exit;
209 } 207 }
210 208
211 mdelay(FW_8192C_POLLING_DELAY); 209 mdelay(FW_8192C_POLLING_DELAY);
@@ -214,9 +212,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
214 212
215 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 213 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
216 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); 214 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
217 215 return -EIO;
218exit:
219 return err;
220} 216}
221 217
222int rtl92c_download_fw(struct ieee80211_hw *hw) 218int rtl92c_download_fw(struct ieee80211_hw *hw)
@@ -226,16 +222,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
226 struct rtl92c_firmware_header *pfwheader; 222 struct rtl92c_firmware_header *pfwheader;
227 u8 *pfwdata; 223 u8 *pfwdata;
228 u32 fwsize; 224 u32 fwsize;
229 int err;
230 enum version_8192c version = rtlhal->version; 225 enum version_8192c version = rtlhal->version;
231 const struct firmware *firmware; 226 const struct firmware *firmware;
232 227
233 printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", 228 printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",
234 rtlpriv->cfg->fw_name); 229 rtlpriv->cfg->fw_name);
235 err = request_firmware(&firmware, rtlpriv->cfg->fw_name, 230 if (request_firmware(&firmware, rtlpriv->cfg->fw_name,
236 rtlpriv->io.dev); 231 rtlpriv->io.dev)) {
237 if (err) { 232 printk(KERN_ERR "rtl8192c: Firmware loading failed\n");
238 printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
239 return 1; 233 return 1;
240 } 234 }
241 235
@@ -267,8 +261,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
267 _rtl92c_write_fw(hw, version, pfwdata, fwsize); 261 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
268 _rtl92c_enable_fw_download(hw, false); 262 _rtl92c_enable_fw_download(hw, false);
269 263
270 err = _rtl92c_fw_free_to_go(hw); 264 if (_rtl92c_fw_free_to_go(hw)) {
271 if (err) {
272 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 265 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
273 ("Firmware is not ready to run!\n")); 266 ("Firmware is not ready to run!\n"));
274 } else { 267 } else {
@@ -303,7 +296,6 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
303 u16 box_reg, box_extreg; 296 u16 box_reg, box_extreg;
304 u8 u1b_tmp; 297 u8 u1b_tmp;
305 bool isfw_read = false; 298 bool isfw_read = false;
306 u8 buf_index = 0;
307 bool bwrite_sucess = false; 299 bool bwrite_sucess = false;
308 u8 wait_h2c_limmit = 100; 300 u8 wait_h2c_limmit = 100;
309 u8 wait_writeh2c_limmit = 100; 301 u8 wait_writeh2c_limmit = 100;
@@ -414,7 +406,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
414 case 1: 406 case 1:
415 boxcontent[0] &= ~(BIT(7)); 407 boxcontent[0] &= ~(BIT(7));
416 memcpy((u8 *) (boxcontent) + 1, 408 memcpy((u8 *) (boxcontent) + 1,
417 p_cmdbuffer + buf_index, 1); 409 p_cmdbuffer, 1);
418 410
419 for (idx = 0; idx < 4; idx++) { 411 for (idx = 0; idx < 4; idx++) {
420 rtl_write_byte(rtlpriv, box_reg + idx, 412 rtl_write_byte(rtlpriv, box_reg + idx,
@@ -424,7 +416,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
424 case 2: 416 case 2:
425 boxcontent[0] &= ~(BIT(7)); 417 boxcontent[0] &= ~(BIT(7));
426 memcpy((u8 *) (boxcontent) + 1, 418 memcpy((u8 *) (boxcontent) + 1,
427 p_cmdbuffer + buf_index, 2); 419 p_cmdbuffer, 2);
428 420
429 for (idx = 0; idx < 4; idx++) { 421 for (idx = 0; idx < 4; idx++) {
430 rtl_write_byte(rtlpriv, box_reg + idx, 422 rtl_write_byte(rtlpriv, box_reg + idx,
@@ -434,7 +426,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
434 case 3: 426 case 3:
435 boxcontent[0] &= ~(BIT(7)); 427 boxcontent[0] &= ~(BIT(7));
436 memcpy((u8 *) (boxcontent) + 1, 428 memcpy((u8 *) (boxcontent) + 1,
437 p_cmdbuffer + buf_index, 3); 429 p_cmdbuffer, 3);
438 430
439 for (idx = 0; idx < 4; idx++) { 431 for (idx = 0; idx < 4; idx++) {
440 rtl_write_byte(rtlpriv, box_reg + idx, 432 rtl_write_byte(rtlpriv, box_reg + idx,
@@ -444,9 +436,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
444 case 4: 436 case 4:
445 boxcontent[0] |= (BIT(7)); 437 boxcontent[0] |= (BIT(7));
446 memcpy((u8 *) (boxextcontent), 438 memcpy((u8 *) (boxextcontent),
447 p_cmdbuffer + buf_index, 2); 439 p_cmdbuffer, 2);
448 memcpy((u8 *) (boxcontent) + 1, 440 memcpy((u8 *) (boxcontent) + 1,
449 p_cmdbuffer + buf_index + 2, 2); 441 p_cmdbuffer + 2, 2);
450 442
451 for (idx = 0; idx < 2; idx++) { 443 for (idx = 0; idx < 2; idx++) {
452 rtl_write_byte(rtlpriv, box_extreg + idx, 444 rtl_write_byte(rtlpriv, box_extreg + idx,
@@ -461,9 +453,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
461 case 5: 453 case 5:
462 boxcontent[0] |= (BIT(7)); 454 boxcontent[0] |= (BIT(7));
463 memcpy((u8 *) (boxextcontent), 455 memcpy((u8 *) (boxextcontent),
464 p_cmdbuffer + buf_index, 2); 456 p_cmdbuffer, 2);
465 memcpy((u8 *) (boxcontent) + 1, 457 memcpy((u8 *) (boxcontent) + 1,
466 p_cmdbuffer + buf_index + 2, 3); 458 p_cmdbuffer + 2, 3);
467 459
468 for (idx = 0; idx < 2; idx++) { 460 for (idx = 0; idx < 2; idx++) {
469 rtl_write_byte(rtlpriv, box_extreg + idx, 461 rtl_write_byte(rtlpriv, box_extreg + idx,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
index 803adcc80c96..b0b0b13dd0ae 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -532,9 +532,9 @@
532#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ 532#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
533do { \ 533do { \
534 if (_size > TX_DESC_NEXT_DESC_OFFSET) \ 534 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
535 memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ 535 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
536 else \ 536 else \
537 memset((void *)__pdesc, 0, _size); \ 537 memset(__pdesc, 0, _size); \
538} while (0); 538} while (0);
539 539
540#define RX_HAL_IS_CCK_RATE(_pdesc)\ 540#define RX_HAL_IS_CCK_RATE(_pdesc)\
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index d0b0d43b9a6d..3f0cb81c424f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -656,7 +656,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
656 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); 656 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
657 __le16 fc = hdr->frame_control; 657 __le16 fc = hdr->frame_control;
658 658
659 memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); 659 memset(pdesc, 0, RTL_TX_HEADER_SIZE);
660 if (firstseg) 660 if (firstseg)
661 SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); 661 SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE);
662 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); 662 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 07db95ff9bc5..2713efe07ce5 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -766,7 +766,7 @@ struct rtl_rfkill {
766#define IQK_MATRIX_REG_NUM 8 766#define IQK_MATRIX_REG_NUM 8
767#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) 767#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21)
768struct iqk_matrix_regs { 768struct iqk_matrix_regs {
769 bool b_iqk_done; 769 bool iqk_done;
770 long value[1][IQK_MATRIX_REG_NUM]; 770 long value[1][IQK_MATRIX_REG_NUM];
771}; 771};
772 772
@@ -1621,19 +1621,19 @@ struct bt_coexist_info {
1621 u32 bt_edca_ul; 1621 u32 bt_edca_ul;
1622 u32 bt_edca_dl; 1622 u32 bt_edca_dl;
1623 1623
1624 bool b_init_set; 1624 bool init_set;
1625 bool b_bt_busy_traffic; 1625 bool bt_busy_traffic;
1626 bool b_bt_traffic_mode_set; 1626 bool bt_traffic_mode_set;
1627 bool b_bt_non_traffic_mode_set; 1627 bool bt_non_traffic_mode_set;
1628 1628
1629 bool b_fw_coexist_all_off; 1629 bool fw_coexist_all_off;
1630 bool b_sw_coexist_all_off; 1630 bool sw_coexist_all_off;
1631 u32 current_state; 1631 u32 current_state;
1632 u32 previous_state; 1632 u32 previous_state;
1633 u8 bt_pre_rssi_state; 1633 u8 bt_pre_rssi_state;
1634 1634
1635 u8 b_reg_bt_iso; 1635 u8 reg_bt_iso;
1636 u8 b_reg_bt_sco; 1636 u8 reg_bt_sco;
1637 1637
1638}; 1638};
1639 1639
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h
index e5c74c631374..79ca5273c9e9 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
@@ -313,8 +313,8 @@ struct wl1251_cmd_vbm_update {
313} __packed; 313} __packed;
314 314
315enum wl1251_cmd_ps_mode { 315enum wl1251_cmd_ps_mode {
316 STATION_ACTIVE_MODE, 316 CHIP_ACTIVE_MODE,
317 STATION_POWER_SAVE_MODE 317 CHIP_POWER_SAVE_MODE
318}; 318};
319 319
320struct wl1251_cmd_ps_params { 320struct wl1251_cmd_ps_params {
diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c
index dfc4579acb06..9f15ccaf8f05 100644
--- a/drivers/net/wireless/wl1251/event.c
+++ b/drivers/net/wireless/wl1251/event.c
@@ -68,14 +68,16 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
68 if (vector & BSS_LOSE_EVENT_ID) { 68 if (vector & BSS_LOSE_EVENT_ID) {
69 wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); 69 wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
70 70
71 if (wl->psm_requested && wl->psm) { 71 if (wl->psm_requested &&
72 wl->station_mode != STATION_ACTIVE_MODE) {
72 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 73 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
73 if (ret < 0) 74 if (ret < 0)
74 return ret; 75 return ret;
75 } 76 }
76 } 77 }
77 78
78 if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { 79 if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID &&
80 wl->station_mode != STATION_ACTIVE_MODE) {
79 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); 81 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
80 82
81 /* indicate to the stack, that beacons have been lost */ 83 /* indicate to the stack, that beacons have been lost */
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 12c9e635a6d6..a14a48c99cdc 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -497,7 +497,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
497 wl->rx_last_id = 0; 497 wl->rx_last_id = 0;
498 wl->next_tx_complete = 0; 498 wl->next_tx_complete = 0;
499 wl->elp = false; 499 wl->elp = false;
500 wl->psm = 0; 500 wl->station_mode = STATION_ACTIVE_MODE;
501 wl->tx_queue_stopped = false; 501 wl->tx_queue_stopped = false;
502 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 502 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
503 wl->rssi_thold = 0; 503 wl->rssi_thold = 0;
@@ -632,13 +632,29 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
632 632
633 wl->psm_requested = false; 633 wl->psm_requested = false;
634 634
635 if (wl->psm) { 635 if (wl->station_mode != STATION_ACTIVE_MODE) {
636 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 636 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
637 if (ret < 0) 637 if (ret < 0)
638 goto out_sleep; 638 goto out_sleep;
639 } 639 }
640 } 640 }
641 641
642 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
643 if (conf->flags & IEEE80211_CONF_IDLE) {
644 ret = wl1251_ps_set_mode(wl, STATION_IDLE);
645 if (ret < 0)
646 goto out_sleep;
647 } else {
648 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
649 if (ret < 0)
650 goto out_sleep;
651 ret = wl1251_join(wl, wl->bss_type, wl->channel,
652 wl->beacon_int, wl->dtim_period);
653 if (ret < 0)
654 goto out_sleep;
655 }
656 }
657
642 if (conf->power_level != wl->power_level) { 658 if (conf->power_level != wl->power_level) {
643 ret = wl1251_acx_tx_power(wl, conf->power_level); 659 ret = wl1251_acx_tx_power(wl, conf->power_level);
644 if (ret < 0) 660 if (ret < 0)
@@ -1384,7 +1400,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
1384 wl->rx_config = WL1251_DEFAULT_RX_CONFIG; 1400 wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
1385 wl->rx_filter = WL1251_DEFAULT_RX_FILTER; 1401 wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
1386 wl->elp = false; 1402 wl->elp = false;
1387 wl->psm = 0; 1403 wl->station_mode = STATION_ACTIVE_MODE;
1388 wl->psm_requested = false; 1404 wl->psm_requested = false;
1389 wl->tx_queue_stopped = false; 1405 wl->tx_queue_stopped = false;
1390 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 1406 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c
index 9cc514703d2a..db719f7d2692 100644
--- a/drivers/net/wireless/wl1251/ps.c
+++ b/drivers/net/wireless/wl1251/ps.c
@@ -39,7 +39,7 @@ void wl1251_elp_work(struct work_struct *work)
39 39
40 mutex_lock(&wl->mutex); 40 mutex_lock(&wl->mutex);
41 41
42 if (wl->elp || !wl->psm) 42 if (wl->elp || wl->station_mode == STATION_ACTIVE_MODE)
43 goto out; 43 goto out;
44 44
45 wl1251_debug(DEBUG_PSM, "chip to elp"); 45 wl1251_debug(DEBUG_PSM, "chip to elp");
@@ -57,7 +57,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
57{ 57{
58 unsigned long delay; 58 unsigned long delay;
59 59
60 if (wl->psm) { 60 if (wl->station_mode != STATION_ACTIVE_MODE) {
61 delay = msecs_to_jiffies(ELP_ENTRY_DELAY); 61 delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
62 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); 62 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
63 } 63 }
@@ -104,7 +104,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
104 return 0; 104 return 0;
105} 105}
106 106
107int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) 107int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
108{ 108{
109 int ret; 109 int ret;
110 110
@@ -128,15 +128,24 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
128 if (ret < 0) 128 if (ret < 0)
129 return ret; 129 return ret;
130 130
131 ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); 131 ret = wl1251_cmd_ps_mode(wl, CHIP_POWER_SAVE_MODE);
132 if (ret < 0) 132 if (ret < 0)
133 return ret; 133 return ret;
134 134
135 ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); 135 ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
136 if (ret < 0) 136 if (ret < 0)
137 return ret; 137 return ret;
138 break;
139 case STATION_IDLE:
140 wl1251_debug(DEBUG_PSM, "entering idle");
138 141
139 wl->psm = 1; 142 ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
143 if (ret < 0)
144 return ret;
145
146 ret = wl1251_cmd_template_set(wl, CMD_DISCONNECT, NULL, 0);
147 if (ret < 0)
148 return ret;
140 break; 149 break;
141 case STATION_ACTIVE_MODE: 150 case STATION_ACTIVE_MODE:
142 default: 151 default:
@@ -163,13 +172,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
163 if (ret < 0) 172 if (ret < 0)
164 return ret; 173 return ret;
165 174
166 ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE); 175 ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE);
167 if (ret < 0) 176 if (ret < 0)
168 return ret; 177 return ret;
169 178
170 wl->psm = 0;
171 break; 179 break;
172 } 180 }
181 wl->station_mode = mode;
173 182
174 return ret; 183 return ret;
175} 184}
diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/wl1251/ps.h
index 55c3dda75e69..75efad246d67 100644
--- a/drivers/net/wireless/wl1251/ps.h
+++ b/drivers/net/wireless/wl1251/ps.h
@@ -26,7 +26,7 @@
26#include "wl1251.h" 26#include "wl1251.h"
27#include "acx.h" 27#include "acx.h"
28 28
29int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); 29int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode);
30void wl1251_ps_elp_sleep(struct wl1251 *wl); 30void wl1251_ps_elp_sleep(struct wl1251 *wl);
31int wl1251_ps_elp_wakeup(struct wl1251 *wl); 31int wl1251_ps_elp_wakeup(struct wl1251 *wl);
32void wl1251_elp_work(struct work_struct *work); 32void wl1251_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index bb23cd522b22..a77f1bbbed0a 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -129,6 +129,12 @@ enum wl1251_partition_type {
129 PART_TABLE_LEN 129 PART_TABLE_LEN
130}; 130};
131 131
132enum wl1251_station_mode {
133 STATION_ACTIVE_MODE,
134 STATION_POWER_SAVE_MODE,
135 STATION_IDLE,
136};
137
132struct wl1251_partition { 138struct wl1251_partition {
133 u32 size; 139 u32 size;
134 u32 start; 140 u32 start;
@@ -358,8 +364,7 @@ struct wl1251 {
358 364
359 struct delayed_work elp_work; 365 struct delayed_work elp_work;
360 366
361 /* we can be in psm, but not in elp, we have to differentiate */ 367 enum wl1251_station_mode station_mode;
362 bool psm;
363 368
364 /* PSM mode requested */ 369 /* PSM mode requested */
365 bool psm_requested; 370 bool psm_requested;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index a73a305d3cba..ff306d763e37 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -557,7 +557,7 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip)
557 return r; 557 return r;
558} 558}
559 559
560/* CR157 can be optionally patched by the EEPROM for original ZD1211 */ 560/* ZD_CR157 can be optionally patched by the EEPROM for original ZD1211 */
561static int patch_cr157(struct zd_chip *chip) 561static int patch_cr157(struct zd_chip *chip)
562{ 562{
563 int r; 563 int r;
@@ -571,7 +571,7 @@ static int patch_cr157(struct zd_chip *chip)
571 return r; 571 return r;
572 572
573 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8); 573 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
574 return zd_iowrite32_locked(chip, value >> 8, CR157); 574 return zd_iowrite32_locked(chip, value >> 8, ZD_CR157);
575} 575}
576 576
577/* 577/*
@@ -593,8 +593,8 @@ static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
593int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel) 593int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
594{ 594{
595 struct zd_ioreq16 ioreqs[] = { 595 struct zd_ioreq16 ioreqs[] = {
596 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 596 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
597 { CR47, 0x1e }, 597 { ZD_CR47, 0x1e },
598 }; 598 };
599 599
600 /* FIXME: Channel 11 is not the edge for all regulatory domains. */ 600 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
@@ -608,69 +608,69 @@ int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
608static int zd1211_hw_reset_phy(struct zd_chip *chip) 608static int zd1211_hw_reset_phy(struct zd_chip *chip)
609{ 609{
610 static const struct zd_ioreq16 ioreqs[] = { 610 static const struct zd_ioreq16 ioreqs[] = {
611 { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 }, 611 { ZD_CR0, 0x0a }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 },
612 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 }, 612 { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xa0 },
613 { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f }, 613 { ZD_CR10, 0x81 }, { ZD_CR11, 0x00 }, { ZD_CR12, 0x7f },
614 { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d }, 614 { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 }, { ZD_CR15, 0x3d },
615 { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a }, 615 { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e }, { ZD_CR18, 0x0a },
616 { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c }, 616 { ZD_CR19, 0x48 }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0c },
617 { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 }, 617 { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 }, { ZD_CR24, 0x14 },
618 { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 }, 618 { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 }, { ZD_CR27, 0x19 },
619 { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b }, 619 { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 }, { ZD_CR30, 0x4b },
620 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, 620 { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 },
621 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, 621 { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 },
622 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, 622 { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c },
623 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 }, 623 { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 },
624 { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff }, 624 { ZD_CR43, 0x10 }, { ZD_CR44, 0x12 }, { ZD_CR46, 0xff },
625 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b }, 625 { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b },
626 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 }, 626 { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 },
627 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 }, 627 { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 },
628 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff }, 628 { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff },
629 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 }, 629 { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 },
630 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 }, 630 { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 },
631 { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 }, 631 { ZD_CR79, 0x68 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 },
632 { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 }, 632 { ZD_CR82, 0x00 }, { ZD_CR83, 0x00 }, { ZD_CR84, 0x00 },
633 { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 }, 633 { ZD_CR85, 0x02 }, { ZD_CR86, 0x00 }, { ZD_CR87, 0x00 },
634 { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 }, 634 { ZD_CR88, 0xff }, { ZD_CR89, 0xfc }, { ZD_CR90, 0x00 },
635 { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 }, 635 { ZD_CR91, 0x00 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x08 },
636 { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff }, 636 { ZD_CR94, 0x00 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0xff },
637 { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 }, 637 { ZD_CR97, 0xe7 }, { ZD_CR98, 0x00 }, { ZD_CR99, 0x00 },
638 { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 }, 638 { ZD_CR100, 0x00 }, { ZD_CR101, 0xae }, { ZD_CR102, 0x02 },
639 { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 }, 639 { ZD_CR103, 0x00 }, { ZD_CR104, 0x03 }, { ZD_CR105, 0x65 },
640 { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a }, 640 { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, { ZD_CR108, 0x0a },
641 { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 }, 641 { ZD_CR109, 0xaa }, { ZD_CR110, 0xaa }, { ZD_CR111, 0x25 },
642 { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e }, 642 { ZD_CR112, 0x25 }, { ZD_CR113, 0x00 }, { ZD_CR119, 0x1e },
643 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 }, 643 { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 },
644 { }, 644 { },
645 { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 }, 645 { ZD_CR5, 0x00 }, { ZD_CR6, 0x00 }, { ZD_CR7, 0x00 },
646 { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 }, 646 { ZD_CR8, 0x00 }, { ZD_CR9, 0x20 }, { ZD_CR12, 0xf0 },
647 { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 }, 647 { ZD_CR20, 0x0e }, { ZD_CR21, 0x0e }, { ZD_CR27, 0x10 },
648 { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 }, 648 { ZD_CR44, 0x33 }, { ZD_CR47, 0x1E }, { ZD_CR83, 0x24 },
649 { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C }, 649 { ZD_CR84, 0x04 }, { ZD_CR85, 0x00 }, { ZD_CR86, 0x0C },
650 { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 }, 650 { ZD_CR87, 0x12 }, { ZD_CR88, 0x0C }, { ZD_CR89, 0x00 },
651 { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 }, 651 { ZD_CR90, 0x10 }, { ZD_CR91, 0x08 }, { ZD_CR93, 0x00 },
652 { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 }, 652 { ZD_CR94, 0x01 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0x50 },
653 { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 }, 653 { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 }, { ZD_CR101, 0x13 },
654 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 }, 654 { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 },
655 { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 }, 655 { ZD_CR105, 0x12 }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 },
656 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, 656 { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 },
657 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, 657 { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 },
658 { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f }, 658 { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR120, 0x4f },
659 { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 }, 659 { ZD_CR125, 0xaa }, { ZD_CR127, 0x03 }, { ZD_CR128, 0x14 },
660 { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C }, 660 { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, { ZD_CR131, 0x0C },
661 { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 }, 661 { ZD_CR136, 0xdf }, { ZD_CR137, 0x40 }, { ZD_CR138, 0xa0 },
662 { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 }, 662 { ZD_CR139, 0xb0 }, { ZD_CR140, 0x99 }, { ZD_CR141, 0x82 },
663 { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c }, 663 { ZD_CR142, 0x54 }, { ZD_CR143, 0x1c }, { ZD_CR144, 0x6c },
664 { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 }, 664 { ZD_CR147, 0x07 }, { ZD_CR148, 0x4c }, { ZD_CR149, 0x50 },
665 { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe }, 665 { ZD_CR150, 0x0e }, { ZD_CR151, 0x18 }, { ZD_CR160, 0xfe },
666 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa }, 666 { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa },
667 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe }, 667 { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe },
668 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba }, 668 { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba },
669 { CR170, 0xba }, { CR171, 0xba }, 669 { ZD_CR170, 0xba }, { ZD_CR171, 0xba },
670 /* Note: CR204 must lead the CR203 */ 670 /* Note: ZD_CR204 must lead the ZD_CR203 */
671 { CR204, 0x7d }, 671 { ZD_CR204, 0x7d },
672 { }, 672 { },
673 { CR203, 0x30 }, 673 { ZD_CR203, 0x30 },
674 }; 674 };
675 675
676 int r, t; 676 int r, t;
@@ -697,62 +697,62 @@ out:
697static int zd1211b_hw_reset_phy(struct zd_chip *chip) 697static int zd1211b_hw_reset_phy(struct zd_chip *chip)
698{ 698{
699 static const struct zd_ioreq16 ioreqs[] = { 699 static const struct zd_ioreq16 ioreqs[] = {
700 { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 }, 700 { ZD_CR0, 0x14 }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 },
701 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 }, 701 { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xe0 },
702 { CR10, 0x81 }, 702 { ZD_CR10, 0x81 },
703 /* power control { { CR11, 1 << 6 }, */ 703 /* power control { { ZD_CR11, 1 << 6 }, */
704 { CR11, 0x00 }, 704 { ZD_CR11, 0x00 },
705 { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 }, 705 { ZD_CR12, 0xf0 }, { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 },
706 { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e }, 706 { ZD_CR15, 0x3d }, { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e },
707 { CR18, 0x0a }, { CR19, 0x48 }, 707 { ZD_CR18, 0x0a }, { ZD_CR19, 0x48 },
708 { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */ 708 { ZD_CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
709 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 }, 709 { ZD_CR21, 0x0e }, { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 },
710 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 }, 710 { ZD_CR24, 0x14 }, { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 },
711 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 }, 711 { ZD_CR27, 0x10 }, { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 },
712 { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */ 712 { ZD_CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
713 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, 713 { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 },
714 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, 714 { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 },
715 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, 715 { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c },
716 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 }, 716 { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 },
717 { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff }, 717 { ZD_CR43, 0x10 }, { ZD_CR44, 0x33 }, { ZD_CR46, 0xff },
718 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b }, 718 { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b },
719 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 }, 719 { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 },
720 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 }, 720 { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 },
721 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff }, 721 { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff },
722 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 }, 722 { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 },
723 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 }, 723 { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 },
724 { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 }, 724 { ZD_CR79, 0xf0 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 },
725 { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 }, 725 { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 },
726 { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 }, 726 { ZD_CR85, 0x00 }, { ZD_CR86, 0x0c }, { ZD_CR87, 0x12 },
727 { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 }, 727 { ZD_CR88, 0x0c }, { ZD_CR89, 0x00 }, { ZD_CR90, 0x58 },
728 { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 }, 728 { ZD_CR91, 0x04 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x00 },
729 { CR94, 0x01 }, 729 { ZD_CR94, 0x01 },
730 { CR95, 0x20 }, /* ZD1211B */ 730 { ZD_CR95, 0x20 }, /* ZD1211B */
731 { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 }, 731 { ZD_CR96, 0x50 }, { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 },
732 { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 }, 732 { ZD_CR99, 0x00 }, { ZD_CR100, 0x01 }, { ZD_CR101, 0x13 },
733 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 }, 733 { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 },
734 { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 }, 734 { ZD_CR105, 0x12 }, { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 },
735 { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 }, 735 { ZD_CR108, 0x0a }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 },
736 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, 736 { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 },
737 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, 737 { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 },
738 { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e }, 738 { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x1e },
739 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 }, 739 { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 },
740 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 740 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
741 { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 }, 741 { ZD_CR131, 0x0c }, { ZD_CR136, 0xdf }, { ZD_CR137, 0xa0 },
742 { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 }, 742 { ZD_CR138, 0xa8 }, { ZD_CR139, 0xb4 }, { ZD_CR140, 0x98 },
743 { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c }, 743 { ZD_CR141, 0x82 }, { ZD_CR142, 0x53 }, { ZD_CR143, 0x1c },
744 { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 }, 744 { ZD_CR144, 0x6c }, { ZD_CR147, 0x07 }, { ZD_CR148, 0x40 },
745 { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */ 745 { ZD_CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
746 { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */ 746 { ZD_CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
747 { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe }, 747 { ZD_CR151, 0x18 }, { ZD_CR159, 0x70 }, { ZD_CR160, 0xfe },
748 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa }, 748 { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa },
749 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe }, 749 { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe },
750 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba }, 750 { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba },
751 { CR170, 0xba }, { CR171, 0xba }, 751 { ZD_CR170, 0xba }, { ZD_CR171, 0xba },
752 /* Note: CR204 must lead the CR203 */ 752 /* Note: ZD_CR204 must lead the ZD_CR203 */
753 { CR204, 0x7d }, 753 { ZD_CR204, 0x7d },
754 {}, 754 {},
755 { CR203, 0x30 }, 755 { ZD_CR203, 0x30 },
756 }; 756 };
757 757
758 int r, t; 758 int r, t;
@@ -1200,24 +1200,24 @@ out:
1200static int update_pwr_int(struct zd_chip *chip, u8 channel) 1200static int update_pwr_int(struct zd_chip *chip, u8 channel)
1201{ 1201{
1202 u8 value = chip->pwr_int_values[channel - 1]; 1202 u8 value = chip->pwr_int_values[channel - 1];
1203 return zd_iowrite16_locked(chip, value, CR31); 1203 return zd_iowrite16_locked(chip, value, ZD_CR31);
1204} 1204}
1205 1205
1206static int update_pwr_cal(struct zd_chip *chip, u8 channel) 1206static int update_pwr_cal(struct zd_chip *chip, u8 channel)
1207{ 1207{
1208 u8 value = chip->pwr_cal_values[channel-1]; 1208 u8 value = chip->pwr_cal_values[channel-1];
1209 return zd_iowrite16_locked(chip, value, CR68); 1209 return zd_iowrite16_locked(chip, value, ZD_CR68);
1210} 1210}
1211 1211
1212static int update_ofdm_cal(struct zd_chip *chip, u8 channel) 1212static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
1213{ 1213{
1214 struct zd_ioreq16 ioreqs[3]; 1214 struct zd_ioreq16 ioreqs[3];
1215 1215
1216 ioreqs[0].addr = CR67; 1216 ioreqs[0].addr = ZD_CR67;
1217 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; 1217 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
1218 ioreqs[1].addr = CR66; 1218 ioreqs[1].addr = ZD_CR66;
1219 ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1]; 1219 ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
1220 ioreqs[2].addr = CR65; 1220 ioreqs[2].addr = ZD_CR65;
1221 ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1]; 1221 ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
1222 1222
1223 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 1223 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -1236,9 +1236,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
1236 return r; 1236 return r;
1237 if (zd_chip_is_zd1211b(chip)) { 1237 if (zd_chip_is_zd1211b(chip)) {
1238 static const struct zd_ioreq16 ioreqs[] = { 1238 static const struct zd_ioreq16 ioreqs[] = {
1239 { CR69, 0x28 }, 1239 { ZD_CR69, 0x28 },
1240 {}, 1240 {},
1241 { CR69, 0x2a }, 1241 { ZD_CR69, 0x2a },
1242 }; 1242 };
1243 1243
1244 r = update_ofdm_cal(chip, channel); 1244 r = update_ofdm_cal(chip, channel);
@@ -1269,7 +1269,7 @@ static int patch_cck_gain(struct zd_chip *chip)
1269 if (r) 1269 if (r)
1270 return r; 1270 return r;
1271 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); 1271 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
1272 return zd_iowrite16_locked(chip, value & 0xff, CR47); 1272 return zd_iowrite16_locked(chip, value & 0xff, ZD_CR47);
1273} 1273}
1274 1274
1275int zd_chip_set_channel(struct zd_chip *chip, u8 channel) 1275int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
@@ -1505,9 +1505,9 @@ int zd_rfwritev_locked(struct zd_chip *chip,
1505int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value) 1505int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
1506{ 1506{
1507 const struct zd_ioreq16 ioreqs[] = { 1507 const struct zd_ioreq16 ioreqs[] = {
1508 { CR244, (value >> 16) & 0xff }, 1508 { ZD_CR244, (value >> 16) & 0xff },
1509 { CR243, (value >> 8) & 0xff }, 1509 { ZD_CR243, (value >> 8) & 0xff },
1510 { CR242, value & 0xff }, 1510 { ZD_CR242, value & 0xff },
1511 }; 1511 };
1512 ZD_ASSERT(mutex_is_locked(&chip->mutex)); 1512 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1513 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 1513 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 14e4402a6111..4be7c3b5b265 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -61,277 +61,288 @@ enum {
61#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset))) 61#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset)))
62 62
63/* 8-bit hardware registers */ 63/* 8-bit hardware registers */
64#define CR0 CTL_REG(0x0000) 64#define ZD_CR0 CTL_REG(0x0000)
65#define CR1 CTL_REG(0x0004) 65#define ZD_CR1 CTL_REG(0x0004)
66#define CR2 CTL_REG(0x0008) 66#define ZD_CR2 CTL_REG(0x0008)
67#define CR3 CTL_REG(0x000C) 67#define ZD_CR3 CTL_REG(0x000C)
68 68
69#define CR5 CTL_REG(0x0010) 69#define ZD_CR5 CTL_REG(0x0010)
70/* bit 5: if set short preamble used 70/* bit 5: if set short preamble used
71 * bit 6: filter band - Japan channel 14 on, else off 71 * bit 6: filter band - Japan channel 14 on, else off
72 */ 72 */
73#define CR6 CTL_REG(0x0014) 73#define ZD_CR6 CTL_REG(0x0014)
74#define CR7 CTL_REG(0x0018) 74#define ZD_CR7 CTL_REG(0x0018)
75#define CR8 CTL_REG(0x001C) 75#define ZD_CR8 CTL_REG(0x001C)
76 76
77#define CR4 CTL_REG(0x0020) 77#define ZD_CR4 CTL_REG(0x0020)
78 78
79#define CR9 CTL_REG(0x0024) 79#define ZD_CR9 CTL_REG(0x0024)
80/* bit 2: antenna switch (together with CR10) */ 80/* bit 2: antenna switch (together with ZD_CR10) */
81#define CR10 CTL_REG(0x0028) 81#define ZD_CR10 CTL_REG(0x0028)
82/* bit 1: antenna switch (together with CR9) 82/* bit 1: antenna switch (together with ZD_CR9)
83 * RF2959 controls with CR11 radion on and off 83 * RF2959 controls with ZD_CR11 radion on and off
84 */ 84 */
85#define CR11 CTL_REG(0x002C) 85#define ZD_CR11 CTL_REG(0x002C)
86/* bit 6: TX power control for OFDM 86/* bit 6: TX power control for OFDM
87 * RF2959 controls with CR10 radio on and off 87 * RF2959 controls with ZD_CR10 radio on and off
88 */ 88 */
89#define CR12 CTL_REG(0x0030) 89#define ZD_CR12 CTL_REG(0x0030)
90#define CR13 CTL_REG(0x0034) 90#define ZD_CR13 CTL_REG(0x0034)
91#define CR14 CTL_REG(0x0038) 91#define ZD_CR14 CTL_REG(0x0038)
92#define CR15 CTL_REG(0x003C) 92#define ZD_CR15 CTL_REG(0x003C)
93#define CR16 CTL_REG(0x0040) 93#define ZD_CR16 CTL_REG(0x0040)
94#define CR17 CTL_REG(0x0044) 94#define ZD_CR17 CTL_REG(0x0044)
95#define CR18 CTL_REG(0x0048) 95#define ZD_CR18 CTL_REG(0x0048)
96#define CR19 CTL_REG(0x004C) 96#define ZD_CR19 CTL_REG(0x004C)
97#define CR20 CTL_REG(0x0050) 97#define ZD_CR20 CTL_REG(0x0050)
98#define CR21 CTL_REG(0x0054) 98#define ZD_CR21 CTL_REG(0x0054)
99#define CR22 CTL_REG(0x0058) 99#define ZD_CR22 CTL_REG(0x0058)
100#define CR23 CTL_REG(0x005C) 100#define ZD_CR23 CTL_REG(0x005C)
101#define CR24 CTL_REG(0x0060) /* CCA threshold */ 101#define ZD_CR24 CTL_REG(0x0060) /* CCA threshold */
102#define CR25 CTL_REG(0x0064) 102#define ZD_CR25 CTL_REG(0x0064)
103#define CR26 CTL_REG(0x0068) 103#define ZD_CR26 CTL_REG(0x0068)
104#define CR27 CTL_REG(0x006C) 104#define ZD_CR27 CTL_REG(0x006C)
105#define CR28 CTL_REG(0x0070) 105#define ZD_CR28 CTL_REG(0x0070)
106#define CR29 CTL_REG(0x0074) 106#define ZD_CR29 CTL_REG(0x0074)
107#define CR30 CTL_REG(0x0078) 107#define ZD_CR30 CTL_REG(0x0078)
108#define CR31 CTL_REG(0x007C) /* TX power control for RF in CCK mode */ 108#define ZD_CR31 CTL_REG(0x007C) /* TX power control for RF in
109#define CR32 CTL_REG(0x0080) 109 * CCK mode
110#define CR33 CTL_REG(0x0084) 110 */
111#define CR34 CTL_REG(0x0088) 111#define ZD_CR32 CTL_REG(0x0080)
112#define CR35 CTL_REG(0x008C) 112#define ZD_CR33 CTL_REG(0x0084)
113#define CR36 CTL_REG(0x0090) 113#define ZD_CR34 CTL_REG(0x0088)
114#define CR37 CTL_REG(0x0094) 114#define ZD_CR35 CTL_REG(0x008C)
115#define CR38 CTL_REG(0x0098) 115#define ZD_CR36 CTL_REG(0x0090)
116#define CR39 CTL_REG(0x009C) 116#define ZD_CR37 CTL_REG(0x0094)
117#define CR40 CTL_REG(0x00A0) 117#define ZD_CR38 CTL_REG(0x0098)
118#define CR41 CTL_REG(0x00A4) 118#define ZD_CR39 CTL_REG(0x009C)
119#define CR42 CTL_REG(0x00A8) 119#define ZD_CR40 CTL_REG(0x00A0)
120#define CR43 CTL_REG(0x00AC) 120#define ZD_CR41 CTL_REG(0x00A4)
121#define CR44 CTL_REG(0x00B0) 121#define ZD_CR42 CTL_REG(0x00A8)
122#define CR45 CTL_REG(0x00B4) 122#define ZD_CR43 CTL_REG(0x00AC)
123#define CR46 CTL_REG(0x00B8) 123#define ZD_CR44 CTL_REG(0x00B0)
124#define CR47 CTL_REG(0x00BC) /* CCK baseband gain 124#define ZD_CR45 CTL_REG(0x00B4)
125 * (patch value might be in EEPROM) 125#define ZD_CR46 CTL_REG(0x00B8)
126 */ 126#define ZD_CR47 CTL_REG(0x00BC) /* CCK baseband gain
127#define CR48 CTL_REG(0x00C0) 127 * (patch value might be in EEPROM)
128#define CR49 CTL_REG(0x00C4) 128 */
129#define CR50 CTL_REG(0x00C8) 129#define ZD_CR48 CTL_REG(0x00C0)
130#define CR51 CTL_REG(0x00CC) /* TX power control for RF in 6-36M modes */ 130#define ZD_CR49 CTL_REG(0x00C4)
131#define CR52 CTL_REG(0x00D0) /* TX power control for RF in 48M mode */ 131#define ZD_CR50 CTL_REG(0x00C8)
132#define CR53 CTL_REG(0x00D4) /* TX power control for RF in 54M mode */ 132#define ZD_CR51 CTL_REG(0x00CC) /* TX power control for RF in
133#define CR54 CTL_REG(0x00D8) 133 * 6-36M modes
134#define CR55 CTL_REG(0x00DC) 134 */
135#define CR56 CTL_REG(0x00E0) 135#define ZD_CR52 CTL_REG(0x00D0) /* TX power control for RF in
136#define CR57 CTL_REG(0x00E4) 136 * 48M mode
137#define CR58 CTL_REG(0x00E8) 137 */
138#define CR59 CTL_REG(0x00EC) 138#define ZD_CR53 CTL_REG(0x00D4) /* TX power control for RF in
139#define CR60 CTL_REG(0x00F0) 139 * 54M mode
140#define CR61 CTL_REG(0x00F4) 140 */
141#define CR62 CTL_REG(0x00F8) 141#define ZD_CR54 CTL_REG(0x00D8)
142#define CR63 CTL_REG(0x00FC) 142#define ZD_CR55 CTL_REG(0x00DC)
143#define CR64 CTL_REG(0x0100) 143#define ZD_CR56 CTL_REG(0x00E0)
144#define CR65 CTL_REG(0x0104) /* OFDM 54M calibration */ 144#define ZD_CR57 CTL_REG(0x00E4)
145#define CR66 CTL_REG(0x0108) /* OFDM 48M calibration */ 145#define ZD_CR58 CTL_REG(0x00E8)
146#define CR67 CTL_REG(0x010C) /* OFDM 36M calibration */ 146#define ZD_CR59 CTL_REG(0x00EC)
147#define CR68 CTL_REG(0x0110) /* CCK calibration */ 147#define ZD_CR60 CTL_REG(0x00F0)
148#define CR69 CTL_REG(0x0114) 148#define ZD_CR61 CTL_REG(0x00F4)
149#define CR70 CTL_REG(0x0118) 149#define ZD_CR62 CTL_REG(0x00F8)
150#define CR71 CTL_REG(0x011C) 150#define ZD_CR63 CTL_REG(0x00FC)
151#define CR72 CTL_REG(0x0120) 151#define ZD_CR64 CTL_REG(0x0100)
152#define CR73 CTL_REG(0x0124) 152#define ZD_CR65 CTL_REG(0x0104) /* OFDM 54M calibration */
153#define CR74 CTL_REG(0x0128) 153#define ZD_CR66 CTL_REG(0x0108) /* OFDM 48M calibration */
154#define CR75 CTL_REG(0x012C) 154#define ZD_CR67 CTL_REG(0x010C) /* OFDM 36M calibration */
155#define CR76 CTL_REG(0x0130) 155#define ZD_CR68 CTL_REG(0x0110) /* CCK calibration */
156#define CR77 CTL_REG(0x0134) 156#define ZD_CR69 CTL_REG(0x0114)
157#define CR78 CTL_REG(0x0138) 157#define ZD_CR70 CTL_REG(0x0118)
158#define CR79 CTL_REG(0x013C) 158#define ZD_CR71 CTL_REG(0x011C)
159#define CR80 CTL_REG(0x0140) 159#define ZD_CR72 CTL_REG(0x0120)
160#define CR81 CTL_REG(0x0144) 160#define ZD_CR73 CTL_REG(0x0124)
161#define CR82 CTL_REG(0x0148) 161#define ZD_CR74 CTL_REG(0x0128)
162#define CR83 CTL_REG(0x014C) 162#define ZD_CR75 CTL_REG(0x012C)
163#define CR84 CTL_REG(0x0150) 163#define ZD_CR76 CTL_REG(0x0130)
164#define CR85 CTL_REG(0x0154) 164#define ZD_CR77 CTL_REG(0x0134)
165#define CR86 CTL_REG(0x0158) 165#define ZD_CR78 CTL_REG(0x0138)
166#define CR87 CTL_REG(0x015C) 166#define ZD_CR79 CTL_REG(0x013C)
167#define CR88 CTL_REG(0x0160) 167#define ZD_CR80 CTL_REG(0x0140)
168#define CR89 CTL_REG(0x0164) 168#define ZD_CR81 CTL_REG(0x0144)
169#define CR90 CTL_REG(0x0168) 169#define ZD_CR82 CTL_REG(0x0148)
170#define CR91 CTL_REG(0x016C) 170#define ZD_CR83 CTL_REG(0x014C)
171#define CR92 CTL_REG(0x0170) 171#define ZD_CR84 CTL_REG(0x0150)
172#define CR93 CTL_REG(0x0174) 172#define ZD_CR85 CTL_REG(0x0154)
173#define CR94 CTL_REG(0x0178) 173#define ZD_CR86 CTL_REG(0x0158)
174#define CR95 CTL_REG(0x017C) 174#define ZD_CR87 CTL_REG(0x015C)
175#define CR96 CTL_REG(0x0180) 175#define ZD_CR88 CTL_REG(0x0160)
176#define CR97 CTL_REG(0x0184) 176#define ZD_CR89 CTL_REG(0x0164)
177#define CR98 CTL_REG(0x0188) 177#define ZD_CR90 CTL_REG(0x0168)
178#define CR99 CTL_REG(0x018C) 178#define ZD_CR91 CTL_REG(0x016C)
179#define CR100 CTL_REG(0x0190) 179#define ZD_CR92 CTL_REG(0x0170)
180#define CR101 CTL_REG(0x0194) 180#define ZD_CR93 CTL_REG(0x0174)
181#define CR102 CTL_REG(0x0198) 181#define ZD_CR94 CTL_REG(0x0178)
182#define CR103 CTL_REG(0x019C) 182#define ZD_CR95 CTL_REG(0x017C)
183#define CR104 CTL_REG(0x01A0) 183#define ZD_CR96 CTL_REG(0x0180)
184#define CR105 CTL_REG(0x01A4) 184#define ZD_CR97 CTL_REG(0x0184)
185#define CR106 CTL_REG(0x01A8) 185#define ZD_CR98 CTL_REG(0x0188)
186#define CR107 CTL_REG(0x01AC) 186#define ZD_CR99 CTL_REG(0x018C)
187#define CR108 CTL_REG(0x01B0) 187#define ZD_CR100 CTL_REG(0x0190)
188#define CR109 CTL_REG(0x01B4) 188#define ZD_CR101 CTL_REG(0x0194)
189#define CR110 CTL_REG(0x01B8) 189#define ZD_CR102 CTL_REG(0x0198)
190#define CR111 CTL_REG(0x01BC) 190#define ZD_CR103 CTL_REG(0x019C)
191#define CR112 CTL_REG(0x01C0) 191#define ZD_CR104 CTL_REG(0x01A0)
192#define CR113 CTL_REG(0x01C4) 192#define ZD_CR105 CTL_REG(0x01A4)
193#define CR114 CTL_REG(0x01C8) 193#define ZD_CR106 CTL_REG(0x01A8)
194#define CR115 CTL_REG(0x01CC) 194#define ZD_CR107 CTL_REG(0x01AC)
195#define CR116 CTL_REG(0x01D0) 195#define ZD_CR108 CTL_REG(0x01B0)
196#define CR117 CTL_REG(0x01D4) 196#define ZD_CR109 CTL_REG(0x01B4)
197#define CR118 CTL_REG(0x01D8) 197#define ZD_CR110 CTL_REG(0x01B8)
198#define CR119 CTL_REG(0x01DC) 198#define ZD_CR111 CTL_REG(0x01BC)
199#define CR120 CTL_REG(0x01E0) 199#define ZD_CR112 CTL_REG(0x01C0)
200#define CR121 CTL_REG(0x01E4) 200#define ZD_CR113 CTL_REG(0x01C4)
201#define CR122 CTL_REG(0x01E8) 201#define ZD_CR114 CTL_REG(0x01C8)
202#define CR123 CTL_REG(0x01EC) 202#define ZD_CR115 CTL_REG(0x01CC)
203#define CR124 CTL_REG(0x01F0) 203#define ZD_CR116 CTL_REG(0x01D0)
204#define CR125 CTL_REG(0x01F4) 204#define ZD_CR117 CTL_REG(0x01D4)
205#define CR126 CTL_REG(0x01F8) 205#define ZD_CR118 CTL_REG(0x01D8)
206#define CR127 CTL_REG(0x01FC) 206#define ZD_CR119 CTL_REG(0x01DC)
207#define CR128 CTL_REG(0x0200) 207#define ZD_CR120 CTL_REG(0x01E0)
208#define CR129 CTL_REG(0x0204) 208#define ZD_CR121 CTL_REG(0x01E4)
209#define CR130 CTL_REG(0x0208) 209#define ZD_CR122 CTL_REG(0x01E8)
210#define CR131 CTL_REG(0x020C) 210#define ZD_CR123 CTL_REG(0x01EC)
211#define CR132 CTL_REG(0x0210) 211#define ZD_CR124 CTL_REG(0x01F0)
212#define CR133 CTL_REG(0x0214) 212#define ZD_CR125 CTL_REG(0x01F4)
213#define CR134 CTL_REG(0x0218) 213#define ZD_CR126 CTL_REG(0x01F8)
214#define CR135 CTL_REG(0x021C) 214#define ZD_CR127 CTL_REG(0x01FC)
215#define CR136 CTL_REG(0x0220) 215#define ZD_CR128 CTL_REG(0x0200)
216#define CR137 CTL_REG(0x0224) 216#define ZD_CR129 CTL_REG(0x0204)
217#define CR138 CTL_REG(0x0228) 217#define ZD_CR130 CTL_REG(0x0208)
218#define CR139 CTL_REG(0x022C) 218#define ZD_CR131 CTL_REG(0x020C)
219#define CR140 CTL_REG(0x0230) 219#define ZD_CR132 CTL_REG(0x0210)
220#define CR141 CTL_REG(0x0234) 220#define ZD_CR133 CTL_REG(0x0214)
221#define CR142 CTL_REG(0x0238) 221#define ZD_CR134 CTL_REG(0x0218)
222#define CR143 CTL_REG(0x023C) 222#define ZD_CR135 CTL_REG(0x021C)
223#define CR144 CTL_REG(0x0240) 223#define ZD_CR136 CTL_REG(0x0220)
224#define CR145 CTL_REG(0x0244) 224#define ZD_CR137 CTL_REG(0x0224)
225#define CR146 CTL_REG(0x0248) 225#define ZD_CR138 CTL_REG(0x0228)
226#define CR147 CTL_REG(0x024C) 226#define ZD_CR139 CTL_REG(0x022C)
227#define CR148 CTL_REG(0x0250) 227#define ZD_CR140 CTL_REG(0x0230)
228#define CR149 CTL_REG(0x0254) 228#define ZD_CR141 CTL_REG(0x0234)
229#define CR150 CTL_REG(0x0258) 229#define ZD_CR142 CTL_REG(0x0238)
230#define CR151 CTL_REG(0x025C) 230#define ZD_CR143 CTL_REG(0x023C)
231#define CR152 CTL_REG(0x0260) 231#define ZD_CR144 CTL_REG(0x0240)
232#define CR153 CTL_REG(0x0264) 232#define ZD_CR145 CTL_REG(0x0244)
233#define CR154 CTL_REG(0x0268) 233#define ZD_CR146 CTL_REG(0x0248)
234#define CR155 CTL_REG(0x026C) 234#define ZD_CR147 CTL_REG(0x024C)
235#define CR156 CTL_REG(0x0270) 235#define ZD_CR148 CTL_REG(0x0250)
236#define CR157 CTL_REG(0x0274) 236#define ZD_CR149 CTL_REG(0x0254)
237#define CR158 CTL_REG(0x0278) 237#define ZD_CR150 CTL_REG(0x0258)
238#define CR159 CTL_REG(0x027C) 238#define ZD_CR151 CTL_REG(0x025C)
239#define CR160 CTL_REG(0x0280) 239#define ZD_CR152 CTL_REG(0x0260)
240#define CR161 CTL_REG(0x0284) 240#define ZD_CR153 CTL_REG(0x0264)
241#define CR162 CTL_REG(0x0288) 241#define ZD_CR154 CTL_REG(0x0268)
242#define CR163 CTL_REG(0x028C) 242#define ZD_CR155 CTL_REG(0x026C)
243#define CR164 CTL_REG(0x0290) 243#define ZD_CR156 CTL_REG(0x0270)
244#define CR165 CTL_REG(0x0294) 244#define ZD_CR157 CTL_REG(0x0274)
245#define CR166 CTL_REG(0x0298) 245#define ZD_CR158 CTL_REG(0x0278)
246#define CR167 CTL_REG(0x029C) 246#define ZD_CR159 CTL_REG(0x027C)
247#define CR168 CTL_REG(0x02A0) 247#define ZD_CR160 CTL_REG(0x0280)
248#define CR169 CTL_REG(0x02A4) 248#define ZD_CR161 CTL_REG(0x0284)
249#define CR170 CTL_REG(0x02A8) 249#define ZD_CR162 CTL_REG(0x0288)
250#define CR171 CTL_REG(0x02AC) 250#define ZD_CR163 CTL_REG(0x028C)
251#define CR172 CTL_REG(0x02B0) 251#define ZD_CR164 CTL_REG(0x0290)
252#define CR173 CTL_REG(0x02B4) 252#define ZD_CR165 CTL_REG(0x0294)
253#define CR174 CTL_REG(0x02B8) 253#define ZD_CR166 CTL_REG(0x0298)
254#define CR175 CTL_REG(0x02BC) 254#define ZD_CR167 CTL_REG(0x029C)
255#define CR176 CTL_REG(0x02C0) 255#define ZD_CR168 CTL_REG(0x02A0)
256#define CR177 CTL_REG(0x02C4) 256#define ZD_CR169 CTL_REG(0x02A4)
257#define CR178 CTL_REG(0x02C8) 257#define ZD_CR170 CTL_REG(0x02A8)
258#define CR179 CTL_REG(0x02CC) 258#define ZD_CR171 CTL_REG(0x02AC)
259#define CR180 CTL_REG(0x02D0) 259#define ZD_CR172 CTL_REG(0x02B0)
260#define CR181 CTL_REG(0x02D4) 260#define ZD_CR173 CTL_REG(0x02B4)
261#define CR182 CTL_REG(0x02D8) 261#define ZD_CR174 CTL_REG(0x02B8)
262#define CR183 CTL_REG(0x02DC) 262#define ZD_CR175 CTL_REG(0x02BC)
263#define CR184 CTL_REG(0x02E0) 263#define ZD_CR176 CTL_REG(0x02C0)
264#define CR185 CTL_REG(0x02E4) 264#define ZD_CR177 CTL_REG(0x02C4)
265#define CR186 CTL_REG(0x02E8) 265#define ZD_CR178 CTL_REG(0x02C8)
266#define CR187 CTL_REG(0x02EC) 266#define ZD_CR179 CTL_REG(0x02CC)
267#define CR188 CTL_REG(0x02F0) 267#define ZD_CR180 CTL_REG(0x02D0)
268#define CR189 CTL_REG(0x02F4) 268#define ZD_CR181 CTL_REG(0x02D4)
269#define CR190 CTL_REG(0x02F8) 269#define ZD_CR182 CTL_REG(0x02D8)
270#define CR191 CTL_REG(0x02FC) 270#define ZD_CR183 CTL_REG(0x02DC)
271#define CR192 CTL_REG(0x0300) 271#define ZD_CR184 CTL_REG(0x02E0)
272#define CR193 CTL_REG(0x0304) 272#define ZD_CR185 CTL_REG(0x02E4)
273#define CR194 CTL_REG(0x0308) 273#define ZD_CR186 CTL_REG(0x02E8)
274#define CR195 CTL_REG(0x030C) 274#define ZD_CR187 CTL_REG(0x02EC)
275#define CR196 CTL_REG(0x0310) 275#define ZD_CR188 CTL_REG(0x02F0)
276#define CR197 CTL_REG(0x0314) 276#define ZD_CR189 CTL_REG(0x02F4)
277#define CR198 CTL_REG(0x0318) 277#define ZD_CR190 CTL_REG(0x02F8)
278#define CR199 CTL_REG(0x031C) 278#define ZD_CR191 CTL_REG(0x02FC)
279#define CR200 CTL_REG(0x0320) 279#define ZD_CR192 CTL_REG(0x0300)
280#define CR201 CTL_REG(0x0324) 280#define ZD_CR193 CTL_REG(0x0304)
281#define CR202 CTL_REG(0x0328) 281#define ZD_CR194 CTL_REG(0x0308)
282#define CR203 CTL_REG(0x032C) /* I2C bus template value & flash control */ 282#define ZD_CR195 CTL_REG(0x030C)
283#define CR204 CTL_REG(0x0330) 283#define ZD_CR196 CTL_REG(0x0310)
284#define CR205 CTL_REG(0x0334) 284#define ZD_CR197 CTL_REG(0x0314)
285#define CR206 CTL_REG(0x0338) 285#define ZD_CR198 CTL_REG(0x0318)
286#define CR207 CTL_REG(0x033C) 286#define ZD_CR199 CTL_REG(0x031C)
287#define CR208 CTL_REG(0x0340) 287#define ZD_CR200 CTL_REG(0x0320)
288#define CR209 CTL_REG(0x0344) 288#define ZD_CR201 CTL_REG(0x0324)
289#define CR210 CTL_REG(0x0348) 289#define ZD_CR202 CTL_REG(0x0328)
290#define CR211 CTL_REG(0x034C) 290#define ZD_CR203 CTL_REG(0x032C) /* I2C bus template value & flash
291#define CR212 CTL_REG(0x0350) 291 * control
292#define CR213 CTL_REG(0x0354) 292 */
293#define CR214 CTL_REG(0x0358) 293#define ZD_CR204 CTL_REG(0x0330)
294#define CR215 CTL_REG(0x035C) 294#define ZD_CR205 CTL_REG(0x0334)
295#define CR216 CTL_REG(0x0360) 295#define ZD_CR206 CTL_REG(0x0338)
296#define CR217 CTL_REG(0x0364) 296#define ZD_CR207 CTL_REG(0x033C)
297#define CR218 CTL_REG(0x0368) 297#define ZD_CR208 CTL_REG(0x0340)
298#define CR219 CTL_REG(0x036C) 298#define ZD_CR209 CTL_REG(0x0344)
299#define CR220 CTL_REG(0x0370) 299#define ZD_CR210 CTL_REG(0x0348)
300#define CR221 CTL_REG(0x0374) 300#define ZD_CR211 CTL_REG(0x034C)
301#define CR222 CTL_REG(0x0378) 301#define ZD_CR212 CTL_REG(0x0350)
302#define CR223 CTL_REG(0x037C) 302#define ZD_CR213 CTL_REG(0x0354)
303#define CR224 CTL_REG(0x0380) 303#define ZD_CR214 CTL_REG(0x0358)
304#define CR225 CTL_REG(0x0384) 304#define ZD_CR215 CTL_REG(0x035C)
305#define CR226 CTL_REG(0x0388) 305#define ZD_CR216 CTL_REG(0x0360)
306#define CR227 CTL_REG(0x038C) 306#define ZD_CR217 CTL_REG(0x0364)
307#define CR228 CTL_REG(0x0390) 307#define ZD_CR218 CTL_REG(0x0368)
308#define CR229 CTL_REG(0x0394) 308#define ZD_CR219 CTL_REG(0x036C)
309#define CR230 CTL_REG(0x0398) 309#define ZD_CR220 CTL_REG(0x0370)
310#define CR231 CTL_REG(0x039C) 310#define ZD_CR221 CTL_REG(0x0374)
311#define CR232 CTL_REG(0x03A0) 311#define ZD_CR222 CTL_REG(0x0378)
312#define CR233 CTL_REG(0x03A4) 312#define ZD_CR223 CTL_REG(0x037C)
313#define CR234 CTL_REG(0x03A8) 313#define ZD_CR224 CTL_REG(0x0380)
314#define CR235 CTL_REG(0x03AC) 314#define ZD_CR225 CTL_REG(0x0384)
315#define CR236 CTL_REG(0x03B0) 315#define ZD_CR226 CTL_REG(0x0388)
316 316#define ZD_CR227 CTL_REG(0x038C)
317#define CR240 CTL_REG(0x03C0) 317#define ZD_CR228 CTL_REG(0x0390)
318/* bit 7: host-controlled RF register writes 318#define ZD_CR229 CTL_REG(0x0394)
319 * CR241-CR245: for hardware controlled writing of RF bits, not needed for 319#define ZD_CR230 CTL_REG(0x0398)
320 * USB 320#define ZD_CR231 CTL_REG(0x039C)
321#define ZD_CR232 CTL_REG(0x03A0)
322#define ZD_CR233 CTL_REG(0x03A4)
323#define ZD_CR234 CTL_REG(0x03A8)
324#define ZD_CR235 CTL_REG(0x03AC)
325#define ZD_CR236 CTL_REG(0x03B0)
326
327#define ZD_CR240 CTL_REG(0x03C0)
328/* bit 7: host-controlled RF register writes
329 * ZD_CR241-ZD_CR245: for hardware controlled writing of RF bits, not needed for
330 * USB
321 */ 331 */
322#define CR241 CTL_REG(0x03C4) 332#define ZD_CR241 CTL_REG(0x03C4)
323#define CR242 CTL_REG(0x03C8) 333#define ZD_CR242 CTL_REG(0x03C8)
324#define CR243 CTL_REG(0x03CC) 334#define ZD_CR243 CTL_REG(0x03CC)
325#define CR244 CTL_REG(0x03D0) 335#define ZD_CR244 CTL_REG(0x03D0)
326#define CR245 CTL_REG(0x03D4) 336#define ZD_CR245 CTL_REG(0x03D4)
327 337
328#define CR251 CTL_REG(0x03EC) /* only used for activation and deactivation of 338#define ZD_CR251 CTL_REG(0x03EC) /* only used for activation and
329 * Airoha RFs AL2230 and AL7230B 339 * deactivation of Airoha RFs AL2230
330 */ 340 * and AL7230B
331#define CR252 CTL_REG(0x03F0) 341 */
332#define CR253 CTL_REG(0x03F4) 342#define ZD_CR252 CTL_REG(0x03F0)
333#define CR254 CTL_REG(0x03F8) 343#define ZD_CR253 CTL_REG(0x03F4)
334#define CR255 CTL_REG(0x03FC) 344#define ZD_CR254 CTL_REG(0x03F8)
345#define ZD_CR255 CTL_REG(0x03FC)
335 346
336#define CR_MAX_PHY_REG 255 347#define CR_MAX_PHY_REG 255
337 348
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index 79dc1035592d..725b7c99b23d 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -55,7 +55,7 @@ struct zd_rf {
55 * defaults to 1 (yes) */ 55 * defaults to 1 (yes) */
56 u8 update_channel_int:1; 56 u8 update_channel_int:1;
57 57
58 /* whether CR47 should be patched from the EEPROM, if the appropriate 58 /* whether ZD_CR47 should be patched from the EEPROM, if the appropriate
59 * flag is set in the POD. The vendor driver suggests that this should 59 * flag is set in the POD. The vendor driver suggests that this should
60 * be done for all RF's, but a bug in their code prevents but their 60 * be done for all RF's, but a bug in their code prevents but their
61 * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */ 61 * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 74a8f7a55591..12babcb633c3 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -61,31 +61,31 @@ static const u32 zd1211b_al2230_table[][3] = {
61}; 61};
62 62
63static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = { 63static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
64 { CR240, 0x57 }, { CR9, 0xe0 }, 64 { ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 },
65}; 65};
66 66
67static const struct zd_ioreq16 ioreqs_init_al2230s[] = { 67static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
68 { CR47, 0x1e }, /* MARK_002 */ 68 { ZD_CR47, 0x1e }, /* MARK_002 */
69 { CR106, 0x22 }, 69 { ZD_CR106, 0x22 },
70 { CR107, 0x2a }, /* MARK_002 */ 70 { ZD_CR107, 0x2a }, /* MARK_002 */
71 { CR109, 0x13 }, /* MARK_002 */ 71 { ZD_CR109, 0x13 }, /* MARK_002 */
72 { CR118, 0xf8 }, /* MARK_002 */ 72 { ZD_CR118, 0xf8 }, /* MARK_002 */
73 { CR119, 0x12 }, { CR122, 0xe0 }, 73 { ZD_CR119, 0x12 }, { ZD_CR122, 0xe0 },
74 { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */ 74 { ZD_CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
75 { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */ 75 { ZD_CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
76 { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */ 76 { ZD_CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
77}; 77};
78 78
79static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) 79static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
80{ 80{
81 int r; 81 int r;
82 static const struct zd_ioreq16 ioreqs[] = { 82 static const struct zd_ioreq16 ioreqs[] = {
83 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, 83 { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
84 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, 84 { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
85 { CR203, 0x06 }, 85 { ZD_CR203, 0x06 },
86 { }, 86 { },
87 87
88 { CR240, 0x80 }, 88 { ZD_CR240, 0x80 },
89 }; 89 };
90 90
91 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 91 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -94,12 +94,12 @@ static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
94 94
95 /* related to antenna selection? */ 95 /* related to antenna selection? */
96 if (chip->new_phy_layout) { 96 if (chip->new_phy_layout) {
97 r = zd_iowrite16_locked(chip, 0xe1, CR9); 97 r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9);
98 if (r) 98 if (r)
99 return r; 99 return r;
100 } 100 }
101 101
102 return zd_iowrite16_locked(chip, 0x06, CR203); 102 return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
103} 103}
104 104
105static int zd1211_al2230_init_hw(struct zd_rf *rf) 105static int zd1211_al2230_init_hw(struct zd_rf *rf)
@@ -108,40 +108,40 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
108 struct zd_chip *chip = zd_rf_to_chip(rf); 108 struct zd_chip *chip = zd_rf_to_chip(rf);
109 109
110 static const struct zd_ioreq16 ioreqs_init[] = { 110 static const struct zd_ioreq16 ioreqs_init[] = {
111 { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 }, 111 { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 },
112 { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 }, 112 { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
113 { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a }, 113 { ZD_CR44, 0x33 }, { ZD_CR106, 0x2a }, { ZD_CR107, 0x1a },
114 { CR109, 0x09 }, { CR110, 0x27 }, { CR111, 0x2b }, 114 { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, { ZD_CR111, 0x2b },
115 { CR112, 0x2b }, { CR119, 0x0a }, { CR10, 0x89 }, 115 { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, { ZD_CR10, 0x89 },
116 /* for newest (3rd cut) AL2300 */ 116 /* for newest (3rd cut) AL2300 */
117 { CR17, 0x28 }, 117 { ZD_CR17, 0x28 },
118 { CR26, 0x93 }, { CR34, 0x30 }, 118 { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
119 /* for newest (3rd cut) AL2300 */ 119 /* for newest (3rd cut) AL2300 */
120 { CR35, 0x3e }, 120 { ZD_CR35, 0x3e },
121 { CR41, 0x24 }, { CR44, 0x32 }, 121 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
122 /* for newest (3rd cut) AL2300 */ 122 /* for newest (3rd cut) AL2300 */
123 { CR46, 0x96 }, 123 { ZD_CR46, 0x96 },
124 { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 }, 124 { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
125 { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, 125 { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
126 { CR92, 0x0a }, { CR99, 0x28 }, { CR100, 0x00 }, 126 { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 },
127 { CR101, 0x13 }, { CR102, 0x27 }, { CR106, 0x24 }, 127 { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR106, 0x24 },
128 { CR107, 0x2a }, { CR109, 0x09 }, { CR110, 0x13 }, 128 { ZD_CR107, 0x2a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x13 },
129 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, 129 { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
130 { CR114, 0x27 }, 130 { ZD_CR114, 0x27 },
131 /* for newest (3rd cut) AL2300 */ 131 /* for newest (3rd cut) AL2300 */
132 { CR115, 0x24 }, 132 { ZD_CR115, 0x24 },
133 { CR116, 0x24 }, { CR117, 0xf4 }, { CR118, 0xfc }, 133 { ZD_CR116, 0x24 }, { ZD_CR117, 0xf4 }, { ZD_CR118, 0xfc },
134 { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 }, 134 { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, { ZD_CR121, 0x77 },
135 { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff }, 135 { ZD_CR122, 0xe0 }, { ZD_CR137, 0x88 }, { ZD_CR252, 0xff },
136 { CR253, 0xff }, 136 { ZD_CR253, 0xff },
137 }; 137 };
138 138
139 static const struct zd_ioreq16 ioreqs_pll[] = { 139 static const struct zd_ioreq16 ioreqs_pll[] = {
140 /* shdnb(PLL_ON)=0 */ 140 /* shdnb(PLL_ON)=0 */
141 { CR251, 0x2f }, 141 { ZD_CR251, 0x2f },
142 /* shdnb(PLL_ON)=1 */ 142 /* shdnb(PLL_ON)=1 */
143 { CR251, 0x3f }, 143 { ZD_CR251, 0x3f },
144 { CR138, 0x28 }, { CR203, 0x06 }, 144 { ZD_CR138, 0x28 }, { ZD_CR203, 0x06 },
145 }; 145 };
146 146
147 static const u32 rv1[] = { 147 static const u32 rv1[] = {
@@ -161,7 +161,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
161 0x0805b6, 161 0x0805b6,
162 0x011687, 162 0x011687,
163 0x000688, 163 0x000688,
164 0x0403b9, /* external control TX power (CR31) */ 164 0x0403b9, /* external control TX power (ZD_CR31) */
165 0x00dbba, 165 0x00dbba,
166 0x00099b, 166 0x00099b,
167 0x0bdffc, 167 0x0bdffc,
@@ -221,52 +221,54 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
221 struct zd_chip *chip = zd_rf_to_chip(rf); 221 struct zd_chip *chip = zd_rf_to_chip(rf);
222 222
223 static const struct zd_ioreq16 ioreqs1[] = { 223 static const struct zd_ioreq16 ioreqs1[] = {
224 { CR10, 0x89 }, { CR15, 0x20 }, 224 { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
225 { CR17, 0x2B }, /* for newest(3rd cut) AL2230 */ 225 { ZD_CR17, 0x2B }, /* for newest(3rd cut) AL2230 */
226 { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 }, 226 { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
227 { CR28, 0x3e }, { CR29, 0x00 }, 227 { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
228 { CR33, 0x28 }, /* 5621 */ 228 { ZD_CR33, 0x28 }, /* 5621 */
229 { CR34, 0x30 }, 229 { ZD_CR34, 0x30 },
230 { CR35, 0x3e }, /* for newest(3rd cut) AL2230 */ 230 { ZD_CR35, 0x3e }, /* for newest(3rd cut) AL2230 */
231 { CR41, 0x24 }, { CR44, 0x32 }, 231 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
232 { CR46, 0x99 }, /* for newest(3rd cut) AL2230 */ 232 { ZD_CR46, 0x99 }, /* for newest(3rd cut) AL2230 */
233 { CR47, 0x1e }, 233 { ZD_CR47, 0x1e },
234 234
235 /* ZD1211B 05.06.10 */ 235 /* ZD1211B 05.06.10 */
236 { CR48, 0x06 }, { CR49, 0xf9 }, { CR51, 0x01 }, 236 { ZD_CR48, 0x06 }, { ZD_CR49, 0xf9 }, { ZD_CR51, 0x01 },
237 { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 }, 237 { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 },
238 { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 }, 238 { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 },
239 { CR69, 0x28 }, 239 { ZD_CR69, 0x28 },
240 240
241 { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, 241 { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
242 { CR87, 0x0a }, { CR89, 0x04 }, 242 { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
243 { CR91, 0x00 }, /* 5621 */ 243 { ZD_CR91, 0x00 }, /* 5621 */
244 { CR92, 0x0a }, 244 { ZD_CR92, 0x0a },
245 { CR98, 0x8d }, /* 4804, for 1212 new algorithm */ 245 { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */
246 { CR99, 0x00 }, /* 5621 */ 246 { ZD_CR99, 0x00 }, /* 5621 */
247 { CR101, 0x13 }, { CR102, 0x27 }, 247 { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
248 { CR106, 0x24 }, /* for newest(3rd cut) AL2230 */ 248 { ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
249 { CR107, 0x2a }, 249 { ZD_CR107, 0x2a },
250 { CR109, 0x13 }, /* 4804, for 1212 new algorithm */ 250 { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
251 { CR110, 0x1f }, /* 4804, for 1212 new algorithm */ 251 { ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */
252 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, 252 { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
253 { CR114, 0x27 }, 253 { ZD_CR114, 0x27 },
254 { CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */ 254 { ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut)
255 { CR116, 0x24 }, 255 * AL2230
256 { CR117, 0xfa }, /* for 1211b */ 256 */
257 { CR118, 0xfa }, /* for 1211b */ 257 { ZD_CR116, 0x24 },
258 { CR119, 0x10 }, 258 { ZD_CR117, 0xfa }, /* for 1211b */
259 { CR120, 0x4f }, 259 { ZD_CR118, 0xfa }, /* for 1211b */
260 { CR121, 0x6c }, /* for 1211b */ 260 { ZD_CR119, 0x10 },
261 { CR122, 0xfc }, /* E0->FC at 4902 */ 261 { ZD_CR120, 0x4f },
262 { CR123, 0x57 }, /* 5623 */ 262 { ZD_CR121, 0x6c }, /* for 1211b */
263 { CR125, 0xad }, /* 4804, for 1212 new algorithm */ 263 { ZD_CR122, 0xfc }, /* E0->FC at 4902 */
264 { CR126, 0x6c }, /* 5614 */ 264 { ZD_CR123, 0x57 }, /* 5623 */
265 { CR127, 0x03 }, /* 4804, for 1212 new algorithm */ 265 { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
266 { CR137, 0x50 }, /* 5614 */ 266 { ZD_CR126, 0x6c }, /* 5614 */
267 { CR138, 0xa8 }, 267 { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
268 { CR144, 0xac }, /* 5621 */ 268 { ZD_CR137, 0x50 }, /* 5614 */
269 { CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 }, 269 { ZD_CR138, 0xa8 },
270 { ZD_CR144, 0xac }, /* 5621 */
271 { ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
270 }; 272 };
271 273
272 static const u32 rv1[] = { 274 static const u32 rv1[] = {
@@ -284,7 +286,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
284 0x6da010, /* Reg6 update for MP versio */ 286 0x6da010, /* Reg6 update for MP versio */
285 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */ 287 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
286 0x116000, 288 0x116000,
287 0x9dc020, /* External control TX power (CR31) */ 289 0x9dc020, /* External control TX power (ZD_CR31) */
288 0x5ddb00, /* RegA update for MP version */ 290 0x5ddb00, /* RegA update for MP version */
289 0xd99000, /* RegB update for MP version */ 291 0xd99000, /* RegB update for MP version */
290 0x3ffbd0, /* RegC update for MP version */ 292 0x3ffbd0, /* RegC update for MP version */
@@ -295,8 +297,8 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
295 }; 297 };
296 298
297 static const struct zd_ioreq16 ioreqs2[] = { 299 static const struct zd_ioreq16 ioreqs2[] = {
298 { CR251, 0x2f }, /* shdnb(PLL_ON)=0 */ 300 { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
299 { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ 301 { ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
300 }; 302 };
301 303
302 static const u32 rv3[] = { 304 static const u32 rv3[] = {
@@ -308,7 +310,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
308 310
309 static const struct zd_ioreq16 ioreqs3[] = { 311 static const struct zd_ioreq16 ioreqs3[] = {
310 /* related to 6M band edge patching, happens unconditionally */ 312 /* related to 6M band edge patching, happens unconditionally */
311 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 313 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
312 }; 314 };
313 315
314 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, 316 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
@@ -361,8 +363,8 @@ static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel)
361 const u32 *rv = zd1211_al2230_table[channel-1]; 363 const u32 *rv = zd1211_al2230_table[channel-1];
362 struct zd_chip *chip = zd_rf_to_chip(rf); 364 struct zd_chip *chip = zd_rf_to_chip(rf);
363 static const struct zd_ioreq16 ioreqs[] = { 365 static const struct zd_ioreq16 ioreqs[] = {
364 { CR138, 0x28 }, 366 { ZD_CR138, 0x28 },
365 { CR203, 0x06 }, 367 { ZD_CR203, 0x06 },
366 }; 368 };
367 369
368 r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS); 370 r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
@@ -393,8 +395,8 @@ static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
393{ 395{
394 struct zd_chip *chip = zd_rf_to_chip(rf); 396 struct zd_chip *chip = zd_rf_to_chip(rf);
395 static const struct zd_ioreq16 ioreqs[] = { 397 static const struct zd_ioreq16 ioreqs[] = {
396 { CR11, 0x00 }, 398 { ZD_CR11, 0x00 },
397 { CR251, 0x3f }, 399 { ZD_CR251, 0x3f },
398 }; 400 };
399 401
400 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 402 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -404,8 +406,8 @@ static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf)
404{ 406{
405 struct zd_chip *chip = zd_rf_to_chip(rf); 407 struct zd_chip *chip = zd_rf_to_chip(rf);
406 static const struct zd_ioreq16 ioreqs[] = { 408 static const struct zd_ioreq16 ioreqs[] = {
407 { CR11, 0x00 }, 409 { ZD_CR11, 0x00 },
408 { CR251, 0x7f }, 410 { ZD_CR251, 0x7f },
409 }; 411 };
410 412
411 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 413 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -415,8 +417,8 @@ static int al2230_switch_radio_off(struct zd_rf *rf)
415{ 417{
416 struct zd_chip *chip = zd_rf_to_chip(rf); 418 struct zd_chip *chip = zd_rf_to_chip(rf);
417 static const struct zd_ioreq16 ioreqs[] = { 419 static const struct zd_ioreq16 ioreqs[] = {
418 { CR11, 0x04 }, 420 { ZD_CR11, 0x04 },
419 { CR251, 0x2f }, 421 { ZD_CR251, 0x2f },
420 }; 422 };
421 423
422 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 424 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index 65095d661e6b..385c670d1293 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -68,19 +68,19 @@ static const u32 rv_init2[] = {
68}; 68};
69 69
70static const struct zd_ioreq16 ioreqs_sw[] = { 70static const struct zd_ioreq16 ioreqs_sw[] = {
71 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 71 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
72 { CR38, 0x38 }, { CR136, 0xdf }, 72 { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
73}; 73};
74 74
75static int zd1211b_al7230b_finalize(struct zd_chip *chip) 75static int zd1211b_al7230b_finalize(struct zd_chip *chip)
76{ 76{
77 int r; 77 int r;
78 static const struct zd_ioreq16 ioreqs[] = { 78 static const struct zd_ioreq16 ioreqs[] = {
79 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, 79 { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
80 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, 80 { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
81 { CR203, 0x04 }, 81 { ZD_CR203, 0x04 },
82 { }, 82 { },
83 { CR240, 0x80 }, 83 { ZD_CR240, 0x80 },
84 }; 84 };
85 85
86 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 86 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -89,12 +89,12 @@ static int zd1211b_al7230b_finalize(struct zd_chip *chip)
89 89
90 if (chip->new_phy_layout) { 90 if (chip->new_phy_layout) {
91 /* antenna selection? */ 91 /* antenna selection? */
92 r = zd_iowrite16_locked(chip, 0xe5, CR9); 92 r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
93 if (r) 93 if (r)
94 return r; 94 return r;
95 } 95 }
96 96
97 return zd_iowrite16_locked(chip, 0x04, CR203); 97 return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
98} 98}
99 99
100static int zd1211_al7230b_init_hw(struct zd_rf *rf) 100static int zd1211_al7230b_init_hw(struct zd_rf *rf)
@@ -106,66 +106,66 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf)
106 * specified */ 106 * specified */
107 static const struct zd_ioreq16 ioreqs_1[] = { 107 static const struct zd_ioreq16 ioreqs_1[] = {
108 /* This one is 7230-specific, and happens before the rest */ 108 /* This one is 7230-specific, and happens before the rest */
109 { CR240, 0x57 }, 109 { ZD_CR240, 0x57 },
110 { }, 110 { },
111 111
112 { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 }, 112 { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 },
113 { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 }, 113 { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
114 { CR44, 0x33 }, 114 { ZD_CR44, 0x33 },
115 /* This value is different for 7230 (was: 0x2a) */ 115 /* This value is different for 7230 (was: 0x2a) */
116 { CR106, 0x22 }, 116 { ZD_CR106, 0x22 },
117 { CR107, 0x1a }, { CR109, 0x09 }, { CR110, 0x27 }, 117 { ZD_CR107, 0x1a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 },
118 { CR111, 0x2b }, { CR112, 0x2b }, { CR119, 0x0a }, 118 { ZD_CR111, 0x2b }, { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a },
119 /* This happened further down in AL2230, 119 /* This happened further down in AL2230,
120 * and the value changed (was: 0xe0) */ 120 * and the value changed (was: 0xe0) */
121 { CR122, 0xfc }, 121 { ZD_CR122, 0xfc },
122 { CR10, 0x89 }, 122 { ZD_CR10, 0x89 },
123 /* for newest (3rd cut) AL2300 */ 123 /* for newest (3rd cut) AL2300 */
124 { CR17, 0x28 }, 124 { ZD_CR17, 0x28 },
125 { CR26, 0x93 }, { CR34, 0x30 }, 125 { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
126 /* for newest (3rd cut) AL2300 */ 126 /* for newest (3rd cut) AL2300 */
127 { CR35, 0x3e }, 127 { ZD_CR35, 0x3e },
128 { CR41, 0x24 }, { CR44, 0x32 }, 128 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
129 /* for newest (3rd cut) AL2300 */ 129 /* for newest (3rd cut) AL2300 */
130 { CR46, 0x96 }, 130 { ZD_CR46, 0x96 },
131 { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 }, 131 { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
132 { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, 132 { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
133 { CR92, 0x0a }, { CR99, 0x28 }, 133 { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 },
134 /* This value is different for 7230 (was: 0x00) */ 134 /* This value is different for 7230 (was: 0x00) */
135 { CR100, 0x02 }, 135 { ZD_CR100, 0x02 },
136 { CR101, 0x13 }, { CR102, 0x27 }, 136 { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
137 /* This value is different for 7230 (was: 0x24) */ 137 /* This value is different for 7230 (was: 0x24) */
138 { CR106, 0x22 }, 138 { ZD_CR106, 0x22 },
139 /* This value is different for 7230 (was: 0x2a) */ 139 /* This value is different for 7230 (was: 0x2a) */
140 { CR107, 0x3f }, 140 { ZD_CR107, 0x3f },
141 { CR109, 0x09 }, 141 { ZD_CR109, 0x09 },
142 /* This value is different for 7230 (was: 0x13) */ 142 /* This value is different for 7230 (was: 0x13) */
143 { CR110, 0x1f }, 143 { ZD_CR110, 0x1f },
144 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, 144 { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
145 { CR114, 0x27 }, 145 { ZD_CR114, 0x27 },
146 /* for newest (3rd cut) AL2300 */ 146 /* for newest (3rd cut) AL2300 */
147 { CR115, 0x24 }, 147 { ZD_CR115, 0x24 },
148 /* This value is different for 7230 (was: 0x24) */ 148 /* This value is different for 7230 (was: 0x24) */
149 { CR116, 0x3f }, 149 { ZD_CR116, 0x3f },
150 /* This value is different for 7230 (was: 0xf4) */ 150 /* This value is different for 7230 (was: 0xf4) */
151 { CR117, 0xfa }, 151 { ZD_CR117, 0xfa },
152 { CR118, 0xfc }, { CR119, 0x10 }, { CR120, 0x4f }, 152 { ZD_CR118, 0xfc }, { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f },
153 { CR121, 0x77 }, { CR137, 0x88 }, 153 { ZD_CR121, 0x77 }, { ZD_CR137, 0x88 },
154 /* This one is 7230-specific */ 154 /* This one is 7230-specific */
155 { CR138, 0xa8 }, 155 { ZD_CR138, 0xa8 },
156 /* This value is different for 7230 (was: 0xff) */ 156 /* This value is different for 7230 (was: 0xff) */
157 { CR252, 0x34 }, 157 { ZD_CR252, 0x34 },
158 /* This value is different for 7230 (was: 0xff) */ 158 /* This value is different for 7230 (was: 0xff) */
159 { CR253, 0x34 }, 159 { ZD_CR253, 0x34 },
160 160
161 /* PLL_OFF */ 161 /* PLL_OFF */
162 { CR251, 0x2f }, 162 { ZD_CR251, 0x2f },
163 }; 163 };
164 164
165 static const struct zd_ioreq16 ioreqs_2[] = { 165 static const struct zd_ioreq16 ioreqs_2[] = {
166 { CR251, 0x3f }, /* PLL_ON */ 166 { ZD_CR251, 0x3f }, /* PLL_ON */
167 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 167 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
168 { CR38, 0x38 }, { CR136, 0xdf }, 168 { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
169 }; 169 };
170 170
171 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); 171 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
@@ -192,10 +192,10 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf)
192 if (r) 192 if (r)
193 return r; 193 return r;
194 194
195 r = zd_iowrite16_locked(chip, 0x06, CR203); 195 r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
196 if (r) 196 if (r)
197 return r; 197 return r;
198 r = zd_iowrite16_locked(chip, 0x80, CR240); 198 r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
199 if (r) 199 if (r)
200 return r; 200 return r;
201 201
@@ -208,79 +208,79 @@ static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
208 struct zd_chip *chip = zd_rf_to_chip(rf); 208 struct zd_chip *chip = zd_rf_to_chip(rf);
209 209
210 static const struct zd_ioreq16 ioreqs_1[] = { 210 static const struct zd_ioreq16 ioreqs_1[] = {
211 { CR240, 0x57 }, { CR9, 0x9 }, 211 { ZD_CR240, 0x57 }, { ZD_CR9, 0x9 },
212 { }, 212 { },
213 { CR10, 0x8b }, { CR15, 0x20 }, 213 { ZD_CR10, 0x8b }, { ZD_CR15, 0x20 },
214 { CR17, 0x2B }, /* for newest (3rd cut) AL2230 */ 214 { ZD_CR17, 0x2B }, /* for newest (3rd cut) AL2230 */
215 { CR20, 0x10 }, /* 4N25->Stone Request */ 215 { ZD_CR20, 0x10 }, /* 4N25->Stone Request */
216 { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 }, 216 { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
217 { CR28, 0x3e }, { CR29, 0x00 }, 217 { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
218 { CR33, 0x28 }, /* 5613 */ 218 { ZD_CR33, 0x28 }, /* 5613 */
219 { CR34, 0x30 }, 219 { ZD_CR34, 0x30 },
220 { CR35, 0x3e }, /* for newest (3rd cut) AL2230 */ 220 { ZD_CR35, 0x3e }, /* for newest (3rd cut) AL2230 */
221 { CR41, 0x24 }, { CR44, 0x32 }, 221 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
222 { CR46, 0x99 }, /* for newest (3rd cut) AL2230 */ 222 { ZD_CR46, 0x99 }, /* for newest (3rd cut) AL2230 */
223 { CR47, 0x1e }, 223 { ZD_CR47, 0x1e },
224 224
225 /* ZD1215 5610 */ 225 /* ZD1215 5610 */
226 { CR48, 0x00 }, { CR49, 0x00 }, { CR51, 0x01 }, 226 { ZD_CR48, 0x00 }, { ZD_CR49, 0x00 }, { ZD_CR51, 0x01 },
227 { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 }, 227 { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 },
228 { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 }, 228 { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 },
229 { CR69, 0x28 }, 229 { ZD_CR69, 0x28 },
230 230
231 { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, 231 { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
232 { CR87, 0x0A }, { CR89, 0x04 }, 232 { ZD_CR87, 0x0A }, { ZD_CR89, 0x04 },
233 { CR90, 0x58 }, /* 5112 */ 233 { ZD_CR90, 0x58 }, /* 5112 */
234 { CR91, 0x00 }, /* 5613 */ 234 { ZD_CR91, 0x00 }, /* 5613 */
235 { CR92, 0x0a }, 235 { ZD_CR92, 0x0a },
236 { CR98, 0x8d }, /* 4804, for 1212 new algorithm */ 236 { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */
237 { CR99, 0x00 }, { CR100, 0x02 }, { CR101, 0x13 }, 237 { ZD_CR99, 0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 },
238 { CR102, 0x27 }, 238 { ZD_CR102, 0x27 },
239 { CR106, 0x20 }, /* change to 0x24 for AL7230B */ 239 { ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */
240 { CR109, 0x13 }, /* 4804, for 1212 new algorithm */ 240 { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
241 { CR112, 0x1f }, 241 { ZD_CR112, 0x1f },
242 }; 242 };
243 243
244 static const struct zd_ioreq16 ioreqs_new_phy[] = { 244 static const struct zd_ioreq16 ioreqs_new_phy[] = {
245 { CR107, 0x28 }, 245 { ZD_CR107, 0x28 },
246 { CR110, 0x1f }, /* 5127, 0x13->0x1f */ 246 { ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */
247 { CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */ 247 { ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
248 { CR116, 0x2a }, { CR118, 0xfa }, { CR119, 0x12 }, 248 { ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 },
249 { CR121, 0x6c }, /* 5613 */ 249 { ZD_CR121, 0x6c }, /* 5613 */
250 }; 250 };
251 251
252 static const struct zd_ioreq16 ioreqs_old_phy[] = { 252 static const struct zd_ioreq16 ioreqs_old_phy[] = {
253 { CR107, 0x24 }, 253 { ZD_CR107, 0x24 },
254 { CR110, 0x13 }, /* 5127, 0x13->0x1f */ 254 { ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */
255 { CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */ 255 { ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
256 { CR116, 0x24 }, { CR118, 0xfc }, { CR119, 0x11 }, 256 { ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 },
257 { CR121, 0x6a }, /* 5613 */ 257 { ZD_CR121, 0x6a }, /* 5613 */
258 }; 258 };
259 259
260 static const struct zd_ioreq16 ioreqs_2[] = { 260 static const struct zd_ioreq16 ioreqs_2[] = {
261 { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x24 }, 261 { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 },
262 { CR117, 0xfa }, { CR120, 0x4f }, 262 { ZD_CR117, 0xfa }, { ZD_CR120, 0x4f },
263 { CR122, 0xfc }, /* E0->FCh at 4901 */ 263 { ZD_CR122, 0xfc }, /* E0->FCh at 4901 */
264 { CR123, 0x57 }, /* 5613 */ 264 { ZD_CR123, 0x57 }, /* 5613 */
265 { CR125, 0xad }, /* 4804, for 1212 new algorithm */ 265 { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
266 { CR126, 0x6c }, /* 5613 */ 266 { ZD_CR126, 0x6c }, /* 5613 */
267 { CR127, 0x03 }, /* 4804, for 1212 new algorithm */ 267 { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
268 { CR130, 0x10 }, 268 { ZD_CR130, 0x10 },
269 { CR131, 0x00 }, /* 5112 */ 269 { ZD_CR131, 0x00 }, /* 5112 */
270 { CR137, 0x50 }, /* 5613 */ 270 { ZD_CR137, 0x50 }, /* 5613 */
271 { CR138, 0xa8 }, /* 5112 */ 271 { ZD_CR138, 0xa8 }, /* 5112 */
272 { CR144, 0xac }, /* 5613 */ 272 { ZD_CR144, 0xac }, /* 5613 */
273 { CR148, 0x40 }, /* 5112 */ 273 { ZD_CR148, 0x40 }, /* 5112 */
274 { CR149, 0x40 }, /* 4O07, 50->40 */ 274 { ZD_CR149, 0x40 }, /* 4O07, 50->40 */
275 { CR150, 0x1a }, /* 5112, 0C->1A */ 275 { ZD_CR150, 0x1a }, /* 5112, 0C->1A */
276 { CR252, 0x34 }, { CR253, 0x34 }, 276 { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
277 { CR251, 0x2f }, /* PLL_OFF */ 277 { ZD_CR251, 0x2f }, /* PLL_OFF */
278 }; 278 };
279 279
280 static const struct zd_ioreq16 ioreqs_3[] = { 280 static const struct zd_ioreq16 ioreqs_3[] = {
281 { CR251, 0x7f }, /* PLL_ON */ 281 { ZD_CR251, 0x7f }, /* PLL_ON */
282 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 282 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
283 { CR38, 0x38 }, { CR136, 0xdf }, 283 { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf },
284 }; 284 };
285 285
286 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); 286 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
@@ -331,16 +331,16 @@ static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
331 331
332 static const struct zd_ioreq16 ioreqs[] = { 332 static const struct zd_ioreq16 ioreqs[] = {
333 /* PLL_ON */ 333 /* PLL_ON */
334 { CR251, 0x3f }, 334 { ZD_CR251, 0x3f },
335 { CR203, 0x06 }, { CR240, 0x08 }, 335 { ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
336 }; 336 };
337 337
338 r = zd_iowrite16_locked(chip, 0x57, CR240); 338 r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
339 if (r) 339 if (r)
340 return r; 340 return r;
341 341
342 /* PLL_OFF */ 342 /* PLL_OFF */
343 r = zd_iowrite16_locked(chip, 0x2f, CR251); 343 r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
344 if (r) 344 if (r)
345 return r; 345 return r;
346 346
@@ -376,15 +376,15 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
376 const u32 *rv = chan_rv[channel-1]; 376 const u32 *rv = chan_rv[channel-1];
377 struct zd_chip *chip = zd_rf_to_chip(rf); 377 struct zd_chip *chip = zd_rf_to_chip(rf);
378 378
379 r = zd_iowrite16_locked(chip, 0x57, CR240); 379 r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
380 if (r) 380 if (r)
381 return r; 381 return r;
382 r = zd_iowrite16_locked(chip, 0xe4, CR9); 382 r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
383 if (r) 383 if (r)
384 return r; 384 return r;
385 385
386 /* PLL_OFF */ 386 /* PLL_OFF */
387 r = zd_iowrite16_locked(chip, 0x2f, CR251); 387 r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
388 if (r) 388 if (r)
389 return r; 389 return r;
390 r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv)); 390 r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
@@ -410,7 +410,7 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
410 if (r) 410 if (r)
411 return r; 411 return r;
412 412
413 r = zd_iowrite16_locked(chip, 0x7f, CR251); 413 r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
414 if (r) 414 if (r)
415 return r; 415 return r;
416 416
@@ -421,8 +421,8 @@ static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf)
421{ 421{
422 struct zd_chip *chip = zd_rf_to_chip(rf); 422 struct zd_chip *chip = zd_rf_to_chip(rf);
423 static const struct zd_ioreq16 ioreqs[] = { 423 static const struct zd_ioreq16 ioreqs[] = {
424 { CR11, 0x00 }, 424 { ZD_CR11, 0x00 },
425 { CR251, 0x3f }, 425 { ZD_CR251, 0x3f },
426 }; 426 };
427 427
428 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 428 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -432,8 +432,8 @@ static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf)
432{ 432{
433 struct zd_chip *chip = zd_rf_to_chip(rf); 433 struct zd_chip *chip = zd_rf_to_chip(rf);
434 static const struct zd_ioreq16 ioreqs[] = { 434 static const struct zd_ioreq16 ioreqs[] = {
435 { CR11, 0x00 }, 435 { ZD_CR11, 0x00 },
436 { CR251, 0x7f }, 436 { ZD_CR251, 0x7f },
437 }; 437 };
438 438
439 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 439 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -443,8 +443,8 @@ static int al7230b_switch_radio_off(struct zd_rf *rf)
443{ 443{
444 struct zd_chip *chip = zd_rf_to_chip(rf); 444 struct zd_chip *chip = zd_rf_to_chip(rf);
445 static const struct zd_ioreq16 ioreqs[] = { 445 static const struct zd_ioreq16 ioreqs[] = {
446 { CR11, 0x04 }, 446 { ZD_CR11, 0x04 },
447 { CR251, 0x2f }, 447 { ZD_CR251, 0x2f },
448 }; 448 };
449 449
450 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 450 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -456,7 +456,7 @@ static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel)
456{ 456{
457 struct zd_chip *chip = zd_rf_to_chip(rf); 457 struct zd_chip *chip = zd_rf_to_chip(rf);
458 struct zd_ioreq16 ioreqs[] = { 458 struct zd_ioreq16 ioreqs[] = {
459 { CR128, 0x14 }, { CR129, 0x12 }, 459 { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
460 }; 460 };
461 461
462 /* FIXME: Channel 11 is not the edge for all regulatory domains. */ 462 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index e36117486c91..784d9ccb8fef 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -152,44 +152,44 @@ static int rf2959_init_hw(struct zd_rf *rf)
152 struct zd_chip *chip = zd_rf_to_chip(rf); 152 struct zd_chip *chip = zd_rf_to_chip(rf);
153 153
154 static const struct zd_ioreq16 ioreqs[] = { 154 static const struct zd_ioreq16 ioreqs[] = {
155 { CR2, 0x1E }, { CR9, 0x20 }, { CR10, 0x89 }, 155 { ZD_CR2, 0x1E }, { ZD_CR9, 0x20 }, { ZD_CR10, 0x89 },
156 { CR11, 0x00 }, { CR15, 0xD0 }, { CR17, 0x68 }, 156 { ZD_CR11, 0x00 }, { ZD_CR15, 0xD0 }, { ZD_CR17, 0x68 },
157 { CR19, 0x4a }, { CR20, 0x0c }, { CR21, 0x0E }, 157 { ZD_CR19, 0x4a }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0E },
158 { CR23, 0x48 }, 158 { ZD_CR23, 0x48 },
159 /* normal size for cca threshold */ 159 /* normal size for cca threshold */
160 { CR24, 0x14 }, 160 { ZD_CR24, 0x14 },
161 /* { CR24, 0x20 }, */ 161 /* { ZD_CR24, 0x20 }, */
162 { CR26, 0x90 }, { CR27, 0x30 }, { CR29, 0x20 }, 162 { ZD_CR26, 0x90 }, { ZD_CR27, 0x30 }, { ZD_CR29, 0x20 },
163 { CR31, 0xb2 }, { CR32, 0x43 }, { CR33, 0x28 }, 163 { ZD_CR31, 0xb2 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x28 },
164 { CR38, 0x30 }, { CR34, 0x0f }, { CR35, 0xF0 }, 164 { ZD_CR38, 0x30 }, { ZD_CR34, 0x0f }, { ZD_CR35, 0xF0 },
165 { CR41, 0x2a }, { CR46, 0x7F }, { CR47, 0x1E }, 165 { ZD_CR41, 0x2a }, { ZD_CR46, 0x7F }, { ZD_CR47, 0x1E },
166 { CR51, 0xc5 }, { CR52, 0xc5 }, { CR53, 0xc5 }, 166 { ZD_CR51, 0xc5 }, { ZD_CR52, 0xc5 }, { ZD_CR53, 0xc5 },
167 { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, 167 { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 },
168 { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 }, 168 { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 },
169 { CR85, 0x00 }, { CR86, 0x10 }, { CR87, 0x2A }, 169 { ZD_CR85, 0x00 }, { ZD_CR86, 0x10 }, { ZD_CR87, 0x2A },
170 { CR88, 0x10 }, { CR89, 0x24 }, { CR90, 0x18 }, 170 { ZD_CR88, 0x10 }, { ZD_CR89, 0x24 }, { ZD_CR90, 0x18 },
171 /* { CR91, 0x18 }, */ 171 /* { ZD_CR91, 0x18 }, */
172 /* should solve continuous CTS frame problems */ 172 /* should solve continuous CTS frame problems */
173 { CR91, 0x00 }, 173 { ZD_CR91, 0x00 },
174 { CR92, 0x0a }, { CR93, 0x00 }, { CR94, 0x01 }, 174 { ZD_CR92, 0x0a }, { ZD_CR93, 0x00 }, { ZD_CR94, 0x01 },
175 { CR95, 0x00 }, { CR96, 0x40 }, { CR97, 0x37 }, 175 { ZD_CR95, 0x00 }, { ZD_CR96, 0x40 }, { ZD_CR97, 0x37 },
176 { CR98, 0x05 }, { CR99, 0x28 }, { CR100, 0x00 }, 176 { ZD_CR98, 0x05 }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 },
177 { CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 }, 177 { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 },
178 { CR104, 0x18 }, { CR105, 0x12 }, 178 { ZD_CR104, 0x18 }, { ZD_CR105, 0x12 },
179 /* normal size */ 179 /* normal size */
180 { CR106, 0x1a }, 180 { ZD_CR106, 0x1a },
181 /* { CR106, 0x22 }, */ 181 /* { ZD_CR106, 0x22 }, */
182 { CR107, 0x24 }, { CR108, 0x0a }, { CR109, 0x13 }, 182 { ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 },
183 { CR110, 0x2F }, { CR111, 0x27 }, { CR112, 0x27 }, 183 { ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 },
184 { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x40 }, 184 { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 },
185 { CR116, 0x40 }, { CR117, 0xF0 }, { CR118, 0xF0 }, 185 { ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 },
186 { CR119, 0x16 }, 186 { ZD_CR119, 0x16 },
187 /* no TX continuation */ 187 /* no TX continuation */
188 { CR122, 0x00 }, 188 { ZD_CR122, 0x00 },
189 /* { CR122, 0xff }, */ 189 /* { ZD_CR122, 0xff }, */
190 { CR127, 0x03 }, { CR131, 0x08 }, { CR138, 0x28 }, 190 { ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 },
191 { CR148, 0x44 }, { CR150, 0x10 }, { CR169, 0xBB }, 191 { ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB },
192 { CR170, 0xBB }, 192 { ZD_CR170, 0xBB },
193 }; 193 };
194 194
195 static const u32 rv[] = { 195 static const u32 rv[] = {
@@ -210,7 +210,7 @@ static int rf2959_init_hw(struct zd_rf *rf)
210 */ 210 */
211 0x294128, /* internal power */ 211 0x294128, /* internal power */
212 /* 0x28252c, */ /* External control TX power */ 212 /* 0x28252c, */ /* External control TX power */
213 /* CR31_CCK, CR51_6-36M, CR52_48M, CR53_54M */ 213 /* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */
214 0x2c0000, 214 0x2c0000,
215 0x300000, 215 0x300000,
216 0x340000, /* REG13(0xD) */ 216 0x340000, /* REG13(0xD) */
@@ -245,8 +245,8 @@ static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
245static int rf2959_switch_radio_on(struct zd_rf *rf) 245static int rf2959_switch_radio_on(struct zd_rf *rf)
246{ 246{
247 static const struct zd_ioreq16 ioreqs[] = { 247 static const struct zd_ioreq16 ioreqs[] = {
248 { CR10, 0x89 }, 248 { ZD_CR10, 0x89 },
249 { CR11, 0x00 }, 249 { ZD_CR11, 0x00 },
250 }; 250 };
251 struct zd_chip *chip = zd_rf_to_chip(rf); 251 struct zd_chip *chip = zd_rf_to_chip(rf);
252 252
@@ -256,8 +256,8 @@ static int rf2959_switch_radio_on(struct zd_rf *rf)
256static int rf2959_switch_radio_off(struct zd_rf *rf) 256static int rf2959_switch_radio_off(struct zd_rf *rf)
257{ 257{
258 static const struct zd_ioreq16 ioreqs[] = { 258 static const struct zd_ioreq16 ioreqs[] = {
259 { CR10, 0x15 }, 259 { ZD_CR10, 0x15 },
260 { CR11, 0x81 }, 260 { ZD_CR11, 0x81 },
261 }; 261 };
262 struct zd_chip *chip = zd_rf_to_chip(rf); 262 struct zd_chip *chip = zd_rf_to_chip(rf);
263 263
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index ba0a0ccb1fa0..c4d324e19c24 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -314,42 +314,44 @@ static int uw2453_init_hw(struct zd_rf *rf)
314 struct zd_chip *chip = zd_rf_to_chip(rf); 314 struct zd_chip *chip = zd_rf_to_chip(rf);
315 315
316 static const struct zd_ioreq16 ioreqs[] = { 316 static const struct zd_ioreq16 ioreqs[] = {
317 { CR10, 0x89 }, { CR15, 0x20 }, 317 { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 },
318 { CR17, 0x28 }, /* 6112 no change */ 318 { ZD_CR17, 0x28 }, /* 6112 no change */
319 { CR23, 0x38 }, { CR24, 0x20 }, { CR26, 0x93 }, 319 { ZD_CR23, 0x38 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 },
320 { CR27, 0x15 }, { CR28, 0x3e }, { CR29, 0x00 }, 320 { ZD_CR27, 0x15 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 },
321 { CR33, 0x28 }, { CR34, 0x30 }, 321 { ZD_CR33, 0x28 }, { ZD_CR34, 0x30 },
322 { CR35, 0x43 }, /* 6112 3e->43 */ 322 { ZD_CR35, 0x43 }, /* 6112 3e->43 */
323 { CR41, 0x24 }, { CR44, 0x32 }, 323 { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
324 { CR46, 0x92 }, /* 6112 96->92 */ 324 { ZD_CR46, 0x92 }, /* 6112 96->92 */
325 { CR47, 0x1e }, 325 { ZD_CR47, 0x1e },
326 { CR48, 0x04 }, /* 5602 Roger */ 326 { ZD_CR48, 0x04 }, /* 5602 Roger */
327 { CR49, 0xfa }, { CR79, 0x58 }, { CR80, 0x30 }, 327 { ZD_CR49, 0xfa }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 },
328 { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, 328 { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 },
329 { CR91, 0x00 }, { CR92, 0x0a }, { CR98, 0x8d }, 329 { ZD_CR91, 0x00 }, { ZD_CR92, 0x0a }, { ZD_CR98, 0x8d },
330 { CR99, 0x28 }, { CR100, 0x02 }, 330 { ZD_CR99, 0x28 }, { ZD_CR100, 0x02 },
331 { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */ 331 { ZD_CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
332 { CR102, 0x27 }, 332 { ZD_CR102, 0x27 },
333 { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */ 333 { ZD_CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f
334 { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */ 334 * 6221 1f->1c
335 { CR109, 0x13 }, 335 */
336 { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */ 336 { ZD_CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
337 { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 }, 337 { ZD_CR109, 0x13 },
338 { CR114, 0x23 }, /* 6221 27->23 */ 338 { ZD_CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
339 { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */ 339 { ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
340 { CR116, 0x24 }, /* 6220 1c->24 */ 340 { ZD_CR114, 0x23 }, /* 6221 27->23 */
341 { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */ 341 { ZD_CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
342 { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */ 342 { ZD_CR116, 0x24 }, /* 6220 1c->24 */
343 { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */ 343 { ZD_CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
344 { CR120, 0x4f }, 344 { ZD_CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
345 { CR121, 0x1f }, /* 6220 4f->1f */ 345 { ZD_CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
346 { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad }, 346 { ZD_CR120, 0x4f },
347 { CR126, 0x6c }, { CR127, 0x03 }, 347 { ZD_CR121, 0x1f }, /* 6220 4f->1f */
348 { CR128, 0x14 }, /* 6302 12->11 */ 348 { ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad },
349 { CR129, 0x12 }, /* 6301 10->0f */ 349 { ZD_CR126, 0x6c }, { ZD_CR127, 0x03 },
350 { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 }, 350 { ZD_CR128, 0x14 }, /* 6302 12->11 */
351 { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff }, 351 { ZD_CR129, 0x12 }, /* 6301 10->0f */
352 { CR253, 0xff }, 352 { ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 },
353 { ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff },
354 { ZD_CR253, 0xff },
353 }; 355 };
354 356
355 static const u32 rv[] = { 357 static const u32 rv[] = {
@@ -433,7 +435,7 @@ static int uw2453_init_hw(struct zd_rf *rf)
433 * the one that produced a lock. */ 435 * the one that produced a lock. */
434 UW2453_PRIV(rf)->config = found_config + 1; 436 UW2453_PRIV(rf)->config = found_config + 1;
435 437
436 return zd_iowrite16_locked(chip, 0x06, CR203); 438 return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
437} 439}
438 440
439static int uw2453_set_channel(struct zd_rf *rf, u8 channel) 441static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
@@ -445,8 +447,8 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
445 struct zd_chip *chip = zd_rf_to_chip(rf); 447 struct zd_chip *chip = zd_rf_to_chip(rf);
446 448
447 static const struct zd_ioreq16 ioreqs[] = { 449 static const struct zd_ioreq16 ioreqs[] = {
448 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, 450 { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
449 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, 451 { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
450 }; 452 };
451 453
452 r = uw2453_synth_set_channel(chip, channel, autocal); 454 r = uw2453_synth_set_channel(chip, channel, autocal);
@@ -474,7 +476,7 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
474 if (r) 476 if (r)
475 return r; 477 return r;
476 478
477 return zd_iowrite16_locked(chip, 0x06, CR203); 479 return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
478} 480}
479 481
480static int uw2453_switch_radio_on(struct zd_rf *rf) 482static int uw2453_switch_radio_on(struct zd_rf *rf)
@@ -482,7 +484,7 @@ static int uw2453_switch_radio_on(struct zd_rf *rf)
482 int r; 484 int r;
483 struct zd_chip *chip = zd_rf_to_chip(rf); 485 struct zd_chip *chip = zd_rf_to_chip(rf);
484 struct zd_ioreq16 ioreqs[] = { 486 struct zd_ioreq16 ioreqs[] = {
485 { CR11, 0x00 }, { CR251, 0x3f }, 487 { ZD_CR11, 0x00 }, { ZD_CR251, 0x3f },
486 }; 488 };
487 489
488 /* enter RXTX mode */ 490 /* enter RXTX mode */
@@ -501,7 +503,7 @@ static int uw2453_switch_radio_off(struct zd_rf *rf)
501 int r; 503 int r;
502 struct zd_chip *chip = zd_rf_to_chip(rf); 504 struct zd_chip *chip = zd_rf_to_chip(rf);
503 static const struct zd_ioreq16 ioreqs[] = { 505 static const struct zd_ioreq16 ioreqs[] = {
504 { CR11, 0x04 }, { CR251, 0x2f }, 506 { ZD_CR11, 0x04 }, { ZD_CR251, 0x2f },
505 }; 507 };
506 508
507 /* enter IDLE mode */ 509 /* enter IDLE mode */
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index ab607bbd6291..0e819943b9e4 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1893,10 +1893,10 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
1893 1893
1894 dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits); 1894 dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits);
1895 1895
1896 r = zd_usb_ioread16(usb, &bit_value_template, CR203); 1896 r = zd_usb_ioread16(usb, &bit_value_template, ZD_CR203);
1897 if (r) { 1897 if (r) {
1898 dev_dbg_f(zd_usb_dev(usb), 1898 dev_dbg_f(zd_usb_dev(usb),
1899 "error %d: Couldn't read CR203\n", r); 1899 "error %d: Couldn't read ZD_CR203\n", r);
1900 return r; 1900 return r;
1901 } 1901 }
1902 bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); 1902 bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 325d0f989257..bf942843b733 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -109,7 +109,7 @@ struct usb_req_rfwrite {
109 __le16 bits; 109 __le16 bits;
110 /* RF2595: 24 */ 110 /* RF2595: 24 */
111 __le16 bit_values[0]; 111 __le16 bit_values[0];
112 /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ 112 /* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
113} __packed; 113} __packed;
114 114
115/* USB interrupt */ 115/* USB interrupt */