aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-01-24 08:25:36 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-01 05:27:15 -0500
commit8ca151b568b67a7b72dcfc6ee6ea7c107ddd795c (patch)
treedac0236038f3791140e9f864c5db2be873c568f0
parentb1e1adfa7d30cd0e8ad9a5c6a89e8c45ebe084f4 (diff)
iwlwifi: add the MVM driver
Newer firmware revisions have a completely new firmware API. This is the new driver for this new API. I've listed the people who directly contributed code, but many others from various teams have contributed in other ways. Cc: Alexander Bondar <alexander.bondar@intel.com> Cc: Amit Beka <amit.beka@intel.com> Cc: Amnon Paz <amnonx.paz@intel.com> Cc: Assaf Krauss <assaf.krauss@intel.com> Cc: David Spinadel <david.spinadel@intel.com> Cc: Dor Shaish <dor.shaish@intel.com> Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Cc: Eytan Lifshitz <eytan.lifshitz@intel.com> Cc: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig14
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c197
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c841
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c378
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h282
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h369
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h140
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h312
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h561
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h380
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h580
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h949
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c644
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c134
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c951
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c1310
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h500
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c311
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c679
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c292
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c207
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c178
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c3096
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h393
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c355
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c437
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c1211
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h368
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c569
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h214
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c916
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c472
37 files changed, 18263 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 5cf43236421e..ba319cba3f1e 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -43,8 +43,20 @@ config IWLWIFI
43 module will be called iwlwifi. 43 module will be called iwlwifi.
44 44
45config IWLDVM 45config IWLDVM
46 tristate "Intel Wireless WiFi" 46 tristate "Intel Wireless WiFi DVM Firmware support"
47 depends on IWLWIFI 47 depends on IWLWIFI
48 help
49 This is the driver supporting the DVM firmware which is
50 currently the only firmware available for existing devices.
51
52config IWLMVM
53 tristate "Intel Wireless WiFi MVM Firmware support"
54 depends on IWLWIFI
55 help
56 This is the driver supporting the MVM firmware which is
57 currently only available for 7000 series devices.
58
59 Say yes if you have such a device.
48 60
49menu "Debugging Options" 61menu "Debugging Options"
50 depends on IWLWIFI 62 depends on IWLWIFI
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 2d4d47a6ef14..6c7800044a04 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -17,5 +17,6 @@ ccflags-y += -D__CHECK_ENDIAN__ -I$(src)
17 17
18 18
19obj-$(CONFIG_IWLDVM) += dvm/ 19obj-$(CONFIG_IWLDVM) += dvm/
20obj-$(CONFIG_IWLMVM) += mvm/
20 21
21CFLAGS_iwl-devtrace.o := -I$(src) 22CFLAGS_iwl-devtrace.o := -I$(src)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index b59ec4c5c8ca..8cf5db7fb5c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -116,6 +116,7 @@ do { \
116#define IWL_DL_HCMD 0x00000004 116#define IWL_DL_HCMD 0x00000004
117#define IWL_DL_STATE 0x00000008 117#define IWL_DL_STATE 0x00000008
118/* 0x000000F0 - 0x00000010 */ 118/* 0x000000F0 - 0x00000010 */
119#define IWL_DL_TE 0x00000020
119#define IWL_DL_EEPROM 0x00000040 120#define IWL_DL_EEPROM 0x00000040
120#define IWL_DL_RADIO 0x00000080 121#define IWL_DL_RADIO 0x00000080
121/* 0x00000F00 - 0x00000100 */ 122/* 0x00000F00 - 0x00000100 */
@@ -156,6 +157,7 @@ do { \
156#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) 157#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
157#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) 158#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
158#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) 159#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
160#define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a)
159#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) 161#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a)
160#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) 162#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
161#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) 163#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index c6751962b2d9..6f228bb2b844 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -139,8 +139,10 @@ struct iwl_drv {
139#endif 139#endif
140}; 140};
141 141
142#define DVM_OP_MODE 0 142enum {
143#define MVM_OP_MODE 1 143 DVM_OP_MODE = 0,
144 MVM_OP_MODE = 1,
145};
144 146
145/* Protects the table contents, i.e. the ops pointer & drv list */ 147/* Protects the table contents, i.e. the ops pointer & drv list */
146static struct mutex iwlwifi_opmode_table_mtx; 148static struct mutex iwlwifi_opmode_table_mtx;
@@ -149,8 +151,8 @@ static struct iwlwifi_opmode_table {
149 const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */ 151 const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */
150 struct list_head drv; /* list of devices using this op_mode */ 152 struct list_head drv; /* list of devices using this op_mode */
151} iwlwifi_opmode_table[] = { /* ops set when driver is initialized */ 153} iwlwifi_opmode_table[] = { /* ops set when driver is initialized */
152 { .name = "iwldvm", .ops = NULL }, 154 [DVM_OP_MODE] = { .name = "iwldvm", .ops = NULL },
153 { .name = "iwlmvm", .ops = NULL }, 155 [MVM_OP_MODE] = { .name = "iwlmvm", .ops = NULL },
154}; 156};
155 157
156/* 158/*
@@ -963,7 +965,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
963 release_firmware(ucode_raw); 965 release_firmware(ucode_raw);
964 966
965 mutex_lock(&iwlwifi_opmode_table_mtx); 967 mutex_lock(&iwlwifi_opmode_table_mtx);
966 op = &iwlwifi_opmode_table[DVM_OP_MODE]; 968 if (fw->mvm_fw)
969 op = &iwlwifi_opmode_table[MVM_OP_MODE];
970 else
971 op = &iwlwifi_opmode_table[DVM_OP_MODE];
967 972
968 /* add this device to the list of devices using this op_mode */ 973 /* add this device to the list of devices using this op_mode */
969 list_add_tail(&drv->list, &op->drv); 974 list_add_tail(&drv->list, &op->drv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 1ad31a9fa3ec..de3c24a5a620 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -166,6 +166,7 @@ struct iwl_tlv_calib_ctrl {
166 * @inst_evtlog_ptr: event log offset for runtime ucode. 166 * @inst_evtlog_ptr: event log offset for runtime ucode.
167 * @inst_evtlog_size: event log size for runtime ucode. 167 * @inst_evtlog_size: event log size for runtime ucode.
168 * @inst_errlog_ptr: error log offfset for runtime ucode. 168 * @inst_errlog_ptr: error log offfset for runtime ucode.
169 * @mvm_fw: indicates this is MVM firmware
169 */ 170 */
170struct iwl_fw { 171struct iwl_fw {
171 u32 ucode_ver; 172 u32 ucode_ver;
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
new file mode 100644
index 000000000000..807b250ec396
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -0,0 +1,10 @@
1obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o
6iwlmvm-y += led.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9
10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
new file mode 100644
index 000000000000..73d24aacb90a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -0,0 +1,197 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <net/mac80211.h>
65#include "fw-api.h"
66#include "mvm.h"
67
68struct iwl_mvm_iface_iterator_data {
69 struct ieee80211_vif *ignore_vif;
70 int idx;
71
72 struct iwl_mvm_phy_ctxt *phyctxt;
73
74 u16 ids[MAX_MACS_IN_BINDING];
75 u16 colors[MAX_MACS_IN_BINDING];
76};
77
78static int iwl_mvm_binding_cmd(struct iwl_mvm *mvm, u32 action,
79 struct iwl_mvm_iface_iterator_data *data)
80{
81 struct iwl_binding_cmd cmd;
82 struct iwl_mvm_phy_ctxt *phyctxt = data->phyctxt;
83 int i, ret;
84 u32 status;
85
86 memset(&cmd, 0, sizeof(cmd));
87
88 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(phyctxt->id,
89 phyctxt->color));
90 cmd.action = cpu_to_le32(action);
91 cmd.phy = cpu_to_le32(FW_CMD_ID_AND_COLOR(phyctxt->id,
92 phyctxt->color));
93
94 for (i = 0; i < MAX_MACS_IN_BINDING; i++)
95 cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
96 for (i = 0; i < data->idx; i++)
97 cmd.macs[i] = cpu_to_le32(FW_CMD_ID_AND_COLOR(data->ids[i],
98 data->colors[i]));
99
100 status = 0;
101 ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
102 sizeof(cmd), &cmd, &status);
103 if (ret) {
104 IWL_ERR(mvm, "Failed to send binding (action:%d): %d\n",
105 action, ret);
106 return ret;
107 }
108
109 if (status) {
110 IWL_ERR(mvm, "Binding command failed: %u\n", status);
111 ret = -EIO;
112 }
113
114 return ret;
115}
116
117static void iwl_mvm_iface_iterator(void *_data, u8 *mac,
118 struct ieee80211_vif *vif)
119{
120 struct iwl_mvm_iface_iterator_data *data = _data;
121 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
122
123 if (vif == data->ignore_vif)
124 return;
125
126 if (mvmvif->phy_ctxt != data->phyctxt)
127 return;
128
129 if (WARN_ON_ONCE(data->idx >= MAX_MACS_IN_BINDING))
130 return;
131
132 data->ids[data->idx] = mvmvif->id;
133 data->colors[data->idx] = mvmvif->color;
134 data->idx++;
135}
136
137static int iwl_mvm_binding_update(struct iwl_mvm *mvm,
138 struct ieee80211_vif *vif,
139 struct iwl_mvm_phy_ctxt *phyctxt,
140 bool add)
141{
142 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
143 struct iwl_mvm_iface_iterator_data data = {
144 .ignore_vif = vif,
145 .phyctxt = phyctxt,
146 };
147 u32 action = FW_CTXT_ACTION_MODIFY;
148
149 lockdep_assert_held(&mvm->mutex);
150
151 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
152 IEEE80211_IFACE_ITER_NORMAL,
153 iwl_mvm_iface_iterator,
154 &data);
155
156 /*
157 * If there are no other interfaces yet we
158 * need to create a new binding.
159 */
160 if (data.idx == 0) {
161 if (add)
162 action = FW_CTXT_ACTION_ADD;
163 else
164 action = FW_CTXT_ACTION_REMOVE;
165 }
166
167 if (add) {
168 if (WARN_ON_ONCE(data.idx >= MAX_MACS_IN_BINDING))
169 return -EINVAL;
170
171 data.ids[data.idx] = mvmvif->id;
172 data.colors[data.idx] = mvmvif->color;
173 data.idx++;
174 }
175
176 return iwl_mvm_binding_cmd(mvm, action, &data);
177}
178
179int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
180{
181 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
182
183 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
184 return -EINVAL;
185
186 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true);
187}
188
189int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
190{
191 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
192
193 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
194 return -EINVAL;
195
196 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false);
197}
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
new file mode 100644
index 000000000000..9a95c374990d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -0,0 +1,841 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <net/cfg80211.h>
65#include <net/ipv6.h>
66#include "iwl-modparams.h"
67#include "fw-api.h"
68#include "mvm.h"
69
70void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
71 struct ieee80211_vif *vif,
72 struct cfg80211_gtk_rekey_data *data)
73{
74 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
75 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
76
77 if (iwlwifi_mod_params.sw_crypto)
78 return;
79
80 mutex_lock(&mvm->mutex);
81
82 memcpy(mvmvif->rekey_data.kek, data->kek, NL80211_KEK_LEN);
83 memcpy(mvmvif->rekey_data.kck, data->kck, NL80211_KCK_LEN);
84 mvmvif->rekey_data.replay_ctr =
85 cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr));
86 mvmvif->rekey_data.valid = true;
87
88 mutex_unlock(&mvm->mutex);
89}
90
91#if IS_ENABLED(CONFIG_IPV6)
92void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
93 struct ieee80211_vif *vif,
94 struct inet6_dev *idev)
95{
96 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
97 struct inet6_ifaddr *ifa;
98 int idx = 0;
99
100 read_lock(&idev->lock);
101 list_for_each_entry(ifa, &idev->addr_list, if_list) {
102 mvmvif->target_ipv6_addrs[idx] = ifa->addr;
103 idx++;
104 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS)
105 break;
106 }
107 read_unlock(&idev->lock);
108
109 mvmvif->num_target_ipv6_addrs = idx;
110}
111#endif
112
113void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
114 struct ieee80211_vif *vif, int idx)
115{
116 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
117
118 mvmvif->tx_key_idx = idx;
119}
120
121static void iwl_mvm_convert_p1k(u16 *p1k, __le16 *out)
122{
123 int i;
124
125 for (i = 0; i < IWL_P1K_SIZE; i++)
126 out[i] = cpu_to_le16(p1k[i]);
127}
128
129struct wowlan_key_data {
130 struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
131 struct iwl_wowlan_tkip_params_cmd *tkip;
132 bool error, use_rsc_tsc, use_tkip;
133 int gtk_key_idx;
134};
135
136static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
137 struct ieee80211_vif *vif,
138 struct ieee80211_sta *sta,
139 struct ieee80211_key_conf *key,
140 void *_data)
141{
142 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
143 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
144 struct wowlan_key_data *data = _data;
145 struct aes_sc *aes_sc, *aes_tx_sc = NULL;
146 struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
147 struct iwl_p1k_cache *rx_p1ks;
148 u8 *rx_mic_key;
149 struct ieee80211_key_seq seq;
150 u32 cur_rx_iv32 = 0;
151 u16 p1k[IWL_P1K_SIZE];
152 int ret, i;
153
154 mutex_lock(&mvm->mutex);
155
156 switch (key->cipher) {
157 case WLAN_CIPHER_SUITE_WEP40:
158 case WLAN_CIPHER_SUITE_WEP104: { /* hack it for now */
159 struct {
160 struct iwl_mvm_wep_key_cmd wep_key_cmd;
161 struct iwl_mvm_wep_key wep_key;
162 } __packed wkc = {
163 .wep_key_cmd.mac_id_n_color =
164 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
165 mvmvif->color)),
166 .wep_key_cmd.num_keys = 1,
167 /* firmware sets STA_KEY_FLG_WEP_13BYTES */
168 .wep_key_cmd.decryption_type = STA_KEY_FLG_WEP,
169 .wep_key.key_index = key->keyidx,
170 .wep_key.key_size = key->keylen,
171 };
172
173 /*
174 * This will fail -- the key functions don't set support
175 * pairwise WEP keys. However, that's better than silently
176 * failing WoWLAN. Or maybe not?
177 */
178 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
179 break;
180
181 memcpy(&wkc.wep_key.key[3], key->key, key->keylen);
182 if (key->keyidx == mvmvif->tx_key_idx) {
183 /* TX key must be at offset 0 */
184 wkc.wep_key.key_offset = 0;
185 } else {
186 /* others start at 1 */
187 data->gtk_key_idx++;
188 wkc.wep_key.key_offset = data->gtk_key_idx;
189 }
190
191 ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC,
192 sizeof(wkc), &wkc);
193 data->error = ret != 0;
194
195 /* don't upload key again */
196 goto out_unlock;
197 }
198 default:
199 data->error = true;
200 goto out_unlock;
201 case WLAN_CIPHER_SUITE_AES_CMAC:
202 /*
203 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
204 * but we also shouldn't abort suspend due to that. It does have
205 * support for the IGTK key renewal, but doesn't really use the
206 * IGTK for anything. This means we could spuriously wake up or
207 * be deauthenticated, but that was considered acceptable.
208 */
209 goto out_unlock;
210 case WLAN_CIPHER_SUITE_TKIP:
211 if (sta) {
212 tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
213 tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;
214
215 rx_p1ks = data->tkip->rx_uni;
216
217 ieee80211_get_key_tx_seq(key, &seq);
218 tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);
219 tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);
220
221 ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);
222 iwl_mvm_convert_p1k(p1k, data->tkip->tx.p1k);
223
224 memcpy(data->tkip->mic_keys.tx,
225 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
226 IWL_MIC_KEY_SIZE);
227
228 rx_mic_key = data->tkip->mic_keys.rx_unicast;
229 } else {
230 tkip_sc =
231 data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
232 rx_p1ks = data->tkip->rx_multi;
233 rx_mic_key = data->tkip->mic_keys.rx_mcast;
234 }
235
236 /*
237 * For non-QoS this relies on the fact that both the uCode and
238 * mac80211 use TID 0 (as they need to to avoid replay attacks)
239 * for checking the IV in the frames.
240 */
241 for (i = 0; i < IWL_NUM_RSC; i++) {
242 ieee80211_get_key_rx_seq(key, i, &seq);
243 tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
244 tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
245 /* wrapping isn't allowed, AP must rekey */
246 if (seq.tkip.iv32 > cur_rx_iv32)
247 cur_rx_iv32 = seq.tkip.iv32;
248 }
249
250 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
251 cur_rx_iv32, p1k);
252 iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
253 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
254 cur_rx_iv32 + 1, p1k);
255 iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
256
257 memcpy(rx_mic_key,
258 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
259 IWL_MIC_KEY_SIZE);
260
261 data->use_tkip = true;
262 data->use_rsc_tsc = true;
263 break;
264 case WLAN_CIPHER_SUITE_CCMP:
265 if (sta) {
266 u8 *pn = seq.ccmp.pn;
267
268 aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
269 aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
270
271 ieee80211_get_key_tx_seq(key, &seq);
272 aes_tx_sc->pn = cpu_to_le64((u64)pn[5] |
273 ((u64)pn[4] << 8) |
274 ((u64)pn[3] << 16) |
275 ((u64)pn[2] << 24) |
276 ((u64)pn[1] << 32) |
277 ((u64)pn[0] << 40));
278 } else {
279 aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
280 }
281
282 /*
283 * For non-QoS this relies on the fact that both the uCode and
284 * mac80211 use TID 0 for checking the IV in the frames.
285 */
286 for (i = 0; i < IWL_NUM_RSC; i++) {
287 u8 *pn = seq.ccmp.pn;
288
289 ieee80211_get_key_rx_seq(key, i, &seq);
290 aes_sc->pn = cpu_to_le64((u64)pn[5] |
291 ((u64)pn[4] << 8) |
292 ((u64)pn[3] << 16) |
293 ((u64)pn[2] << 24) |
294 ((u64)pn[1] << 32) |
295 ((u64)pn[0] << 40));
296 }
297 data->use_rsc_tsc = true;
298 break;
299 }
300
301 /*
302 * The D3 firmware hardcodes the key offset 0 as the key it uses
303 * to transmit packets to the AP, i.e. the PTK.
304 */
305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
306 key->hw_key_idx = 0;
307 } else {
308 data->gtk_key_idx++;
309 key->hw_key_idx = data->gtk_key_idx;
310 }
311
312 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
313 data->error = ret != 0;
314out_unlock:
315 mutex_unlock(&mvm->mutex);
316}
317
318static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
319 struct cfg80211_wowlan *wowlan)
320{
321 struct iwl_wowlan_patterns_cmd *pattern_cmd;
322 struct iwl_host_cmd cmd = {
323 .id = WOWLAN_PATTERNS,
324 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
325 .flags = CMD_SYNC,
326 };
327 int i, err;
328
329 if (!wowlan->n_patterns)
330 return 0;
331
332 cmd.len[0] = sizeof(*pattern_cmd) +
333 wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern);
334
335 pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
336 if (!pattern_cmd)
337 return -ENOMEM;
338
339 pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
340
341 for (i = 0; i < wowlan->n_patterns; i++) {
342 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
343
344 memcpy(&pattern_cmd->patterns[i].mask,
345 wowlan->patterns[i].mask, mask_len);
346 memcpy(&pattern_cmd->patterns[i].pattern,
347 wowlan->patterns[i].pattern,
348 wowlan->patterns[i].pattern_len);
349 pattern_cmd->patterns[i].mask_size = mask_len;
350 pattern_cmd->patterns[i].pattern_size =
351 wowlan->patterns[i].pattern_len;
352 }
353
354 cmd.data[0] = pattern_cmd;
355 err = iwl_mvm_send_cmd(mvm, &cmd);
356 kfree(pattern_cmd);
357 return err;
358}
359
360static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
361 struct ieee80211_vif *vif)
362{
363 struct iwl_proto_offload_cmd cmd = {};
364#if IS_ENABLED(CONFIG_IPV6)
365 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
366 int i;
367
368 if (mvmvif->num_target_ipv6_addrs) {
369 cmd.enabled |= cpu_to_le32(IWL_D3_PROTO_OFFLOAD_NS);
370 memcpy(cmd.ndp_mac_addr, vif->addr, ETH_ALEN);
371 }
372
373 BUILD_BUG_ON(sizeof(cmd.target_ipv6_addr[i]) !=
374 sizeof(mvmvif->target_ipv6_addrs[i]));
375
376 for (i = 0; i < mvmvif->num_target_ipv6_addrs; i++)
377 memcpy(cmd.target_ipv6_addr[i],
378 &mvmvif->target_ipv6_addrs[i],
379 sizeof(cmd.target_ipv6_addr[i]));
380#endif
381
382 if (vif->bss_conf.arp_addr_cnt) {
383 cmd.enabled |= cpu_to_le32(IWL_D3_PROTO_OFFLOAD_ARP);
384 cmd.host_ipv4_addr = vif->bss_conf.arp_addr_list[0];
385 memcpy(cmd.arp_mac_addr, vif->addr, ETH_ALEN);
386 }
387
388 if (!cmd.enabled)
389 return 0;
390
391 return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC,
392 sizeof(cmd), &cmd);
393}
394
395struct iwl_d3_iter_data {
396 struct iwl_mvm *mvm;
397 struct ieee80211_vif *vif;
398 bool error;
399};
400
401static void iwl_mvm_d3_iface_iterator(void *_data, u8 *mac,
402 struct ieee80211_vif *vif)
403{
404 struct iwl_d3_iter_data *data = _data;
405 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
406
407 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
408 return;
409
410 if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
411 return;
412
413 if (data->vif) {
414 IWL_ERR(data->mvm, "More than one managed interface active!\n");
415 data->error = true;
416 return;
417 }
418
419 data->vif = vif;
420}
421
422static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
423 struct ieee80211_sta *ap_sta)
424{
425 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
426 struct ieee80211_chanctx_conf *ctx;
427 u8 chains_static, chains_dynamic;
428 struct cfg80211_chan_def chandef;
429 int ret, i;
430 struct iwl_binding_cmd binding_cmd = {};
431 struct iwl_time_quota_cmd quota_cmd = {};
432 u32 status;
433
434 /* add back the PHY */
435 if (WARN_ON(!mvmvif->phy_ctxt))
436 return -EINVAL;
437
438 rcu_read_lock();
439 ctx = rcu_dereference(vif->chanctx_conf);
440 if (WARN_ON(!ctx)) {
441 rcu_read_unlock();
442 return -EINVAL;
443 }
444 chandef = ctx->def;
445 chains_static = ctx->rx_chains_static;
446 chains_dynamic = ctx->rx_chains_dynamic;
447 rcu_read_unlock();
448
449 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef,
450 chains_static, chains_dynamic);
451 if (ret)
452 return ret;
453
454 /* add back the MAC */
455 mvmvif->uploaded = false;
456
457 if (WARN_ON(!vif->bss_conf.assoc))
458 return -EINVAL;
459 /* hack */
460 vif->bss_conf.assoc = false;
461 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
462 vif->bss_conf.assoc = true;
463 if (ret)
464 return ret;
465
466 /* add back binding - XXX refactor? */
467 binding_cmd.id_and_color =
468 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
469 mvmvif->phy_ctxt->color));
470 binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
471 binding_cmd.phy =
472 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
473 mvmvif->phy_ctxt->color));
474 binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
475 mvmvif->color));
476 for (i = 1; i < MAX_MACS_IN_BINDING; i++)
477 binding_cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
478
479 status = 0;
480 ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
481 sizeof(binding_cmd), &binding_cmd,
482 &status);
483 if (ret) {
484 IWL_ERR(mvm, "Failed to add binding: %d\n", ret);
485 return ret;
486 }
487
488 if (status) {
489 IWL_ERR(mvm, "Binding command failed: %u\n", status);
490 return -EIO;
491 }
492
493 ret = iwl_mvm_sta_add_to_fw(mvm, ap_sta);
494 if (ret)
495 return ret;
496 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
497
498 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
499 if (ret)
500 return ret;
501
502 /* and some quota */
503 quota_cmd.quotas[0].id_and_color =
504 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
505 mvmvif->phy_ctxt->color));
506 quota_cmd.quotas[0].quota = cpu_to_le32(100);
507 quota_cmd.quotas[0].max_duration = cpu_to_le32(1000);
508
509 for (i = 1; i < MAX_BINDINGS; i++)
510 quota_cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
511
512 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
513 sizeof(quota_cmd), &quota_cmd);
514 if (ret)
515 IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
516
517 return 0;
518}
519
520int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
521{
522 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
523 struct iwl_d3_iter_data suspend_iter_data = {
524 .mvm = mvm,
525 };
526 struct ieee80211_vif *vif;
527 struct iwl_mvm_vif *mvmvif;
528 struct ieee80211_sta *ap_sta;
529 struct iwl_mvm_sta *mvm_ap_sta;
530 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
531 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
532 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
533 struct iwl_d3_manager_config d3_cfg_cmd = {};
534 struct wowlan_key_data key_data = {
535 .use_rsc_tsc = false,
536 .tkip = &tkip_cmd,
537 .use_tkip = false,
538 };
539 int ret, i;
540 u16 seq;
541 u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
542
543 if (WARN_ON(!wowlan))
544 return -EINVAL;
545
546 key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
547 if (!key_data.rsc_tsc)
548 return -ENOMEM;
549
550 mutex_lock(&mvm->mutex);
551
552 old_aux_sta_id = mvm->aux_sta.sta_id;
553
554 /* see if there's only a single BSS vif and it's associated */
555 ieee80211_iterate_active_interfaces_atomic(
556 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
557 iwl_mvm_d3_iface_iterator, &suspend_iter_data);
558
559 if (suspend_iter_data.error || !suspend_iter_data.vif) {
560 ret = 1;
561 goto out_noreset;
562 }
563
564 vif = suspend_iter_data.vif;
565 mvmvif = iwl_mvm_vif_from_mac80211(vif);
566
567 ap_sta = rcu_dereference_protected(
568 mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
569 lockdep_is_held(&mvm->mutex));
570 if (IS_ERR_OR_NULL(ap_sta)) {
571 ret = -EINVAL;
572 goto out_noreset;
573 }
574
575 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
576
577 /*
578 * The D3 firmware still hardcodes the AP station ID for the
579 * BSS we're associated with as 0. Store the real STA ID here
580 * and assign 0. When we leave this function, we'll restore
581 * the original value for the resume code.
582 */
583 old_ap_sta_id = mvm_ap_sta->sta_id;
584 mvm_ap_sta->sta_id = 0;
585 mvmvif->ap_sta_id = 0;
586
587 /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */
588
589 wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported;
590
591 /*
592 * We know the last used seqno, and the uCode expects to know that
593 * one, it will increment before TX.
594 */
595 seq = mvm_ap_sta->last_seq_ctl & IEEE80211_SCTL_SEQ;
596 wowlan_config_cmd.non_qos_seq = cpu_to_le16(seq);
597
598 /*
599 * For QoS counters, we store the one to use next, so subtract 0x10
600 * since the uCode will add 0x10 *before* using the value while we
601 * increment after using the value (i.e. store the next value to use).
602 */
603 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
604 seq = mvm_ap_sta->tid_data[i].seq_number;
605 seq -= 0x10;
606 wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq);
607 }
608
609 if (wowlan->disconnect)
610 wowlan_config_cmd.wakeup_filter |=
611 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
612 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
613 if (wowlan->magic_pkt)
614 wowlan_config_cmd.wakeup_filter |=
615 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
616 if (wowlan->gtk_rekey_failure)
617 wowlan_config_cmd.wakeup_filter |=
618 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
619 if (wowlan->eap_identity_req)
620 wowlan_config_cmd.wakeup_filter |=
621 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
622 if (wowlan->four_way_handshake)
623 wowlan_config_cmd.wakeup_filter |=
624 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
625 if (wowlan->n_patterns)
626 wowlan_config_cmd.wakeup_filter |=
627 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
628
629 if (wowlan->rfkill_release)
630 d3_cfg_cmd.wakeup_flags |=
631 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
632
633 iwl_mvm_cancel_scan(mvm);
634
635 iwl_trans_stop_device(mvm->trans);
636
637 /*
638 * Set the HW restart bit -- this is mostly true as we're
639 * going to load new firmware and reprogram that, though
640 * the reprogramming is going to be manual to avoid adding
641 * all the MACs that aren't support.
642 * We don't have to clear up everything though because the
643 * reprogramming is manual. When we resume, we'll actually
644 * go through a proper restart sequence again to switch
645 * back to the runtime firmware image.
646 */
647 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
648
649 /* We reprogram keys and shouldn't allocate new key indices */
650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
651
652 /*
653 * The D3 firmware still hardcodes the AP station ID for the
654 * BSS we're associated with as 0. As a result, we have to move
655 * the auxiliary station to ID 1 so the ID 0 remains free for
656 * the AP station for later.
657 * We set the sta_id to 1 here, and reset it to its previous
658 * value (that we stored above) later.
659 */
660 mvm->aux_sta.sta_id = 1;
661
662 ret = iwl_mvm_load_d3_fw(mvm);
663 if (ret)
664 goto out;
665
666 ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
667 if (ret)
668 goto out;
669
670 if (!iwlwifi_mod_params.sw_crypto) {
671 /*
672 * This needs to be unlocked due to lock ordering
673 * constraints. Since we're in the suspend path
674 * that isn't really a problem though.
675 */
676 mutex_unlock(&mvm->mutex);
677 ieee80211_iter_keys(mvm->hw, vif,
678 iwl_mvm_wowlan_program_keys,
679 &key_data);
680 mutex_lock(&mvm->mutex);
681 if (key_data.error) {
682 ret = -EIO;
683 goto out;
684 }
685
686 if (key_data.use_rsc_tsc) {
687 struct iwl_host_cmd rsc_tsc_cmd = {
688 .id = WOWLAN_TSC_RSC_PARAM,
689 .flags = CMD_SYNC,
690 .data[0] = key_data.rsc_tsc,
691 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
692 .len[0] = sizeof(*key_data.rsc_tsc),
693 };
694
695 ret = iwl_mvm_send_cmd(mvm, &rsc_tsc_cmd);
696 if (ret)
697 goto out;
698 }
699
700 if (key_data.use_tkip) {
701 ret = iwl_mvm_send_cmd_pdu(mvm,
702 WOWLAN_TKIP_PARAM,
703 CMD_SYNC, sizeof(tkip_cmd),
704 &tkip_cmd);
705 if (ret)
706 goto out;
707 }
708
709 if (mvmvif->rekey_data.valid) {
710 memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
711 memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
712 NL80211_KCK_LEN);
713 kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN);
714 memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek,
715 NL80211_KEK_LEN);
716 kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
717 kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
718
719 ret = iwl_mvm_send_cmd_pdu(mvm,
720 WOWLAN_KEK_KCK_MATERIAL,
721 CMD_SYNC,
722 sizeof(kek_kck_cmd),
723 &kek_kck_cmd);
724 if (ret)
725 goto out;
726 }
727 }
728
729 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION,
730 CMD_SYNC, sizeof(wowlan_config_cmd),
731 &wowlan_config_cmd);
732 if (ret)
733 goto out;
734
735 ret = iwl_mvm_send_patterns(mvm, wowlan);
736 if (ret)
737 goto out;
738
739 ret = iwl_mvm_send_proto_offload(mvm, vif);
740 if (ret)
741 goto out;
742
743 /* must be last -- this switches firmware state */
744 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
745 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
746 if (ret)
747 goto out;
748
749 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
750
751 iwl_trans_d3_suspend(mvm->trans);
752 out:
753 mvm->aux_sta.sta_id = old_aux_sta_id;
754 mvm_ap_sta->sta_id = old_ap_sta_id;
755 mvmvif->ap_sta_id = old_ap_sta_id;
756 out_noreset:
757 kfree(key_data.rsc_tsc);
758 if (ret < 0)
759 ieee80211_restart_hw(mvm->hw);
760
761 mutex_unlock(&mvm->mutex);
762
763 return ret;
764}
765
766int iwl_mvm_resume(struct ieee80211_hw *hw)
767{
768 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
769 struct iwl_d3_iter_data resume_iter_data = {
770 .mvm = mvm,
771 };
772 struct ieee80211_vif *vif = NULL;
773 u32 base;
774 int ret;
775 enum iwl_d3_status d3_status;
776 struct error_table_start {
777 /* cf. struct iwl_error_event_table */
778 u32 valid;
779 u32 error_id;
780 } err_info;
781
782 mutex_lock(&mvm->mutex);
783
784 /* get the BSS vif pointer again */
785 ieee80211_iterate_active_interfaces_atomic(
786 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
787 iwl_mvm_d3_iface_iterator, &resume_iter_data);
788
789 if (WARN_ON(resume_iter_data.error || !resume_iter_data.vif))
790 goto out_unlock;
791
792 vif = resume_iter_data.vif;
793
794 ret = iwl_trans_d3_resume(mvm->trans, &d3_status);
795 if (ret)
796 goto out_unlock;
797
798 if (d3_status != IWL_D3_STATUS_ALIVE) {
799 IWL_INFO(mvm, "Device was reset during suspend\n");
800 goto out_unlock;
801 }
802
803 base = mvm->error_event_table;
804
805 iwl_trans_read_mem_bytes(mvm->trans, base,
806 &err_info, sizeof(err_info));
807
808 if (err_info.valid) {
809 IWL_INFO(mvm, "error table is valid (%d)\n",
810 err_info.valid);
811 if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN)
812 IWL_ERR(mvm, "this was due to RF-kill\n");
813 goto out_unlock;
814 }
815
816 /* TODO: get status and whatever else ... */
817 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_GET_STATUSES, CMD_SYNC, 0, NULL);
818 if (ret)
819 IWL_ERR(mvm, "failed to query status (%d)\n", ret);
820
821 ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);
822 if (ret)
823 IWL_ERR(mvm, "failed to query offloads (%d)\n", ret);
824
825 out_unlock:
826 mutex_unlock(&mvm->mutex);
827
828 if (vif)
829 ieee80211_resume_disconnect(vif);
830
831 /* return 1 to reconfigure the device */
832 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
833 return 1;
834}
835
836void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
837{
838 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
839
840 device_set_wakeup_enable(mvm->trans->dev, enabled);
841}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
new file mode 100644
index 000000000000..c1bdb5582126
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -0,0 +1,378 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include "mvm.h"
64#include "sta.h"
65#include "iwl-io.h"
66
67struct iwl_dbgfs_mvm_ctx {
68 struct iwl_mvm *mvm;
69 struct ieee80211_vif *vif;
70};
71
72static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
73{
74 file->private_data = inode->i_private;
75 return 0;
76}
77
78static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
79 const char __user *user_buf,
80 size_t count, loff_t *ppos)
81{
82 struct iwl_mvm *mvm = file->private_data;
83
84 char buf[16];
85 int buf_size, ret;
86 u32 scd_q_msk;
87
88 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
89 return -EIO;
90
91 memset(buf, 0, sizeof(buf));
92 buf_size = min(count, sizeof(buf) - 1);
93 if (copy_from_user(buf, user_buf, buf_size))
94 return -EFAULT;
95
96 if (sscanf(buf, "%x", &scd_q_msk) != 1)
97 return -EINVAL;
98
99 IWL_ERR(mvm, "FLUSHING queues: scd_q_msk = 0x%x\n", scd_q_msk);
100
101 mutex_lock(&mvm->mutex);
102 ret = iwl_mvm_flush_tx_path(mvm, scd_q_msk, true) ? : count;
103 mutex_unlock(&mvm->mutex);
104
105 return ret;
106}
107
108static ssize_t iwl_dbgfs_sta_drain_write(struct file *file,
109 const char __user *user_buf,
110 size_t count, loff_t *ppos)
111{
112 struct iwl_mvm *mvm = file->private_data;
113 struct ieee80211_sta *sta;
114
115 char buf[8];
116 int buf_size, sta_id, drain, ret;
117
118 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
119 return -EIO;
120
121 memset(buf, 0, sizeof(buf));
122 buf_size = min(count, sizeof(buf) - 1);
123 if (copy_from_user(buf, user_buf, buf_size))
124 return -EFAULT;
125
126 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
127 return -EINVAL;
128
129 mutex_lock(&mvm->mutex);
130
131 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
132 lockdep_is_held(&mvm->mutex));
133 if (IS_ERR_OR_NULL(sta))
134 ret = -ENOENT;
135 else
136 ret = iwl_mvm_drain_sta(mvm, (void *)sta->drv_priv, drain) ? :
137 count;
138
139 mutex_unlock(&mvm->mutex);
140
141 return ret;
142}
143
144static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
145 size_t count, loff_t *ppos)
146{
147 struct iwl_mvm *mvm = file->private_data;
148 const struct fw_img *img;
149 int ofs, len, pos = 0;
150 size_t bufsz, ret;
151 char *buf;
152 u8 *ptr;
153
154 /* default is to dump the entire data segment */
155 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
156 mvm->dbgfs_sram_offset = 0x800000;
157 if (!mvm->ucode_loaded)
158 return -EINVAL;
159 img = &mvm->fw->img[mvm->cur_ucode];
160 mvm->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
161 }
162 len = mvm->dbgfs_sram_len;
163
164 bufsz = len * 4 + 256;
165 buf = kzalloc(bufsz, GFP_KERNEL);
166 if (!buf)
167 return -ENOMEM;
168
169 ptr = kzalloc(len, GFP_KERNEL);
170 if (!ptr) {
171 kfree(buf);
172 return -ENOMEM;
173 }
174
175 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
176 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
177 mvm->dbgfs_sram_offset);
178
179 iwl_trans_read_mem_bytes(mvm->trans,
180 mvm->dbgfs_sram_offset,
181 ptr, len);
182 for (ofs = 0; ofs < len; ofs += 16) {
183 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
184 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
185 bufsz - pos, false);
186 pos += strlen(buf + pos);
187 if (bufsz - pos > 0)
188 buf[pos++] = '\n';
189 }
190
191 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
192
193 kfree(buf);
194 kfree(ptr);
195
196 return ret;
197}
198
199static ssize_t iwl_dbgfs_sram_write(struct file *file,
200 const char __user *user_buf, size_t count,
201 loff_t *ppos)
202{
203 struct iwl_mvm *mvm = file->private_data;
204 char buf[64];
205 int buf_size;
206 u32 offset, len;
207
208 memset(buf, 0, sizeof(buf));
209 buf_size = min(count, sizeof(buf) - 1);
210 if (copy_from_user(buf, user_buf, buf_size))
211 return -EFAULT;
212
213 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
214 if ((offset & 0x3) || (len & 0x3))
215 return -EINVAL;
216 mvm->dbgfs_sram_offset = offset;
217 mvm->dbgfs_sram_len = len;
218 } else {
219 mvm->dbgfs_sram_offset = 0;
220 mvm->dbgfs_sram_len = 0;
221 }
222
223 return count;
224}
225
226static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
227 size_t count, loff_t *ppos)
228{
229 struct iwl_mvm *mvm = file->private_data;
230 struct ieee80211_sta *sta;
231 char buf[400];
232 int i, pos = 0, bufsz = sizeof(buf);
233
234 mutex_lock(&mvm->mutex);
235
236 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
237 pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
238 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
239 lockdep_is_held(&mvm->mutex));
240 if (!sta)
241 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
242 else if (IS_ERR(sta))
243 pos += scnprintf(buf + pos, bufsz - pos, "%ld\n",
244 PTR_ERR(sta));
245 else
246 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
247 sta->addr);
248 }
249
250 mutex_unlock(&mvm->mutex);
251
252 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
253}
254
255static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file,
256 const char __user *user_buf,
257 size_t count, loff_t *ppos)
258{
259 struct iwl_mvm *mvm = file->private_data;
260 char buf[8] = {};
261 int allow;
262
263 if (!mvm->ucode_loaded)
264 return -EIO;
265
266 if (copy_from_user(buf, user_buf, sizeof(buf)))
267 return -EFAULT;
268
269 if (sscanf(buf, "%d", &allow) != 1)
270 return -EINVAL;
271
272 IWL_DEBUG_POWER(mvm, "%s device power down\n",
273 allow ? "allow" : "prevent");
274
275 /*
276 * TODO: Send REPLY_DEBUG_CMD (0xf0) when FW support it
277 */
278
279 return count;
280}
281
282static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
283 const char __user *user_buf,
284 size_t count, loff_t *ppos)
285{
286 struct iwl_mvm *mvm = file->private_data;
287 char buf[8] = {};
288 int allow;
289
290 if (copy_from_user(buf, user_buf, sizeof(buf)))
291 return -EFAULT;
292
293 if (sscanf(buf, "%d", &allow) != 1)
294 return -EINVAL;
295
296 IWL_DEBUG_POWER(mvm, "%s device power down in d3\n",
297 allow ? "allow" : "prevent");
298
299 /*
300 * TODO: When WoWLAN FW alive notification happens, driver will send
301 * REPLY_DEBUG_CMD setting power_down_allow flag according to
302 * mvm->prevent_power_down_d3
303 */
304 mvm->prevent_power_down_d3 = !allow;
305
306 return count;
307}
308
309#define MVM_DEBUGFS_READ_FILE_OPS(name) \
310static const struct file_operations iwl_dbgfs_##name##_ops = { \
311 .read = iwl_dbgfs_##name##_read, \
312 .open = iwl_dbgfs_open_file_generic, \
313 .llseek = generic_file_llseek, \
314}
315
316#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name) \
317static const struct file_operations iwl_dbgfs_##name##_ops = { \
318 .write = iwl_dbgfs_##name##_write, \
319 .read = iwl_dbgfs_##name##_read, \
320 .open = iwl_dbgfs_open_file_generic, \
321 .llseek = generic_file_llseek, \
322};
323
324#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
325static const struct file_operations iwl_dbgfs_##name##_ops = { \
326 .write = iwl_dbgfs_##name##_write, \
327 .open = iwl_dbgfs_open_file_generic, \
328 .llseek = generic_file_llseek, \
329};
330
331#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
332 if (!debugfs_create_file(#name, mode, parent, mvm, \
333 &iwl_dbgfs_##name##_ops)) \
334 goto err; \
335 } while (0)
336
337#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
338 if (!debugfs_create_file(#name, mode, parent, vif, \
339 &iwl_dbgfs_##name##_ops)) \
340 goto err; \
341 } while (0)
342
343/* Device wide debugfs entries */
344MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush);
345MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
346MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
347MVM_DEBUGFS_READ_FILE_OPS(stations);
348MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
349MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
350
351int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
352{
353 char buf[100];
354
355 mvm->debugfs_dir = dbgfs_dir;
356
357 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR);
358 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
359 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
360 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
361 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
362 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
363
364 /*
365 * Create a symlink with mac80211. It will be removed when mac80211
366 * exists (before the opmode exists which removes the target.)
367 */
368 snprintf(buf, 100, "../../%s/%s",
369 dbgfs_dir->d_parent->d_parent->d_name.name,
370 dbgfs_dir->d_parent->d_name.name);
371 if (!debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf))
372 goto err;
373
374 return 0;
375err:
376 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
377 return -ENOMEM;
378}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
new file mode 100644
index 000000000000..cf6f9a02fb74
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -0,0 +1,282 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_d3_h__
64#define __fw_api_d3_h__
65
66/**
67 * enum iwl_d3_wakeup_flags - D3 manager wakeup flags
68 * @IWL_WAKEUP_D3_CONFIG_FW_ERROR: wake up on firmware sysassert
69 */
70enum iwl_d3_wakeup_flags {
71 IWL_WAKEUP_D3_CONFIG_FW_ERROR = BIT(0),
72}; /* D3_MANAGER_WAKEUP_CONFIG_API_E_VER_3 */
73
74/**
75 * struct iwl_d3_manager_config - D3 manager configuration command
76 * @min_sleep_time: minimum sleep time (in usec)
77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags
78 *
79 * The structure is used for the D3_CONFIG_CMD command.
80 */
81struct iwl_d3_manager_config {
82 __le32 min_sleep_time;
83 __le32 wakeup_flags;
84} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_3 */
85
86
87/* TODO: OFFLOADS_QUERY_API_S_VER_1 */
88
89/**
90 * enum iwl_d3_proto_offloads - enabled protocol offloads
91 * @IWL_D3_PROTO_OFFLOAD_ARP: ARP data is enabled
92 * @IWL_D3_PROTO_OFFLOAD_NS: NS (Neighbor Solicitation) is enabled
93 */
94enum iwl_proto_offloads {
95 IWL_D3_PROTO_OFFLOAD_ARP = BIT(0),
96 IWL_D3_PROTO_OFFLOAD_NS = BIT(1),
97};
98
99#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS 2
100
101/**
102 * struct iwl_proto_offload_cmd - ARP/NS offload configuration
103 * @enabled: enable flags
104 * @remote_ipv4_addr: remote address to answer to (or zero if all)
105 * @host_ipv4_addr: our IPv4 address to respond to queries for
106 * @arp_mac_addr: our MAC address for ARP responses
107 * @remote_ipv6_addr: remote address to answer to (or zero if all)
108 * @solicited_node_ipv6_addr: broken -- solicited node address exists
109 * for each target address
110 * @target_ipv6_addr: our target addresses
111 * @ndp_mac_addr: neighbor soliciation response MAC address
112 */
113struct iwl_proto_offload_cmd {
114 __le32 enabled;
115 __be32 remote_ipv4_addr;
116 __be32 host_ipv4_addr;
117 u8 arp_mac_addr[ETH_ALEN];
118 __le16 reserved1;
119
120 u8 remote_ipv6_addr[16];
121 u8 solicited_node_ipv6_addr[16];
122 u8 target_ipv6_addr[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS][16];
123 u8 ndp_mac_addr[ETH_ALEN];
124 __le16 reserved2;
125} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_1 */
126
127
128/*
129 * WOWLAN_PATTERNS
130 */
131#define IWL_WOWLAN_MIN_PATTERN_LEN 16
132#define IWL_WOWLAN_MAX_PATTERN_LEN 128
133
134struct iwl_wowlan_pattern {
135 u8 mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
136 u8 pattern[IWL_WOWLAN_MAX_PATTERN_LEN];
137 u8 mask_size;
138 u8 pattern_size;
139 __le16 reserved;
140} __packed; /* WOWLAN_PATTERN_API_S_VER_1 */
141
142#define IWL_WOWLAN_MAX_PATTERNS 20
143
144struct iwl_wowlan_patterns_cmd {
145 __le32 n_patterns;
146 struct iwl_wowlan_pattern patterns[];
147} __packed; /* WOWLAN_PATTERN_ARRAY_API_S_VER_1 */
148
149enum iwl_wowlan_wakeup_filters {
150 IWL_WOWLAN_WAKEUP_MAGIC_PACKET = BIT(0),
151 IWL_WOWLAN_WAKEUP_PATTERN_MATCH = BIT(1),
152 IWL_WOWLAN_WAKEUP_BEACON_MISS = BIT(2),
153 IWL_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3),
154 IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4),
155 IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5),
156 IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6),
157 IWL_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(7),
158 IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT = BIT(8),
159 IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS = BIT(9),
160 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE = BIT(10),
161 /* BIT(11) reserved */
162 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET = BIT(12),
163}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
164
165struct iwl_wowlan_config_cmd {
166 __le32 wakeup_filter;
167 __le16 non_qos_seq;
168 __le16 qos_seq[8];
169 u8 wowlan_ba_teardown_tids;
170 u8 is_11n_connection;
171} __packed; /* WOWLAN_CONFIG_API_S_VER_2 */
172
173/*
174 * WOWLAN_TSC_RSC_PARAMS
175 */
176#define IWL_NUM_RSC 16
177
178struct tkip_sc {
179 __le16 iv16;
180 __le16 pad;
181 __le32 iv32;
182} __packed; /* TKIP_SC_API_U_VER_1 */
183
184struct iwl_tkip_rsc_tsc {
185 struct tkip_sc unicast_rsc[IWL_NUM_RSC];
186 struct tkip_sc multicast_rsc[IWL_NUM_RSC];
187 struct tkip_sc tsc;
188} __packed; /* TKIP_TSC_RSC_API_S_VER_1 */
189
190struct aes_sc {
191 __le64 pn;
192} __packed; /* TKIP_AES_SC_API_U_VER_1 */
193
194struct iwl_aes_rsc_tsc {
195 struct aes_sc unicast_rsc[IWL_NUM_RSC];
196 struct aes_sc multicast_rsc[IWL_NUM_RSC];
197 struct aes_sc tsc;
198} __packed; /* AES_TSC_RSC_API_S_VER_1 */
199
200union iwl_all_tsc_rsc {
201 struct iwl_tkip_rsc_tsc tkip;
202 struct iwl_aes_rsc_tsc aes;
203}; /* ALL_TSC_RSC_API_S_VER_2 */
204
205struct iwl_wowlan_rsc_tsc_params_cmd {
206 union iwl_all_tsc_rsc all_tsc_rsc;
207} __packed; /* ALL_TSC_RSC_API_S_VER_2 */
208
209#define IWL_MIC_KEY_SIZE 8
210struct iwl_mic_keys {
211 u8 tx[IWL_MIC_KEY_SIZE];
212 u8 rx_unicast[IWL_MIC_KEY_SIZE];
213 u8 rx_mcast[IWL_MIC_KEY_SIZE];
214} __packed; /* MIC_KEYS_API_S_VER_1 */
215
216#define IWL_P1K_SIZE 5
217struct iwl_p1k_cache {
218 __le16 p1k[IWL_P1K_SIZE];
219} __packed;
220
221#define IWL_NUM_RX_P1K_CACHE 2
222
223struct iwl_wowlan_tkip_params_cmd {
224 struct iwl_mic_keys mic_keys;
225 struct iwl_p1k_cache tx;
226 struct iwl_p1k_cache rx_uni[IWL_NUM_RX_P1K_CACHE];
227 struct iwl_p1k_cache rx_multi[IWL_NUM_RX_P1K_CACHE];
228} __packed; /* WOWLAN_TKIP_SETTING_API_S_VER_1 */
229
230#define IWL_KCK_MAX_SIZE 32
231#define IWL_KEK_MAX_SIZE 32
232
233struct iwl_wowlan_kek_kck_material_cmd {
234 u8 kck[IWL_KCK_MAX_SIZE];
235 u8 kek[IWL_KEK_MAX_SIZE];
236 __le16 kck_len;
237 __le16 kek_len;
238 __le64 replay_ctr;
239} __packed; /* KEK_KCK_MATERIAL_API_S_VER_2 */
240
241#define RF_KILL_INDICATOR_FOR_WOWLAN 0x87
242
243enum iwl_wowlan_rekey_status {
244 IWL_WOWLAN_REKEY_POST_REKEY = 0,
245 IWL_WOWLAN_REKEY_WHILE_REKEY = 1,
246}; /* WOWLAN_REKEY_STATUS_API_E_VER_1 */
247
248enum iwl_wowlan_wakeup_reason {
249 IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS = 0,
250 IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET = BIT(0),
251 IWL_WOWLAN_WAKEUP_BY_PATTERN = BIT(1),
252 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON = BIT(2),
253 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH = BIT(3),
254 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE = BIT(4),
255 IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED = BIT(5),
256 IWL_WOWLAN_WAKEUP_BY_UCODE_ERROR = BIT(6),
257 IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST = BIT(7),
258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8),
259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9),
260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10),
261 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11),
262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
264
265struct iwl_wowlan_status {
266 __le64 replay_ctr;
267 __le16 pattern_number;
268 __le16 non_qos_seq_ctr;
269 __le16 qos_seq_ctr[8];
270 __le32 wakeup_reasons;
271 __le32 rekey_status;
272 __le32 num_of_gtk_rekeys;
273 __le32 transmitted_ndps;
274 __le32 received_beacons;
275 __le32 wake_packet_length;
276 __le32 wake_packet_bufsize;
277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
279
280/* TODO: NetDetect API */
281
282#endif /* __fw_api_d3_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
new file mode 100644
index 000000000000..ae39b7dfda7b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -0,0 +1,369 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_mac_h__
64#define __fw_api_mac_h__
65
66/*
67 * The first MAC indices (starting from 0)
68 * are available to the driver, AUX follows
69 */
70#define MAC_INDEX_AUX 4
71#define MAC_INDEX_MIN_DRIVER 0
72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
73
74#define AC_NUM 4 /* Number of access categories */
75
76/**
77 * enum iwl_mac_protection_flags - MAC context flags
78 * @MAC_PROT_FLG_TGG_PROTECT: 11g protection when transmitting OFDM frames,
79 * this will require CCK RTS/CTS2self.
80 * RTS/CTS will protect full burst time.
81 * @MAC_PROT_FLG_HT_PROT: enable HT protection
82 * @MAC_PROT_FLG_FAT_PROT: protect 40 MHz transmissions
83 * @MAC_PROT_FLG_SELF_CTS_EN: allow CTS2self
84 */
85enum iwl_mac_protection_flags {
86 MAC_PROT_FLG_TGG_PROTECT = BIT(3),
87 MAC_PROT_FLG_HT_PROT = BIT(23),
88 MAC_PROT_FLG_FAT_PROT = BIT(24),
89 MAC_PROT_FLG_SELF_CTS_EN = BIT(30),
90};
91
92#define MAC_FLG_SHORT_SLOT BIT(4)
93#define MAC_FLG_SHORT_PREAMBLE BIT(5)
94
95/**
96 * enum iwl_mac_types - Supported MAC types
97 * @FW_MAC_TYPE_FIRST: lowest supported MAC type
98 * @FW_MAC_TYPE_AUX: Auxiliary MAC (internal)
99 * @FW_MAC_TYPE_LISTENER: monitor MAC type (?)
100 * @FW_MAC_TYPE_PIBSS: Pseudo-IBSS
101 * @FW_MAC_TYPE_IBSS: IBSS
102 * @FW_MAC_TYPE_BSS_STA: BSS (managed) station
103 * @FW_MAC_TYPE_P2P_DEVICE: P2P Device
104 * @FW_MAC_TYPE_P2P_STA: P2P client
105 * @FW_MAC_TYPE_GO: P2P GO
106 * @FW_MAC_TYPE_TEST: ?
107 * @FW_MAC_TYPE_MAX: highest support MAC type
108 */
109enum iwl_mac_types {
110 FW_MAC_TYPE_FIRST = 1,
111 FW_MAC_TYPE_AUX = FW_MAC_TYPE_FIRST,
112 FW_MAC_TYPE_LISTENER,
113 FW_MAC_TYPE_PIBSS,
114 FW_MAC_TYPE_IBSS,
115 FW_MAC_TYPE_BSS_STA,
116 FW_MAC_TYPE_P2P_DEVICE,
117 FW_MAC_TYPE_P2P_STA,
118 FW_MAC_TYPE_GO,
119 FW_MAC_TYPE_TEST,
120 FW_MAC_TYPE_MAX = FW_MAC_TYPE_TEST
121}; /* MAC_CONTEXT_TYPE_API_E_VER_1 */
122
123/**
124 * enum iwl_tsf_id - TSF hw timer ID
125 * @TSF_ID_A: use TSF A
126 * @TSF_ID_B: use TSF B
127 * @TSF_ID_C: use TSF C
128 * @TSF_ID_D: use TSF D
129 * @NUM_TSF_IDS: number of TSF timers available
130 */
131enum iwl_tsf_id {
132 TSF_ID_A = 0,
133 TSF_ID_B = 1,
134 TSF_ID_C = 2,
135 TSF_ID_D = 3,
136 NUM_TSF_IDS = 4,
137}; /* TSF_ID_API_E_VER_1 */
138
139/**
140 * struct iwl_mac_data_ap - configuration data for AP MAC context
141 * @beacon_time: beacon transmit time in system time
142 * @beacon_tsf: beacon transmit time in TSF
143 * @bi: beacon interval in TU
144 * @bi_reciprocal: 2^32 / bi
145 * @dtim_interval: dtim transmit time in TU
146 * @dtim_reciprocal: 2^32 / dtim_interval
147 * @mcast_qid: queue ID for multicast traffic
148 * @beacon_template: beacon template ID
149 */
150struct iwl_mac_data_ap {
151 __le32 beacon_time;
152 __le64 beacon_tsf;
153 __le32 bi;
154 __le32 bi_reciprocal;
155 __le32 dtim_interval;
156 __le32 dtim_reciprocal;
157 __le32 mcast_qid;
158 __le32 beacon_template;
159} __packed; /* AP_MAC_DATA_API_S_VER_1 */
160
161/**
162 * struct iwl_mac_data_ibss - configuration data for IBSS MAC context
163 * @beacon_time: beacon transmit time in system time
164 * @beacon_tsf: beacon transmit time in TSF
165 * @bi: beacon interval in TU
166 * @bi_reciprocal: 2^32 / bi
167 */
168struct iwl_mac_data_ibss {
169 __le32 beacon_time;
170 __le64 beacon_tsf;
171 __le32 bi;
172 __le32 bi_reciprocal;
173} __packed; /* IBSS_MAC_DATA_API_S_VER_1 */
174
175/**
176 * struct iwl_mac_data_sta - configuration data for station MAC context
177 * @is_assoc: 1 for associated state, 0 otherwise
178 * @dtim_time: DTIM arrival time in system time
179 * @dtim_tsf: DTIM arrival time in TSF
180 * @bi: beacon interval in TU, applicable only when associated
181 * @bi_reciprocal: 2^32 / bi , applicable only when associated
182 * @dtim_interval: DTIM interval in TU, applicable only when associated
183 * @dtim_reciprocal: 2^32 / dtim_interval , applicable only when associated
184 * @listen_interval: in beacon intervals, applicable only when associated
185 * @assoc_id: unique ID assigned by the AP during association
186 */
187struct iwl_mac_data_sta {
188 __le32 is_assoc;
189 __le32 dtim_time;
190 __le64 dtim_tsf;
191 __le32 bi;
192 __le32 bi_reciprocal;
193 __le32 dtim_interval;
194 __le32 dtim_reciprocal;
195 __le32 listen_interval;
196 __le32 assoc_id;
197 __le32 assoc_beacon_arrive_time;
198} __packed; /* STA_MAC_DATA_API_S_VER_1 */
199
200/**
201 * struct iwl_mac_data_go - configuration data for P2P GO MAC context
202 * @ap: iwl_mac_data_ap struct with most config data
203 * @ctwin: client traffic window in TU (period after TBTT when GO is present).
204 * 0 indicates that there is no CT window.
205 * @opp_ps_enabled: indicate that opportunistic PS allowed
206 */
207struct iwl_mac_data_go {
208 struct iwl_mac_data_ap ap;
209 __le32 ctwin;
210 __le32 opp_ps_enabled;
211} __packed; /* GO_MAC_DATA_API_S_VER_1 */
212
213/**
214 * struct iwl_mac_data_p2p_sta - configuration data for P2P client MAC context
215 * @sta: iwl_mac_data_sta struct with most config data
216 * @ctwin: client traffic window in TU (period after TBTT when GO is present).
217 * 0 indicates that there is no CT window.
218 */
219struct iwl_mac_data_p2p_sta {
220 struct iwl_mac_data_sta sta;
221 __le32 ctwin;
222} __packed; /* P2P_STA_MAC_DATA_API_S_VER_1 */
223
224/**
225 * struct iwl_mac_data_pibss - Pseudo IBSS config data
226 * @stats_interval: interval in TU between statistics notifications to host.
227 */
228struct iwl_mac_data_pibss {
229 __le32 stats_interval;
230} __packed; /* PIBSS_MAC_DATA_API_S_VER_1 */
231
232/*
233 * struct iwl_mac_data_p2p_dev - configuration data for the P2P Device MAC
234 * context.
235 * @is_disc_extended: if set to true, P2P Device discoverability is enabled on
236 * other channels as well. This should be to true only in case that the
237 * device is discoverable and there is an active GO. Note that setting this
238 * field when not needed, will increase the number of interrupts and have
239 * effect on the platform power, as this setting opens the Rx filters on
240 * all macs.
241 */
242struct iwl_mac_data_p2p_dev {
243 __le32 is_disc_extended;
244} __packed; /* _P2P_DEV_MAC_DATA_API_S_VER_1 */
245
246/**
247 * enum iwl_mac_filter_flags - MAC context filter flags
248 * @MAC_FILTER_IN_PROMISC: accept all data frames
249 * @MAC_FILTER_IN_CONTROL_AND_MGMT: pass all mangement and
250 * control frames to the host
251 * @MAC_FILTER_ACCEPT_GRP: accept multicast frames
252 * @MAC_FILTER_DIS_DECRYPT: don't decrypt unicast frames
253 * @MAC_FILTER_DIS_GRP_DECRYPT: don't decrypt multicast frames
254 * @MAC_FILTER_IN_BEACON: transfer foreign BSS's beacons to host
255 * (in station mode when associated)
256 * @MAC_FILTER_OUT_BCAST: filter out all broadcast frames
257 * @MAC_FILTER_IN_CRC32: extract FCS and append it to frames
258 * @MAC_FILTER_IN_PROBE_REQUEST: pass probe requests to host
259 */
260enum iwl_mac_filter_flags {
261 MAC_FILTER_IN_PROMISC = BIT(0),
262 MAC_FILTER_IN_CONTROL_AND_MGMT = BIT(1),
263 MAC_FILTER_ACCEPT_GRP = BIT(2),
264 MAC_FILTER_DIS_DECRYPT = BIT(3),
265 MAC_FILTER_DIS_GRP_DECRYPT = BIT(4),
266 MAC_FILTER_IN_BEACON = BIT(6),
267 MAC_FILTER_OUT_BCAST = BIT(8),
268 MAC_FILTER_IN_CRC32 = BIT(11),
269 MAC_FILTER_IN_PROBE_REQUEST = BIT(12),
270};
271
272/**
273 * enum iwl_mac_qos_flags - QoS flags
274 * @MAC_QOS_FLG_UPDATE_EDCA: ?
275 * @MAC_QOS_FLG_TGN: HT is enabled
276 * @MAC_QOS_FLG_TXOP_TYPE: ?
277 *
278 */
279enum iwl_mac_qos_flags {
280 MAC_QOS_FLG_UPDATE_EDCA = BIT(0),
281 MAC_QOS_FLG_TGN = BIT(1),
282 MAC_QOS_FLG_TXOP_TYPE = BIT(4),
283};
284
285/**
286 * struct iwl_ac_qos - QOS timing params for MAC_CONTEXT_CMD
287 * @cw_min: Contention window, start value in numbers of slots.
288 * Should be a power-of-2, minus 1. Device's default is 0x0f.
289 * @cw_max: Contention window, max value in numbers of slots.
290 * Should be a power-of-2, minus 1. Device's default is 0x3f.
291 * @aifsn: Number of slots in Arbitration Interframe Space (before
292 * performing random backoff timing prior to Tx). Device default 1.
293 * @fifos_mask: FIFOs used by this MAC for this AC
294 * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0.
295 *
296 * One instance of this config struct for each of 4 EDCA access categories
297 * in struct iwl_qosparam_cmd.
298 *
299 * Device will automatically increase contention window by (2*CW) + 1 for each
300 * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW
301 * value, to cap the CW value.
302 */
303struct iwl_ac_qos {
304 __le16 cw_min;
305 __le16 cw_max;
306 u8 aifsn;
307 u8 fifos_mask;
308 __le16 edca_txop;
309} __packed; /* AC_QOS_API_S_VER_2 */
310
311/**
312 * struct iwl_mac_ctx_cmd - command structure to configure MAC contexts
313 * ( MAC_CONTEXT_CMD = 0x28 )
314 * @id_and_color: ID and color of the MAC
315 * @action: action to perform, one of FW_CTXT_ACTION_*
316 * @mac_type: one of FW_MAC_TYPE_*
317 * @tsd_id: TSF HW timer, one of TSF_ID_*
318 * @node_addr: MAC address
319 * @bssid_addr: BSSID
320 * @cck_rates: basic rates available for CCK
321 * @ofdm_rates: basic rates available for OFDM
322 * @protection_flags: combination of MAC_PROT_FLG_FLAG_*
323 * @cck_short_preamble: 0x20 for enabling short preamble, 0 otherwise
324 * @short_slot: 0x10 for enabling short slots, 0 otherwise
325 * @filter_flags: combination of MAC_FILTER_*
326 * @qos_flags: from MAC_QOS_FLG_*
327 * @ac: one iwl_mac_qos configuration for each AC
328 * @mac_specific: one of struct iwl_mac_data_*, according to mac_type
329 */
330struct iwl_mac_ctx_cmd {
331 /* COMMON_INDEX_HDR_API_S_VER_1 */
332 __le32 id_and_color;
333 __le32 action;
334 /* MAC_CONTEXT_COMMON_DATA_API_S_VER_1 */
335 __le32 mac_type;
336 __le32 tsf_id;
337 u8 node_addr[6];
338 __le16 reserved_for_node_addr;
339 u8 bssid_addr[6];
340 __le16 reserved_for_bssid_addr;
341 __le32 cck_rates;
342 __le32 ofdm_rates;
343 __le32 protection_flags;
344 __le32 cck_short_preamble;
345 __le32 short_slot;
346 __le32 filter_flags;
347 /* MAC_QOS_PARAM_API_S_VER_1 */
348 __le32 qos_flags;
349 struct iwl_ac_qos ac[AC_NUM+1];
350 /* MAC_CONTEXT_COMMON_DATA_API_S */
351 union {
352 struct iwl_mac_data_ap ap;
353 struct iwl_mac_data_go go;
354 struct iwl_mac_data_sta sta;
355 struct iwl_mac_data_p2p_sta p2p_sta;
356 struct iwl_mac_data_p2p_dev p2p_dev;
357 struct iwl_mac_data_pibss pibss;
358 struct iwl_mac_data_ibss ibss;
359 };
360} __packed; /* MAC_CONTEXT_CMD_API_S_VER_1 */
361
362static inline u32 iwl_mvm_reciprocal(u32 v)
363{
364 if (!v)
365 return 0;
366 return 0xFFFFFFFF / v;
367}
368
369#endif /* __fw_api_mac_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
new file mode 100644
index 000000000000..be36b7604b7f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -0,0 +1,140 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __fw_api_power_h__
65#define __fw_api_power_h__
66
67/* Power Management Commands, Responses, Notifications */
68
69/**
70 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
72 * '1' Driver enables PM (use rest of parameters)
73 * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
74 * '1' PM could sleep over DTIM till listen Interval.
75 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
76 * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
77 * access categories are both delivery and trigger enabled.
78 * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
79 * PBW Snoozing enabled
80 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
81*/
82enum iwl_power_flags {
83 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0),
84 POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1),
85 POWER_FLAGS_LPRX_ENA_MSK = BIT(2),
86 POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3),
87 POWER_FLAGS_BT_SCO_ENA = BIT(4),
88 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5)
89};
90
91/**
92 * struct iwl_powertable_cmd - Power Table Command
93 * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
94 *
95 * @id_and_color: MAC contex identifier
96 * @action: Action on context - no action, add new,
97 * modify existent, remove
98 * @flags: Power table command flags from POWER_FLAGS_*
99 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec.
100 * Minimum allowed:- 3 * DTIM
101 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to
102 * PSM transition - legacy PM
103 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
104 * PSM transition - legacy PM
105 * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to
106 * PSM transition - uAPSD
107 * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
108 * PSM transition - uAPSD
109 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
110 * Default: 80dbm
111 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
112 * @snooze_interval: TBD
113 * @snooze_window: TBD
114 * @snooze_step: TBD
115 * @qndp_tid: TBD
116 * @uapsd_ac_flags: TBD
117 * @uapsd_max_sp: TBD
118 */
119struct iwl_powertable_cmd {
120 /* COMMON_INDEX_HDR_API_S_VER_1 */
121 __le32 id_and_color;
122 __le32 action;
123 __le16 flags;
124 u8 reserved;
125 __le16 keep_alive_seconds;
126 __le32 rx_data_timeout;
127 __le32 tx_data_timeout;
128 __le32 rx_data_timeout_uapsd;
129 __le32 tx_data_timeout_uapsd;
130 u8 lprx_rssi_threshold;
131 u8 num_skip_dtim;
132 __le16 snooze_interval;
133 __le16 snooze_window;
134 u8 snooze_step;
135 u8 qndp_tid;
136 u8 uapsd_ac_flags;
137 u8 uapsd_max_sp;
138} __packed;
139
140#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
new file mode 100644
index 000000000000..aa3474d08231
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -0,0 +1,312 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_rs_h__
64#define __fw_api_rs_h__
65
66#include "fw-api-mac.h"
67
68/*
69 * These serve as indexes into
70 * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
71 */
72enum {
73 IWL_RATE_1M_INDEX = 0,
74 IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
75 IWL_RATE_2M_INDEX,
76 IWL_RATE_5M_INDEX,
77 IWL_RATE_11M_INDEX,
78 IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
79 IWL_RATE_6M_INDEX,
80 IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
81 IWL_RATE_9M_INDEX,
82 IWL_RATE_12M_INDEX,
83 IWL_RATE_18M_INDEX,
84 IWL_RATE_24M_INDEX,
85 IWL_RATE_36M_INDEX,
86 IWL_RATE_48M_INDEX,
87 IWL_RATE_54M_INDEX,
88 IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX,
89 IWL_RATE_60M_INDEX,
90 IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
91 IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1,
92 IWL_RATE_COUNT,
93};
94
95#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
96
97/* fw API values for legacy bit rates, both OFDM and CCK */
98enum {
99 IWL_RATE_6M_PLCP = 13,
100 IWL_RATE_9M_PLCP = 15,
101 IWL_RATE_12M_PLCP = 5,
102 IWL_RATE_18M_PLCP = 7,
103 IWL_RATE_24M_PLCP = 9,
104 IWL_RATE_36M_PLCP = 11,
105 IWL_RATE_48M_PLCP = 1,
106 IWL_RATE_54M_PLCP = 3,
107 IWL_RATE_1M_PLCP = 10,
108 IWL_RATE_2M_PLCP = 20,
109 IWL_RATE_5M_PLCP = 55,
110 IWL_RATE_11M_PLCP = 110,
111};
112
113/*
114 * rate_n_flags bit fields
115 *
116 * The 32-bit value has different layouts in the low 8 bites depending on the
117 * format. There are three formats, HT, VHT and legacy (11abg, with subformats
118 * for CCK and OFDM).
119 *
120 * High-throughput (HT) rate format
121 * bit 8 is 1, bit 26 is 0, bit 9 is 0 (OFDM)
122 * Very High-throughput (VHT) rate format
123 * bit 8 is 0, bit 26 is 1, bit 9 is 0 (OFDM)
124 * Legacy OFDM rate format for bits 7:0
125 * bit 8 is 0, bit 26 is 0, bit 9 is 0 (OFDM)
126 * Legacy CCK rate format for bits 7:0:
127 * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK)
128 */
129
130/* Bit 8: (1) HT format, (0) legacy or VHT format */
131#define RATE_MCS_HT_POS 8
132#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS)
133
134/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */
135#define RATE_MCS_CCK_POS 9
136#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS)
137
138/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */
139#define RATE_MCS_VHT_POS 26
140#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS)
141
142
143/*
144 * High-throughput (HT) rate format for bits 7:0
145 *
146 * 2-0: MCS rate base
147 * 0) 6 Mbps
148 * 1) 12 Mbps
149 * 2) 18 Mbps
150 * 3) 24 Mbps
151 * 4) 36 Mbps
152 * 5) 48 Mbps
153 * 6) 54 Mbps
154 * 7) 60 Mbps
155 * 4-3: 0) Single stream (SISO)
156 * 1) Dual stream (MIMO)
157 * 2) Triple stream (MIMO)
158 * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data
159 * (bits 7-6 are zero)
160 *
161 * Together the low 5 bits work out to the MCS index because we don't
162 * support MCSes above 15/23, and 0-7 have one stream, 8-15 have two
163 * streams and 16-23 have three streams. We could also support MCS 32
164 * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
165 */
166#define RATE_HT_MCS_RATE_CODE_MSK 0x7
167
168/* Bit 10: (1) Use Green Field preamble */
169#define RATE_HT_MCS_GF_POS 10
170#define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS)
171
172#define RATE_HT_MCS_INDEX_MSK 0x3f
173
174/*
175 * Very High-throughput (VHT) rate format for bits 7:0
176 *
177 * 3-0: VHT MCS (0-9)
178 * 5-4: number of streams - 1:
179 * 0) Single stream (SISO)
180 * 1) Dual stream (MIMO)
181 * 2) Triple stream (MIMO)
182 */
183
184/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */
185#define RATE_VHT_MCS_RATE_CODE_MSK 0xf
186#define RATE_VHT_MCS_NSS_POS 4
187#define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS)
188
189/*
190 * Legacy OFDM rate format for bits 7:0
191 *
192 * 3-0: 0xD) 6 Mbps
193 * 0xF) 9 Mbps
194 * 0x5) 12 Mbps
195 * 0x7) 18 Mbps
196 * 0x9) 24 Mbps
197 * 0xB) 36 Mbps
198 * 0x1) 48 Mbps
199 * 0x3) 54 Mbps
200 * (bits 7-4 are 0)
201 *
202 * Legacy CCK rate format for bits 7:0:
203 * bit 8 is 0, bit 26 is 0, bit 9 is 1 (CCK):
204 *
205 * 6-0: 10) 1 Mbps
206 * 20) 2 Mbps
207 * 55) 5.5 Mbps
208 * 110) 11 Mbps
209 * (bit 7 is 0)
210 */
211#define RATE_LEGACY_RATE_MSK 0xff
212
213
214/*
215 * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz
216 * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT
217 */
218#define RATE_MCS_CHAN_WIDTH_POS 11
219#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS)
220#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS)
221#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS)
222#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS)
223#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS)
224
225/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */
226#define RATE_MCS_SGI_POS 13
227#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS)
228
229/* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */
230#define RATE_MCS_ANT_POS 14
231#define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS)
232#define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS)
233#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS)
234#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \
235 RATE_MCS_ANT_B_MSK)
236#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \
237 RATE_MCS_ANT_C_MSK)
238#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK
239#define RATE_MCS_ANT_NUM 3
240
241/* Bit 17-18: (0) SS, (1) SS*2 */
242#define RATE_MCS_STBC_POS 17
243#define RATE_MCS_STBC_MSK (1 << RATE_MCS_STBC_POS)
244
245/* Bit 19: (0) Beamforming is off, (1) Beamforming is on */
246#define RATE_MCS_BF_POS 19
247#define RATE_MCS_BF_MSK (1 << RATE_MCS_BF_POS)
248
249/* Bit 20: (0) ZLF is off, (1) ZLF is on */
250#define RATE_MCS_ZLF_POS 20
251#define RATE_MCS_ZLF_MSK (1 << RATE_MCS_ZLF_POS)
252
253/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */
254#define RATE_MCS_DUP_POS 24
255#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS)
256
257/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */
258#define RATE_MCS_LDPC_POS 27
259#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS)
260
261
262/* Link Quality definitions */
263
264/* # entries in rate scale table to support Tx retries */
265#define LQ_MAX_RETRY_NUM 16
266
267/* Link quality command flags, only this one is available */
268#define LQ_FLAG_SET_STA_TLC_RTS_MSK BIT(0)
269
270/**
271 * struct iwl_lq_cmd - link quality command
272 * @sta_id: station to update
273 * @control: not used
274 * @flags: combination of LQ_FLAG_*
275 * @mimo_delim: the first SISO index in rs_table, which separates MIMO
276 * and SISO rates
277 * @single_stream_ant_msk: best antenna for SISO (can be dual in CDD).
278 * Should be ANT_[ABC]
279 * @dual_stream_ant_msk: best antennas for MIMO, combination of ANT_[ABC]
280 * @initial_rate_index: first index from rs_table per AC category
281 * @agg_time_limit: aggregation max time threshold in usec/100, meaning
282 * value of 100 is one usec. Range is 100 to 8000
283 * @agg_disable_start_th: try-count threshold for starting aggregation.
284 * If a frame has higher try-count, it should not be selected for
285 * starting an aggregation sequence.
286 * @agg_frame_cnt_limit: max frame count in an aggregation.
287 * 0: no limit
288 * 1: no aggregation (one frame per aggregation)
289 * 2 - 0x3f: maximal number of frames (up to 3f == 63)
290 * @rs_table: array of rates for each TX try, each is rate_n_flags,
291 * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP
292 * @bf_params: beam forming params, currently not used
293 */
294struct iwl_lq_cmd {
295 u8 sta_id;
296 u8 reserved1;
297 u16 control;
298 /* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */
299 u8 flags;
300 u8 mimo_delim;
301 u8 single_stream_ant_msk;
302 u8 dual_stream_ant_msk;
303 u8 initial_rate_index[AC_NUM];
304 /* LINK_QUAL_AGG_PARAMS_API_S_VER_1 */
305 __le16 agg_time_limit;
306 u8 agg_disable_start_th;
307 u8 agg_frame_cnt_limit;
308 __le32 reserved2;
309 __le32 rs_table[LQ_MAX_RETRY_NUM];
310 __le32 bf_params;
311}; /* LINK_QUALITY_CMD_API_S_VER_1 */
312#endif /* __fw_api_rs_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
new file mode 100644
index 000000000000..670ac8f95e26
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -0,0 +1,561 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __fw_api_scan_h__
65#define __fw_api_scan_h__
66
67#include "fw-api.h"
68
69/* Scan Commands, Responses, Notifications */
70
71/* Masks for iwl_scan_channel.type flags */
72#define SCAN_CHANNEL_TYPE_PASSIVE 0
73#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
74#define SCAN_CHANNEL_NARROW_BAND BIT(22)
75
76/* Max number of IEs for direct SSID scans in a command */
77#define PROBE_OPTION_MAX 20
78
79/**
80 * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
81 * @channel: band is selected by iwl_scan_cmd "flags" field
82 * @tx_gain: gain for analog radio
83 * @dsp_atten: gain for DSP
84 * @active_dwell: dwell time for active scan in TU, typically 5-50
85 * @passive_dwell: dwell time for passive scan in TU, typically 20-500
86 * @type: type is broken down to these bits:
87 * bit 0: 0 = passive, 1 = active
88 * bits 1-20: SSID direct bit map. If any of these bits is set then
89 * the corresponding SSID IE is transmitted in probe request
90 * (bit i adds IE in position i to the probe request)
91 * bit 22: channel width, 0 = regular, 1 = TGj narrow channel
92 *
93 * @iteration_count:
94 * @iteration_interval:
95 * This struct is used once for each channel in the scan list.
96 * Each channel can independently select:
97 * 1) SSID for directed active scans
98 * 2) Txpower setting (for rate specified within Tx command)
99 * 3) How long to stay on-channel (behavior may be modified by quiet_time,
100 * quiet_plcp_th, good_CRC_th)
101 *
102 * To avoid uCode errors, make sure the following are true (see comments
103 * under struct iwl_scan_cmd about max_out_time and quiet_time):
104 * 1) If using passive_dwell (i.e. passive_dwell != 0):
105 * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
106 * 2) quiet_time <= active_dwell
107 * 3) If restricting off-channel time (i.e. max_out_time !=0):
108 * passive_dwell < max_out_time
109 * active_dwell < max_out_time
110 */
111struct iwl_scan_channel {
112 __le32 type;
113 __le16 channel;
114 __le16 iteration_count;
115 __le32 iteration_interval;
116 __le16 active_dwell;
117 __le16 passive_dwell;
118} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */
119
120/**
121 * struct iwl_ssid_ie - directed scan network information element
122 *
123 * Up to 20 of these may appear in REPLY_SCAN_CMD,
124 * selected by "type" bit field in struct iwl_scan_channel;
125 * each channel may select different ssids from among the 20 entries.
126 * SSID IEs get transmitted in reverse order of entry.
127 */
128struct iwl_ssid_ie {
129 u8 id;
130 u8 len;
131 u8 ssid[IEEE80211_MAX_SSID_LEN];
132} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
133
134/**
135 * iwl_scan_flags - masks for scan command flags
136 *@SCAN_FLAGS_PERIODIC_SCAN:
137 *@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX:
138 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
139 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
140 *@SCAN_FLAGS_FRAGMENTED_SCAN:
141 */
142enum iwl_scan_flags {
143 SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
144 SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1),
145 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
146 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
147 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
148};
149
150/**
151 * enum iwl_scan_type - Scan types for scan command
152 * @SCAN_TYPE_FORCED:
153 * @SCAN_TYPE_BACKGROUND:
154 * @SCAN_TYPE_OS:
155 * @SCAN_TYPE_ROAMING:
156 * @SCAN_TYPE_ACTION:
157 * @SCAN_TYPE_DISCOVERY:
158 * @SCAN_TYPE_DISCOVERY_FORCED:
159 */
160enum iwl_scan_type {
161 SCAN_TYPE_FORCED = 0,
162 SCAN_TYPE_BACKGROUND = 1,
163 SCAN_TYPE_OS = 2,
164 SCAN_TYPE_ROAMING = 3,
165 SCAN_TYPE_ACTION = 4,
166 SCAN_TYPE_DISCOVERY = 5,
167 SCAN_TYPE_DISCOVERY_FORCED = 6,
168}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
169
170/* Maximal number of channels to scan */
171#define MAX_NUM_SCAN_CHANNELS 0x24
172
173/**
174 * struct iwl_scan_cmd - scan request command
175 * ( SCAN_REQUEST_CMD = 0x80 )
176 * @len: command length in bytes
177 * @scan_flags: scan flags from SCAN_FLAGS_*
178 * @channel_count: num of channels in channel list (1 - MAX_NUM_SCAN_CHANNELS)
179 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
180 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
181 * this number of packets were received (typically 1)
182 * @passive2active: is auto switching from passive to active allowed (0 or 1)
183 * @rxchain_sel_flags: RXON_RX_CHAIN_*
184 * @max_out_time: in usecs, max out of serving channel time
185 * @suspend_time: how long to pause scan when returning to service channel:
186 * bits 0-19: beacon interal in usecs (suspend before executing)
187 * bits 20-23: reserved
188 * bits 24-31: number of beacons (suspend between channels)
189 * @rxon_flags: RXON_FLG_*
190 * @filter_flags: RXON_FILTER_*
191 * @tx_cmd: for active scans (zero for passive), w/o payload,
192 * no RS so specify TX rate
193 * @direct_scan: direct scan SSIDs
194 * @type: one of SCAN_TYPE_*
195 * @repeats: how many time to repeat the scan
196 */
197struct iwl_scan_cmd {
198 __le16 len;
199 u8 scan_flags;
200 u8 channel_count;
201 __le16 quiet_time;
202 __le16 quiet_plcp_th;
203 __le16 passive2active;
204 __le16 rxchain_sel_flags;
205 __le32 max_out_time;
206 __le32 suspend_time;
207 /* RX_ON_FLAGS_API_S_VER_1 */
208 __le32 rxon_flags;
209 __le32 filter_flags;
210 struct iwl_tx_cmd tx_cmd;
211 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
212 __le32 type;
213 __le32 repeats;
214
215 /*
216 * Probe request frame, followed by channel list.
217 *
218 * Size of probe request frame is specified by byte count in tx_cmd.
219 * Channel list follows immediately after probe request frame.
220 * Number of channels in list is specified by channel_count.
221 * Each channel in list is of type:
222 *
223 * struct iwl_scan_channel channels[0];
224 *
225 * NOTE: Only one band of channels can be scanned per pass. You
226 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
227 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
228 * before requesting another scan.
229 */
230 u8 data[0];
231} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */
232
233/* Response to scan request contains only status with one of these values */
234#define SCAN_RESPONSE_OK 0x1
235#define SCAN_RESPONSE_ERROR 0x2
236
237/*
238 * SCAN_ABORT_CMD = 0x81
239 * When scan abort is requested, the command has no fields except the common
240 * header. The response contains only a status with one of these values.
241 */
242#define SCAN_ABORT_POSSIBLE 0x1
243#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */
244
245/* TODO: complete documentation */
246#define SCAN_OWNER_STATUS 0x1
247#define MEASURE_OWNER_STATUS 0x2
248
249/**
250 * struct iwl_scan_start_notif - notifies start of scan in the device
251 * ( SCAN_START_NOTIFICATION = 0x82 )
252 * @tsf_low: TSF timer (lower half) in usecs
253 * @tsf_high: TSF timer (higher half) in usecs
254 * @beacon_timer: structured as follows:
255 * bits 0:19 - beacon interval in usecs
256 * bits 20:23 - reserved (0)
257 * bits 24:31 - number of beacons
258 * @channel: which channel is scanned
259 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
260 * @status: one of *_OWNER_STATUS
261 */
262struct iwl_scan_start_notif {
263 __le32 tsf_low;
264 __le32 tsf_high;
265 __le32 beacon_timer;
266 u8 channel;
267 u8 band;
268 u8 reserved[2];
269 __le32 status;
270} __packed; /* SCAN_START_NTF_API_S_VER_1 */
271
272/* scan results probe_status first bit indicates success */
273#define SCAN_PROBE_STATUS_OK 0
274#define SCAN_PROBE_STATUS_TX_FAILED BIT(0)
275/* error statuses combined with TX_FAILED */
276#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1)
277#define SCAN_PROBE_STATUS_FAIL_BT BIT(2)
278
279/* How many statistics are gathered for each channel */
280#define SCAN_RESULTS_STATISTICS 1
281
282/**
283 * enum iwl_scan_complete_status - status codes for scan complete notifications
284 * @SCAN_COMP_STATUS_OK: scan completed successfully
285 * @SCAN_COMP_STATUS_ABORT: scan was aborted by user
286 * @SCAN_COMP_STATUS_ERR_SLEEP: sending null sleep packet failed
287 * @SCAN_COMP_STATUS_ERR_CHAN_TIMEOUT: timeout before channel is ready
288 * @SCAN_COMP_STATUS_ERR_PROBE: sending probe request failed
289 * @SCAN_COMP_STATUS_ERR_WAKEUP: sending null wakeup packet failed
290 * @SCAN_COMP_STATUS_ERR_ANTENNAS: invalid antennas chosen at scan command
291 * @SCAN_COMP_STATUS_ERR_INTERNAL: internal error caused scan abort
292 * @SCAN_COMP_STATUS_ERR_COEX: medium was lost ot WiMax
293 * @SCAN_COMP_STATUS_P2P_ACTION_OK: P2P public action frame TX was successful
294 * (not an error!)
295 * @SCAN_COMP_STATUS_ITERATION_END: indicates end of one repeatition the driver
296 * asked for
297 * @SCAN_COMP_STATUS_ERR_ALLOC_TE: scan could not allocate time events
298*/
299enum iwl_scan_complete_status {
300 SCAN_COMP_STATUS_OK = 0x1,
301 SCAN_COMP_STATUS_ABORT = 0x2,
302 SCAN_COMP_STATUS_ERR_SLEEP = 0x3,
303 SCAN_COMP_STATUS_ERR_CHAN_TIMEOUT = 0x4,
304 SCAN_COMP_STATUS_ERR_PROBE = 0x5,
305 SCAN_COMP_STATUS_ERR_WAKEUP = 0x6,
306 SCAN_COMP_STATUS_ERR_ANTENNAS = 0x7,
307 SCAN_COMP_STATUS_ERR_INTERNAL = 0x8,
308 SCAN_COMP_STATUS_ERR_COEX = 0x9,
309 SCAN_COMP_STATUS_P2P_ACTION_OK = 0xA,
310 SCAN_COMP_STATUS_ITERATION_END = 0x0B,
311 SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C,
312};
313
314/**
315 * struct iwl_scan_results_notif - scan results for one channel
316 * ( SCAN_RESULTS_NOTIFICATION = 0x83 )
317 * @channel: which channel the results are from
318 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
319 * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
320 * @num_probe_not_sent: # of request that weren't sent due to not enough time
321 * @duration: duration spent in channel, in usecs
322 * @statistics: statistics gathered for this channel
323 */
324struct iwl_scan_results_notif {
325 u8 channel;
326 u8 band;
327 u8 probe_status;
328 u8 num_probe_not_sent;
329 __le32 duration;
330 __le32 statistics[SCAN_RESULTS_STATISTICS];
331} __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */
332
333/**
334 * struct iwl_scan_complete_notif - notifies end of scanning (all channels)
335 * ( SCAN_COMPLETE_NOTIFICATION = 0x84 )
336 * @scanned_channels: number of channels scanned (and number of valid results)
337 * @status: one of SCAN_COMP_STATUS_*
338 * @bt_status: BT on/off status
339 * @last_channel: last channel that was scanned
340 * @tsf_low: TSF timer (lower half) in usecs
341 * @tsf_high: TSF timer (higher half) in usecs
342 * @results: all scan results, only "scanned_channels" of them are valid
343 */
344struct iwl_scan_complete_notif {
345 u8 scanned_channels;
346 u8 status;
347 u8 bt_status;
348 u8 last_channel;
349 __le32 tsf_low;
350 __le32 tsf_high;
351 struct iwl_scan_results_notif results[MAX_NUM_SCAN_CHANNELS];
352} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
353
354/* scan offload */
355#define IWL_MAX_SCAN_CHANNELS 40
356#define IWL_SCAN_MAX_BLACKLIST_LEN 64
357#define IWL_SCAN_MAX_PROFILES 11
358#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
359
360/* Default watchdog (in MS) for scheduled scan iteration */
361#define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000)
362
363#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1)
364#define CAN_ABORT_STATUS 1
365
366#define IWL_FULL_SCAN_MULTIPLIER 5
367#define IWL_FAST_SCHED_SCAN_ITERATIONS 3
368
369/**
370 * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6
371 * @scan_flags: see enum iwl_scan_flags
372 * @channel_count: channels in channel list
373 * @quiet_time: dwell time, in milisiconds, on quiet channel
374 * @quiet_plcp_th: quiet channel num of packets threshold
375 * @good_CRC_th: passive to active promotion threshold
376 * @rx_chain: RXON rx chain.
377 * @max_out_time: max uSec to be out of assoceated channel
378 * @suspend_time: pause scan this long when returning to service channel
379 * @flags: RXON flags
380 * @filter_flags: RXONfilter
381 * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz.
382 * @direct_scan: list of SSIDs for directed active scan
383 * @scan_type: see enum iwl_scan_type.
384 * @rep_count: repetition count for each scheduled scan iteration.
385 */
386struct iwl_scan_offload_cmd {
387 __le16 len;
388 u8 scan_flags;
389 u8 channel_count;
390 __le16 quiet_time;
391 __le16 quiet_plcp_th;
392 __le16 good_CRC_th;
393 __le16 rx_chain;
394 __le32 max_out_time;
395 __le32 suspend_time;
396 /* RX_ON_FLAGS_API_S_VER_1 */
397 __le32 flags;
398 __le32 filter_flags;
399 struct iwl_tx_cmd tx_cmd[2];
400 /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
401 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
402 __le32 scan_type;
403 __le32 rep_count;
404} __packed;
405
406enum iwl_scan_offload_channel_flags {
407 IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE = BIT(0),
408 IWL_SCAN_OFFLOAD_CHANNEL_NARROW = BIT(22),
409 IWL_SCAN_OFFLOAD_CHANNEL_FULL = BIT(24),
410 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL = BIT(25),
411};
412
413/**
414 * iwl_scan_channel_cfg - SCAN_CHANNEL_CFG_S
415 * @type: bitmap - see enum iwl_scan_offload_channel_flags.
416 * 0: passive (0) or active (1) scan.
417 * 1-20: directed scan to i'th ssid.
418 * 22: channel width configuation - 1 for narrow.
419 * 24: full scan.
420 * 25: partial scan.
421 * @channel_number: channel number 1-13 etc.
422 * @iter_count: repetition count for the channel.
423 * @iter_interval: interval between two innteration on one channel.
424 * @dwell_time: entry 0 - active scan, entry 1 - passive scan.
425 */
426struct iwl_scan_channel_cfg {
427 __le32 type[IWL_MAX_SCAN_CHANNELS];
428 __le16 channel_number[IWL_MAX_SCAN_CHANNELS];
429 __le16 iter_count[IWL_MAX_SCAN_CHANNELS];
430 __le32 iter_interval[IWL_MAX_SCAN_CHANNELS];
431 u8 dwell_time[IWL_MAX_SCAN_CHANNELS][2];
432} __packed;
433
434/**
435 * iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
436 * @scan_cmd: scan command fixed part
437 * @channel_cfg: scan channel configuration
438 * @data: probe request frames (one per band)
439 */
440struct iwl_scan_offload_cfg {
441 struct iwl_scan_offload_cmd scan_cmd;
442 struct iwl_scan_channel_cfg channel_cfg;
443 u8 data[0];
444} __packed;
445
446/**
447 * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S
448 * @ssid: MAC address to filter out
449 * @reported_rssi: AP rssi reported to the host
450 */
451struct iwl_scan_offload_blacklist {
452 u8 ssid[ETH_ALEN];
453 u8 reported_rssi;
454 u8 reserved;
455} __packed;
456
457enum iwl_scan_offload_network_type {
458 IWL_NETWORK_TYPE_BSS = 1,
459 IWL_NETWORK_TYPE_IBSS = 2,
460 IWL_NETWORK_TYPE_ANY = 3,
461};
462
463enum iwl_scan_offload_band_selection {
464 IWL_SCAN_OFFLOAD_SELECT_2_4 = 0x4,
465 IWL_SCAN_OFFLOAD_SELECT_5_2 = 0x8,
466 IWL_SCAN_OFFLOAD_SELECT_ANY = 0xc,
467};
468
469/**
470 * iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S
471 * @ssid_index: index to ssid list in fixed part
472 * @unicast_cipher: encryption olgorithm to match - bitmap
473 * @aut_alg: authentication olgorithm to match - bitmap
474 * @network_type: enum iwl_scan_offload_network_type
475 * @band_selection: enum iwl_scan_offload_band_selection
476 */
477struct iwl_scan_offload_profile {
478 u8 ssid_index;
479 u8 unicast_cipher;
480 u8 auth_alg;
481 u8 network_type;
482 u8 band_selection;
483 u8 reserved[3];
484} __packed;
485
486/**
487 * iwl_scan_offload_profile_cfg - SCAN_OFFLOAD_PROFILES_CFG_API_S_VER_1
488 * @blaclist: AP list to filter off from scan results
489 * @profiles: profiles to search for match
490 * @blacklist_len: length of blacklist
491 * @num_profiles: num of profiles in the list
492 */
493struct iwl_scan_offload_profile_cfg {
494 struct iwl_scan_offload_blacklist blacklist[IWL_SCAN_MAX_BLACKLIST_LEN];
495 struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
496 u8 blacklist_len;
497 u8 num_profiles;
498 u8 reserved[2];
499} __packed;
500
501/**
502 * iwl_scan_offload_schedule - schedule of scan offload
503 * @delay: delay between iterations, in seconds.
504 * @iterations: num of scan iterations
505 * @full_scan_mul: number of partial scans before each full scan
506 */
507struct iwl_scan_offload_schedule {
508 u16 delay;
509 u8 iterations;
510 u8 full_scan_mul;
511} __packed;
512
513/*
514 * iwl_scan_offload_flags
515 *
516 * IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID: filter mode - upload every beacon or match
517 * ssid list.
518 * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
519 * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan
520 * on A band.
521 */
522enum iwl_scan_offload_flags {
523 IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID = BIT(0),
524 IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2),
525 IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3),
526};
527
528/**
529 * iwl_scan_offload_req - scan offload request command
530 * @flags: bitmap - enum iwl_scan_offload_flags.
531 * @watchdog: maximum scan duration in TU.
532 * @delay: delay in seconds before first iteration.
533 * @schedule_line: scan offload schedule, for fast and regular scan.
534 */
535struct iwl_scan_offload_req {
536 __le16 flags;
537 __le16 watchdog;
538 __le16 delay;
539 __le16 reserved;
540 struct iwl_scan_offload_schedule schedule_line[2];
541} __packed;
542
543enum iwl_scan_offload_compleate_status {
544 IWL_SCAN_OFFLOAD_COMPLETED = 1,
545 IWL_SCAN_OFFLOAD_ABORTED = 2,
546};
547
548/**
549 * iwl_scan_offload_complete - SCAN_OFFLOAD_COMPLETE_NTF_API_S_VER_1
550 * @last_schedule_line: last schedule line executed (fast or regular)
551 * @last_schedule_iteration: last scan iteration executed before scan abort
552 * @status: enum iwl_scan_offload_compleate_status
553 */
554struct iwl_scan_offload_complete {
555 u8 last_schedule_line;
556 u8 last_schedule_iteration;
557 u8 status;
558 u8 reserved;
559} __packed;
560
561#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
new file mode 100644
index 000000000000..0acb53dda22d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -0,0 +1,380 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_sta_h__
64#define __fw_api_sta_h__
65
66/**
67 * enum iwl_sta_flags - flags for the ADD_STA host command
68 * @STA_FLG_REDUCED_TX_PWR_CTRL:
69 * @STA_FLG_REDUCED_TX_PWR_DATA:
70 * @STA_FLG_FLG_ANT_MSK: Antenna selection
71 * @STA_FLG_PS: set if STA is in Power Save
72 * @STA_FLG_INVALID: set if STA is invalid
73 * @STA_FLG_DLP_EN: Direct Link Protocol is enabled
74 * @STA_FLG_SET_ALL_KEYS: the current key applies to all key IDs
75 * @STA_FLG_DRAIN_FLOW: drain flow
76 * @STA_FLG_PAN: STA is for PAN interface
77 * @STA_FLG_CLASS_AUTH:
78 * @STA_FLG_CLASS_ASSOC:
79 * @STA_FLG_CLASS_MIMO_PROT:
80 * @STA_FLG_MAX_AGG_SIZE_MSK: maximal size for A-MPDU
81 * @STA_FLG_AGG_MPDU_DENS_MSK: maximal MPDU density for Tx aggregation
82 * @STA_FLG_FAT_EN_MSK: support for channel width (for Tx). This flag is
83 * initialised by driver and can be updated by fw upon reception of
84 * action frames that can change the channel width. When cleared the fw
85 * will send all the frames in 20MHz even when FAT channel is requested.
86 * @STA_FLG_MIMO_EN_MSK: support for MIMO. This flag is initialised by the
87 * driver and can be updated by fw upon reception of action frames.
88 * @STA_FLG_MFP_EN: Management Frame Protection
89 */
90enum iwl_sta_flags {
91 STA_FLG_REDUCED_TX_PWR_CTRL = BIT(3),
92 STA_FLG_REDUCED_TX_PWR_DATA = BIT(6),
93
94 STA_FLG_FLG_ANT_A = (1 << 4),
95 STA_FLG_FLG_ANT_B = (2 << 4),
96 STA_FLG_FLG_ANT_MSK = (STA_FLG_FLG_ANT_A |
97 STA_FLG_FLG_ANT_B),
98
99 STA_FLG_PS = BIT(8),
100 STA_FLG_INVALID = BIT(9),
101 STA_FLG_DLP_EN = BIT(10),
102 STA_FLG_SET_ALL_KEYS = BIT(11),
103 STA_FLG_DRAIN_FLOW = BIT(12),
104 STA_FLG_PAN = BIT(13),
105 STA_FLG_CLASS_AUTH = BIT(14),
106 STA_FLG_CLASS_ASSOC = BIT(15),
107 STA_FLG_RTS_MIMO_PROT = BIT(17),
108
109 STA_FLG_MAX_AGG_SIZE_SHIFT = 19,
110 STA_FLG_MAX_AGG_SIZE_8K = (0 << STA_FLG_MAX_AGG_SIZE_SHIFT),
111 STA_FLG_MAX_AGG_SIZE_16K = (1 << STA_FLG_MAX_AGG_SIZE_SHIFT),
112 STA_FLG_MAX_AGG_SIZE_32K = (2 << STA_FLG_MAX_AGG_SIZE_SHIFT),
113 STA_FLG_MAX_AGG_SIZE_64K = (3 << STA_FLG_MAX_AGG_SIZE_SHIFT),
114 STA_FLG_MAX_AGG_SIZE_128K = (4 << STA_FLG_MAX_AGG_SIZE_SHIFT),
115 STA_FLG_MAX_AGG_SIZE_256K = (5 << STA_FLG_MAX_AGG_SIZE_SHIFT),
116 STA_FLG_MAX_AGG_SIZE_512K = (6 << STA_FLG_MAX_AGG_SIZE_SHIFT),
117 STA_FLG_MAX_AGG_SIZE_1024K = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
118 STA_FLG_MAX_AGG_SIZE_MSK = (7 << STA_FLG_MAX_AGG_SIZE_SHIFT),
119
120 STA_FLG_AGG_MPDU_DENS_SHIFT = 23,
121 STA_FLG_AGG_MPDU_DENS_2US = (4 << STA_FLG_AGG_MPDU_DENS_SHIFT),
122 STA_FLG_AGG_MPDU_DENS_4US = (5 << STA_FLG_AGG_MPDU_DENS_SHIFT),
123 STA_FLG_AGG_MPDU_DENS_8US = (6 << STA_FLG_AGG_MPDU_DENS_SHIFT),
124 STA_FLG_AGG_MPDU_DENS_16US = (7 << STA_FLG_AGG_MPDU_DENS_SHIFT),
125 STA_FLG_AGG_MPDU_DENS_MSK = (7 << STA_FLG_AGG_MPDU_DENS_SHIFT),
126
127 STA_FLG_FAT_EN_20MHZ = (0 << 26),
128 STA_FLG_FAT_EN_40MHZ = (1 << 26),
129 STA_FLG_FAT_EN_80MHZ = (2 << 26),
130 STA_FLG_FAT_EN_160MHZ = (3 << 26),
131 STA_FLG_FAT_EN_MSK = (3 << 26),
132
133 STA_FLG_MIMO_EN_SISO = (0 << 28),
134 STA_FLG_MIMO_EN_MIMO2 = (1 << 28),
135 STA_FLG_MIMO_EN_MIMO3 = (2 << 28),
136 STA_FLG_MIMO_EN_MSK = (3 << 28),
137};
138
139/**
140 * enum iwl_sta_key_flag - key flags for the ADD_STA host command
141 * @STA_KEY_FLG_EN_MSK: mask for encryption algorithm
142 * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from
143 * station info array (1 - n 1X mode)
144 * @STA_KEY_FLG_KEYID_MSK: the index of the key
145 * @STA_KEY_NOT_VALID: key is invalid
146 * @STA_KEY_FLG_WEP_13BYTES: set for 13 bytes WEP key
147 * @STA_KEY_MULTICAST: set for multical key
148 * @STA_KEY_MFP: key is used for Management Frame Protection
149 */
150enum iwl_sta_key_flag {
151 STA_KEY_FLG_NO_ENC = (0 << 0),
152 STA_KEY_FLG_WEP = (1 << 0),
153 STA_KEY_FLG_CCM = (2 << 0),
154 STA_KEY_FLG_TKIP = (3 << 0),
155 STA_KEY_FLG_CMAC = (6 << 0),
156 STA_KEY_FLG_ENC_UNKNOWN = (7 << 0),
157 STA_KEY_FLG_EN_MSK = (7 << 0),
158
159 STA_KEY_FLG_WEP_KEY_MAP = BIT(3),
160 STA_KEY_FLG_KEYID_POS = 8,
161 STA_KEY_FLG_KEYID_MSK = (3 << STA_KEY_FLG_KEYID_POS),
162 STA_KEY_NOT_VALID = BIT(11),
163 STA_KEY_FLG_WEP_13BYTES = BIT(12),
164 STA_KEY_MULTICAST = BIT(14),
165 STA_KEY_MFP = BIT(15),
166};
167
168/**
169 * enum iwl_sta_modify_flag - indicate to the fw what flag are being changed
170 * @STA_MODIFY_KEY: this command modifies %key
171 * @STA_MODIFY_TID_DISABLE_TX: this command modifies %tid_disable_tx
172 * @STA_MODIFY_TX_RATE: unused
173 * @STA_MODIFY_ADD_BA_TID: this command modifies %add_immediate_ba_tid
174 * @STA_MODIFY_REMOVE_BA_TID: this command modifies %remove_immediate_ba_tid
175 * @STA_MODIFY_SLEEPING_STA_TX_COUNT: this command modifies %sleep_tx_count
176 * @STA_MODIFY_PROT_TH:
177 * @STA_MODIFY_QUEUES: modify the queues used by this station
178 */
179enum iwl_sta_modify_flag {
180 STA_MODIFY_KEY = BIT(0),
181 STA_MODIFY_TID_DISABLE_TX = BIT(1),
182 STA_MODIFY_TX_RATE = BIT(2),
183 STA_MODIFY_ADD_BA_TID = BIT(3),
184 STA_MODIFY_REMOVE_BA_TID = BIT(4),
185 STA_MODIFY_SLEEPING_STA_TX_COUNT = BIT(5),
186 STA_MODIFY_PROT_TH = BIT(6),
187 STA_MODIFY_QUEUES = BIT(7),
188};
189
190#define STA_MODE_MODIFY 1
191
192/**
193 * enum iwl_sta_sleep_flag - type of sleep of the station
194 * @STA_SLEEP_STATE_AWAKE:
195 * @STA_SLEEP_STATE_PS_POLL:
196 * @STA_SLEEP_STATE_UAPSD:
197 */
198enum iwl_sta_sleep_flag {
199 STA_SLEEP_STATE_AWAKE = 0,
200 STA_SLEEP_STATE_PS_POLL = BIT(0),
201 STA_SLEEP_STATE_UAPSD = BIT(1),
202};
203
204/* STA ID and color bits definitions */
205#define STA_ID_SEED (0x0f)
206#define STA_ID_POS (0)
207#define STA_ID_MSK (STA_ID_SEED << STA_ID_POS)
208
209#define STA_COLOR_SEED (0x7)
210#define STA_COLOR_POS (4)
211#define STA_COLOR_MSK (STA_COLOR_SEED << STA_COLOR_POS)
212
213#define STA_ID_N_COLOR_GET_COLOR(id_n_color) \
214 (((id_n_color) & STA_COLOR_MSK) >> STA_COLOR_POS)
215#define STA_ID_N_COLOR_GET_ID(id_n_color) \
216 (((id_n_color) & STA_ID_MSK) >> STA_ID_POS)
217
218#define STA_KEY_MAX_NUM (16)
219#define STA_KEY_IDX_INVALID (0xff)
220#define STA_KEY_MAX_DATA_KEY_NUM (4)
221#define IWL_MAX_GLOBAL_KEYS (4)
222#define STA_KEY_LEN_WEP40 (5)
223#define STA_KEY_LEN_WEP104 (13)
224
225/**
226 * struct iwl_mvm_keyinfo - key information
227 * @key_flags: type %iwl_sta_key_flag
228 * @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection
229 * @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx
230 * @key_offset: key offset in the fw's key table
231 * @key: 16-byte unicast decryption key
232 * @tx_secur_seq_cnt: initial RSC / PN needed for replay check
233 * @hw_tkip_mic_rx_key: byte: MIC Rx Key - used for TKIP only
234 * @hw_tkip_mic_tx_key: byte: MIC Tx Key - used for TKIP only
235 */
236struct iwl_mvm_keyinfo {
237 __le16 key_flags;
238 u8 tkip_rx_tsc_byte2;
239 u8 reserved1;
240 __le16 tkip_rx_ttak[5];
241 u8 key_offset;
242 u8 reserved2;
243 u8 key[16];
244 __le64 tx_secur_seq_cnt;
245 __le64 hw_tkip_mic_rx_key;
246 __le64 hw_tkip_mic_tx_key;
247} __packed;
248
249/**
250 * struct iwl_mvm_add_sta_cmd - Add / modify a station in the fw's station table
251 * ( REPLY_ADD_STA = 0x18 )
252 * @add_modify: 1: modify existing, 0: add new station
253 * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent
254 * @multicast_tx_key_id: multicast tx key id. Relevant only when multicast key
255 * sent
256 * @mac_id_n_color: the Mac context this station belongs to
257 * @addr[ETH_ALEN]: station's MAC address
258 * @sta_id: index of station in uCode's station table
259 * @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave
260 * alone. 1 - modify, 0 - don't change.
261 * @key: look at %iwl_mvm_keyinfo
262 * @station_flags: look at %iwl_sta_flags
263 * @station_flags_msk: what of %station_flags have changed
264 * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable
265 * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field.
266 * @add_immediate_ba_tid: tid for which to add block-ack support (Rx)
267 * Set %STA_MODIFY_ADD_BA_TID to use this field, and also set
268 * add_immediate_ba_ssn.
269 * @remove_immediate_ba_tid: tid for which to remove block-ack support (Rx)
270 * Set %STA_MODIFY_REMOVE_BA_TID to use this field
271 * @add_immediate_ba_ssn: ssn for the Rx block-ack session. Used together with
272 * add_immediate_ba_tid.
273 * @sleep_tx_count: number of packets to transmit to station even though it is
274 * asleep. Used to synchronise PS-poll and u-APSD responses while ucode
275 * keeps track of STA sleep state.
276 * @sleep_state_flags: Look at %iwl_sta_sleep_flag.
277 * @assoc_id: assoc_id to be sent in VHT PLCP (9-bit), for grp use 0, for AP
278 * mac-addr.
279 * @beamform_flags: beam forming controls
280 * @tfd_queue_msk: tfd queues used by this station
281 *
282 * The device contains an internal table of per-station information, with info
283 * on security keys, aggregation parameters, and Tx rates for initial Tx
284 * attempt and any retries (set by REPLY_TX_LINK_QUALITY_CMD).
285 *
286 * ADD_STA sets up the table entry for one station, either creating a new
287 * entry, or modifying a pre-existing one.
288 */
289struct iwl_mvm_add_sta_cmd {
290 u8 add_modify;
291 u8 unicast_tx_key_id;
292 u8 multicast_tx_key_id;
293 u8 reserved1;
294 __le32 mac_id_n_color;
295 u8 addr[ETH_ALEN];
296 __le16 reserved2;
297 u8 sta_id;
298 u8 modify_mask;
299 __le16 reserved3;
300 struct iwl_mvm_keyinfo key;
301 __le32 station_flags;
302 __le32 station_flags_msk;
303 __le16 tid_disable_tx;
304 __le16 reserved4;
305 u8 add_immediate_ba_tid;
306 u8 remove_immediate_ba_tid;
307 __le16 add_immediate_ba_ssn;
308 __le16 sleep_tx_count;
309 __le16 sleep_state_flags;
310 __le16 assoc_id;
311 __le16 beamform_flags;
312 __le32 tfd_queue_msk;
313} __packed; /* ADD_STA_CMD_API_S_VER_5 */
314
315/**
316 * enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command
317 * @ADD_STA_SUCCESS: operation was executed successfully
318 * @ADD_STA_STATIONS_OVERLOAD: no room left in the fw's station table
319 * @ADD_STA_IMMEDIATE_BA_FAILURE: can't add Rx block ack session
320 * @ADD_STA_MODIFY_NON_EXISTING_STA: driver requested to modify a station that
321 * doesn't exist.
322 */
323enum iwl_mvm_add_sta_rsp_status {
324 ADD_STA_SUCCESS = 0x1,
325 ADD_STA_STATIONS_OVERLOAD = 0x2,
326 ADD_STA_IMMEDIATE_BA_FAILURE = 0x4,
327 ADD_STA_MODIFY_NON_EXISTING_STA = 0x8,
328};
329
330/**
331 * struct iwl_mvm_rm_sta_cmd - Add / modify a station in the fw's station table
332 * ( REMOVE_STA = 0x19 )
333 * @sta_id: the station id of the station to be removed
334 */
335struct iwl_mvm_rm_sta_cmd {
336 u8 sta_id;
337 u8 reserved[3];
338} __packed; /* REMOVE_STA_CMD_API_S_VER_2 */
339
340/**
341 * struct iwl_mvm_mgmt_mcast_key_cmd
342 * ( MGMT_MCAST_KEY = 0x1f )
343 * @ctrl_flags: %iwl_sta_key_flag
344 * @IGTK:
345 * @K1: IGTK master key
346 * @K2: IGTK sub key
347 * @sta_id: station ID that support IGTK
348 * @key_id:
349 * @receive_seq_cnt: initial RSC/PN needed for replay check
350 */
351struct iwl_mvm_mgmt_mcast_key_cmd {
352 __le32 ctrl_flags;
353 u8 IGTK[16];
354 u8 K1[16];
355 u8 K2[16];
356 __le32 key_id;
357 __le32 sta_id;
358 __le64 receive_seq_cnt;
359} __packed; /* SEC_MGMT_MULTICAST_KEY_CMD_API_S_VER_1 */
360
361struct iwl_mvm_wep_key {
362 u8 key_index;
363 u8 key_offset;
364 __le16 reserved1;
365 u8 key_size;
366 u8 reserved2[3];
367 u8 key[16];
368} __packed;
369
370struct iwl_mvm_wep_key_cmd {
371 __le32 mac_id_n_color;
372 u8 num_keys;
373 u8 decryption_type;
374 u8 flags;
375 u8 reserved;
376 struct iwl_mvm_wep_key wep_key[0];
377} __packed; /* SEC_CURR_WEP_KEY_CMD_API_S_VER_2 */
378
379
380#endif /* __fw_api_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
new file mode 100644
index 000000000000..2677914bf0a6
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -0,0 +1,580 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __fw_api_tx_h__
64#define __fw_api_tx_h__
65
66/**
67 * enum iwl_tx_flags - bitmasks for tx_flags in TX command
68 * @TX_CMD_FLG_PROT_REQUIRE: use RTS or CTS-to-self to protect the frame
69 * @TX_CMD_FLG_ACK: expect ACK from receiving station
70 * @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command.
71 * Otherwise, use rate_n_flags from the TX command
72 * @TX_CMD_FLG_BA: this frame is a block ack
73 * @TX_CMD_FLG_BAR: this frame is a BA request, immediate BAR is expected
74 * Must set TX_CMD_FLG_ACK with this flag.
75 * @TX_CMD_FLG_TXOP_PROT: protect frame with full TXOP protection
76 * @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
77 * @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
78 * @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
79 * @TX_CMD_FLG_BT_DIS: disable BT priority for this frame
80 * @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
81 * Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
82 * @TX_CMD_FLG_MORE_FRAG: this frame is non-last MPDU
83 * @TX_CMD_FLG_NEXT_FRAME: this frame includes information of the next frame
84 * @TX_CMD_FLG_TSF: FW should calculate and insert TSF in the frame
85 * Should be set for beacons and probe responses
86 * @TX_CMD_FLG_CALIB: activate PA TX power calibrations
87 * @TX_CMD_FLG_KEEP_SEQ_CTL: if seq_ctl is set, don't increase inner seq count
88 * @TX_CMD_FLG_AGG_START: allow this frame to start aggregation
89 * @TX_CMD_FLG_MH_PAD: driver inserted 2 byte padding after MAC header.
90 * Should be set for 26/30 length MAC headers
91 * @TX_CMD_FLG_RESP_TO_DRV: zero this if the response should go only to FW
92 * @TX_CMD_FLG_CCMP_AGG: this frame uses CCMP for aggregation acceleration
93 * @TX_CMD_FLG_TKIP_MIC_DONE: FW already performed TKIP MIC calculation
94 * @TX_CMD_FLG_CTS_ONLY: send CTS only, no data after that
95 * @TX_CMD_FLG_DUR: disable duration overwriting used in PS-Poll Assoc-id
96 * @TX_CMD_FLG_FW_DROP: FW should mark frame to be dropped
97 * @TX_CMD_FLG_EXEC_PAPD: execute PAPD
98 * @TX_CMD_FLG_PAPD_TYPE: 0 for reference power, 1 for nominal power
99 * @TX_CMD_FLG_HCCA_CHUNK: mark start of TSPEC chunk
100 */
101enum iwl_tx_flags {
102 TX_CMD_FLG_PROT_REQUIRE = BIT(0),
103 TX_CMD_FLG_ACK = BIT(3),
104 TX_CMD_FLG_STA_RATE = BIT(4),
105 TX_CMD_FLG_BA = BIT(5),
106 TX_CMD_FLG_BAR = BIT(6),
107 TX_CMD_FLG_TXOP_PROT = BIT(7),
108 TX_CMD_FLG_VHT_NDPA = BIT(8),
109 TX_CMD_FLG_HT_NDPA = BIT(9),
110 TX_CMD_FLG_CSI_FDBK2HOST = BIT(10),
111 TX_CMD_FLG_BT_DIS = BIT(12),
112 TX_CMD_FLG_SEQ_CTL = BIT(13),
113 TX_CMD_FLG_MORE_FRAG = BIT(14),
114 TX_CMD_FLG_NEXT_FRAME = BIT(15),
115 TX_CMD_FLG_TSF = BIT(16),
116 TX_CMD_FLG_CALIB = BIT(17),
117 TX_CMD_FLG_KEEP_SEQ_CTL = BIT(18),
118 TX_CMD_FLG_AGG_START = BIT(19),
119 TX_CMD_FLG_MH_PAD = BIT(20),
120 TX_CMD_FLG_RESP_TO_DRV = BIT(21),
121 TX_CMD_FLG_CCMP_AGG = BIT(22),
122 TX_CMD_FLG_TKIP_MIC_DONE = BIT(23),
123 TX_CMD_FLG_CTS_ONLY = BIT(24),
124 TX_CMD_FLG_DUR = BIT(25),
125 TX_CMD_FLG_FW_DROP = BIT(26),
126 TX_CMD_FLG_EXEC_PAPD = BIT(27),
127 TX_CMD_FLG_PAPD_TYPE = BIT(28),
128 TX_CMD_FLG_HCCA_CHUNK = BIT(31)
129}; /* TX_FLAGS_BITS_API_S_VER_1 */
130
131/*
132 * TX command security control
133 */
134#define TX_CMD_SEC_WEP 0x01
135#define TX_CMD_SEC_CCM 0x02
136#define TX_CMD_SEC_TKIP 0x03
137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
139#define TX_CMD_SEC_KEY128 0x08
140
141/* TODO: how does these values are OK with only 16 bit variable??? */
142/*
143 * TX command next frame info
144 *
145 * bits 0:2 - security control (TX_CMD_SEC_*)
146 * bit 3 - immediate ACK required
147 * bit 4 - rate is taken from STA table
148 * bit 5 - frame belongs to BA stream
149 * bit 6 - immediate BA response expected
150 * bit 7 - unused
151 * bits 8:15 - Station ID
152 * bits 16:31 - rate
153 */
154#define TX_CMD_NEXT_FRAME_ACK_MSK (0x8)
155#define TX_CMD_NEXT_FRAME_STA_RATE_MSK (0x10)
156#define TX_CMD_NEXT_FRAME_BA_MSK (0x20)
157#define TX_CMD_NEXT_FRAME_IMM_BA_RSP_MSK (0x40)
158#define TX_CMD_NEXT_FRAME_FLAGS_MSK (0xf8)
159#define TX_CMD_NEXT_FRAME_STA_ID_MSK (0xff00)
160#define TX_CMD_NEXT_FRAME_STA_ID_POS (8)
161#define TX_CMD_NEXT_FRAME_RATE_MSK (0xffff0000)
162#define TX_CMD_NEXT_FRAME_RATE_POS (16)
163
164/*
165 * TX command Frame life time in us - to be written in pm_frame_timeout
166 */
167#define TX_CMD_LIFE_TIME_INFINITE 0xFFFFFFFF
168#define TX_CMD_LIFE_TIME_DEFAULT 2000000 /* 2000 ms*/
169#define TX_CMD_LIFE_TIME_PROBE_RESP 40000 /* 40 ms */
170#define TX_CMD_LIFE_TIME_EXPIRED_FRAME 0
171
172/*
173 * TID for non QoS frames - to be written in tid_tspec
174 */
175#define IWL_TID_NON_QOS IWL_MAX_TID_COUNT
176
177/*
178 * Limits on the retransmissions - to be written in {data,rts}_retry_limit
179 */
180#define IWL_DEFAULT_TX_RETRY 15
181#define IWL_MGMT_DFAULT_RETRY_LIMIT 3
182#define IWL_RTS_DFAULT_RETRY_LIMIT 60
183#define IWL_BAR_DFAULT_RETRY_LIMIT 60
184#define IWL_LOW_RETRY_LIMIT 7
185
186/* TODO: complete documentation for try_cnt and btkill_cnt */
187/**
188 * struct iwl_tx_cmd - TX command struct to FW
189 * ( TX_CMD = 0x1c )
190 * @len: in bytes of the payload, see below for details
191 * @next_frame_len: same as len, but for next frame (0 if not applicable)
192 * Used for fragmentation and bursting, but not in 11n aggregation.
193 * @tx_flags: combination of TX_CMD_FLG_*
194 * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
195 * cleared. Combination of RATE_MCS_*
196 * @sta_id: index of destination station in FW station table
197 * @sec_ctl: security control, TX_CMD_SEC_*
198 * @initial_rate_index: index into the the rate table for initial TX attempt.
199 * Applied if TX_CMD_FLG_STA_RATE_MSK is set, normally 0 for data frames.
200 * @key: security key
201 * @next_frame_flags: TX_CMD_SEC_* and TX_CMD_NEXT_FRAME_*
202 * @life_time: frame life time (usecs??)
203 * @dram_lsb_ptr: Physical address of scratch area in the command (try_cnt +
204 * btkill_cnd + reserved), first 32 bits. "0" disables usage.
205 * @dram_msb_ptr: upper bits of the scratch physical address
206 * @rts_retry_limit: max attempts for RTS
207 * @data_retry_limit: max attempts to send the data packet
208 * @tid_spec: TID/tspec
209 * @pm_frame_timeout: PM TX frame timeout
210 * @driver_txop: duration od EDCA TXOP, in 32-usec units. Set this if not
211 * specified by HCCA protocol
212 *
213 * The byte count (both len and next_frame_len) includes MAC header
214 * (24/26/30/32 bytes)
215 * + 2 bytes pad if 26/30 header size
216 * + 8 byte IV for CCM or TKIP (not used for WEP)
217 * + Data payload
218 * + 8-byte MIC (not used for CCM/WEP)
219 * It does not include post-MAC padding, i.e.,
220 * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.
221 * Range of len: 14-2342 bytes.
222 *
223 * After the struct fields the MAC header is placed, plus any padding,
224 * and then the actial payload.
225 */
226struct iwl_tx_cmd {
227 __le16 len;
228 __le16 next_frame_len;
229 __le32 tx_flags;
230 /* DRAM_SCRATCH_API_U_VER_1 */
231 u8 try_cnt;
232 u8 btkill_cnt;
233 __le16 reserved;
234 __le32 rate_n_flags;
235 u8 sta_id;
236 u8 sec_ctl;
237 u8 initial_rate_index;
238 u8 reserved2;
239 u8 key[16];
240 __le16 next_frame_flags;
241 __le16 reserved3;
242 __le32 life_time;
243 __le32 dram_lsb_ptr;
244 u8 dram_msb_ptr;
245 u8 rts_retry_limit;
246 u8 data_retry_limit;
247 u8 tid_tspec;
248 __le16 pm_frame_timeout;
249 __le16 driver_txop;
250 u8 payload[0];
251 struct ieee80211_hdr hdr[0];
252} __packed; /* TX_CMD_API_S_VER_3 */
253
254/*
255 * TX response related data
256 */
257
258/*
259 * enum iwl_tx_status - status that is returned by the fw after attempts to Tx
260 * @TX_STATUS_SUCCESS:
261 * @TX_STATUS_DIRECT_DONE:
262 * @TX_STATUS_POSTPONE_DELAY:
263 * @TX_STATUS_POSTPONE_FEW_BYTES:
264 * @TX_STATUS_POSTPONE_BT_PRIO:
265 * @TX_STATUS_POSTPONE_QUIET_PERIOD:
266 * @TX_STATUS_POSTPONE_CALC_TTAK:
267 * @TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY:
268 * @TX_STATUS_FAIL_SHORT_LIMIT:
269 * @TX_STATUS_FAIL_LONG_LIMIT:
270 * @TX_STATUS_FAIL_UNDERRUN:
271 * @TX_STATUS_FAIL_DRAIN_FLOW:
272 * @TX_STATUS_FAIL_RFKILL_FLUSH:
273 * @TX_STATUS_FAIL_LIFE_EXPIRE:
274 * @TX_STATUS_FAIL_DEST_PS:
275 * @TX_STATUS_FAIL_HOST_ABORTED:
276 * @TX_STATUS_FAIL_BT_RETRY:
277 * @TX_STATUS_FAIL_STA_INVALID:
278 * @TX_TATUS_FAIL_FRAG_DROPPED:
279 * @TX_STATUS_FAIL_TID_DISABLE:
280 * @TX_STATUS_FAIL_FIFO_FLUSHED:
281 * @TX_STATUS_FAIL_SMALL_CF_POLL:
282 * @TX_STATUS_FAIL_FW_DROP:
283 * @TX_STATUS_FAIL_STA_COLOR_MISMATCH: mismatch between color of Tx cmd and
284 * STA table
285 * @TX_FRAME_STATUS_INTERNAL_ABORT:
286 * @TX_MODE_MSK:
287 * @TX_MODE_NO_BURST:
288 * @TX_MODE_IN_BURST_SEQ:
289 * @TX_MODE_FIRST_IN_BURST:
290 * @TX_QUEUE_NUM_MSK:
291 *
292 * Valid only if frame_count =1
293 * TODO: complete documentation
294 */
295enum iwl_tx_status {
296 TX_STATUS_MSK = 0x000000ff,
297 TX_STATUS_SUCCESS = 0x01,
298 TX_STATUS_DIRECT_DONE = 0x02,
299 /* postpone TX */
300 TX_STATUS_POSTPONE_DELAY = 0x40,
301 TX_STATUS_POSTPONE_FEW_BYTES = 0x41,
302 TX_STATUS_POSTPONE_BT_PRIO = 0x42,
303 TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43,
304 TX_STATUS_POSTPONE_CALC_TTAK = 0x44,
305 /* abort TX */
306 TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81,
307 TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
308 TX_STATUS_FAIL_LONG_LIMIT = 0x83,
309 TX_STATUS_FAIL_UNDERRUN = 0x84,
310 TX_STATUS_FAIL_DRAIN_FLOW = 0x85,
311 TX_STATUS_FAIL_RFKILL_FLUSH = 0x86,
312 TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
313 TX_STATUS_FAIL_DEST_PS = 0x88,
314 TX_STATUS_FAIL_HOST_ABORTED = 0x89,
315 TX_STATUS_FAIL_BT_RETRY = 0x8a,
316 TX_STATUS_FAIL_STA_INVALID = 0x8b,
317 TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
318 TX_STATUS_FAIL_TID_DISABLE = 0x8d,
319 TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e,
320 TX_STATUS_FAIL_SMALL_CF_POLL = 0x8f,
321 TX_STATUS_FAIL_FW_DROP = 0x90,
322 TX_STATUS_FAIL_STA_COLOR_MISMATCH = 0x91,
323 TX_STATUS_INTERNAL_ABORT = 0x92,
324 TX_MODE_MSK = 0x00000f00,
325 TX_MODE_NO_BURST = 0x00000000,
326 TX_MODE_IN_BURST_SEQ = 0x00000100,
327 TX_MODE_FIRST_IN_BURST = 0x00000200,
328 TX_QUEUE_NUM_MSK = 0x0001f000,
329 TX_NARROW_BW_MSK = 0x00060000,
330 TX_NARROW_BW_1DIV2 = 0x00020000,
331 TX_NARROW_BW_1DIV4 = 0x00040000,
332 TX_NARROW_BW_1DIV8 = 0x00060000,
333};
334
335/*
336 * enum iwl_tx_agg_status - TX aggregation status
337 * @AGG_TX_STATE_STATUS_MSK:
338 * @AGG_TX_STATE_TRANSMITTED:
339 * @AGG_TX_STATE_UNDERRUN:
340 * @AGG_TX_STATE_BT_PRIO:
341 * @AGG_TX_STATE_FEW_BYTES:
342 * @AGG_TX_STATE_ABORT:
343 * @AGG_TX_STATE_LAST_SENT_TTL:
344 * @AGG_TX_STATE_LAST_SENT_TRY_CNT:
345 * @AGG_TX_STATE_LAST_SENT_BT_KILL:
346 * @AGG_TX_STATE_SCD_QUERY:
347 * @AGG_TX_STATE_TEST_BAD_CRC32:
348 * @AGG_TX_STATE_RESPONSE:
349 * @AGG_TX_STATE_DUMP_TX:
350 * @AGG_TX_STATE_DELAY_TX:
351 * @AGG_TX_STATE_TRY_CNT_MSK: Retry count for 1st frame in aggregation (retries
352 * occur if tx failed for this frame when it was a member of a previous
353 * aggregation block). If rate scaling is used, retry count indicates the
354 * rate table entry used for all frames in the new agg.
355 *@ AGG_TX_STATE_SEQ_NUM_MSK: Command ID and sequence number of Tx command for
356 * this frame
357 *
358 * TODO: complete documentation
359 */
360enum iwl_tx_agg_status {
361 AGG_TX_STATE_STATUS_MSK = 0x00fff,
362 AGG_TX_STATE_TRANSMITTED = 0x000,
363 AGG_TX_STATE_UNDERRUN = 0x001,
364 AGG_TX_STATE_BT_PRIO = 0x002,
365 AGG_TX_STATE_FEW_BYTES = 0x004,
366 AGG_TX_STATE_ABORT = 0x008,
367 AGG_TX_STATE_LAST_SENT_TTL = 0x010,
368 AGG_TX_STATE_LAST_SENT_TRY_CNT = 0x020,
369 AGG_TX_STATE_LAST_SENT_BT_KILL = 0x040,
370 AGG_TX_STATE_SCD_QUERY = 0x080,
371 AGG_TX_STATE_TEST_BAD_CRC32 = 0x0100,
372 AGG_TX_STATE_RESPONSE = 0x1ff,
373 AGG_TX_STATE_DUMP_TX = 0x200,
374 AGG_TX_STATE_DELAY_TX = 0x400,
375 AGG_TX_STATE_TRY_CNT_POS = 12,
376 AGG_TX_STATE_TRY_CNT_MSK = 0xf << AGG_TX_STATE_TRY_CNT_POS,
377};
378
379#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL| \
380 AGG_TX_STATE_LAST_SENT_TRY_CNT| \
381 AGG_TX_STATE_LAST_SENT_BT_KILL)
382
383/*
384 * The mask below describes a status where we are absolutely sure that the MPDU
385 * wasn't sent. For BA/Underrun we cannot be that sure. All we know that we've
386 * written the bytes to the TXE, but we know nothing about what the DSP did.
387 */
388#define AGG_TX_STAT_FRAME_NOT_SENT (AGG_TX_STATE_FEW_BYTES | \
389 AGG_TX_STATE_ABORT | \
390 AGG_TX_STATE_SCD_QUERY)
391
392/*
393 * REPLY_TX = 0x1c (response)
394 *
395 * This response may be in one of two slightly different formats, indicated
396 * by the frame_count field:
397 *
398 * 1) No aggregation (frame_count == 1). This reports Tx results for a single
399 * frame. Multiple attempts, at various bit rates, may have been made for
400 * this frame.
401 *
402 * 2) Aggregation (frame_count > 1). This reports Tx results for two or more
403 * frames that used block-acknowledge. All frames were transmitted at
404 * same rate. Rate scaling may have been used if first frame in this new
405 * agg block failed in previous agg block(s).
406 *
407 * Note that, for aggregation, ACK (block-ack) status is not delivered
408 * here; block-ack has not been received by the time the device records
409 * this status.
410 * This status relates to reasons the tx might have been blocked or aborted
411 * within the device, rather than whether it was received successfully by
412 * the destination station.
413 */
414
415/**
416 * struct agg_tx_status - per packet TX aggregation status
417 * @status: enum iwl_tx_agg_status
418 * @sequence: Sequence # for this frame's Tx cmd (not SSN!)
419 */
420struct agg_tx_status {
421 __le16 status;
422 __le16 sequence;
423} __packed;
424
425/*
426 * definitions for initial rate index field
427 * bits [3:0] initial rate index
428 * bits [6:4] rate table color, used for the initial rate
429 * bit-7 invalid rate indication
430 */
431#define TX_RES_INIT_RATE_INDEX_MSK 0x0f
432#define TX_RES_RATE_TABLE_COLOR_MSK 0x70
433#define TX_RES_INV_RATE_INDEX_MSK 0x80
434
435#define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f)
436#define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)
437
438/**
439 * struct iwl_mvm_tx_resp - notifies that fw is TXing a packet
440 * ( REPLY_TX = 0x1c )
441 * @frame_count: 1 no aggregation, >1 aggregation
442 * @bt_kill_count: num of times blocked by bluetooth (unused for agg)
443 * @failure_rts: num of failures due to unsuccessful RTS
444 * @failure_frame: num failures due to no ACK (unused for agg)
445 * @initial_rate: for non-agg: rate of the successful Tx. For agg: rate of the
446 * Tx of all the batch. RATE_MCS_*
447 * @wireless_media_time: for non-agg: RTS + CTS + frame tx attempts time + ACK.
448 * for agg: RTS + CTS + aggregation tx time + block-ack time.
449 * in usec.
450 * @pa_status: tx power info
451 * @pa_integ_res_a: tx power info
452 * @pa_integ_res_b: tx power info
453 * @pa_integ_res_c: tx power info
454 * @measurement_req_id: tx power info
455 * @tfd_info: TFD information set by the FH
456 * @seq_ctl: sequence control from the Tx cmd
457 * @byte_cnt: byte count from the Tx cmd
458 * @tlc_info: TLC rate info
459 * @ra_tid: bits [3:0] = ra, bits [7:4] = tid
460 * @frame_ctrl: frame control
461 * @status: for non-agg: frame status TX_STATUS_*
462 * for agg: status of 1st frame, AGG_TX_STATE_*; other frame status fields
463 * follow this one, up to frame_count.
464 *
465 * After the array of statuses comes the SSN of the SCD. Look at
466 * %iwl_mvm_get_scd_ssn for more details.
467 */
468struct iwl_mvm_tx_resp {
469 u8 frame_count;
470 u8 bt_kill_count;
471 u8 failure_rts;
472 u8 failure_frame;
473 __le32 initial_rate;
474 __le16 wireless_media_time;
475
476 u8 pa_status;
477 u8 pa_integ_res_a[3];
478 u8 pa_integ_res_b[3];
479 u8 pa_integ_res_c[3];
480 __le16 measurement_req_id;
481 __le16 reserved;
482
483 __le32 tfd_info;
484 __le16 seq_ctl;
485 __le16 byte_cnt;
486 u8 tlc_info;
487 u8 ra_tid;
488 __le16 frame_ctrl;
489
490 struct agg_tx_status status;
491} __packed; /* TX_RSP_API_S_VER_3 */
492
493/**
494 * struct iwl_mvm_ba_notif - notifies about reception of BA
495 * ( BA_NOTIF = 0xc5 )
496 * @sta_addr_lo32: lower 32 bits of the MAC address
497 * @sta_addr_hi16: upper 16 bits of the MAC address
498 * @sta_id: Index of recipient (BA-sending) station in fw's station table
499 * @tid: tid of the session
500 * @seq_ctl:
501 * @bitmap: the bitmap of the BA notification as seen in the air
502 * @scd_flow: the tx queue this BA relates to
503 * @scd_ssn: the index of the last contiguously sent packet
504 * @txed: number of Txed frames in this batch
505 * @txed_2_done: number of Acked frames in this batch
506 */
507struct iwl_mvm_ba_notif {
508 __le32 sta_addr_lo32;
509 __le16 sta_addr_hi16;
510 __le16 reserved;
511
512 u8 sta_id;
513 u8 tid;
514 __le16 seq_ctl;
515 __le64 bitmap;
516 __le16 scd_flow;
517 __le16 scd_ssn;
518 u8 txed;
519 u8 txed_2_done;
520 __le16 reserved1;
521} __packed;
522
523/*
524 * struct iwl_mac_beacon_cmd - beacon template command
525 * @tx: the tx commands associated with the beacon frame
526 * @template_id: currently equal to the mac context id of the coresponding
527 * mac.
528 * @tim_idx: the offset of the tim IE in the beacon
529 * @tim_size: the length of the tim IE
530 * @frame: the template of the beacon frame
531 */
532struct iwl_mac_beacon_cmd {
533 struct iwl_tx_cmd tx;
534 __le32 template_id;
535 __le32 tim_idx;
536 __le32 tim_size;
537 struct ieee80211_hdr frame[0];
538} __packed;
539
540/**
541 * enum iwl_dump_control - dump (flush) control flags
542 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
543 * and the TFD queues are empty.
544 */
545enum iwl_dump_control {
546 DUMP_TX_FIFO_FLUSH = BIT(1),
547};
548
549/**
550 * struct iwl_tx_path_flush_cmd -- queue/FIFO flush command
551 * @queues_ctl: bitmap of queues to flush
552 * @flush_ctl: control flags
553 * @reserved: reserved
554 */
555struct iwl_tx_path_flush_cmd {
556 __le32 queues_ctl;
557 __le16 flush_ctl;
558 __le16 reserved;
559} __packed; /* TX_PATH_FLUSH_CMD_API_S_VER_1 */
560
561/**
562 * iwl_mvm_get_scd_ssn - returns the SSN of the SCD
563 * @tx_resp: the Tx response from the fw (agg or non-agg)
564 *
565 * When the fw sends an AMPDU, it fetches the MPDUs one after the other. Since
566 * it can't know that everything will go well until the end of the AMPDU, it
567 * can't know in advance the number of MPDUs that will be sent in the current
568 * batch. This is why it writes the agg Tx response while it fetches the MPDUs.
569 * Hence, it can't know in advance what the SSN of the SCD will be at the end
570 * of the batch. This is why the SSN of the SCD is written at the end of the
571 * whole struct at a variable offset. This function knows how to cope with the
572 * variable offset and returns the SSN of the SCD.
573 */
574static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm_tx_resp *tx_resp)
575{
576 return le32_to_cpup((__le32 *)&tx_resp->status +
577 tx_resp->frame_count) & 0xfff;
578}
579
580#endif /* __fw_api_tx_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
new file mode 100644
index 000000000000..9fd49db32a32
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -0,0 +1,949 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __fw_api_h__
65#define __fw_api_h__
66
67#include "fw-api-rs.h"
68#include "fw-api-tx.h"
69#include "fw-api-sta.h"
70#include "fw-api-mac.h"
71#include "fw-api-power.h"
72#include "fw-api-d3.h"
73
74/* queue and FIFO numbers by usage */
75enum {
76 IWL_MVM_OFFCHANNEL_QUEUE = 8,
77 IWL_MVM_CMD_QUEUE = 9,
78 IWL_MVM_AUX_QUEUE = 15,
79 IWL_MVM_FIRST_AGG_QUEUE = 16,
80 IWL_MVM_NUM_QUEUES = 20,
81 IWL_MVM_LAST_AGG_QUEUE = IWL_MVM_NUM_QUEUES - 1,
82 IWL_MVM_CMD_FIFO = 7
83};
84
85#define IWL_MVM_STATION_COUNT 16
86
87/* commands */
88enum {
89 MVM_ALIVE = 0x1,
90 REPLY_ERROR = 0x2,
91
92 INIT_COMPLETE_NOTIF = 0x4,
93
94 /* PHY context commands */
95 PHY_CONTEXT_CMD = 0x8,
96 DBG_CFG = 0x9,
97
98 /* station table */
99 ADD_STA = 0x18,
100 REMOVE_STA = 0x19,
101
102 /* TX */
103 TX_CMD = 0x1c,
104 TXPATH_FLUSH = 0x1e,
105 MGMT_MCAST_KEY = 0x1f,
106
107 /* global key */
108 WEP_KEY = 0x20,
109
110 /* MAC and Binding commands */
111 MAC_CONTEXT_CMD = 0x28,
112 TIME_EVENT_CMD = 0x29, /* both CMD and response */
113 TIME_EVENT_NOTIFICATION = 0x2a,
114 BINDING_CONTEXT_CMD = 0x2b,
115 TIME_QUOTA_CMD = 0x2c,
116
117 LQ_CMD = 0x4e,
118
119 /* Calibration */
120 TEMPERATURE_NOTIFICATION = 0x62,
121 CALIBRATION_CFG_CMD = 0x65,
122 CALIBRATION_RES_NOTIFICATION = 0x66,
123 CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
124 RADIO_VERSION_NOTIFICATION = 0x68,
125
126 /* Scan offload */
127 SCAN_OFFLOAD_REQUEST_CMD = 0x51,
128 SCAN_OFFLOAD_ABORT_CMD = 0x52,
129 SCAN_OFFLOAD_COMPLETE = 0x6D,
130 SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
131 SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
132
133 /* Phy */
134 PHY_CONFIGURATION_CMD = 0x6a,
135 CALIB_RES_NOTIF_PHY_DB = 0x6b,
136 /* PHY_DB_CMD = 0x6c, */
137
138 /* Power */
139 POWER_TABLE_CMD = 0x77,
140
141 /* Scanning */
142 SCAN_REQUEST_CMD = 0x80,
143 SCAN_ABORT_CMD = 0x81,
144 SCAN_START_NOTIFICATION = 0x82,
145 SCAN_RESULTS_NOTIFICATION = 0x83,
146 SCAN_COMPLETE_NOTIFICATION = 0x84,
147
148 /* NVM */
149 NVM_ACCESS_CMD = 0x88,
150
151 SET_CALIB_DEFAULT_CMD = 0x8e,
152
153 BEACON_TEMPLATE_CMD = 0x91,
154 TX_ANT_CONFIGURATION_CMD = 0x98,
155 STATISTICS_NOTIFICATION = 0x9d,
156
157 /* RF-KILL commands and notifications */
158 CARD_STATE_CMD = 0xa0,
159 CARD_STATE_NOTIFICATION = 0xa1,
160
161 REPLY_RX_PHY_CMD = 0xc0,
162 REPLY_RX_MPDU_CMD = 0xc1,
163 BA_NOTIF = 0xc5,
164
165 REPLY_DEBUG_CMD = 0xf0,
166 DEBUG_LOG_MSG = 0xf7,
167
168 /* D3 commands/notifications */
169 D3_CONFIG_CMD = 0xd3,
170 PROT_OFFLOAD_CONFIG_CMD = 0xd4,
171 OFFLOADS_QUERY_CMD = 0xd5,
172 REMOTE_WAKE_CONFIG_CMD = 0xd6,
173
174 /* for WoWLAN in particular */
175 WOWLAN_PATTERNS = 0xe0,
176 WOWLAN_CONFIGURATION = 0xe1,
177 WOWLAN_TSC_RSC_PARAM = 0xe2,
178 WOWLAN_TKIP_PARAM = 0xe3,
179 WOWLAN_KEK_KCK_MATERIAL = 0xe4,
180 WOWLAN_GET_STATUSES = 0xe5,
181 WOWLAN_TX_POWER_PER_DB = 0xe6,
182
183 /* and for NetDetect */
184 NET_DETECT_CONFIG_CMD = 0x54,
185 NET_DETECT_PROFILES_QUERY_CMD = 0x56,
186 NET_DETECT_PROFILES_CMD = 0x57,
187 NET_DETECT_HOTSPOTS_CMD = 0x58,
188 NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
189
190 REPLY_MAX = 0xff,
191};
192
193/**
194 * struct iwl_cmd_response - generic response struct for most commands
195 * @status: status of the command asked, changes for each one
196 */
197struct iwl_cmd_response {
198 __le32 status;
199};
200
201/*
202 * struct iwl_tx_ant_cfg_cmd
203 * @valid: valid antenna configuration
204 */
205struct iwl_tx_ant_cfg_cmd {
206 __le32 valid;
207} __packed;
208
209/*
210 * Calibration control struct.
211 * Sent as part of the phy configuration command.
212 * @flow_trigger: bitmap for which calibrations to perform according to
213 * flow triggers.
214 * @event_trigger: bitmap for which calibrations to perform according to
215 * event triggers.
216 */
217struct iwl_calib_ctrl {
218 __le32 flow_trigger;
219 __le32 event_trigger;
220} __packed;
221
222/* This enum defines the bitmap of various calibrations to enable in both
223 * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
224 */
225enum iwl_calib_cfg {
226 IWL_CALIB_CFG_XTAL_IDX = BIT(0),
227 IWL_CALIB_CFG_TEMPERATURE_IDX = BIT(1),
228 IWL_CALIB_CFG_VOLTAGE_READ_IDX = BIT(2),
229 IWL_CALIB_CFG_PAPD_IDX = BIT(3),
230 IWL_CALIB_CFG_TX_PWR_IDX = BIT(4),
231 IWL_CALIB_CFG_DC_IDX = BIT(5),
232 IWL_CALIB_CFG_BB_FILTER_IDX = BIT(6),
233 IWL_CALIB_CFG_LO_LEAKAGE_IDX = BIT(7),
234 IWL_CALIB_CFG_TX_IQ_IDX = BIT(8),
235 IWL_CALIB_CFG_TX_IQ_SKEW_IDX = BIT(9),
236 IWL_CALIB_CFG_RX_IQ_IDX = BIT(10),
237 IWL_CALIB_CFG_RX_IQ_SKEW_IDX = BIT(11),
238 IWL_CALIB_CFG_SENSITIVITY_IDX = BIT(12),
239 IWL_CALIB_CFG_CHAIN_NOISE_IDX = BIT(13),
240 IWL_CALIB_CFG_DISCONNECTED_ANT_IDX = BIT(14),
241 IWL_CALIB_CFG_ANT_COUPLING_IDX = BIT(15),
242 IWL_CALIB_CFG_DAC_IDX = BIT(16),
243 IWL_CALIB_CFG_ABS_IDX = BIT(17),
244 IWL_CALIB_CFG_AGC_IDX = BIT(18),
245};
246
247/*
248 * Phy configuration command.
249 */
250struct iwl_phy_cfg_cmd {
251 __le32 phy_cfg;
252 struct iwl_calib_ctrl calib_control;
253} __packed;
254
255#define PHY_CFG_RADIO_TYPE (BIT(0) | BIT(1))
256#define PHY_CFG_RADIO_STEP (BIT(2) | BIT(3))
257#define PHY_CFG_RADIO_DASH (BIT(4) | BIT(5))
258#define PHY_CFG_PRODUCT_NUMBER (BIT(6) | BIT(7))
259#define PHY_CFG_TX_CHAIN_A BIT(8)
260#define PHY_CFG_TX_CHAIN_B BIT(9)
261#define PHY_CFG_TX_CHAIN_C BIT(10)
262#define PHY_CFG_RX_CHAIN_A BIT(12)
263#define PHY_CFG_RX_CHAIN_B BIT(13)
264#define PHY_CFG_RX_CHAIN_C BIT(14)
265
266
267/* Target of the NVM_ACCESS_CMD */
268enum {
269 NVM_ACCESS_TARGET_CACHE = 0,
270 NVM_ACCESS_TARGET_OTP = 1,
271 NVM_ACCESS_TARGET_EEPROM = 2,
272};
273
274/**
275 * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
276 * @op_code: 0 - read, 1 - write.
277 * @target: NVM_ACCESS_TARGET_*. should be 0 for read.
278 * @cache_refresh: 0 - None, 1- NVM.
279 * @offset: offset in the nvm data.
280 * @length: of the chunk.
281 * @data: empty on read, the NVM chunk on write
282 */
283struct iwl_nvm_access_cmd_ver1 {
284 u8 op_code;
285 u8 target;
286 u8 cache_refresh;
287 u8 reserved;
288 __le16 offset;
289 __le16 length;
290 u8 data[];
291} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
292
293/**
294 * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
295 * @offset: the offset in the nvm data
296 * @length: of the chunk
297 * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
298 */
299struct iwl_nvm_access_resp_ver1 {
300 __le16 offset;
301 __le16 length;
302 u8 data[];
303} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
304
305/* Section types for NVM_ACCESS_CMD version 2 */
306enum {
307 NVM_SECTION_TYPE_HW = 0,
308 NVM_SECTION_TYPE_SW,
309 NVM_SECTION_TYPE_PAPD,
310 NVM_SECTION_TYPE_BT,
311 NVM_SECTION_TYPE_CALIBRATION,
312 NVM_SECTION_TYPE_PRODUCTION,
313 NVM_SECTION_TYPE_POST_FCS_CALIB,
314 NVM_NUM_OF_SECTIONS,
315};
316
317/**
318 * struct iwl_nvm_access_cmd_ver2 - Request the device to send an NVM section
319 * @op_code: 0 - read, 1 - write
320 * @target: NVM_ACCESS_TARGET_*
321 * @type: NVM_SECTION_TYPE_*
322 * @offset: offset in bytes into the section
323 * @length: in bytes, to read/write
324 * @data: if write operation, the data to write. On read its empty
325 */
326struct iwl_nvm_access_cmd_ver2 {
327 u8 op_code;
328 u8 target;
329 __le16 type;
330 __le16 offset;
331 __le16 length;
332 u8 data[];
333} __packed; /* NVM_ACCESS_CMD_API_S_VER_2 */
334
335/**
336 * struct iwl_nvm_access_resp_ver2 - response to NVM_ACCESS_CMD
337 * @offset: offset in bytes into the section
338 * @length: in bytes, either how much was written or read
339 * @type: NVM_SECTION_TYPE_*
340 * @status: 0 for success, fail otherwise
341 * @data: if read operation, the data returned. Empty on write.
342 */
343struct iwl_nvm_access_resp_ver2 {
344 __le16 offset;
345 __le16 length;
346 __le16 type;
347 __le16 status;
348 u8 data[];
349} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_2 */
350
351/* MVM_ALIVE 0x1 */
352
353/* alive response is_valid values */
354#define ALIVE_RESP_UCODE_OK BIT(0)
355#define ALIVE_RESP_RFKILL BIT(1)
356
357/* alive response ver_type values */
358enum {
359 FW_TYPE_HW = 0,
360 FW_TYPE_PROT = 1,
361 FW_TYPE_AP = 2,
362 FW_TYPE_WOWLAN = 3,
363 FW_TYPE_TIMING = 4,
364 FW_TYPE_WIPAN = 5
365};
366
367/* alive response ver_subtype values */
368enum {
369 FW_SUBTYPE_FULL_FEATURE = 0,
370 FW_SUBTYPE_BOOTSRAP = 1, /* Not valid */
371 FW_SUBTYPE_REDUCED = 2,
372 FW_SUBTYPE_ALIVE_ONLY = 3,
373 FW_SUBTYPE_WOWLAN = 4,
374 FW_SUBTYPE_AP_SUBTYPE = 5,
375 FW_SUBTYPE_WIPAN = 6,
376 FW_SUBTYPE_INITIALIZE = 9
377};
378
379#define IWL_ALIVE_STATUS_ERR 0xDEAD
380#define IWL_ALIVE_STATUS_OK 0xCAFE
381
382#define IWL_ALIVE_FLG_RFKILL BIT(0)
383
384struct mvm_alive_resp {
385 __le16 status;
386 __le16 flags;
387 u8 ucode_minor;
388 u8 ucode_major;
389 __le16 id;
390 u8 api_minor;
391 u8 api_major;
392 u8 ver_subtype;
393 u8 ver_type;
394 u8 mac;
395 u8 opt;
396 __le16 reserved2;
397 __le32 timestamp;
398 __le32 error_event_table_ptr; /* SRAM address for error log */
399 __le32 log_event_table_ptr; /* SRAM address for event log */
400 __le32 cpu_register_ptr;
401 __le32 dbgm_config_ptr;
402 __le32 alive_counter_ptr;
403 __le32 scd_base_ptr; /* SRAM address for SCD */
404} __packed; /* ALIVE_RES_API_S_VER_1 */
405
406/* Error response/notification */
407enum {
408 FW_ERR_UNKNOWN_CMD = 0x0,
409 FW_ERR_INVALID_CMD_PARAM = 0x1,
410 FW_ERR_SERVICE = 0x2,
411 FW_ERR_ARC_MEMORY = 0x3,
412 FW_ERR_ARC_CODE = 0x4,
413 FW_ERR_WATCH_DOG = 0x5,
414 FW_ERR_WEP_GRP_KEY_INDX = 0x10,
415 FW_ERR_WEP_KEY_SIZE = 0x11,
416 FW_ERR_OBSOLETE_FUNC = 0x12,
417 FW_ERR_UNEXPECTED = 0xFE,
418 FW_ERR_FATAL = 0xFF
419};
420
421/**
422 * struct iwl_error_resp - FW error indication
423 * ( REPLY_ERROR = 0x2 )
424 * @error_type: one of FW_ERR_*
425 * @cmd_id: the command ID for which the error occured
426 * @bad_cmd_seq_num: sequence number of the erroneous command
427 * @error_service: which service created the error, applicable only if
428 * error_type = 2, otherwise 0
429 * @timestamp: TSF in usecs.
430 */
431struct iwl_error_resp {
432 __le32 error_type;
433 u8 cmd_id;
434 u8 reserved1;
435 __le16 bad_cmd_seq_num;
436 __le32 error_service;
437 __le64 timestamp;
438} __packed;
439
440
441/* Common PHY, MAC and Bindings definitions */
442
443#define MAX_MACS_IN_BINDING (3)
444#define MAX_BINDINGS (4)
445#define AUX_BINDING_INDEX (3)
446#define MAX_PHYS (4)
447
448/* Used to extract ID and color from the context dword */
449#define FW_CTXT_ID_POS (0)
450#define FW_CTXT_ID_MSK (0xff << FW_CTXT_ID_POS)
451#define FW_CTXT_COLOR_POS (8)
452#define FW_CTXT_COLOR_MSK (0xff << FW_CTXT_COLOR_POS)
453#define FW_CTXT_INVALID (0xffffffff)
454
455#define FW_CMD_ID_AND_COLOR(_id, _color) ((_id << FW_CTXT_ID_POS) |\
456 (_color << FW_CTXT_COLOR_POS))
457
458/* Possible actions on PHYs, MACs and Bindings */
459enum {
460 FW_CTXT_ACTION_STUB = 0,
461 FW_CTXT_ACTION_ADD,
462 FW_CTXT_ACTION_MODIFY,
463 FW_CTXT_ACTION_REMOVE,
464 FW_CTXT_ACTION_NUM
465}; /* COMMON_CONTEXT_ACTION_API_E_VER_1 */
466
467/* Time Events */
468
469/* Time Event types, according to MAC type */
470enum iwl_time_event_type {
471 /* BSS Station Events */
472 TE_BSS_STA_AGGRESSIVE_ASSOC,
473 TE_BSS_STA_ASSOC,
474 TE_BSS_EAP_DHCP_PROT,
475 TE_BSS_QUIET_PERIOD,
476
477 /* P2P Device Events */
478 TE_P2P_DEVICE_DISCOVERABLE,
479 TE_P2P_DEVICE_LISTEN,
480 TE_P2P_DEVICE_ACTION_SCAN,
481 TE_P2P_DEVICE_FULL_SCAN,
482
483 /* P2P Client Events */
484 TE_P2P_CLIENT_AGGRESSIVE_ASSOC,
485 TE_P2P_CLIENT_ASSOC,
486 TE_P2P_CLIENT_QUIET_PERIOD,
487
488 /* P2P GO Events */
489 TE_P2P_GO_ASSOC_PROT,
490 TE_P2P_GO_REPETITIVE_NOA,
491 TE_P2P_GO_CT_WINDOW,
492
493 /* WiDi Sync Events */
494 TE_WIDI_TX_SYNC,
495
496 TE_MAX
497}; /* MAC_EVENT_TYPE_API_E_VER_1 */
498
499/* Time Event dependencies: none, on another TE, or in a specific time */
500enum {
501 TE_INDEPENDENT = 0,
502 TE_DEP_OTHER = 1,
503 TE_DEP_TSF = 2,
504 TE_EVENT_SOCIOPATHIC = 4,
505}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */
506
507/* When to send Time Event notifications and to whom (internal = FW) */
508enum {
509 TE_NOTIF_NONE = 0,
510 TE_NOTIF_HOST_START = 0x1,
511 TE_NOTIF_HOST_END = 0x2,
512 TE_NOTIF_INTERNAL_START = 0x4,
513 TE_NOTIF_INTERNAL_END = 0x8
514}; /* MAC_EVENT_ACTION_API_E_VER_1 */
515
516/*
517 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed.
518 * @TE_FRAG_SINGLE: fragmentation of the time event is allowed, but only
519 * the first fragment is scheduled.
520 * @TE_FRAG_DUAL: fragmentation of the time event is allowed, but only
521 * the first 2 fragments are scheduled.
522 * @TE_FRAG_ENDLESS: fragmentation of the time event is allowed, and any number
523 * of fragments are valid.
524 *
525 * Other than the constant defined above, specifying a fragmentation value 'x'
526 * means that the event can be fragmented but only the first 'x' will be
527 * scheduled.
528 */
529enum {
530 TE_FRAG_NONE = 0,
531 TE_FRAG_SINGLE = 1,
532 TE_FRAG_DUAL = 2,
533 TE_FRAG_ENDLESS = 0xffffffff
534};
535
536/* Repeat the time event endlessly (until removed) */
537#define TE_REPEAT_ENDLESS (0xffffffff)
538/* If a Time Event has bounded repetitions, this is the maximal value */
539#define TE_REPEAT_MAX_MSK (0x0fffffff)
540/* If a Time Event can be fragmented, this is the max number of fragments */
541#define TE_FRAG_MAX_MSK (0x0fffffff)
542
543/**
544 * struct iwl_time_event_cmd - configuring Time Events
545 * ( TIME_EVENT_CMD = 0x29 )
546 * @id_and_color: ID and color of the relevant MAC
547 * @action: action to perform, one of FW_CTXT_ACTION_*
548 * @id: this field has two meanings, depending on the action:
549 * If the action is ADD, then it means the type of event to add.
550 * For all other actions it is the unique event ID assigned when the
551 * event was added by the FW.
552 * @apply_time: When to start the Time Event (in GP2)
553 * @max_delay: maximum delay to event's start (apply time), in TU
554 * @depends_on: the unique ID of the event we depend on (if any)
555 * @interval: interval between repetitions, in TU
556 * @interval_reciprocal: 2^32 / interval
557 * @duration: duration of event in TU
558 * @repeat: how many repetitions to do, can be TE_REPEAT_ENDLESS
559 * @dep_policy: one of TE_INDEPENDENT, TE_DEP_OTHER, TE_DEP_TSF
560 * @is_present: 0 or 1, are we present or absent during the Time Event
561 * @max_frags: maximal number of fragments the Time Event can be divided to
562 * @notify: notifications using TE_NOTIF_* (whom to notify when)
563 */
564struct iwl_time_event_cmd {
565 /* COMMON_INDEX_HDR_API_S_VER_1 */
566 __le32 id_and_color;
567 __le32 action;
568 __le32 id;
569 /* MAC_TIME_EVENT_DATA_API_S_VER_1 */
570 __le32 apply_time;
571 __le32 max_delay;
572 __le32 dep_policy;
573 __le32 depends_on;
574 __le32 is_present;
575 __le32 max_frags;
576 __le32 interval;
577 __le32 interval_reciprocal;
578 __le32 duration;
579 __le32 repeat;
580 __le32 notify;
581} __packed; /* MAC_TIME_EVENT_CMD_API_S_VER_1 */
582
583/**
584 * struct iwl_time_event_resp - response structure to iwl_time_event_cmd
585 * @status: bit 0 indicates success, all others specify errors
586 * @id: the Time Event type
587 * @unique_id: the unique ID assigned (in ADD) or given (others) to the TE
588 * @id_and_color: ID and color of the relevant MAC
589 */
590struct iwl_time_event_resp {
591 __le32 status;
592 __le32 id;
593 __le32 unique_id;
594 __le32 id_and_color;
595} __packed; /* MAC_TIME_EVENT_RSP_API_S_VER_1 */
596
597/**
598 * struct iwl_time_event_notif - notifications of time event start/stop
599 * ( TIME_EVENT_NOTIFICATION = 0x2a )
600 * @timestamp: action timestamp in GP2
601 * @session_id: session's unique id
602 * @unique_id: unique id of the Time Event itself
603 * @id_and_color: ID and color of the relevant MAC
604 * @action: one of TE_NOTIF_START or TE_NOTIF_END
605 * @status: true if scheduled, false otherwise (not executed)
606 */
607struct iwl_time_event_notif {
608 __le32 timestamp;
609 __le32 session_id;
610 __le32 unique_id;
611 __le32 id_and_color;
612 __le32 action;
613 __le32 status;
614} __packed; /* MAC_TIME_EVENT_NTFY_API_S_VER_1 */
615
616
617/* Bindings and Time Quota */
618
619/**
620 * struct iwl_binding_cmd - configuring bindings
621 * ( BINDING_CONTEXT_CMD = 0x2b )
622 * @id_and_color: ID and color of the relevant Binding
623 * @action: action to perform, one of FW_CTXT_ACTION_*
624 * @macs: array of MAC id and colors which belong to the binding
625 * @phy: PHY id and color which belongs to the binding
626 */
627struct iwl_binding_cmd {
628 /* COMMON_INDEX_HDR_API_S_VER_1 */
629 __le32 id_and_color;
630 __le32 action;
631 /* BINDING_DATA_API_S_VER_1 */
632 __le32 macs[MAX_MACS_IN_BINDING];
633 __le32 phy;
634} __packed; /* BINDING_CMD_API_S_VER_1 */
635
636/**
637 * struct iwl_time_quota_data - configuration of time quota per binding
638 * @id_and_color: ID and color of the relevant Binding
639 * @quota: absolute time quota in TU. The scheduler will try to divide the
640 * remainig quota (after Time Events) according to this quota.
641 * @max_duration: max uninterrupted context duration in TU
642 */
643struct iwl_time_quota_data {
644 __le32 id_and_color;
645 __le32 quota;
646 __le32 max_duration;
647} __packed; /* TIME_QUOTA_DATA_API_S_VER_1 */
648
649/**
650 * struct iwl_time_quota_cmd - configuration of time quota between bindings
651 * ( TIME_QUOTA_CMD = 0x2c )
652 * @quotas: allocations per binding
653 */
654struct iwl_time_quota_cmd {
655 struct iwl_time_quota_data quotas[MAX_BINDINGS];
656} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_1 */
657
658
659/* PHY context */
660
661/* Supported bands */
662#define PHY_BAND_5 (0)
663#define PHY_BAND_24 (1)
664
665/* Supported channel width, vary if there is VHT support */
666#define PHY_VHT_CHANNEL_MODE20 (0x0)
667#define PHY_VHT_CHANNEL_MODE40 (0x1)
668#define PHY_VHT_CHANNEL_MODE80 (0x2)
669#define PHY_VHT_CHANNEL_MODE160 (0x3)
670
671/*
672 * Control channel position:
673 * For legacy set bit means upper channel, otherwise lower.
674 * For VHT - bit-2 marks if the control is lower/upper relative to center-freq
675 * bits-1:0 mark the distance from the center freq. for 20Mhz, offset is 0.
676 * center_freq
677 * |
678 * 40Mhz |_______|_______|
679 * 80Mhz |_______|_______|_______|_______|
680 * 160Mhz |_______|_______|_______|_______|_______|_______|_______|_______|
681 * code 011 010 001 000 | 100 101 110 111
682 */
683#define PHY_VHT_CTRL_POS_1_BELOW (0x0)
684#define PHY_VHT_CTRL_POS_2_BELOW (0x1)
685#define PHY_VHT_CTRL_POS_3_BELOW (0x2)
686#define PHY_VHT_CTRL_POS_4_BELOW (0x3)
687#define PHY_VHT_CTRL_POS_1_ABOVE (0x4)
688#define PHY_VHT_CTRL_POS_2_ABOVE (0x5)
689#define PHY_VHT_CTRL_POS_3_ABOVE (0x6)
690#define PHY_VHT_CTRL_POS_4_ABOVE (0x7)
691
692/*
693 * @band: PHY_BAND_*
694 * @channel: channel number
695 * @width: PHY_[VHT|LEGACY]_CHANNEL_*
696 * @ctrl channel: PHY_[VHT|LEGACY]_CTRL_*
697 */
698struct iwl_fw_channel_info {
699 u8 band;
700 u8 channel;
701 u8 width;
702 u8 ctrl_pos;
703} __packed;
704
705#define PHY_RX_CHAIN_DRIVER_FORCE_POS (0)
706#define PHY_RX_CHAIN_DRIVER_FORCE_MSK \
707 (0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS)
708#define PHY_RX_CHAIN_VALID_POS (1)
709#define PHY_RX_CHAIN_VALID_MSK \
710 (0x7 << PHY_RX_CHAIN_VALID_POS)
711#define PHY_RX_CHAIN_FORCE_SEL_POS (4)
712#define PHY_RX_CHAIN_FORCE_SEL_MSK \
713 (0x7 << PHY_RX_CHAIN_FORCE_SEL_POS)
714#define PHY_RX_CHAIN_FORCE_MIMO_SEL_POS (7)
715#define PHY_RX_CHAIN_FORCE_MIMO_SEL_MSK \
716 (0x7 << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS)
717#define PHY_RX_CHAIN_CNT_POS (10)
718#define PHY_RX_CHAIN_CNT_MSK \
719 (0x3 << PHY_RX_CHAIN_CNT_POS)
720#define PHY_RX_CHAIN_MIMO_CNT_POS (12)
721#define PHY_RX_CHAIN_MIMO_CNT_MSK \
722 (0x3 << PHY_RX_CHAIN_MIMO_CNT_POS)
723#define PHY_RX_CHAIN_MIMO_FORCE_POS (14)
724#define PHY_RX_CHAIN_MIMO_FORCE_MSK \
725 (0x1 << PHY_RX_CHAIN_MIMO_FORCE_POS)
726
727/* TODO: fix the value, make it depend on firmware at runtime? */
728#define NUM_PHY_CTX 3
729
730/* TODO: complete missing documentation */
731/**
732 * struct iwl_phy_context_cmd - config of the PHY context
733 * ( PHY_CONTEXT_CMD = 0x8 )
734 * @id_and_color: ID and color of the relevant Binding
735 * @action: action to perform, one of FW_CTXT_ACTION_*
736 * @apply_time: 0 means immediate apply and context switch.
737 * other value means apply new params after X usecs
738 * @tx_param_color: ???
739 * @channel_info:
740 * @txchain_info: ???
741 * @rxchain_info: ???
742 * @acquisition_data: ???
743 * @dsp_cfg_flags: set to 0
744 */
745struct iwl_phy_context_cmd {
746 /* COMMON_INDEX_HDR_API_S_VER_1 */
747 __le32 id_and_color;
748 __le32 action;
749 /* PHY_CONTEXT_DATA_API_S_VER_1 */
750 __le32 apply_time;
751 __le32 tx_param_color;
752 struct iwl_fw_channel_info ci;
753 __le32 txchain_info;
754 __le32 rxchain_info;
755 __le32 acquisition_data;
756 __le32 dsp_cfg_flags;
757} __packed; /* PHY_CONTEXT_CMD_API_VER_1 */
758
759#define IWL_RX_INFO_PHY_CNT 8
760#define IWL_RX_INFO_AGC_IDX 1
761#define IWL_RX_INFO_RSSI_AB_IDX 2
762#define IWL_RX_INFO_RSSI_C_IDX 3
763#define IWL_OFDM_AGC_DB_MSK 0xfe00
764#define IWL_OFDM_AGC_DB_POS 9
765#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
766#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
767#define IWL_OFDM_RSSI_A_POS 0
768#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
769#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
770#define IWL_OFDM_RSSI_B_POS 16
771#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff
772#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00
773#define IWL_OFDM_RSSI_C_POS 0
774
775/**
776 * struct iwl_rx_phy_info - phy info
777 * (REPLY_RX_PHY_CMD = 0xc0)
778 * @non_cfg_phy_cnt: non configurable DSP phy data byte count
779 * @cfg_phy_cnt: configurable DSP phy data byte count
780 * @stat_id: configurable DSP phy data set ID
781 * @reserved1:
782 * @system_timestamp: GP2 at on air rise
783 * @timestamp: TSF at on air rise
784 * @beacon_time_stamp: beacon at on-air rise
785 * @phy_flags: general phy flags: band, modulation, ...
786 * @channel: channel number
787 * @non_cfg_phy_buf: for various implementations of non_cfg_phy
788 * @rate_n_flags: RATE_MCS_*
789 * @byte_count: frame's byte-count
790 * @frame_time: frame's time on the air, based on byte count and frame rate
791 * calculation
792 *
793 * Before each Rx, the device sends this data. It contains PHY information
794 * about the reception of the packet.
795 */
796struct iwl_rx_phy_info {
797 u8 non_cfg_phy_cnt;
798 u8 cfg_phy_cnt;
799 u8 stat_id;
800 u8 reserved1;
801 __le32 system_timestamp;
802 __le64 timestamp;
803 __le32 beacon_time_stamp;
804 __le16 phy_flags;
805 __le16 channel;
806 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];
807 __le32 rate_n_flags;
808 __le32 byte_count;
809 __le16 reserved2;
810 __le16 frame_time;
811} __packed;
812
813struct iwl_rx_mpdu_res_start {
814 __le16 byte_count;
815 __le16 reserved;
816} __packed;
817
818/**
819 * enum iwl_rx_phy_flags - to parse %iwl_rx_phy_info phy_flags
820 * @RX_RES_PHY_FLAGS_BAND_24: true if the packet was received on 2.4 band
821 * @RX_RES_PHY_FLAGS_MOD_CCK:
822 * @RX_RES_PHY_FLAGS_SHORT_PREAMBLE: true if packet's preamble was short
823 * @RX_RES_PHY_FLAGS_NARROW_BAND:
824 * @RX_RES_PHY_FLAGS_ANTENNA: antenna on which the packet was received
825 * @RX_RES_PHY_FLAGS_AGG: set if the packet was part of an A-MPDU
826 * @RX_RES_PHY_FLAGS_OFDM_HT: The frame was an HT frame
827 * @RX_RES_PHY_FLAGS_OFDM_GF: The frame used GF preamble
828 * @RX_RES_PHY_FLAGS_OFDM_VHT: The frame was a VHT frame
829 */
830enum iwl_rx_phy_flags {
831 RX_RES_PHY_FLAGS_BAND_24 = BIT(0),
832 RX_RES_PHY_FLAGS_MOD_CCK = BIT(1),
833 RX_RES_PHY_FLAGS_SHORT_PREAMBLE = BIT(2),
834 RX_RES_PHY_FLAGS_NARROW_BAND = BIT(3),
835 RX_RES_PHY_FLAGS_ANTENNA = (0x7 << 4),
836 RX_RES_PHY_FLAGS_ANTENNA_POS = 4,
837 RX_RES_PHY_FLAGS_AGG = BIT(7),
838 RX_RES_PHY_FLAGS_OFDM_HT = BIT(8),
839 RX_RES_PHY_FLAGS_OFDM_GF = BIT(9),
840 RX_RES_PHY_FLAGS_OFDM_VHT = BIT(10),
841};
842
843/**
844 * enum iwl_mvm_rx_status - written by fw for each Rx packet
845 * @RX_MPDU_RES_STATUS_CRC_OK: CRC is fine
846 * @RX_MPDU_RES_STATUS_OVERRUN_OK: there was no RXE overflow
847 * @RX_MPDU_RES_STATUS_SRC_STA_FOUND:
848 * @RX_MPDU_RES_STATUS_KEY_VALID:
849 * @RX_MPDU_RES_STATUS_KEY_PARAM_OK:
850 * @RX_MPDU_RES_STATUS_ICV_OK: ICV is fine, if not, the packet is destroyed
851 * @RX_MPDU_RES_STATUS_MIC_OK: used for CCM alg only. TKIP MIC is checked
852 * in the driver.
853 * @RX_MPDU_RES_STATUS_TTAK_OK: TTAK is fine
854 * @RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR: valid for alg = CCM_CMAC or
855 * alg = CCM only. Checks replay attack for 11w frames. Relevant only if
856 * %RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME is set.
857 * @RX_MPDU_RES_STATUS_SEC_NO_ENC: this frame is not encrypted
858 * @RX_MPDU_RES_STATUS_SEC_WEP_ENC: this frame is encrypted using WEP
859 * @RX_MPDU_RES_STATUS_SEC_CCM_ENC: this frame is encrypted using CCM
860 * @RX_MPDU_RES_STATUS_SEC_TKIP_ENC: this frame is encrypted using TKIP
861 * @RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC: this frame is encrypted using CCM_CMAC
862 * @RX_MPDU_RES_STATUS_SEC_ENC_ERR: this frame couldn't be decrypted
863 * @RX_MPDU_RES_STATUS_SEC_ENC_MSK: bitmask of the encryption algorithm
864 * @RX_MPDU_RES_STATUS_DEC_DONE: this frame has been successfully decrypted
865 * @RX_MPDU_RES_STATUS_PROTECT_FRAME_BIT_CMP:
866 * @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP:
867 * @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT:
868 * @RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME: this frame is an 11w management frame
869 * @RX_MPDU_RES_STATUS_HASH_INDEX_MSK:
870 * @RX_MPDU_RES_STATUS_STA_ID_MSK:
871 * @RX_MPDU_RES_STATUS_RRF_KILL:
872 * @RX_MPDU_RES_STATUS_FILTERING_MSK:
873 * @RX_MPDU_RES_STATUS2_FILTERING_MSK:
874 */
875enum iwl_mvm_rx_status {
876 RX_MPDU_RES_STATUS_CRC_OK = BIT(0),
877 RX_MPDU_RES_STATUS_OVERRUN_OK = BIT(1),
878 RX_MPDU_RES_STATUS_SRC_STA_FOUND = BIT(2),
879 RX_MPDU_RES_STATUS_KEY_VALID = BIT(3),
880 RX_MPDU_RES_STATUS_KEY_PARAM_OK = BIT(4),
881 RX_MPDU_RES_STATUS_ICV_OK = BIT(5),
882 RX_MPDU_RES_STATUS_MIC_OK = BIT(6),
883 RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
884 RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR = BIT(7),
885 RX_MPDU_RES_STATUS_SEC_NO_ENC = (0 << 8),
886 RX_MPDU_RES_STATUS_SEC_WEP_ENC = (1 << 8),
887 RX_MPDU_RES_STATUS_SEC_CCM_ENC = (2 << 8),
888 RX_MPDU_RES_STATUS_SEC_TKIP_ENC = (3 << 8),
889 RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC = (6 << 8),
890 RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8),
891 RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8),
892 RX_MPDU_RES_STATUS_DEC_DONE = BIT(11),
893 RX_MPDU_RES_STATUS_PROTECT_FRAME_BIT_CMP = BIT(12),
894 RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP = BIT(13),
895 RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT = BIT(14),
896 RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME = BIT(15),
897 RX_MPDU_RES_STATUS_HASH_INDEX_MSK = (0x3F0000),
898 RX_MPDU_RES_STATUS_STA_ID_MSK = (0x1f000000),
899 RX_MPDU_RES_STATUS_RRF_KILL = BIT(29),
900 RX_MPDU_RES_STATUS_FILTERING_MSK = (0xc00000),
901 RX_MPDU_RES_STATUS2_FILTERING_MSK = (0xc0000000),
902};
903
904/**
905 * struct iwl_radio_version_notif - information on the radio version
906 * ( RADIO_VERSION_NOTIFICATION = 0x68 )
907 * @radio_flavor:
908 * @radio_step:
909 * @radio_dash:
910 */
911struct iwl_radio_version_notif {
912 __le32 radio_flavor;
913 __le32 radio_step;
914 __le32 radio_dash;
915} __packed; /* RADIO_VERSION_NOTOFICATION_S_VER_1 */
916
917enum iwl_card_state_flags {
918 CARD_ENABLED = 0x00,
919 HW_CARD_DISABLED = 0x01,
920 SW_CARD_DISABLED = 0x02,
921 CT_KILL_CARD_DISABLED = 0x04,
922 HALT_CARD_DISABLED = 0x08,
923 CARD_DISABLED_MSK = 0x0f,
924 CARD_IS_RX_ON = 0x10,
925};
926
927/**
928 * struct iwl_radio_version_notif - information on the radio version
929 * ( CARD_STATE_NOTIFICATION = 0xa1 )
930 * @flags: %iwl_card_state_flags
931 */
932struct iwl_card_state_notif {
933 __le32 flags;
934} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
935
936/**
937 * struct iwl_set_calib_default_cmd - set default value for calibration.
938 * ( SET_CALIB_DEFAULT_CMD = 0x8e )
939 * @calib_index: the calibration to set value for
940 * @length: of data
941 * @data: the value to set for the calibration result
942 */
943struct iwl_set_calib_default_cmd {
944 __le16 calib_index;
945 __le16 length;
946 u8 data[0];
947} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
948
949#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
new file mode 100644
index 000000000000..90473c2ba1c7
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -0,0 +1,644 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <net/mac80211.h>
64
65#include "iwl-trans.h"
66#include "iwl-op-mode.h"
67#include "iwl-fw.h"
68#include "iwl-debug.h"
69#include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */
70#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */
71#include "iwl-eeprom-parse.h"
72
73#include "mvm.h"
74#include "iwl-phy-db.h"
75
76#define MVM_UCODE_ALIVE_TIMEOUT HZ
77#define MVM_UCODE_CALIB_TIMEOUT (2*HZ)
78
79#define UCODE_VALID_OK cpu_to_le32(0x1)
80
81/* Default calibration values for WkP - set to INIT image w/o running */
82static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
83 0x00, 0x18, 0x00 };
84static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
85 0x7f, 0x7f, 0x7f };
86static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
87static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
88 0x00 };
89static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
90static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
91static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
92static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
93
94struct iwl_calib_default_data {
95 u16 size;
96 void *data;
97};
98
99#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
100
101static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
102 [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
103 [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
104 [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
105 [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
106 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
107 [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
108 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
109};
110
111struct iwl_mvm_alive_data {
112 bool valid;
113 u32 scd_base_addr;
114};
115
116static inline const struct fw_img *
117iwl_get_ucode_image(struct iwl_mvm *mvm, enum iwl_ucode_type ucode_type)
118{
119 if (ucode_type >= IWL_UCODE_TYPE_MAX)
120 return NULL;
121
122 return &mvm->fw->img[ucode_type];
123}
124
125static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
126{
127 struct iwl_tx_ant_cfg_cmd tx_ant_cmd = {
128 .valid = cpu_to_le32(valid_tx_ant),
129 };
130
131 IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant);
132 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
133 sizeof(tx_ant_cmd), &tx_ant_cmd);
134}
135
136static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
137 struct iwl_rx_packet *pkt, void *data)
138{
139 struct iwl_mvm *mvm =
140 container_of(notif_wait, struct iwl_mvm, notif_wait);
141 struct iwl_mvm_alive_data *alive_data = data;
142 struct mvm_alive_resp *palive;
143
144 palive = (void *)pkt->data;
145
146 mvm->error_event_table = le32_to_cpu(palive->error_event_table_ptr);
147 mvm->log_event_table = le32_to_cpu(palive->log_event_table_ptr);
148 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
149
150 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
151 IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n",
152 le16_to_cpu(palive->status), palive->ver_type,
153 palive->ver_subtype);
154
155 return true;
156}
157
158static bool iwl_wait_phy_db_entry(struct iwl_notif_wait_data *notif_wait,
159 struct iwl_rx_packet *pkt, void *data)
160{
161 struct iwl_phy_db *phy_db = data;
162
163 if (pkt->hdr.cmd != CALIB_RES_NOTIF_PHY_DB) {
164 WARN_ON(pkt->hdr.cmd != INIT_COMPLETE_NOTIF);
165 return true;
166 }
167
168 WARN_ON(iwl_phy_db_set_section(phy_db, pkt, GFP_ATOMIC));
169
170 return false;
171}
172
173static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
174 enum iwl_ucode_type ucode_type)
175{
176 struct iwl_notification_wait alive_wait;
177 struct iwl_mvm_alive_data alive_data;
178 const struct fw_img *fw;
179 int ret, i;
180 enum iwl_ucode_type old_type = mvm->cur_ucode;
181 static const u8 alive_cmd[] = { MVM_ALIVE };
182
183 mvm->cur_ucode = ucode_type;
184 fw = iwl_get_ucode_image(mvm, ucode_type);
185
186 mvm->ucode_loaded = false;
187
188 if (!fw)
189 return -EINVAL;
190
191 iwl_init_notification_wait(&mvm->notif_wait, &alive_wait,
192 alive_cmd, ARRAY_SIZE(alive_cmd),
193 iwl_alive_fn, &alive_data);
194
195 ret = iwl_trans_start_fw(mvm->trans, fw, ucode_type == IWL_UCODE_INIT);
196 if (ret) {
197 mvm->cur_ucode = old_type;
198 iwl_remove_notification(&mvm->notif_wait, &alive_wait);
199 return ret;
200 }
201
202 /*
203 * Some things may run in the background now, but we
204 * just wait for the ALIVE notification here.
205 */
206 ret = iwl_wait_notification(&mvm->notif_wait, &alive_wait,
207 MVM_UCODE_ALIVE_TIMEOUT);
208 if (ret) {
209 mvm->cur_ucode = old_type;
210 return ret;
211 }
212
213 if (!alive_data.valid) {
214 IWL_ERR(mvm, "Loaded ucode is not valid!\n");
215 mvm->cur_ucode = old_type;
216 return -EIO;
217 }
218
219 iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr);
220
221 /*
222 * Note: all the queues are enabled as part of the interface
223 * initialization, but in firmware restart scenarios they
224 * could be stopped, so wake them up. In firmware restart,
225 * mac80211 will have the queues stopped as well until the
226 * reconfiguration completes. During normal startup, they
227 * will be empty.
228 */
229
230 for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
231 if (i < IWL_MVM_FIRST_AGG_QUEUE && i != IWL_MVM_CMD_QUEUE)
232 mvm->queue_to_mac80211[i] = i;
233 else
234 mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
235 atomic_set(&mvm->queue_stop_count[i], 0);
236 }
237
238 mvm->transport_queue_stop = 0;
239
240 mvm->ucode_loaded = true;
241
242 return 0;
243}
244#define IWL_HW_REV_ID_RAINBOW 0x2
245#define IWL_PROJ_TYPE_LHP 0x5
246
247static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
248{
249 struct iwl_nvm_data *data = mvm->nvm_data;
250 /* Temp calls to static definitions, will be changed to CSR calls */
251 u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
252 u8 project_type = IWL_PROJ_TYPE_LHP;
253
254 return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
255 (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
256 (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
257}
258
259static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
260{
261 struct iwl_phy_cfg_cmd phy_cfg_cmd;
262 enum iwl_ucode_type ucode_type = mvm->cur_ucode;
263
264 /* Set parameters */
265 phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm));
266 phy_cfg_cmd.calib_control.event_trigger =
267 mvm->fw->default_calib[ucode_type].event_trigger;
268 phy_cfg_cmd.calib_control.flow_trigger =
269 mvm->fw->default_calib[ucode_type].flow_trigger;
270
271 IWL_DEBUG_INFO(mvm, "Sending Phy CFG command: 0x%x\n",
272 phy_cfg_cmd.phy_cfg);
273
274 return iwl_mvm_send_cmd_pdu(mvm, PHY_CONFIGURATION_CMD, CMD_SYNC,
275 sizeof(phy_cfg_cmd), &phy_cfg_cmd);
276}
277
278/* Starting with the new PHY DB implementation - New calibs are enabled */
279/* Value - 0x405e7 */
280#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\
281 IWL_CALIB_CFG_TEMPERATURE_IDX |\
282 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
283 IWL_CALIB_CFG_DC_IDX |\
284 IWL_CALIB_CFG_BB_FILTER_IDX |\
285 IWL_CALIB_CFG_LO_LEAKAGE_IDX |\
286 IWL_CALIB_CFG_TX_IQ_IDX |\
287 IWL_CALIB_CFG_RX_IQ_IDX |\
288 IWL_CALIB_CFG_AGC_IDX)
289
290#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0
291
292/* Value 0x41567 */
293#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\
294 IWL_CALIB_CFG_TEMPERATURE_IDX |\
295 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
296 IWL_CALIB_CFG_BB_FILTER_IDX |\
297 IWL_CALIB_CFG_DC_IDX |\
298 IWL_CALIB_CFG_TX_IQ_IDX |\
299 IWL_CALIB_CFG_RX_IQ_IDX |\
300 IWL_CALIB_CFG_SENSITIVITY_IDX |\
301 IWL_CALIB_CFG_AGC_IDX)
302
303#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\
304 IWL_CALIB_CFG_TEMPERATURE_IDX |\
305 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
306 IWL_CALIB_CFG_TX_PWR_IDX |\
307 IWL_CALIB_CFG_DC_IDX |\
308 IWL_CALIB_CFG_TX_IQ_IDX |\
309 IWL_CALIB_CFG_SENSITIVITY_IDX)
310
311/*
312 * Sets the calibrations trigger values that will be sent to the FW for runtime
313 * and init calibrations.
314 * The ones given in the FW TLV are not correct.
315 */
316static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
317{
318 struct iwl_tlv_calib_ctrl default_calib;
319
320 /*
321 * WkP FW TLV calib bits are wrong, overwrite them.
322 * This defines the dynamic calibrations which are implemented in the
323 * uCode both for init(flow) calculation and event driven calibs.
324 */
325
326 /* Init Image */
327 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
328 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
329
330 if (default_calib.event_trigger !=
331 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
332 IWL_ERR(mvm,
333 "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
334 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
335 default_calib.event_trigger);
336 if (default_calib.flow_trigger !=
337 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
338 IWL_ERR(mvm,
339 "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
340 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
341 default_calib.flow_trigger);
342
343 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
344 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
345 IWL_ERR(mvm,
346 "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
347 default_calib.event_trigger,
348 default_calib.flow_trigger);
349
350 /* Run time image */
351 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
352 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
353
354 if (default_calib.event_trigger !=
355 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
356 IWL_ERR(mvm,
357 "Updating the event calib for RT image: 0x%x -> 0x%x\n",
358 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
359 default_calib.event_trigger);
360 if (default_calib.flow_trigger !=
361 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
362 IWL_ERR(mvm,
363 "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
364 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
365 default_calib.flow_trigger);
366
367 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
368 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
369 IWL_ERR(mvm,
370 "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
371 default_calib.event_trigger,
372 default_calib.flow_trigger);
373}
374
375static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
376{
377 u8 cmd_raw[16]; /* holds the variable size commands */
378 struct iwl_set_calib_default_cmd *cmd =
379 (struct iwl_set_calib_default_cmd *)cmd_raw;
380 int ret, i;
381
382 /* Setting default values for calibrations we don't run */
383 for (i = 0; i < ARRAY_SIZE(wkp_calib_default_data); i++) {
384 u16 cmd_len;
385
386 if (wkp_calib_default_data[i].size == 0)
387 continue;
388
389 memset(cmd_raw, 0, sizeof(cmd_raw));
390 cmd_len = wkp_calib_default_data[i].size + sizeof(cmd);
391 cmd->calib_index = cpu_to_le16(i);
392 cmd->length = cpu_to_le16(wkp_calib_default_data[i].size);
393 if (WARN_ONCE(cmd_len > sizeof(cmd_raw),
394 "Need to enlarge cmd_raw to %d\n", cmd_len))
395 break;
396 memcpy(cmd->data, wkp_calib_default_data[i].data,
397 wkp_calib_default_data[i].size);
398 ret = iwl_mvm_send_cmd_pdu(mvm, SET_CALIB_DEFAULT_CMD, 0,
399 sizeof(*cmd) +
400 wkp_calib_default_data[i].size,
401 cmd);
402 if (ret)
403 return ret;
404 }
405
406 return 0;
407}
408
409int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
410{
411 struct iwl_notification_wait calib_wait;
412 static const u8 init_complete[] = {
413 INIT_COMPLETE_NOTIF,
414 CALIB_RES_NOTIF_PHY_DB
415 };
416 int ret;
417
418 lockdep_assert_held(&mvm->mutex);
419
420 if (mvm->init_ucode_run)
421 return 0;
422
423 iwl_init_notification_wait(&mvm->notif_wait,
424 &calib_wait,
425 init_complete,
426 ARRAY_SIZE(init_complete),
427 iwl_wait_phy_db_entry,
428 mvm->phy_db);
429
430 /* Will also start the device */
431 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT);
432 if (ret) {
433 IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret);
434 goto error;
435 }
436
437 if (read_nvm) {
438 /* Read nvm */
439 ret = iwl_nvm_init(mvm);
440 if (ret) {
441 IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
442 goto error;
443 }
444 }
445
446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
447 WARN_ON(ret);
448
449 /* Override the calibrations from TLV and the const of fw */
450 iwl_set_default_calib_trigger(mvm);
451
452 /* WkP doesn't have all calibrations, need to set default values */
453 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
454 ret = iwl_set_default_calibrations(mvm);
455 if (ret)
456 goto error;
457 }
458
459 /*
460 * Send phy configurations command to init uCode
461 * to start the 16.0 uCode init image internal calibrations.
462 */
463 ret = iwl_send_phy_cfg_cmd(mvm);
464 if (ret) {
465 IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
466 ret);
467 goto error;
468 }
469
470 /*
471 * Some things may run in the background now, but we
472 * just wait for the calibration complete notification.
473 */
474 ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
475 MVM_UCODE_CALIB_TIMEOUT);
476 if (!ret)
477 mvm->init_ucode_run = true;
478 goto out;
479
480error:
481 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
482out:
483 if (!iwlmvm_mod_params.init_dbg) {
484 iwl_trans_stop_device(mvm->trans);
485 } else if (!mvm->nvm_data) {
486 /* we want to debug INIT and we have no NVM - fake */
487 mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
488 sizeof(struct ieee80211_channel) +
489 sizeof(struct ieee80211_rate),
490 GFP_KERNEL);
491 if (!mvm->nvm_data)
492 return -ENOMEM;
493 mvm->nvm_data->valid_rx_ant = 1;
494 mvm->nvm_data->valid_tx_ant = 1;
495 mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels;
496 mvm->nvm_data->bands[0].n_channels = 1;
497 mvm->nvm_data->bands[0].n_bitrates = 1;
498 mvm->nvm_data->bands[0].bitrates =
499 (void *)mvm->nvm_data->channels + 1;
500 mvm->nvm_data->bands[0].bitrates->hw_value = 10;
501 }
502
503 return ret;
504}
505
506#define UCODE_CALIB_TIMEOUT (2*HZ)
507
508int iwl_mvm_up(struct iwl_mvm *mvm)
509{
510 int ret, i;
511
512 lockdep_assert_held(&mvm->mutex);
513
514 ret = iwl_trans_start_hw(mvm->trans);
515 if (ret)
516 return ret;
517
518 /* If we were in RFKILL during module loading, load init ucode now */
519 if (!mvm->init_ucode_run) {
520 ret = iwl_run_init_mvm_ucode(mvm, false);
521 if (ret && !iwlmvm_mod_params.init_dbg) {
522 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
523 goto error;
524 }
525 }
526
527 if (iwlmvm_mod_params.init_dbg)
528 return 0;
529
530 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
531 if (ret) {
532 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
533 goto error;
534 }
535
536 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
537 if (ret)
538 goto error;
539
540 /* Send phy db control command and then phy db calibration*/
541 ret = iwl_send_phy_db_data(mvm->phy_db);
542 if (ret)
543 goto error;
544
545 ret = iwl_send_phy_cfg_cmd(mvm);
546 if (ret)
547 goto error;
548
549 /* init the fw <-> mac80211 STA mapping */
550 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
551 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
552
553 /* Add auxiliary station for scanning */
554 ret = iwl_mvm_add_aux_sta(mvm);
555 if (ret)
556 goto error;
557
558 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
559
560 return 0;
561 error:
562 iwl_trans_stop_device(mvm->trans);
563 return ret;
564}
565
566int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
567{
568 int ret, i;
569
570 lockdep_assert_held(&mvm->mutex);
571
572 ret = iwl_trans_start_hw(mvm->trans);
573 if (ret)
574 return ret;
575
576 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_WOWLAN);
577 if (ret) {
578 IWL_ERR(mvm, "Failed to start WoWLAN firmware: %d\n", ret);
579 goto error;
580 }
581
582 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
583 if (ret)
584 goto error;
585
586 /* Send phy db control command and then phy db calibration*/
587 ret = iwl_send_phy_db_data(mvm->phy_db);
588 if (ret)
589 goto error;
590
591 ret = iwl_send_phy_cfg_cmd(mvm);
592 if (ret)
593 goto error;
594
595 /* init the fw <-> mac80211 STA mapping */
596 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
597 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
598
599 /* Add auxiliary station for scanning */
600 ret = iwl_mvm_add_aux_sta(mvm);
601 if (ret)
602 goto error;
603
604 return 0;
605 error:
606 iwl_trans_stop_device(mvm->trans);
607 return ret;
608}
609
610int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
611 struct iwl_rx_cmd_buffer *rxb,
612 struct iwl_device_cmd *cmd)
613{
614 struct iwl_rx_packet *pkt = rxb_addr(rxb);
615 struct iwl_card_state_notif *card_state_notif = (void *)pkt->data;
616 u32 flags = le32_to_cpu(card_state_notif->flags);
617
618 IWL_DEBUG_RF_KILL(mvm, "Card state received: HW:%s SW:%s CT:%s\n",
619 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
620 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
621 (flags & CT_KILL_CARD_DISABLED) ?
622 "Reached" : "Not reached");
623
624 if (flags & CARD_DISABLED_MSK)
625 iwl_write32(mvm->trans, CSR_UCODE_DRV_GP1_SET,
626 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
627
628 return 0;
629}
630
631int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
632 struct iwl_device_cmd *cmd)
633{
634 struct iwl_rx_packet *pkt = rxb_addr(rxb);
635 struct iwl_radio_version_notif *radio_version = (void *)pkt->data;
636
637 /* TODO: what to do with that? */
638 IWL_DEBUG_INFO(mvm,
639 "Radio version: flavor: 0x%08x, step 0x%08x, dash 0x%08x\n",
640 le32_to_cpu(radio_version->radio_flavor),
641 le32_to_cpu(radio_version->radio_step),
642 le32_to_cpu(radio_version->radio_dash));
643 return 0;
644}
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
new file mode 100644
index 000000000000..011906e73a05
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -0,0 +1,134 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/leds.h>
65#include "iwl-io.h"
66#include "iwl-csr.h"
67#include "mvm.h"
68
69/* Set led register on */
70static void iwl_mvm_led_enable(struct iwl_mvm *mvm)
71{
72 iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON);
73}
74
75/* Set led register off */
76static void iwl_mvm_led_disable(struct iwl_mvm *mvm)
77{
78 iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_OFF);
79}
80
81static void iwl_led_brightness_set(struct led_classdev *led_cdev,
82 enum led_brightness brightness)
83{
84 struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);
85 if (brightness > 0)
86 iwl_mvm_led_enable(mvm);
87 else
88 iwl_mvm_led_disable(mvm);
89}
90
91int iwl_mvm_leds_init(struct iwl_mvm *mvm)
92{
93 int mode = iwlwifi_mod_params.led_mode;
94 int ret;
95
96 switch (mode) {
97 case IWL_LED_DEFAULT:
98 case IWL_LED_RF_STATE:
99 mode = IWL_LED_RF_STATE;
100 break;
101 case IWL_LED_DISABLE:
102 IWL_INFO(mvm, "Led disabled\n");
103 return 0;
104 default:
105 return -EINVAL;
106 };
107
108 mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
109 wiphy_name(mvm->hw->wiphy));
110 mvm->led.brightness_set = iwl_led_brightness_set;
111 mvm->led.max_brightness = 1;
112
113 if (mode == IWL_LED_RF_STATE)
114 mvm->led.default_trigger =
115 ieee80211_get_radio_led_name(mvm->hw);
116
117 ret = led_classdev_register(mvm->trans->dev, &mvm->led);
118 if (ret) {
119 kfree(mvm->led.name);
120 IWL_INFO(mvm, "Failed to enable led\n");
121 return ret;
122 }
123
124 return 0;
125}
126
127void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
128{
129 if (iwlwifi_mod_params.led_mode == IWL_LED_DISABLE)
130 return;
131
132 led_classdev_unregister(&mvm->led);
133 kfree(mvm->led.name);
134}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
new file mode 100644
index 000000000000..c08a17a3cab9
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -0,0 +1,951 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/etherdevice.h>
65#include <net/mac80211.h>
66#include "iwl-io.h"
67#include "iwl-prph.h"
68#include "fw-api.h"
69#include "mvm.h"
70
71const u8 iwl_mvm_ac_to_tx_fifo[] = {
72 IWL_MVM_TX_FIFO_BK,
73 IWL_MVM_TX_FIFO_BE,
74 IWL_MVM_TX_FIFO_VI,
75 IWL_MVM_TX_FIFO_VO,
76};
77
78struct iwl_mvm_mac_iface_iterator_data {
79 struct iwl_mvm *mvm;
80 struct ieee80211_vif *vif;
81 unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
82 unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
83 unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_FIRST_AGG_QUEUE)];
84 enum iwl_tsf_id preferred_tsf;
85 bool found_vif;
86};
87
88static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
89 struct ieee80211_vif *vif)
90{
91 struct iwl_mvm_mac_iface_iterator_data *data = _data;
92 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
93 u32 ac;
94
95 /* Iterator may already find the interface being added -- skip it */
96 if (vif == data->vif) {
97 data->found_vif = true;
98 return;
99 }
100
101 /* Mark the queues used by the vif */
102 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
103 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
104 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
105
106 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
107 __set_bit(vif->cab_queue, data->used_hw_queues);
108
109 /*
110 * Mark MAC IDs as used by clearing the available bit, and
111 * (below) mark TSFs as used if their existing use is not
112 * compatible with the new interface type.
113 * No locking or atomic bit operations are needed since the
114 * data is on the stack of the caller function.
115 */
116 __clear_bit(mvmvif->id, data->available_mac_ids);
117
118 /*
119 * The TSF is a hardware/firmware resource, there are 4 and
120 * the driver should assign and free them as needed. However,
121 * there are cases where 2 MACs should share the same TSF ID
122 * for the purpose of clock sync, an optimization to avoid
123 * clock drift causing overlapping TBTTs/DTIMs for a GO and
124 * client in the system.
125 *
126 * The firmware will decide according to the MAC type which
127 * will be the master and slave. Clients that need to sync
128 * with a remote station will be the master, and an AP or GO
129 * will be the slave.
130 *
131 * Depending on the new interface type it can be slaved to
132 * or become the master of an existing interface.
133 */
134 switch (data->vif->type) {
135 case NL80211_IFTYPE_STATION:
136 /*
137 * The new interface is client, so if the existing one
138 * we're iterating is an AP, the TSF should be used to
139 * avoid drift between the new client and existing AP,
140 * the existing AP will get drift updates from the new
141 * client context in this case
142 */
143 if (vif->type == NL80211_IFTYPE_AP) {
144 if (data->preferred_tsf == NUM_TSF_IDS &&
145 test_bit(mvmvif->tsf_id, data->available_tsf_ids))
146 data->preferred_tsf = mvmvif->tsf_id;
147 return;
148 }
149 break;
150 case NL80211_IFTYPE_AP:
151 /*
152 * The new interface is AP/GO, so should get drift
153 * updates from an existing client or use the same
154 * TSF as an existing GO. There's no drift between
155 * TSFs internally but if they used different TSFs
156 * then a new client MAC could update one of them
157 * and cause drift that way.
158 */
159 if (vif->type == NL80211_IFTYPE_STATION ||
160 vif->type == NL80211_IFTYPE_AP) {
161 if (data->preferred_tsf == NUM_TSF_IDS &&
162 test_bit(mvmvif->tsf_id, data->available_tsf_ids))
163 data->preferred_tsf = mvmvif->tsf_id;
164 return;
165 }
166 break;
167 default:
168 /*
169 * For all other interface types there's no need to
170 * take drift into account. Either they're exclusive
171 * like IBSS and monitor, or we don't care much about
172 * their TSF (like P2P Device), but we won't be able
173 * to share the TSF resource.
174 */
175 break;
176 }
177
178 /*
179 * Unless we exited above, we can't share the TSF resource
180 * that the virtual interface we're iterating over is using
181 * with the new one, so clear the available bit and if this
182 * was the preferred one, reset that as well.
183 */
184 __clear_bit(mvmvif->tsf_id, data->available_tsf_ids);
185
186 if (data->preferred_tsf == mvmvif->tsf_id)
187 data->preferred_tsf = NUM_TSF_IDS;
188}
189
190/*
191 * Get the mask of the queus used by the vif
192 */
193u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
194 struct ieee80211_vif *vif)
195{
196 u32 qmask, ac;
197
198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
199 return BIT(IWL_OFFCHANNEL_QUEUE);
200
201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
202 BIT(vif->cab_queue) : 0;
203
204 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
205 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
206 qmask |= BIT(vif->hw_queue[ac]);
207
208 return qmask;
209}
210
211static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
212 struct ieee80211_vif *vif)
213{
214 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
215 struct iwl_mvm_mac_iface_iterator_data data = {
216 .mvm = mvm,
217 .vif = vif,
218 .available_mac_ids = { (1 << NUM_MAC_INDEX_DRIVER) - 1 },
219 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
220 /* no preference yet */
221 .preferred_tsf = NUM_TSF_IDS,
222 .used_hw_queues = {
223 BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
224 BIT(IWL_MVM_AUX_QUEUE) |
225 BIT(IWL_MVM_CMD_QUEUE)
226 },
227 .found_vif = false,
228 };
229 u32 ac;
230 int ret;
231
232 /*
233 * Allocate a MAC ID and a TSF for this MAC, along with the queues
234 * and other resources.
235 */
236
237 /*
238 * Before the iterator, we start with all MAC IDs and TSFs available.
239 *
240 * During iteration, all MAC IDs are cleared that are in use by other
241 * virtual interfaces, and all TSF IDs are cleared that can't be used
242 * by this new virtual interface because they're used by an interface
243 * that can't share it with the new one.
244 * At the same time, we check if there's a preferred TSF in the case
245 * that we should share it with another interface.
246 */
247
248 ieee80211_iterate_active_interfaces_atomic(
249 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
250 iwl_mvm_mac_iface_iterator, &data);
251
252 /*
253 * In the case we're getting here during resume, it's similar to
254 * firmware restart, and with RESUME_ALL the iterator will find
255 * the vif being added already.
256 * We don't want to reassign any IDs in either case since doing
257 * so would probably assign different IDs (as interfaces aren't
258 * necessarily added in the same order), but the old IDs were
259 * preserved anyway, so skip ID assignment for both resume and
260 * recovery.
261 */
262 if (data.found_vif)
263 return 0;
264
265 /* Therefore, in recovery, we can't get here */
266 WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
267
268 mvmvif->id = find_first_bit(data.available_mac_ids,
269 NUM_MAC_INDEX_DRIVER);
270 if (mvmvif->id == NUM_MAC_INDEX_DRIVER) {
271 IWL_ERR(mvm, "Failed to init MAC context - no free ID!\n");
272 ret = -EIO;
273 goto exit_fail;
274 }
275
276 if (data.preferred_tsf != NUM_TSF_IDS)
277 mvmvif->tsf_id = data.preferred_tsf;
278 else
279 mvmvif->tsf_id = find_first_bit(data.available_tsf_ids,
280 NUM_TSF_IDS);
281 if (mvmvif->tsf_id == NUM_TSF_IDS) {
282 IWL_ERR(mvm, "Failed to init MAC context - no free TSF!\n");
283 ret = -EIO;
284 goto exit_fail;
285 }
286
287 mvmvif->color = 0;
288
289 /* No need to allocate data queues to P2P Device MAC.*/
290 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
291 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
292 vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
293
294 return 0;
295 }
296
297 /* Find available queues, and allocate them to the ACs */
298 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
299 u8 queue = find_first_zero_bit(data.used_hw_queues,
300 IWL_MVM_FIRST_AGG_QUEUE);
301
302 if (queue >= IWL_MVM_FIRST_AGG_QUEUE) {
303 IWL_ERR(mvm, "Failed to allocate queue\n");
304 ret = -EIO;
305 goto exit_fail;
306 }
307
308 __set_bit(queue, data.used_hw_queues);
309 vif->hw_queue[ac] = queue;
310 }
311
312 /* Allocate the CAB queue for softAP and GO interfaces */
313 if (vif->type == NL80211_IFTYPE_AP) {
314 u8 queue = find_first_zero_bit(data.used_hw_queues,
315 IWL_MVM_FIRST_AGG_QUEUE);
316
317 if (queue >= IWL_MVM_FIRST_AGG_QUEUE) {
318 IWL_ERR(mvm, "Failed to allocate cab queue\n");
319 ret = -EIO;
320 goto exit_fail;
321 }
322
323 vif->cab_queue = queue;
324 } else {
325 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
326 }
327
328 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
329 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
330
331 INIT_LIST_HEAD(&mvmvif->time_event_data.list);
332 mvmvif->time_event_data.id = TE_MAX;
333
334 return 0;
335
336exit_fail:
337 memset(mvmvif, 0, sizeof(struct iwl_mvm_vif));
338 memset(vif->hw_queue, IEEE80211_INVAL_HW_QUEUE, sizeof(vif->hw_queue));
339 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
340 return ret;
341}
342
343int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
344{
345 u32 ac;
346 int ret;
347
348 lockdep_assert_held(&mvm->mutex);
349
350 ret = iwl_mvm_mac_ctxt_allocate_resources(mvm, vif);
351 if (ret)
352 return ret;
353
354 switch (vif->type) {
355 case NL80211_IFTYPE_P2P_DEVICE:
356 iwl_trans_ac_txq_enable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
357 IWL_MVM_TX_FIFO_VO);
358 break;
359 case NL80211_IFTYPE_AP:
360 iwl_trans_ac_txq_enable(mvm->trans, vif->cab_queue,
361 IWL_MVM_TX_FIFO_VO);
362 /* fall through */
363 default:
364 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
365 iwl_trans_ac_txq_enable(mvm->trans, vif->hw_queue[ac],
366 iwl_mvm_ac_to_tx_fifo[ac]);
367 break;
368 }
369
370 return 0;
371}
372
373void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
374{
375 int ac;
376
377 lockdep_assert_held(&mvm->mutex);
378
379 switch (vif->type) {
380 case NL80211_IFTYPE_P2P_DEVICE:
381 iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE);
382 break;
383 case NL80211_IFTYPE_AP:
384 iwl_trans_txq_disable(mvm->trans, vif->cab_queue);
385 /* fall through */
386 default:
387 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
388 iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]);
389 }
390}
391
392static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
393 struct ieee80211_vif *vif,
394 enum ieee80211_band band,
395 u8 *cck_rates, u8 *ofdm_rates)
396{
397 struct ieee80211_supported_band *sband;
398 unsigned long basic = vif->bss_conf.basic_rates;
399 int lowest_present_ofdm = 100;
400 int lowest_present_cck = 100;
401 u8 cck = 0;
402 u8 ofdm = 0;
403 int i;
404
405 sband = mvm->hw->wiphy->bands[band];
406
407 for_each_set_bit(i, &basic, BITS_PER_LONG) {
408 int hw = sband->bitrates[i].hw_value;
409 if (hw >= IWL_FIRST_OFDM_RATE) {
410 ofdm |= BIT(hw - IWL_FIRST_OFDM_RATE);
411 if (lowest_present_ofdm > hw)
412 lowest_present_ofdm = hw;
413 } else {
414 BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
415
416 cck |= BIT(hw);
417 if (lowest_present_cck > hw)
418 lowest_present_cck = hw;
419 }
420 }
421
422 /*
423 * Now we've got the basic rates as bitmaps in the ofdm and cck
424 * variables. This isn't sufficient though, as there might not
425 * be all the right rates in the bitmap. E.g. if the only basic
426 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
427 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
428 *
429 * [...] a STA responding to a received frame shall transmit
430 * its Control Response frame [...] at the highest rate in the
431 * BSSBasicRateSet parameter that is less than or equal to the
432 * rate of the immediately previous frame in the frame exchange
433 * sequence ([...]) and that is of the same modulation class
434 * ([...]) as the received frame. If no rate contained in the
435 * BSSBasicRateSet parameter meets these conditions, then the
436 * control frame sent in response to a received frame shall be
437 * transmitted at the highest mandatory rate of the PHY that is
438 * less than or equal to the rate of the received frame, and
439 * that is of the same modulation class as the received frame.
440 *
441 * As a consequence, we need to add all mandatory rates that are
442 * lower than all of the basic rates to these bitmaps.
443 */
444
445 if (IWL_RATE_24M_INDEX < lowest_present_ofdm)
446 ofdm |= IWL_RATE_BIT_MSK(24) >> IWL_FIRST_OFDM_RATE;
447 if (IWL_RATE_12M_INDEX < lowest_present_ofdm)
448 ofdm |= IWL_RATE_BIT_MSK(12) >> IWL_FIRST_OFDM_RATE;
449 /* 6M already there or needed so always add */
450 ofdm |= IWL_RATE_BIT_MSK(6) >> IWL_FIRST_OFDM_RATE;
451
452 /*
453 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
454 * Note, however:
455 * - if no CCK rates are basic, it must be ERP since there must
456 * be some basic rates at all, so they're OFDM => ERP PHY
457 * (or we're in 5 GHz, and the cck bitmap will never be used)
458 * - if 11M is a basic rate, it must be ERP as well, so add 5.5M
459 * - if 5.5M is basic, 1M and 2M are mandatory
460 * - if 2M is basic, 1M is mandatory
461 * - if 1M is basic, that's the only valid ACK rate.
462 * As a consequence, it's not as complicated as it sounds, just add
463 * any lower rates to the ACK rate bitmap.
464 */
465 if (IWL_RATE_11M_INDEX < lowest_present_cck)
466 cck |= IWL_RATE_BIT_MSK(11) >> IWL_FIRST_CCK_RATE;
467 if (IWL_RATE_5M_INDEX < lowest_present_cck)
468 cck |= IWL_RATE_BIT_MSK(5) >> IWL_FIRST_CCK_RATE;
469 if (IWL_RATE_2M_INDEX < lowest_present_cck)
470 cck |= IWL_RATE_BIT_MSK(2) >> IWL_FIRST_CCK_RATE;
471 /* 1M already there or needed so always add */
472 cck |= IWL_RATE_BIT_MSK(1) >> IWL_FIRST_CCK_RATE;
473
474 *cck_rates = cck;
475 *ofdm_rates = ofdm;
476}
477
478static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
479 struct ieee80211_vif *vif,
480 struct iwl_mac_ctx_cmd *cmd,
481 u32 action)
482{
483 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
484 struct ieee80211_chanctx_conf *chanctx;
485 u8 cck_ack_rates, ofdm_ack_rates;
486 int i;
487
488 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
489 mvmvif->color));
490 cmd->action = cpu_to_le32(action);
491
492 switch (vif->type) {
493 case NL80211_IFTYPE_STATION:
494 if (vif->p2p)
495 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_P2P_STA);
496 else
497 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_BSS_STA);
498 break;
499 case NL80211_IFTYPE_AP:
500 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_GO);
501 break;
502 case NL80211_IFTYPE_MONITOR:
503 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_LISTENER);
504 break;
505 case NL80211_IFTYPE_P2P_DEVICE:
506 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_P2P_DEVICE);
507 break;
508 case NL80211_IFTYPE_ADHOC:
509 cmd->mac_type = cpu_to_le32(FW_MAC_TYPE_IBSS);
510 break;
511 default:
512 WARN_ON_ONCE(1);
513 }
514
515 cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id);
516
517 memcpy(cmd->node_addr, vif->addr, ETH_ALEN);
518 if (vif->bss_conf.bssid)
519 memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN);
520 else
521 eth_broadcast_addr(cmd->bssid_addr);
522
523 rcu_read_lock();
524 chanctx = rcu_dereference(vif->chanctx_conf);
525 iwl_mvm_ack_rates(mvm, vif, chanctx ? chanctx->def.chan->band
526 : IEEE80211_BAND_2GHZ,
527 &cck_ack_rates, &ofdm_ack_rates);
528 rcu_read_unlock();
529
530 cmd->cck_rates = cpu_to_le32((u32)cck_ack_rates);
531 cmd->ofdm_rates = cpu_to_le32((u32)ofdm_ack_rates);
532
533 cmd->cck_short_preamble =
534 cpu_to_le32(vif->bss_conf.use_short_preamble ?
535 MAC_FLG_SHORT_PREAMBLE : 0);
536 cmd->short_slot =
537 cpu_to_le32(vif->bss_conf.use_short_slot ?
538 MAC_FLG_SHORT_SLOT : 0);
539
540 for (i = 0; i < AC_NUM; i++) {
541 cmd->ac[i].cw_min = cpu_to_le16(mvmvif->queue_params[i].cw_min);
542 cmd->ac[i].cw_max = cpu_to_le16(mvmvif->queue_params[i].cw_max);
543 cmd->ac[i].aifsn = mvmvif->queue_params[i].aifs;
544 cmd->ac[i].edca_txop =
545 cpu_to_le16(mvmvif->queue_params[i].txop * 32);
546 cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]);
547 }
548
549 if (vif->bss_conf.qos)
550 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
551
552 if (vif->bss_conf.use_cts_prot)
553 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT |
554 MAC_PROT_FLG_SELF_CTS_EN);
555
556 /*
557 * I think that we should enable these 2 flags regardless the HT PROT
558 * fields in the HT IE, but I am not sure. Someone knows whom to ask?...
559 */
560 if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
561 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN);
562 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_HT_PROT |
563 MAC_PROT_FLG_FAT_PROT);
564 }
565
566 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
567}
568
569static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
570 struct iwl_mac_ctx_cmd *cmd)
571{
572 int ret = iwl_mvm_send_cmd_pdu(mvm, MAC_CONTEXT_CMD, CMD_SYNC,
573 sizeof(*cmd), cmd);
574 if (ret)
575 IWL_ERR(mvm, "Failed to send MAC context (action:%d): %d\n",
576 le32_to_cpu(cmd->action), ret);
577 return ret;
578}
579
580/*
581 * Fill the specific data for mac context of type station or p2p client
582 */
583static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
584 struct ieee80211_vif *vif,
585 struct iwl_mac_data_sta *ctxt_sta)
586{
587 ctxt_sta->is_assoc = cpu_to_le32(vif->bss_conf.assoc ? 1 : 0);
588
589 ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
590 ctxt_sta->bi_reciprocal =
591 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
592 ctxt_sta->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
593 vif->bss_conf.dtim_period);
594 ctxt_sta->dtim_reciprocal =
595 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
596 vif->bss_conf.dtim_period));
597
598 ctxt_sta->listen_interval = cpu_to_le32(mvm->hw->conf.listen_interval);
599 ctxt_sta->assoc_id = cpu_to_le32(vif->bss_conf.aid);
600}
601
602static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
603 struct ieee80211_vif *vif,
604 u32 action)
605{
606 struct iwl_mac_ctx_cmd cmd = {};
607
608 WARN_ON(vif->type != NL80211_IFTYPE_STATION || vif->p2p);
609
610 /* Fill the common data for all mac context types */
611 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
612
613 /* Fill the data specific for station mode */
614 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
615
616 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
617}
618
619static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
620 struct ieee80211_vif *vif,
621 u32 action)
622{
623 struct iwl_mac_ctx_cmd cmd = {};
624
625 WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p);
626
627 /* Fill the common data for all mac context types */
628 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
629
630 /* Fill the data specific for station mode */
631 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta);
632
633 cmd.p2p_sta.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
634
635 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
636}
637
638static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
639 struct ieee80211_vif *vif,
640 u32 action)
641{
642 struct iwl_mac_ctx_cmd cmd = {};
643
644 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
645
646 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
647 /* No other data to be filled */
648 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
649}
650
651struct iwl_mvm_go_iterator_data {
652 bool go_active;
653};
654
655static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
656{
657 struct iwl_mvm_go_iterator_data *data = _data;
658 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
659
660 if (vif->type == NL80211_IFTYPE_AP && vif->p2p && mvmvif->ap_active)
661 data->go_active = true;
662}
663
664static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
665 struct ieee80211_vif *vif,
666 u32 action)
667{
668 struct iwl_mac_ctx_cmd cmd = {};
669 struct iwl_mvm_go_iterator_data data = {};
670
671 WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);
672
673 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
674
675 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
676 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC);
677
678 /*
679 * This flag should be set to true when the P2P Device is
680 * discoverable and there is at least another active P2P GO. Settings
681 * this flag will allow the P2P Device to be discoverable on other
682 * channels in addition to its listen channel.
683 * Note that this flag should not be set in other cases as it opens the
684 * Rx filters on all MAC and increases the number of interrupts.
685 */
686 ieee80211_iterate_active_interfaces_atomic(
687 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
688 iwl_mvm_go_iterator, &data);
689
690 cmd.p2p_dev.is_disc_extended = cpu_to_le32(data.go_active ? 1 : 0);
691 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
692}
693
694static void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
695 struct iwl_mac_beacon_cmd *beacon_cmd,
696 u8 *beacon, u32 frame_size)
697{
698 u32 tim_idx;
699 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
700
701 /* The index is relative to frame start but we start looking at the
702 * variable-length part of the beacon. */
703 tim_idx = mgmt->u.beacon.variable - beacon;
704
705 /* Parse variable-length elements of beacon to find WLAN_EID_TIM */
706 while ((tim_idx < (frame_size - 2)) &&
707 (beacon[tim_idx] != WLAN_EID_TIM))
708 tim_idx += beacon[tim_idx+1] + 2;
709
710 /* If TIM field was found, set variables */
711 if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
712 beacon_cmd->tim_idx = cpu_to_le32(tim_idx);
713 beacon_cmd->tim_size = cpu_to_le32((u32)beacon[tim_idx+1]);
714 } else {
715 IWL_WARN(mvm, "Unable to find TIM Element in beacon\n");
716 }
717}
718
719static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
720 struct ieee80211_vif *vif,
721 struct sk_buff *beacon)
722{
723 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
724 struct iwl_host_cmd cmd = {
725 .id = BEACON_TEMPLATE_CMD,
726 .flags = CMD_ASYNC,
727 };
728 struct iwl_mac_beacon_cmd beacon_cmd = {};
729 struct ieee80211_tx_info *info;
730 u32 beacon_skb_len;
731 u32 rate;
732
733 if (WARN_ON(!beacon))
734 return -EINVAL;
735
736 beacon_skb_len = beacon->len;
737
738 /* TODO: for now the beacon template id is set to be the mac context id.
739 * Might be better to handle it as another resource ... */
740 beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
741
742 /* Set up TX command fields */
743 beacon_cmd.tx.len = cpu_to_le16((u16)beacon_skb_len);
744 beacon_cmd.tx.sta_id = mvmvif->bcast_sta.sta_id;
745 beacon_cmd.tx.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
746 beacon_cmd.tx.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
747 TX_CMD_FLG_BT_DIS |
748 TX_CMD_FLG_TSF);
749
750 mvm->mgmt_last_antenna_idx =
751 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
752 mvm->mgmt_last_antenna_idx);
753
754 beacon_cmd.tx.rate_n_flags =
755 cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
756 RATE_MCS_ANT_POS);
757
758 info = IEEE80211_SKB_CB(beacon);
759
760 if (info->band == IEEE80211_BAND_5GHZ || vif->p2p) {
761 rate = IWL_FIRST_OFDM_RATE;
762 } else {
763 rate = IWL_FIRST_CCK_RATE;
764 beacon_cmd.tx.rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
765 }
766 beacon_cmd.tx.rate_n_flags |=
767 cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
768
769 /* Set up TX beacon command fields */
770 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd,
771 beacon->data,
772 beacon_skb_len);
773
774 /* Submit command */
775 cmd.len[0] = sizeof(beacon_cmd);
776 cmd.data[0] = &beacon_cmd;
777 cmd.dataflags[0] = 0;
778 cmd.len[1] = beacon_skb_len;
779 cmd.data[1] = beacon->data;
780 cmd.dataflags[1] = IWL_HCMD_DFL_DUP;
781
782 return iwl_mvm_send_cmd(mvm, &cmd);
783}
784
785/* The beacon template for the AP/GO context has changed and needs update */
786int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
787 struct ieee80211_vif *vif)
788{
789 struct sk_buff *beacon;
790 int ret;
791
792 WARN_ON(vif->type != NL80211_IFTYPE_AP);
793
794 beacon = ieee80211_beacon_get(mvm->hw, vif);
795 if (!beacon)
796 return -ENOMEM;
797
798 ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon);
799 dev_kfree_skb(beacon);
800 return ret;
801}
802
803/*
804 * Fill the specific data for mac context of type AP of P2P GO
805 */
806static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
807 struct ieee80211_vif *vif,
808 struct iwl_mac_data_ap *ctxt_ap)
809{
810 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
811 u32 curr_dev_time;
812
813 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
814 ctxt_ap->bi_reciprocal =
815 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
816 ctxt_ap->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
817 vif->bss_conf.dtim_period);
818 ctxt_ap->dtim_reciprocal =
819 cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
820 vif->bss_conf.dtim_period));
821
822 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
823 curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
824 ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);
825
826 ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time);
827
828 /* TODO: Assume that the beacon id == mac context id */
829 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);
830}
831
832static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
833 struct ieee80211_vif *vif,
834 u32 action)
835{
836 struct iwl_mac_ctx_cmd cmd = {};
837
838 WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p);
839
840 /* Fill the common data for all mac context types */
841 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
842
843 /* Fill the data specific for ap mode */
844 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap);
845
846 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
847}
848
849static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
850 struct ieee80211_vif *vif,
851 u32 action)
852{
853 struct iwl_mac_ctx_cmd cmd = {};
854
855 WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);
856
857 /* Fill the common data for all mac context types */
858 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
859
860 /* Fill the data specific for GO mode */
861 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap);
862
863 cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
864 cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
865
866 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
867}
868
869static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
870 u32 action)
871{
872 switch (vif->type) {
873 case NL80211_IFTYPE_STATION:
874 if (!vif->p2p)
875 return iwl_mvm_mac_ctxt_cmd_station(mvm, vif,
876 action);
877 else
878 return iwl_mvm_mac_ctxt_cmd_p2p_client(mvm, vif,
879 action);
880 break;
881 case NL80211_IFTYPE_AP:
882 if (!vif->p2p)
883 return iwl_mvm_mac_ctxt_cmd_ap(mvm, vif, action);
884 else
885 return iwl_mvm_mac_ctxt_cmd_go(mvm, vif, action);
886 break;
887 case NL80211_IFTYPE_MONITOR:
888 return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action);
889 case NL80211_IFTYPE_P2P_DEVICE:
890 return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action);
891 default:
892 break;
893 }
894
895 return -EOPNOTSUPP;
896}
897
898int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
899{
900 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
901 int ret;
902
903 if (WARN_ONCE(mvmvif->uploaded, "Adding active MAC %pM/%d\n",
904 vif->addr, ieee80211_vif_type_p2p(vif)))
905 return -EIO;
906
907 ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD);
908 if (ret)
909 return ret;
910
911 mvmvif->uploaded = true;
912 return 0;
913}
914
915int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
916{
917 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
918
919 if (WARN_ONCE(!mvmvif->uploaded, "Changing inactive MAC %pM/%d\n",
920 vif->addr, ieee80211_vif_type_p2p(vif)))
921 return -EIO;
922
923 return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY);
924}
925
926int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
927{
928 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
929 struct iwl_mac_ctx_cmd cmd;
930 int ret;
931
932 if (WARN_ONCE(!mvmvif->uploaded, "Removing inactive MAC %pM/%d\n",
933 vif->addr, ieee80211_vif_type_p2p(vif)))
934 return -EIO;
935
936 memset(&cmd, 0, sizeof(cmd));
937
938 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
939 mvmvif->color));
940 cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE);
941
942 ret = iwl_mvm_send_cmd_pdu(mvm, MAC_CONTEXT_CMD, CMD_SYNC,
943 sizeof(cmd), &cmd);
944 if (ret) {
945 IWL_ERR(mvm, "Failed to remove MAC context: %d\n", ret);
946 return ret;
947 }
948
949 mvmvif->uploaded = false;
950 return 0;
951}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
new file mode 100644
index 000000000000..a6b05a02cfd4
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -0,0 +1,1310 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <linux/kernel.h>
64#include <linux/slab.h>
65#include <linux/skbuff.h>
66#include <linux/netdevice.h>
67#include <linux/etherdevice.h>
68#include <net/mac80211.h>
69
70#include "iwl-op-mode.h"
71#include "iwl-io.h"
72#include "mvm.h"
73#include "sta.h"
74#include "time-event.h"
75#include "iwl-eeprom-parse.h"
76#include "fw-api-scan.h"
77#include "iwl-phy-db.h"
78
79static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
80 {
81 .max = 1,
82 .types = BIT(NL80211_IFTYPE_STATION) |
83 BIT(NL80211_IFTYPE_AP),
84 },
85 {
86 .max = 1,
87 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
88 BIT(NL80211_IFTYPE_P2P_GO),
89 },
90 {
91 .max = 1,
92 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
93 },
94};
95
96static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
97 {
98 .num_different_channels = 1,
99 .max_interfaces = 3,
100 .limits = iwl_mvm_limits,
101 .n_limits = ARRAY_SIZE(iwl_mvm_limits),
102 },
103};
104
105int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
106{
107 struct ieee80211_hw *hw = mvm->hw;
108 int num_mac, ret;
109
110 /* Tell mac80211 our characteristics */
111 hw->flags = IEEE80211_HW_SIGNAL_DBM |
112 IEEE80211_HW_SPECTRUM_MGMT |
113 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
114 IEEE80211_HW_QUEUE_CONTROL |
115 IEEE80211_HW_WANT_MONITOR_VIF |
116 IEEE80211_HW_SCAN_WHILE_IDLE |
117 IEEE80211_HW_NEED_DTIM_PERIOD |
118 IEEE80211_HW_SUPPORTS_PS |
119 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
120 IEEE80211_HW_AMPDU_AGGREGATION;
121
122 hw->queues = IWL_FIRST_AMPDU_QUEUE;
123 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
124 hw->rate_control_algorithm = "iwl-mvm-rs";
125
126 /*
127 * Enable 11w if advertised by firmware and software crypto
128 * is not enabled (as the firmware will interpret some mgmt
129 * packets, so enabling it with software crypto isn't safe)
130 */
131 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
132 !iwlwifi_mod_params.sw_crypto)
133 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
134
135 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
136 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
137 hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);
138
139 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
140 BIT(NL80211_IFTYPE_P2P_CLIENT) |
141 BIT(NL80211_IFTYPE_AP) |
142 BIT(NL80211_IFTYPE_P2P_GO) |
143 BIT(NL80211_IFTYPE_P2P_DEVICE);
144
145 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
146 WIPHY_FLAG_DISABLE_BEACON_HINTS |
147 WIPHY_FLAG_IBSS_RSN;
148
149 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
150 hw->wiphy->n_iface_combinations =
151 ARRAY_SIZE(iwl_mvm_iface_combinations);
152
153 hw->wiphy->max_remain_on_channel_duration = 500;
154 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
155
156 /* Extract MAC address */
157 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
158 hw->wiphy->addresses = mvm->addresses;
159 hw->wiphy->n_addresses = 1;
160 num_mac = mvm->nvm_data->n_hw_addrs;
161 if (num_mac > 1) {
162 memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr,
163 ETH_ALEN);
164 mvm->addresses[1].addr[5]++;
165 hw->wiphy->n_addresses++;
166 }
167
168 /* we create the 802.11 header and a max-length SSID element */
169 hw->wiphy->max_scan_ie_len =
170 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
171 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
172
173 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
174 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
175 &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
176 if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
177 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
178 &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
179
180 hw->wiphy->hw_version = mvm->trans->hw_id;
181
182 if (iwlwifi_mod_params.power_save)
183 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
184 else
185 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
186
187 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
188 NL80211_FEATURE_P2P_GO_OPPPS;
189
190 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
191
192#ifdef CONFIG_PM_SLEEP
193 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
194 mvm->trans->ops->d3_suspend &&
195 mvm->trans->ops->d3_resume &&
196 device_can_wakeup(mvm->trans->dev)) {
197 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
198 WIPHY_WOWLAN_DISCONNECT |
199 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
200 WIPHY_WOWLAN_RFKILL_RELEASE;
201 if (!iwlwifi_mod_params.sw_crypto)
202 hw->wiphy->wowlan.flags |=
203 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
204 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
205 WIPHY_WOWLAN_4WAY_HANDSHAKE;
206
207 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
208 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
209 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
210 }
211#endif
212
213 ret = iwl_mvm_leds_init(mvm);
214 if (ret)
215 return ret;
216
217 return ieee80211_register_hw(mvm->hw);
218}
219
220static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
221 struct ieee80211_tx_control *control,
222 struct sk_buff *skb)
223{
224 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
225
226 if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) {
227 IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n");
228 goto drop;
229 }
230
231 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE &&
232 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
233 goto drop;
234
235 if (control->sta) {
236 if (iwl_mvm_tx_skb(mvm, skb, control->sta))
237 goto drop;
238 return;
239 }
240
241 if (iwl_mvm_tx_skb_non_sta(mvm, skb))
242 goto drop;
243 return;
244 drop:
245 ieee80211_free_txskb(hw, skb);
246}
247
248static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
249 struct ieee80211_vif *vif,
250 enum ieee80211_ampdu_mlme_action action,
251 struct ieee80211_sta *sta, u16 tid,
252 u16 *ssn, u8 buf_size)
253{
254 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
255 int ret;
256
257 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
258 sta->addr, tid, action);
259
260 if (!(mvm->nvm_data->sku_cap_11n_enable))
261 return -EACCES;
262
263 mutex_lock(&mvm->mutex);
264
265 switch (action) {
266 case IEEE80211_AMPDU_RX_START:
267 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) {
268 ret = -EINVAL;
269 break;
270 }
271 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
272 break;
273 case IEEE80211_AMPDU_RX_STOP:
274 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
275 break;
276 case IEEE80211_AMPDU_TX_START:
277 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
278 break;
279 case IEEE80211_AMPDU_TX_STOP_CONT:
280 case IEEE80211_AMPDU_TX_STOP_FLUSH:
281 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
282 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
283 break;
284 case IEEE80211_AMPDU_TX_OPERATIONAL:
285 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
286 break;
287 default:
288 WARN_ON_ONCE(1);
289 ret = -EINVAL;
290 break;
291 }
292 mutex_unlock(&mvm->mutex);
293
294 return ret;
295}
296
297static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
298 struct ieee80211_vif *vif)
299{
300 struct iwl_mvm *mvm = data;
301 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
302
303 mvmvif->uploaded = false;
304 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
305
306 /* does this make sense at all? */
307 mvmvif->color++;
308
309 spin_lock_bh(&mvm->time_event_lock);
310 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
311 spin_unlock_bh(&mvm->time_event_lock);
312
313 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
314 mvmvif->phy_ctxt = NULL;
315}
316
317static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
318{
319 iwl_trans_stop_device(mvm->trans);
320 iwl_trans_stop_hw(mvm->trans, false);
321
322 mvm->scan_status = IWL_MVM_SCAN_NONE;
323
324 /* just in case one was running */
325 ieee80211_remain_on_channel_expired(mvm->hw);
326
327 ieee80211_iterate_active_interfaces_atomic(
328 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
329 iwl_mvm_cleanup_iterator, mvm);
330
331 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
332 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
333
334 ieee80211_wake_queues(mvm->hw);
335
336 mvm->vif_count = 0;
337}
338
339static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
340{
341 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
342 int ret;
343
344 mutex_lock(&mvm->mutex);
345
346 /* Clean up some internal and mac80211 state on restart */
347 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
348 iwl_mvm_restart_cleanup(mvm);
349
350 ret = iwl_mvm_up(mvm);
351 mutex_unlock(&mvm->mutex);
352
353 return ret;
354}
355
356static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
357{
358 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
359 int ret;
360
361 mutex_lock(&mvm->mutex);
362
363 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
364 ret = iwl_mvm_update_quotas(mvm, NULL);
365 if (ret)
366 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
367 ret);
368
369 mutex_unlock(&mvm->mutex);
370}
371
372static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
373{
374 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
375
376 flush_work(&mvm->async_handlers_wk);
377
378 mutex_lock(&mvm->mutex);
379 /* async_handlers_wk is now blocked */
380
381 /*
382 * The work item could be running or queued if the
383 * ROC time event stops just as we get here.
384 */
385 cancel_work_sync(&mvm->roc_done_wk);
386
387 iwl_trans_stop_device(mvm->trans);
388 iwl_trans_stop_hw(mvm->trans, false);
389
390 iwl_mvm_async_handlers_purge(mvm);
391 /* async_handlers_list is empty and will stay empty: HW is stopped */
392
393 /* the fw is stopped, the aux sta is dead: clean up driver state */
394 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
395
396 mutex_unlock(&mvm->mutex);
397
398 /*
399 * The worker might have been waiting for the mutex, let it run and
400 * discover that its list is now empty.
401 */
402 cancel_work_sync(&mvm->async_handlers_wk);
403}
404
405static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
406 struct ieee80211_vif *vif)
407{
408 struct iwl_mvm *mvm = data;
409 int ret;
410
411 ret = iwl_mvm_power_disable(mvm, vif);
412 if (ret)
413 IWL_ERR(mvm, "failed to disable power management\n");
414}
415
416static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
417 struct ieee80211_vif *vif)
418{
419 struct iwl_mvm *mvm = data;
420
421 iwl_mvm_power_update_mode(mvm, vif);
422}
423
424static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
425 struct ieee80211_vif *vif)
426{
427 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
428 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
429 int ret;
430
431 /*
432 * Not much to do here. The stack will not allow interface
433 * types or combinations that we didn't advertise, so we
434 * don't really have to check the types.
435 */
436
437 mutex_lock(&mvm->mutex);
438
439 /* Allocate resources for the MAC context, and add it the the fw */
440 ret = iwl_mvm_mac_ctxt_init(mvm, vif);
441 if (ret)
442 goto out_unlock;
443
444 /*
445 * The AP binding flow can be done only after the beacon
446 * template is configured (which happens only in the mac80211
447 * start_ap() flow), and adding the broadcast station can happen
448 * only after the binding.
449 * In addition, since modifying the MAC before adding a bcast
450 * station is not allowed by the FW, delay the adding of MAC context to
451 * the point where we can also add the bcast station.
452 * In short: there's not much we can do at this point, other than
453 * allocating resources :)
454 */
455 if (vif->type == NL80211_IFTYPE_AP) {
456 u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
457 ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
458 qmask);
459 if (ret) {
460 IWL_ERR(mvm, "Failed to allocate bcast sta\n");
461 goto out_release;
462 }
463
464 goto out_unlock;
465 }
466
467 /*
468 * TODO: remove this temporary code.
469 * Currently MVM FW supports power management only on single MAC.
470 * Iterate and disable PM on all active interfaces.
471 * Note: the method below does not count the new interface being added
472 * at this moment.
473 */
474 mvm->vif_count++;
475 if (mvm->vif_count > 1) {
476 IWL_DEBUG_MAC80211(mvm,
477 "Disable power on existing interfaces\n");
478 ieee80211_iterate_active_interfaces(
479 mvm->hw,
480 IEEE80211_IFACE_ITER_NORMAL,
481 iwl_mvm_pm_disable_iterator, mvm);
482 }
483
484 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
485 if (ret)
486 goto out_release;
487
488 /*
489 * Update power state on the new interface. Admittedly, based on
490 * mac80211 logics this power update will disable power management
491 */
492 iwl_mvm_power_update_mode(mvm, vif);
493
494 /*
495 * P2P_DEVICE interface does not have a channel context assigned to it,
496 * so a dedicated PHY context is allocated to it and the corresponding
497 * MAC context is bound to it at this stage.
498 */
499 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
500 struct ieee80211_channel *chan;
501 struct cfg80211_chan_def chandef;
502
503 mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
504
505 /*
506 * The channel used here isn't relevant as it's
507 * going to be overwritten as part of the ROC flow.
508 * For now use the first channel we have.
509 */
510 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
511 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
512 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
513 &chandef, 1, 1);
514 if (ret)
515 goto out_remove_mac;
516
517 ret = iwl_mvm_binding_add_vif(mvm, vif);
518 if (ret)
519 goto out_remove_phy;
520
521 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
522 if (ret)
523 goto out_unbind;
524
525 /* Save a pointer to p2p device vif, so it can later be used to
526 * update the p2p device MAC when a GO is started/stopped */
527 mvm->p2p_device_vif = vif;
528 }
529
530 goto out_unlock;
531
532 out_unbind:
533 iwl_mvm_binding_remove_vif(mvm, vif);
534 out_remove_phy:
535 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
536 out_remove_mac:
537 mvmvif->phy_ctxt = NULL;
538 iwl_mvm_mac_ctxt_remove(mvm, vif);
539 out_release:
540 /*
541 * TODO: remove this temporary code.
542 * Currently MVM FW supports power management only on single MAC.
543 * Check if only one additional interface remains after rereasing
544 * current one. Update power mode on the remaining interface.
545 */
546 mvm->vif_count--;
547 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
548 mvm->vif_count);
549 if (mvm->vif_count == 1) {
550 ieee80211_iterate_active_interfaces(
551 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
552 iwl_mvm_power_update_iterator, mvm);
553 }
554 iwl_mvm_mac_ctxt_release(mvm, vif);
555 out_unlock:
556 mutex_unlock(&mvm->mutex);
557
558 return ret;
559}
560
561static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
562 struct ieee80211_vif *vif)
563{
564 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
565 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
566 u32 tfd_msk = 0, ac;
567
568 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
569 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
570 tfd_msk |= BIT(vif->hw_queue[ac]);
571
572 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
573 tfd_msk |= BIT(vif->cab_queue);
574
575 if (tfd_msk) {
576 mutex_lock(&mvm->mutex);
577 iwl_mvm_flush_tx_path(mvm, tfd_msk, true);
578 mutex_unlock(&mvm->mutex);
579 }
580
581 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
582 /*
583 * Flush the ROC worker which will flush the OFFCHANNEL queue.
584 * We assume here that all the packets sent to the OFFCHANNEL
585 * queue are sent in ROC session.
586 */
587 flush_work(&mvm->roc_done_wk);
588 } else {
589 /*
590 * By now, all the AC queues are empty. The AGG queues are
591 * empty too. We already got all the Tx responses for all the
592 * packets in the queues. The drain work can have been
593 * triggered. Flush it. This work item takes the mutex, so kill
594 * it before we take it.
595 */
596 flush_work(&mvm->sta_drained_wk);
597 }
598
599 mutex_lock(&mvm->mutex);
600
601 /*
602 * For AP/GO interface, the tear down of the resources allocated to the
603 * interface should be handled as part of the bss_info_changed flow.
604 */
605 if (vif->type == NL80211_IFTYPE_AP) {
606 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
607 goto out_release;
608 }
609
610 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
611 mvm->p2p_device_vif = NULL;
612 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
613 iwl_mvm_binding_remove_vif(mvm, vif);
614 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
615 mvmvif->phy_ctxt = NULL;
616 }
617
618 /*
619 * TODO: remove this temporary code.
620 * Currently MVM FW supports power management only on single MAC.
621 * Check if only one additional interface remains after removing
622 * current one. Update power mode on the remaining interface.
623 */
624 if (mvm->vif_count)
625 mvm->vif_count--;
626 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
627 mvm->vif_count);
628 if (mvm->vif_count == 1) {
629 ieee80211_iterate_active_interfaces(
630 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
631 iwl_mvm_power_update_iterator, mvm);
632 }
633
634 iwl_mvm_mac_ctxt_remove(mvm, vif);
635
636out_release:
637 iwl_mvm_mac_ctxt_release(mvm, vif);
638 mutex_unlock(&mvm->mutex);
639}
640
641static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
642{
643 return 0;
644}
645
646static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
647 unsigned int changed_flags,
648 unsigned int *total_flags,
649 u64 multicast)
650{
651 *total_flags = 0;
652}
653
654static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
655 struct ieee80211_vif *vif,
656 struct ieee80211_bss_conf *bss_conf,
657 u32 changes)
658{
659 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
660 int ret;
661
662 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
663 if (ret)
664 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
665
666 if (changes & BSS_CHANGED_ASSOC) {
667 if (bss_conf->assoc) {
668 /* add quota for this interface */
669 ret = iwl_mvm_update_quotas(mvm, vif);
670 if (ret) {
671 IWL_ERR(mvm, "failed to update quotas\n");
672 return;
673 }
674 iwl_mvm_remove_time_event(mvm, mvmvif,
675 &mvmvif->time_event_data);
676 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
677 /* remove AP station now that the MAC is unassoc */
678 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
679 if (ret)
680 IWL_ERR(mvm, "failed to remove AP station\n");
681 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
682 /* remove quota for this interface */
683 ret = iwl_mvm_update_quotas(mvm, NULL);
684 if (ret)
685 IWL_ERR(mvm, "failed to update quotas\n");
686 }
687 } else if (changes & BSS_CHANGED_PS) {
688 /*
689 * TODO: remove this temporary code.
690 * Currently MVM FW supports power management only on single
691 * MAC. Avoid power mode update if more than one interface
692 * is active.
693 */
694 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
695 mvm->vif_count);
696 if (mvm->vif_count == 1) {
697 ret = iwl_mvm_power_update_mode(mvm, vif);
698 if (ret)
699 IWL_ERR(mvm, "failed to update power mode\n");
700 }
701 }
702}
703
704static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
705{
706 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
707 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
708 int ret;
709
710 mutex_lock(&mvm->mutex);
711
712 /* Send the beacon template */
713 ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
714 if (ret)
715 goto out_unlock;
716
717 /* Add the mac context */
718 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
719 if (ret)
720 goto out_unlock;
721
722 /* Perform the binding */
723 ret = iwl_mvm_binding_add_vif(mvm, vif);
724 if (ret)
725 goto out_remove;
726
727 mvmvif->ap_active = true;
728
729 /* Send the bcast station. At this stage the TBTT and DTIM time events
730 * are added and applied to the scheduler */
731 ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
732 if (ret)
733 goto out_unbind;
734
735 ret = iwl_mvm_update_quotas(mvm, vif);
736 if (ret)
737 goto out_rm_bcast;
738
739 /* Need to update the P2P Device MAC */
740 if (vif->p2p && mvm->p2p_device_vif)
741 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
742
743 mutex_unlock(&mvm->mutex);
744 return 0;
745
746out_rm_bcast:
747 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
748out_unbind:
749 iwl_mvm_binding_remove_vif(mvm, vif);
750out_remove:
751 iwl_mvm_mac_ctxt_remove(mvm, vif);
752out_unlock:
753 mutex_unlock(&mvm->mutex);
754 return ret;
755}
756
757static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
758{
759 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
760 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
761
762 mutex_lock(&mvm->mutex);
763
764 mvmvif->ap_active = false;
765
766 /* Need to update the P2P Device MAC */
767 if (vif->p2p && mvm->p2p_device_vif)
768 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
769
770 iwl_mvm_update_quotas(mvm, NULL);
771 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
772 iwl_mvm_binding_remove_vif(mvm, vif);
773 iwl_mvm_mac_ctxt_remove(mvm, vif);
774
775 mutex_unlock(&mvm->mutex);
776}
777
778static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm,
779 struct ieee80211_vif *vif,
780 struct ieee80211_bss_conf *bss_conf,
781 u32 changes)
782{
783 /* Need to send a new beacon template to the FW */
784 if (changes & BSS_CHANGED_BEACON) {
785 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
786 IWL_WARN(mvm, "Failed updating beacon data\n");
787 }
788}
789
790static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
791 struct ieee80211_vif *vif,
792 struct ieee80211_bss_conf *bss_conf,
793 u32 changes)
794{
795 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
796
797 mutex_lock(&mvm->mutex);
798
799 switch (vif->type) {
800 case NL80211_IFTYPE_STATION:
801 iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
802 break;
803 case NL80211_IFTYPE_AP:
804 iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes);
805 break;
806 default:
807 /* shouldn't happen */
808 WARN_ON_ONCE(1);
809 }
810
811 mutex_unlock(&mvm->mutex);
812}
813
814static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
815 struct ieee80211_vif *vif,
816 struct cfg80211_scan_request *req)
817{
818 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
819 int ret;
820
821 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
822 return -EINVAL;
823
824 mutex_lock(&mvm->mutex);
825
826 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
827 ret = iwl_mvm_scan_request(mvm, vif, req);
828 else
829 ret = -EBUSY;
830
831 mutex_unlock(&mvm->mutex);
832
833 return ret;
834}
835
836static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
837 struct ieee80211_vif *vif)
838{
839 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
840
841 mutex_lock(&mvm->mutex);
842
843 iwl_mvm_cancel_scan(mvm);
844
845 mutex_unlock(&mvm->mutex);
846}
847
848static void
849iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
850 struct ieee80211_sta *sta, u16 tid,
851 int num_frames,
852 enum ieee80211_frame_release_type reason,
853 bool more_data)
854{
855 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
856 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
857
858 /* TODO: how do we tell the fw to send frames for a specific TID */
859
860 /*
861 * The fw will send EOSP notification when the last frame will be
862 * transmitted.
863 */
864 iwl_mvm_sta_modify_sleep_tx_count(mvm, mvmsta->sta_id, reason,
865 num_frames);
866}
867
868static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
869 struct ieee80211_vif *vif,
870 enum sta_notify_cmd cmd,
871 struct ieee80211_sta *sta)
872{
873 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
874 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
875
876 switch (cmd) {
877 case STA_NOTIFY_SLEEP:
878 if (atomic_read(&mvmsta->pending_frames) > 0)
879 ieee80211_sta_block_awake(hw, sta, true);
880 /*
881 * The fw updates the STA to be asleep. Tx packets on the Tx
882 * queues to this station will not be transmitted. The fw will
883 * send a Tx response with TX_STATUS_FAIL_DEST_PS.
884 */
885 break;
886 case STA_NOTIFY_AWAKE:
887 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION))
888 break;
889 iwl_mvm_sta_modify_ps_wake(mvm, mvmsta->sta_id);
890 break;
891 default:
892 break;
893 }
894}
895
896static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
897 struct ieee80211_vif *vif,
898 struct ieee80211_sta *sta,
899 enum ieee80211_sta_state old_state,
900 enum ieee80211_sta_state new_state)
901{
902 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
903 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
904 int ret;
905
906 IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
907 sta->addr, old_state, new_state);
908
909 /* this would be a mac80211 bug ... but don't crash */
910 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
911 return -EINVAL;
912
913 /* if a STA is being removed, reuse its ID */
914 flush_work(&mvm->sta_drained_wk);
915
916 mutex_lock(&mvm->mutex);
917 if (old_state == IEEE80211_STA_NOTEXIST &&
918 new_state == IEEE80211_STA_NONE) {
919 ret = iwl_mvm_add_sta(mvm, vif, sta);
920 } else if (old_state == IEEE80211_STA_NONE &&
921 new_state == IEEE80211_STA_AUTH) {
922 ret = 0;
923 } else if (old_state == IEEE80211_STA_AUTH &&
924 new_state == IEEE80211_STA_ASSOC) {
925 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
926 ret = 0;
927 } else if (old_state == IEEE80211_STA_ASSOC &&
928 new_state == IEEE80211_STA_AUTHORIZED) {
929 ret = 0;
930 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
931 new_state == IEEE80211_STA_ASSOC) {
932 ret = 0;
933 } else if (old_state == IEEE80211_STA_ASSOC &&
934 new_state == IEEE80211_STA_AUTH) {
935 ret = 0;
936 } else if (old_state == IEEE80211_STA_AUTH &&
937 new_state == IEEE80211_STA_NONE) {
938 ret = 0;
939 } else if (old_state == IEEE80211_STA_NONE &&
940 new_state == IEEE80211_STA_NOTEXIST) {
941 ret = iwl_mvm_rm_sta(mvm, vif, sta);
942 } else {
943 ret = -EIO;
944 }
945 mutex_unlock(&mvm->mutex);
946
947 return ret;
948}
949
950static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
951{
952 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
953
954 mvm->rts_threshold = value;
955
956 return 0;
957}
958
959static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
960 struct ieee80211_vif *vif, u16 ac,
961 const struct ieee80211_tx_queue_params *params)
962{
963 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
964 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
965
966 mvmvif->queue_params[ac] = *params;
967
968 /*
969 * No need to update right away, we'll get BSS_CHANGED_QOS
970 * The exception is P2P_DEVICE interface which needs immediate update.
971 */
972 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
973 int ret;
974
975 mutex_lock(&mvm->mutex);
976 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
977 mutex_unlock(&mvm->mutex);
978 return ret;
979 }
980 return 0;
981}
982
983static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
984 struct ieee80211_vif *vif)
985{
986 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
987 u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
988 200 + vif->bss_conf.beacon_int);
989 u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
990 100 + vif->bss_conf.beacon_int);
991
992 if (WARN_ON_ONCE(vif->bss_conf.assoc))
993 return;
994
995 mutex_lock(&mvm->mutex);
996 /* Try really hard to protect the session and hear a beacon */
997 iwl_mvm_protect_session(mvm, vif, duration, min_duration);
998 mutex_unlock(&mvm->mutex);
999}
1000
1001static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1002 enum set_key_cmd cmd,
1003 struct ieee80211_vif *vif,
1004 struct ieee80211_sta *sta,
1005 struct ieee80211_key_conf *key)
1006{
1007 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1008 int ret;
1009
1010 if (iwlwifi_mod_params.sw_crypto) {
1011 IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
1012 return -EOPNOTSUPP;
1013 }
1014
1015 switch (key->cipher) {
1016 case WLAN_CIPHER_SUITE_TKIP:
1017 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1018 /* fall-through */
1019 case WLAN_CIPHER_SUITE_CCMP:
1020 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1021 break;
1022 case WLAN_CIPHER_SUITE_AES_CMAC:
1023 WARN_ON_ONCE(!(hw->flags & IEEE80211_HW_MFP_CAPABLE));
1024 break;
1025 case WLAN_CIPHER_SUITE_WEP40:
1026 case WLAN_CIPHER_SUITE_WEP104:
1027 /*
1028 * Support for TX only, at least for now, so accept
1029 * the key and do nothing else. Then mac80211 will
1030 * pass it for TX but we don't have to use it for RX.
1031 */
1032 return 0;
1033 default:
1034 return -EOPNOTSUPP;
1035 }
1036
1037 mutex_lock(&mvm->mutex);
1038
1039 switch (cmd) {
1040 case SET_KEY:
1041 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1042 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1043 if (ret) {
1044 IWL_WARN(mvm, "set key failed\n");
1045 /*
1046 * can't add key for RX, but we don't need it
1047 * in the device for TX so still return 0
1048 */
1049 ret = 0;
1050 }
1051
1052 break;
1053 case DISABLE_KEY:
1054 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1055 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1056 break;
1057 default:
1058 ret = -EINVAL;
1059 }
1060
1061 mutex_unlock(&mvm->mutex);
1062 return ret;
1063}
1064
1065static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1066 struct ieee80211_vif *vif,
1067 struct ieee80211_key_conf *keyconf,
1068 struct ieee80211_sta *sta,
1069 u32 iv32, u16 *phase1key)
1070{
1071 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1072
1073 iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1074}
1075
1076
1077static int iwl_mvm_roc(struct ieee80211_hw *hw,
1078 struct ieee80211_vif *vif,
1079 struct ieee80211_channel *channel,
1080 int duration)
1081{
1082 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1083 struct cfg80211_chan_def chandef;
1084 int ret;
1085
1086 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1087 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1088 return -EINVAL;
1089 }
1090
1091 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d)\n", channel->hw_value,
1092 duration);
1093
1094 mutex_lock(&mvm->mutex);
1095
1096 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1097 ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1098 &chandef, 1, 1);
1099
1100 /* Schedule the time events */
1101 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration);
1102
1103 mutex_unlock(&mvm->mutex);
1104 IWL_DEBUG_MAC80211(mvm, "leave\n");
1105
1106 return ret;
1107}
1108
1109static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
1110{
1111 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1112
1113 IWL_DEBUG_MAC80211(mvm, "enter\n");
1114
1115 mutex_lock(&mvm->mutex);
1116 iwl_mvm_stop_p2p_roc(mvm);
1117 mutex_unlock(&mvm->mutex);
1118
1119 IWL_DEBUG_MAC80211(mvm, "leave\n");
1120 return 0;
1121}
1122
1123static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1124 struct ieee80211_chanctx_conf *ctx)
1125{
1126 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1127 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1128 int ret;
1129
1130 mutex_lock(&mvm->mutex);
1131
1132 IWL_DEBUG_MAC80211(mvm, "Add PHY context\n");
1133 ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def,
1134 ctx->rx_chains_static,
1135 ctx->rx_chains_dynamic);
1136 mutex_unlock(&mvm->mutex);
1137 return ret;
1138}
1139
1140static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1141 struct ieee80211_chanctx_conf *ctx)
1142{
1143 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1144 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1145
1146 mutex_lock(&mvm->mutex);
1147 iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt);
1148 mutex_unlock(&mvm->mutex);
1149}
1150
1151static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1152 struct ieee80211_chanctx_conf *ctx,
1153 u32 changed)
1154{
1155 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1156 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1157
1158 mutex_lock(&mvm->mutex);
1159 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1160 ctx->rx_chains_static,
1161 ctx->rx_chains_dynamic);
1162 mutex_unlock(&mvm->mutex);
1163}
1164
1165static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1166 struct ieee80211_vif *vif,
1167 struct ieee80211_chanctx_conf *ctx)
1168{
1169 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1170 struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv;
1171 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1172 int ret;
1173
1174 mutex_lock(&mvm->mutex);
1175
1176 mvmvif->phy_ctxt = phyctx;
1177
1178 switch (vif->type) {
1179 case NL80211_IFTYPE_AP:
1180 /*
1181 * The AP binding flow is handled as part of the start_ap flow
1182 * (in bss_info_changed).
1183 */
1184 ret = 0;
1185 goto out_unlock;
1186 case NL80211_IFTYPE_STATION:
1187 case NL80211_IFTYPE_ADHOC:
1188 case NL80211_IFTYPE_MONITOR:
1189 break;
1190 default:
1191 ret = -EINVAL;
1192 goto out_unlock;
1193 }
1194
1195 ret = iwl_mvm_binding_add_vif(mvm, vif);
1196 if (ret)
1197 goto out_unlock;
1198
1199 /*
1200 * Setting the quota at this stage is only required for monitor
1201 * interfaces. For the other types, the bss_info changed flow
1202 * will handle quota settings.
1203 */
1204 if (vif->type == NL80211_IFTYPE_MONITOR) {
1205 ret = iwl_mvm_update_quotas(mvm, vif);
1206 if (ret)
1207 goto out_remove_binding;
1208 }
1209
1210 goto out_unlock;
1211
1212 out_remove_binding:
1213 iwl_mvm_binding_remove_vif(mvm, vif);
1214 out_unlock:
1215 mutex_unlock(&mvm->mutex);
1216 if (ret)
1217 mvmvif->phy_ctxt = NULL;
1218 return ret;
1219}
1220
1221static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1222 struct ieee80211_vif *vif,
1223 struct ieee80211_chanctx_conf *ctx)
1224{
1225 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1226 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1227
1228 mutex_lock(&mvm->mutex);
1229
1230 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1231
1232 if (vif->type == NL80211_IFTYPE_AP)
1233 goto out_unlock;
1234
1235 iwl_mvm_binding_remove_vif(mvm, vif);
1236 switch (vif->type) {
1237 case NL80211_IFTYPE_MONITOR:
1238 iwl_mvm_update_quotas(mvm, vif);
1239 break;
1240 default:
1241 break;
1242 }
1243
1244out_unlock:
1245 mvmvif->phy_ctxt = NULL;
1246 mutex_unlock(&mvm->mutex);
1247}
1248
1249static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1250 struct ieee80211_sta *sta,
1251 bool set)
1252{
1253 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1254 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1255
1256 if (!mvm_sta || !mvm_sta->vif) {
1257 IWL_ERR(mvm, "Station is not associated to a vif\n");
1258 return -EINVAL;
1259 }
1260
1261 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1262}
1263
1264struct ieee80211_ops iwl_mvm_hw_ops = {
1265 .tx = iwl_mvm_mac_tx,
1266 .ampdu_action = iwl_mvm_mac_ampdu_action,
1267 .start = iwl_mvm_mac_start,
1268 .restart_complete = iwl_mvm_mac_restart_complete,
1269 .stop = iwl_mvm_mac_stop,
1270 .add_interface = iwl_mvm_mac_add_interface,
1271 .remove_interface = iwl_mvm_mac_remove_interface,
1272 .config = iwl_mvm_mac_config,
1273 .configure_filter = iwl_mvm_configure_filter,
1274 .bss_info_changed = iwl_mvm_bss_info_changed,
1275 .hw_scan = iwl_mvm_mac_hw_scan,
1276 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1277 .sta_state = iwl_mvm_mac_sta_state,
1278 .sta_notify = iwl_mvm_mac_sta_notify,
1279 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1280 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1281 .conf_tx = iwl_mvm_mac_conf_tx,
1282 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1283 .set_key = iwl_mvm_mac_set_key,
1284 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1285 .remain_on_channel = iwl_mvm_roc,
1286 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1287
1288 .add_chanctx = iwl_mvm_add_chanctx,
1289 .remove_chanctx = iwl_mvm_remove_chanctx,
1290 .change_chanctx = iwl_mvm_change_chanctx,
1291 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1292 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1293
1294 .start_ap = iwl_mvm_start_ap,
1295 .stop_ap = iwl_mvm_stop_ap,
1296
1297 .set_tim = iwl_mvm_set_tim,
1298
1299#ifdef CONFIG_PM_SLEEP
1300 /* look at d3.c */
1301 .suspend = iwl_mvm_suspend,
1302 .resume = iwl_mvm_resume,
1303 .set_wakeup = iwl_mvm_set_wakeup,
1304 .set_rekey_data = iwl_mvm_set_rekey_data,
1305#if IS_ENABLED(CONFIG_IPV6)
1306 .ipv6_addr_change = iwl_mvm_ipv6_addr_change,
1307#endif
1308 .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
1309#endif
1310};
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
new file mode 100644
index 000000000000..4e339ccfa800
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -0,0 +1,500 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __IWL_MVM_H__
65#define __IWL_MVM_H__
66
67#include <linux/list.h>
68#include <linux/spinlock.h>
69#include <linux/leds.h>
70#include <linux/in6.h>
71
72#include "iwl-op-mode.h"
73#include "iwl-trans.h"
74#include "iwl-notif-wait.h"
75#include "iwl-eeprom-parse.h"
76#include "iwl-test.h"
77#include "iwl-trans.h"
78#include "sta.h"
79#include "fw-api.h"
80
81#define IWL_INVALID_MAC80211_QUEUE 0xff
82#define IWL_MVM_MAX_ADDRESSES 2
83#define IWL_RSSI_OFFSET 44
84
85enum iwl_mvm_tx_fifo {
86 IWL_MVM_TX_FIFO_BK = 0,
87 IWL_MVM_TX_FIFO_BE,
88 IWL_MVM_TX_FIFO_VI,
89 IWL_MVM_TX_FIFO_VO,
90};
91
92/* Placeholder */
93#define IWL_OFFCHANNEL_QUEUE 8
94#define IWL_FIRST_AMPDU_QUEUE 11
95
96extern struct ieee80211_ops iwl_mvm_hw_ops;
97/**
98 * struct iwl_mvm_mod_params - module parameters for iwlmvm
99 * @init_dbg: if true, then the NIC won't be stopped if the INIT fw asserted.
100 * We will register to mac80211 to have testmode working. The NIC must not
101 * be up'ed after the INIT fw asserted. This is useful to be able to use
102 * proprietary tools over testmode to debug the INIT fw.
103 * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power
104 * Save)-2(default), LP(Low Power)-3
105 */
106struct iwl_mvm_mod_params {
107 bool init_dbg;
108 int power_scheme;
109};
110extern struct iwl_mvm_mod_params iwlmvm_mod_params;
111
112struct iwl_mvm_phy_ctxt {
113 u16 id;
114 u16 color;
115
116 /*
117 * TODO: This should probably be removed. Currently here only for rate
118 * scaling algorithm
119 */
120 struct ieee80211_channel *channel;
121};
122
123struct iwl_mvm_time_event_data {
124 struct ieee80211_vif *vif;
125 struct list_head list;
126 unsigned long end_jiffies;
127 u32 duration;
128 bool running;
129 u32 uid;
130
131 /*
132 * The access to the 'id' field must be done when the
133 * mvm->time_event_lock is held, as it value is used to indicate
134 * if the te is in the time event list or not (when id == TE_MAX)
135 */
136 u32 id;
137};
138
139 /* Power management */
140
141/**
142 * enum iwl_power_scheme
143 * @IWL_POWER_LEVEL_CAM - Continuously Active Mode
144 * @IWL_POWER_LEVEL_BPS - Balanced Power Save (default)
145 * @IWL_POWER_LEVEL_LP - Low Power
146 */
147enum iwl_power_scheme {
148 IWL_POWER_SCHEME_CAM = 1,
149 IWL_POWER_SCHEME_BPS,
150 IWL_POWER_SCHEME_LP
151};
152
153#define IWL_CONN_MAX_LISTEN_INTERVAL 70
154
155/**
156 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
157 * @id: between 0 and 3
158 * @color: to solve races upon MAC addition and removal
159 * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
160 * @uploaded: indicates the MAC context has been added to the device
161 * @ap_active: indicates that ap context is configured, and that the interface
162 * should get quota etc.
163 * @queue_params: QoS params for this MAC
164 * @bcast_sta: station used for broadcast packets. Used by the following
165 * vifs: P2P_DEVICE, GO and AP.
166 * @beacon_skb: the skb used to hold the AP/GO beacon template
167 */
168struct iwl_mvm_vif {
169 u16 id;
170 u16 color;
171 u8 ap_sta_id;
172
173 bool uploaded;
174 bool ap_active;
175
176 enum iwl_tsf_id tsf_id;
177
178 /*
179 * QoS data from mac80211, need to store this here
180 * as mac80211 has a separate callback but we need
181 * to have the data for the MAC context
182 */
183 struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
184 struct iwl_mvm_time_event_data time_event_data;
185
186 struct iwl_mvm_int_sta bcast_sta;
187
188 /*
189 * Assigned while mac80211 has the interface in a channel context,
190 * or, for P2P Device, while it exists.
191 */
192 struct iwl_mvm_phy_ctxt *phy_ctxt;
193
194#ifdef CONFIG_PM_SLEEP
195 /* WoWLAN GTK rekey data */
196 struct {
197 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
198 __le64 replay_ctr;
199 bool valid;
200 } rekey_data;
201
202 int tx_key_idx;
203
204#if IS_ENABLED(CONFIG_IPV6)
205 /* IPv6 addresses for WoWLAN */
206 struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS];
207 int num_target_ipv6_addrs;
208#endif
209#endif
210
211#ifdef CONFIG_IWLWIFI_DEBUGFS
212 struct dentry *dbgfs_dir;
213 void *dbgfs_data;
214#endif
215};
216
217static inline struct iwl_mvm_vif *
218iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
219{
220 return (void *)vif->drv_priv;
221}
222
223enum iwl_mvm_status {
224 IWL_MVM_STATUS_HW_RFKILL,
225 IWL_MVM_STATUS_ROC_RUNNING,
226 IWL_MVM_STATUS_IN_HW_RESTART,
227};
228
229enum iwl_scan_status {
230 IWL_MVM_SCAN_NONE,
231 IWL_MVM_SCAN_OS,
232};
233
234/**
235 * struct iwl_nvm_section - describes an NVM section in memory.
236 *
237 * This struct holds an NVM section read from the NIC using NVM_ACCESS_CMD,
238 * and saved for later use by the driver. Not all NVM sections are saved
239 * this way, only the needed ones.
240 */
241struct iwl_nvm_section {
242 u16 length;
243 const u8 *data;
244};
245
246struct iwl_mvm {
247 /* for logger access */
248 struct device *dev;
249
250 struct iwl_trans *trans;
251 const struct iwl_fw *fw;
252 const struct iwl_cfg *cfg;
253 struct iwl_phy_db *phy_db;
254 struct ieee80211_hw *hw;
255
256 /* for protecting access to iwl_mvm */
257 struct mutex mutex;
258 struct list_head async_handlers_list;
259 spinlock_t async_handlers_lock;
260 struct work_struct async_handlers_wk;
261
262 struct work_struct roc_done_wk;
263
264 unsigned long status;
265
266 enum iwl_ucode_type cur_ucode;
267 bool ucode_loaded;
268 bool init_ucode_run;
269 u32 error_event_table;
270 u32 log_event_table;
271
272 u32 ampdu_ref;
273
274 struct iwl_notif_wait_data notif_wait;
275
276 unsigned long transport_queue_stop;
277 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
278 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
279
280 struct iwl_nvm_data *nvm_data;
281 /* eeprom blob for debugfs/testmode */
282 u8 *eeprom_blob;
283 size_t eeprom_blob_size;
284 /* NVM sections for 7000 family */
285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
286
287 /* EEPROM MAC addresses */
288 struct mac_address addresses[IWL_MVM_MAX_ADDRESSES];
289
290 /* data related to data path */
291 struct iwl_rx_phy_info last_phy_info;
292 struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
293 struct work_struct sta_drained_wk;
294 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
295
296 /* configured by mac80211 */
297 u32 rts_threshold;
298
299 /* Scan status, cmd (pre-allocated) and auxiliary station */
300 enum iwl_scan_status scan_status;
301 struct iwl_scan_cmd *scan_cmd;
302
303 /* Internal station */
304 struct iwl_mvm_int_sta aux_sta;
305
306 u8 scan_last_antenna_idx; /* to toggle TX between antennas */
307 u8 mgmt_last_antenna_idx;
308
309#ifdef CONFIG_IWLWIFI_DEBUGFS
310 struct dentry *debugfs_dir;
311 u32 dbgfs_sram_offset, dbgfs_sram_len;
312 bool prevent_power_down_d3;
313#endif
314
315 struct iwl_mvm_phy_ctxt phy_ctxt_roc;
316
317 struct list_head time_event_list;
318 spinlock_t time_event_lock;
319
320 /*
321 * A bitmap indicating the index of the key in use. The firmware
322 * can hold 16 keys at most. Reflect this fact.
323 */
324 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
325 u8 vif_count;
326
327 struct led_classdev led;
328
329 struct ieee80211_vif *p2p_device_vif;
330};
331
332/* Extract MVM priv from op_mode and _hw */
333#define IWL_OP_MODE_GET_MVM(_iwl_op_mode) \
334 ((struct iwl_mvm *)(_iwl_op_mode)->op_mode_specific)
335
336#define IWL_MAC80211_GET_MVM(_hw) \
337 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
338
339extern const u8 iwl_mvm_ac_to_tx_fifo[];
340
341struct iwl_rate_info {
342 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
343 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
344 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
345 u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
346 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
347};
348
349/******************
350 * MVM Methods
351 ******************/
352/* uCode */
353int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm);
354
355/* Utils */
356int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
357 enum ieee80211_band band);
358u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
359void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
360u8 first_antenna(u8 mask);
361u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
362
363/* Tx / Host Commands */
364int __must_check iwl_mvm_send_cmd(struct iwl_mvm *mvm,
365 struct iwl_host_cmd *cmd);
366int __must_check iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id,
367 u32 flags, u16 len, const void *data);
368int __must_check iwl_mvm_send_cmd_status(struct iwl_mvm *mvm,
369 struct iwl_host_cmd *cmd,
370 u32 *status);
371int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u8 id,
372 u16 len, const void *data,
373 u32 *status);
374int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
375 struct ieee80211_sta *sta);
376int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb);
377#ifdef CONFIG_IWLWIFI_DEBUG
378const char *iwl_mvm_get_tx_fail_reason(u32 status);
379#else
380static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
381#endif
382int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync);
383void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm);
384
385/* Statistics */
386int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm,
387 struct iwl_rx_cmd_buffer *rxb,
388 struct iwl_device_cmd *cmd);
389int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
390 struct iwl_rx_cmd_buffer *rxb,
391 struct iwl_device_cmd *cmd);
392
393/* NVM */
394int iwl_nvm_init(struct iwl_mvm *mvm);
395
396int iwl_mvm_up(struct iwl_mvm *mvm);
397int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
398
399int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm);
400
401/*
402 * FW notifications / CMD responses handlers
403 * Convention: iwl_mvm_rx_<NAME OF THE CMD>
404 */
405int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
406 struct iwl_device_cmd *cmd);
407int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
408 struct iwl_device_cmd *cmd);
409int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
410 struct iwl_device_cmd *cmd);
411int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
412 struct iwl_device_cmd *cmd);
413int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
414 struct iwl_device_cmd *cmd);
415int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
416 struct iwl_device_cmd *cmd);
417int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
418 struct iwl_rx_cmd_buffer *rxb,
419 struct iwl_device_cmd *cmd);
420int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
421 struct iwl_device_cmd *cmd);
422
423/* MVM PHY */
424int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
425 struct cfg80211_chan_def *chandef,
426 u8 chains_static, u8 chains_dynamic);
427int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
428 struct cfg80211_chan_def *chandef,
429 u8 chains_static, u8 chains_dynamic);
430void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm,
431 struct iwl_mvm_phy_ctxt *ctxt);
432
433/* MAC (virtual interface) programming */
434int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
435void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
436int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
437int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
438int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
439u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
440 struct ieee80211_vif *vif);
441int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
442 struct ieee80211_vif *vif);
443
444/* Bindings */
445int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
446int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
447
448/* Quota management */
449int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif);
450
451/* Scanning */
452int iwl_mvm_scan_request(struct iwl_mvm *mvm,
453 struct ieee80211_vif *vif,
454 struct cfg80211_scan_request *req);
455int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
456 struct iwl_device_cmd *cmd);
457int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
458 struct iwl_device_cmd *cmd);
459void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
460
461/* MVM debugfs */
462#ifdef CONFIG_IWLWIFI_DEBUGFS
463int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
464int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
465 struct dentry *dbgfs_dir);
466void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
467 struct iwl_powertable_cmd *cmd);
468#else
469static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm,
470 struct dentry *dbgfs_dir)
471{
472 return 0;
473}
474#endif /* CONFIG_IWLWIFI_DEBUGFS */
475
476/* rate scaling */
477int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
478 u8 flags, bool init);
479
480/* power managment */
481int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
482int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
483
484int iwl_mvm_leds_init(struct iwl_mvm *mvm);
485void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
486
487/* D3 (WoWLAN, NetDetect) */
488int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
489int iwl_mvm_resume(struct ieee80211_hw *hw);
490void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled);
491void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
492 struct ieee80211_vif *vif,
493 struct cfg80211_gtk_rekey_data *data);
494void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
495 struct ieee80211_vif *vif,
496 struct inet6_dev *idev);
497void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
498 struct ieee80211_vif *vif, int idx);
499
500#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
new file mode 100644
index 000000000000..20016bcbdeab
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -0,0 +1,311 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include "iwl-trans.h"
64#include "mvm.h"
65#include "iwl-eeprom-parse.h"
66#include "iwl-eeprom-read.h"
67#include "iwl-nvm-parse.h"
68
69/* list of NVM sections we are allowed/need to read */
70static const int nvm_to_read[] = {
71 NVM_SECTION_TYPE_HW,
72 NVM_SECTION_TYPE_SW,
73 NVM_SECTION_TYPE_CALIBRATION,
74 NVM_SECTION_TYPE_PRODUCTION,
75};
76
77/* used to simplify the shared operations on NCM_ACCESS_CMD versions */
78union iwl_nvm_access_cmd {
79 struct iwl_nvm_access_cmd_ver1 ver1;
80 struct iwl_nvm_access_cmd_ver2 ver2;
81};
82union iwl_nvm_access_resp {
83 struct iwl_nvm_access_resp_ver1 ver1;
84 struct iwl_nvm_access_resp_ver2 ver2;
85};
86
87static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
88 u16 offset, u16 length)
89{
90 cmd->offset = cpu_to_le16(offset);
91 cmd->length = cpu_to_le16(length);
92 cmd->cache_refresh = 1;
93}
94
95static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
96 u16 offset, u16 length, u16 section)
97{
98 cmd->offset = cpu_to_le16(offset);
99 cmd->length = cpu_to_le16(length);
100 cmd->type = cpu_to_le16(section);
101}
102
103static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
104 u16 offset, u16 length, u8 *data)
105{
106 union iwl_nvm_access_cmd nvm_access_cmd;
107 union iwl_nvm_access_resp *nvm_resp;
108 struct iwl_rx_packet *pkt;
109 struct iwl_host_cmd cmd = {
110 .id = NVM_ACCESS_CMD,
111 .flags = CMD_SYNC | CMD_WANT_SKB,
112 .data = { &nvm_access_cmd, },
113 };
114 int ret, bytes_read, offset_read;
115 u8 *resp_data;
116
117 memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd));
118
119 /* TODO: not sure family should be the decider, maybe FW version? */
120 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
121 iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
122 offset, length, section);
123 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
124 } else {
125 iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
126 offset, length);
127 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
128 }
129
130 ret = iwl_mvm_send_cmd(mvm, &cmd);
131 if (ret)
132 return ret;
133
134 pkt = cmd.resp_pkt;
135 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
136 IWL_ERR(mvm, "Bad return from NVM_ACCES_COMMAND (0x%08X)\n",
137 pkt->hdr.flags);
138 ret = -EIO;
139 goto exit;
140 }
141
142 /* Extract NVM response */
143 nvm_resp = (void *)pkt->data;
144 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
145 ret = le16_to_cpu(nvm_resp->ver2.status);
146 bytes_read = le16_to_cpu(nvm_resp->ver2.length);
147 offset_read = le16_to_cpu(nvm_resp->ver2.offset);
148 resp_data = nvm_resp->ver2.data;
149 } else {
150 ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
151 bytes_read = le16_to_cpu(nvm_resp->ver1.length);
152 offset_read = le16_to_cpu(nvm_resp->ver1.offset);
153 resp_data = nvm_resp->ver1.data;
154 }
155 if (ret) {
156 IWL_ERR(mvm,
157 "NVM access command failed with status %d (device: %s)\n",
158 ret, mvm->cfg->name);
159 ret = -EINVAL;
160 goto exit;
161 }
162
163 if (offset_read != offset) {
164 IWL_ERR(mvm, "NVM ACCESS response with invalid offset %d\n",
165 offset_read);
166 ret = -EINVAL;
167 goto exit;
168 }
169
170 /* Write data to NVM */
171 memcpy(data + offset, resp_data, bytes_read);
172 ret = bytes_read;
173
174exit:
175 iwl_free_resp(&cmd);
176 return ret;
177}
178
179/*
180 * Reads an NVM section completely.
181 * NICs prior to 7000 family doesn't have a real NVM, but just read
182 * section 0 which is the EEPROM. Because the EEPROM reading is unlimited
183 * by uCode, we need to manually check in this case that we don't
184 * overflow and try to read more than the EEPROM size.
185 * For 7000 family NICs, we supply the maximal size we can read, and
186 * the uCode fills the response with as much data as we can,
187 * without overflowing, so no check is needed.
188 */
189static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
190 u8 *data)
191{
192 u16 length, offset = 0;
193 int ret;
194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
195
196 length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024))
197 - sizeof(union iwl_nvm_access_cmd)
198 - sizeof(struct iwl_rx_packet);
199 /*
200 * if length is greater than EEPROM size, truncate it because uCode
201 * doesn't check it by itself, and exit the loop when reached.
202 */
203 if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
204 length = mvm->cfg->base_params->eeprom_size;
205 ret = length;
206
207 /* Read the NVM until exhausted (reading less than requested) */
208 while (ret == length) {
209 ret = iwl_nvm_read_chunk(mvm, section, offset, length, data);
210 if (ret < 0) {
211 IWL_ERR(mvm,
212 "Cannot read NVM from section %d offset %d, length %d\n",
213 section, offset, length);
214 return ret;
215 }
216 offset += ret;
217 if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
218 break;
219 }
220
221 IWL_INFO(mvm, "NVM section %d read completed\n", section);
222 return offset;
223}
224
225static struct iwl_nvm_data *
226iwl_parse_nvm_sections(struct iwl_mvm *mvm)
227{
228 struct iwl_nvm_section *sections = mvm->nvm_sections;
229 const __le16 *hw, *sw, *calib;
230
231 /* Checking for required sections */
232 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
233 !mvm->nvm_sections[NVM_SECTION_TYPE_HW].data) {
234 IWL_ERR(mvm, "Can't parse empty NVM sections\n");
235 return NULL;
236 }
237
238 if (WARN_ON(!mvm->cfg))
239 return NULL;
240
241 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data;
242 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
243 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
244 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib);
245}
246
247int iwl_nvm_init(struct iwl_mvm *mvm)
248{
249 int ret, i, section;
250 u8 *nvm_buffer, *temp;
251
252 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
253 /* TODO: find correct NVM max size for a section */
254 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
255 GFP_KERNEL);
256 if (!nvm_buffer)
257 return -ENOMEM;
258 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
259 section = nvm_to_read[i];
260 /* we override the constness for initial read */
261 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
262 if (ret < 0)
263 break;
264 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
265 if (!temp) {
266 ret = -ENOMEM;
267 break;
268 }
269 mvm->nvm_sections[section].data = temp;
270 mvm->nvm_sections[section].length = ret;
271 }
272 kfree(nvm_buffer);
273 if (ret < 0)
274 return ret;
275 } else {
276 /* allocate eeprom */
277 mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size;
278 IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n",
279 mvm->eeprom_blob_size);
280 mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
281 if (!mvm->eeprom_blob)
282 return -ENOMEM;
283
284 ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
285 if (ret != mvm->eeprom_blob_size) {
286 IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
287 ret, mvm->eeprom_blob_size);
288 kfree(mvm->eeprom_blob);
289 mvm->eeprom_blob = NULL;
290 return -EINVAL;
291 }
292 }
293
294 ret = 0;
295 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
296 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
297 else
298 mvm->nvm_data =
299 iwl_parse_eeprom_data(mvm->trans->dev,
300 mvm->cfg,
301 mvm->eeprom_blob,
302 mvm->eeprom_blob_size);
303
304 if (!mvm->nvm_data) {
305 kfree(mvm->eeprom_blob);
306 mvm->eeprom_blob = NULL;
307 ret = -ENOMEM;
308 }
309
310 return ret;
311}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
new file mode 100644
index 000000000000..e675e4a6707f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -0,0 +1,679 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <linux/module.h>
64#include <net/mac80211.h>
65
66#include "iwl-notif-wait.h"
67#include "iwl-trans.h"
68#include "iwl-op-mode.h"
69#include "iwl-fw.h"
70#include "iwl-debug.h"
71#include "iwl-drv.h"
72#include "iwl-modparams.h"
73#include "mvm.h"
74#include "iwl-phy-db.h"
75#include "iwl-eeprom-parse.h"
76#include "iwl-csr.h"
77#include "iwl-io.h"
78#include "iwl-prph.h"
79#include "rs.h"
80#include "fw-api-scan.h"
81#include "time-event.h"
82
83/*
84 * module name, copyright, version, etc.
85 */
86#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
87
88#define DRV_VERSION IWLWIFI_VERSION
89
90MODULE_DESCRIPTION(DRV_DESCRIPTION);
91MODULE_VERSION(DRV_VERSION);
92MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
93MODULE_LICENSE("GPL");
94
95static const struct iwl_op_mode_ops iwl_mvm_ops;
96
97struct iwl_mvm_mod_params iwlmvm_mod_params = {
98 .power_scheme = IWL_POWER_SCHEME_BPS,
99 /* rest of fields are 0 by default */
100};
101
102module_param_named(init_dbg, iwlmvm_mod_params.init_dbg, bool, S_IRUGO);
103MODULE_PARM_DESC(init_dbg,
104 "set to true to debug an ASSERT in INIT fw (default: false");
105module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO);
106MODULE_PARM_DESC(power_scheme,
107 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2");
108
109/*
110 * module init and exit functions
111 */
112static int __init iwl_mvm_init(void)
113{
114 int ret;
115
116 ret = iwl_mvm_rate_control_register();
117 if (ret) {
118 pr_err("Unable to register rate control algorithm: %d\n", ret);
119 return ret;
120 }
121
122 ret = iwl_opmode_register("iwlmvm", &iwl_mvm_ops);
123
124 if (ret) {
125 pr_err("Unable to register MVM op_mode: %d\n", ret);
126 iwl_mvm_rate_control_unregister();
127 }
128
129 return ret;
130}
131module_init(iwl_mvm_init);
132
133static void __exit iwl_mvm_exit(void)
134{
135 iwl_opmode_deregister("iwlmvm");
136 iwl_mvm_rate_control_unregister();
137}
138module_exit(iwl_mvm_exit);
139
140static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
141{
142 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
144 u32 reg_val = 0;
145
146 /*
147 * We can't upload the correct value to the INIT image
148 * as we don't have nvm_data by that time.
149 *
150 * TODO: Figure out what we should do here
151 */
152 if (mvm->nvm_data) {
153 radio_cfg_type = mvm->nvm_data->radio_cfg_type;
154 radio_cfg_step = mvm->nvm_data->radio_cfg_step;
155 radio_cfg_dash = mvm->nvm_data->radio_cfg_dash;
156 } else {
157 radio_cfg_type = 0;
158 radio_cfg_step = 0;
159 radio_cfg_dash = 0;
160 }
161
162 /* SKU control */
163 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
164 CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
165 reg_val |= CSR_HW_REV_DASH(mvm->trans->hw_rev) <<
166 CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
167
168 /* radio configuration */
169 reg_val |= radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
170 reg_val |= radio_cfg_step << CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
171 reg_val |= radio_cfg_dash << CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
172
173 WARN_ON((radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE) &
174 ~CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE);
175
176 /* silicon bits */
177 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
178 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
179
180 iwl_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
181 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
182 CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP |
183 CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
184 CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
185 CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH |
186 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
187 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI,
188 reg_val);
189
190 IWL_DEBUG_INFO(mvm, "Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type,
191 radio_cfg_step, radio_cfg_dash);
192
193 /*
194 * W/A : NIC is stuck in a reset state after Early PCIe power off
195 * (PCIe power is lost before PERST# is asserted), causing ME FW
196 * to lose ownership and not being able to obtain it back.
197 */
198 iwl_set_bits_mask_prph(mvm->trans, APMG_PS_CTRL_REG,
199 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
200 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
201}
202
203struct iwl_rx_handlers {
204 u8 cmd_id;
205 bool async;
206 int (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
207 struct iwl_device_cmd *cmd);
208};
209
210#define RX_HANDLER(_cmd_id, _fn, _async) \
211 { .cmd_id = _cmd_id , .fn = _fn , .async = _async }
212
213/*
214 * Handlers for fw notifications
215 * Convention: RX_HANDLER(CMD_NAME, iwl_mvm_rx_CMD_NAME
216 * This list should be in order of frequency for performance purposes.
217 *
218 * The handler can be SYNC - this means that it will be called in the Rx path
219 * which can't acquire mvm->mutex. If the handler needs to hold mvm->mutex (and
220 * only in this case!), it should be set as ASYNC. In that case, it will be
221 * called from a worker with mvm->mutex held.
222 */
223static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
224 RX_HANDLER(REPLY_RX_MPDU_CMD, iwl_mvm_rx_rx_mpdu, false),
225 RX_HANDLER(REPLY_RX_PHY_CMD, iwl_mvm_rx_rx_phy_cmd, false),
226 RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false),
227 RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
228 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
229
230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232
233 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
234 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
235
236 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
237};
238#undef RX_HANDLER
239#define CMD(x) [x] = #x
240
241static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
242 CMD(MVM_ALIVE),
243 CMD(REPLY_ERROR),
244 CMD(INIT_COMPLETE_NOTIF),
245 CMD(PHY_CONTEXT_CMD),
246 CMD(MGMT_MCAST_KEY),
247 CMD(TX_CMD),
248 CMD(TXPATH_FLUSH),
249 CMD(MAC_CONTEXT_CMD),
250 CMD(TIME_EVENT_CMD),
251 CMD(TIME_EVENT_NOTIFICATION),
252 CMD(BINDING_CONTEXT_CMD),
253 CMD(TIME_QUOTA_CMD),
254 CMD(RADIO_VERSION_NOTIFICATION),
255 CMD(SCAN_REQUEST_CMD),
256 CMD(SCAN_ABORT_CMD),
257 CMD(SCAN_START_NOTIFICATION),
258 CMD(SCAN_RESULTS_NOTIFICATION),
259 CMD(SCAN_COMPLETE_NOTIFICATION),
260 CMD(NVM_ACCESS_CMD),
261 CMD(PHY_CONFIGURATION_CMD),
262 CMD(CALIB_RES_NOTIF_PHY_DB),
263 CMD(SET_CALIB_DEFAULT_CMD),
264 CMD(CALIBRATION_COMPLETE_NOTIFICATION),
265 CMD(ADD_STA),
266 CMD(REMOVE_STA),
267 CMD(LQ_CMD),
268 CMD(SCAN_OFFLOAD_CONFIG_CMD),
269 CMD(SCAN_OFFLOAD_REQUEST_CMD),
270 CMD(SCAN_OFFLOAD_ABORT_CMD),
271 CMD(SCAN_OFFLOAD_COMPLETE),
272 CMD(SCAN_OFFLOAD_UPDATE_PROFILES_CMD),
273 CMD(POWER_TABLE_CMD),
274 CMD(WEP_KEY),
275 CMD(REPLY_RX_PHY_CMD),
276 CMD(REPLY_RX_MPDU_CMD),
277 CMD(BEACON_TEMPLATE_CMD),
278 CMD(STATISTICS_NOTIFICATION),
279 CMD(TX_ANT_CONFIGURATION_CMD),
280 CMD(D3_CONFIG_CMD),
281 CMD(PROT_OFFLOAD_CONFIG_CMD),
282 CMD(OFFLOADS_QUERY_CMD),
283 CMD(REMOTE_WAKE_CONFIG_CMD),
284 CMD(WOWLAN_PATTERNS),
285 CMD(WOWLAN_CONFIGURATION),
286 CMD(WOWLAN_TSC_RSC_PARAM),
287 CMD(WOWLAN_TKIP_PARAM),
288 CMD(WOWLAN_KEK_KCK_MATERIAL),
289 CMD(WOWLAN_GET_STATUSES),
290 CMD(WOWLAN_TX_POWER_PER_DB),
291 CMD(NET_DETECT_CONFIG_CMD),
292 CMD(NET_DETECT_PROFILES_QUERY_CMD),
293 CMD(NET_DETECT_PROFILES_CMD),
294 CMD(NET_DETECT_HOTSPOTS_CMD),
295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
296};
297#undef CMD
298
299/* this forward declaration can avoid to export the function */
300static void iwl_mvm_async_handlers_wk(struct work_struct *wk);
301
302static struct iwl_op_mode *
303iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
304 const struct iwl_fw *fw, struct dentry *dbgfs_dir)
305{
306 struct ieee80211_hw *hw;
307 struct iwl_op_mode *op_mode;
308 struct iwl_mvm *mvm;
309 struct iwl_trans_config trans_cfg = {};
310 static const u8 no_reclaim_cmds[] = {
311 TX_CMD,
312 };
313 int err, scan_size;
314
315 switch (cfg->device_family) {
316 case IWL_DEVICE_FAMILY_6030:
317 case IWL_DEVICE_FAMILY_6005:
318 case IWL_DEVICE_FAMILY_7000:
319 break;
320 default:
321 IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
322 return NULL;
323 }
324
325 /********************************
326 * 1. Allocating and configuring HW data
327 ********************************/
328 hw = ieee80211_alloc_hw(sizeof(struct iwl_op_mode) +
329 sizeof(struct iwl_mvm),
330 &iwl_mvm_hw_ops);
331 if (!hw)
332 return NULL;
333
334 op_mode = hw->priv;
335 op_mode->ops = &iwl_mvm_ops;
336 op_mode->trans = trans;
337
338 mvm = IWL_OP_MODE_GET_MVM(op_mode);
339 mvm->dev = trans->dev;
340 mvm->trans = trans;
341 mvm->cfg = cfg;
342 mvm->fw = fw;
343 mvm->hw = hw;
344
345 mutex_init(&mvm->mutex);
346 spin_lock_init(&mvm->async_handlers_lock);
347 INIT_LIST_HEAD(&mvm->time_event_list);
348 INIT_LIST_HEAD(&mvm->async_handlers_list);
349 spin_lock_init(&mvm->time_event_lock);
350
351 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
352 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
353 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
354
355 SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev);
356
357 /*
358 * Populate the state variables that the transport layer needs
359 * to know about.
360 */
361 trans_cfg.op_mode = op_mode;
362 trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
365
366 /* TODO: this should really be a TLV */
367 if (cfg->device_family == IWL_DEVICE_FAMILY_7000)
368 trans_cfg.bc_table_dword = true;
369
370 if (!iwlwifi_mod_params.wd_disable)
371 trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
372 else
373 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
374
375 trans_cfg.command_names = iwl_mvm_cmd_strings;
376
377 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
378 trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO;
379
380 snprintf(mvm->hw->wiphy->fw_version,
381 sizeof(mvm->hw->wiphy->fw_version),
382 "%s", fw->fw_version);
383
384 /* Configure transport layer */
385 iwl_trans_configure(mvm->trans, &trans_cfg);
386
387 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
388 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
389
390 /* set up notification wait support */
391 iwl_notification_wait_init(&mvm->notif_wait);
392
393 /* Init phy db */
394 mvm->phy_db = iwl_phy_db_init(trans);
395 if (!mvm->phy_db) {
396 IWL_ERR(mvm, "Cannot init phy_db\n");
397 goto out_free;
398 }
399
400 IWL_INFO(mvm, "Detected %s, REV=0x%X\n",
401 mvm->cfg->name, mvm->trans->hw_rev);
402
403 err = iwl_trans_start_hw(mvm->trans);
404 if (err)
405 goto out_free;
406
407 mutex_lock(&mvm->mutex);
408 err = iwl_run_init_mvm_ucode(mvm, true);
409 mutex_unlock(&mvm->mutex);
410 if (err && !iwlmvm_mod_params.init_dbg) {
411 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
412 goto out_free;
413 }
414
415 /* Stop the hw after the ALIVE and NVM has been read */
416 if (!iwlmvm_mod_params.init_dbg)
417 iwl_trans_stop_hw(mvm->trans, false);
418
419 scan_size = sizeof(struct iwl_scan_cmd) +
420 mvm->fw->ucode_capa.max_probe_length +
421 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel));
422 mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL);
423 if (!mvm->scan_cmd)
424 goto out_free;
425
426 err = iwl_mvm_mac_setup_register(mvm);
427 if (err)
428 goto out_free;
429
430 err = iwl_mvm_dbgfs_register(mvm, dbgfs_dir);
431 if (err)
432 goto out_unregister;
433
434 return op_mode;
435
436 out_unregister:
437 ieee80211_unregister_hw(mvm->hw);
438 out_free:
439 iwl_phy_db_free(mvm->phy_db);
440 kfree(mvm->scan_cmd);
441 kfree(mvm->eeprom_blob);
442 iwl_trans_stop_hw(trans, true);
443 ieee80211_free_hw(mvm->hw);
444 return NULL;
445}
446
447static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
448{
449 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
450 int i;
451
452 iwl_mvm_leds_exit(mvm);
453
454 ieee80211_unregister_hw(mvm->hw);
455
456 kfree(mvm->scan_cmd);
457
458 iwl_trans_stop_hw(mvm->trans, true);
459
460 iwl_phy_db_free(mvm->phy_db);
461 mvm->phy_db = NULL;
462
463 kfree(mvm->eeprom_blob);
464 iwl_free_nvm_data(mvm->nvm_data);
465 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
466 kfree(mvm->nvm_sections[i].data);
467
468 ieee80211_free_hw(mvm->hw);
469}
470
471struct iwl_async_handler_entry {
472 struct list_head list;
473 struct iwl_rx_cmd_buffer rxb;
474 int (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
475 struct iwl_device_cmd *cmd);
476};
477
478void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm)
479{
480 struct iwl_async_handler_entry *entry, *tmp;
481
482 spin_lock_bh(&mvm->async_handlers_lock);
483 list_for_each_entry_safe(entry, tmp, &mvm->async_handlers_list, list) {
484 iwl_free_rxb(&entry->rxb);
485 list_del(&entry->list);
486 kfree(entry);
487 }
488 spin_unlock_bh(&mvm->async_handlers_lock);
489}
490
491static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
492{
493 struct iwl_mvm *mvm =
494 container_of(wk, struct iwl_mvm, async_handlers_wk);
495 struct iwl_async_handler_entry *entry, *tmp;
496 struct list_head local_list;
497
498 INIT_LIST_HEAD(&local_list);
499
500 /* Ensure that we are not in stop flow (check iwl_mvm_mac_stop) */
501 mutex_lock(&mvm->mutex);
502
503 /*
504 * Sync with Rx path with a lock. Remove all the entries from this list,
505 * add them to a local one (lock free), and then handle them.
506 */
507 spin_lock_bh(&mvm->async_handlers_lock);
508 list_splice_init(&mvm->async_handlers_list, &local_list);
509 spin_unlock_bh(&mvm->async_handlers_lock);
510
511 list_for_each_entry_safe(entry, tmp, &local_list, list) {
512 if (entry->fn(mvm, &entry->rxb, NULL))
513 IWL_WARN(mvm,
514 "returned value from ASYNC handlers are ignored\n");
515 iwl_free_rxb(&entry->rxb);
516 list_del(&entry->list);
517 kfree(entry);
518 }
519 mutex_unlock(&mvm->mutex);
520}
521
522static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
523 struct iwl_rx_cmd_buffer *rxb,
524 struct iwl_device_cmd *cmd)
525{
526 struct iwl_rx_packet *pkt = rxb_addr(rxb);
527 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
528 u8 i;
529
530 /*
531 * Do the notification wait before RX handlers so
532 * even if the RX handler consumes the RXB we have
533 * access to it in the notification wait entry.
534 */
535 iwl_notification_wait_notify(&mvm->notif_wait, pkt);
536
537 for (i = 0; i < ARRAY_SIZE(iwl_mvm_rx_handlers); i++) {
538 const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i];
539 if (rx_h->cmd_id == pkt->hdr.cmd) {
540 struct iwl_async_handler_entry *entry;
541 if (!rx_h->async)
542 return rx_h->fn(mvm, rxb, cmd);
543
544 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
545 /* we can't do much... */
546 if (!entry)
547 return 0;
548
549 entry->rxb._page = rxb_steal_page(rxb);
550 entry->rxb._offset = rxb->_offset;
551 entry->rxb._rx_page_order = rxb->_rx_page_order;
552 entry->fn = rx_h->fn;
553 spin_lock(&mvm->async_handlers_lock);
554 list_add_tail(&entry->list, &mvm->async_handlers_list);
555 spin_unlock(&mvm->async_handlers_lock);
556 schedule_work(&mvm->async_handlers_wk);
557 }
558 }
559
560 return 0;
561}
562
563static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
564{
565 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
566 int mq = mvm->queue_to_mac80211[queue];
567
568 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
569 return;
570
571 if (atomic_inc_return(&mvm->queue_stop_count[mq]) > 1) {
572 IWL_DEBUG_TX_QUEUES(mvm,
573 "queue %d (mac80211 %d) already stopped\n",
574 queue, mq);
575 return;
576 }
577
578 set_bit(mq, &mvm->transport_queue_stop);
579 ieee80211_stop_queue(mvm->hw, mq);
580}
581
582static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
583{
584 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
585 int mq = mvm->queue_to_mac80211[queue];
586
587 if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
588 return;
589
590 if (atomic_dec_return(&mvm->queue_stop_count[mq]) > 0) {
591 IWL_DEBUG_TX_QUEUES(mvm,
592 "queue %d (mac80211 %d) already awake\n",
593 queue, mq);
594 return;
595 }
596
597 clear_bit(mq, &mvm->transport_queue_stop);
598
599 ieee80211_wake_queue(mvm->hw, mq);
600}
601
602static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
603{
604 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
605
606 if (state)
607 set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
608 else
609 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
610
611 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, state);
612}
613
614static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
615{
616 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
617 struct ieee80211_tx_info *info;
618
619 info = IEEE80211_SKB_CB(skb);
620 iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
621 ieee80211_free_txskb(mvm->hw, skb);
622}
623
624static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
625{
626 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
627
628 iwl_mvm_dump_nic_error_log(mvm);
629
630 iwl_abort_notification_waits(&mvm->notif_wait);
631
632 /*
633 * If we're restarting already, don't cycle restarts.
634 * If INIT fw asserted, it will likely fail again.
635 * If WoWLAN fw asserted, don't restart either, mac80211
636 * can't recover this since we're already half suspended.
637 */
638 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
639 IWL_ERR(mvm, "Firmware error during reconfiguration! Abort.\n");
640 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR &&
641 iwlwifi_mod_params.restart_fw) {
642 /*
643 * This is a bit racy, but worst case we tell mac80211 about
644 * a stopped/aborted (sched) scan when that was already done
645 * which is not a problem. It is necessary to abort any scan
646 * here because mac80211 requires having the scan cleared
647 * before restarting.
648 * We'll reset the scan_status to NONE in restart cleanup in
649 * the next start() call from mac80211.
650 */
651 switch (mvm->scan_status) {
652 case IWL_MVM_SCAN_NONE:
653 break;
654 case IWL_MVM_SCAN_OS:
655 ieee80211_scan_completed(mvm->hw, true);
656 break;
657 }
658
659 ieee80211_restart_hw(mvm->hw);
660 }
661}
662
663static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
664{
665 WARN_ON(1);
666}
667
668static const struct iwl_op_mode_ops iwl_mvm_ops = {
669 .start = iwl_op_mode_mvm_start,
670 .stop = iwl_op_mode_mvm_stop,
671 .rx = iwl_mvm_rx_dispatch,
672 .queue_full = iwl_mvm_stop_sw_queue,
673 .queue_not_full = iwl_mvm_wake_sw_queue,
674 .hw_rf_kill = iwl_mvm_set_hw_rfkill_state,
675 .free_skb = iwl_mvm_free_skb,
676 .nic_error = iwl_mvm_nic_error,
677 .cmd_queue_full = iwl_mvm_cmd_queue_full,
678 .nic_config = iwl_mvm_nic_config,
679};
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
new file mode 100644
index 000000000000..b428448f8ddf
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -0,0 +1,292 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <net/mac80211.h>
65#include "fw-api.h"
66#include "mvm.h"
67
68/* Maps the driver specific channel width definition to the the fw values */
69static inline u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef)
70{
71 switch (chandef->width) {
72 case NL80211_CHAN_WIDTH_20_NOHT:
73 case NL80211_CHAN_WIDTH_20:
74 return PHY_VHT_CHANNEL_MODE20;
75 case NL80211_CHAN_WIDTH_40:
76 return PHY_VHT_CHANNEL_MODE40;
77 case NL80211_CHAN_WIDTH_80:
78 return PHY_VHT_CHANNEL_MODE80;
79 case NL80211_CHAN_WIDTH_160:
80 return PHY_VHT_CHANNEL_MODE160;
81 default:
82 WARN(1, "Invalid channel width=%u", chandef->width);
83 return PHY_VHT_CHANNEL_MODE20;
84 }
85}
86
87/*
88 * Maps the driver specific control channel position (relative to the center
89 * freq) definitions to the the fw values
90 */
91static inline u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef)
92{
93 switch (chandef->chan->center_freq - chandef->center_freq1) {
94 case -70:
95 return PHY_VHT_CTRL_POS_4_BELOW;
96 case -50:
97 return PHY_VHT_CTRL_POS_3_BELOW;
98 case -30:
99 return PHY_VHT_CTRL_POS_2_BELOW;
100 case -10:
101 return PHY_VHT_CTRL_POS_1_BELOW;
102 case 10:
103 return PHY_VHT_CTRL_POS_1_ABOVE;
104 case 30:
105 return PHY_VHT_CTRL_POS_2_ABOVE;
106 case 50:
107 return PHY_VHT_CTRL_POS_3_ABOVE;
108 case 70:
109 return PHY_VHT_CTRL_POS_4_ABOVE;
110 default:
111 WARN(1, "Invalid channel definition");
112 case 0:
113 /*
114 * The FW is expected to check the control channel position only
115 * when in HT/VHT and the channel width is not 20MHz. Return
116 * this value as the default one.
117 */
118 return PHY_VHT_CTRL_POS_1_BELOW;
119 }
120}
121
122/*
123 * Construct the generic fields of the PHY context command
124 */
125static void iwl_mvm_phy_ctxt_cmd_hdr(struct iwl_mvm_phy_ctxt *ctxt,
126 struct iwl_phy_context_cmd *cmd,
127 u32 action, u32 apply_time)
128{
129 memset(cmd, 0, sizeof(struct iwl_phy_context_cmd));
130
131 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(ctxt->id,
132 ctxt->color));
133 cmd->action = cpu_to_le32(action);
134 cmd->apply_time = cpu_to_le32(apply_time);
135}
136
137/*
138 * Add the phy configuration to the PHY context command
139 */
140static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
141 struct iwl_phy_context_cmd *cmd,
142 struct cfg80211_chan_def *chandef,
143 u8 chains_static, u8 chains_dynamic)
144{
145 u8 valid_rx_chains, active_cnt, idle_cnt;
146
147 /* Set the channel info data */
148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
149 PHY_BAND_24 : PHY_BAND_5);
150
151 cmd->ci.channel = chandef->chan->hw_value;
152 cmd->ci.width = iwl_mvm_get_channel_width(chandef);
153 cmd->ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef);
154
155 /* Set rx the chains */
156
157 /* TODO:
158 * Need to add on chain noise calibration limitations, and
159 * BT coex considerations.
160 */
161 valid_rx_chains = mvm->nvm_data->valid_rx_ant;
162 idle_cnt = chains_static;
163 active_cnt = chains_dynamic;
164
165 cmd->rxchain_info = cpu_to_le32(valid_rx_chains <<
166 PHY_RX_CHAIN_VALID_POS);
167 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
168 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
169 PHY_RX_CHAIN_MIMO_CNT_POS);
170
171 cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant);
172}
173
174/*
175 * Send a command to apply the current phy configuration. The command is send
176 * only if something in the configuration changed: in case that this is the
177 * first time that the phy configuration is applied or in case that the phy
178 * configuration changed from the previous apply.
179 */
180static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
181 struct iwl_mvm_phy_ctxt *ctxt,
182 struct cfg80211_chan_def *chandef,
183 u8 chains_static, u8 chains_dynamic,
184 u32 action, u32 apply_time)
185{
186 struct iwl_phy_context_cmd cmd;
187 int ret;
188
189 /* Set the command header fields */
190 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, action, apply_time);
191
192 /* Set the command data */
193 iwl_mvm_phy_ctxt_cmd_data(mvm, &cmd, chandef,
194 chains_static, chains_dynamic);
195
196 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC,
197 sizeof(struct iwl_phy_context_cmd),
198 &cmd);
199 if (ret)
200 IWL_ERR(mvm, "PHY ctxt cmd error. ret=%d\n", ret);
201 return ret;
202}
203
204
205struct phy_ctx_used_data {
206 unsigned long used[BITS_TO_LONGS(NUM_PHY_CTX)];
207};
208
209static void iwl_mvm_phy_ctx_used_iter(struct ieee80211_hw *hw,
210 struct ieee80211_chanctx_conf *ctx,
211 void *_data)
212{
213 struct phy_ctx_used_data *data = _data;
214 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
215
216 __set_bit(phy_ctxt->id, data->used);
217}
218
219/*
220 * Send a command to add a PHY context based on the current HW configuration.
221 */
222int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
223 struct cfg80211_chan_def *chandef,
224 u8 chains_static, u8 chains_dynamic)
225{
226 struct phy_ctx_used_data data = {
227 .used = { },
228 };
229
230 /*
231 * If this is a regular PHY context (not the ROC one)
232 * skip the ROC PHY context's ID.
233 */
234 if (ctxt != &mvm->phy_ctxt_roc)
235 __set_bit(mvm->phy_ctxt_roc.id, data.used);
236
237 lockdep_assert_held(&mvm->mutex);
238 ctxt->color++;
239
240 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
241 ieee80211_iter_chan_contexts_atomic(
242 mvm->hw, iwl_mvm_phy_ctx_used_iter, &data);
243
244 ctxt->id = find_first_zero_bit(data.used, NUM_PHY_CTX);
245 if (WARN_ONCE(ctxt->id == NUM_PHY_CTX,
246 "Failed to init PHY context - no free ID!\n"))
247 return -EIO;
248 }
249
250 ctxt->channel = chandef->chan;
251 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
252 chains_static, chains_dynamic,
253 FW_CTXT_ACTION_ADD, 0);
254}
255
256/*
257 * Send a command to modify the PHY context based on the current HW
258 * configuration. Note that the function does not check that the configuration
259 * changed.
260 */
261int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
262 struct cfg80211_chan_def *chandef,
263 u8 chains_static, u8 chains_dynamic)
264{
265 lockdep_assert_held(&mvm->mutex);
266
267 ctxt->channel = chandef->chan;
268 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
269 chains_static, chains_dynamic,
270 FW_CTXT_ACTION_MODIFY, 0);
271}
272
273/*
274 * Send a command to the FW to remove the given phy context.
275 * Once the command is sent, regardless of success or failure, the context is
276 * marked as invalid
277 */
278void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
279{
280 struct iwl_phy_context_cmd cmd;
281 int ret;
282
283 lockdep_assert_held(&mvm->mutex);
284
285 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0);
286 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC,
287 sizeof(struct iwl_phy_context_cmd),
288 &cmd);
289 if (ret)
290 IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
291 ctxt->id);
292}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
new file mode 100644
index 000000000000..63628739cf4a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -0,0 +1,207 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/kernel.h>
65#include <linux/module.h>
66#include <linux/slab.h>
67#include <linux/init.h>
68
69#include <net/mac80211.h>
70
71#include "iwl-debug.h"
72#include "mvm.h"
73#include "iwl-modparams.h"
74#include "fw-api-power.h"
75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77
78static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
79 struct iwl_powertable_cmd *cmd)
80{
81 struct ieee80211_hw *hw = mvm->hw;
82 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
83 struct ieee80211_chanctx_conf *chanctx_conf;
84 struct ieee80211_channel *chan;
85 int dtimper, dtimper_msec;
86 int keep_alive;
87 bool radar_detect = false;
88
89 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
90 mvmvif->color));
91 cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY);
92
93 if ((!vif->bss_conf.ps) ||
94 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM))
95 return;
96
97 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
98
99 dtimper = hw->conf.ps_dtim_period ?: 1;
100
101 /* Check if radar detection is required on current channel */
102 rcu_read_lock();
103 chanctx_conf = rcu_dereference(vif->chanctx_conf);
104 WARN_ON(!chanctx_conf);
105 if (chanctx_conf) {
106 chan = chanctx_conf->def.chan;
107 radar_detect = chan->flags & IEEE80211_CHAN_RADAR;
108 }
109 rcu_read_unlock();
110
111 /* Check skip over DTIM conditions */
112 if (!radar_detect && (dtimper <= 10) &&
113 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) {
114 cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK);
115 cmd->num_skip_dtim = 2;
116 }
117
118 /* Check that keep alive period is at least 3 * DTIM */
119 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
120 keep_alive = max_t(int, 3 * dtimper_msec,
121 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC);
122 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
123
124 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
125
126 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) {
127 /* TODO: Also for D3 (device sleep / WoWLAN) */
128 cmd->rx_data_timeout = cpu_to_le32(10);
129 cmd->tx_data_timeout = cpu_to_le32(10);
130 } else {
131 cmd->rx_data_timeout = cpu_to_le32(50);
132 cmd->tx_data_timeout = cpu_to_le32(50);
133 }
134}
135
136int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
137{
138 struct iwl_powertable_cmd cmd = {};
139
140 if (!iwlwifi_mod_params.power_save) {
141 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
142 return 0;
143 }
144
145 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
146 return 0;
147
148 iwl_power_build_cmd(mvm, vif, &cmd);
149
150 IWL_DEBUG_POWER(mvm,
151 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
152 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
153 le16_to_cpu(cmd.flags));
154
155 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
156 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
157 le16_to_cpu(cmd.keep_alive_seconds));
158 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
159 le32_to_cpu(cmd.rx_data_timeout));
160 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
161 le32_to_cpu(cmd.tx_data_timeout));
162 IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n",
163 le32_to_cpu(cmd.rx_data_timeout_uapsd));
164 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
165 le32_to_cpu(cmd.tx_data_timeout_uapsd));
166 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
167 cmd.lprx_rssi_threshold);
168 IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim);
169 }
170
171 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
172 sizeof(cmd), &cmd);
173}
174
175int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
176{
177 struct iwl_powertable_cmd cmd = {};
178 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
179
180 if (!iwlwifi_mod_params.power_save) {
181 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
182 return 0;
183 }
184
185 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
186 return 0;
187
188 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
189 mvmvif->color));
190 cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY);
191
192 IWL_DEBUG_POWER(mvm,
193 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
194 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
195 le16_to_cpu(cmd.flags));
196
197 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
198 sizeof(cmd), &cmd);
199}
200
201#ifdef CONFIG_IWLWIFI_DEBUGFS
202void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
203 struct iwl_powertable_cmd *cmd)
204{
205 iwl_power_build_cmd(mvm, vif, cmd);
206}
207#endif /* CONFIG_IWLWIFI_DEBUGFS */
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
new file mode 100644
index 000000000000..2d4611a563c5
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -0,0 +1,178 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <net/mac80211.h>
65#include "fw-api.h"
66#include "mvm.h"
67
68struct iwl_mvm_quota_iterator_data {
69 int n_interfaces[MAX_BINDINGS];
70 int colors[MAX_BINDINGS];
71 struct ieee80211_vif *new_vif;
72};
73
74static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
75 struct ieee80211_vif *vif)
76{
77 struct iwl_mvm_quota_iterator_data *data = _data;
78 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
79 u16 id;
80
81 /*
82 * We'll account for the new interface (if any) below,
83 * skip it here in case we're not called from within
84 * the add_interface callback (otherwise it won't show
85 * up in iteration)
86 */
87 if (vif == data->new_vif)
88 return;
89
90 if (!mvmvif->phy_ctxt)
91 return;
92
93 /* currently, PHY ID == binding ID */
94 id = mvmvif->phy_ctxt->id;
95
96 /* need at least one binding per PHY */
97 BUILD_BUG_ON(NUM_PHY_CTX > MAX_BINDINGS);
98
99 if (WARN_ON_ONCE(id >= MAX_BINDINGS))
100 return;
101
102 if (data->colors[id] < 0)
103 data->colors[id] = mvmvif->phy_ctxt->color;
104 else
105 WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
106
107 switch (vif->type) {
108 case NL80211_IFTYPE_STATION:
109 if (vif->bss_conf.assoc)
110 data->n_interfaces[id]++;
111 break;
112 case NL80211_IFTYPE_AP:
113 if (mvmvif->ap_active)
114 data->n_interfaces[id]++;
115 break;
116 case NL80211_IFTYPE_MONITOR:
117 data->n_interfaces[id]++;
118 break;
119 case NL80211_IFTYPE_P2P_DEVICE:
120 break;
121 case NL80211_IFTYPE_ADHOC:
122 if (vif->bss_conf.ibss_joined)
123 data->n_interfaces[id]++;
124 break;
125 default:
126 WARN_ON_ONCE(1);
127 break;
128 }
129}
130
131int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
132{
133 struct iwl_time_quota_cmd cmd;
134 int i, idx, ret;
135 struct iwl_mvm_quota_iterator_data data = {
136 .n_interfaces = {},
137 .colors = { -1, -1, -1, -1 },
138 .new_vif = newvif,
139 };
140
141 /* update all upon completion */
142 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
143 return 0;
144
145 BUILD_BUG_ON(data.colors[MAX_BINDINGS - 1] != -1);
146
147 lockdep_assert_held(&mvm->mutex);
148
149 memset(&cmd, 0, sizeof(cmd));
150
151 ieee80211_iterate_active_interfaces_atomic(
152 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
153 iwl_mvm_quota_iterator, &data);
154 if (newvif) {
155 data.new_vif = NULL;
156 iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
157 }
158
159 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
160 if (data.n_interfaces[i] <= 0)
161 continue;
162
163 cmd.quotas[idx].id_and_color =
164 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
165 cmd.quotas[idx].quota = cpu_to_le32(100);
166 cmd.quotas[idx].max_duration = cpu_to_le32(1000);
167 idx++;
168 }
169
170 for (i = idx; i < MAX_BINDINGS; i++)
171 cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
172
173 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
174 sizeof(cmd), &cmd);
175 if (ret)
176 IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
177 return ret;
178}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
new file mode 100644
index 000000000000..60a4291ca221
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -0,0 +1,3096 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/skbuff.h>
29#include <linux/slab.h>
30#include <net/mac80211.h>
31
32#include <linux/netdevice.h>
33#include <linux/etherdevice.h>
34#include <linux/delay.h>
35
36#include <linux/workqueue.h>
37#include "rs.h"
38#include "fw-api.h"
39#include "sta.h"
40#include "iwl-op-mode.h"
41#include "mvm.h"
42
43#define RS_NAME "iwl-mvm-rs"
44
45#define NUM_TRY_BEFORE_ANT_TOGGLE 1
46#define IWL_NUMBER_TRY 1
47#define IWL_HT_NUMBER_TRY 3
48
49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
50#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
51#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
52
53/* max allowed rate miss before sync LQ cmd */
54#define IWL_MISSED_RATE_MAX 15
55/* max time to accum history 2 seconds */
56#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)
57
58static u8 rs_ht_to_legacy[] = {
59 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
60 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
61 IWL_RATE_6M_INDEX,
62 IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX,
63 IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX,
64 IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX,
65 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
66};
67
68static const u8 ant_toggle_lookup[] = {
69 /*ANT_NONE -> */ ANT_NONE,
70 /*ANT_A -> */ ANT_B,
71 /*ANT_B -> */ ANT_C,
72 /*ANT_AB -> */ ANT_BC,
73 /*ANT_C -> */ ANT_A,
74 /*ANT_AC -> */ ANT_AB,
75 /*ANT_BC -> */ ANT_AC,
76 /*ANT_ABC -> */ ANT_ABC,
77};
78
79#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
80 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
81 IWL_RATE_SISO_##s##M_PLCP, \
82 IWL_RATE_MIMO2_##s##M_PLCP,\
83 IWL_RATE_MIMO3_##s##M_PLCP,\
84 IWL_RATE_##r##M_IEEE, \
85 IWL_RATE_##ip##M_INDEX, \
86 IWL_RATE_##in##M_INDEX, \
87 IWL_RATE_##rp##M_INDEX, \
88 IWL_RATE_##rn##M_INDEX, \
89 IWL_RATE_##pp##M_INDEX, \
90 IWL_RATE_##np##M_INDEX }
91
92/*
93 * Parameter order:
94 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
95 *
96 * If there isn't a valid next or previous rate then INV is used which
97 * maps to IWL_RATE_INVALID
98 *
99 */
100static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
101 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
102 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
103 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
104 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
105 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
106 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
107 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
108 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
109 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
110 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
111 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
112 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
113 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
114 /* FIXME:RS: ^^ should be INV (legacy) */
115};
116
117static inline u8 rs_extract_rate(u32 rate_n_flags)
118{
119 /* also works for HT because bits 7:6 are zero there */
120 return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK);
121}
122
123static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
124{
125 int idx = 0;
126
127 /* HT rate format */
128 if (rate_n_flags & RATE_MCS_HT_MSK) {
129 idx = rs_extract_rate(rate_n_flags);
130
131 if (idx >= IWL_RATE_MIMO3_6M_PLCP)
132 idx = idx - IWL_RATE_MIMO3_6M_PLCP;
133 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
134 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
135
136 idx += IWL_FIRST_OFDM_RATE;
137 /* skip 9M not supported in ht*/
138 if (idx >= IWL_RATE_9M_INDEX)
139 idx += 1;
140 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
141 return idx;
142
143 /* legacy rate format, search for match in table */
144 } else {
145 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
146 if (iwl_rates[idx].plcp ==
147 rs_extract_rate(rate_n_flags))
148 return idx;
149 }
150
151 return -1;
152}
153
154static void rs_rate_scale_perform(struct iwl_mvm *mvm,
155 struct sk_buff *skb,
156 struct ieee80211_sta *sta,
157 struct iwl_lq_sta *lq_sta);
158static void rs_fill_link_cmd(struct iwl_mvm *mvm,
159 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
160static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
161
162
163#ifdef CONFIG_MAC80211_DEBUGFS
164static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
165 u32 *rate_n_flags, int index);
166#else
167static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
168 u32 *rate_n_flags, int index)
169{}
170#endif
171
172/**
173 * The following tables contain the expected throughput metrics for all rates
174 *
175 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
176 *
177 * where invalid entries are zeros.
178 *
179 * CCK rates are only valid in legacy table and will only be used in G
180 * (2.4 GHz) band.
181 */
182
183static s32 expected_tpt_legacy[IWL_RATE_COUNT] = {
184 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0
185};
186
187static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = {
188 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */
189 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */
190 {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */
191 {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */
192};
193
194static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = {
195 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */
196 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */
197 {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */
198 {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */
199};
200
201static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
202 {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */
203 {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */
204 {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */
205 {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/
206};
207
208static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
209 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */
210 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */
211 {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */
212 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */
213};
214
215static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {
216 {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */
217 {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */
218 {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */
219 {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */
220};
221
222static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = {
223 {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297}, /* Norm */
224 {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300}, /* SGI */
225 {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070}, /* AGG */
226 {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */
227};
228
229/* mbps, mcs */
230static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
231 { "1", "BPSK DSSS"},
232 { "2", "QPSK DSSS"},
233 {"5.5", "BPSK CCK"},
234 { "11", "QPSK CCK"},
235 { "6", "BPSK 1/2"},
236 { "9", "BPSK 1/2"},
237 { "12", "QPSK 1/2"},
238 { "18", "QPSK 3/4"},
239 { "24", "16QAM 1/2"},
240 { "36", "16QAM 3/4"},
241 { "48", "64QAM 2/3"},
242 { "54", "64QAM 3/4"},
243 { "60", "64QAM 5/6"},
244};
245
246#define MCS_INDEX_PER_STREAM (8)
247
248static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
249{
250 window->data = 0;
251 window->success_counter = 0;
252 window->success_ratio = IWL_INVALID_VALUE;
253 window->counter = 0;
254 window->average_tpt = IWL_INVALID_VALUE;
255 window->stamp = 0;
256}
257
258static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
259{
260 return (ant_type & valid_antenna) == ant_type;
261}
262
263/*
264 * removes the old data from the statistics. All data that is older than
265 * TID_MAX_TIME_DIFF, will be deleted.
266 */
267static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)
268{
269 /* The oldest age we want to keep */
270 u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;
271
272 while (tl->queue_count &&
273 (tl->time_stamp < oldest_time)) {
274 tl->total -= tl->packet_count[tl->head];
275 tl->packet_count[tl->head] = 0;
276 tl->time_stamp += TID_QUEUE_CELL_SPACING;
277 tl->queue_count--;
278 tl->head++;
279 if (tl->head >= TID_QUEUE_MAX_SIZE)
280 tl->head = 0;
281 }
282}
283
284/*
285 * increment traffic load value for tid and also remove
286 * any old values if passed the certain time period
287 */
288static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
289 struct ieee80211_hdr *hdr)
290{
291 u32 curr_time = jiffies_to_msecs(jiffies);
292 u32 time_diff;
293 s32 index;
294 struct iwl_traffic_load *tl = NULL;
295 u8 tid;
296
297 if (ieee80211_is_data_qos(hdr->frame_control)) {
298 u8 *qc = ieee80211_get_qos_ctl(hdr);
299 tid = qc[0] & 0xf;
300 } else {
301 return IWL_MAX_TID_COUNT;
302 }
303
304 if (unlikely(tid >= IWL_MAX_TID_COUNT))
305 return IWL_MAX_TID_COUNT;
306
307 tl = &lq_data->load[tid];
308
309 curr_time -= curr_time % TID_ROUND_VALUE;
310
311 /* Happens only for the first packet. Initialize the data */
312 if (!(tl->queue_count)) {
313 tl->total = 1;
314 tl->time_stamp = curr_time;
315 tl->queue_count = 1;
316 tl->head = 0;
317 tl->packet_count[0] = 1;
318 return IWL_MAX_TID_COUNT;
319 }
320
321 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
322 index = time_diff / TID_QUEUE_CELL_SPACING;
323
324 /* The history is too long: remove data that is older than */
325 /* TID_MAX_TIME_DIFF */
326 if (index >= TID_QUEUE_MAX_SIZE)
327 rs_tl_rm_old_stats(tl, curr_time);
328
329 index = (tl->head + index) % TID_QUEUE_MAX_SIZE;
330 tl->packet_count[index] = tl->packet_count[index] + 1;
331 tl->total = tl->total + 1;
332
333 if ((index + 1) > tl->queue_count)
334 tl->queue_count = index + 1;
335
336 return tid;
337}
338
339#ifdef CONFIG_MAC80211_DEBUGFS
340/**
341 * Program the device to use fixed rate for frame transmit
342 * This is for debugging/testing only
343 * once the device start use fixed rate, we need to reload the module
344 * to being back the normal operation.
345 */
346static void rs_program_fix_rate(struct iwl_mvm *mvm,
347 struct iwl_lq_sta *lq_sta)
348{
349 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
350 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
351 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
352 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
353
354 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
355 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
356
357 if (lq_sta->dbg_fixed_rate) {
358 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
359 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
360 }
361}
362#endif
363
364/*
365 get the traffic load value for tid
366*/
367static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
368{
369 u32 curr_time = jiffies_to_msecs(jiffies);
370 u32 time_diff;
371 s32 index;
372 struct iwl_traffic_load *tl = NULL;
373
374 if (tid >= IWL_MAX_TID_COUNT)
375 return 0;
376
377 tl = &(lq_data->load[tid]);
378
379 curr_time -= curr_time % TID_ROUND_VALUE;
380
381 if (!(tl->queue_count))
382 return 0;
383
384 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
385 index = time_diff / TID_QUEUE_CELL_SPACING;
386
387 /* The history is too long: remove data that is older than */
388 /* TID_MAX_TIME_DIFF */
389 if (index >= TID_QUEUE_MAX_SIZE)
390 rs_tl_rm_old_stats(tl, curr_time);
391
392 return tl->total;
393}
394
395static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
396 struct iwl_lq_sta *lq_data, u8 tid,
397 struct ieee80211_sta *sta)
398{
399 int ret = -EAGAIN;
400 u32 load;
401
402 load = rs_tl_get_load(lq_data, tid);
403
404 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) {
405 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
406 sta->addr, tid);
407 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
408 if (ret == -EAGAIN) {
409 /*
410 * driver and mac80211 is out of sync
411 * this might be cause by reloading firmware
412 * stop the tx ba session here
413 */
414 IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",
415 tid);
416 ieee80211_stop_tx_ba_session(sta, tid);
417 }
418 } else {
419 IWL_DEBUG_HT(mvm,
420 "Aggregation not enabled for tid %d because load = %u\n",
421 tid, load);
422 }
423 return ret;
424}
425
426static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, u8 tid,
427 struct iwl_lq_sta *lq_data,
428 struct ieee80211_sta *sta)
429{
430 if (tid < IWL_MAX_TID_COUNT)
431 rs_tl_turn_on_agg_for_tid(mvm, lq_data, tid, sta);
432 else
433 IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n",
434 tid, IWL_MAX_TID_COUNT);
435}
436
437static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
438{
439 return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
440 !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
441 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
442}
443
444/*
445 * Static function to get the expected throughput from an iwl_scale_tbl_info
446 * that wraps a NULL pointer check
447 */
448static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
449{
450 if (tbl->expected_tpt)
451 return tbl->expected_tpt[rs_index];
452 return 0;
453}
454
455/**
456 * rs_collect_tx_data - Update the success/failure sliding window
457 *
458 * We keep a sliding window of the last 62 packets transmitted
459 * at this rate. window->data contains the bitmask of successful
460 * packets.
461 */
462static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
463 int scale_index, int attempts, int successes)
464{
465 struct iwl_rate_scale_data *window = NULL;
466 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
467 s32 fail_count, tpt;
468
469 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
470 return -EINVAL;
471
472 /* Select window for current tx bit rate */
473 window = &(tbl->win[scale_index]);
474
475 /* Get expected throughput */
476 tpt = get_expected_tpt(tbl, scale_index);
477
478 /*
479 * Keep track of only the latest 62 tx frame attempts in this rate's
480 * history window; anything older isn't really relevant any more.
481 * If we have filled up the sliding window, drop the oldest attempt;
482 * if the oldest attempt (highest bit in bitmap) shows "success",
483 * subtract "1" from the success counter (this is the main reason
484 * we keep these bitmaps!).
485 */
486 while (attempts > 0) {
487 if (window->counter >= IWL_RATE_MAX_WINDOW) {
488 /* remove earliest */
489 window->counter = IWL_RATE_MAX_WINDOW - 1;
490
491 if (window->data & mask) {
492 window->data &= ~mask;
493 window->success_counter--;
494 }
495 }
496
497 /* Increment frames-attempted counter */
498 window->counter++;
499
500 /* Shift bitmap by one frame to throw away oldest history */
501 window->data <<= 1;
502
503 /* Mark the most recent #successes attempts as successful */
504 if (successes > 0) {
505 window->success_counter++;
506 window->data |= 0x1;
507 successes--;
508 }
509
510 attempts--;
511 }
512
513 /* Calculate current success ratio, avoid divide-by-0! */
514 if (window->counter > 0)
515 window->success_ratio = 128 * (100 * window->success_counter)
516 / window->counter;
517 else
518 window->success_ratio = IWL_INVALID_VALUE;
519
520 fail_count = window->counter - window->success_counter;
521
522 /* Calculate average throughput, if we have enough history. */
523 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
524 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
525 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
526 else
527 window->average_tpt = IWL_INVALID_VALUE;
528
529 /* Tag this window as having been updated */
530 window->stamp = jiffies;
531
532 return 0;
533}
534
535/*
536 * Fill uCode API rate_n_flags field, based on "search" or "active" table.
537 */
538/* FIXME:RS:remove this function and put the flags statically in the table */
539static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
540 struct iwl_scale_tbl_info *tbl,
541 int index, u8 use_green)
542{
543 u32 rate_n_flags = 0;
544
545 if (is_legacy(tbl->lq_type)) {
546 rate_n_flags = iwl_rates[index].plcp;
547 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
548 rate_n_flags |= RATE_MCS_CCK_MSK;
549 } else if (is_Ht(tbl->lq_type)) {
550 if (index > IWL_LAST_OFDM_RATE) {
551 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
552 index = IWL_LAST_OFDM_RATE;
553 }
554 rate_n_flags = RATE_MCS_HT_MSK;
555
556 if (is_siso(tbl->lq_type))
557 rate_n_flags |= iwl_rates[index].plcp_siso;
558 else if (is_mimo2(tbl->lq_type))
559 rate_n_flags |= iwl_rates[index].plcp_mimo2;
560 else
561 rate_n_flags |= iwl_rates[index].plcp_mimo3;
562 } else {
563 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type);
564 }
565
566 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
567 RATE_MCS_ANT_ABC_MSK);
568
569 if (is_Ht(tbl->lq_type)) {
570 if (tbl->is_ht40)
571 rate_n_flags |= RATE_MCS_CHAN_WIDTH_40;
572 if (tbl->is_SGI)
573 rate_n_flags |= RATE_MCS_SGI_MSK;
574
575 if (use_green) {
576 rate_n_flags |= RATE_HT_MCS_GF_MSK;
577 if (is_siso(tbl->lq_type) && tbl->is_SGI) {
578 rate_n_flags &= ~RATE_MCS_SGI_MSK;
579 IWL_ERR(mvm, "GF was set with SGI:SISO\n");
580 }
581 }
582 }
583 return rate_n_flags;
584}
585
586/*
587 * Interpret uCode API's rate_n_flags format,
588 * fill "search" or "active" tx mode table.
589 */
590static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
591 enum ieee80211_band band,
592 struct iwl_scale_tbl_info *tbl,
593 int *rate_idx)
594{
595 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
596 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
597 u8 mcs;
598
599 memset(tbl, 0, sizeof(struct iwl_scale_tbl_info));
600 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
601
602 if (*rate_idx == IWL_RATE_INVALID) {
603 *rate_idx = -1;
604 return -EINVAL;
605 }
606 tbl->is_SGI = 0; /* default legacy setup */
607 tbl->is_ht40 = 0;
608 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
609 tbl->lq_type = LQ_NONE;
610 tbl->max_search = IWL_MAX_SEARCH;
611
612 /* legacy rate format */
613 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
614 if (num_of_ant == 1) {
615 if (band == IEEE80211_BAND_5GHZ)
616 tbl->lq_type = LQ_A;
617 else
618 tbl->lq_type = LQ_G;
619 }
620 /* HT rate format */
621 } else {
622 if (rate_n_flags & RATE_MCS_SGI_MSK)
623 tbl->is_SGI = 1;
624
625 if (rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */
626 tbl->is_ht40 = 1;
627
628 mcs = rs_extract_rate(rate_n_flags);
629
630 /* SISO */
631 if (mcs <= IWL_RATE_SISO_60M_PLCP) {
632 if (num_of_ant == 1)
633 tbl->lq_type = LQ_SISO; /*else NONE*/
634 /* MIMO2 */
635 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {
636 if (num_of_ant == 2)
637 tbl->lq_type = LQ_MIMO2;
638 /* MIMO3 */
639 } else {
640 if (num_of_ant == 3) {
641 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
642 tbl->lq_type = LQ_MIMO3;
643 }
644 }
645 }
646 return 0;
647}
648
649/* switch to another antenna/antennas and return 1 */
650/* if no other valid antenna found, return 0 */
651static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
652 struct iwl_scale_tbl_info *tbl)
653{
654 u8 new_ant_type;
655
656 if (!tbl->ant_type || tbl->ant_type > ANT_ABC)
657 return 0;
658
659 if (!rs_is_valid_ant(valid_ant, tbl->ant_type))
660 return 0;
661
662 new_ant_type = ant_toggle_lookup[tbl->ant_type];
663
664 while ((new_ant_type != tbl->ant_type) &&
665 !rs_is_valid_ant(valid_ant, new_ant_type))
666 new_ant_type = ant_toggle_lookup[new_ant_type];
667
668 if (new_ant_type == tbl->ant_type)
669 return 0;
670
671 tbl->ant_type = new_ant_type;
672 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK;
673 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;
674 return 1;
675}
676
677/**
678 * Green-field mode is valid if the station supports it and
679 * there are no non-GF stations present in the BSS.
680 */
681static bool rs_use_green(struct ieee80211_sta *sta)
682{
683 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
684
685 bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode &
686 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
687
688 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green;
689}
690
691/**
692 * rs_get_supported_rates - get the available rates
693 *
694 * if management frame or broadcast frame only return
695 * basic available rates.
696 *
697 */
698static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
699 struct ieee80211_hdr *hdr,
700 enum iwl_table_type rate_type)
701{
702 if (is_legacy(rate_type)) {
703 return lq_sta->active_legacy_rate;
704 } else {
705 if (is_siso(rate_type))
706 return lq_sta->active_siso_rate;
707 else if (is_mimo2(rate_type))
708 return lq_sta->active_mimo2_rate;
709 else
710 return lq_sta->active_mimo3_rate;
711 }
712}
713
714static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
715 int rate_type)
716{
717 u8 high = IWL_RATE_INVALID;
718 u8 low = IWL_RATE_INVALID;
719
720 /* 802.11A or ht walks to the next literal adjacent rate in
721 * the rate table */
722 if (is_a_band(rate_type) || !is_legacy(rate_type)) {
723 int i;
724 u32 mask;
725
726 /* Find the previous rate that is in the rate mask */
727 i = index - 1;
728 for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
729 if (rate_mask & mask) {
730 low = i;
731 break;
732 }
733 }
734
735 /* Find the next rate that is in the rate mask */
736 i = index + 1;
737 for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
738 if (rate_mask & mask) {
739 high = i;
740 break;
741 }
742 }
743
744 return (high << 8) | low;
745 }
746
747 low = index;
748 while (low != IWL_RATE_INVALID) {
749 low = iwl_rates[low].prev_rs;
750 if (low == IWL_RATE_INVALID)
751 break;
752 if (rate_mask & (1 << low))
753 break;
754 IWL_DEBUG_RATE(mvm, "Skipping masked lower rate: %d\n", low);
755 }
756
757 high = index;
758 while (high != IWL_RATE_INVALID) {
759 high = iwl_rates[high].next_rs;
760 if (high == IWL_RATE_INVALID)
761 break;
762 if (rate_mask & (1 << high))
763 break;
764 IWL_DEBUG_RATE(mvm, "Skipping masked higher rate: %d\n", high);
765 }
766
767 return (high << 8) | low;
768}
769
770static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
771 struct iwl_scale_tbl_info *tbl,
772 u8 scale_index, u8 ht_possible)
773{
774 s32 low;
775 u16 rate_mask;
776 u16 high_low;
777 u8 switch_to_legacy = 0;
778 u8 is_green = lq_sta->is_green;
779 struct iwl_mvm *mvm = lq_sta->drv;
780
781 /* check if we need to switch from HT to legacy rates.
782 * assumption is that mandatory rates (1Mbps or 6Mbps)
783 * are always supported (spec demand) */
784 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
785 switch_to_legacy = 1;
786 scale_index = rs_ht_to_legacy[scale_index];
787 if (lq_sta->band == IEEE80211_BAND_5GHZ)
788 tbl->lq_type = LQ_A;
789 else
790 tbl->lq_type = LQ_G;
791
792 if (num_of_ant(tbl->ant_type) > 1)
793 tbl->ant_type =
794 first_antenna(mvm->nvm_data->valid_tx_ant);
795
796 tbl->is_ht40 = 0;
797 tbl->is_SGI = 0;
798 tbl->max_search = IWL_MAX_SEARCH;
799 }
800
801 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
802
803 /* Mask with station rate restriction */
804 if (is_legacy(tbl->lq_type)) {
805 /* supp_rates has no CCK bits in A mode */
806 if (lq_sta->band == IEEE80211_BAND_5GHZ)
807 rate_mask = (u16)(rate_mask &
808 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
809 else
810 rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
811 }
812
813 /* If we switched from HT to legacy, check current rate */
814 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
815 low = scale_index;
816 goto out;
817 }
818
819 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
820 tbl->lq_type);
821 low = high_low & 0xff;
822
823 if (low == IWL_RATE_INVALID)
824 low = scale_index;
825
826out:
827 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
828}
829
830/*
831 * Simple function to compare two rate scale table types
832 */
833static bool table_type_matches(struct iwl_scale_tbl_info *a,
834 struct iwl_scale_tbl_info *b)
835{
836 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
837 (a->is_SGI == b->is_SGI);
838}
839
840/*
841 * mac80211 sends us Tx status
842 */
843static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
844 struct ieee80211_sta *sta, void *priv_sta,
845 struct sk_buff *skb)
846{
847 int legacy_success;
848 int retries;
849 int rs_index, mac_index, i;
850 struct iwl_lq_sta *lq_sta = priv_sta;
851 struct iwl_lq_cmd *table;
852 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
853 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r;
854 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
855 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
856 enum mac80211_rate_control_flags mac_flags;
857 u32 tx_rate;
858 struct iwl_scale_tbl_info tbl_type;
859 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
860
861 IWL_DEBUG_RATE_LIMIT(mvm,
862 "get frame ack response, update rate scale window\n");
863
864 /* Treat uninitialized rate scaling data same as non-existing. */
865 if (!lq_sta) {
866 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
867 return;
868 } else if (!lq_sta->drv) {
869 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
870 return;
871 }
872
873 if (!ieee80211_is_data(hdr->frame_control) ||
874 info->flags & IEEE80211_TX_CTL_NO_ACK)
875 return;
876
877 /* This packet was aggregated but doesn't carry status info */
878 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
879 !(info->flags & IEEE80211_TX_STAT_AMPDU))
880 return;
881
882 /*
883 * Ignore this Tx frame response if its initial rate doesn't match
884 * that of latest Link Quality command. There may be stragglers
885 * from a previous Link Quality command, but we're no longer interested
886 * in those; they're either from the "active" mode while we're trying
887 * to check "search" mode, or a prior "search" mode after we've moved
888 * to a new "search" mode (which might become the new "active" mode).
889 */
890 table = &lq_sta->lq;
891 tx_rate = le32_to_cpu(table->rs_table[0]);
892 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, &rs_index);
893 if (info->band == IEEE80211_BAND_5GHZ)
894 rs_index -= IWL_FIRST_OFDM_RATE;
895 mac_flags = info->status.rates[0].flags;
896 mac_index = info->status.rates[0].idx;
897 /* For HT packets, map MCS to PLCP */
898 if (mac_flags & IEEE80211_TX_RC_MCS) {
899 /* Remove # of streams */
900 mac_index &= RATE_HT_MCS_RATE_CODE_MSK;
901 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
902 mac_index++;
903 /*
904 * mac80211 HT index is always zero-indexed; we need to move
905 * HT OFDM rates after CCK rates in 2.4 GHz band
906 */
907 if (info->band == IEEE80211_BAND_2GHZ)
908 mac_index += IWL_FIRST_OFDM_RATE;
909 }
910 /* Here we actually compare this rate to the latest LQ command */
911 if ((mac_index < 0) ||
912 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
913 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
914 (tbl_type.ant_type != info->status.antenna) ||
915 (!!(tx_rate & RATE_MCS_HT_MSK) !=
916 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
917 (!!(tx_rate & RATE_HT_MCS_GF_MSK) !=
918 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
919 (rs_index != mac_index)) {
920 IWL_DEBUG_RATE(mvm,
921 "initial rate %d does not match %d (0x%x)\n",
922 mac_index, rs_index, tx_rate);
923 /*
924 * Since rates mis-match, the last LQ command may have failed.
925 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
926 * ... driver.
927 */
928 lq_sta->missed_rate_counter++;
929 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
930 lq_sta->missed_rate_counter = 0;
931 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
932 }
933 /* Regardless, ignore this status info for outdated rate */
934 return;
935 } else
936 /* Rate did match, so reset the missed_rate_counter */
937 lq_sta->missed_rate_counter = 0;
938
939 /* Figure out if rate scale algorithm is in active or search table */
940 if (table_type_matches(&tbl_type,
941 &(lq_sta->lq_info[lq_sta->active_tbl]))) {
942 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
943 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
944 } else if (table_type_matches(
945 &tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) {
946 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
947 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
948 } else {
949 IWL_DEBUG_RATE(mvm,
950 "Neither active nor search matches tx rate\n");
951 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
952 IWL_DEBUG_RATE(mvm, "active- lq:%x, ant:%x, SGI:%d\n",
953 tmp_tbl->lq_type, tmp_tbl->ant_type,
954 tmp_tbl->is_SGI);
955 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
956 IWL_DEBUG_RATE(mvm, "search- lq:%x, ant:%x, SGI:%d\n",
957 tmp_tbl->lq_type, tmp_tbl->ant_type,
958 tmp_tbl->is_SGI);
959 IWL_DEBUG_RATE(mvm, "actual- lq:%x, ant:%x, SGI:%d\n",
960 tbl_type.lq_type, tbl_type.ant_type,
961 tbl_type.is_SGI);
962 /*
963 * no matching table found, let's by-pass the data collection
964 * and continue to perform rate scale to find the rate table
965 */
966 rs_stay_in_table(lq_sta, true);
967 goto done;
968 }
969
970 /*
971 * Updating the frame history depends on whether packets were
972 * aggregated.
973 *
974 * For aggregation, all packets were transmitted at the same rate, the
975 * first index into rate scale table.
976 */
977 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
978 tx_rate = le32_to_cpu(table->rs_table[0]);
979 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type,
980 &rs_index);
981 rs_collect_tx_data(curr_tbl, rs_index,
982 info->status.ampdu_len,
983 info->status.ampdu_ack_len);
984
985 /* Update success/fail counts if not searching for new mode */
986 if (lq_sta->stay_in_tbl) {
987 lq_sta->total_success += info->status.ampdu_ack_len;
988 lq_sta->total_failed += (info->status.ampdu_len -
989 info->status.ampdu_ack_len);
990 }
991 } else {
992 /*
993 * For legacy, update frame history with for each Tx retry.
994 */
995 retries = info->status.rates[0].count - 1;
996 /* HW doesn't send more than 15 retries */
997 retries = min(retries, 15);
998
999 /* The last transmission may have been successful */
1000 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1001 /* Collect data for each rate used during failed TX attempts */
1002 for (i = 0; i <= retries; ++i) {
1003 tx_rate = le32_to_cpu(table->rs_table[i]);
1004 rs_get_tbl_info_from_mcs(tx_rate, info->band,
1005 &tbl_type, &rs_index);
1006 /*
1007 * Only collect stats if retried rate is in the same RS
1008 * table as active/search.
1009 */
1010 if (table_type_matches(&tbl_type, curr_tbl))
1011 tmp_tbl = curr_tbl;
1012 else if (table_type_matches(&tbl_type, other_tbl))
1013 tmp_tbl = other_tbl;
1014 else
1015 continue;
1016 rs_collect_tx_data(tmp_tbl, rs_index, 1,
1017 i < retries ? 0 : legacy_success);
1018 }
1019
1020 /* Update success/fail counts if not searching for new mode */
1021 if (lq_sta->stay_in_tbl) {
1022 lq_sta->total_success += legacy_success;
1023 lq_sta->total_failed += retries + (1 - legacy_success);
1024 }
1025 }
1026 /* The last TX rate is cached in lq_sta; it's set in if/else above */
1027 lq_sta->last_rate_n_flags = tx_rate;
1028done:
1029 /* See if there's a better rate or modulation mode to try. */
1030 if (sta && sta->supp_rates[sband->band])
1031 rs_rate_scale_perform(mvm, skb, sta, lq_sta);
1032}
1033
1034/*
1035 * Begin a period of staying with a selected modulation mode.
1036 * Set "stay_in_tbl" flag to prevent any mode switches.
1037 * Set frame tx success limits according to legacy vs. high-throughput,
1038 * and reset overall (spanning all rates) tx success history statistics.
1039 * These control how long we stay using same modulation mode before
1040 * searching for a new mode.
1041 */
1042static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
1043 struct iwl_lq_sta *lq_sta)
1044{
1045 IWL_DEBUG_RATE(mvm, "we are staying in the same table\n");
1046 lq_sta->stay_in_tbl = 1; /* only place this gets set */
1047 if (is_legacy) {
1048 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
1049 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
1050 lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;
1051 } else {
1052 lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
1053 lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
1054 lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
1055 }
1056 lq_sta->table_count = 0;
1057 lq_sta->total_failed = 0;
1058 lq_sta->total_success = 0;
1059 lq_sta->flush_timer = jiffies;
1060 lq_sta->action_counter = 0;
1061}
1062
1063/*
1064 * Find correct throughput table for given mode of modulation
1065 */
1066static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1067 struct iwl_scale_tbl_info *tbl)
1068{
1069 /* Used to choose among HT tables */
1070 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
1071
1072 /* Check for invalid LQ type */
1073 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) {
1074 tbl->expected_tpt = expected_tpt_legacy;
1075 return;
1076 }
1077
1078 /* Legacy rates have only one table */
1079 if (is_legacy(tbl->lq_type)) {
1080 tbl->expected_tpt = expected_tpt_legacy;
1081 return;
1082 }
1083
1084 /* Choose among many HT tables depending on number of streams
1085 * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation
1086 * status */
1087 if (is_siso(tbl->lq_type) && !tbl->is_ht40)
1088 ht_tbl_pointer = expected_tpt_siso20MHz;
1089 else if (is_siso(tbl->lq_type))
1090 ht_tbl_pointer = expected_tpt_siso40MHz;
1091 else if (is_mimo2(tbl->lq_type) && !tbl->is_ht40)
1092 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1093 else if (is_mimo2(tbl->lq_type))
1094 ht_tbl_pointer = expected_tpt_mimo2_40MHz;
1095 else if (is_mimo3(tbl->lq_type) && !tbl->is_ht40)
1096 ht_tbl_pointer = expected_tpt_mimo3_20MHz;
1097 else /* if (is_mimo3(tbl->lq_type)) <-- must be true */
1098 ht_tbl_pointer = expected_tpt_mimo3_40MHz;
1099
1100 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */
1101 tbl->expected_tpt = ht_tbl_pointer[0];
1102 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */
1103 tbl->expected_tpt = ht_tbl_pointer[1];
1104 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */
1105 tbl->expected_tpt = ht_tbl_pointer[2];
1106 else /* AGG+SGI */
1107 tbl->expected_tpt = ht_tbl_pointer[3];
1108}
1109
1110/*
1111 * Find starting rate for new "search" high-throughput mode of modulation.
1112 * Goal is to find lowest expected rate (under perfect conditions) that is
1113 * above the current measured throughput of "active" mode, to give new mode
1114 * a fair chance to prove itself without too many challenges.
1115 *
1116 * This gets called when transitioning to more aggressive modulation
1117 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
1118 * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need
1119 * to decrease to match "active" throughput. When moving from MIMO to SISO,
1120 * bit rate will typically need to increase, but not if performance was bad.
1121 */
1122static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1123 struct iwl_lq_sta *lq_sta,
1124 struct iwl_scale_tbl_info *tbl, /* "search" */
1125 u16 rate_mask, s8 index)
1126{
1127 /* "active" values */
1128 struct iwl_scale_tbl_info *active_tbl =
1129 &(lq_sta->lq_info[lq_sta->active_tbl]);
1130 s32 active_sr = active_tbl->win[index].success_ratio;
1131 s32 active_tpt = active_tbl->expected_tpt[index];
1132
1133 /* expected "search" throughput */
1134 s32 *tpt_tbl = tbl->expected_tpt;
1135
1136 s32 new_rate, high, low, start_hi;
1137 u16 high_low;
1138 s8 rate = index;
1139
1140 new_rate = high = low = start_hi = IWL_RATE_INVALID;
1141
1142 while (1) {
1143 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1144 tbl->lq_type);
1145
1146 low = high_low & 0xff;
1147 high = (high_low >> 8) & 0xff;
1148
1149 /*
1150 * Lower the "search" bit rate, to give new "search" mode
1151 * approximately the same throughput as "active" if:
1152 *
1153 * 1) "Active" mode has been working modestly well (but not
1154 * great), and expected "search" throughput (under perfect
1155 * conditions) at candidate rate is above the actual
1156 * measured "active" throughput (but less than expected
1157 * "active" throughput under perfect conditions).
1158 * OR
1159 * 2) "Active" mode has been working perfectly or very well
1160 * and expected "search" throughput (under perfect
1161 * conditions) at candidate rate is above expected
1162 * "active" throughput (under perfect conditions).
1163 */
1164 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
1165 ((active_sr > IWL_RATE_DECREASE_TH) &&
1166 (active_sr <= IWL_RATE_HIGH_TH) &&
1167 (tpt_tbl[rate] <= active_tpt))) ||
1168 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
1169 (tpt_tbl[rate] > active_tpt))) {
1170 /* (2nd or later pass)
1171 * If we've already tried to raise the rate, and are
1172 * now trying to lower it, use the higher rate. */
1173 if (start_hi != IWL_RATE_INVALID) {
1174 new_rate = start_hi;
1175 break;
1176 }
1177
1178 new_rate = rate;
1179
1180 /* Loop again with lower rate */
1181 if (low != IWL_RATE_INVALID)
1182 rate = low;
1183
1184 /* Lower rate not available, use the original */
1185 else
1186 break;
1187
1188 /* Else try to raise the "search" rate to match "active" */
1189 } else {
1190 /* (2nd or later pass)
1191 * If we've already tried to lower the rate, and are
1192 * now trying to raise it, use the lower rate. */
1193 if (new_rate != IWL_RATE_INVALID)
1194 break;
1195
1196 /* Loop again with higher rate */
1197 else if (high != IWL_RATE_INVALID) {
1198 start_hi = high;
1199 rate = high;
1200
1201 /* Higher rate not available, use the original */
1202 } else {
1203 new_rate = rate;
1204 break;
1205 }
1206 }
1207 }
1208
1209 return new_rate;
1210}
1211
1212static bool iwl_is_ht40_tx_allowed(struct iwl_mvm *mvm,
1213 struct ieee80211_sta_ht_cap *ht_cap)
1214{
1215 /*
1216 * Remainder of this function checks ht_cap, but if it's
1217 * NULL then we can do HT40 (special case for RXON)
1218 */
1219 if (!ht_cap)
1220 return true;
1221
1222 if (!ht_cap->ht_supported)
1223 return false;
1224
1225 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
1226 return false;
1227
1228 return true;
1229}
1230
1231/*
1232 * Set up search table for MIMO2
1233 */
1234static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1235 struct iwl_lq_sta *lq_sta,
1236 struct ieee80211_sta *sta,
1237 struct iwl_scale_tbl_info *tbl, int index)
1238{
1239 u16 rate_mask;
1240 s32 rate;
1241 s8 is_green = lq_sta->is_green;
1242
1243 if (!sta->ht_cap.ht_supported)
1244 return -1;
1245
1246 if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
1247 == WLAN_HT_CAP_SM_PS_STATIC)
1248 return -1;
1249
1250 /* Need both Tx chains/antennas to support MIMO */
1251 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2)
1252 return -1;
1253
1254 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
1255
1256 tbl->lq_type = LQ_MIMO2;
1257 tbl->action = 0;
1258 tbl->max_search = IWL_MAX_SEARCH;
1259 rate_mask = lq_sta->active_mimo2_rate;
1260
1261 if (iwl_is_ht40_tx_allowed(mvm, &sta->ht_cap))
1262 tbl->is_ht40 = 1;
1263 else
1264 tbl->is_ht40 = 0;
1265
1266 rs_set_expected_tpt_table(lq_sta, tbl);
1267
1268 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1269
1270 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 best rate %d mask %X\n",
1271 rate, rate_mask);
1272 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1273 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1274 rate, rate_mask);
1275 return -1;
1276 }
1277 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1278
1279 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1280 tbl->current_rate, is_green);
1281 return 0;
1282}
1283
1284/*
1285 * Set up search table for MIMO3
1286 */
1287static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
1288 struct iwl_lq_sta *lq_sta,
1289 struct ieee80211_sta *sta,
1290 struct iwl_scale_tbl_info *tbl, int index)
1291{
1292 u16 rate_mask;
1293 s32 rate;
1294 s8 is_green = lq_sta->is_green;
1295
1296 if (!sta->ht_cap.ht_supported)
1297 return -1;
1298
1299 if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
1300 == WLAN_HT_CAP_SM_PS_STATIC)
1301 return -1;
1302
1303 /* Need both Tx chains/antennas to support MIMO */
1304 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3)
1305 return -1;
1306
1307 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n");
1308
1309 tbl->lq_type = LQ_MIMO3;
1310 tbl->action = 0;
1311 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
1312 rate_mask = lq_sta->active_mimo3_rate;
1313
1314 if (iwl_is_ht40_tx_allowed(mvm, &sta->ht_cap))
1315 tbl->is_ht40 = 1;
1316 else
1317 tbl->is_ht40 = 0;
1318
1319 rs_set_expected_tpt_table(lq_sta, tbl);
1320
1321 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1322
1323 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 best rate %d mask %X\n",
1324 rate, rate_mask);
1325 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1326 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1327 rate, rate_mask);
1328 return -1;
1329 }
1330 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1331
1332 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1333 tbl->current_rate, is_green);
1334 return 0;
1335}
1336
1337/*
1338 * Set up search table for SISO
1339 */
1340static int rs_switch_to_siso(struct iwl_mvm *mvm,
1341 struct iwl_lq_sta *lq_sta,
1342 struct ieee80211_sta *sta,
1343 struct iwl_scale_tbl_info *tbl, int index)
1344{
1345 u16 rate_mask;
1346 u8 is_green = lq_sta->is_green;
1347 s32 rate;
1348
1349 if (!sta->ht_cap.ht_supported)
1350 return -1;
1351
1352 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n");
1353
1354 tbl->lq_type = LQ_SISO;
1355 tbl->action = 0;
1356 tbl->max_search = IWL_MAX_SEARCH;
1357 rate_mask = lq_sta->active_siso_rate;
1358
1359 if (iwl_is_ht40_tx_allowed(mvm, &sta->ht_cap))
1360 tbl->is_ht40 = 1;
1361 else
1362 tbl->is_ht40 = 0;
1363
1364 if (is_green)
1365 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
1366
1367 rs_set_expected_tpt_table(lq_sta, tbl);
1368 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1369
1370 IWL_DEBUG_RATE(mvm, "LQ: get best rate %d mask %X\n", rate, rate_mask);
1371 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1372 IWL_DEBUG_RATE(mvm,
1373 "can not switch with index %d rate mask %x\n",
1374 rate, rate_mask);
1375 return -1;
1376 }
1377 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1378 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1379 tbl->current_rate, is_green);
1380 return 0;
1381}
1382
1383/*
1384 * Try to switch to new modulation mode from legacy
1385 */
1386static int rs_move_legacy_other(struct iwl_mvm *mvm,
1387 struct iwl_lq_sta *lq_sta,
1388 struct ieee80211_sta *sta,
1389 int index)
1390{
1391 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1392 struct iwl_scale_tbl_info *search_tbl =
1393 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1394 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1395 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1396 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1397 u8 start_action;
1398 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1399 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1400 int ret;
1401 u8 update_search_tbl_counter = 0;
1402
1403 start_action = tbl->action;
1404 while (1) {
1405 lq_sta->action_counter++;
1406 switch (tbl->action) {
1407 case IWL_LEGACY_SWITCH_ANTENNA1:
1408 case IWL_LEGACY_SWITCH_ANTENNA2:
1409 IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n");
1410
1411 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
1412 tx_chains_num <= 1) ||
1413 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
1414 tx_chains_num <= 2))
1415 break;
1416
1417 /* Don't change antenna if success has been great */
1418 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1419 break;
1420
1421 /* Set up search table to try other antenna */
1422 memcpy(search_tbl, tbl, sz);
1423
1424 if (rs_toggle_antenna(valid_tx_ant,
1425 &search_tbl->current_rate,
1426 search_tbl)) {
1427 update_search_tbl_counter = 1;
1428 rs_set_expected_tpt_table(lq_sta, search_tbl);
1429 goto out;
1430 }
1431 break;
1432 case IWL_LEGACY_SWITCH_SISO:
1433 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to SISO\n");
1434
1435 /* Set up search table to try SISO */
1436 memcpy(search_tbl, tbl, sz);
1437 search_tbl->is_SGI = 0;
1438 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1439 search_tbl, index);
1440 if (!ret) {
1441 lq_sta->action_counter = 0;
1442 goto out;
1443 }
1444
1445 break;
1446 case IWL_LEGACY_SWITCH_MIMO2_AB:
1447 case IWL_LEGACY_SWITCH_MIMO2_AC:
1448 case IWL_LEGACY_SWITCH_MIMO2_BC:
1449 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO2\n");
1450
1451 /* Set up search table to try MIMO */
1452 memcpy(search_tbl, tbl, sz);
1453 search_tbl->is_SGI = 0;
1454
1455 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)
1456 search_tbl->ant_type = ANT_AB;
1457 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
1458 search_tbl->ant_type = ANT_AC;
1459 else
1460 search_tbl->ant_type = ANT_BC;
1461
1462 if (!rs_is_valid_ant(valid_tx_ant,
1463 search_tbl->ant_type))
1464 break;
1465
1466 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1467 search_tbl, index);
1468 if (!ret) {
1469 lq_sta->action_counter = 0;
1470 goto out;
1471 }
1472 break;
1473
1474 case IWL_LEGACY_SWITCH_MIMO3_ABC:
1475 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO3\n");
1476
1477 /* Set up search table to try MIMO3 */
1478 memcpy(search_tbl, tbl, sz);
1479 search_tbl->is_SGI = 0;
1480
1481 search_tbl->ant_type = ANT_ABC;
1482
1483 if (!rs_is_valid_ant(valid_tx_ant,
1484 search_tbl->ant_type))
1485 break;
1486
1487 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1488 search_tbl, index);
1489 if (!ret) {
1490 lq_sta->action_counter = 0;
1491 goto out;
1492 }
1493 break;
1494 }
1495 tbl->action++;
1496 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1497 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1498
1499 if (tbl->action == start_action)
1500 break;
1501 }
1502 search_tbl->lq_type = LQ_NONE;
1503 return 0;
1504
1505out:
1506 lq_sta->search_better_tbl = 1;
1507 tbl->action++;
1508 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1509 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1510 if (update_search_tbl_counter)
1511 search_tbl->action = tbl->action;
1512 return 0;
1513}
1514
1515/*
1516 * Try to switch to new modulation mode from SISO
1517 */
1518static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1519 struct iwl_lq_sta *lq_sta,
1520 struct ieee80211_sta *sta, int index)
1521{
1522 u8 is_green = lq_sta->is_green;
1523 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1524 struct iwl_scale_tbl_info *search_tbl =
1525 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1526 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1527 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1528 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1529 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1530 u8 start_action;
1531 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1532 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1533 u8 update_search_tbl_counter = 0;
1534 int ret;
1535
1536 start_action = tbl->action;
1537 while (1) {
1538 lq_sta->action_counter++;
1539 switch (tbl->action) {
1540 case IWL_SISO_SWITCH_ANTENNA1:
1541 case IWL_SISO_SWITCH_ANTENNA2:
1542 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n");
1543 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1544 tx_chains_num <= 1) ||
1545 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1546 tx_chains_num <= 2))
1547 break;
1548
1549 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1550 break;
1551
1552 memcpy(search_tbl, tbl, sz);
1553 if (rs_toggle_antenna(valid_tx_ant,
1554 &search_tbl->current_rate,
1555 search_tbl)) {
1556 update_search_tbl_counter = 1;
1557 goto out;
1558 }
1559 break;
1560 case IWL_SISO_SWITCH_MIMO2_AB:
1561 case IWL_SISO_SWITCH_MIMO2_AC:
1562 case IWL_SISO_SWITCH_MIMO2_BC:
1563 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n");
1564 memcpy(search_tbl, tbl, sz);
1565 search_tbl->is_SGI = 0;
1566
1567 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)
1568 search_tbl->ant_type = ANT_AB;
1569 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
1570 search_tbl->ant_type = ANT_AC;
1571 else
1572 search_tbl->ant_type = ANT_BC;
1573
1574 if (!rs_is_valid_ant(valid_tx_ant,
1575 search_tbl->ant_type))
1576 break;
1577
1578 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1579 search_tbl, index);
1580 if (!ret)
1581 goto out;
1582 break;
1583 case IWL_SISO_SWITCH_GI:
1584 if (!tbl->is_ht40 && !(ht_cap->cap &
1585 IEEE80211_HT_CAP_SGI_20))
1586 break;
1587 if (tbl->is_ht40 && !(ht_cap->cap &
1588 IEEE80211_HT_CAP_SGI_40))
1589 break;
1590
1591 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n");
1592
1593 memcpy(search_tbl, tbl, sz);
1594 if (is_green) {
1595 if (!tbl->is_SGI)
1596 break;
1597 else
1598 IWL_ERR(mvm,
1599 "SGI was set in GF+SISO\n");
1600 }
1601 search_tbl->is_SGI = !tbl->is_SGI;
1602 rs_set_expected_tpt_table(lq_sta, search_tbl);
1603 if (tbl->is_SGI) {
1604 s32 tpt = lq_sta->last_tpt / 100;
1605 if (tpt >= search_tbl->expected_tpt[index])
1606 break;
1607 }
1608 search_tbl->current_rate =
1609 rate_n_flags_from_tbl(mvm, search_tbl,
1610 index, is_green);
1611 update_search_tbl_counter = 1;
1612 goto out;
1613 case IWL_SISO_SWITCH_MIMO3_ABC:
1614 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO3\n");
1615 memcpy(search_tbl, tbl, sz);
1616 search_tbl->is_SGI = 0;
1617 search_tbl->ant_type = ANT_ABC;
1618
1619 if (!rs_is_valid_ant(valid_tx_ant,
1620 search_tbl->ant_type))
1621 break;
1622
1623 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1624 search_tbl, index);
1625 if (!ret)
1626 goto out;
1627 break;
1628 }
1629 tbl->action++;
1630 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1631 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1632
1633 if (tbl->action == start_action)
1634 break;
1635 }
1636 search_tbl->lq_type = LQ_NONE;
1637 return 0;
1638
1639 out:
1640 lq_sta->search_better_tbl = 1;
1641 tbl->action++;
1642 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
1643 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1644 if (update_search_tbl_counter)
1645 search_tbl->action = tbl->action;
1646
1647 return 0;
1648}
1649
1650/*
1651 * Try to switch to new modulation mode from MIMO2
1652 */
1653static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1654 struct iwl_lq_sta *lq_sta,
1655 struct ieee80211_sta *sta, int index)
1656{
1657 s8 is_green = lq_sta->is_green;
1658 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1659 struct iwl_scale_tbl_info *search_tbl =
1660 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1661 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1662 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1663 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1664 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1665 u8 start_action;
1666 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1667 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1668 u8 update_search_tbl_counter = 0;
1669 int ret;
1670
1671 start_action = tbl->action;
1672 while (1) {
1673 lq_sta->action_counter++;
1674 switch (tbl->action) {
1675 case IWL_MIMO2_SWITCH_ANTENNA1:
1676 case IWL_MIMO2_SWITCH_ANTENNA2:
1677 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle Antennas\n");
1678
1679 if (tx_chains_num <= 2)
1680 break;
1681
1682 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1683 break;
1684
1685 memcpy(search_tbl, tbl, sz);
1686 if (rs_toggle_antenna(valid_tx_ant,
1687 &search_tbl->current_rate,
1688 search_tbl)) {
1689 update_search_tbl_counter = 1;
1690 goto out;
1691 }
1692 break;
1693 case IWL_MIMO2_SWITCH_SISO_A:
1694 case IWL_MIMO2_SWITCH_SISO_B:
1695 case IWL_MIMO2_SWITCH_SISO_C:
1696 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n");
1697
1698 /* Set up new search table for SISO */
1699 memcpy(search_tbl, tbl, sz);
1700
1701 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1702 search_tbl->ant_type = ANT_A;
1703 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1704 search_tbl->ant_type = ANT_B;
1705 else
1706 search_tbl->ant_type = ANT_C;
1707
1708 if (!rs_is_valid_ant(valid_tx_ant,
1709 search_tbl->ant_type))
1710 break;
1711
1712 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1713 search_tbl, index);
1714 if (!ret)
1715 goto out;
1716
1717 break;
1718
1719 case IWL_MIMO2_SWITCH_GI:
1720 if (!tbl->is_ht40 && !(ht_cap->cap &
1721 IEEE80211_HT_CAP_SGI_20))
1722 break;
1723 if (tbl->is_ht40 && !(ht_cap->cap &
1724 IEEE80211_HT_CAP_SGI_40))
1725 break;
1726
1727 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n");
1728
1729 /* Set up new search table for MIMO2 */
1730 memcpy(search_tbl, tbl, sz);
1731 search_tbl->is_SGI = !tbl->is_SGI;
1732 rs_set_expected_tpt_table(lq_sta, search_tbl);
1733 /*
1734 * If active table already uses the fastest possible
1735 * modulation (dual stream with short guard interval),
1736 * and it's working well, there's no need to look
1737 * for a better type of modulation!
1738 */
1739 if (tbl->is_SGI) {
1740 s32 tpt = lq_sta->last_tpt / 100;
1741 if (tpt >= search_tbl->expected_tpt[index])
1742 break;
1743 }
1744 search_tbl->current_rate =
1745 rate_n_flags_from_tbl(mvm, search_tbl,
1746 index, is_green);
1747 update_search_tbl_counter = 1;
1748 goto out;
1749
1750 case IWL_MIMO2_SWITCH_MIMO3_ABC:
1751 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to MIMO3\n");
1752 memcpy(search_tbl, tbl, sz);
1753 search_tbl->is_SGI = 0;
1754 search_tbl->ant_type = ANT_ABC;
1755
1756 if (!rs_is_valid_ant(valid_tx_ant,
1757 search_tbl->ant_type))
1758 break;
1759
1760 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1761 search_tbl, index);
1762 if (!ret)
1763 goto out;
1764
1765 break;
1766 }
1767 tbl->action++;
1768 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
1769 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1770
1771 if (tbl->action == start_action)
1772 break;
1773 }
1774 search_tbl->lq_type = LQ_NONE;
1775 return 0;
1776 out:
1777 lq_sta->search_better_tbl = 1;
1778 tbl->action++;
1779 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
1780 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1781 if (update_search_tbl_counter)
1782 search_tbl->action = tbl->action;
1783
1784 return 0;
1785}
1786
1787/*
1788 * Try to switch to new modulation mode from MIMO3
1789 */
1790static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
1791 struct iwl_lq_sta *lq_sta,
1792 struct ieee80211_sta *sta, int index)
1793{
1794 s8 is_green = lq_sta->is_green;
1795 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1796 struct iwl_scale_tbl_info *search_tbl =
1797 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1798 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1799 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1800 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1801 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1802 u8 start_action;
1803 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
1804 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1805 int ret;
1806 u8 update_search_tbl_counter = 0;
1807
1808 start_action = tbl->action;
1809 while (1) {
1810 lq_sta->action_counter++;
1811 switch (tbl->action) {
1812 case IWL_MIMO3_SWITCH_ANTENNA1:
1813 case IWL_MIMO3_SWITCH_ANTENNA2:
1814 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 toggle Antennas\n");
1815
1816 if (tx_chains_num <= 3)
1817 break;
1818
1819 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1820 break;
1821
1822 memcpy(search_tbl, tbl, sz);
1823 if (rs_toggle_antenna(valid_tx_ant,
1824 &search_tbl->current_rate,
1825 search_tbl))
1826 goto out;
1827 break;
1828 case IWL_MIMO3_SWITCH_SISO_A:
1829 case IWL_MIMO3_SWITCH_SISO_B:
1830 case IWL_MIMO3_SWITCH_SISO_C:
1831 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 switch to SISO\n");
1832
1833 /* Set up new search table for SISO */
1834 memcpy(search_tbl, tbl, sz);
1835
1836 if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
1837 search_tbl->ant_type = ANT_A;
1838 else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
1839 search_tbl->ant_type = ANT_B;
1840 else
1841 search_tbl->ant_type = ANT_C;
1842
1843 if (!rs_is_valid_ant(valid_tx_ant,
1844 search_tbl->ant_type))
1845 break;
1846
1847 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1848 search_tbl, index);
1849 if (!ret)
1850 goto out;
1851
1852 break;
1853
1854 case IWL_MIMO3_SWITCH_MIMO2_AB:
1855 case IWL_MIMO3_SWITCH_MIMO2_AC:
1856 case IWL_MIMO3_SWITCH_MIMO2_BC:
1857 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 switch to MIMO2\n");
1858
1859 memcpy(search_tbl, tbl, sz);
1860 search_tbl->is_SGI = 0;
1861 if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
1862 search_tbl->ant_type = ANT_AB;
1863 else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
1864 search_tbl->ant_type = ANT_AC;
1865 else
1866 search_tbl->ant_type = ANT_BC;
1867
1868 if (!rs_is_valid_ant(valid_tx_ant,
1869 search_tbl->ant_type))
1870 break;
1871
1872 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1873 search_tbl, index);
1874 if (!ret)
1875 goto out;
1876
1877 break;
1878
1879 case IWL_MIMO3_SWITCH_GI:
1880 if (!tbl->is_ht40 && !(ht_cap->cap &
1881 IEEE80211_HT_CAP_SGI_20))
1882 break;
1883 if (tbl->is_ht40 && !(ht_cap->cap &
1884 IEEE80211_HT_CAP_SGI_40))
1885 break;
1886
1887 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 toggle SGI/NGI\n");
1888
1889 /* Set up new search table for MIMO */
1890 memcpy(search_tbl, tbl, sz);
1891 search_tbl->is_SGI = !tbl->is_SGI;
1892 rs_set_expected_tpt_table(lq_sta, search_tbl);
1893 /*
1894 * If active table already uses the fastest possible
1895 * modulation (dual stream with short guard interval),
1896 * and it's working well, there's no need to look
1897 * for a better type of modulation!
1898 */
1899 if (tbl->is_SGI) {
1900 s32 tpt = lq_sta->last_tpt / 100;
1901 if (tpt >= search_tbl->expected_tpt[index])
1902 break;
1903 }
1904 search_tbl->current_rate =
1905 rate_n_flags_from_tbl(mvm, search_tbl,
1906 index, is_green);
1907 update_search_tbl_counter = 1;
1908 goto out;
1909 }
1910 tbl->action++;
1911 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1912 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1913
1914 if (tbl->action == start_action)
1915 break;
1916 }
1917 search_tbl->lq_type = LQ_NONE;
1918 return 0;
1919 out:
1920 lq_sta->search_better_tbl = 1;
1921 tbl->action++;
1922 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1923 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1924 if (update_search_tbl_counter)
1925 search_tbl->action = tbl->action;
1926
1927 return 0;
1928}
1929
1930/*
1931 * Check whether we should continue using same modulation mode, or
1932 * begin search for a new mode, based on:
1933 * 1) # tx successes or failures while using this mode
1934 * 2) # times calling this function
1935 * 3) elapsed time in this mode (not used, for now)
1936 */
1937static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1938{
1939 struct iwl_scale_tbl_info *tbl;
1940 int i;
1941 int active_tbl;
1942 int flush_interval_passed = 0;
1943 struct iwl_mvm *mvm;
1944
1945 mvm = lq_sta->drv;
1946 active_tbl = lq_sta->active_tbl;
1947
1948 tbl = &(lq_sta->lq_info[active_tbl]);
1949
1950 /* If we've been disallowing search, see if we should now allow it */
1951 if (lq_sta->stay_in_tbl) {
1952 /* Elapsed time using current modulation mode */
1953 if (lq_sta->flush_timer)
1954 flush_interval_passed =
1955 time_after(jiffies,
1956 (unsigned long)(lq_sta->flush_timer +
1957 IWL_RATE_SCALE_FLUSH_INTVL));
1958
1959 /*
1960 * Check if we should allow search for new modulation mode.
1961 * If many frames have failed or succeeded, or we've used
1962 * this same modulation for a long time, allow search, and
1963 * reset history stats that keep track of whether we should
1964 * allow a new search. Also (below) reset all bitmaps and
1965 * stats in active history.
1966 */
1967 if (force_search ||
1968 (lq_sta->total_failed > lq_sta->max_failure_limit) ||
1969 (lq_sta->total_success > lq_sta->max_success_limit) ||
1970 ((!lq_sta->search_better_tbl) &&
1971 (lq_sta->flush_timer) && (flush_interval_passed))) {
1972 IWL_DEBUG_RATE(mvm,
1973 "LQ: stay is expired %d %d %d\n",
1974 lq_sta->total_failed,
1975 lq_sta->total_success,
1976 flush_interval_passed);
1977
1978 /* Allow search for new mode */
1979 lq_sta->stay_in_tbl = 0; /* only place reset */
1980 lq_sta->total_failed = 0;
1981 lq_sta->total_success = 0;
1982 lq_sta->flush_timer = 0;
1983 /*
1984 * Else if we've used this modulation mode enough repetitions
1985 * (regardless of elapsed time or success/failure), reset
1986 * history bitmaps and rate-specific stats for all rates in
1987 * active table.
1988 */
1989 } else {
1990 lq_sta->table_count++;
1991 if (lq_sta->table_count >=
1992 lq_sta->table_count_limit) {
1993 lq_sta->table_count = 0;
1994
1995 IWL_DEBUG_RATE(mvm,
1996 "LQ: stay in table clear win\n");
1997 for (i = 0; i < IWL_RATE_COUNT; i++)
1998 rs_rate_scale_clear_window(
1999 &(tbl->win[i]));
2000 }
2001 }
2002
2003 /* If transitioning to allow "search", reset all history
2004 * bitmaps and stats in active table (this will become the new
2005 * "search" table). */
2006 if (!lq_sta->stay_in_tbl) {
2007 for (i = 0; i < IWL_RATE_COUNT; i++)
2008 rs_rate_scale_clear_window(&(tbl->win[i]));
2009 }
2010 }
2011}
2012
2013/*
2014 * setup rate table in uCode
2015 */
2016static void rs_update_rate_tbl(struct iwl_mvm *mvm,
2017 struct iwl_lq_sta *lq_sta,
2018 struct iwl_scale_tbl_info *tbl,
2019 int index, u8 is_green)
2020{
2021 u32 rate;
2022
2023 /* Update uCode's rate table. */
2024 rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green);
2025 rs_fill_link_cmd(mvm, lq_sta, rate);
2026 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2027}
2028
2029/*
2030 * Do rate scaling and search for new modulation mode.
2031 */
2032static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2033 struct sk_buff *skb,
2034 struct ieee80211_sta *sta,
2035 struct iwl_lq_sta *lq_sta)
2036{
2037 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2038 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2039 int low = IWL_RATE_INVALID;
2040 int high = IWL_RATE_INVALID;
2041 int index;
2042 int i;
2043 struct iwl_rate_scale_data *window = NULL;
2044 int current_tpt = IWL_INVALID_VALUE;
2045 int low_tpt = IWL_INVALID_VALUE;
2046 int high_tpt = IWL_INVALID_VALUE;
2047 u32 fail_count;
2048 s8 scale_action = 0;
2049 u16 rate_mask;
2050 u8 update_lq = 0;
2051 struct iwl_scale_tbl_info *tbl, *tbl1;
2052 u16 rate_scale_index_msk = 0;
2053 u8 is_green = 0;
2054 u8 active_tbl = 0;
2055 u8 done_search = 0;
2056 u16 high_low;
2057 s32 sr;
2058 u8 tid = IWL_MAX_TID_COUNT;
2059 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
2060 struct iwl_mvm_tid_data *tid_data;
2061
2062 IWL_DEBUG_RATE(mvm, "rate scale calculate new rate for skb\n");
2063
2064 /* Send management frames and NO_ACK data using lowest rate. */
2065 /* TODO: this could probably be improved.. */
2066 if (!ieee80211_is_data(hdr->frame_control) ||
2067 info->flags & IEEE80211_TX_CTL_NO_ACK)
2068 return;
2069
2070 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
2071
2072 tid = rs_tl_add_packet(lq_sta, hdr);
2073 if ((tid != IWL_MAX_TID_COUNT) &&
2074 (lq_sta->tx_agg_tid_en & (1 << tid))) {
2075 tid_data = &sta_priv->tid_data[tid];
2076 if (tid_data->state == IWL_AGG_OFF)
2077 lq_sta->is_agg = 0;
2078 else
2079 lq_sta->is_agg = 1;
2080 } else {
2081 lq_sta->is_agg = 0;
2082 }
2083
2084 /*
2085 * Select rate-scale / modulation-mode table to work with in
2086 * the rest of this function: "search" if searching for better
2087 * modulation mode, or "active" if doing rate scaling within a mode.
2088 */
2089 if (!lq_sta->search_better_tbl)
2090 active_tbl = lq_sta->active_tbl;
2091 else
2092 active_tbl = 1 - lq_sta->active_tbl;
2093
2094 tbl = &(lq_sta->lq_info[active_tbl]);
2095 if (is_legacy(tbl->lq_type))
2096 lq_sta->is_green = 0;
2097 else
2098 lq_sta->is_green = rs_use_green(sta);
2099 is_green = lq_sta->is_green;
2100
2101 /* current tx rate */
2102 index = lq_sta->last_txrate_idx;
2103
2104 IWL_DEBUG_RATE(mvm, "Rate scale index %d for type %d\n", index,
2105 tbl->lq_type);
2106
2107 /* rates available for this association, and for modulation mode */
2108 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
2109
2110 IWL_DEBUG_RATE(mvm, "mask 0x%04X\n", rate_mask);
2111
2112 /* mask with station rate restriction */
2113 if (is_legacy(tbl->lq_type)) {
2114 if (lq_sta->band == IEEE80211_BAND_5GHZ)
2115 /* supp_rates has no CCK bits in A mode */
2116 rate_scale_index_msk = (u16) (rate_mask &
2117 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
2118 else
2119 rate_scale_index_msk = (u16) (rate_mask &
2120 lq_sta->supp_rates);
2121
2122 } else {
2123 rate_scale_index_msk = rate_mask;
2124 }
2125
2126 if (!rate_scale_index_msk)
2127 rate_scale_index_msk = rate_mask;
2128
2129 if (!((1 << index) & rate_scale_index_msk)) {
2130 IWL_ERR(mvm, "Current Rate is not valid\n");
2131 if (lq_sta->search_better_tbl) {
2132 /* revert to active table if search table is not valid*/
2133 tbl->lq_type = LQ_NONE;
2134 lq_sta->search_better_tbl = 0;
2135 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2136 /* get "active" rate info */
2137 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2138 rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green);
2139 }
2140 return;
2141 }
2142
2143 /* Get expected throughput table and history window for current rate */
2144 if (!tbl->expected_tpt) {
2145 IWL_ERR(mvm, "tbl->expected_tpt is NULL\n");
2146 return;
2147 }
2148
2149 /* force user max rate if set by user */
2150 if ((lq_sta->max_rate_idx != -1) &&
2151 (lq_sta->max_rate_idx < index)) {
2152 index = lq_sta->max_rate_idx;
2153 update_lq = 1;
2154 window = &(tbl->win[index]);
2155 goto lq_update;
2156 }
2157
2158 window = &(tbl->win[index]);
2159
2160 /*
2161 * If there is not enough history to calculate actual average
2162 * throughput, keep analyzing results of more tx frames, without
2163 * changing rate or mode (bypass most of the rest of this function).
2164 * Set up new rate table in uCode only if old rate is not supported
2165 * in current association (use new rate found above).
2166 */
2167 fail_count = window->counter - window->success_counter;
2168 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
2169 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
2170 IWL_DEBUG_RATE(mvm,
2171 "LQ: still below TH. succ=%d total=%d for index %d\n",
2172 window->success_counter, window->counter, index);
2173
2174 /* Can't calculate this yet; not enough history */
2175 window->average_tpt = IWL_INVALID_VALUE;
2176
2177 /* Should we stay with this modulation mode,
2178 * or search for a new one? */
2179 rs_stay_in_table(lq_sta, false);
2180
2181 goto out;
2182 }
2183 /* Else we have enough samples; calculate estimate of
2184 * actual average throughput */
2185 if (window->average_tpt != ((window->success_ratio *
2186 tbl->expected_tpt[index] + 64) / 128)) {
2187 IWL_ERR(mvm,
2188 "expected_tpt should have been calculated by now\n");
2189 window->average_tpt = ((window->success_ratio *
2190 tbl->expected_tpt[index] + 64) / 128);
2191 }
2192
2193 /* If we are searching for better modulation mode, check success. */
2194 if (lq_sta->search_better_tbl) {
2195 /* If good success, continue using the "search" mode;
2196 * no need to send new link quality command, since we're
2197 * continuing to use the setup that we've been trying. */
2198 if (window->average_tpt > lq_sta->last_tpt) {
2199 IWL_DEBUG_RATE(mvm,
2200 "LQ: SWITCHING TO NEW TABLE suc=%d cur-tpt=%d old-tpt=%d\n",
2201 window->success_ratio,
2202 window->average_tpt,
2203 lq_sta->last_tpt);
2204
2205 if (!is_legacy(tbl->lq_type))
2206 lq_sta->enable_counter = 1;
2207
2208 /* Swap tables; "search" becomes "active" */
2209 lq_sta->active_tbl = active_tbl;
2210 current_tpt = window->average_tpt;
2211 /* Else poor success; go back to mode in "active" table */
2212 } else {
2213 IWL_DEBUG_RATE(mvm,
2214 "LQ: GOING BACK TO THE OLD TABLE suc=%d cur-tpt=%d old-tpt=%d\n",
2215 window->success_ratio,
2216 window->average_tpt,
2217 lq_sta->last_tpt);
2218
2219 /* Nullify "search" table */
2220 tbl->lq_type = LQ_NONE;
2221
2222 /* Revert to "active" table */
2223 active_tbl = lq_sta->active_tbl;
2224 tbl = &(lq_sta->lq_info[active_tbl]);
2225
2226 /* Revert to "active" rate and throughput info */
2227 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2228 current_tpt = lq_sta->last_tpt;
2229
2230 /* Need to set up a new rate table in uCode */
2231 update_lq = 1;
2232 }
2233
2234 /* Either way, we've made a decision; modulation mode
2235 * search is done, allow rate adjustment next time. */
2236 lq_sta->search_better_tbl = 0;
2237 done_search = 1; /* Don't switch modes below! */
2238 goto lq_update;
2239 }
2240
2241 /* (Else) not in search of better modulation mode, try for better
2242 * starting rate, while staying in this mode. */
2243 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk,
2244 tbl->lq_type);
2245 low = high_low & 0xff;
2246 high = (high_low >> 8) & 0xff;
2247
2248 /* If user set max rate, dont allow higher than user constrain */
2249 if ((lq_sta->max_rate_idx != -1) &&
2250 (lq_sta->max_rate_idx < high))
2251 high = IWL_RATE_INVALID;
2252
2253 sr = window->success_ratio;
2254
2255 /* Collect measured throughputs for current and adjacent rates */
2256 current_tpt = window->average_tpt;
2257 if (low != IWL_RATE_INVALID)
2258 low_tpt = tbl->win[low].average_tpt;
2259 if (high != IWL_RATE_INVALID)
2260 high_tpt = tbl->win[high].average_tpt;
2261
2262 scale_action = 0;
2263
2264 /* Too many failures, decrease rate */
2265 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
2266 IWL_DEBUG_RATE(mvm,
2267 "decrease rate because of low success_ratio\n");
2268 scale_action = -1;
2269 /* No throughput measured yet for adjacent rates; try increase. */
2270 } else if ((low_tpt == IWL_INVALID_VALUE) &&
2271 (high_tpt == IWL_INVALID_VALUE)) {
2272 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
2273 scale_action = 1;
2274 else if (low != IWL_RATE_INVALID)
2275 scale_action = 0;
2276 }
2277
2278 /* Both adjacent throughputs are measured, but neither one has better
2279 * throughput; we're using the best rate, don't change it! */
2280 else if ((low_tpt != IWL_INVALID_VALUE) &&
2281 (high_tpt != IWL_INVALID_VALUE) &&
2282 (low_tpt < current_tpt) &&
2283 (high_tpt < current_tpt))
2284 scale_action = 0;
2285
2286 /* At least one adjacent rate's throughput is measured,
2287 * and may have better performance. */
2288 else {
2289 /* Higher adjacent rate's throughput is measured */
2290 if (high_tpt != IWL_INVALID_VALUE) {
2291 /* Higher rate has better throughput */
2292 if (high_tpt > current_tpt &&
2293 sr >= IWL_RATE_INCREASE_TH) {
2294 scale_action = 1;
2295 } else {
2296 scale_action = 0;
2297 }
2298
2299 /* Lower adjacent rate's throughput is measured */
2300 } else if (low_tpt != IWL_INVALID_VALUE) {
2301 /* Lower rate has better throughput */
2302 if (low_tpt > current_tpt) {
2303 IWL_DEBUG_RATE(mvm,
2304 "decrease rate because of low tpt\n");
2305 scale_action = -1;
2306 } else if (sr >= IWL_RATE_INCREASE_TH) {
2307 scale_action = 1;
2308 }
2309 }
2310 }
2311
2312 /* Sanity check; asked for decrease, but success rate or throughput
2313 * has been good at old rate. Don't change it. */
2314 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
2315 ((sr > IWL_RATE_HIGH_TH) ||
2316 (current_tpt > (100 * tbl->expected_tpt[low]))))
2317 scale_action = 0;
2318
2319 switch (scale_action) {
2320 case -1:
2321 /* Decrease starting rate, update uCode's rate table */
2322 if (low != IWL_RATE_INVALID) {
2323 update_lq = 1;
2324 index = low;
2325 }
2326
2327 break;
2328 case 1:
2329 /* Increase starting rate, update uCode's rate table */
2330 if (high != IWL_RATE_INVALID) {
2331 update_lq = 1;
2332 index = high;
2333 }
2334
2335 break;
2336 case 0:
2337 /* No change */
2338 default:
2339 break;
2340 }
2341
2342 IWL_DEBUG_RATE(mvm,
2343 "choose rate scale index %d action %d low %d high %d type %d\n",
2344 index, scale_action, low, high, tbl->lq_type);
2345
2346lq_update:
2347 /* Replace uCode's rate table for the destination station. */
2348 if (update_lq)
2349 rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green);
2350
2351 rs_stay_in_table(lq_sta, false);
2352
2353 /*
2354 * Search for new modulation mode if we're:
2355 * 1) Not changing rates right now
2356 * 2) Not just finishing up a search
2357 * 3) Allowing a new search
2358 */
2359 if (!update_lq && !done_search &&
2360 !lq_sta->stay_in_tbl && window->counter) {
2361 /* Save current throughput to compare with "search" throughput*/
2362 lq_sta->last_tpt = current_tpt;
2363
2364 /* Select a new "search" modulation mode to try.
2365 * If one is found, set up the new "search" table. */
2366 if (is_legacy(tbl->lq_type))
2367 rs_move_legacy_other(mvm, lq_sta, sta, index);
2368 else if (is_siso(tbl->lq_type))
2369 rs_move_siso_to_other(mvm, lq_sta, sta, index);
2370 else if (is_mimo2(tbl->lq_type))
2371 rs_move_mimo2_to_other(mvm, lq_sta, sta, index);
2372 else
2373 rs_move_mimo3_to_other(mvm, lq_sta, sta, index);
2374
2375 /* If new "search" mode was selected, set up in uCode table */
2376 if (lq_sta->search_better_tbl) {
2377 /* Access the "search" table, clear its history. */
2378 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
2379 for (i = 0; i < IWL_RATE_COUNT; i++)
2380 rs_rate_scale_clear_window(&(tbl->win[i]));
2381
2382 /* Use new "search" start rate */
2383 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2384
2385 IWL_DEBUG_RATE(mvm,
2386 "Switch current mcs: %X index: %d\n",
2387 tbl->current_rate, index);
2388 rs_fill_link_cmd(mvm, lq_sta, tbl->current_rate);
2389 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2390 } else {
2391 done_search = 1;
2392 }
2393 }
2394
2395 if (done_search && !lq_sta->stay_in_tbl) {
2396 /* If the "active" (non-search) mode was legacy,
2397 * and we've tried switching antennas,
2398 * but we haven't been able to try HT modes (not available),
2399 * stay with best antenna legacy modulation for a while
2400 * before next round of mode comparisons. */
2401 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2402 if (is_legacy(tbl1->lq_type) && !sta->ht_cap.ht_supported &&
2403 lq_sta->action_counter > tbl1->max_search) {
2404 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2405 rs_set_stay_in_table(mvm, 1, lq_sta);
2406 }
2407
2408 /* If we're in an HT mode, and all 3 mode switch actions
2409 * have been tried and compared, stay in this best modulation
2410 * mode for a while before next round of mode comparisons. */
2411 if (lq_sta->enable_counter &&
2412 (lq_sta->action_counter >= tbl1->max_search)) {
2413 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2414 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2415 (tid != IWL_MAX_TID_COUNT)) {
2416 tid_data = &sta_priv->tid_data[tid];
2417 if (tid_data->state == IWL_AGG_OFF) {
2418 IWL_DEBUG_RATE(mvm,
2419 "try to aggregate tid %d\n",
2420 tid);
2421 rs_tl_turn_on_agg(mvm, tid,
2422 lq_sta, sta);
2423 }
2424 }
2425 rs_set_stay_in_table(mvm, 0, lq_sta);
2426 }
2427 }
2428
2429out:
2430 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green);
2431 lq_sta->last_txrate_idx = index;
2432}
2433
2434/**
2435 * rs_initialize_lq - Initialize a station's hardware rate table
2436 *
2437 * The uCode's station table contains a table of fallback rates
2438 * for automatic fallback during transmission.
2439 *
2440 * NOTE: This sets up a default set of values. These will be replaced later
2441 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2442 * rc80211_simple.
2443 *
2444 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
2445 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
2446 * which requires station table entry to exist).
2447 */
2448static void rs_initialize_lq(struct iwl_mvm *mvm,
2449 struct ieee80211_sta *sta,
2450 struct iwl_lq_sta *lq_sta,
2451 enum ieee80211_band band)
2452{
2453 struct iwl_scale_tbl_info *tbl;
2454 int rate_idx;
2455 int i;
2456 u32 rate;
2457 u8 use_green = rs_use_green(sta);
2458 u8 active_tbl = 0;
2459 u8 valid_tx_ant;
2460
2461 if (!sta || !lq_sta)
2462 return;
2463
2464 i = lq_sta->last_txrate_idx;
2465
2466 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
2467
2468 if (!lq_sta->search_better_tbl)
2469 active_tbl = lq_sta->active_tbl;
2470 else
2471 active_tbl = 1 - lq_sta->active_tbl;
2472
2473 tbl = &(lq_sta->lq_info[active_tbl]);
2474
2475 if ((i < 0) || (i >= IWL_RATE_COUNT))
2476 i = 0;
2477
2478 rate = iwl_rates[i].plcp;
2479 tbl->ant_type = first_antenna(valid_tx_ant);
2480 rate |= tbl->ant_type << RATE_MCS_ANT_POS;
2481
2482 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
2483 rate |= RATE_MCS_CCK_MSK;
2484
2485 rs_get_tbl_info_from_mcs(rate, band, tbl, &rate_idx);
2486 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
2487 rs_toggle_antenna(valid_tx_ant, &rate, tbl);
2488
2489 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx, use_green);
2490 tbl->current_rate = rate;
2491 rs_set_expected_tpt_table(lq_sta, tbl);
2492 rs_fill_link_cmd(NULL, lq_sta, rate);
2493 /* TODO restore station should remember the lq cmd */
2494 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true);
2495}
2496
2497static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2498 struct ieee80211_tx_rate_control *txrc)
2499{
2500 struct sk_buff *skb = txrc->skb;
2501 struct ieee80211_supported_band *sband = txrc->sband;
2502 struct iwl_op_mode *op_mode __maybe_unused =
2503 (struct iwl_op_mode *)mvm_r;
2504 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2505 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2506 struct iwl_lq_sta *lq_sta = mvm_sta;
2507 int rate_idx;
2508
2509 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n");
2510
2511 /* Get max rate if user set max rate */
2512 if (lq_sta) {
2513 lq_sta->max_rate_idx = txrc->max_rate_idx;
2514 if ((sband->band == IEEE80211_BAND_5GHZ) &&
2515 (lq_sta->max_rate_idx != -1))
2516 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
2517 if ((lq_sta->max_rate_idx < 0) ||
2518 (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
2519 lq_sta->max_rate_idx = -1;
2520 }
2521
2522 /* Treat uninitialized rate scaling data same as non-existing. */
2523 if (lq_sta && !lq_sta->drv) {
2524 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
2525 mvm_sta = NULL;
2526 }
2527
2528 /* Send management frames and NO_ACK data using lowest rate. */
2529 if (rate_control_send_low(sta, mvm_sta, txrc))
2530 return;
2531
2532 rate_idx = lq_sta->last_txrate_idx;
2533
2534 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
2535 rate_idx -= IWL_FIRST_OFDM_RATE;
2536 /* 6M and 9M shared same MCS index */
2537 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2538 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2539 IWL_RATE_MIMO3_6M_PLCP)
2540 rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
2541 else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2542 IWL_RATE_MIMO2_6M_PLCP)
2543 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
2544 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
2545 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
2546 info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
2547 if (lq_sta->last_rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */
2548 info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
2549 if (lq_sta->last_rate_n_flags & RATE_HT_MCS_GF_MSK)
2550 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
2551 } else {
2552 /* Check for invalid rates */
2553 if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||
2554 ((sband->band == IEEE80211_BAND_5GHZ) &&
2555 (rate_idx < IWL_FIRST_OFDM_RATE)))
2556 rate_idx = rate_lowest_index(sband, sta);
2557 /* On valid 5 GHz rate, adjust index */
2558 else if (sband->band == IEEE80211_BAND_5GHZ)
2559 rate_idx -= IWL_FIRST_OFDM_RATE;
2560 info->control.rates[0].flags = 0;
2561 }
2562 info->control.rates[0].idx = rate_idx;
2563}
2564
2565static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2566 gfp_t gfp)
2567{
2568 struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2569 struct iwl_op_mode *op_mode __maybe_unused =
2570 (struct iwl_op_mode *)mvm_rate;
2571 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2572
2573 IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
2574
2575 return &sta_priv->lq_sta;
2576}
2577
2578/*
2579 * Called after adding a new station to initialize rate scaling
2580 */
2581void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2582 enum ieee80211_band band)
2583{
2584 int i, j;
2585 struct ieee80211_hw *hw = mvm->hw;
2586 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2587 struct iwl_mvm_sta *sta_priv;
2588 struct iwl_lq_sta *lq_sta;
2589 struct ieee80211_supported_band *sband;
2590 unsigned long supp; /* must be unsigned long for for_each_set_bit */
2591
2592 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2593 lq_sta = &sta_priv->lq_sta;
2594 sband = hw->wiphy->bands[band];
2595
2596 lq_sta->lq.sta_id = sta_priv->sta_id;
2597
2598 for (j = 0; j < LQ_SIZE; j++)
2599 for (i = 0; i < IWL_RATE_COUNT; i++)
2600 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2601
2602 lq_sta->flush_timer = 0;
2603 lq_sta->supp_rates = sta->supp_rates[sband->band];
2604 for (j = 0; j < LQ_SIZE; j++)
2605 for (i = 0; i < IWL_RATE_COUNT; i++)
2606 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2607
2608 IWL_DEBUG_RATE(mvm,
2609 "LQ: *** rate scale station global init for station %d ***\n",
2610 sta_priv->sta_id);
2611 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2612 * the lowest or the highest rate.. Could consider using RSSI from
2613 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2614 * after assoc.. */
2615
2616 lq_sta->max_rate_idx = -1;
2617 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2618 lq_sta->is_green = rs_use_green(sta);
2619 lq_sta->band = sband->band;
2620 /*
2621 * active legacy rates as per supported rates bitmap
2622 */
2623 supp = sta->supp_rates[sband->band];
2624 lq_sta->active_legacy_rate = 0;
2625 for_each_set_bit(i, &supp, BITS_PER_LONG)
2626 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
2627
2628 /*
2629 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2630 * supp_rates[] does not; shift to convert format, force 9 MBits off.
2631 */
2632 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2633 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2634 lq_sta->active_siso_rate &= ~((u16)0x2);
2635 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2636
2637 /* Same here */
2638 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2639 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2640 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2641 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2642
2643 lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;
2644 lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;
2645 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2646 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2647
2648 IWL_DEBUG_RATE(mvm,
2649 "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
2650 lq_sta->active_siso_rate,
2651 lq_sta->active_mimo2_rate,
2652 lq_sta->active_mimo3_rate);
2653
2654 /* These values will be overridden later */
2655 lq_sta->lq.single_stream_ant_msk =
2656 first_antenna(mvm->nvm_data->valid_tx_ant);
2657 lq_sta->lq.dual_stream_ant_msk =
2658 mvm->nvm_data->valid_tx_ant &
2659 ~first_antenna(mvm->nvm_data->valid_tx_ant);
2660 if (!lq_sta->lq.dual_stream_ant_msk) {
2661 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2662 } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) {
2663 lq_sta->lq.dual_stream_ant_msk =
2664 mvm->nvm_data->valid_tx_ant;
2665 }
2666
2667 /* as default allow aggregation for all tids */
2668 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2669 lq_sta->drv = mvm;
2670
2671 /* Set last_txrate_idx to lowest rate */
2672 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
2673 if (sband->band == IEEE80211_BAND_5GHZ)
2674 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2675 lq_sta->is_agg = 0;
2676#ifdef CONFIG_MAC80211_DEBUGFS
2677 lq_sta->dbg_fixed_rate = 0;
2678#endif
2679
2680 rs_initialize_lq(mvm, sta, lq_sta, band);
2681}
2682
2683static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2684 struct iwl_lq_sta *lq_sta, u32 new_rate)
2685{
2686 struct iwl_scale_tbl_info tbl_type;
2687 int index = 0;
2688 int rate_idx;
2689 int repeat_rate = 0;
2690 u8 ant_toggle_cnt = 0;
2691 u8 use_ht_possible = 1;
2692 u8 valid_tx_ant = 0;
2693 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2694
2695 /* Override starting rate (index 0) if needed for debug purposes */
2696 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2697
2698 /* Interpret new_rate (rate_n_flags) */
2699 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2700 &tbl_type, &rate_idx);
2701
2702 /* How many times should we repeat the initial rate? */
2703 if (is_legacy(tbl_type.lq_type)) {
2704 ant_toggle_cnt = 1;
2705 repeat_rate = IWL_NUMBER_TRY;
2706 } else {
2707 repeat_rate = min(IWL_HT_NUMBER_TRY,
2708 LINK_QUAL_AGG_DISABLE_START_DEF - 1);
2709 }
2710
2711 lq_cmd->mimo_delim = is_mimo(tbl_type.lq_type) ? 1 : 0;
2712
2713 /* Fill 1st table entry (index 0) */
2714 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2715
2716 if (num_of_ant(tbl_type.ant_type) == 1)
2717 lq_cmd->single_stream_ant_msk = tbl_type.ant_type;
2718 else if (num_of_ant(tbl_type.ant_type) == 2)
2719 lq_cmd->dual_stream_ant_msk = tbl_type.ant_type;
2720 /* otherwise we don't modify the existing value */
2721
2722 index++;
2723 repeat_rate--;
2724 if (mvm)
2725 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
2726
2727 /* Fill rest of rate table */
2728 while (index < LINK_QUAL_MAX_RETRY_NUM) {
2729 /* Repeat initial/next rate.
2730 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2731 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
2732 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
2733 if (is_legacy(tbl_type.lq_type)) {
2734 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2735 ant_toggle_cnt++;
2736 else if (mvm &&
2737 rs_toggle_antenna(valid_tx_ant,
2738 &new_rate, &tbl_type))
2739 ant_toggle_cnt = 1;
2740 }
2741
2742 /* Override next rate if needed for debug purposes */
2743 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2744
2745 /* Fill next table entry */
2746 lq_cmd->rs_table[index] =
2747 cpu_to_le32(new_rate);
2748 repeat_rate--;
2749 index++;
2750 }
2751
2752 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2753 &rate_idx);
2754
2755
2756 /* Indicate to uCode which entries might be MIMO.
2757 * If initial rate was MIMO, this will finally end up
2758 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
2759 if (is_mimo(tbl_type.lq_type))
2760 lq_cmd->mimo_delim = index;
2761
2762 /* Get next rate */
2763 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
2764 use_ht_possible);
2765
2766 /* How many times should we repeat the next rate? */
2767 if (is_legacy(tbl_type.lq_type)) {
2768 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2769 ant_toggle_cnt++;
2770 else if (mvm &&
2771 rs_toggle_antenna(valid_tx_ant,
2772 &new_rate, &tbl_type))
2773 ant_toggle_cnt = 1;
2774
2775 repeat_rate = IWL_NUMBER_TRY;
2776 } else {
2777 repeat_rate = IWL_HT_NUMBER_TRY;
2778 }
2779
2780 /* Don't allow HT rates after next pass.
2781 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */
2782 use_ht_possible = 0;
2783
2784 /* Override next rate if needed for debug purposes */
2785 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2786
2787 /* Fill next table entry */
2788 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2789
2790 index++;
2791 repeat_rate--;
2792 }
2793
2794 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
2795 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
2796
2797 lq_cmd->agg_time_limit =
2798 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2799}
2800
2801static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
2802{
2803 return hw->priv;
2804}
2805/* rate scale requires free function to be implemented */
2806static void rs_free(void *mvm_rate)
2807{
2808 return;
2809}
2810
2811static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
2812 void *mvm_sta)
2813{
2814 struct iwl_op_mode *op_mode __maybe_unused = mvm_r;
2815 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2816
2817 IWL_DEBUG_RATE(mvm, "enter\n");
2818 IWL_DEBUG_RATE(mvm, "leave\n");
2819}
2820
2821#ifdef CONFIG_MAC80211_DEBUGFS
2822static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2823 u32 *rate_n_flags, int index)
2824{
2825 struct iwl_mvm *mvm;
2826 u8 valid_tx_ant;
2827 u8 ant_sel_tx;
2828
2829 mvm = lq_sta->drv;
2830 valid_tx_ant = mvm->nvm_data->valid_tx_ant;
2831 if (lq_sta->dbg_fixed_rate) {
2832 ant_sel_tx =
2833 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
2834 >> RATE_MCS_ANT_POS);
2835 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
2836 *rate_n_flags = lq_sta->dbg_fixed_rate;
2837 IWL_DEBUG_RATE(mvm, "Fixed rate ON\n");
2838 } else {
2839 lq_sta->dbg_fixed_rate = 0;
2840 IWL_ERR(mvm,
2841 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
2842 ant_sel_tx, valid_tx_ant);
2843 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n");
2844 }
2845 } else {
2846 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n");
2847 }
2848}
2849
2850static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2851 const char __user *user_buf, size_t count, loff_t *ppos)
2852{
2853 struct iwl_lq_sta *lq_sta = file->private_data;
2854 struct iwl_mvm *mvm;
2855 char buf[64];
2856 size_t buf_size;
2857 u32 parsed_rate;
2858
2859
2860 mvm = lq_sta->drv;
2861 memset(buf, 0, sizeof(buf));
2862 buf_size = min(count, sizeof(buf) - 1);
2863 if (copy_from_user(buf, user_buf, buf_size))
2864 return -EFAULT;
2865
2866 if (sscanf(buf, "%x", &parsed_rate) == 1)
2867 lq_sta->dbg_fixed_rate = parsed_rate;
2868 else
2869 lq_sta->dbg_fixed_rate = 0;
2870
2871 rs_program_fix_rate(mvm, lq_sta);
2872
2873 return count;
2874}
2875
2876static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2877 char __user *user_buf, size_t count, loff_t *ppos)
2878{
2879 char *buff;
2880 int desc = 0;
2881 int i = 0;
2882 int index = 0;
2883 ssize_t ret;
2884
2885 struct iwl_lq_sta *lq_sta = file->private_data;
2886 struct iwl_mvm *mvm;
2887 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2888
2889 mvm = lq_sta->drv;
2890 buff = kmalloc(1024, GFP_KERNEL);
2891 if (!buff)
2892 return -ENOMEM;
2893
2894 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
2895 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
2896 lq_sta->total_failed, lq_sta->total_success,
2897 lq_sta->active_legacy_rate);
2898 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2899 lq_sta->dbg_fixed_rate);
2900 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2901 (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "",
2902 (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "",
2903 (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : "");
2904 desc += sprintf(buff+desc, "lq type %s\n",
2905 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2906 if (is_Ht(tbl->lq_type)) {
2907 desc += sprintf(buff+desc, " %s",
2908 (is_siso(tbl->lq_type)) ? "SISO" :
2909 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
2910 desc += sprintf(buff+desc, " %s",
2911 (tbl->is_ht40) ? "40MHz" : "20MHz");
2912 desc += sprintf(buff+desc, " %s %s %s\n",
2913 (tbl->is_SGI) ? "SGI" : "",
2914 (lq_sta->is_green) ? "GF enabled" : "",
2915 (lq_sta->is_agg) ? "AGG on" : "");
2916 }
2917 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2918 lq_sta->last_rate_n_flags);
2919 desc += sprintf(buff+desc,
2920 "general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
2921 lq_sta->lq.flags,
2922 lq_sta->lq.mimo_delim,
2923 lq_sta->lq.single_stream_ant_msk,
2924 lq_sta->lq.dual_stream_ant_msk);
2925
2926 desc += sprintf(buff+desc,
2927 "agg: time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
2928 le16_to_cpu(lq_sta->lq.agg_time_limit),
2929 lq_sta->lq.agg_disable_start_th,
2930 lq_sta->lq.agg_frame_cnt_limit);
2931
2932 desc += sprintf(buff+desc,
2933 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
2934 lq_sta->lq.initial_rate_index[0],
2935 lq_sta->lq.initial_rate_index[1],
2936 lq_sta->lq.initial_rate_index[2],
2937 lq_sta->lq.initial_rate_index[3]);
2938
2939 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
2940 index = iwl_hwrate_to_plcp_idx(
2941 le32_to_cpu(lq_sta->lq.rs_table[i]));
2942 if (is_legacy(tbl->lq_type)) {
2943 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
2944 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2945 iwl_rate_mcs[index].mbps);
2946 } else {
2947 desc += sprintf(buff+desc,
2948 " rate[%d] 0x%X %smbps (%s)\n",
2949 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2950 iwl_rate_mcs[index].mbps,
2951 iwl_rate_mcs[index].mcs);
2952 }
2953 }
2954
2955 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2956 kfree(buff);
2957 return ret;
2958}
2959
2960static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
2961 .write = rs_sta_dbgfs_scale_table_write,
2962 .read = rs_sta_dbgfs_scale_table_read,
2963 .open = simple_open,
2964 .llseek = default_llseek,
2965};
2966static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2967 char __user *user_buf, size_t count, loff_t *ppos)
2968{
2969 char *buff;
2970 int desc = 0;
2971 int i, j;
2972 ssize_t ret;
2973
2974 struct iwl_lq_sta *lq_sta = file->private_data;
2975
2976 buff = kmalloc(1024, GFP_KERNEL);
2977 if (!buff)
2978 return -ENOMEM;
2979
2980 for (i = 0; i < LQ_SIZE; i++) {
2981 desc += sprintf(buff+desc,
2982 "%s type=%d SGI=%d HT40=%d DUP=0 GF=%d\n"
2983 "rate=0x%X\n",
2984 lq_sta->active_tbl == i ? "*" : "x",
2985 lq_sta->lq_info[i].lq_type,
2986 lq_sta->lq_info[i].is_SGI,
2987 lq_sta->lq_info[i].is_ht40,
2988 lq_sta->is_green,
2989 lq_sta->lq_info[i].current_rate);
2990 for (j = 0; j < IWL_RATE_COUNT; j++) {
2991 desc += sprintf(buff+desc,
2992 "counter=%d success=%d %%=%d\n",
2993 lq_sta->lq_info[i].win[j].counter,
2994 lq_sta->lq_info[i].win[j].success_counter,
2995 lq_sta->lq_info[i].win[j].success_ratio);
2996 }
2997 }
2998 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2999 kfree(buff);
3000 return ret;
3001}
3002
3003static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
3004 .read = rs_sta_dbgfs_stats_table_read,
3005 .open = simple_open,
3006 .llseek = default_llseek,
3007};
3008
3009static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
3010 char __user *user_buf, size_t count, loff_t *ppos)
3011{
3012 struct iwl_lq_sta *lq_sta = file->private_data;
3013 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3014 char buff[120];
3015 int desc = 0;
3016
3017 if (is_Ht(tbl->lq_type))
3018 desc += sprintf(buff+desc,
3019 "Bit Rate= %d Mb/s\n",
3020 tbl->expected_tpt[lq_sta->last_txrate_idx]);
3021 else
3022 desc += sprintf(buff+desc,
3023 "Bit Rate= %d Mb/s\n",
3024 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
3025
3026 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
3027}
3028
3029static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
3030 .read = rs_sta_dbgfs_rate_scale_data_read,
3031 .open = simple_open,
3032 .llseek = default_llseek,
3033};
3034
3035static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3036{
3037 struct iwl_lq_sta *lq_sta = mvm_sta;
3038 lq_sta->rs_sta_dbgfs_scale_table_file =
3039 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
3040 lq_sta, &rs_sta_dbgfs_scale_table_ops);
3041 lq_sta->rs_sta_dbgfs_stats_table_file =
3042 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
3043 lq_sta, &rs_sta_dbgfs_stats_table_ops);
3044 lq_sta->rs_sta_dbgfs_rate_scale_data_file =
3045 debugfs_create_file("rate_scale_data", S_IRUSR, dir,
3046 lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
3047 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
3048 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
3049 &lq_sta->tx_agg_tid_en);
3050}
3051
3052static void rs_remove_debugfs(void *mvm, void *mvm_sta)
3053{
3054 struct iwl_lq_sta *lq_sta = mvm_sta;
3055 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
3056 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
3057 debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
3058 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
3059}
3060#endif
3061
3062/*
3063 * Initialization of rate scaling information is done by driver after
3064 * the station is added. Since mac80211 calls this function before a
3065 * station is added we ignore it.
3066 */
3067static void rs_rate_init_stub(void *mvm_r,
3068 struct ieee80211_supported_band *sband,
3069 struct ieee80211_sta *sta, void *mvm_sta)
3070{
3071}
3072static struct rate_control_ops rs_mvm_ops = {
3073 .module = NULL,
3074 .name = RS_NAME,
3075 .tx_status = rs_tx_status,
3076 .get_rate = rs_get_rate,
3077 .rate_init = rs_rate_init_stub,
3078 .alloc = rs_alloc,
3079 .free = rs_free,
3080 .alloc_sta = rs_alloc_sta,
3081 .free_sta = rs_free_sta,
3082#ifdef CONFIG_MAC80211_DEBUGFS
3083 .add_sta_debugfs = rs_add_debugfs,
3084 .remove_sta_debugfs = rs_remove_debugfs,
3085#endif
3086};
3087
3088int iwl_mvm_rate_control_register(void)
3089{
3090 return ieee80211_rate_control_register(&rs_mvm_ops);
3091}
3092
3093void iwl_mvm_rate_control_unregister(void)
3094{
3095 ieee80211_rate_control_unregister(&rs_mvm_ops);
3096}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
new file mode 100644
index 000000000000..219c6857cc0f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -0,0 +1,393 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#ifndef __rs_h__
28#define __rs_h__
29
30#include <net/mac80211.h>
31
32#include "iwl-config.h"
33
34#include "fw-api.h"
35#include "iwl-trans.h"
36
37struct iwl_rs_rate_info {
38 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
39 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
40 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
41 u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
42 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
43 u8 prev_ieee; /* previous rate in IEEE speeds */
44 u8 next_ieee; /* next rate in IEEE speeds */
45 u8 prev_rs; /* previous rate used in rs algo */
46 u8 next_rs; /* next rate used in rs algo */
47 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
48 u8 next_rs_tgg; /* next rate used in TGG rs algo */
49};
50
51#define IWL_RATE_60M_PLCP 3
52
53enum {
54 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
55 IWL_RATE_INVALID = IWL_RATE_COUNT,
56};
57
58#define LINK_QUAL_MAX_RETRY_NUM 16
59
60enum {
61 IWL_RATE_6M_INDEX_TABLE = 0,
62 IWL_RATE_9M_INDEX_TABLE,
63 IWL_RATE_12M_INDEX_TABLE,
64 IWL_RATE_18M_INDEX_TABLE,
65 IWL_RATE_24M_INDEX_TABLE,
66 IWL_RATE_36M_INDEX_TABLE,
67 IWL_RATE_48M_INDEX_TABLE,
68 IWL_RATE_54M_INDEX_TABLE,
69 IWL_RATE_1M_INDEX_TABLE,
70 IWL_RATE_2M_INDEX_TABLE,
71 IWL_RATE_5M_INDEX_TABLE,
72 IWL_RATE_11M_INDEX_TABLE,
73 IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
74};
75
76/* #define vs. enum to keep from defaulting to 'large integer' */
77#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX)
78#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX)
79#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX)
80#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX)
81#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX)
82#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX)
83#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX)
84#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX)
85#define IWL_RATE_60M_MASK (1 << IWL_RATE_60M_INDEX)
86#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX)
87#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX)
88#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
89#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
90
91
92/* uCode API values for OFDM high-throughput (HT) bit rates */
93enum {
94 IWL_RATE_SISO_6M_PLCP = 0,
95 IWL_RATE_SISO_12M_PLCP = 1,
96 IWL_RATE_SISO_18M_PLCP = 2,
97 IWL_RATE_SISO_24M_PLCP = 3,
98 IWL_RATE_SISO_36M_PLCP = 4,
99 IWL_RATE_SISO_48M_PLCP = 5,
100 IWL_RATE_SISO_54M_PLCP = 6,
101 IWL_RATE_SISO_60M_PLCP = 7,
102 IWL_RATE_MIMO2_6M_PLCP = 0x8,
103 IWL_RATE_MIMO2_12M_PLCP = 0x9,
104 IWL_RATE_MIMO2_18M_PLCP = 0xa,
105 IWL_RATE_MIMO2_24M_PLCP = 0xb,
106 IWL_RATE_MIMO2_36M_PLCP = 0xc,
107 IWL_RATE_MIMO2_48M_PLCP = 0xd,
108 IWL_RATE_MIMO2_54M_PLCP = 0xe,
109 IWL_RATE_MIMO2_60M_PLCP = 0xf,
110 IWL_RATE_MIMO3_6M_PLCP = 0x10,
111 IWL_RATE_MIMO3_12M_PLCP = 0x11,
112 IWL_RATE_MIMO3_18M_PLCP = 0x12,
113 IWL_RATE_MIMO3_24M_PLCP = 0x13,
114 IWL_RATE_MIMO3_36M_PLCP = 0x14,
115 IWL_RATE_MIMO3_48M_PLCP = 0x15,
116 IWL_RATE_MIMO3_54M_PLCP = 0x16,
117 IWL_RATE_MIMO3_60M_PLCP = 0x17,
118 IWL_RATE_SISO_INVM_PLCP,
119 IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
120 IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
121};
122
123/* MAC header values for bit rates */
124enum {
125 IWL_RATE_6M_IEEE = 12,
126 IWL_RATE_9M_IEEE = 18,
127 IWL_RATE_12M_IEEE = 24,
128 IWL_RATE_18M_IEEE = 36,
129 IWL_RATE_24M_IEEE = 48,
130 IWL_RATE_36M_IEEE = 72,
131 IWL_RATE_48M_IEEE = 96,
132 IWL_RATE_54M_IEEE = 108,
133 IWL_RATE_60M_IEEE = 120,
134 IWL_RATE_1M_IEEE = 2,
135 IWL_RATE_2M_IEEE = 4,
136 IWL_RATE_5M_IEEE = 11,
137 IWL_RATE_11M_IEEE = 22,
138};
139
140#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
141
142#define IWL_INVALID_VALUE -1
143
144#define IWL_MIN_RSSI_VAL -100
145#define IWL_MAX_RSSI_VAL 0
146
147/* These values specify how many Tx frame attempts before
148 * searching for a new modulation mode */
149#define IWL_LEGACY_FAILURE_LIMIT 160
150#define IWL_LEGACY_SUCCESS_LIMIT 480
151#define IWL_LEGACY_TABLE_COUNT 160
152
153#define IWL_NONE_LEGACY_FAILURE_LIMIT 400
154#define IWL_NONE_LEGACY_SUCCESS_LIMIT 4500
155#define IWL_NONE_LEGACY_TABLE_COUNT 1500
156
157/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */
158#define IWL_RS_GOOD_RATIO 12800 /* 100% */
159#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
160#define IWL_RATE_HIGH_TH 10880 /* 85% */
161#define IWL_RATE_INCREASE_TH 6400 /* 50% */
162#define IWL_RATE_DECREASE_TH 1920 /* 15% */
163
164/* possible actions when in legacy mode */
165#define IWL_LEGACY_SWITCH_ANTENNA1 0
166#define IWL_LEGACY_SWITCH_ANTENNA2 1
167#define IWL_LEGACY_SWITCH_SISO 2
168#define IWL_LEGACY_SWITCH_MIMO2_AB 3
169#define IWL_LEGACY_SWITCH_MIMO2_AC 4
170#define IWL_LEGACY_SWITCH_MIMO2_BC 5
171#define IWL_LEGACY_SWITCH_MIMO3_ABC 6
172
173/* possible actions when in siso mode */
174#define IWL_SISO_SWITCH_ANTENNA1 0
175#define IWL_SISO_SWITCH_ANTENNA2 1
176#define IWL_SISO_SWITCH_MIMO2_AB 2
177#define IWL_SISO_SWITCH_MIMO2_AC 3
178#define IWL_SISO_SWITCH_MIMO2_BC 4
179#define IWL_SISO_SWITCH_GI 5
180#define IWL_SISO_SWITCH_MIMO3_ABC 6
181
182
183/* possible actions when in mimo mode */
184#define IWL_MIMO2_SWITCH_ANTENNA1 0
185#define IWL_MIMO2_SWITCH_ANTENNA2 1
186#define IWL_MIMO2_SWITCH_SISO_A 2
187#define IWL_MIMO2_SWITCH_SISO_B 3
188#define IWL_MIMO2_SWITCH_SISO_C 4
189#define IWL_MIMO2_SWITCH_GI 5
190#define IWL_MIMO2_SWITCH_MIMO3_ABC 6
191
192
193/* possible actions when in mimo3 mode */
194#define IWL_MIMO3_SWITCH_ANTENNA1 0
195#define IWL_MIMO3_SWITCH_ANTENNA2 1
196#define IWL_MIMO3_SWITCH_SISO_A 2
197#define IWL_MIMO3_SWITCH_SISO_B 3
198#define IWL_MIMO3_SWITCH_SISO_C 4
199#define IWL_MIMO3_SWITCH_MIMO2_AB 5
200#define IWL_MIMO3_SWITCH_MIMO2_AC 6
201#define IWL_MIMO3_SWITCH_MIMO2_BC 7
202#define IWL_MIMO3_SWITCH_GI 8
203
204
205#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
206#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
207
208/*FIXME:RS:add possible actions for MIMO3*/
209
210#define IWL_ACTION_LIMIT 3 /* # possible actions */
211
212#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
213#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
214#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
215
216#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
217#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
218#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
219
220#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
221#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
222#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
223
224#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */
225
226/* load per tid defines for A-MPDU activation */
227#define IWL_AGG_TPT_THREHOLD 0
228#define IWL_AGG_LOAD_THRESHOLD 10
229#define IWL_AGG_ALL_TID 0xff
230#define TID_QUEUE_CELL_SPACING 50 /*mS */
231#define TID_QUEUE_MAX_SIZE 20
232#define TID_ROUND_VALUE 5 /* mS */
233
234#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
235#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
236
237enum iwl_table_type {
238 LQ_NONE,
239 LQ_G, /* legacy types */
240 LQ_A,
241 LQ_SISO, /* high-throughput types */
242 LQ_MIMO2,
243 LQ_MIMO3,
244 LQ_MAX,
245};
246
247#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
248#define is_siso(tbl) ((tbl) == LQ_SISO)
249#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
250#define is_mimo3(tbl) ((tbl) == LQ_MIMO3)
251#define is_mimo(tbl) (is_mimo2(tbl) || is_mimo3(tbl))
252#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
253#define is_a_band(tbl) ((tbl) == LQ_A)
254#define is_g_and(tbl) ((tbl) == LQ_G)
255
256#define IWL_MAX_MCS_DISPLAY_SIZE 12
257
258struct iwl_rate_mcs_info {
259 char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
260 char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
261};
262
263/**
264 * struct iwl_rate_scale_data -- tx success history for one rate
265 */
266struct iwl_rate_scale_data {
267 u64 data; /* bitmap of successful frames */
268 s32 success_counter; /* number of frames successful */
269 s32 success_ratio; /* per-cent * 128 */
270 s32 counter; /* number of frames attempted */
271 s32 average_tpt; /* success ratio * expected throughput */
272 unsigned long stamp;
273};
274
275/**
276 * struct iwl_scale_tbl_info -- tx params and success history for all rates
277 *
278 * There are two of these in struct iwl_lq_sta,
279 * one for "active", and one for "search".
280 */
281struct iwl_scale_tbl_info {
282 enum iwl_table_type lq_type;
283 u8 ant_type;
284 u8 is_SGI; /* 1 = short guard interval */
285 u8 is_ht40; /* 1 = 40 MHz channel width */
286 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
287 u8 max_search; /* maximun number of tables we can search */
288 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
289 u32 current_rate; /* rate_n_flags, uCode API format */
290 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
291};
292
293struct iwl_traffic_load {
294 unsigned long time_stamp; /* age of the oldest statistics */
295 u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
296 * slice */
297 u32 total; /* total num of packets during the
298 * last TID_MAX_TIME_DIFF */
299 u8 queue_count; /* number of queues that has
300 * been used since the last cleanup */
301 u8 head; /* start of the circular buffer */
302};
303
304/**
305 * struct iwl_lq_sta -- driver's rate scaling private structure
306 *
307 * Pointer to this gets passed back and forth between driver and mac80211.
308 */
309struct iwl_lq_sta {
310 u8 active_tbl; /* index of active table, range 0-1 */
311 u8 enable_counter; /* indicates HT mode */
312 u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
313 u8 search_better_tbl; /* 1: currently trying alternate mode */
314 s32 last_tpt;
315
316 /* The following determine when to search for a new mode */
317 u32 table_count_limit;
318 u32 max_failure_limit; /* # failed frames before new search */
319 u32 max_success_limit; /* # successful frames before new search */
320 u32 table_count;
321 u32 total_failed; /* total failed frames, any/all rates */
322 u32 total_success; /* total successful frames, any/all rates */
323 u64 flush_timer; /* time staying in mode before new search */
324
325 u8 action_counter; /* # mode-switch actions tried */
326 u8 is_green;
327 enum ieee80211_band band;
328
329 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
330 u32 supp_rates;
331 u16 active_legacy_rate;
332 u16 active_siso_rate;
333 u16 active_mimo2_rate;
334 u16 active_mimo3_rate;
335 s8 max_rate_idx; /* Max rate set by user */
336 u8 missed_rate_counter;
337
338 struct iwl_lq_cmd lq;
339 struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
340 struct iwl_traffic_load load[IWL_MAX_TID_COUNT];
341 u8 tx_agg_tid_en;
342#ifdef CONFIG_MAC80211_DEBUGFS
343 struct dentry *rs_sta_dbgfs_scale_table_file;
344 struct dentry *rs_sta_dbgfs_stats_table_file;
345 struct dentry *rs_sta_dbgfs_rate_scale_data_file;
346 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
347 u32 dbg_fixed_rate;
348#endif
349 struct iwl_mvm *drv;
350
351 /* used to be in sta_info */
352 int last_txrate_idx;
353 /* last tx rate_n_flags */
354 u32 last_rate_n_flags;
355 /* packets destined for this STA are aggregated */
356 u8 is_agg;
357 /* BT traffic this sta was last updated in */
358 u8 last_bt_traffic;
359};
360
361static inline u8 num_of_ant(u8 mask)
362{
363 return !!((mask) & ANT_A) +
364 !!((mask) & ANT_B) +
365 !!((mask) & ANT_C);
366}
367
368/* Initialize station's rate scaling information after adding station */
369extern void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm,
370 struct ieee80211_sta *sta,
371 enum ieee80211_band band);
372
373/**
374 * iwl_rate_control_register - Register the rate control algorithm callbacks
375 *
376 * Since the rate control algorithm is hardware specific, there is no need
377 * or reason to place it as a stand alone module. The driver can call
378 * iwl_rate_control_register in order to register the rate control callbacks
379 * with the mac80211 subsystem. This should be performed prior to calling
380 * ieee80211_register_hw
381 *
382 */
383extern int iwl_mvm_rate_control_register(void);
384
385/**
386 * iwl_rate_control_unregister - Unregister the rate control callbacks
387 *
388 * This should be called after calling ieee80211_unregister_hw, but before
389 * the driver is unloaded.
390 */
391extern void iwl_mvm_rate_control_unregister(void);
392
393#endif /* __rs__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
new file mode 100644
index 000000000000..52da375e5740
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -0,0 +1,355 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62#include "iwl-trans.h"
63
64#include "mvm.h"
65#include "fw-api.h"
66
67/*
68 * iwl_mvm_rx_rx_phy_cmd - REPLY_RX_PHY_CMD handler
69 *
70 * Copies the phy information in mvm->last_phy_info, it will be used when the
71 * actual data will come from the fw in the next packet.
72 */
73int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
74 struct iwl_device_cmd *cmd)
75{
76 struct iwl_rx_packet *pkt = rxb_addr(rxb);
77
78 memcpy(&mvm->last_phy_info, pkt->data, sizeof(mvm->last_phy_info));
79 mvm->ampdu_ref++;
80 return 0;
81}
82
83/*
84 * iwl_mvm_pass_packet_to_mac80211 - builds the packet for mac80211
85 *
86 * Adds the rxb to a new skb and give it to mac80211
87 */
88static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
89 struct ieee80211_hdr *hdr, u16 len,
90 u32 ampdu_status,
91 struct iwl_rx_cmd_buffer *rxb,
92 struct ieee80211_rx_status *stats)
93{
94 struct sk_buff *skb;
95 unsigned int hdrlen, fraglen;
96
97 /* Dont use dev_alloc_skb(), we'll have enough headroom once
98 * ieee80211_hdr pulled.
99 */
100 skb = alloc_skb(128, GFP_ATOMIC);
101 if (!skb) {
102 IWL_ERR(mvm, "alloc_skb failed\n");
103 return;
104 }
105 /* If frame is small enough to fit in skb->head, pull it completely.
106 * If not, only pull ieee80211_hdr so that splice() or TCP coalesce
107 * are more efficient.
108 */
109 hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr);
110
111 memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
112 fraglen = len - hdrlen;
113
114 if (fraglen) {
115 int offset = (void *)hdr + hdrlen -
116 rxb_addr(rxb) + rxb_offset(rxb);
117
118 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
119 fraglen, rxb->truesize);
120 }
121
122 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
123
124 ieee80211_rx(mvm->hw, skb);
125}
126
127/*
128 * iwl_mvm_calc_rssi - calculate the rssi in dBm
129 * @phy_info: the phy information for the coming packet
130 */
131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
132 struct iwl_rx_phy_info *phy_info)
133{
134 u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db;
135 u32 val;
136
137 /* Find max rssi among 3 possible receivers.
138 * These values are measured by the Digital Signal Processor (DSP).
139 * They should stay fairly constant even as the signal strength varies,
140 * if the radio's Automatic Gain Control (AGC) is working right.
141 * AGC value (see below) will provide the "interesting" info.
142 */
143 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
144 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
145 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
146 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]);
147 rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS;
148
149 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
150 agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
151
152 max_rssi = max_t(u32, rssi_a, rssi_b);
153 max_rssi = max_t(u32, max_rssi, rssi_c);
154
155 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
156 rssi_a, rssi_b, rssi_c, max_rssi, agc_db);
157
158 /* dBm = max_rssi dB - agc dB - constant.
159 * Higher AGC (higher radio gain) means lower signal. */
160 return max_rssi - agc_db - IWL_RSSI_OFFSET;
161}
162
163/*
164 * iwl_mvm_set_mac80211_rx_flag - translate fw status to mac80211 format
165 * @mvm: the mvm object
166 * @hdr: 80211 header
167 * @stats: status in mac80211's format
168 * @rx_pkt_status: status coming from fw
169 *
170 * returns non 0 value if the packet should be dropped
171 */
172static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
173 struct ieee80211_hdr *hdr,
174 struct ieee80211_rx_status *stats,
175 u32 rx_pkt_status)
176{
177 if (!ieee80211_has_protected(hdr->frame_control) ||
178 (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
179 RX_MPDU_RES_STATUS_SEC_NO_ENC)
180 return 0;
181
182 /* packet was encrypted with unknown alg */
183 if ((rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
184 RX_MPDU_RES_STATUS_SEC_ENC_ERR)
185 return 0;
186
187 switch (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) {
188 case RX_MPDU_RES_STATUS_SEC_CCM_ENC:
189 /* alg is CCM: check MIC only */
190 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_MIC_OK))
191 return -1;
192
193 stats->flag |= RX_FLAG_DECRYPTED;
194 IWL_DEBUG_WEP(mvm, "hw decrypted CCMP successfully\n");
195 return 0;
196
197 case RX_MPDU_RES_STATUS_SEC_TKIP_ENC:
198 /* Don't drop the frame and decrypt it in SW */
199 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
200 return 0;
201 /* fall through if TTAK OK */
202
203 case RX_MPDU_RES_STATUS_SEC_WEP_ENC:
204 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_ICV_OK))
205 return -1;
206
207 stats->flag |= RX_FLAG_DECRYPTED;
208 return 0;
209
210 default:
211 IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
212 }
213
214 return 0;
215}
216
217/*
218 * iwl_mvm_rx_rx_mpdu - REPLY_RX_MPDU_CMD handler
219 *
220 * Handles the actual data of the Rx packet from the fw
221 */
222int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
223 struct iwl_device_cmd *cmd)
224{
225 struct ieee80211_hdr *hdr;
226 struct ieee80211_rx_status rx_status = {};
227 struct iwl_rx_packet *pkt = rxb_addr(rxb);
228 struct iwl_rx_phy_info *phy_info;
229 struct iwl_rx_mpdu_res_start *rx_res;
230 u32 len;
231 u32 ampdu_status;
232 u32 rate_n_flags;
233 u32 rx_pkt_status;
234
235 phy_info = &mvm->last_phy_info;
236 rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
237 hdr = (struct ieee80211_hdr *)(pkt->data + sizeof(*rx_res));
238 len = le16_to_cpu(rx_res->byte_count);
239 rx_pkt_status = le32_to_cpup((__le32 *)
240 (pkt->data + sizeof(*rx_res) + len));
241
242 memset(&rx_status, 0, sizeof(rx_status));
243
244 /*
245 * drop the packet if it has failed being decrypted by HW
246 */
247 if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) {
248 IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n",
249 rx_pkt_status);
250 return 0;
251 }
252
253 if ((unlikely(phy_info->cfg_phy_cnt > 20))) {
254 IWL_DEBUG_DROP(mvm, "dsp size out of range [0,20]: %d\n",
255 phy_info->cfg_phy_cnt);
256 return 0;
257 }
258
259 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_CRC_OK) ||
260 !(rx_pkt_status & RX_MPDU_RES_STATUS_OVERRUN_OK)) {
261 IWL_DEBUG_RX(mvm, "Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status);
262 return 0;
263 }
264
265 /* This will be used in several places later */
266 rate_n_flags = le32_to_cpu(phy_info->rate_n_flags);
267
268 /* rx_status carries information about the packet to mac80211 */
269 rx_status.mactime = le64_to_cpu(phy_info->timestamp);
270 rx_status.band =
271 (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
272 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
273 rx_status.freq =
274 ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel),
275 rx_status.band);
276 /*
277 * TSF as indicated by the fw is at INA time, but mac80211 expects the
278 * TSF at the beginning of the MPDU.
279 */
280 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
281
282 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
283 rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info);
284
285 IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal,
286 (unsigned long long)rx_status.mactime);
287
288 /*
289 * "antenna number"
290 *
291 * It seems that the antenna field in the phy flags value
292 * is actually a bit field. This is undefined by radiotap,
293 * it wants an actual antenna number but I always get "7"
294 * for most legacy frames I receive indicating that the
295 * same frame was received on all three RX chains.
296 *
297 * I think this field should be removed in favor of a
298 * new 802.11n radiotap field "RX chains" that is defined
299 * as a bitmask.
300 */
301 rx_status.antenna = (le16_to_cpu(phy_info->phy_flags) &
302 RX_RES_PHY_FLAGS_ANTENNA)
303 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
304
305 /* set the preamble flag if appropriate */
306 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
307 rx_status.flag |= RX_FLAG_SHORTPRE;
308
309 if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
310 /*
311 * We know which subframes of an A-MPDU belong
312 * together since we get a single PHY response
313 * from the firmware for all of them
314 */
315 rx_status.flag |= RX_FLAG_AMPDU_DETAILS;
316 rx_status.ampdu_reference = mvm->ampdu_ref;
317 }
318
319 /* Set up the HT phy flags */
320 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
321 case RATE_MCS_CHAN_WIDTH_20:
322 break;
323 case RATE_MCS_CHAN_WIDTH_40:
324 rx_status.flag |= RX_FLAG_40MHZ;
325 break;
326 case RATE_MCS_CHAN_WIDTH_80:
327 rx_status.flag |= RX_FLAG_80MHZ;
328 break;
329 case RATE_MCS_CHAN_WIDTH_160:
330 rx_status.flag |= RX_FLAG_160MHZ;
331 break;
332 }
333 if (rate_n_flags & RATE_MCS_SGI_MSK)
334 rx_status.flag |= RX_FLAG_SHORT_GI;
335 if (rate_n_flags & RATE_HT_MCS_GF_MSK)
336 rx_status.flag |= RX_FLAG_HT_GF;
337 if (rate_n_flags & RATE_MCS_HT_MSK) {
338 rx_status.flag |= RX_FLAG_HT;
339 rx_status.rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
340 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
341 rx_status.vht_nss =
342 ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
343 RATE_VHT_MCS_NSS_POS) + 1;
344 rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
345 rx_status.flag |= RX_FLAG_VHT;
346 } else {
347 rx_status.rate_idx =
348 iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
349 rx_status.band);
350 }
351
352 iwl_mvm_pass_packet_to_mac80211(mvm, hdr, len, ampdu_status,
353 rxb, &rx_status);
354 return 0;
355}
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
new file mode 100644
index 000000000000..406c53ad0a49
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -0,0 +1,437 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/etherdevice.h>
65#include <net/mac80211.h>
66
67#include "mvm.h"
68#include "iwl-eeprom-parse.h"
69#include "fw-api-scan.h"
70
71#define IWL_PLCP_QUIET_THRESH 1
72#define IWL_ACTIVE_QUIET_TIME 10
73
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{
76 u16 rx_chain;
77 u8 rx_ant = mvm->nvm_data->valid_rx_ant;
78
79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
81 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
82 rx_chain |= 0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS;
83 return cpu_to_le16(rx_chain);
84}
85
86static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif)
87{
88 if (vif->bss_conf.assoc)
89 return cpu_to_le32(200 * 1024);
90 else
91 return 0;
92}
93
94static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif)
95{
96 if (vif->bss_conf.assoc)
97 return cpu_to_le32(vif->bss_conf.beacon_int);
98 else
99 return 0;
100}
101
102static inline __le32
103iwl_mvm_scan_rxon_flags(struct cfg80211_scan_request *req)
104{
105 if (req->channels[0]->band == IEEE80211_BAND_2GHZ)
106 return cpu_to_le32(PHY_BAND_24);
107 else
108 return cpu_to_le32(PHY_BAND_5);
109}
110
111static inline __le32
112iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
113 bool no_cck)
114{
115 u32 tx_ant;
116
117 mvm->scan_last_antenna_idx =
118 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
119 mvm->scan_last_antenna_idx);
120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
121
122 if (band == IEEE80211_BAND_2GHZ && !no_cck)
123 return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK |
124 tx_ant);
125 else
126 return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant);
127}
128
129/*
130 * We insert the SSIDs in an inverted order, because the FW will
131 * invert it back. The most prioritized SSID, which is first in the
132 * request list, is not copied here, but inserted directly to the probe
133 * request.
134 */
135static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
136 struct cfg80211_scan_request *req)
137{
138 int fw_idx, req_idx;
139
140 fw_idx = 0;
141 for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) {
142 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
143 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
144 memcpy(cmd->direct_scan[fw_idx].ssid,
145 req->ssids[req_idx].ssid,
146 req->ssids[req_idx].ssid_len);
147 }
148}
149
150/*
151 * If req->n_ssids > 0, it means we should do an active scan.
152 * In case of active scan w/o directed scan, we receive a zero-length SSID
153 * just to notify that this scan is active and not passive.
154 * In order to notify the FW of the number of SSIDs we wish to scan (including
155 * the zero-length one), we need to set the corresponding bits in chan->type,
156 * one for each SSID, and set the active bit (first).
157 */
158static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
159{
160 if (band == IEEE80211_BAND_2GHZ)
161 return 30 + 3 * (n_ssids + 1);
162 return 20 + 2 * (n_ssids + 1);
163}
164
165static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
166{
167 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
168}
169
170static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
171 struct cfg80211_scan_request *req)
172{
173 u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band);
174 u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band,
175 req->n_ssids);
176 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
177 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
178 int i;
179 __le32 chan_type_value;
180
181 if (req->n_ssids > 0)
182 chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1);
183 else
184 chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
185
186 for (i = 0; i < cmd->channel_count; i++) {
187 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
188 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
189 chan->type = SCAN_CHANNEL_TYPE_PASSIVE;
190 else
191 chan->type = chan_type_value;
192 chan->active_dwell = cpu_to_le16(active_dwell);
193 chan->passive_dwell = cpu_to_le16(passive_dwell);
194 chan->iteration_count = cpu_to_le16(1);
195 chan++;
196 }
197}
198
199/*
200 * Fill in probe request with the following parameters:
201 * TA is our vif HW address, which mac80211 ensures we have.
202 * Packet is broadcasted, so this is both SA and DA.
203 * The probe request IE is made out of two: first comes the most prioritized
204 * SSID if a directed scan is requested. Second comes whatever extra
205 * information was given to us as the scan request IE.
206 */
207static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
208 int n_ssids, const u8 *ssid, int ssid_len,
209 const u8 *ie, int ie_len,
210 int left)
211{
212 int len = 0;
213 u8 *pos = NULL;
214
215 /* Make sure there is enough space for the probe request,
216 * two mandatory IEs and the data */
217 left -= 24;
218 if (left < 0)
219 return 0;
220
221 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
222 eth_broadcast_addr(frame->da);
223 memcpy(frame->sa, ta, ETH_ALEN);
224 eth_broadcast_addr(frame->bssid);
225 frame->seq_ctrl = 0;
226
227 len += 24;
228
229 /* for passive scans, no need to fill anything */
230 if (n_ssids == 0)
231 return (u16)len;
232
233 /* points to the payload of the request */
234 pos = &frame->u.probe_req.variable[0];
235
236 /* fill in our SSID IE */
237 left -= ssid_len + 2;
238 if (left < 0)
239 return 0;
240 *pos++ = WLAN_EID_SSID;
241 *pos++ = ssid_len;
242 if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
243 memcpy(pos, ssid, ssid_len);
244 pos += ssid_len;
245 }
246
247 len += ssid_len + 2;
248
249 if (WARN_ON(left < ie_len))
250 return len;
251
252 if (ie && ie_len) {
253 memcpy(pos, ie, ie_len);
254 len += ie_len;
255 }
256
257 return (u16)len;
258}
259
260int iwl_mvm_scan_request(struct iwl_mvm *mvm,
261 struct ieee80211_vif *vif,
262 struct cfg80211_scan_request *req)
263{
264 struct iwl_host_cmd hcmd = {
265 .id = SCAN_REQUEST_CMD,
266 .len = { 0, },
267 .data = { mvm->scan_cmd, },
268 .flags = CMD_SYNC,
269 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
270 };
271 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
272 int ret;
273 u32 status;
274 int ssid_len = 0;
275 u8 *ssid = NULL;
276
277 lockdep_assert_held(&mvm->mutex);
278 BUG_ON(mvm->scan_cmd == NULL);
279
280 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
281 mvm->scan_status = IWL_MVM_SCAN_OS;
282 memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
283 mvm->fw->ucode_capa.max_probe_length +
284 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
285
286 cmd->channel_count = (u8)req->n_channels;
287 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
288 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
289 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
290 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif);
291 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif);
292 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
293 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
294 MAC_FILTER_IN_BEACON);
295 cmd->type = SCAN_TYPE_FORCED;
296 cmd->repeats = cpu_to_le32(1);
297
298 /*
299 * If the user asked for passive scan, don't change to active scan if
300 * you see any activity on the channel - remain passive.
301 */
302 if (req->n_ssids > 0) {
303 cmd->passive2active = cpu_to_le16(1);
304 ssid = req->ssids[0].ssid;
305 ssid_len = req->ssids[0].ssid_len;
306 } else {
307 cmd->passive2active = 0;
308 }
309
310 iwl_mvm_scan_fill_ssids(cmd, req);
311
312 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
313 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
314 cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
315 cmd->tx_cmd.rate_n_flags =
316 iwl_mvm_scan_rate_n_flags(mvm, req->channels[0]->band,
317 req->no_cck);
318
319 cmd->tx_cmd.len =
320 cpu_to_le16(iwl_mvm_fill_probe_req(
321 (struct ieee80211_mgmt *)cmd->data,
322 vif->addr,
323 req->n_ssids, ssid, ssid_len,
324 req->ie, req->ie_len,
325 mvm->fw->ucode_capa.max_probe_length));
326
327 iwl_mvm_scan_fill_channels(cmd, req);
328
329 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
330 le16_to_cpu(cmd->tx_cmd.len) +
331 (cmd->channel_count * sizeof(struct iwl_scan_channel)));
332 hcmd.len[0] = le16_to_cpu(cmd->len);
333
334 status = SCAN_RESPONSE_OK;
335 ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &status);
336 if (!ret && status == SCAN_RESPONSE_OK) {
337 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
338 } else {
339 /*
340 * If the scan failed, it usually means that the FW was unable
341 * to allocate the time events. Warn on it, but maybe we
342 * should try to send the command again with different params.
343 */
344 IWL_ERR(mvm, "Scan failed! status 0x%x ret %d\n",
345 status, ret);
346 mvm->scan_status = IWL_MVM_SCAN_NONE;
347 ret = -EIO;
348 }
349 return ret;
350}
351
352int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
353 struct iwl_device_cmd *cmd)
354{
355 struct iwl_rx_packet *pkt = rxb_addr(rxb);
356 struct iwl_cmd_response *resp = (void *)pkt->data;
357
358 IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n",
359 le32_to_cpu(resp->status));
360 return 0;
361}
362
363int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
364 struct iwl_device_cmd *cmd)
365{
366 struct iwl_rx_packet *pkt = rxb_addr(rxb);
367 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
368
369 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n",
370 notif->status, notif->scanned_channels);
371
372 mvm->scan_status = IWL_MVM_SCAN_NONE;
373 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK);
374
375 return 0;
376}
377
378static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
379 struct iwl_rx_packet *pkt, void *data)
380{
381 struct iwl_mvm *mvm =
382 container_of(notif_wait, struct iwl_mvm, notif_wait);
383 struct iwl_scan_complete_notif *notif;
384 u32 *resp;
385
386 switch (pkt->hdr.cmd) {
387 case SCAN_ABORT_CMD:
388 resp = (void *)pkt->data;
389 if (*resp == CAN_ABORT_STATUS) {
390 IWL_DEBUG_SCAN(mvm,
391 "Scan can be aborted, wait until completion\n");
392 return false;
393 }
394
395 IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n",
396 *resp);
397 return true;
398
399 case SCAN_COMPLETE_NOTIFICATION:
400 notif = (void *)pkt->data;
401 IWL_DEBUG_SCAN(mvm, "Scan aborted: status 0x%x\n",
402 notif->status);
403 return true;
404
405 default:
406 WARN_ON(1);
407 return false;
408 };
409}
410
411void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
412{
413 struct iwl_notification_wait wait_scan_abort;
414 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
415 SCAN_COMPLETE_NOTIFICATION };
416 int ret;
417
418 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
419 scan_abort_notif,
420 ARRAY_SIZE(scan_abort_notif),
421 iwl_mvm_scan_abort_notif, NULL);
422
423 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL);
424 if (ret) {
425 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
426 goto out_remove_notif;
427 }
428
429 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, 1 * HZ);
430 if (ret)
431 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
432
433 return;
434
435out_remove_notif:
436 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
437}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
new file mode 100644
index 000000000000..69603c3b2b39
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -0,0 +1,1211 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <net/mac80211.h>
64
65#include "mvm.h"
66#include "sta.h"
67
68static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
69{
70 int sta_id;
71
72 WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
73
74 lockdep_assert_held(&mvm->mutex);
75
76 /* Don't take rcu_read_lock() since we are protected by mvm->mutex */
77 for (sta_id = 0; sta_id < IWL_MVM_STATION_COUNT; sta_id++)
78 if (!rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
79 lockdep_is_held(&mvm->mutex)))
80 return sta_id;
81 return IWL_MVM_STATION_COUNT;
82}
83
84/* add a NEW station to fw */
85int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta)
86{
87 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
88 struct iwl_mvm_add_sta_cmd add_sta_cmd;
89 int ret;
90 u32 status;
91 u32 agg_size = 0, mpdu_dens = 0;
92
93 memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
94
95 add_sta_cmd.sta_id = mvm_sta->sta_id;
96 add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
97 add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
98 memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN);
99
100 /* STA_FLG_FAT_EN_MSK ? */
101 /* STA_FLG_MIMO_EN_MSK ? */
102
103 if (sta->ht_cap.ht_supported) {
104 add_sta_cmd.station_flags_msk |=
105 cpu_to_le32(STA_FLG_MAX_AGG_SIZE_MSK |
106 STA_FLG_AGG_MPDU_DENS_MSK);
107
108 mpdu_dens = sta->ht_cap.ampdu_density;
109 }
110
111 if (sta->vht_cap.vht_supported) {
112 agg_size = sta->vht_cap.cap &
113 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
114 agg_size >>=
115 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
116 } else if (sta->ht_cap.ht_supported) {
117 agg_size = sta->ht_cap.ampdu_factor;
118 }
119
120 add_sta_cmd.station_flags |=
121 cpu_to_le32(agg_size << STA_FLG_MAX_AGG_SIZE_SHIFT);
122 add_sta_cmd.station_flags |=
123 cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
124
125 status = ADD_STA_SUCCESS;
126 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd),
127 &add_sta_cmd, &status);
128 if (ret)
129 return ret;
130
131 switch (status) {
132 case ADD_STA_SUCCESS:
133 IWL_DEBUG_ASSOC(mvm, "ADD_STA PASSED\n");
134 break;
135 default:
136 ret = -EIO;
137 IWL_ERR(mvm, "ADD_STA failed\n");
138 break;
139 }
140
141 return ret;
142}
143
144int iwl_mvm_add_sta(struct iwl_mvm *mvm,
145 struct ieee80211_vif *vif,
146 struct ieee80211_sta *sta)
147{
148 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
149 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
150 int i, ret, sta_id;
151
152 lockdep_assert_held(&mvm->mutex);
153
154 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
155 sta_id = iwl_mvm_find_free_sta_id(mvm);
156 else
157 sta_id = mvm_sta->sta_id;
158
159 if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
160 return -ENOSPC;
161
162 spin_lock_init(&mvm_sta->lock);
163
164 mvm_sta->sta_id = sta_id;
165 mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id,
166 mvmvif->color);
167 mvm_sta->vif = vif;
168 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
169
170 /* HW restart, don't assume the memory has been zeroed */
171 atomic_set(&mvm_sta->pending_frames, 0);
172 mvm_sta->tid_disable_agg = 0;
173 mvm_sta->tfd_queue_msk = 0;
174 for (i = 0; i < IEEE80211_NUM_ACS; i++)
175 if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
176 mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]);
177
178 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
179 mvm_sta->tfd_queue_msk |= BIT(vif->cab_queue);
180
181 /* for HW restart - need to reset the seq_number etc... */
182 memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data));
183
184 ret = iwl_mvm_sta_add_to_fw(mvm, sta);
185 if (ret)
186 return ret;
187
188 /* The first station added is the AP, the others are TDLS STAs */
189 if (vif->type == NL80211_IFTYPE_STATION &&
190 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
191 mvmvif->ap_sta_id = sta_id;
192
193 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
194
195 return 0;
196}
197
198int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
199 bool drain)
200{
201 struct iwl_mvm_add_sta_cmd cmd = {};
202 int ret;
203 u32 status;
204
205 lockdep_assert_held(&mvm->mutex);
206
207 cmd.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color);
208 cmd.sta_id = mvmsta->sta_id;
209 cmd.add_modify = STA_MODE_MODIFY;
210 cmd.station_flags = drain ? cpu_to_le32(STA_FLG_DRAIN_FLOW) : 0;
211 cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW);
212
213 status = ADD_STA_SUCCESS;
214 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
215 &cmd, &status);
216 if (ret)
217 return ret;
218
219 switch (status) {
220 case ADD_STA_SUCCESS:
221 IWL_DEBUG_INFO(mvm, "Frames for staid %d will drained in fw\n",
222 mvmsta->sta_id);
223 break;
224 default:
225 ret = -EIO;
226 IWL_ERR(mvm, "Couldn't drain frames for staid %d\n",
227 mvmsta->sta_id);
228 break;
229 }
230
231 return ret;
232}
233
234/*
235 * Remove a station from the FW table. Before sending the command to remove
236 * the station validate that the station is indeed known to the driver (sanity
237 * only).
238 */
239static int iwl_mvm_rm_sta_common(struct iwl_mvm *mvm, u8 sta_id)
240{
241 struct ieee80211_sta *sta;
242 struct iwl_mvm_rm_sta_cmd rm_sta_cmd = {
243 .sta_id = sta_id,
244 };
245 int ret;
246
247 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
248 lockdep_is_held(&mvm->mutex));
249
250 /* Note: internal stations are marked as error values */
251 if (!sta) {
252 IWL_ERR(mvm, "Invalid station id\n");
253 return -EINVAL;
254 }
255
256 ret = iwl_mvm_send_cmd_pdu(mvm, REMOVE_STA, CMD_SYNC,
257 sizeof(rm_sta_cmd), &rm_sta_cmd);
258 if (ret) {
259 IWL_ERR(mvm, "Failed to remove station. Id=%d\n", sta_id);
260 return ret;
261 }
262
263 return 0;
264}
265
266void iwl_mvm_sta_drained_wk(struct work_struct *wk)
267{
268 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, sta_drained_wk);
269 u8 sta_id;
270
271 /*
272 * The mutex is needed because of the SYNC cmd, but not only: if the
273 * work would run concurrently with iwl_mvm_rm_sta, it would run before
274 * iwl_mvm_rm_sta sets the station as busy, and exit. Then
275 * iwl_mvm_rm_sta would set the station as busy, and nobody will clean
276 * that later.
277 */
278 mutex_lock(&mvm->mutex);
279
280 for_each_set_bit(sta_id, mvm->sta_drained, IWL_MVM_STATION_COUNT) {
281 int ret;
282 struct ieee80211_sta *sta =
283 rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
284 lockdep_is_held(&mvm->mutex));
285
286 /* This station is in use */
287 if (!IS_ERR(sta))
288 continue;
289
290 if (PTR_ERR(sta) == -EINVAL) {
291 IWL_ERR(mvm, "Drained sta %d, but it is internal?\n",
292 sta_id);
293 continue;
294 }
295
296 if (!sta) {
297 IWL_ERR(mvm, "Drained sta %d, but it was NULL?\n",
298 sta_id);
299 continue;
300 }
301
302 WARN_ON(PTR_ERR(sta) != -EBUSY);
303 /* This station was removed and we waited until it got drained,
304 * we can now proceed and remove it.
305 */
306 ret = iwl_mvm_rm_sta_common(mvm, sta_id);
307 if (ret) {
308 IWL_ERR(mvm,
309 "Couldn't remove sta %d after it was drained\n",
310 sta_id);
311 continue;
312 }
313 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
314 clear_bit(sta_id, mvm->sta_drained);
315 }
316
317 mutex_unlock(&mvm->mutex);
318}
319
320int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
321 struct ieee80211_vif *vif,
322 struct ieee80211_sta *sta)
323{
324 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
325 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
326 int ret;
327
328 lockdep_assert_held(&mvm->mutex);
329
330 if (vif->type == NL80211_IFTYPE_STATION &&
331 mvmvif->ap_sta_id == mvm_sta->sta_id) {
332 /*
333 * Put a non-NULL since the fw station isn't removed.
334 * It will be removed after the MAC will be set as
335 * unassoc.
336 */
337 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
338 ERR_PTR(-EINVAL));
339
340 /* flush its queues here since we are freeing mvm_sta */
341 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
342
343 /* if we are associated - we can't remove the AP STA now */
344 if (vif->bss_conf.assoc)
345 return ret;
346
347 /* unassoc - go ahead - remove the AP STA now */
348 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
349 }
350
351 /*
352 * There are frames pending on the AC queues for this station.
353 * We need to wait until all the frames are drained...
354 */
355 if (atomic_read(&mvm_sta->pending_frames)) {
356 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
357 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
358 ERR_PTR(-EBUSY));
359 } else {
360 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
361 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
362 }
363
364 return ret;
365}
366
367int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
368 struct ieee80211_vif *vif,
369 u8 sta_id)
370{
371 int ret = iwl_mvm_rm_sta_common(mvm, sta_id);
372
373 lockdep_assert_held(&mvm->mutex);
374
375 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
376 return ret;
377}
378
379int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
380 u32 qmask)
381{
382 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
383 sta->sta_id = iwl_mvm_find_free_sta_id(mvm);
384 if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_STATION_COUNT))
385 return -ENOSPC;
386 }
387
388 sta->tfd_queue_msk = qmask;
389
390 /* put a non-NULL value so iterating over the stations won't stop */
391 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], ERR_PTR(-EINVAL));
392 return 0;
393}
394
395void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
396{
397 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
398 memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
399 sta->sta_id = IWL_MVM_STATION_COUNT;
400}
401
402static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
403 struct iwl_mvm_int_sta *sta,
404 const u8 *addr,
405 u16 mac_id, u16 color)
406{
407 struct iwl_mvm_add_sta_cmd cmd;
408 int ret;
409 u32 status;
410
411 lockdep_assert_held(&mvm->mutex);
412
413 memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd));
414 cmd.sta_id = sta->sta_id;
415 cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
416 color));
417
418 cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
419
420 if (addr)
421 memcpy(cmd.addr, addr, ETH_ALEN);
422
423 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
424 &cmd, &status);
425 if (ret)
426 return ret;
427
428 switch (status) {
429 case ADD_STA_SUCCESS:
430 IWL_DEBUG_INFO(mvm, "Internal station added.\n");
431 return 0;
432 default:
433 ret = -EIO;
434 IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
435 status);
436 break;
437 }
438 return ret;
439}
440
441int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
442{
443 int ret;
444
445 lockdep_assert_held(&mvm->mutex);
446
447 /* Add the aux station, but without any queues */
448 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0);
449 if (ret)
450 return ret;
451
452 ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
453 MAC_INDEX_AUX, 0);
454
455 if (ret)
456 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
457 return ret;
458}
459
460/*
461 * Send the add station command for the vif's broadcast station.
462 * Assumes that the station was already allocated.
463 *
464 * @mvm: the mvm component
465 * @vif: the interface to which the broadcast station is added
466 * @bsta: the broadcast station to add.
467 */
468int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
469 struct iwl_mvm_int_sta *bsta)
470{
471 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
472 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
473
474 lockdep_assert_held(&mvm->mutex);
475
476 if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT))
477 return -ENOSPC;
478
479 return iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
480 mvmvif->id, mvmvif->color);
481}
482
483/* Send the FW a request to remove the station from it's internal data
484 * structures, but DO NOT remove the entry from the local data structures. */
485int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
486 struct iwl_mvm_int_sta *bsta)
487{
488 int ret;
489
490 lockdep_assert_held(&mvm->mutex);
491
492 ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
493 if (ret)
494 IWL_WARN(mvm, "Failed sending remove station\n");
495 return ret;
496}
497
498/* Allocate a new station entry for the broadcast station to the given vif,
499 * and send it to the FW.
500 * Note that each P2P mac should have its own broadcast station.
501 *
502 * @mvm: the mvm component
503 * @vif: the interface to which the broadcast station is added
504 * @bsta: the broadcast station to add. */
505int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
506 struct iwl_mvm_int_sta *bsta)
507{
508 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
509 static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
510 u32 qmask;
511 int ret;
512
513 lockdep_assert_held(&mvm->mutex);
514
515 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
516 ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask);
517 if (ret)
518 return ret;
519
520 ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
521 mvmvif->id, mvmvif->color);
522
523 if (ret)
524 iwl_mvm_dealloc_int_sta(mvm, bsta);
525 return ret;
526}
527
528/*
529 * Send the FW a request to remove the station from it's internal data
530 * structures, and in addition remove it from the local data structure.
531 */
532int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
533{
534 int ret;
535
536 lockdep_assert_held(&mvm->mutex);
537
538 ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
539 if (ret)
540 return ret;
541
542 iwl_mvm_dealloc_int_sta(mvm, bsta);
543 return ret;
544}
545
546int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
547 int tid, u16 ssn, bool start)
548{
549 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
550 struct iwl_mvm_add_sta_cmd cmd = {};
551 int ret;
552 u32 status;
553
554 lockdep_assert_held(&mvm->mutex);
555
556 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
557 cmd.sta_id = mvm_sta->sta_id;
558 cmd.add_modify = STA_MODE_MODIFY;
559 cmd.add_immediate_ba_tid = (u8) tid;
560 cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
561 cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
562 STA_MODIFY_REMOVE_BA_TID;
563
564 status = ADD_STA_SUCCESS;
565 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
566 &cmd, &status);
567 if (ret)
568 return ret;
569
570 switch (status) {
571 case ADD_STA_SUCCESS:
572 IWL_DEBUG_INFO(mvm, "RX BA Session %sed in fw\n",
573 start ? "start" : "stopp");
574 break;
575 case ADD_STA_IMMEDIATE_BA_FAILURE:
576 IWL_WARN(mvm, "RX BA Session refused by fw\n");
577 ret = -ENOSPC;
578 break;
579 default:
580 ret = -EIO;
581 IWL_ERR(mvm, "RX BA Session failed %sing, status 0x%x\n",
582 start ? "start" : "stopp", status);
583 break;
584 }
585
586 return ret;
587}
588
589static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
590 int tid, u8 queue, bool start)
591{
592 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
593 struct iwl_mvm_add_sta_cmd cmd = {};
594 int ret;
595 u32 status;
596
597 lockdep_assert_held(&mvm->mutex);
598
599 if (start) {
600 mvm_sta->tfd_queue_msk |= BIT(queue);
601 mvm_sta->tid_disable_agg &= ~BIT(tid);
602 } else {
603 mvm_sta->tfd_queue_msk &= ~BIT(queue);
604 mvm_sta->tid_disable_agg |= BIT(tid);
605 }
606
607 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
608 cmd.sta_id = mvm_sta->sta_id;
609 cmd.add_modify = STA_MODE_MODIFY;
610 cmd.modify_mask = STA_MODIFY_QUEUES | STA_MODIFY_TID_DISABLE_TX;
611 cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
612 cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
613
614 status = ADD_STA_SUCCESS;
615 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
616 &cmd, &status);
617 if (ret)
618 return ret;
619
620 switch (status) {
621 case ADD_STA_SUCCESS:
622 break;
623 default:
624 ret = -EIO;
625 IWL_ERR(mvm, "TX BA Session failed %sing, status 0x%x\n",
626 start ? "start" : "stopp", status);
627 break;
628 }
629
630 return ret;
631}
632
633static const u8 tid_to_ac[] = {
634 IEEE80211_AC_BE,
635 IEEE80211_AC_BK,
636 IEEE80211_AC_BK,
637 IEEE80211_AC_BE,
638 IEEE80211_AC_VI,
639 IEEE80211_AC_VI,
640 IEEE80211_AC_VO,
641 IEEE80211_AC_VO,
642};
643
644int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
645 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
646{
647 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
648 struct iwl_mvm_tid_data *tid_data;
649 int txq_id;
650
651 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
652 return -EINVAL;
653
654 if (mvmsta->tid_data[tid].state != IWL_AGG_OFF) {
655 IWL_ERR(mvm, "Start AGG when state is not IWL_AGG_OFF %d!\n",
656 mvmsta->tid_data[tid].state);
657 return -ENXIO;
658 }
659
660 lockdep_assert_held(&mvm->mutex);
661
662 for (txq_id = IWL_MVM_FIRST_AGG_QUEUE;
663 txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++)
664 if (mvm->queue_to_mac80211[txq_id] ==
665 IWL_INVALID_MAC80211_QUEUE)
666 break;
667
668 if (txq_id > IWL_MVM_LAST_AGG_QUEUE) {
669 IWL_ERR(mvm, "Failed to allocate agg queue\n");
670 return -EIO;
671 }
672
673 /* the new tx queue is still connected to the same mac80211 queue */
674 mvm->queue_to_mac80211[txq_id] = vif->hw_queue[tid_to_ac[tid]];
675
676 spin_lock_bh(&mvmsta->lock);
677 tid_data = &mvmsta->tid_data[tid];
678 tid_data->ssn = SEQ_TO_SN(tid_data->seq_number);
679 tid_data->txq_id = txq_id;
680 *ssn = tid_data->ssn;
681
682 IWL_DEBUG_TX_QUEUES(mvm,
683 "Start AGG: sta %d tid %d queue %d - ssn = %d, next_recl = %d\n",
684 mvmsta->sta_id, tid, txq_id, tid_data->ssn,
685 tid_data->next_reclaimed);
686
687 if (tid_data->ssn == tid_data->next_reclaimed) {
688 tid_data->state = IWL_AGG_STARTING;
689 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
690 } else {
691 tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA;
692 }
693
694 spin_unlock_bh(&mvmsta->lock);
695
696 return 0;
697}
698
699int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
700 struct ieee80211_sta *sta, u16 tid, u8 buf_size)
701{
702 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
703 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
704 int queue, fifo, ret;
705 u16 ssn;
706
707 buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
708
709 spin_lock_bh(&mvmsta->lock);
710 ssn = tid_data->ssn;
711 queue = tid_data->txq_id;
712 tid_data->state = IWL_AGG_ON;
713 tid_data->ssn = 0xffff;
714 spin_unlock_bh(&mvmsta->lock);
715
716 fifo = iwl_mvm_ac_to_tx_fifo[tid_to_ac[tid]];
717
718 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
719 if (ret)
720 return -EIO;
721
722 iwl_trans_txq_enable(mvm->trans, queue, fifo, mvmsta->sta_id, tid,
723 buf_size, ssn);
724
725 /*
726 * Even though in theory the peer could have different
727 * aggregation reorder buffer sizes for different sessions,
728 * our ucode doesn't allow for that and has a global limit
729 * for each station. Therefore, use the minimum of all the
730 * aggregation sessions and our default value.
731 */
732 mvmsta->max_agg_bufsize =
733 min(mvmsta->max_agg_bufsize, buf_size);
734 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
735
736 if (mvm->cfg->ht_params->use_rts_for_aggregation) {
737 /*
738 * switch to RTS/CTS if it is the prefer protection
739 * method for HT traffic
740 */
741 mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
742 /*
743 * TODO: remove the TLC_RTS flag when we tear down the last
744 * AGG session (agg_tids_count in DVM)
745 */
746 }
747
748 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
749 sta->addr, tid);
750
751 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
752}
753
754int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
755 struct ieee80211_sta *sta, u16 tid)
756{
757 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
758 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
759 u16 txq_id;
760 int err;
761
762 spin_lock_bh(&mvmsta->lock);
763
764 txq_id = tid_data->txq_id;
765
766 IWL_DEBUG_TX_QUEUES(mvm, "Stop AGG: sta %d tid %d q %d state %d\n",
767 mvmsta->sta_id, tid, txq_id, tid_data->state);
768
769 switch (tid_data->state) {
770 case IWL_AGG_ON:
771 tid_data->ssn = SEQ_TO_SN(tid_data->seq_number);
772
773 IWL_DEBUG_TX_QUEUES(mvm,
774 "ssn = %d, next_recl = %d\n",
775 tid_data->ssn, tid_data->next_reclaimed);
776
777 /* There are still packets for this RA / TID in the HW */
778 if (tid_data->ssn != tid_data->next_reclaimed) {
779 tid_data->state = IWL_EMPTYING_HW_QUEUE_DELBA;
780 err = 0;
781 break;
782 }
783
784 tid_data->ssn = 0xffff;
785 iwl_trans_txq_disable(mvm->trans, txq_id);
786 /* fall through */
787 case IWL_AGG_STARTING:
788 case IWL_EMPTYING_HW_QUEUE_ADDBA:
789 /*
790 * The agg session has been stopped before it was set up. This
791 * can happen when the AddBA timer times out for example.
792 */
793
794 /* No barriers since we are under mutex */
795 lockdep_assert_held(&mvm->mutex);
796 mvm->queue_to_mac80211[txq_id] = IWL_INVALID_MAC80211_QUEUE;
797
798 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
799 tid_data->state = IWL_AGG_OFF;
800 err = 0;
801 break;
802 default:
803 IWL_ERR(mvm,
804 "Stopping AGG while state not ON or starting for %d on %d (%d)\n",
805 mvmsta->sta_id, tid, tid_data->state);
806 IWL_ERR(mvm,
807 "\ttid_data->txq_id = %d\n", tid_data->txq_id);
808 err = -EINVAL;
809 }
810
811 spin_unlock_bh(&mvmsta->lock);
812
813 return err;
814}
815
816static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
817{
818 int i;
819
820 lockdep_assert_held(&mvm->mutex);
821
822 i = find_first_zero_bit(mvm->fw_key_table, STA_KEY_MAX_NUM);
823
824 if (i == STA_KEY_MAX_NUM)
825 return STA_KEY_IDX_INVALID;
826
827 __set_bit(i, mvm->fw_key_table);
828
829 return i;
830}
831
832static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
833 struct ieee80211_sta *sta)
834{
835 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
836
837 if (sta) {
838 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
839
840 return mvm_sta->sta_id;
841 }
842
843 /*
844 * The device expects GTKs for station interfaces to be
845 * installed as GTKs for the AP station. If we have no
846 * station ID, then use AP's station ID.
847 */
848 if (vif->type == NL80211_IFTYPE_STATION &&
849 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
850 return mvmvif->ap_sta_id;
851
852 return IWL_INVALID_STATION;
853}
854
855static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
856 struct iwl_mvm_sta *mvm_sta,
857 struct ieee80211_key_conf *keyconf,
858 u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
859 u32 cmd_flags)
860{
861 __le16 key_flags;
862 struct iwl_mvm_add_sta_cmd cmd = {};
863 int ret, status;
864 u16 keyidx;
865 int i;
866
867 keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
868 STA_KEY_FLG_KEYID_MSK;
869 key_flags = cpu_to_le16(keyidx);
870 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_KEY_MAP);
871
872 switch (keyconf->cipher) {
873 case WLAN_CIPHER_SUITE_TKIP:
874 key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP);
875 cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
876 for (i = 0; i < 5; i++)
877 cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
878 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
879 break;
880 case WLAN_CIPHER_SUITE_CCMP:
881 key_flags |= cpu_to_le16(STA_KEY_FLG_CCM);
882 memcpy(cmd.key.key, keyconf->key, keyconf->keylen);
883 break;
884 default:
885 WARN_ON(1);
886 return -EINVAL;
887 }
888
889 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
890 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
891
892 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
893 cmd.key.key_offset = keyconf->hw_key_idx;
894 cmd.key.key_flags = key_flags;
895 cmd.add_modify = STA_MODE_MODIFY;
896 cmd.modify_mask = STA_MODIFY_KEY;
897 cmd.sta_id = sta_id;
898
899 status = ADD_STA_SUCCESS;
900 if (cmd_flags == CMD_SYNC)
901 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
902 &cmd, &status);
903 else
904 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
905 sizeof(cmd), &cmd);
906
907 switch (status) {
908 case ADD_STA_SUCCESS:
909 IWL_DEBUG_WEP(mvm, "MODIFY_STA: set dynamic key passed\n");
910 break;
911 default:
912 ret = -EIO;
913 IWL_ERR(mvm, "MODIFY_STA: set dynamic key failed\n");
914 break;
915 }
916
917 return ret;
918}
919
920static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
921 struct ieee80211_key_conf *keyconf,
922 u8 sta_id, bool remove_key)
923{
924 struct iwl_mvm_mgmt_mcast_key_cmd igtk_cmd = {};
925
926 /* verify the key details match the required command's expectations */
927 if (WARN_ON((keyconf->cipher != WLAN_CIPHER_SUITE_AES_CMAC) ||
928 (keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
929 (keyconf->keyidx != 4 && keyconf->keyidx != 5)))
930 return -EINVAL;
931
932 igtk_cmd.key_id = cpu_to_le32(keyconf->keyidx);
933 igtk_cmd.sta_id = cpu_to_le32(sta_id);
934
935 if (remove_key) {
936 igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
937 } else {
938 struct ieee80211_key_seq seq;
939 const u8 *pn;
940
941 memcpy(igtk_cmd.IGTK, keyconf->key, keyconf->keylen);
942 ieee80211_aes_cmac_calculate_k1_k2(keyconf,
943 igtk_cmd.K1, igtk_cmd.K2);
944 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
945 pn = seq.aes_cmac.pn;
946 igtk_cmd.receive_seq_cnt = cpu_to_le64(((u64) pn[5] << 0) |
947 ((u64) pn[4] << 8) |
948 ((u64) pn[3] << 16) |
949 ((u64) pn[2] << 24) |
950 ((u64) pn[1] << 32) |
951 ((u64) pn[0] << 40));
952 }
953
954 IWL_DEBUG_INFO(mvm, "%s igtk for sta %u\n",
955 remove_key ? "removing" : "installing",
956 igtk_cmd.sta_id);
957
958 return iwl_mvm_send_cmd_pdu(mvm, MGMT_MCAST_KEY, CMD_SYNC,
959 sizeof(igtk_cmd), &igtk_cmd);
960}
961
962
963static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
964 struct ieee80211_vif *vif,
965 struct ieee80211_sta *sta)
966{
967 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
968
969 if (sta)
970 return sta->addr;
971
972 if (vif->type == NL80211_IFTYPE_STATION &&
973 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
974 u8 sta_id = mvmvif->ap_sta_id;
975 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
976 lockdep_is_held(&mvm->mutex));
977 return sta->addr;
978 }
979
980
981 return NULL;
982}
983
984int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
985 struct ieee80211_vif *vif,
986 struct ieee80211_sta *sta,
987 struct ieee80211_key_conf *keyconf,
988 bool have_key_offset)
989{
990 struct iwl_mvm_sta *mvm_sta;
991 int ret;
992 u8 *addr, sta_id;
993 struct ieee80211_key_seq seq;
994 u16 p1k[5];
995
996 lockdep_assert_held(&mvm->mutex);
997
998 /* Get the station id from the mvm local station table */
999 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1000 if (sta_id == IWL_INVALID_STATION) {
1001 IWL_ERR(mvm, "Failed to find station id\n");
1002 return -EINVAL;
1003 }
1004
1005 if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
1006 ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
1007 goto end;
1008 }
1009
1010 /*
1011 * It is possible that the 'sta' parameter is NULL, and thus
1012 * there is a need to retrieve the sta from the local station table.
1013 */
1014 if (!sta) {
1015 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1016 lockdep_is_held(&mvm->mutex));
1017 if (IS_ERR_OR_NULL(sta)) {
1018 IWL_ERR(mvm, "Invalid station id\n");
1019 return -EINVAL;
1020 }
1021 }
1022
1023 mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1024 if (WARN_ON_ONCE(mvm_sta->vif != vif))
1025 return -EINVAL;
1026
1027 if (!have_key_offset) {
1028 /*
1029 * The D3 firmware hardcodes the PTK offset to 0, so we have to
1030 * configure it there. As a result, this workaround exists to
1031 * let the caller set the key offset (hw_key_idx), see d3.c.
1032 */
1033 keyconf->hw_key_idx = iwl_mvm_set_fw_key_idx(mvm);
1034 if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
1035 return -ENOSPC;
1036 }
1037
1038 switch (keyconf->cipher) {
1039 case WLAN_CIPHER_SUITE_TKIP:
1040 addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
1041 /* get phase 1 key from mac80211 */
1042 ieee80211_get_key_rx_seq(keyconf, 0, &seq);
1043 ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
1044 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1045 seq.tkip.iv32, p1k, CMD_SYNC);
1046 break;
1047 case WLAN_CIPHER_SUITE_CCMP:
1048 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1049 0, NULL, CMD_SYNC);
1050 break;
1051 default:
1052 IWL_ERR(mvm, "Unknown cipher %x\n", keyconf->cipher);
1053 ret = -EINVAL;
1054 }
1055
1056 if (ret)
1057 __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1058
1059end:
1060 IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
1061 keyconf->cipher, keyconf->keylen, keyconf->keyidx,
1062 sta->addr, ret);
1063 return ret;
1064}
1065
1066int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1067 struct ieee80211_vif *vif,
1068 struct ieee80211_sta *sta,
1069 struct ieee80211_key_conf *keyconf)
1070{
1071 struct iwl_mvm_sta *mvm_sta;
1072 struct iwl_mvm_add_sta_cmd cmd = {};
1073 __le16 key_flags;
1074 int ret, status;
1075 u8 sta_id;
1076
1077 lockdep_assert_held(&mvm->mutex);
1078
1079 /* Get the station id from the mvm local station table */
1080 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1081
1082 IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
1083 keyconf->keyidx, sta_id);
1084
1085 if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
1086 return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
1087
1088 ret = __test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
1089 if (!ret) {
1090 IWL_ERR(mvm, "offset %d not used in fw key table.\n",
1091 keyconf->hw_key_idx);
1092 return -ENOENT;
1093 }
1094
1095 if (sta_id == IWL_INVALID_STATION) {
1096 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
1097 return 0;
1098 }
1099
1100 /*
1101 * It is possible that the 'sta' parameter is NULL, and thus
1102 * there is a need to retrieve the sta from the local station table,
1103 * for example when a GTK is removed (where the sta_id will then be
1104 * the AP ID, and no station was passed by mac80211.)
1105 */
1106 if (!sta) {
1107 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1108 lockdep_is_held(&mvm->mutex));
1109 if (!sta) {
1110 IWL_ERR(mvm, "Invalid station id\n");
1111 return -EINVAL;
1112 }
1113 }
1114
1115 mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1116 if (WARN_ON_ONCE(mvm_sta->vif != vif))
1117 return -EINVAL;
1118
1119 key_flags = cpu_to_le16(keyconf->keyidx & STA_KEY_FLG_KEYID_MSK);
1120 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
1121 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
1122
1123 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
1124 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
1125
1126 cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
1127 cmd.key.key_flags = key_flags;
1128 cmd.key.key_offset = keyconf->hw_key_idx;
1129 cmd.sta_id = sta_id;
1130
1131 cmd.modify_mask = STA_MODIFY_KEY;
1132 cmd.add_modify = STA_MODE_MODIFY;
1133
1134 status = ADD_STA_SUCCESS;
1135 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
1136 &cmd, &status);
1137
1138 switch (status) {
1139 case ADD_STA_SUCCESS:
1140 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
1141 break;
1142 default:
1143 ret = -EIO;
1144 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
1145 break;
1146 }
1147
1148 return ret;
1149}
1150
1151void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1152 struct ieee80211_vif *vif,
1153 struct ieee80211_key_conf *keyconf,
1154 struct ieee80211_sta *sta, u32 iv32,
1155 u16 *phase1key)
1156{
1157 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1158 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1159
1160 if (sta_id == IWL_INVALID_STATION)
1161 return;
1162
1163 iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
1164 iv32, phase1key, CMD_ASYNC);
1165}
1166
1167void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
1168{
1169 struct iwl_mvm_add_sta_cmd cmd = {
1170 .add_modify = STA_MODE_MODIFY,
1171 .sta_id = sta_id,
1172 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1173 .sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE),
1174 };
1175 int ret;
1176
1177 /*
1178 * Same modify mask for sleep_tx_count and sleep_state_flags but this
1179 * should be fine since if we set the STA as "awake", then
1180 * sleep_tx_count is not relevant.
1181 */
1182 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1183 if (ret)
1184 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1185}
1186
1187void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id,
1188 enum ieee80211_frame_release_type reason,
1189 u16 cnt)
1190{
1191 u16 sleep_state_flags =
1192 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1193 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1194 struct iwl_mvm_add_sta_cmd cmd = {
1195 .add_modify = STA_MODE_MODIFY,
1196 .sta_id = sta_id,
1197 .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
1198 .sleep_tx_count = cpu_to_le16(cnt),
1199 /*
1200 * Same modify mask for sleep_tx_count and sleep_state_flags so
1201 * we must set the sleep_state_flags too.
1202 */
1203 .sleep_state_flags = cpu_to_le16(sleep_state_flags),
1204 };
1205 int ret;
1206
1207 /* TODO: somehow the fw doesn't seem to take PS_POLL into account */
1208 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1209 if (ret)
1210 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1211}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
new file mode 100644
index 000000000000..1bf301097984
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -0,0 +1,368 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __sta_h__
65#define __sta_h__
66
67#include <linux/spinlock.h>
68#include <net/mac80211.h>
69#include <linux/wait.h>
70
71#include "iwl-trans.h" /* for IWL_MAX_TID_COUNT */
72#include "fw-api.h" /* IWL_MVM_STATION_COUNT */
73#include "rs.h"
74
75struct iwl_mvm;
76
77/**
78 * DOC: station table - introduction
79 *
80 * The station table is a list of data structure that reprensent the stations.
81 * In STA/P2P client mode, the driver will hold one station for the AP/ GO.
82 * In GO/AP mode, the driver will have as many stations as associated clients.
83 * All these stations are reflected in the fw's station table. The driver
84 * keeps the fw's station table up to date with the ADD_STA command. Stations
85 * can be removed by the REMOVE_STA command.
86 *
87 * All the data related to a station is held in the structure %iwl_mvm_sta
88 * which is embed in the mac80211's %ieee80211_sta (in the drv_priv) area.
89 * This data includes the index of the station in the fw, per tid information
90 * (sequence numbers, Block-ack state machine, etc...). The stations are
91 * created and deleted by the %sta_state callback from %ieee80211_ops.
92 *
93 * The driver holds a map: %fw_id_to_mac_id that allows to fetch a
94 * %ieee80211_sta (and the %iwl_mvm_sta embedded into it) based on a fw
95 * station index. That way, the driver is able to get the tid related data in
96 * O(1) in time sensitive paths (Tx / Tx response / BA notification). These
97 * paths are triggered by the fw, and the driver needs to get a pointer to the
98 * %ieee80211 structure. This map helps to get that pointer quickly.
99 */
100
101/**
102 * DOC: station table - locking
103 *
104 * As stated before, the station is created / deleted by mac80211's %sta_state
105 * callback from %ieee80211_ops which can sleep. The next paragraph explains
106 * the locking of a single stations, the next ones relates to the station
107 * table.
108 *
109 * The station holds the sequence number per tid. So this data needs to be
110 * accessed in the Tx path (which is softIRQ). It also holds the Block-Ack
111 * information (the state machine / and the logic that checks if the queues
112 * were drained), so it also needs to be accessible from the Tx response flow.
113 * In short, the station needs to be access from sleepable context as well as
114 * from tasklets, so the station itself needs a spinlock.
115 *
116 * The writers of %fw_id_to_mac_id map are serialized by the global mutex of
117 * the mvm op_mode. This is possible since %sta_state can sleep.
118 * The pointers in this map are RCU protected, hence we won't replace the
119 * station while we have Tx / Tx response / BA notification running.
120 *
121 * If a station is deleted while it still has packets in its A-MPDU queues,
122 * then the reclaim flow will notice that there is no station in the map for
123 * sta_id and it will dump the responses.
124 */
125
126/**
127 * DOC: station table - internal stations
128 *
129 * The FW needs a few internal stations that are not reflected in
130 * mac80211, such as broadcast station in AP / GO mode, or AUX sta for
131 * scanning and P2P device (during the GO negotiation).
132 * For these kind of stations we have %iwl_mvm_int_sta struct which holds the
133 * data relevant for them from both %iwl_mvm_sta and %ieee80211_sta.
134 * Usually the data for these stations is static, so no locking is required,
135 * and no TID data as this is also not needed.
136 * One thing to note, is that these stations have an ID in the fw, but not
137 * in mac80211. In order to "reserve" them a sta_id in %fw_id_to_mac_id
138 * we fill ERR_PTR(EINVAL) in this mapping and all other dereferencing of
139 * pointers from this mapping need to check that the value is not error
140 * or NULL.
141 *
142 * Currently there is only one auxiliary station for scanning, initialized
143 * on init.
144 */
145
146/**
147 * DOC: station table - AP Station in STA mode
148 *
149 * %iwl_mvm_vif includes the index of the AP station in the fw's STA table:
150 * %ap_sta_id. To get the point to the coresponsding %ieee80211_sta,
151 * &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove
152 * the AP station from the fw before setting the MAC context as unassociated.
153 * Hence, %fw_id_to_mac_id[%ap_sta_id] will be NULLed when the AP station is
154 * removed by mac80211, but the station won't be removed in the fw until the
155 * VIF is set as unassociated. Then, %ap_sta_id will be invalidated.
156 */
157
158/**
159 * DOC: station table - Drain vs. Flush
160 *
161 * Flush means that all the frames in the SCD queue are dumped regardless the
162 * station to which they were sent. We do that when we disassociate and before
163 * we remove the STA of the AP. The flush can be done synchronously against the
164 * fw.
165 * Drain means that the fw will drop all the frames sent to a specific station.
166 * This is useful when a client (if we are IBSS / GO or AP) disassociates. In
167 * that case, we need to drain all the frames for that client from the AC queues
168 * that are shared with the other clients. Only then, we can remove the STA in
169 * the fw. In order to do so, we track the non-AMPDU packets for each station.
170 * If mac80211 removes a STA and if it still has non-AMPDU packets pending in
171 * the queues, we mark this station as %EBUSY in %fw_id_to_mac_id, and drop all
172 * the frames for this STA (%iwl_mvm_rm_sta). When the last frame is dropped
173 * (we know about it with its Tx response), we remove the station in fw and set
174 * it as %NULL in %fw_id_to_mac_id: this is the purpose of
175 * %iwl_mvm_sta_drained_wk.
176 */
177
178/**
179 * DOC: station table - fw restart
180 *
181 * When the fw asserts, or we have any other issue that requires to reset the
182 * driver, we require mac80211 to reconfigure the driver. Since the private
183 * data of the stations is embed in mac80211's %ieee80211_sta, that data will
184 * not be zeroed and needs to be reinitialized manually.
185 * %IWL_MVM_STATUS_IN_HW_RESTART is set during restart and that will hint us
186 * that we must not allocate a new sta_id but reuse the previous one. This
187 * means that the stations being re-added after the reset will have the same
188 * place in the fw as before the reset. We do need to zero the %fw_id_to_mac_id
189 * map, since the stations aren't in the fw any more. Internal stations that
190 * are not added by mac80211 will be re-added in the init flow that is called
191 * after the restart: mac80211 call's %iwl_mvm_mac_start which calls to
192 * %iwl_mvm_up.
193 */
194
195/**
196 * DOC: AP mode - PS
197 *
198 * When a station is asleep, the fw will set it as "asleep". All the
199 * non-aggregation frames to that station will be dropped by the fw
200 * (%TX_STATUS_FAIL_DEST_PS failure code).
201 * AMPDUs are in a separate queue that is stopped by the fw. We just need to
202 * let mac80211 know how many frames we have in these queues so that it can
203 * properly handle trigger frames.
204 * When the a trigger frame is received, mac80211 tells the driver to send
205 * frames from the AMPDU queues or AC queue depending on which queue are
206 * delivery-enabled and what TID has frames to transmit (Note that mac80211 has
207 * all the knowledege since all the non-agg frames are buffered / filtered, and
208 * the driver tells mac80211 about agg frames). The driver needs to tell the fw
209 * to let frames out even if the station is asleep. This is done by
210 * %iwl_mvm_sta_modify_sleep_tx_count.
211 * When we receive a frame from that station with PM bit unset, the
212 * driver needs to let the fw know that this station isn't alseep any more.
213 * This is done by %iwl_mvm_sta_modify_ps_wake.
214 *
215 * TODO - EOSP handling
216 */
217
218/**
219 * enum iwl_mvm_agg_state
220 *
221 * The state machine of the BA agreement establishment / tear down.
222 * These states relate to a specific RA / TID.
223 *
224 * @IWL_AGG_OFF: aggregation is not used
225 * @IWL_AGG_STARTING: aggregation are starting (between start and oper)
226 * @IWL_AGG_ON: aggregation session is up
227 * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the
228 * HW queue to be empty from packets for this RA /TID.
229 * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the
230 * HW queue to be empty from packets for this RA /TID.
231 */
232enum iwl_mvm_agg_state {
233 IWL_AGG_OFF = 0,
234 IWL_AGG_STARTING,
235 IWL_AGG_ON,
236 IWL_EMPTYING_HW_QUEUE_ADDBA,
237 IWL_EMPTYING_HW_QUEUE_DELBA,
238};
239
240/**
241 * struct iwl_mvm_tid_data - holds the states for each RA / TID
242 * @seq_number: the next WiFi sequence number to use
243 * @next_reclaimed: the WiFi sequence number of the next packet to be acked.
244 * This is basically (last acked packet++).
245 * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the
246 * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
247 * @state: state of the BA agreement establishment / tear down.
248 * @txq_id: Tx queue used by the BA session
249 * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or
250 * the first packet to be sent in legacy HW queue in Tx AGG stop flow.
251 * Basically when next_reclaimed reaches ssn, we can tell mac80211 that
252 * we are ready to finish the Tx AGG stop / start flow.
253 * @wait_for_ba: Expect block-ack before next Tx reply
254 */
255struct iwl_mvm_tid_data {
256 u16 seq_number;
257 u16 next_reclaimed;
258 /* The rest is Tx AGG related */
259 u32 rate_n_flags;
260 enum iwl_mvm_agg_state state;
261 u16 txq_id;
262 u16 ssn;
263 bool wait_for_ba;
264};
265
266/**
267 * struct iwl_mvm_sta - representation of a station in the driver
268 * @sta_id: the index of the station in the fw (will be replaced by id_n_color)
269 * @tfd_queue_msk: the tfd queues used by the station
270 * @mac_id_n_color: the MAC context this station is linked to
271 * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for
272 * tid.
273 * @max_agg_bufsize: the maximal size of the AGG buffer for this station
274 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
275 * and from Tx response flow, it needs a spinlock.
276 * @pending_frames: number of frames for this STA on the shared Tx queues.
277 * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
278 *
279 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
280 * in the structure for use by driver. This structure is placed in that
281 * space.
282 *
283 */
284struct iwl_mvm_sta {
285 u32 sta_id;
286 u32 tfd_queue_msk;
287 u32 mac_id_n_color;
288 u16 tid_disable_agg;
289 u8 max_agg_bufsize;
290 spinlock_t lock;
291 atomic_t pending_frames;
292 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
293 struct iwl_lq_sta lq_sta;
294 struct ieee80211_vif *vif;
295
296#ifdef CONFIG_PM_SLEEP
297 u16 last_seq_ctl;
298#endif
299};
300
301/**
302 * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or
303 * broadcast)
304 * @sta_id: the index of the station in the fw (will be replaced by id_n_color)
305 * @tfd_queue_msk: the tfd queues used by the station
306 */
307struct iwl_mvm_int_sta {
308 u32 sta_id;
309 u32 tfd_queue_msk;
310};
311
312int iwl_mvm_sta_add_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta);
313int iwl_mvm_add_sta(struct iwl_mvm *mvm,
314 struct ieee80211_vif *vif,
315 struct ieee80211_sta *sta);
316int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
317 struct ieee80211_vif *vif,
318 struct ieee80211_sta *sta);
319int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
320 struct ieee80211_vif *vif,
321 u8 sta_id);
322int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
323 struct ieee80211_vif *vif,
324 struct ieee80211_sta *sta,
325 struct ieee80211_key_conf *key,
326 bool have_key_offset);
327int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
328 struct ieee80211_vif *vif,
329 struct ieee80211_sta *sta,
330 struct ieee80211_key_conf *keyconf);
331
332void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
333 struct ieee80211_vif *vif,
334 struct ieee80211_key_conf *keyconf,
335 struct ieee80211_sta *sta, u32 iv32,
336 u16 *phase1key);
337
338/* AMPDU */
339int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
340 int tid, u16 ssn, bool start);
341int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
342 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
343int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
344 struct ieee80211_sta *sta, u16 tid, u8 buf_size);
345int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
346 struct ieee80211_sta *sta, u16 tid);
347
348int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
349int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
350 u32 qmask);
351void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
352 struct iwl_mvm_int_sta *sta);
353int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
354 struct iwl_mvm_int_sta *bsta);
355int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
356 struct iwl_mvm_int_sta *bsta);
357int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
358 struct iwl_mvm_int_sta *bsta);
359int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
360void iwl_mvm_sta_drained_wk(struct work_struct *wk);
361void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id);
362void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id,
363 enum ieee80211_frame_release_type reason,
364 u16 cnt);
365int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
366 bool drain);
367
368#endif /* __sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
new file mode 100644
index 000000000000..b9f076f4f17c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -0,0 +1,569 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/jiffies.h>
65#include <net/mac80211.h>
66
67#include "iwl-notif-wait.h"
68#include "iwl-trans.h"
69#include "fw-api.h"
70#include "time-event.h"
71#include "mvm.h"
72#include "iwl-io.h"
73#include "iwl-prph.h"
74
75/* A TimeUnit is 1024 microsecond */
76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
77#define MSEC_TO_TU(_msec) (_msec*1000/1024)
78
79void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
80 struct iwl_mvm_time_event_data *te_data)
81{
82 lockdep_assert_held(&mvm->time_event_lock);
83
84 if (te_data->id == TE_MAX)
85 return;
86
87 list_del(&te_data->list);
88 te_data->running = false;
89 te_data->uid = 0;
90 te_data->id = TE_MAX;
91 te_data->vif = NULL;
92}
93
94void iwl_mvm_roc_done_wk(struct work_struct *wk)
95{
96 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
97
98 synchronize_net();
99
100 /*
101 * Flush the offchannel queue -- this is called when the time
102 * event finishes or is cancelled, so that frames queued for it
103 * won't get stuck on the queue and be transmitted in the next
104 * time event.
105 * We have to send the command asynchronously since this cannot
106 * be under the mutex for locking reasons, but that's not an
107 * issue as it will have to complete before the next command is
108 * executed, and a new time event means a new command.
109 */
110 iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false);
111}
112
113static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
114{
115 /*
116 * First, clear the ROC_RUNNING status bit. This will cause the TX
117 * path to drop offchannel transmissions. That would also be done
118 * by mac80211, but it is racy, in particular in the case that the
119 * time event actually completed in the firmware (which is handled
120 * in iwl_mvm_te_handle_notif).
121 */
122 clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
123
124 /*
125 * Of course, our status bit is just as racy as mac80211, so in
126 * addition, fire off the work struct which will drop all frames
127 * from the hardware queues that made it through the race. First
128 * it will of course synchronize the TX path to make sure that
129 * any *new* TX will be rejected.
130 */
131 schedule_work(&mvm->roc_done_wk);
132}
133
134/*
135 * Handles a FW notification for an event that is known to the driver.
136 *
137 * @mvm: the mvm component
138 * @te_data: the time event data
139 * @notif: the notification data corresponding the time event data.
140 */
141static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
142 struct iwl_mvm_time_event_data *te_data,
143 struct iwl_time_event_notif *notif)
144{
145 lockdep_assert_held(&mvm->time_event_lock);
146
147 IWL_DEBUG_TE(mvm, "Handle time event notif - UID = 0x%x action %d\n",
148 le32_to_cpu(notif->unique_id),
149 le32_to_cpu(notif->action));
150
151 /*
152 * The FW sends the start/end time event notifications even for events
153 * that it fails to schedule. This is indicated in the status field of
154 * the notification. This happens in cases that the scheduler cannot
155 * find a schedule that can handle the event (for example requesting a
156 * P2P Device discoveribility, while there are other higher priority
157 * events in the system).
158 */
159 WARN_ONCE(!le32_to_cpu(notif->status),
160 "Failed to schedule time event\n");
161
162 if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) {
163 IWL_DEBUG_TE(mvm,
164 "TE ended - current time %lu, estimated end %lu\n",
165 jiffies, te_data->end_jiffies);
166
167 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
168 ieee80211_remain_on_channel_expired(mvm->hw);
169 iwl_mvm_roc_finished(mvm);
170 }
171
172 /*
173 * By now, we should have finished association
174 * and know the dtim period.
175 */
176 if (te_data->vif->type == NL80211_IFTYPE_STATION &&
177 (!te_data->vif->bss_conf.assoc ||
178 !te_data->vif->bss_conf.dtim_period))
179 IWL_ERR(mvm,
180 "No assocation and the time event is over already...\n");
181
182 iwl_mvm_te_clear_data(mvm, te_data);
183 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) {
184 te_data->running = true;
185 te_data->end_jiffies = jiffies +
186 TU_TO_JIFFIES(te_data->duration);
187
188 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
189 set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
190 ieee80211_ready_on_channel(mvm->hw);
191 }
192 } else {
193 IWL_WARN(mvm, "Got TE with unknown action\n");
194 }
195}
196
197/*
198 * The Rx handler for time event notifications
199 */
200int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
201 struct iwl_rx_cmd_buffer *rxb,
202 struct iwl_device_cmd *cmd)
203{
204 struct iwl_rx_packet *pkt = rxb_addr(rxb);
205 struct iwl_time_event_notif *notif = (void *)pkt->data;
206 struct iwl_mvm_time_event_data *te_data, *tmp;
207
208 IWL_DEBUG_TE(mvm, "Time event notification - UID = 0x%x action %d\n",
209 le32_to_cpu(notif->unique_id),
210 le32_to_cpu(notif->action));
211
212 spin_lock_bh(&mvm->time_event_lock);
213 list_for_each_entry_safe(te_data, tmp, &mvm->time_event_list, list) {
214 if (le32_to_cpu(notif->unique_id) == te_data->uid)
215 iwl_mvm_te_handle_notif(mvm, te_data, notif);
216 }
217 spin_unlock_bh(&mvm->time_event_lock);
218
219 return 0;
220}
221
222static bool iwl_mvm_time_event_notif(struct iwl_notif_wait_data *notif_wait,
223 struct iwl_rx_packet *pkt, void *data)
224{
225 struct iwl_mvm *mvm =
226 container_of(notif_wait, struct iwl_mvm, notif_wait);
227 struct iwl_mvm_time_event_data *te_data = data;
228 struct ieee80211_vif *vif = te_data->vif;
229 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
230 struct iwl_time_event_notif *notif;
231 struct iwl_time_event_resp *resp;
232
233 u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
234
235 /* until we do something else */
236 WARN_ON(te_data->id != TE_BSS_STA_AGGRESSIVE_ASSOC);
237
238 switch (pkt->hdr.cmd) {
239 case TIME_EVENT_CMD:
240 resp = (void *)pkt->data;
241 /* TODO: I can't check that since the fw is buggy - it doesn't
242 * put the right values when we remove a TE. We can be here
243 * when we remove a TE because the remove TE command is sent in
244 * ASYNC...
245 * WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color));
246 */
247 te_data->uid = le32_to_cpu(resp->unique_id);
248 IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid);
249 return false;
250
251 case TIME_EVENT_NOTIFICATION:
252 notif = (void *)pkt->data;
253 WARN_ON(le32_to_cpu(notif->status) != 1);
254 WARN_ON(mac_id_n_color != le32_to_cpu(notif->id_and_color));
255 /* check if this is our Time Event that is starting */
256 if (le32_to_cpu(notif->unique_id) != te_data->uid)
257 return false;
258 IWL_DEBUG_TE(mvm, "Event %d is starting - time is %d\n",
259 te_data->uid, le32_to_cpu(notif->timestamp));
260
261 WARN_ONCE(!le32_to_cpu(notif->status),
262 "Failed to schedule protected session TE\n");
263
264 te_data->running = true;
265 te_data->end_jiffies = jiffies +
266 TU_TO_JIFFIES(te_data->duration);
267 return true;
268
269 default:
270 WARN_ON(1);
271 return false;
272 };
273}
274
275void iwl_mvm_protect_session(struct iwl_mvm *mvm,
276 struct ieee80211_vif *vif,
277 u32 duration, u32 min_duration)
278{
279 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
280 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
281 static const u8 time_event_notif[] = { TIME_EVENT_CMD,
282 TIME_EVENT_NOTIFICATION };
283 struct iwl_notification_wait wait_time_event;
284 struct iwl_time_event_cmd time_cmd = {};
285 int ret;
286
287 lockdep_assert_held(&mvm->mutex);
288
289 if (te_data->running &&
290 time_after(te_data->end_jiffies,
291 jiffies + TU_TO_JIFFIES(min_duration))) {
292 IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n",
293 jiffies_to_msecs(te_data->end_jiffies - jiffies));
294 return;
295 }
296
297 if (te_data->running) {
298 IWL_DEBUG_TE(mvm, "extend 0x%x: only %u ms left\n",
299 te_data->uid,
300 jiffies_to_msecs(te_data->end_jiffies - jiffies));
301 /*
302 * we don't have enough time
303 * cancel the current TE and issue a new one
304 * Of course it would be better to remove the old one only
305 * when the new one is added, but we don't care if we are off
306 * channel for a bit. All we need to do, is not to return
307 * before we actually begin to be on the channel.
308 */
309 iwl_mvm_stop_session_protection(mvm, vif);
310 }
311
312 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
313 time_event_notif,
314 ARRAY_SIZE(time_event_notif),
315 iwl_mvm_time_event_notif,
316 &mvmvif->time_event_data);
317
318 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
319 time_cmd.id_and_color =
320 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
321 time_cmd.id = cpu_to_le32(TE_BSS_STA_AGGRESSIVE_ASSOC);
322
323 time_cmd.apply_time =
324 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG));
325 time_cmd.dep_policy = TE_INDEPENDENT;
326 time_cmd.is_present = cpu_to_le32(1);
327 time_cmd.max_frags = cpu_to_le32(TE_FRAG_NONE);
328 time_cmd.max_delay = cpu_to_le32(500);
329 /* TODO: why do we need to interval = bi if it is not periodic? */
330 time_cmd.interval = cpu_to_le32(1);
331 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1));
332 time_cmd.duration = cpu_to_le32(duration);
333 time_cmd.repeat = cpu_to_le32(1);
334 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END);
335
336 te_data->vif = vif;
337 te_data->duration = duration;
338
339 spin_lock_bh(&mvm->time_event_lock);
340 te_data->id = le32_to_cpu(time_cmd.id);
341 list_add_tail(&te_data->list, &mvm->time_event_list);
342 spin_unlock_bh(&mvm->time_event_lock);
343
344 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
345 sizeof(time_cmd), &time_cmd);
346 if (ret) {
347 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
348 goto out_remove_notif;
349 }
350
351 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ);
352 if (ret) {
353 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
354 spin_lock_bh(&mvm->time_event_lock);
355 iwl_mvm_te_clear_data(mvm, te_data);
356 spin_unlock_bh(&mvm->time_event_lock);
357 }
358
359 return;
360
361out_remove_notif:
362 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
363}
364
365/*
366 * Explicit request to remove a time event. The removal of a time event needs to
367 * be synchronized with the flow of a time event's end notification, which also
368 * removes the time event from the op mode data structures.
369 */
370void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
371 struct iwl_mvm_vif *mvmvif,
372 struct iwl_mvm_time_event_data *te_data)
373{
374 struct iwl_time_event_cmd time_cmd = {};
375 u32 id, uid;
376 int ret;
377
378 /*
379 * It is possible that by the time we got to this point the time
380 * event was already removed.
381 */
382 spin_lock_bh(&mvm->time_event_lock);
383
384 /* Save time event uid before clearing its data */
385 uid = te_data->uid;
386 id = te_data->id;
387
388 /*
389 * The clear_data function handles time events that were already removed
390 */
391 iwl_mvm_te_clear_data(mvm, te_data);
392 spin_unlock_bh(&mvm->time_event_lock);
393
394 /*
395 * It is possible that by the time we try to remove it, the time event
396 * has already ended and removed. In such a case there is no need to
397 * send a removal command.
398 */
399 if (id == TE_MAX) {
400 IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", uid);
401 return;
402 }
403
404 /* When we remove a TE, the UID is to be set in the id field */
405 time_cmd.id = cpu_to_le32(uid);
406 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE);
407 time_cmd.id_and_color =
408 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
409
410 IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
411 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_ASYNC,
412 sizeof(time_cmd), &time_cmd);
413 if (WARN_ON(ret))
414 return;
415}
416
417void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
418 struct ieee80211_vif *vif)
419{
420 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
421 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
422
423 lockdep_assert_held(&mvm->mutex);
424 iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
425}
426
427static bool iwl_mvm_roc_te_notif(struct iwl_notif_wait_data *notif_wait,
428 struct iwl_rx_packet *pkt, void *data)
429{
430 struct iwl_mvm *mvm =
431 container_of(notif_wait, struct iwl_mvm, notif_wait);
432 struct iwl_mvm_time_event_data *te_data = data;
433 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
434 struct iwl_time_event_resp *resp;
435
436 u32 mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
437
438 /* until we do something else */
439 WARN_ON(te_data->id != TE_P2P_DEVICE_DISCOVERABLE);
440
441 switch (pkt->hdr.cmd) {
442 case TIME_EVENT_CMD:
443 resp = (void *)pkt->data;
444 WARN_ON(mac_id_n_color != le32_to_cpu(resp->id_and_color));
445 te_data->uid = le32_to_cpu(resp->unique_id);
446 IWL_DEBUG_TE(mvm, "Got response - UID = 0x%x\n", te_data->uid);
447 return true;
448
449 default:
450 WARN_ON(1);
451 return false;
452 };
453}
454
455int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
456 int duration)
457{
458 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
459 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
460 static const u8 roc_te_notif[] = { TIME_EVENT_CMD };
461 struct iwl_notification_wait wait_time_event;
462 struct iwl_time_event_cmd time_cmd = {};
463 int ret;
464
465 lockdep_assert_held(&mvm->mutex);
466 if (te_data->running) {
467 IWL_WARN(mvm, "P2P_DEVICE remain on channel already running\n");
468 return -EBUSY;
469 }
470
471 /*
472 * Flush the done work, just in case it's still pending, so that
473 * the work it does can complete and we can accept new frames.
474 */
475 flush_work(&mvm->roc_done_wk);
476
477 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
478 roc_te_notif,
479 ARRAY_SIZE(roc_te_notif),
480 iwl_mvm_roc_te_notif,
481 &mvmvif->time_event_data);
482
483 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
484 time_cmd.id_and_color =
485 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
486 time_cmd.id = cpu_to_le32(TE_P2P_DEVICE_DISCOVERABLE);
487
488 time_cmd.apply_time = cpu_to_le32(0);
489 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
490 time_cmd.is_present = cpu_to_le32(1);
491
492 time_cmd.interval = cpu_to_le32(1);
493
494 /*
495 * TE_P2P_DEVICE_DISCOVERABLE can have lower priority than other events
496 * that are being scheduled by the driver/fw, and thus it might not be
497 * scheduled. To improve the chances of it being scheduled, allow it to
498 * be fragmented.
499 * In addition, for the same reasons, allow to delay the scheduling of
500 * the time event.
501 */
502 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
503 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
504 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
505 time_cmd.repeat = cpu_to_le32(1);
506 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END);
507
508 /* Push the te data to the tracked te list */
509 te_data->vif = vif;
510 te_data->duration = MSEC_TO_TU(duration);
511
512 spin_lock_bh(&mvm->time_event_lock);
513 te_data->id = le32_to_cpu(time_cmd.id);
514 list_add_tail(&te_data->list, &mvm->time_event_list);
515 spin_unlock_bh(&mvm->time_event_lock);
516
517 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
518 sizeof(time_cmd), &time_cmd);
519 if (ret) {
520 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
521 goto out_remove_notif;
522 }
523
524 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1 * HZ);
525 if (ret) {
526 IWL_ERR(mvm, "%s - failed on timeout\n", __func__);
527 iwl_mvm_te_clear_data(mvm, te_data);
528 }
529
530 return ret;
531
532out_remove_notif:
533 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
534 return ret;
535}
536
537void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
538{
539 struct iwl_mvm_vif *mvmvif;
540 struct iwl_mvm_time_event_data *te_data;
541
542 lockdep_assert_held(&mvm->mutex);
543
544 /*
545 * Iterate over the list of time events and find the time event that is
546 * associated with a P2P_DEVICE interface.
547 * This assumes that a P2P_DEVICE interface can have only a single time
548 * event at any given time and this time event coresponds to a ROC
549 * request
550 */
551 mvmvif = NULL;
552 spin_lock_bh(&mvm->time_event_lock);
553 list_for_each_entry(te_data, &mvm->time_event_list, list) {
554 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
555 mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
556 break;
557 }
558 }
559 spin_unlock_bh(&mvm->time_event_lock);
560
561 if (!mvmvif) {
562 IWL_WARN(mvm, "P2P_DEVICE no remain on channel event\n");
563 return;
564 }
565
566 iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
567
568 iwl_mvm_roc_finished(mvm);
569}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
new file mode 100644
index 000000000000..64fb57a5ab43
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -0,0 +1,214 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __time_event_h__
65#define __time_event_h__
66
67#include "fw-api.h"
68
69#include "mvm.h"
70
71/**
72 * DOC: Time Events - what is it?
73 *
74 * Time Events are a fw feature that allows the driver to control the presence
75 * of the device on the channel. Since the fw supports multiple channels
76 * concurrently, the fw may choose to jump to another channel at any time.
77 * In order to make sure that the fw is on a specific channel at a certain time
78 * and for a certain duration, the driver needs to issue a time event.
79 *
80 * The simplest example is for BSS association. The driver issues a time event,
81 * waits for it to start, and only then tells mac80211 that we can start the
82 * association. This way, we make sure that the association will be done
83 * smoothly and won't be interrupted by channel switch decided within the fw.
84 */
85
86 /**
87 * DOC: The flow against the fw
88 *
89 * When the driver needs to make sure we are in a certain channel, at a certain
90 * time and for a certain duration, it sends a Time Event. The flow against the
91 * fw goes like this:
92 * 1) Driver sends a TIME_EVENT_CMD to the fw
93 * 2) Driver gets the response for that command. This response contains the
94 * Unique ID (UID) of the event.
95 * 3) The fw sends notification when the event starts.
96 *
97 * Of course the API provides various options that allow to cover parameters
98 * of the flow.
99 * What is the duration of the event?
100 * What is the start time of the event?
101 * Is there an end-time for the event?
102 * How much can the event be delayed?
103 * Can the event be split?
104 * If yes what is the maximal number of chunks?
105 * etc...
106 */
107
108/**
109 * DOC: Abstraction to the driver
110 *
111 * In order to simplify the use of time events to the rest of the driver,
112 * we abstract the use of time events. This component provides the functions
113 * needed by the driver.
114 */
115
116#define IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
117#define IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
118
119/**
120 * iwl_mvm_protect_session - start / extend the session protection.
121 * @mvm: the mvm component
122 * @vif: the virtual interface for which the session is issued
123 * @duration: the duration of the session in TU.
124 * @min_duration: will start a new session if the current session will end
125 * in less than min_duration.
126 *
127 * This function can be used to start a session protection which means that the
128 * fw will stay on the channel for %duration_ms milliseconds. This function
129 * will block (sleep) until the session starts. This function can also be used
130 * to extend a currently running session.
131 * This function is meant to be used for BSS association for example, where we
132 * want to make sure that the fw stays on the channel during the association.
133 */
134void iwl_mvm_protect_session(struct iwl_mvm *mvm,
135 struct ieee80211_vif *vif,
136 u32 duration, u32 min_duration);
137
138/**
139 * iwl_mvm_stop_session_protection - cancel the session protection.
140 * @mvm: the mvm component
141 * @vif: the virtual interface for which the session is issued
142 *
143 * This functions cancels the session protection which is an act of good
144 * citizenship. If it is not needed any more it should be cancelled because
145 * the other bindings wait for the medium during that time.
146 * This funtions doesn't sleep.
147 */
148void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
149 struct ieee80211_vif *vif);
150
151/*
152 * iwl_mvm_rx_time_event_notif - handles %TIME_EVENT_NOTIFICATION.
153 */
154int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
155 struct iwl_rx_cmd_buffer *rxb,
156 struct iwl_device_cmd *cmd);
157
158/**
159 * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionlity
160 * @mvm: the mvm component
161 * @vif: the virtual interface for which the roc is requested. It is assumed
162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE
163 * @duration: the requested duration in millisecond for the fw to be on the
164 * channel that is bound to the vif.
165 *
166 * This function can be used to issue a remain on channel session,
167 * which means that the fw will stay in the channel for the request %duration
168 * milliseconds. The function is async, meaning that it only issues the ROC
169 * request but does not wait for it to start. Once the FW is ready to serve the
170 * ROC request, it will issue a notification to the driver that it is on the
171 * requested channel. Once the FW completes the ROC request it will issue
172 * another notification to the driver.
173 */
174int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
175 int duration);
176
177/**
178 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
179 * @mvm: the mvm component
180 *
181 * This function can be used to cancel an ongoing ROC session.
182 * The function is async, it will instruct the FW to stop serving the ROC
183 * session, but will not wait for the actual stopping of the session.
184 */
185void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm);
186
187/**
188 * iwl_mvm_remove_time_event - general function to clean up of time event
189 * @mvm: the mvm component
190 * @vif: the vif to which the time event belongs
191 * @te_data: the time event data that corresponds to that time event
192 *
193 * This function can be used to cancel a time event regardless its type.
194 * It is useful for cleaning up time events running before removing an
195 * interface.
196 */
197void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
198 struct iwl_mvm_vif *mvmvif,
199 struct iwl_mvm_time_event_data *te_data);
200
201/**
202 * iwl_mvm_te_clear_data - remove time event from list
203 * @mvm: the mvm component
204 * @te_data: the time event data to remove
205 *
206 * This function is mostly internal, it is made available here only
207 * for firmware restart purposes.
208 */
209void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
210 struct iwl_mvm_time_event_data *te_data);
211
212void iwl_mvm_roc_done_wk(struct work_struct *wk);
213
214#endif /* __time_event_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
new file mode 100644
index 000000000000..cada8efe0cca
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -0,0 +1,916 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <linux/ieee80211.h>
64#include <linux/etherdevice.h>
65
66#include "iwl-trans.h"
67#include "iwl-eeprom-parse.h"
68#include "mvm.h"
69#include "sta.h"
70
71/*
72 * Sets most of the Tx cmd's fields
73 */
74static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
75 struct iwl_tx_cmd *tx_cmd,
76 struct ieee80211_tx_info *info, u8 sta_id)
77{
78 struct ieee80211_hdr *hdr = (void *)skb->data;
79 __le16 fc = hdr->frame_control;
80 u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags);
81 u32 len = skb->len + FCS_LEN;
82
83 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
84 tx_flags |= TX_CMD_FLG_ACK;
85 else
86 tx_flags &= ~TX_CMD_FLG_ACK;
87
88 if (ieee80211_is_probe_resp(fc))
89 tx_flags |= TX_CMD_FLG_TSF;
90 else if (ieee80211_is_back_req(fc))
91 tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
92
93 /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
94 if (info->band == IEEE80211_BAND_2GHZ &&
95 (skb->protocol == cpu_to_be16(ETH_P_PAE) ||
96 is_multicast_ether_addr(hdr->addr1) ||
97 ieee80211_is_back_req(fc) ||
98 ieee80211_is_mgmt(fc)))
99 tx_flags |= TX_CMD_FLG_BT_DIS;
100
101 if (ieee80211_has_morefrags(fc))
102 tx_flags |= TX_CMD_FLG_MORE_FRAG;
103
104 if (ieee80211_is_data_qos(fc)) {
105 u8 *qc = ieee80211_get_qos_ctl(hdr);
106 tx_cmd->tid_tspec = qc[0] & 0xf;
107 tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
108 } else {
109 tx_cmd->tid_tspec = IWL_TID_NON_QOS;
110 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
111 tx_flags |= TX_CMD_FLG_SEQ_CTL;
112 else
113 tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
114 }
115
116 if (ieee80211_is_mgmt(fc)) {
117 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
118 tx_cmd->pm_frame_timeout = cpu_to_le16(3);
119 else
120 tx_cmd->pm_frame_timeout = cpu_to_le16(2);
121
122 /* The spec allows Action frames in A-MPDU, we don't support
123 * it
124 */
125 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU);
126 } else {
127 tx_cmd->pm_frame_timeout = 0;
128 }
129
130 if (info->flags & IEEE80211_TX_CTL_AMPDU)
131 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
132
133 if (ieee80211_is_data(fc) && len > mvm->rts_threshold &&
134 !is_multicast_ether_addr(ieee80211_get_DA(hdr)))
135 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
136
137 tx_cmd->driver_txop = 0;
138 tx_cmd->tx_flags = cpu_to_le32(tx_flags);
139 /* Total # bytes to be transmitted */
140 tx_cmd->len = cpu_to_le16((u16)skb->len);
141 tx_cmd->next_frame_len = 0;
142 tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
143 tx_cmd->sta_id = sta_id;
144}
145
146/*
147 * Sets the fields in the Tx cmd that are rate related
148 */
149static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
150 struct iwl_tx_cmd *tx_cmd,
151 struct ieee80211_tx_info *info,
152 struct ieee80211_sta *sta,
153 __le16 fc)
154{
155 u32 rate_flags;
156 int rate_idx;
157 u8 rate_plcp;
158
159 /* Set retry limit on RTS packets */
160 tx_cmd->rts_retry_limit = IWL_RTS_DFAULT_RETRY_LIMIT;
161
162 /* Set retry limit on DATA packets and Probe Responses*/
163 if (ieee80211_is_probe_resp(fc)) {
164 tx_cmd->data_retry_limit = IWL_MGMT_DFAULT_RETRY_LIMIT;
165 tx_cmd->rts_retry_limit =
166 min(tx_cmd->data_retry_limit, tx_cmd->rts_retry_limit);
167 } else if (ieee80211_is_back_req(fc)) {
168 tx_cmd->data_retry_limit = IWL_BAR_DFAULT_RETRY_LIMIT;
169 } else {
170 tx_cmd->data_retry_limit = IWL_DEFAULT_TX_RETRY;
171 }
172
173 /*
174 * for data packets, rate info comes from the table inside he fw. This
175 * table is controlled by LINK_QUALITY commands
176 */
177
178 if (ieee80211_is_data(fc)) {
179 tx_cmd->initial_rate_index = 0;
180 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
181 return;
182 } else if (ieee80211_is_back_req(fc)) {
183 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
184 }
185
186 /* HT rate doesn't make sense for a non data frame */
187 WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
188 "Got an HT rate for a non data frame 0x%x\n",
189 info->control.rates[0].flags);
190
191 rate_idx = info->control.rates[0].idx;
192 /* if the rate isn't a well known legacy rate, take the lowest one */
193 if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT_LEGACY)
194 rate_idx = rate_lowest_index(
195 &mvm->nvm_data->bands[info->band], sta);
196
197 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
198 if (info->band == IEEE80211_BAND_5GHZ)
199 rate_idx += IWL_FIRST_OFDM_RATE;
200
201 /* For 2.4 GHZ band, check that there is no need to remap */
202 BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
203
204 /* Get PLCP rate for tx_cmd->rate_n_flags */
205 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
206
207 mvm->mgmt_last_antenna_idx =
208 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant,
209 mvm->mgmt_last_antenna_idx);
210 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
211
212 /* Set CCK flag as needed */
213 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
214 rate_flags |= RATE_MCS_CCK_MSK;
215
216 /* Set the rate in the TX cmd */
217 tx_cmd->rate_n_flags = cpu_to_le32((u32)rate_plcp | rate_flags);
218}
219
220/*
221 * Sets the fields in the Tx cmd that are crypto related
222 */
223static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
224 struct ieee80211_tx_info *info,
225 struct iwl_tx_cmd *tx_cmd,
226 struct sk_buff *skb_frag)
227{
228 struct ieee80211_key_conf *keyconf = info->control.hw_key;
229
230 switch (keyconf->cipher) {
231 case WLAN_CIPHER_SUITE_CCMP:
232 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
233 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
234 if (info->flags & IEEE80211_TX_CTL_AMPDU)
235 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_CCMP_AGG);
236 break;
237
238 case WLAN_CIPHER_SUITE_TKIP:
239 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
240 ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
241 break;
242
243 case WLAN_CIPHER_SUITE_WEP104:
244 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
245 /* fall through */
246 case WLAN_CIPHER_SUITE_WEP40:
247 tx_cmd->sec_ctl |= TX_CMD_SEC_WEP |
248 ((keyconf->keyidx << TX_CMD_SEC_WEP_KEY_IDX_POS) &
249 TX_CMD_SEC_WEP_KEY_IDX_MSK);
250
251 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
252 break;
253 default:
254 IWL_ERR(mvm, "Unknown encode cipher %x\n", keyconf->cipher);
255 break;
256 }
257}
258
259/*
260 * Allocates and sets the Tx cmd the driver data pointers in the skb
261 */
262static struct iwl_device_cmd *
263iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
264 struct ieee80211_sta *sta, u8 sta_id)
265{
266 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
267 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
268 struct iwl_device_cmd *dev_cmd;
269 struct iwl_tx_cmd *tx_cmd;
270
271 dev_cmd = iwl_trans_alloc_tx_cmd(mvm->trans);
272
273 if (unlikely(!dev_cmd))
274 return NULL;
275
276 memset(dev_cmd, 0, sizeof(*dev_cmd));
277 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
278
279 if (info->control.hw_key)
280 iwl_mvm_set_tx_cmd_crypto(mvm, info, tx_cmd, skb);
281
282 iwl_mvm_set_tx_cmd(mvm, skb, tx_cmd, info, sta_id);
283
284 iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control);
285
286 memset(&info->status, 0, sizeof(info->status));
287
288 info->driver_data[0] = NULL;
289 info->driver_data[1] = dev_cmd;
290
291 return dev_cmd;
292}
293
294int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
295{
296 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
297 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
298 struct iwl_device_cmd *dev_cmd;
299 struct iwl_tx_cmd *tx_cmd;
300 u8 sta_id;
301
302 if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU))
303 return -1;
304
305 if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
306 (!info->control.vif ||
307 info->hw_queue != info->control.vif->cab_queue)))
308 return -1;
309
310 /*
311 * If the interface on which frame is sent is the P2P_DEVICE
312 * or an AP/GO interface use the broadcast station associated
313 * with it; otherwise use the AUX station.
314 */
315 if (info->control.vif &&
316 (info->control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
317 info->control.vif->type == NL80211_IFTYPE_AP)) {
318 struct iwl_mvm_vif *mvmvif =
319 iwl_mvm_vif_from_mac80211(info->control.vif);
320 sta_id = mvmvif->bcast_sta.sta_id;
321 } else {
322 sta_id = mvm->aux_sta.sta_id;
323 }
324
325 IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, info->hw_queue);
326
327 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, NULL, sta_id);
328 if (!dev_cmd)
329 return -1;
330
331 /* From now on, we cannot access info->control */
332 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
333
334 /* Copy MAC header from skb into command buffer */
335 memcpy(tx_cmd->hdr, hdr, ieee80211_hdrlen(hdr->frame_control));
336
337 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, info->hw_queue)) {
338 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
339 return -1;
340 }
341
342 return 0;
343}
344
345/*
346 * Sets the fields in the Tx cmd that are crypto related
347 */
348int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
349 struct ieee80211_sta *sta)
350{
351 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
352 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
353 struct iwl_mvm_sta *mvmsta;
354 struct iwl_device_cmd *dev_cmd;
355 struct iwl_tx_cmd *tx_cmd;
356 __le16 fc;
357 u16 seq_number = 0;
358 u8 tid = IWL_MAX_TID_COUNT;
359 u8 txq_id = info->hw_queue;
360 bool is_data_qos = false, is_ampdu = false;
361
362 mvmsta = (void *)sta->drv_priv;
363 fc = hdr->frame_control;
364
365 if (WARN_ON_ONCE(!mvmsta))
366 return -1;
367
368 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION))
369 return -1;
370
371 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id);
372 if (!dev_cmd)
373 goto drop;
374
375 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
376 /* From now on, we cannot access info->control */
377
378 spin_lock(&mvmsta->lock);
379
380 if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
381 u8 *qc = NULL;
382 qc = ieee80211_get_qos_ctl(hdr);
383 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
384 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
385 goto drop_unlock_sta;
386
387 seq_number = mvmsta->tid_data[tid].seq_number;
388 seq_number &= IEEE80211_SCTL_SEQ;
389 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
390 hdr->seq_ctrl |= cpu_to_le16(seq_number);
391 seq_number += 0x10;
392 is_data_qos = true;
393 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
394 }
395
396 /* Copy MAC header from skb into command buffer */
397 memcpy(tx_cmd->hdr, hdr, ieee80211_hdrlen(fc));
398
399 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
400
401 if (is_ampdu) {
402 if (WARN_ON_ONCE(mvmsta->tid_data[tid].state != IWL_AGG_ON))
403 goto drop_unlock_sta;
404 txq_id = mvmsta->tid_data[tid].txq_id;
405 }
406
407 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
408 tid, txq_id, seq_number);
409
410 /* NOTE: aggregation will need changes here (for txq id) */
411 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
412 goto drop_unlock_sta;
413
414 if (is_data_qos && !ieee80211_has_morefrags(fc))
415 mvmsta->tid_data[tid].seq_number = seq_number;
416
417 spin_unlock(&mvmsta->lock);
418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
420 txq_id < IWL_FIRST_AMPDU_QUEUE)
421 atomic_inc(&mvmsta->pending_frames);
422
423 return 0;
424
425drop_unlock_sta:
426 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
427 spin_unlock(&mvmsta->lock);
428drop:
429 return -1;
430}
431
432static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
433 struct ieee80211_sta *sta, u8 tid)
434{
435 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
436 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
437 struct ieee80211_vif *vif = mvmsta->vif;
438
439 lockdep_assert_held(&mvmsta->lock);
440
441 if (tid_data->ssn != tid_data->next_reclaimed)
442 return;
443
444 switch (tid_data->state) {
445 case IWL_EMPTYING_HW_QUEUE_ADDBA:
446 IWL_DEBUG_TX_QUEUES(mvm,
447 "Can continue addBA flow ssn = next_recl = %d\n",
448 tid_data->next_reclaimed);
449 tid_data->state = IWL_AGG_STARTING;
450 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
451 break;
452
453 case IWL_EMPTYING_HW_QUEUE_DELBA:
454 IWL_DEBUG_TX_QUEUES(mvm,
455 "Can continue DELBA flow ssn = next_recl = %d\n",
456 tid_data->next_reclaimed);
457 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
458 tid_data->state = IWL_AGG_OFF;
459 /*
460 * we can't hold the mutex - but since we are after a sequence
461 * point (call to iwl_trans_txq_disable), so we don't even need
462 * a memory barrier.
463 */
464 mvm->queue_to_mac80211[tid_data->txq_id] =
465 IWL_INVALID_MAC80211_QUEUE;
466 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
467 break;
468
469 default:
470 break;
471 }
472}
473
474#ifdef CONFIG_IWLWIFI_DEBUG
475const char *iwl_mvm_get_tx_fail_reason(u32 status)
476{
477#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
478#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
479
480 switch (status & TX_STATUS_MSK) {
481 case TX_STATUS_SUCCESS:
482 return "SUCCESS";
483 TX_STATUS_POSTPONE(DELAY);
484 TX_STATUS_POSTPONE(FEW_BYTES);
485 TX_STATUS_POSTPONE(BT_PRIO);
486 TX_STATUS_POSTPONE(QUIET_PERIOD);
487 TX_STATUS_POSTPONE(CALC_TTAK);
488 TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
489 TX_STATUS_FAIL(SHORT_LIMIT);
490 TX_STATUS_FAIL(LONG_LIMIT);
491 TX_STATUS_FAIL(UNDERRUN);
492 TX_STATUS_FAIL(DRAIN_FLOW);
493 TX_STATUS_FAIL(RFKILL_FLUSH);
494 TX_STATUS_FAIL(LIFE_EXPIRE);
495 TX_STATUS_FAIL(DEST_PS);
496 TX_STATUS_FAIL(HOST_ABORTED);
497 TX_STATUS_FAIL(BT_RETRY);
498 TX_STATUS_FAIL(STA_INVALID);
499 TX_STATUS_FAIL(FRAG_DROPPED);
500 TX_STATUS_FAIL(TID_DISABLE);
501 TX_STATUS_FAIL(FIFO_FLUSHED);
502 TX_STATUS_FAIL(SMALL_CF_POLL);
503 TX_STATUS_FAIL(FW_DROP);
504 TX_STATUS_FAIL(STA_COLOR_MISMATCH);
505 }
506
507 return "UNKNOWN";
508
509#undef TX_STATUS_FAIL
510#undef TX_STATUS_POSTPONE
511}
512#endif /* CONFIG_IWLWIFI_DEBUG */
513
514/**
515 * translate ucode response to mac80211 tx status control values
516 */
517static void iwl_mvm_hwrate_to_tx_control(u32 rate_n_flags,
518 struct ieee80211_tx_info *info)
519{
520 struct ieee80211_tx_rate *r = &info->status.rates[0];
521
522 info->status.antenna =
523 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
524 if (rate_n_flags & RATE_HT_MCS_GF_MSK)
525 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
526 switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
527 case RATE_MCS_CHAN_WIDTH_20:
528 break;
529 case RATE_MCS_CHAN_WIDTH_40:
530 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
531 break;
532 case RATE_MCS_CHAN_WIDTH_80:
533 r->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
534 break;
535 case RATE_MCS_CHAN_WIDTH_160:
536 r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH;
537 break;
538 }
539 if (rate_n_flags & RATE_MCS_SGI_MSK)
540 r->flags |= IEEE80211_TX_RC_SHORT_GI;
541 if (rate_n_flags & RATE_MCS_HT_MSK) {
542 r->flags |= IEEE80211_TX_RC_MCS;
543 r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
544 } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
545 ieee80211_rate_set_vht(
546 r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK,
547 ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
548 RATE_VHT_MCS_NSS_POS) + 1);
549 r->flags |= IEEE80211_TX_RC_VHT_MCS;
550 } else {
551 r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
552 info->band);
553 }
554}
555
556static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
557 struct iwl_rx_packet *pkt)
558{
559 struct ieee80211_sta *sta;
560 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
561 int txq_id = SEQ_TO_QUEUE(sequence);
562 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
563 int sta_id = IWL_MVM_TX_RES_GET_RA(tx_resp->ra_tid);
564 int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid);
565 u32 status = le16_to_cpu(tx_resp->status.status);
566 u16 ssn = iwl_mvm_get_scd_ssn(tx_resp);
567 struct iwl_mvm_sta *mvmsta;
568 struct sk_buff_head skbs;
569 u8 skb_freed = 0;
570 u16 next_reclaimed, seq_ctl;
571
572 __skb_queue_head_init(&skbs);
573
574 seq_ctl = le16_to_cpu(tx_resp->seq_ctl);
575
576 /* we can free until ssn % q.n_bd not inclusive */
577 iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs);
578
579 while (!skb_queue_empty(&skbs)) {
580 struct sk_buff *skb = __skb_dequeue(&skbs);
581 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
582
583 skb_freed++;
584
585 iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
586
587 memset(&info->status, 0, sizeof(info->status));
588
589 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
590
591 /* inform mac80211 about what happened with the frame */
592 switch (status & TX_STATUS_MSK) {
593 case TX_STATUS_SUCCESS:
594 case TX_STATUS_DIRECT_DONE:
595 info->flags |= IEEE80211_TX_STAT_ACK;
596 break;
597 case TX_STATUS_FAIL_DEST_PS:
598 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
599 break;
600 default:
601 break;
602 }
603
604 info->status.rates[0].count = tx_resp->failure_frame + 1;
605 iwl_mvm_hwrate_to_tx_control(le32_to_cpu(tx_resp->initial_rate),
606 info);
607
608 /* Single frame failure in an AMPDU queue => send BAR */
609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&
610 !(info->flags & IEEE80211_TX_STAT_ACK)) {
611 /* there must be only one skb in the skb_list */
612 WARN_ON_ONCE(skb_freed > 1 ||
613 !skb_queue_empty(&skbs));
614 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
615 }
616
617 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */
618 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
619 struct ieee80211_hdr *hdr = (void *)skb->data;
620 seq_ctl = le16_to_cpu(hdr->seq_ctrl);
621 }
622
623 ieee80211_tx_status(mvm->hw, skb);
624 }
625
626 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) {
627 /* If this is an aggregation queue, we use the ssn since:
628 * ssn = wifi seq_num % 256.
629 * The seq_ctl is the sequence control of the packet to which
630 * this Tx response relates. But if there is a hole in the
631 * bitmap of the BA we received, this Tx response may allow to
632 * reclaim the hole and all the subsequent packets that were
633 * already acked. In that case, seq_ctl != ssn, and the next
634 * packet to be reclaimed will be ssn and not seq_ctl. In that
635 * case, several packets will be reclaimed even if
636 * frame_count = 1.
637 *
638 * The ssn is the index (% 256) of the latest packet that has
639 * treated (acked / dropped) + 1.
640 */
641 next_reclaimed = ssn;
642 } else {
643 /* The next packet to be reclaimed is the one after this one */
644 next_reclaimed = SEQ_TO_SN(seq_ctl + 0x10);
645 }
646
647 IWL_DEBUG_TX_REPLY(mvm,
648 "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x "
649 "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n",
650 txq_id, iwl_mvm_get_tx_fail_reason(status),
651 status, le32_to_cpu(tx_resp->initial_rate),
652 tx_resp->failure_frame, SEQ_TO_INDEX(sequence),
653 ssn, next_reclaimed, seq_ctl);
654
655 rcu_read_lock();
656
657 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
658
659 if (!IS_ERR_OR_NULL(sta)) {
660 mvmsta = (void *)sta->drv_priv;
661
662 if (tid != IWL_TID_NON_QOS) {
663 struct iwl_mvm_tid_data *tid_data =
664 &mvmsta->tid_data[tid];
665
666 spin_lock(&mvmsta->lock);
667 tid_data->next_reclaimed = next_reclaimed;
668 IWL_DEBUG_TX_REPLY(mvm, "Next reclaimed packet:%d\n",
669 next_reclaimed);
670 iwl_mvm_check_ratid_empty(mvm, sta, tid);
671 spin_unlock(&mvmsta->lock);
672 }
673
674#ifdef CONFIG_PM_SLEEP
675 mvmsta->last_seq_ctl = seq_ctl;
676#endif
677 } else {
678 sta = NULL;
679 mvmsta = NULL;
680 }
681
682 /*
683 * If the txq is not an AMPDU queue, there is no chance we freed
684 * several skbs. Check that out...
685 * If there are no pending frames for this STA, notify mac80211 that
686 * this station can go to sleep in its STA table.
687 */
688 if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta &&
689 !WARN_ON(skb_freed > 1) &&
690 mvmsta->vif->type == NL80211_IFTYPE_AP &&
691 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
692 ieee80211_sta_block_awake(mvm->hw, sta, false);
693 set_bit(sta_id, mvm->sta_drained);
694 schedule_work(&mvm->sta_drained_wk);
695 }
696
697 rcu_read_unlock();
698}
699
700#ifdef CONFIG_IWLWIFI_DEBUG
701#define AGG_TX_STATE_(x) case AGG_TX_STATE_ ## x: return #x
702static const char *iwl_get_agg_tx_status(u16 status)
703{
704 switch (status & AGG_TX_STATE_STATUS_MSK) {
705 AGG_TX_STATE_(TRANSMITTED);
706 AGG_TX_STATE_(UNDERRUN);
707 AGG_TX_STATE_(BT_PRIO);
708 AGG_TX_STATE_(FEW_BYTES);
709 AGG_TX_STATE_(ABORT);
710 AGG_TX_STATE_(LAST_SENT_TTL);
711 AGG_TX_STATE_(LAST_SENT_TRY_CNT);
712 AGG_TX_STATE_(LAST_SENT_BT_KILL);
713 AGG_TX_STATE_(SCD_QUERY);
714 AGG_TX_STATE_(TEST_BAD_CRC32);
715 AGG_TX_STATE_(RESPONSE);
716 AGG_TX_STATE_(DUMP_TX);
717 AGG_TX_STATE_(DELAY_TX);
718 }
719
720 return "UNKNOWN";
721}
722
723static void iwl_mvm_rx_tx_cmd_agg_dbg(struct iwl_mvm *mvm,
724 struct iwl_rx_packet *pkt)
725{
726 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
727 struct agg_tx_status *frame_status = &tx_resp->status;
728 int i;
729
730 for (i = 0; i < tx_resp->frame_count; i++) {
731 u16 fstatus = le16_to_cpu(frame_status[i].status);
732
733 IWL_DEBUG_TX_REPLY(mvm,
734 "status %s (0x%04x), try-count (%d) seq (0x%x)\n",
735 iwl_get_agg_tx_status(fstatus),
736 fstatus & AGG_TX_STATE_STATUS_MSK,
737 (fstatus & AGG_TX_STATE_TRY_CNT_MSK) >>
738 AGG_TX_STATE_TRY_CNT_POS,
739 le16_to_cpu(frame_status[i].sequence));
740 }
741}
742#else
743static void iwl_mvm_rx_tx_cmd_agg_dbg(struct iwl_mvm *mvm,
744 struct iwl_rx_packet *pkt)
745{}
746#endif /* CONFIG_IWLWIFI_DEBUG */
747
748static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
749 struct iwl_rx_packet *pkt)
750{
751 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
752 int sta_id = IWL_MVM_TX_RES_GET_RA(tx_resp->ra_tid);
753 int tid = IWL_MVM_TX_RES_GET_TID(tx_resp->ra_tid);
754 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
755 struct ieee80211_sta *sta;
756
757 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE))
758 return;
759
760 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
761 return;
762
763 iwl_mvm_rx_tx_cmd_agg_dbg(mvm, pkt);
764
765 rcu_read_lock();
766
767 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
768
769 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
770 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
771 mvmsta->tid_data[tid].rate_n_flags =
772 le32_to_cpu(tx_resp->initial_rate);
773 }
774
775 rcu_read_unlock();
776}
777
778int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
779 struct iwl_device_cmd *cmd)
780{
781 struct iwl_rx_packet *pkt = rxb_addr(rxb);
782 struct iwl_mvm_tx_resp *tx_resp = (void *)pkt->data;
783
784 if (tx_resp->frame_count == 1)
785 iwl_mvm_rx_tx_cmd_single(mvm, pkt);
786 else
787 iwl_mvm_rx_tx_cmd_agg(mvm, pkt);
788
789 return 0;
790}
791
792int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
793 struct iwl_device_cmd *cmd)
794{
795 struct iwl_rx_packet *pkt = rxb_addr(rxb);
796 struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data;
797 struct sk_buff_head reclaimed_skbs;
798 struct iwl_mvm_tid_data *tid_data;
799 struct ieee80211_tx_info *info;
800 struct ieee80211_sta *sta;
801 struct iwl_mvm_sta *mvmsta;
802 struct ieee80211_hdr *hdr;
803 struct sk_buff *skb;
804 int sta_id, tid, freed;
805
806 /* "flow" corresponds to Tx queue */
807 u16 scd_flow = le16_to_cpu(ba_notif->scd_flow);
808
809 /* "ssn" is start of block-ack Tx window, corresponds to index
810 * (in Tx queue's circular buffer) of first TFD/frame in window */
811 u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn);
812
813 sta_id = ba_notif->sta_id;
814 tid = ba_notif->tid;
815
816 rcu_read_lock();
817
818 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
819
820 /* Reclaiming frames for a station that has been deleted ? */
821 if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
822 rcu_read_unlock();
823 return 0;
824 }
825
826 mvmsta = (void *)sta->drv_priv;
827 tid_data = &mvmsta->tid_data[tid];
828
829 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d",
830 tid_data->txq_id, tid, scd_flow)) {
831 rcu_read_unlock();
832 return 0;
833 }
834
835 spin_lock(&mvmsta->lock);
836
837 __skb_queue_head_init(&reclaimed_skbs);
838
839 /*
840 * Release all TFDs before the SSN, i.e. all TFDs in front of
841 * block-ack window (we assume that they've been successfully
842 * transmitted ... if not, it's too late anyway).
843 */
844 iwl_trans_reclaim(mvm->trans, scd_flow, ba_resp_scd_ssn,
845 &reclaimed_skbs);
846
847 IWL_DEBUG_TX_REPLY(mvm,
848 "BA_NOTIFICATION Received from %pM, sta_id = %d\n",
849 (u8 *)&ba_notif->sta_addr_lo32,
850 ba_notif->sta_id);
851 IWL_DEBUG_TX_REPLY(mvm,
852 "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = %d, scd_ssn = %d sent:%d, acked:%d\n",
853 ba_notif->tid, le16_to_cpu(ba_notif->seq_ctl),
854 (unsigned long long)le64_to_cpu(ba_notif->bitmap),
855 scd_flow, ba_resp_scd_ssn, ba_notif->txed,
856 ba_notif->txed_2_done);
857
858 tid_data->next_reclaimed = ba_resp_scd_ssn;
859
860 iwl_mvm_check_ratid_empty(mvm, sta, tid);
861
862 freed = 0;
863
864 skb_queue_walk(&reclaimed_skbs, skb) {
865 hdr = (struct ieee80211_hdr *)skb->data;
866
867 if (ieee80211_is_data_qos(hdr->frame_control))
868 freed++;
869 else
870 WARN_ON_ONCE(1);
871
872 info = IEEE80211_SKB_CB(skb);
873 iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
874
875 if (freed == 1) {
876 /* this is the first skb we deliver in this batch */
877 /* put the rate scaling data there */
878 info = IEEE80211_SKB_CB(skb);
879 memset(&info->status, 0, sizeof(info->status));
880 info->flags |= IEEE80211_TX_STAT_ACK;
881 info->flags |= IEEE80211_TX_STAT_AMPDU;
882 info->status.ampdu_ack_len = ba_notif->txed_2_done;
883 info->status.ampdu_len = ba_notif->txed;
884 iwl_mvm_hwrate_to_tx_control(tid_data->rate_n_flags,
885 info);
886 }
887 }
888
889 spin_unlock(&mvmsta->lock);
890
891 rcu_read_unlock();
892
893 while (!skb_queue_empty(&reclaimed_skbs)) {
894 skb = __skb_dequeue(&reclaimed_skbs);
895 ieee80211_tx_status(mvm->hw, skb);
896 }
897
898 return 0;
899}
900
901int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync)
902{
903 int ret;
904 struct iwl_tx_path_flush_cmd flush_cmd = {
905 .queues_ctl = cpu_to_le32(tfd_msk),
906 .flush_ctl = cpu_to_le16(DUMP_TX_FIFO_FLUSH),
907 };
908
909 u32 flags = sync ? CMD_SYNC : CMD_ASYNC;
910
911 ret = iwl_mvm_send_cmd_pdu(mvm, TXPATH_FLUSH, flags,
912 sizeof(flush_cmd), &flush_cmd);
913 if (ret)
914 IWL_ERR(mvm, "Failed to send flush command (%d)\n", ret);
915 return ret;
916}
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
new file mode 100644
index 000000000000..000e842c2edd
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -0,0 +1,472 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9 *
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
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <net/mac80211.h>
64
65#include "iwl-debug.h"
66#include "iwl-io.h"
67
68#include "mvm.h"
69#include "fw-api-rs.h"
70
71/*
72 * Will return 0 even if the cmd failed when RFKILL is asserted unless
73 * CMD_WANT_SKB is set in cmd->flags.
74 */
75int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
76{
77 int ret;
78
79 /*
80 * Synchronous commands from this op-mode must hold
81 * the mutex, this ensures we don't try to send two
82 * (or more) synchronous commands at a time.
83 */
84 if (!(cmd->flags & CMD_ASYNC))
85 lockdep_assert_held(&mvm->mutex);
86
87 ret = iwl_trans_send_cmd(mvm->trans, cmd);
88
89 /*
90 * If the caller wants the SKB, then don't hide any problems, the
91 * caller might access the response buffer which will be NULL if
92 * the command failed.
93 */
94 if (cmd->flags & CMD_WANT_SKB)
95 return ret;
96
97 /* Silently ignore failures if RFKILL is asserted */
98 if (!ret || ret == -ERFKILL)
99 return 0;
100 return ret;
101}
102
103int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id,
104 u32 flags, u16 len, const void *data)
105{
106 struct iwl_host_cmd cmd = {
107 .id = id,
108 .len = { len, },
109 .data = { data, },
110 .flags = flags,
111 };
112
113 return iwl_mvm_send_cmd(mvm, &cmd);
114}
115
116/*
117 * We assume that the caller set the status to the sucess value
118 */
119int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
120 u32 *status)
121{
122 struct iwl_rx_packet *pkt;
123 struct iwl_cmd_response *resp;
124 int ret, resp_len;
125
126 lockdep_assert_held(&mvm->mutex);
127
128 /*
129 * Only synchronous commands can wait for status,
130 * we use WANT_SKB so the caller can't.
131 */
132 if (WARN_ONCE(cmd->flags & (CMD_ASYNC | CMD_WANT_SKB),
133 "cmd flags %x", cmd->flags))
134 return -EINVAL;
135
136 cmd->flags |= CMD_SYNC | CMD_WANT_SKB;
137
138 ret = iwl_trans_send_cmd(mvm->trans, cmd);
139 if (ret == -ERFKILL) {
140 /*
141 * The command failed because of RFKILL, don't update
142 * the status, leave it as success and return 0.
143 */
144 return 0;
145 } else if (ret) {
146 return ret;
147 }
148
149 pkt = cmd->resp_pkt;
150 /* Can happen if RFKILL is asserted */
151 if (!pkt) {
152 ret = 0;
153 goto out_free_resp;
154 }
155
156 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
157 ret = -EIO;
158 goto out_free_resp;
159 }
160
161 resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
162 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {
163 ret = -EIO;
164 goto out_free_resp;
165 }
166
167 resp = (void *)pkt->data;
168 *status = le32_to_cpu(resp->status);
169 out_free_resp:
170 iwl_free_resp(cmd);
171 return ret;
172}
173
174/*
175 * We assume that the caller set the status to the sucess value
176 */
177int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u8 id, u16 len,
178 const void *data, u32 *status)
179{
180 struct iwl_host_cmd cmd = {
181 .id = id,
182 .len = { len, },
183 .data = { data, },
184 };
185
186 return iwl_mvm_send_cmd_status(mvm, &cmd, status);
187}
188
189#define IWL_DECLARE_RATE_INFO(r) \
190 [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
191
192/*
193 * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
194 */
195static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
196 IWL_DECLARE_RATE_INFO(1),
197 IWL_DECLARE_RATE_INFO(2),
198 IWL_DECLARE_RATE_INFO(5),
199 IWL_DECLARE_RATE_INFO(11),
200 IWL_DECLARE_RATE_INFO(6),
201 IWL_DECLARE_RATE_INFO(9),
202 IWL_DECLARE_RATE_INFO(12),
203 IWL_DECLARE_RATE_INFO(18),
204 IWL_DECLARE_RATE_INFO(24),
205 IWL_DECLARE_RATE_INFO(36),
206 IWL_DECLARE_RATE_INFO(48),
207 IWL_DECLARE_RATE_INFO(54),
208};
209
210int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
211 enum ieee80211_band band)
212{
213 int rate = rate_n_flags & RATE_LEGACY_RATE_MSK;
214 int idx;
215 int band_offset = 0;
216
217 /* Legacy rate format, search for match in table */
218 if (band == IEEE80211_BAND_5GHZ)
219 band_offset = IWL_FIRST_OFDM_RATE;
220 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
221 if (fw_rate_idx_to_plcp[idx] == rate)
222 return idx - band_offset;
223
224 return -1;
225}
226
227u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx)
228{
229 /* Get PLCP rate for tx_cmd->rate_n_flags */
230 return fw_rate_idx_to_plcp[rate_idx];
231}
232
233int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
234 struct iwl_device_cmd *cmd)
235{
236 struct iwl_rx_packet *pkt = rxb_addr(rxb);
237 struct iwl_error_resp *err_resp = (void *)pkt->data;
238
239 IWL_ERR(mvm, "FW Error notification: type 0x%08X cmd_id 0x%02X\n",
240 le32_to_cpu(err_resp->error_type), err_resp->cmd_id);
241 IWL_ERR(mvm, "FW Error notification: seq 0x%04X service 0x%08X\n",
242 le16_to_cpu(err_resp->bad_cmd_seq_num),
243 le32_to_cpu(err_resp->error_service));
244 IWL_ERR(mvm, "FW Error notification: timestamp 0x%16llX\n",
245 le64_to_cpu(err_resp->timestamp));
246 return 0;
247}
248
249/*
250 * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h.
251 * The parameter should also be a combination of ANT_[ABC].
252 */
253u8 first_antenna(u8 mask)
254{
255 BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */
256 WARN_ON_ONCE(!mask); /* ffs will return 0 if mask is zeroed */
257 return (u8)(BIT(ffs(mask)));
258}
259
260/*
261 * Toggles between TX antennas to send the probe request on.
262 * Receives the bitmask of valid TX antennas and the *index* used
263 * for the last TX, and returns the next valid *index* to use.
264 * In order to set it in the tx_cmd, must do BIT(idx).
265 */
266u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
267{
268 u8 ind = last_idx;
269 int i;
270
271 for (i = 0; i < RATE_MCS_ANT_NUM; i++) {
272 ind = (ind + 1) % RATE_MCS_ANT_NUM;
273 if (valid & BIT(ind))
274 return ind;
275 }
276
277 WARN_ONCE(1, "Failed to toggle between antennas 0x%x", valid);
278 return last_idx;
279}
280
281static struct {
282 char *name;
283 u8 num;
284} advanced_lookup[] = {
285 { "NMI_INTERRUPT_WDG", 0x34 },
286 { "SYSASSERT", 0x35 },
287 { "UCODE_VERSION_MISMATCH", 0x37 },
288 { "BAD_COMMAND", 0x38 },
289 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
290 { "FATAL_ERROR", 0x3D },
291 { "NMI_TRM_HW_ERR", 0x46 },
292 { "NMI_INTERRUPT_TRM", 0x4C },
293 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
294 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
295 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
296 { "NMI_INTERRUPT_HOST", 0x66 },
297 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
298 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
299 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
300 { "ADVANCED_SYSASSERT", 0 },
301};
302
303static const char *desc_lookup(u32 num)
304{
305 int i;
306
307 for (i = 0; i < ARRAY_SIZE(advanced_lookup) - 1; i++)
308 if (advanced_lookup[i].num == num)
309 return advanced_lookup[i].name;
310
311 /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
312 return advanced_lookup[i].name;
313}
314
315/*
316 * Note: This structure is read from the device with IO accesses,
317 * and the reading already does the endian conversion. As it is
318 * read with u32-sized accesses, any members with a different size
319 * need to be ordered correctly though!
320 */
321struct iwl_error_event_table {
322 u32 valid; /* (nonzero) valid, (0) log is empty */
323 u32 error_id; /* type of error */
324 u32 pc; /* program counter */
325 u32 blink1; /* branch link */
326 u32 blink2; /* branch link */
327 u32 ilink1; /* interrupt link */
328 u32 ilink2; /* interrupt link */
329 u32 data1; /* error-specific data */
330 u32 data2; /* error-specific data */
331 u32 data3; /* error-specific data */
332 u32 bcon_time; /* beacon timer */
333 u32 tsf_low; /* network timestamp function timer */
334 u32 tsf_hi; /* network timestamp function timer */
335 u32 gp1; /* GP1 timer register */
336 u32 gp2; /* GP2 timer register */
337 u32 gp3; /* GP3 timer register */
338 u32 ucode_ver; /* uCode version */
339 u32 hw_ver; /* HW Silicon version */
340 u32 brd_ver; /* HW board version */
341 u32 log_pc; /* log program counter */
342 u32 frame_ptr; /* frame pointer */
343 u32 stack_ptr; /* stack pointer */
344 u32 hcmd; /* last host command header */
345 u32 isr0; /* isr status register LMPM_NIC_ISR0:
346 * rxtx_flag */
347 u32 isr1; /* isr status register LMPM_NIC_ISR1:
348 * host_flag */
349 u32 isr2; /* isr status register LMPM_NIC_ISR2:
350 * enc_flag */
351 u32 isr3; /* isr status register LMPM_NIC_ISR3:
352 * time_flag */
353 u32 isr4; /* isr status register LMPM_NIC_ISR4:
354 * wico interrupt */
355 u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
356 u32 wait_event; /* wait event() caller address */
357 u32 l2p_control; /* L2pControlField */
358 u32 l2p_duration; /* L2pDurationField */
359 u32 l2p_mhvalid; /* L2pMhValidBits */
360 u32 l2p_addr_match; /* L2pAddrMatchStat */
361 u32 lmpm_pmg_sel; /* indicate which clocks are turned on
362 * (LMPM_PMG_SEL) */
363 u32 u_timestamp; /* indicate when the date and time of the
364 * compilation */
365 u32 flow_handler; /* FH read/write pointers, RX credit */
366} __packed;
367
368#define ERROR_START_OFFSET (1 * sizeof(u32))
369#define ERROR_ELEM_SIZE (7 * sizeof(u32))
370
371void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
372{
373 struct iwl_trans *trans = mvm->trans;
374 struct iwl_error_event_table table;
375 u32 base;
376
377 base = mvm->error_event_table;
378 if (mvm->cur_ucode == IWL_UCODE_INIT) {
379 if (!base)
380 base = mvm->fw->init_errlog_ptr;
381 } else {
382 if (!base)
383 base = mvm->fw->inst_errlog_ptr;
384 }
385
386 if (base < 0x800000 || base >= 0x80C000) {
387 IWL_ERR(mvm,
388 "Not valid error log pointer 0x%08X for %s uCode\n",
389 base,
390 (mvm->cur_ucode == IWL_UCODE_INIT)
391 ? "Init" : "RT");
392 return;
393 }
394
395 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
396
397 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
398 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
399 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
400 mvm->status, table.valid);
401 }
402
403 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
404 table.data1, table.data2, table.data3,
405 table.blink1, table.blink2, table.ilink1,
406 table.ilink2, table.bcon_time, table.gp1,
407 table.gp2, table.gp3, table.ucode_ver,
408 table.hw_ver, table.brd_ver);
409 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
410 desc_lookup(table.error_id));
411 IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
412 IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
413 IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
414 IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
415 IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
416 IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
417 IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
418 IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
419 IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
420 IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
421 IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
422 IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
423 IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
424 IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
425 IWL_ERR(mvm, "0x%08X | uCode version\n", table.ucode_ver);
426 IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
427 IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
428 IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
429 IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
430 IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
431 IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
432 IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
433 IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
434 IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
435 IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
436 IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
437 IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
438 IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
439 IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
440 IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
441 IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
442 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
443}
444
445/**
446 * iwl_mvm_send_lq_cmd() - Send link quality command
447 * @init: This command is sent as part of station initialization right
448 * after station has been added.
449 *
450 * The link quality command is sent as the last step of station creation.
451 * This is the special case in which init is set and we call a callback in
452 * this case to clear the state indicating that station creation is in
453 * progress.
454 */
455int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
456 u8 flags, bool init)
457{
458 struct iwl_host_cmd cmd = {
459 .id = LQ_CMD,
460 .len = { sizeof(struct iwl_lq_cmd), },
461 .flags = flags,
462 .data = { lq, },
463 };
464
465 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
466 return -EINVAL;
467
468 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
469 return -EINVAL;
470
471 return iwl_mvm_send_cmd(mvm, &cmd);
472}