Commit 0374737727b65f31b9357051b421a3141c0d39ec
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Showing 6 changed files Inline Diff
drivers/net/wireless/iwlwifi/dvm/commands.h
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | 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. | 4 | * redistributing this file, you may do so under either license. |
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, but | 14 | * This program is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * General Public License for more details. | 17 | * General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 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 | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
22 | * USA | 22 | * USA |
23 | * | 23 | * |
24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
25 | * in the file called LICENSE.GPL. | 25 | * in the file called LICENSE.GPL. |
26 | * | 26 | * |
27 | * Contact Information: | 27 | * Contact Information: |
28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
37 | * modification, are permitted provided that the following conditions | 37 | * modification, are permitted provided that the following conditions |
38 | * are met: | 38 | * are met: |
39 | * | 39 | * |
40 | * * Redistributions of source code must retain the above copyright | 40 | * * Redistributions of source code must retain the above copyright |
41 | * notice, this list of conditions and the following disclaimer. | 41 | * notice, this list of conditions and the following disclaimer. |
42 | * * Redistributions in binary form must reproduce the above copyright | 42 | * * Redistributions in binary form must reproduce the above copyright |
43 | * notice, this list of conditions and the following disclaimer in | 43 | * notice, this list of conditions and the following disclaimer in |
44 | * the documentation and/or other materials provided with the | 44 | * the documentation and/or other materials provided with the |
45 | * distribution. | 45 | * distribution. |
46 | * * Neither the name Intel Corporation nor the names of its | 46 | * * Neither the name Intel Corporation nor the names of its |
47 | * contributors may be used to endorse or promote products derived | 47 | * contributors may be used to endorse or promote products derived |
48 | * from this software without specific prior written permission. | 48 | * from this software without specific prior written permission. |
49 | * | 49 | * |
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | /* | 63 | /* |
64 | * Please use this file (commands.h) only for uCode API definitions. | 64 | * Please use this file (commands.h) only for uCode API definitions. |
65 | * Please use iwl-xxxx-hw.h for hardware-related definitions. | 65 | * Please use iwl-xxxx-hw.h for hardware-related definitions. |
66 | * Please use dev.h for driver implementation definitions. | 66 | * Please use dev.h for driver implementation definitions. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
70 | #define __iwl_commands_h__ | 70 | #define __iwl_commands_h__ |
71 | 71 | ||
72 | #include <linux/ieee80211.h> | 72 | #include <linux/ieee80211.h> |
73 | #include <linux/types.h> | 73 | #include <linux/types.h> |
74 | 74 | ||
75 | 75 | ||
76 | enum { | 76 | enum { |
77 | REPLY_ALIVE = 0x1, | 77 | REPLY_ALIVE = 0x1, |
78 | REPLY_ERROR = 0x2, | 78 | REPLY_ERROR = 0x2, |
79 | REPLY_ECHO = 0x3, /* test command */ | 79 | REPLY_ECHO = 0x3, /* test command */ |
80 | 80 | ||
81 | /* RXON and QOS commands */ | 81 | /* RXON and QOS commands */ |
82 | REPLY_RXON = 0x10, | 82 | REPLY_RXON = 0x10, |
83 | REPLY_RXON_ASSOC = 0x11, | 83 | REPLY_RXON_ASSOC = 0x11, |
84 | REPLY_QOS_PARAM = 0x13, | 84 | REPLY_QOS_PARAM = 0x13, |
85 | REPLY_RXON_TIMING = 0x14, | 85 | REPLY_RXON_TIMING = 0x14, |
86 | 86 | ||
87 | /* Multi-Station support */ | 87 | /* Multi-Station support */ |
88 | REPLY_ADD_STA = 0x18, | 88 | REPLY_ADD_STA = 0x18, |
89 | REPLY_REMOVE_STA = 0x19, | 89 | REPLY_REMOVE_STA = 0x19, |
90 | REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ | 90 | REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ |
91 | REPLY_TXFIFO_FLUSH = 0x1e, | 91 | REPLY_TXFIFO_FLUSH = 0x1e, |
92 | 92 | ||
93 | /* Security */ | 93 | /* Security */ |
94 | REPLY_WEPKEY = 0x20, | 94 | REPLY_WEPKEY = 0x20, |
95 | 95 | ||
96 | /* RX, TX, LEDs */ | 96 | /* RX, TX, LEDs */ |
97 | REPLY_TX = 0x1c, | 97 | REPLY_TX = 0x1c, |
98 | REPLY_LEDS_CMD = 0x48, | 98 | REPLY_LEDS_CMD = 0x48, |
99 | REPLY_TX_LINK_QUALITY_CMD = 0x4e, | 99 | REPLY_TX_LINK_QUALITY_CMD = 0x4e, |
100 | 100 | ||
101 | /* WiMAX coexistence */ | 101 | /* WiMAX coexistence */ |
102 | COEX_PRIORITY_TABLE_CMD = 0x5a, | 102 | COEX_PRIORITY_TABLE_CMD = 0x5a, |
103 | COEX_MEDIUM_NOTIFICATION = 0x5b, | 103 | COEX_MEDIUM_NOTIFICATION = 0x5b, |
104 | COEX_EVENT_CMD = 0x5c, | 104 | COEX_EVENT_CMD = 0x5c, |
105 | 105 | ||
106 | /* Calibration */ | 106 | /* Calibration */ |
107 | TEMPERATURE_NOTIFICATION = 0x62, | 107 | TEMPERATURE_NOTIFICATION = 0x62, |
108 | CALIBRATION_CFG_CMD = 0x65, | 108 | CALIBRATION_CFG_CMD = 0x65, |
109 | CALIBRATION_RES_NOTIFICATION = 0x66, | 109 | CALIBRATION_RES_NOTIFICATION = 0x66, |
110 | CALIBRATION_COMPLETE_NOTIFICATION = 0x67, | 110 | CALIBRATION_COMPLETE_NOTIFICATION = 0x67, |
111 | 111 | ||
112 | /* 802.11h related */ | 112 | /* 802.11h related */ |
113 | REPLY_QUIET_CMD = 0x71, /* not used */ | 113 | REPLY_QUIET_CMD = 0x71, /* not used */ |
114 | REPLY_CHANNEL_SWITCH = 0x72, | 114 | REPLY_CHANNEL_SWITCH = 0x72, |
115 | CHANNEL_SWITCH_NOTIFICATION = 0x73, | 115 | CHANNEL_SWITCH_NOTIFICATION = 0x73, |
116 | REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, | 116 | REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, |
117 | SPECTRUM_MEASURE_NOTIFICATION = 0x75, | 117 | SPECTRUM_MEASURE_NOTIFICATION = 0x75, |
118 | 118 | ||
119 | /* Power Management */ | 119 | /* Power Management */ |
120 | POWER_TABLE_CMD = 0x77, | 120 | POWER_TABLE_CMD = 0x77, |
121 | PM_SLEEP_NOTIFICATION = 0x7A, | 121 | PM_SLEEP_NOTIFICATION = 0x7A, |
122 | PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, | 122 | PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, |
123 | 123 | ||
124 | /* Scan commands and notifications */ | 124 | /* Scan commands and notifications */ |
125 | REPLY_SCAN_CMD = 0x80, | 125 | REPLY_SCAN_CMD = 0x80, |
126 | REPLY_SCAN_ABORT_CMD = 0x81, | 126 | REPLY_SCAN_ABORT_CMD = 0x81, |
127 | SCAN_START_NOTIFICATION = 0x82, | 127 | SCAN_START_NOTIFICATION = 0x82, |
128 | SCAN_RESULTS_NOTIFICATION = 0x83, | 128 | SCAN_RESULTS_NOTIFICATION = 0x83, |
129 | SCAN_COMPLETE_NOTIFICATION = 0x84, | 129 | SCAN_COMPLETE_NOTIFICATION = 0x84, |
130 | 130 | ||
131 | /* IBSS/AP commands */ | 131 | /* IBSS/AP commands */ |
132 | BEACON_NOTIFICATION = 0x90, | 132 | BEACON_NOTIFICATION = 0x90, |
133 | REPLY_TX_BEACON = 0x91, | 133 | REPLY_TX_BEACON = 0x91, |
134 | WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */ | 134 | WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */ |
135 | 135 | ||
136 | /* Miscellaneous commands */ | 136 | /* Miscellaneous commands */ |
137 | REPLY_TX_POWER_DBM_CMD = 0x95, | 137 | REPLY_TX_POWER_DBM_CMD = 0x95, |
138 | QUIET_NOTIFICATION = 0x96, /* not used */ | 138 | QUIET_NOTIFICATION = 0x96, /* not used */ |
139 | REPLY_TX_PWR_TABLE_CMD = 0x97, | 139 | REPLY_TX_PWR_TABLE_CMD = 0x97, |
140 | REPLY_TX_POWER_DBM_CMD_V1 = 0x98, /* old version of API */ | 140 | REPLY_TX_POWER_DBM_CMD_V1 = 0x98, /* old version of API */ |
141 | TX_ANT_CONFIGURATION_CMD = 0x98, | 141 | TX_ANT_CONFIGURATION_CMD = 0x98, |
142 | MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ | 142 | MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ |
143 | 143 | ||
144 | /* Bluetooth device coexistence config command */ | 144 | /* Bluetooth device coexistence config command */ |
145 | REPLY_BT_CONFIG = 0x9b, | 145 | REPLY_BT_CONFIG = 0x9b, |
146 | 146 | ||
147 | /* Statistics */ | 147 | /* Statistics */ |
148 | REPLY_STATISTICS_CMD = 0x9c, | 148 | REPLY_STATISTICS_CMD = 0x9c, |
149 | STATISTICS_NOTIFICATION = 0x9d, | 149 | STATISTICS_NOTIFICATION = 0x9d, |
150 | 150 | ||
151 | /* RF-KILL commands and notifications */ | 151 | /* RF-KILL commands and notifications */ |
152 | REPLY_CARD_STATE_CMD = 0xa0, | 152 | REPLY_CARD_STATE_CMD = 0xa0, |
153 | CARD_STATE_NOTIFICATION = 0xa1, | 153 | CARD_STATE_NOTIFICATION = 0xa1, |
154 | 154 | ||
155 | /* Missed beacons notification */ | 155 | /* Missed beacons notification */ |
156 | MISSED_BEACONS_NOTIFICATION = 0xa2, | 156 | MISSED_BEACONS_NOTIFICATION = 0xa2, |
157 | 157 | ||
158 | REPLY_CT_KILL_CONFIG_CMD = 0xa4, | 158 | REPLY_CT_KILL_CONFIG_CMD = 0xa4, |
159 | SENSITIVITY_CMD = 0xa8, | 159 | SENSITIVITY_CMD = 0xa8, |
160 | REPLY_PHY_CALIBRATION_CMD = 0xb0, | 160 | REPLY_PHY_CALIBRATION_CMD = 0xb0, |
161 | REPLY_RX_PHY_CMD = 0xc0, | 161 | REPLY_RX_PHY_CMD = 0xc0, |
162 | REPLY_RX_MPDU_CMD = 0xc1, | 162 | REPLY_RX_MPDU_CMD = 0xc1, |
163 | REPLY_RX = 0xc3, | 163 | REPLY_RX = 0xc3, |
164 | REPLY_COMPRESSED_BA = 0xc5, | 164 | REPLY_COMPRESSED_BA = 0xc5, |
165 | 165 | ||
166 | /* BT Coex */ | 166 | /* BT Coex */ |
167 | REPLY_BT_COEX_PRIO_TABLE = 0xcc, | 167 | REPLY_BT_COEX_PRIO_TABLE = 0xcc, |
168 | REPLY_BT_COEX_PROT_ENV = 0xcd, | 168 | REPLY_BT_COEX_PROT_ENV = 0xcd, |
169 | REPLY_BT_COEX_PROFILE_NOTIF = 0xce, | 169 | REPLY_BT_COEX_PROFILE_NOTIF = 0xce, |
170 | 170 | ||
171 | /* PAN commands */ | 171 | /* PAN commands */ |
172 | REPLY_WIPAN_PARAMS = 0xb2, | 172 | REPLY_WIPAN_PARAMS = 0xb2, |
173 | REPLY_WIPAN_RXON = 0xb3, /* use REPLY_RXON structure */ | 173 | REPLY_WIPAN_RXON = 0xb3, /* use REPLY_RXON structure */ |
174 | REPLY_WIPAN_RXON_TIMING = 0xb4, /* use REPLY_RXON_TIMING structure */ | 174 | REPLY_WIPAN_RXON_TIMING = 0xb4, /* use REPLY_RXON_TIMING structure */ |
175 | REPLY_WIPAN_RXON_ASSOC = 0xb6, /* use REPLY_RXON_ASSOC structure */ | 175 | REPLY_WIPAN_RXON_ASSOC = 0xb6, /* use REPLY_RXON_ASSOC structure */ |
176 | REPLY_WIPAN_QOS_PARAM = 0xb7, /* use REPLY_QOS_PARAM structure */ | 176 | REPLY_WIPAN_QOS_PARAM = 0xb7, /* use REPLY_QOS_PARAM structure */ |
177 | REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ | 177 | REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ |
178 | REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, | 178 | REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, |
179 | REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, | 179 | REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, |
180 | REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd, | 180 | REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd, |
181 | 181 | ||
182 | REPLY_WOWLAN_PATTERNS = 0xe0, | 182 | REPLY_WOWLAN_PATTERNS = 0xe0, |
183 | REPLY_WOWLAN_WAKEUP_FILTER = 0xe1, | 183 | REPLY_WOWLAN_WAKEUP_FILTER = 0xe1, |
184 | REPLY_WOWLAN_TSC_RSC_PARAMS = 0xe2, | 184 | REPLY_WOWLAN_TSC_RSC_PARAMS = 0xe2, |
185 | REPLY_WOWLAN_TKIP_PARAMS = 0xe3, | 185 | REPLY_WOWLAN_TKIP_PARAMS = 0xe3, |
186 | REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, | 186 | REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, |
187 | REPLY_WOWLAN_GET_STATUS = 0xe5, | 187 | REPLY_WOWLAN_GET_STATUS = 0xe5, |
188 | REPLY_D3_CONFIG = 0xd3, | 188 | REPLY_D3_CONFIG = 0xd3, |
189 | 189 | ||
190 | REPLY_MAX = 0xff | 190 | REPLY_MAX = 0xff |
191 | }; | 191 | }; |
192 | 192 | ||
193 | /* | 193 | /* |
194 | * Minimum number of queues. MAX_NUM is defined in hw specific files. | 194 | * Minimum number of queues. MAX_NUM is defined in hw specific files. |
195 | * Set the minimum to accommodate | 195 | * Set the minimum to accommodate |
196 | * - 4 standard TX queues | 196 | * - 4 standard TX queues |
197 | * - the command queue | 197 | * - the command queue |
198 | * - 4 PAN TX queues | 198 | * - 4 PAN TX queues |
199 | * - the PAN multicast queue, and | 199 | * - the PAN multicast queue, and |
200 | * - the AUX (TX during scan dwell) queue. | 200 | * - the AUX (TX during scan dwell) queue. |
201 | */ | 201 | */ |
202 | #define IWL_MIN_NUM_QUEUES 11 | 202 | #define IWL_MIN_NUM_QUEUES 11 |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * Command queue depends on iPAN support. | 205 | * Command queue depends on iPAN support. |
206 | */ | 206 | */ |
207 | #define IWL_DEFAULT_CMD_QUEUE_NUM 4 | 207 | #define IWL_DEFAULT_CMD_QUEUE_NUM 4 |
208 | #define IWL_IPAN_CMD_QUEUE_NUM 9 | 208 | #define IWL_IPAN_CMD_QUEUE_NUM 9 |
209 | 209 | ||
210 | #define IWL_TX_FIFO_BK 0 /* shared */ | 210 | #define IWL_TX_FIFO_BK 0 /* shared */ |
211 | #define IWL_TX_FIFO_BE 1 | 211 | #define IWL_TX_FIFO_BE 1 |
212 | #define IWL_TX_FIFO_VI 2 /* shared */ | 212 | #define IWL_TX_FIFO_VI 2 /* shared */ |
213 | #define IWL_TX_FIFO_VO 3 | 213 | #define IWL_TX_FIFO_VO 3 |
214 | #define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK | 214 | #define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK |
215 | #define IWL_TX_FIFO_BE_IPAN 4 | 215 | #define IWL_TX_FIFO_BE_IPAN 4 |
216 | #define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI | 216 | #define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI |
217 | #define IWL_TX_FIFO_VO_IPAN 5 | 217 | #define IWL_TX_FIFO_VO_IPAN 5 |
218 | /* re-uses the VO FIFO, uCode will properly flush/schedule */ | 218 | /* re-uses the VO FIFO, uCode will properly flush/schedule */ |
219 | #define IWL_TX_FIFO_AUX 5 | 219 | #define IWL_TX_FIFO_AUX 5 |
220 | #define IWL_TX_FIFO_UNUSED 255 | 220 | #define IWL_TX_FIFO_UNUSED 255 |
221 | 221 | ||
222 | #define IWLAGN_CMD_FIFO_NUM 7 | 222 | #define IWLAGN_CMD_FIFO_NUM 7 |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * This queue number is required for proper operation | 225 | * This queue number is required for proper operation |
226 | * because the ucode will stop/start the scheduler as | 226 | * because the ucode will stop/start the scheduler as |
227 | * required. | 227 | * required. |
228 | */ | 228 | */ |
229 | #define IWL_IPAN_MCAST_QUEUE 8 | 229 | #define IWL_IPAN_MCAST_QUEUE 8 |
230 | 230 | ||
231 | /****************************************************************************** | 231 | /****************************************************************************** |
232 | * (0) | 232 | * (0) |
233 | * Commonly used structures and definitions: | 233 | * Commonly used structures and definitions: |
234 | * Command header, rate_n_flags, txpower | 234 | * Command header, rate_n_flags, txpower |
235 | * | 235 | * |
236 | *****************************************************************************/ | 236 | *****************************************************************************/ |
237 | 237 | ||
238 | /** | 238 | /** |
239 | * iwlagn rate_n_flags bit fields | 239 | * iwlagn rate_n_flags bit fields |
240 | * | 240 | * |
241 | * rate_n_flags format is used in following iwlagn commands: | 241 | * rate_n_flags format is used in following iwlagn commands: |
242 | * REPLY_RX (response only) | 242 | * REPLY_RX (response only) |
243 | * REPLY_RX_MPDU (response only) | 243 | * REPLY_RX_MPDU (response only) |
244 | * REPLY_TX (both command and response) | 244 | * REPLY_TX (both command and response) |
245 | * REPLY_TX_LINK_QUALITY_CMD | 245 | * REPLY_TX_LINK_QUALITY_CMD |
246 | * | 246 | * |
247 | * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"): | 247 | * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"): |
248 | * 2-0: 0) 6 Mbps | 248 | * 2-0: 0) 6 Mbps |
249 | * 1) 12 Mbps | 249 | * 1) 12 Mbps |
250 | * 2) 18 Mbps | 250 | * 2) 18 Mbps |
251 | * 3) 24 Mbps | 251 | * 3) 24 Mbps |
252 | * 4) 36 Mbps | 252 | * 4) 36 Mbps |
253 | * 5) 48 Mbps | 253 | * 5) 48 Mbps |
254 | * 6) 54 Mbps | 254 | * 6) 54 Mbps |
255 | * 7) 60 Mbps | 255 | * 7) 60 Mbps |
256 | * | 256 | * |
257 | * 4-3: 0) Single stream (SISO) | 257 | * 4-3: 0) Single stream (SISO) |
258 | * 1) Dual stream (MIMO) | 258 | * 1) Dual stream (MIMO) |
259 | * 2) Triple stream (MIMO) | 259 | * 2) Triple stream (MIMO) |
260 | * | 260 | * |
261 | * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data | 261 | * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data |
262 | * | 262 | * |
263 | * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"): | 263 | * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"): |
264 | * 3-0: 0xD) 6 Mbps | 264 | * 3-0: 0xD) 6 Mbps |
265 | * 0xF) 9 Mbps | 265 | * 0xF) 9 Mbps |
266 | * 0x5) 12 Mbps | 266 | * 0x5) 12 Mbps |
267 | * 0x7) 18 Mbps | 267 | * 0x7) 18 Mbps |
268 | * 0x9) 24 Mbps | 268 | * 0x9) 24 Mbps |
269 | * 0xB) 36 Mbps | 269 | * 0xB) 36 Mbps |
270 | * 0x1) 48 Mbps | 270 | * 0x1) 48 Mbps |
271 | * 0x3) 54 Mbps | 271 | * 0x3) 54 Mbps |
272 | * | 272 | * |
273 | * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): | 273 | * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): |
274 | * 6-0: 10) 1 Mbps | 274 | * 6-0: 10) 1 Mbps |
275 | * 20) 2 Mbps | 275 | * 20) 2 Mbps |
276 | * 55) 5.5 Mbps | 276 | * 55) 5.5 Mbps |
277 | * 110) 11 Mbps | 277 | * 110) 11 Mbps |
278 | */ | 278 | */ |
279 | #define RATE_MCS_CODE_MSK 0x7 | 279 | #define RATE_MCS_CODE_MSK 0x7 |
280 | #define RATE_MCS_SPATIAL_POS 3 | 280 | #define RATE_MCS_SPATIAL_POS 3 |
281 | #define RATE_MCS_SPATIAL_MSK 0x18 | 281 | #define RATE_MCS_SPATIAL_MSK 0x18 |
282 | #define RATE_MCS_HT_DUP_POS 5 | 282 | #define RATE_MCS_HT_DUP_POS 5 |
283 | #define RATE_MCS_HT_DUP_MSK 0x20 | 283 | #define RATE_MCS_HT_DUP_MSK 0x20 |
284 | /* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */ | 284 | /* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */ |
285 | #define RATE_MCS_RATE_MSK 0xff | 285 | #define RATE_MCS_RATE_MSK 0xff |
286 | 286 | ||
287 | /* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ | 287 | /* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ |
288 | #define RATE_MCS_FLAGS_POS 8 | 288 | #define RATE_MCS_FLAGS_POS 8 |
289 | #define RATE_MCS_HT_POS 8 | 289 | #define RATE_MCS_HT_POS 8 |
290 | #define RATE_MCS_HT_MSK 0x100 | 290 | #define RATE_MCS_HT_MSK 0x100 |
291 | 291 | ||
292 | /* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ | 292 | /* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ |
293 | #define RATE_MCS_CCK_POS 9 | 293 | #define RATE_MCS_CCK_POS 9 |
294 | #define RATE_MCS_CCK_MSK 0x200 | 294 | #define RATE_MCS_CCK_MSK 0x200 |
295 | 295 | ||
296 | /* Bit 10: (1) Use Green Field preamble */ | 296 | /* Bit 10: (1) Use Green Field preamble */ |
297 | #define RATE_MCS_GF_POS 10 | 297 | #define RATE_MCS_GF_POS 10 |
298 | #define RATE_MCS_GF_MSK 0x400 | 298 | #define RATE_MCS_GF_MSK 0x400 |
299 | 299 | ||
300 | /* Bit 11: (1) Use 40Mhz HT40 chnl width, (0) use 20 MHz legacy chnl width */ | 300 | /* Bit 11: (1) Use 40Mhz HT40 chnl width, (0) use 20 MHz legacy chnl width */ |
301 | #define RATE_MCS_HT40_POS 11 | 301 | #define RATE_MCS_HT40_POS 11 |
302 | #define RATE_MCS_HT40_MSK 0x800 | 302 | #define RATE_MCS_HT40_MSK 0x800 |
303 | 303 | ||
304 | /* Bit 12: (1) Duplicate data on both 20MHz chnls. HT40 (bit 11) must be set. */ | 304 | /* Bit 12: (1) Duplicate data on both 20MHz chnls. HT40 (bit 11) must be set. */ |
305 | #define RATE_MCS_DUP_POS 12 | 305 | #define RATE_MCS_DUP_POS 12 |
306 | #define RATE_MCS_DUP_MSK 0x1000 | 306 | #define RATE_MCS_DUP_MSK 0x1000 |
307 | 307 | ||
308 | /* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ | 308 | /* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ |
309 | #define RATE_MCS_SGI_POS 13 | 309 | #define RATE_MCS_SGI_POS 13 |
310 | #define RATE_MCS_SGI_MSK 0x2000 | 310 | #define RATE_MCS_SGI_MSK 0x2000 |
311 | 311 | ||
312 | /** | 312 | /** |
313 | * rate_n_flags Tx antenna masks | 313 | * rate_n_flags Tx antenna masks |
314 | * 4965 has 2 transmitters | 314 | * 4965 has 2 transmitters |
315 | * 5100 has 1 transmitter B | 315 | * 5100 has 1 transmitter B |
316 | * 5150 has 1 transmitter A | 316 | * 5150 has 1 transmitter A |
317 | * 5300 has 3 transmitters | 317 | * 5300 has 3 transmitters |
318 | * 5350 has 3 transmitters | 318 | * 5350 has 3 transmitters |
319 | * bit14:16 | 319 | * bit14:16 |
320 | */ | 320 | */ |
321 | #define RATE_MCS_ANT_POS 14 | 321 | #define RATE_MCS_ANT_POS 14 |
322 | #define RATE_MCS_ANT_A_MSK 0x04000 | 322 | #define RATE_MCS_ANT_A_MSK 0x04000 |
323 | #define RATE_MCS_ANT_B_MSK 0x08000 | 323 | #define RATE_MCS_ANT_B_MSK 0x08000 |
324 | #define RATE_MCS_ANT_C_MSK 0x10000 | 324 | #define RATE_MCS_ANT_C_MSK 0x10000 |
325 | #define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK) | 325 | #define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK) |
326 | #define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK) | 326 | #define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK) |
327 | #define RATE_ANT_NUM 3 | 327 | #define RATE_ANT_NUM 3 |
328 | 328 | ||
329 | #define POWER_TABLE_NUM_ENTRIES 33 | 329 | #define POWER_TABLE_NUM_ENTRIES 33 |
330 | #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 | 330 | #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 |
331 | #define POWER_TABLE_CCK_ENTRY 32 | 331 | #define POWER_TABLE_CCK_ENTRY 32 |
332 | 332 | ||
333 | #define IWL_PWR_NUM_HT_OFDM_ENTRIES 24 | 333 | #define IWL_PWR_NUM_HT_OFDM_ENTRIES 24 |
334 | #define IWL_PWR_CCK_ENTRIES 2 | 334 | #define IWL_PWR_CCK_ENTRIES 2 |
335 | 335 | ||
336 | /** | 336 | /** |
337 | * struct tx_power_dual_stream | 337 | * struct tx_power_dual_stream |
338 | * | 338 | * |
339 | * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH | 339 | * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH |
340 | * | 340 | * |
341 | * Same format as iwl_tx_power_dual_stream, but __le32 | 341 | * Same format as iwl_tx_power_dual_stream, but __le32 |
342 | */ | 342 | */ |
343 | struct tx_power_dual_stream { | 343 | struct tx_power_dual_stream { |
344 | __le32 dw; | 344 | __le32 dw; |
345 | } __packed; | 345 | } __packed; |
346 | 346 | ||
347 | /** | 347 | /** |
348 | * Command REPLY_TX_POWER_DBM_CMD = 0x98 | 348 | * Command REPLY_TX_POWER_DBM_CMD = 0x98 |
349 | * struct iwlagn_tx_power_dbm_cmd | 349 | * struct iwlagn_tx_power_dbm_cmd |
350 | */ | 350 | */ |
351 | #define IWLAGN_TX_POWER_AUTO 0x7f | 351 | #define IWLAGN_TX_POWER_AUTO 0x7f |
352 | #define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6) | 352 | #define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6) |
353 | 353 | ||
354 | struct iwlagn_tx_power_dbm_cmd { | 354 | struct iwlagn_tx_power_dbm_cmd { |
355 | s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ | 355 | s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ |
356 | u8 flags; | 356 | u8 flags; |
357 | s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ | 357 | s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ |
358 | u8 reserved; | 358 | u8 reserved; |
359 | } __packed; | 359 | } __packed; |
360 | 360 | ||
361 | /** | 361 | /** |
362 | * Command TX_ANT_CONFIGURATION_CMD = 0x98 | 362 | * Command TX_ANT_CONFIGURATION_CMD = 0x98 |
363 | * This command is used to configure valid Tx antenna. | 363 | * This command is used to configure valid Tx antenna. |
364 | * By default uCode concludes the valid antenna according to the radio flavor. | 364 | * By default uCode concludes the valid antenna according to the radio flavor. |
365 | * This command enables the driver to override/modify this conclusion. | 365 | * This command enables the driver to override/modify this conclusion. |
366 | */ | 366 | */ |
367 | struct iwl_tx_ant_config_cmd { | 367 | struct iwl_tx_ant_config_cmd { |
368 | __le32 valid; | 368 | __le32 valid; |
369 | } __packed; | 369 | } __packed; |
370 | 370 | ||
371 | /****************************************************************************** | 371 | /****************************************************************************** |
372 | * (0a) | 372 | * (0a) |
373 | * Alive and Error Commands & Responses: | 373 | * Alive and Error Commands & Responses: |
374 | * | 374 | * |
375 | *****************************************************************************/ | 375 | *****************************************************************************/ |
376 | 376 | ||
377 | #define UCODE_VALID_OK cpu_to_le32(0x1) | 377 | #define UCODE_VALID_OK cpu_to_le32(0x1) |
378 | 378 | ||
379 | /** | 379 | /** |
380 | * REPLY_ALIVE = 0x1 (response only, not a command) | 380 | * REPLY_ALIVE = 0x1 (response only, not a command) |
381 | * | 381 | * |
382 | * uCode issues this "alive" notification once the runtime image is ready | 382 | * uCode issues this "alive" notification once the runtime image is ready |
383 | * to receive commands from the driver. This is the *second* "alive" | 383 | * to receive commands from the driver. This is the *second* "alive" |
384 | * notification that the driver will receive after rebooting uCode; | 384 | * notification that the driver will receive after rebooting uCode; |
385 | * this "alive" is indicated by subtype field != 9. | 385 | * this "alive" is indicated by subtype field != 9. |
386 | * | 386 | * |
387 | * See comments documenting "BSM" (bootstrap state machine). | 387 | * See comments documenting "BSM" (bootstrap state machine). |
388 | * | 388 | * |
389 | * This response includes two pointers to structures within the device's | 389 | * This response includes two pointers to structures within the device's |
390 | * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: | 390 | * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: |
391 | * | 391 | * |
392 | * 1) log_event_table_ptr indicates base of the event log. This traces | 392 | * 1) log_event_table_ptr indicates base of the event log. This traces |
393 | * a 256-entry history of uCode execution within a circular buffer. | 393 | * a 256-entry history of uCode execution within a circular buffer. |
394 | * Its header format is: | 394 | * Its header format is: |
395 | * | 395 | * |
396 | * __le32 log_size; log capacity (in number of entries) | 396 | * __le32 log_size; log capacity (in number of entries) |
397 | * __le32 type; (1) timestamp with each entry, (0) no timestamp | 397 | * __le32 type; (1) timestamp with each entry, (0) no timestamp |
398 | * __le32 wraps; # times uCode has wrapped to top of circular buffer | 398 | * __le32 wraps; # times uCode has wrapped to top of circular buffer |
399 | * __le32 write_index; next circular buffer entry that uCode would fill | 399 | * __le32 write_index; next circular buffer entry that uCode would fill |
400 | * | 400 | * |
401 | * The header is followed by the circular buffer of log entries. Entries | 401 | * The header is followed by the circular buffer of log entries. Entries |
402 | * with timestamps have the following format: | 402 | * with timestamps have the following format: |
403 | * | 403 | * |
404 | * __le32 event_id; range 0 - 1500 | 404 | * __le32 event_id; range 0 - 1500 |
405 | * __le32 timestamp; low 32 bits of TSF (of network, if associated) | 405 | * __le32 timestamp; low 32 bits of TSF (of network, if associated) |
406 | * __le32 data; event_id-specific data value | 406 | * __le32 data; event_id-specific data value |
407 | * | 407 | * |
408 | * Entries without timestamps contain only event_id and data. | 408 | * Entries without timestamps contain only event_id and data. |
409 | * | 409 | * |
410 | * | 410 | * |
411 | * 2) error_event_table_ptr indicates base of the error log. This contains | 411 | * 2) error_event_table_ptr indicates base of the error log. This contains |
412 | * information about any uCode error that occurs. For agn, the format | 412 | * information about any uCode error that occurs. For agn, the format |
413 | * of the error log is defined by struct iwl_error_event_table. | 413 | * of the error log is defined by struct iwl_error_event_table. |
414 | * | 414 | * |
415 | * The Linux driver can print both logs to the system log when a uCode error | 415 | * The Linux driver can print both logs to the system log when a uCode error |
416 | * occurs. | 416 | * occurs. |
417 | */ | 417 | */ |
418 | 418 | ||
419 | /* | 419 | /* |
420 | * Note: This structure is read from the device with IO accesses, | 420 | * Note: This structure is read from the device with IO accesses, |
421 | * and the reading already does the endian conversion. As it is | 421 | * and the reading already does the endian conversion. As it is |
422 | * read with u32-sized accesses, any members with a different size | 422 | * read with u32-sized accesses, any members with a different size |
423 | * need to be ordered correctly though! | 423 | * need to be ordered correctly though! |
424 | */ | 424 | */ |
425 | struct iwl_error_event_table { | 425 | struct iwl_error_event_table { |
426 | u32 valid; /* (nonzero) valid, (0) log is empty */ | 426 | u32 valid; /* (nonzero) valid, (0) log is empty */ |
427 | u32 error_id; /* type of error */ | 427 | u32 error_id; /* type of error */ |
428 | u32 pc; /* program counter */ | 428 | u32 pc; /* program counter */ |
429 | u32 blink1; /* branch link */ | 429 | u32 blink1; /* branch link */ |
430 | u32 blink2; /* branch link */ | 430 | u32 blink2; /* branch link */ |
431 | u32 ilink1; /* interrupt link */ | 431 | u32 ilink1; /* interrupt link */ |
432 | u32 ilink2; /* interrupt link */ | 432 | u32 ilink2; /* interrupt link */ |
433 | u32 data1; /* error-specific data */ | 433 | u32 data1; /* error-specific data */ |
434 | u32 data2; /* error-specific data */ | 434 | u32 data2; /* error-specific data */ |
435 | u32 line; /* source code line of error */ | 435 | u32 line; /* source code line of error */ |
436 | u32 bcon_time; /* beacon timer */ | 436 | u32 bcon_time; /* beacon timer */ |
437 | u32 tsf_low; /* network timestamp function timer */ | 437 | u32 tsf_low; /* network timestamp function timer */ |
438 | u32 tsf_hi; /* network timestamp function timer */ | 438 | u32 tsf_hi; /* network timestamp function timer */ |
439 | u32 gp1; /* GP1 timer register */ | 439 | u32 gp1; /* GP1 timer register */ |
440 | u32 gp2; /* GP2 timer register */ | 440 | u32 gp2; /* GP2 timer register */ |
441 | u32 gp3; /* GP3 timer register */ | 441 | u32 gp3; /* GP3 timer register */ |
442 | u32 ucode_ver; /* uCode version */ | 442 | u32 ucode_ver; /* uCode version */ |
443 | u32 hw_ver; /* HW Silicon version */ | 443 | u32 hw_ver; /* HW Silicon version */ |
444 | u32 brd_ver; /* HW board version */ | 444 | u32 brd_ver; /* HW board version */ |
445 | u32 log_pc; /* log program counter */ | 445 | u32 log_pc; /* log program counter */ |
446 | u32 frame_ptr; /* frame pointer */ | 446 | u32 frame_ptr; /* frame pointer */ |
447 | u32 stack_ptr; /* stack pointer */ | 447 | u32 stack_ptr; /* stack pointer */ |
448 | u32 hcmd; /* last host command header */ | 448 | u32 hcmd; /* last host command header */ |
449 | u32 isr0; /* isr status register LMPM_NIC_ISR0: | 449 | u32 isr0; /* isr status register LMPM_NIC_ISR0: |
450 | * rxtx_flag */ | 450 | * rxtx_flag */ |
451 | u32 isr1; /* isr status register LMPM_NIC_ISR1: | 451 | u32 isr1; /* isr status register LMPM_NIC_ISR1: |
452 | * host_flag */ | 452 | * host_flag */ |
453 | u32 isr2; /* isr status register LMPM_NIC_ISR2: | 453 | u32 isr2; /* isr status register LMPM_NIC_ISR2: |
454 | * enc_flag */ | 454 | * enc_flag */ |
455 | u32 isr3; /* isr status register LMPM_NIC_ISR3: | 455 | u32 isr3; /* isr status register LMPM_NIC_ISR3: |
456 | * time_flag */ | 456 | * time_flag */ |
457 | u32 isr4; /* isr status register LMPM_NIC_ISR4: | 457 | u32 isr4; /* isr status register LMPM_NIC_ISR4: |
458 | * wico interrupt */ | 458 | * wico interrupt */ |
459 | u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */ | 459 | u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */ |
460 | u32 wait_event; /* wait event() caller address */ | 460 | u32 wait_event; /* wait event() caller address */ |
461 | u32 l2p_control; /* L2pControlField */ | 461 | u32 l2p_control; /* L2pControlField */ |
462 | u32 l2p_duration; /* L2pDurationField */ | 462 | u32 l2p_duration; /* L2pDurationField */ |
463 | u32 l2p_mhvalid; /* L2pMhValidBits */ | 463 | u32 l2p_mhvalid; /* L2pMhValidBits */ |
464 | u32 l2p_addr_match; /* L2pAddrMatchStat */ | 464 | u32 l2p_addr_match; /* L2pAddrMatchStat */ |
465 | u32 lmpm_pmg_sel; /* indicate which clocks are turned on | 465 | u32 lmpm_pmg_sel; /* indicate which clocks are turned on |
466 | * (LMPM_PMG_SEL) */ | 466 | * (LMPM_PMG_SEL) */ |
467 | u32 u_timestamp; /* indicate when the date and time of the | 467 | u32 u_timestamp; /* indicate when the date and time of the |
468 | * compilation */ | 468 | * compilation */ |
469 | u32 flow_handler; /* FH read/write pointers, RX credit */ | 469 | u32 flow_handler; /* FH read/write pointers, RX credit */ |
470 | } __packed; | 470 | } __packed; |
471 | 471 | ||
472 | struct iwl_alive_resp { | 472 | struct iwl_alive_resp { |
473 | u8 ucode_minor; | 473 | u8 ucode_minor; |
474 | u8 ucode_major; | 474 | u8 ucode_major; |
475 | __le16 reserved1; | 475 | __le16 reserved1; |
476 | u8 sw_rev[8]; | 476 | u8 sw_rev[8]; |
477 | u8 ver_type; | 477 | u8 ver_type; |
478 | u8 ver_subtype; /* not "9" for runtime alive */ | 478 | u8 ver_subtype; /* not "9" for runtime alive */ |
479 | __le16 reserved2; | 479 | __le16 reserved2; |
480 | __le32 log_event_table_ptr; /* SRAM address for event log */ | 480 | __le32 log_event_table_ptr; /* SRAM address for event log */ |
481 | __le32 error_event_table_ptr; /* SRAM address for error log */ | 481 | __le32 error_event_table_ptr; /* SRAM address for error log */ |
482 | __le32 timestamp; | 482 | __le32 timestamp; |
483 | __le32 is_valid; | 483 | __le32 is_valid; |
484 | } __packed; | 484 | } __packed; |
485 | 485 | ||
486 | /* | 486 | /* |
487 | * REPLY_ERROR = 0x2 (response only, not a command) | 487 | * REPLY_ERROR = 0x2 (response only, not a command) |
488 | */ | 488 | */ |
489 | struct iwl_error_resp { | 489 | struct iwl_error_resp { |
490 | __le32 error_type; | 490 | __le32 error_type; |
491 | u8 cmd_id; | 491 | u8 cmd_id; |
492 | u8 reserved1; | 492 | u8 reserved1; |
493 | __le16 bad_cmd_seq_num; | 493 | __le16 bad_cmd_seq_num; |
494 | __le32 error_info; | 494 | __le32 error_info; |
495 | __le64 timestamp; | 495 | __le64 timestamp; |
496 | } __packed; | 496 | } __packed; |
497 | 497 | ||
498 | /****************************************************************************** | 498 | /****************************************************************************** |
499 | * (1) | 499 | * (1) |
500 | * RXON Commands & Responses: | 500 | * RXON Commands & Responses: |
501 | * | 501 | * |
502 | *****************************************************************************/ | 502 | *****************************************************************************/ |
503 | 503 | ||
504 | /* | 504 | /* |
505 | * Rx config defines & structure | 505 | * Rx config defines & structure |
506 | */ | 506 | */ |
507 | /* rx_config device types */ | 507 | /* rx_config device types */ |
508 | enum { | 508 | enum { |
509 | RXON_DEV_TYPE_AP = 1, | 509 | RXON_DEV_TYPE_AP = 1, |
510 | RXON_DEV_TYPE_ESS = 3, | 510 | RXON_DEV_TYPE_ESS = 3, |
511 | RXON_DEV_TYPE_IBSS = 4, | 511 | RXON_DEV_TYPE_IBSS = 4, |
512 | RXON_DEV_TYPE_SNIFFER = 6, | 512 | RXON_DEV_TYPE_SNIFFER = 6, |
513 | RXON_DEV_TYPE_CP = 7, | 513 | RXON_DEV_TYPE_CP = 7, |
514 | RXON_DEV_TYPE_2STA = 8, | 514 | RXON_DEV_TYPE_2STA = 8, |
515 | RXON_DEV_TYPE_P2P = 9, | 515 | RXON_DEV_TYPE_P2P = 9, |
516 | }; | 516 | }; |
517 | 517 | ||
518 | 518 | ||
519 | #define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0) | 519 | #define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0) |
520 | #define RXON_RX_CHAIN_DRIVER_FORCE_POS (0) | 520 | #define RXON_RX_CHAIN_DRIVER_FORCE_POS (0) |
521 | #define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1) | 521 | #define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1) |
522 | #define RXON_RX_CHAIN_VALID_POS (1) | 522 | #define RXON_RX_CHAIN_VALID_POS (1) |
523 | #define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4) | 523 | #define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4) |
524 | #define RXON_RX_CHAIN_FORCE_SEL_POS (4) | 524 | #define RXON_RX_CHAIN_FORCE_SEL_POS (4) |
525 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK cpu_to_le16(0x7 << 7) | 525 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK cpu_to_le16(0x7 << 7) |
526 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) | 526 | #define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) |
527 | #define RXON_RX_CHAIN_CNT_MSK cpu_to_le16(0x3 << 10) | 527 | #define RXON_RX_CHAIN_CNT_MSK cpu_to_le16(0x3 << 10) |
528 | #define RXON_RX_CHAIN_CNT_POS (10) | 528 | #define RXON_RX_CHAIN_CNT_POS (10) |
529 | #define RXON_RX_CHAIN_MIMO_CNT_MSK cpu_to_le16(0x3 << 12) | 529 | #define RXON_RX_CHAIN_MIMO_CNT_MSK cpu_to_le16(0x3 << 12) |
530 | #define RXON_RX_CHAIN_MIMO_CNT_POS (12) | 530 | #define RXON_RX_CHAIN_MIMO_CNT_POS (12) |
531 | #define RXON_RX_CHAIN_MIMO_FORCE_MSK cpu_to_le16(0x1 << 14) | 531 | #define RXON_RX_CHAIN_MIMO_FORCE_MSK cpu_to_le16(0x1 << 14) |
532 | #define RXON_RX_CHAIN_MIMO_FORCE_POS (14) | 532 | #define RXON_RX_CHAIN_MIMO_FORCE_POS (14) |
533 | 533 | ||
534 | /* rx_config flags */ | 534 | /* rx_config flags */ |
535 | /* band & modulation selection */ | 535 | /* band & modulation selection */ |
536 | #define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0) | 536 | #define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0) |
537 | #define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1) | 537 | #define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1) |
538 | /* auto detection enable */ | 538 | /* auto detection enable */ |
539 | #define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2) | 539 | #define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2) |
540 | /* TGg protection when tx */ | 540 | /* TGg protection when tx */ |
541 | #define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3) | 541 | #define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3) |
542 | /* cck short slot & preamble */ | 542 | /* cck short slot & preamble */ |
543 | #define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4) | 543 | #define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4) |
544 | #define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5) | 544 | #define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5) |
545 | /* antenna selection */ | 545 | /* antenna selection */ |
546 | #define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7) | 546 | #define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7) |
547 | #define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00) | 547 | #define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00) |
548 | #define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8) | 548 | #define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8) |
549 | #define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9) | 549 | #define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9) |
550 | /* radar detection enable */ | 550 | /* radar detection enable */ |
551 | #define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12) | 551 | #define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12) |
552 | #define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13) | 552 | #define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13) |
553 | /* rx response to host with 8-byte TSF | 553 | /* rx response to host with 8-byte TSF |
554 | * (according to ON_AIR deassertion) */ | 554 | * (according to ON_AIR deassertion) */ |
555 | #define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15) | 555 | #define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15) |
556 | 556 | ||
557 | 557 | ||
558 | /* HT flags */ | 558 | /* HT flags */ |
559 | #define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) | 559 | #define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) |
560 | #define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK cpu_to_le32(0x1 << 22) | 560 | #define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK cpu_to_le32(0x1 << 22) |
561 | 561 | ||
562 | #define RXON_FLG_HT_OPERATING_MODE_POS (23) | 562 | #define RXON_FLG_HT_OPERATING_MODE_POS (23) |
563 | 563 | ||
564 | #define RXON_FLG_HT_PROT_MSK cpu_to_le32(0x1 << 23) | 564 | #define RXON_FLG_HT_PROT_MSK cpu_to_le32(0x1 << 23) |
565 | #define RXON_FLG_HT40_PROT_MSK cpu_to_le32(0x2 << 23) | 565 | #define RXON_FLG_HT40_PROT_MSK cpu_to_le32(0x2 << 23) |
566 | 566 | ||
567 | #define RXON_FLG_CHANNEL_MODE_POS (25) | 567 | #define RXON_FLG_CHANNEL_MODE_POS (25) |
568 | #define RXON_FLG_CHANNEL_MODE_MSK cpu_to_le32(0x3 << 25) | 568 | #define RXON_FLG_CHANNEL_MODE_MSK cpu_to_le32(0x3 << 25) |
569 | 569 | ||
570 | /* channel mode */ | 570 | /* channel mode */ |
571 | enum { | 571 | enum { |
572 | CHANNEL_MODE_LEGACY = 0, | 572 | CHANNEL_MODE_LEGACY = 0, |
573 | CHANNEL_MODE_PURE_40 = 1, | 573 | CHANNEL_MODE_PURE_40 = 1, |
574 | CHANNEL_MODE_MIXED = 2, | 574 | CHANNEL_MODE_MIXED = 2, |
575 | CHANNEL_MODE_RESERVED = 3, | 575 | CHANNEL_MODE_RESERVED = 3, |
576 | }; | 576 | }; |
577 | #define RXON_FLG_CHANNEL_MODE_LEGACY cpu_to_le32(CHANNEL_MODE_LEGACY << RXON_FLG_CHANNEL_MODE_POS) | 577 | #define RXON_FLG_CHANNEL_MODE_LEGACY cpu_to_le32(CHANNEL_MODE_LEGACY << RXON_FLG_CHANNEL_MODE_POS) |
578 | #define RXON_FLG_CHANNEL_MODE_PURE_40 cpu_to_le32(CHANNEL_MODE_PURE_40 << RXON_FLG_CHANNEL_MODE_POS) | 578 | #define RXON_FLG_CHANNEL_MODE_PURE_40 cpu_to_le32(CHANNEL_MODE_PURE_40 << RXON_FLG_CHANNEL_MODE_POS) |
579 | #define RXON_FLG_CHANNEL_MODE_MIXED cpu_to_le32(CHANNEL_MODE_MIXED << RXON_FLG_CHANNEL_MODE_POS) | 579 | #define RXON_FLG_CHANNEL_MODE_MIXED cpu_to_le32(CHANNEL_MODE_MIXED << RXON_FLG_CHANNEL_MODE_POS) |
580 | 580 | ||
581 | /* CTS to self (if spec allows) flag */ | 581 | /* CTS to self (if spec allows) flag */ |
582 | #define RXON_FLG_SELF_CTS_EN cpu_to_le32(0x1<<30) | 582 | #define RXON_FLG_SELF_CTS_EN cpu_to_le32(0x1<<30) |
583 | 583 | ||
584 | /* rx_config filter flags */ | 584 | /* rx_config filter flags */ |
585 | /* accept all data frames */ | 585 | /* accept all data frames */ |
586 | #define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0) | 586 | #define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0) |
587 | /* pass control & management to host */ | 587 | /* pass control & management to host */ |
588 | #define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1) | 588 | #define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1) |
589 | /* accept multi-cast */ | 589 | /* accept multi-cast */ |
590 | #define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2) | 590 | #define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2) |
591 | /* don't decrypt uni-cast frames */ | 591 | /* don't decrypt uni-cast frames */ |
592 | #define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3) | 592 | #define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3) |
593 | /* don't decrypt multi-cast frames */ | 593 | /* don't decrypt multi-cast frames */ |
594 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4) | 594 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4) |
595 | /* STA is associated */ | 595 | /* STA is associated */ |
596 | #define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5) | 596 | #define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5) |
597 | /* transfer to host non bssid beacons in associated state */ | 597 | /* transfer to host non bssid beacons in associated state */ |
598 | #define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6) | 598 | #define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6) |
599 | 599 | ||
600 | /** | 600 | /** |
601 | * REPLY_RXON = 0x10 (command, has simple generic response) | 601 | * REPLY_RXON = 0x10 (command, has simple generic response) |
602 | * | 602 | * |
603 | * RXON tunes the radio tuner to a service channel, and sets up a number | 603 | * RXON tunes the radio tuner to a service channel, and sets up a number |
604 | * of parameters that are used primarily for Rx, but also for Tx operations. | 604 | * of parameters that are used primarily for Rx, but also for Tx operations. |
605 | * | 605 | * |
606 | * NOTE: When tuning to a new channel, driver must set the | 606 | * NOTE: When tuning to a new channel, driver must set the |
607 | * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent | 607 | * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent |
608 | * info within the device, including the station tables, tx retry | 608 | * info within the device, including the station tables, tx retry |
609 | * rate tables, and txpower tables. Driver must build a new station | 609 | * rate tables, and txpower tables. Driver must build a new station |
610 | * table and txpower table before transmitting anything on the RXON | 610 | * table and txpower table before transmitting anything on the RXON |
611 | * channel. | 611 | * channel. |
612 | * | 612 | * |
613 | * NOTE: All RXONs wipe clean the internal txpower table. Driver must | 613 | * NOTE: All RXONs wipe clean the internal txpower table. Driver must |
614 | * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), | 614 | * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), |
615 | * regardless of whether RXON_FILTER_ASSOC_MSK is set. | 615 | * regardless of whether RXON_FILTER_ASSOC_MSK is set. |
616 | */ | 616 | */ |
617 | 617 | ||
618 | struct iwl_rxon_cmd { | 618 | struct iwl_rxon_cmd { |
619 | u8 node_addr[6]; | 619 | u8 node_addr[6]; |
620 | __le16 reserved1; | 620 | __le16 reserved1; |
621 | u8 bssid_addr[6]; | 621 | u8 bssid_addr[6]; |
622 | __le16 reserved2; | 622 | __le16 reserved2; |
623 | u8 wlap_bssid_addr[6]; | 623 | u8 wlap_bssid_addr[6]; |
624 | __le16 reserved3; | 624 | __le16 reserved3; |
625 | u8 dev_type; | 625 | u8 dev_type; |
626 | u8 air_propagation; | 626 | u8 air_propagation; |
627 | __le16 rx_chain; | 627 | __le16 rx_chain; |
628 | u8 ofdm_basic_rates; | 628 | u8 ofdm_basic_rates; |
629 | u8 cck_basic_rates; | 629 | u8 cck_basic_rates; |
630 | __le16 assoc_id; | 630 | __le16 assoc_id; |
631 | __le32 flags; | 631 | __le32 flags; |
632 | __le32 filter_flags; | 632 | __le32 filter_flags; |
633 | __le16 channel; | 633 | __le16 channel; |
634 | u8 ofdm_ht_single_stream_basic_rates; | 634 | u8 ofdm_ht_single_stream_basic_rates; |
635 | u8 ofdm_ht_dual_stream_basic_rates; | 635 | u8 ofdm_ht_dual_stream_basic_rates; |
636 | u8 ofdm_ht_triple_stream_basic_rates; | 636 | u8 ofdm_ht_triple_stream_basic_rates; |
637 | u8 reserved5; | 637 | u8 reserved5; |
638 | __le16 acquisition_data; | 638 | __le16 acquisition_data; |
639 | __le16 reserved6; | 639 | __le16 reserved6; |
640 | } __packed; | 640 | } __packed; |
641 | 641 | ||
642 | /* | 642 | /* |
643 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) | 643 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) |
644 | */ | 644 | */ |
645 | struct iwl_rxon_assoc_cmd { | 645 | struct iwl_rxon_assoc_cmd { |
646 | __le32 flags; | 646 | __le32 flags; |
647 | __le32 filter_flags; | 647 | __le32 filter_flags; |
648 | u8 ofdm_basic_rates; | 648 | u8 ofdm_basic_rates; |
649 | u8 cck_basic_rates; | 649 | u8 cck_basic_rates; |
650 | __le16 reserved1; | 650 | __le16 reserved1; |
651 | u8 ofdm_ht_single_stream_basic_rates; | 651 | u8 ofdm_ht_single_stream_basic_rates; |
652 | u8 ofdm_ht_dual_stream_basic_rates; | 652 | u8 ofdm_ht_dual_stream_basic_rates; |
653 | u8 ofdm_ht_triple_stream_basic_rates; | 653 | u8 ofdm_ht_triple_stream_basic_rates; |
654 | u8 reserved2; | 654 | u8 reserved2; |
655 | __le16 rx_chain_select_flags; | 655 | __le16 rx_chain_select_flags; |
656 | __le16 acquisition_data; | 656 | __le16 acquisition_data; |
657 | __le32 reserved3; | 657 | __le32 reserved3; |
658 | } __packed; | 658 | } __packed; |
659 | 659 | ||
660 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 | 660 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 |
661 | #define IWL_MAX_UCODE_BEACON_INTERVAL 4 /* 4096 */ | 661 | #define IWL_MAX_UCODE_BEACON_INTERVAL 4 /* 4096 */ |
662 | 662 | ||
663 | /* | 663 | /* |
664 | * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) | 664 | * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) |
665 | */ | 665 | */ |
666 | struct iwl_rxon_time_cmd { | 666 | struct iwl_rxon_time_cmd { |
667 | __le64 timestamp; | 667 | __le64 timestamp; |
668 | __le16 beacon_interval; | 668 | __le16 beacon_interval; |
669 | __le16 atim_window; | 669 | __le16 atim_window; |
670 | __le32 beacon_init_val; | 670 | __le32 beacon_init_val; |
671 | __le16 listen_interval; | 671 | __le16 listen_interval; |
672 | u8 dtim_period; | 672 | u8 dtim_period; |
673 | u8 delta_cp_bss_tbtts; | 673 | u8 delta_cp_bss_tbtts; |
674 | } __packed; | 674 | } __packed; |
675 | 675 | ||
676 | /* | 676 | /* |
677 | * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) | 677 | * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) |
678 | */ | 678 | */ |
679 | /** | 679 | /** |
680 | * struct iwl5000_channel_switch_cmd | 680 | * struct iwl5000_channel_switch_cmd |
681 | * @band: 0- 5.2GHz, 1- 2.4GHz | 681 | * @band: 0- 5.2GHz, 1- 2.4GHz |
682 | * @expect_beacon: 0- resume transmits after channel switch | 682 | * @expect_beacon: 0- resume transmits after channel switch |
683 | * 1- wait for beacon to resume transmits | 683 | * 1- wait for beacon to resume transmits |
684 | * @channel: new channel number | 684 | * @channel: new channel number |
685 | * @rxon_flags: Rx on flags | 685 | * @rxon_flags: Rx on flags |
686 | * @rxon_filter_flags: filtering parameters | 686 | * @rxon_filter_flags: filtering parameters |
687 | * @switch_time: switch time in extended beacon format | 687 | * @switch_time: switch time in extended beacon format |
688 | * @reserved: reserved bytes | 688 | * @reserved: reserved bytes |
689 | */ | 689 | */ |
690 | struct iwl5000_channel_switch_cmd { | 690 | struct iwl5000_channel_switch_cmd { |
691 | u8 band; | 691 | u8 band; |
692 | u8 expect_beacon; | 692 | u8 expect_beacon; |
693 | __le16 channel; | 693 | __le16 channel; |
694 | __le32 rxon_flags; | 694 | __le32 rxon_flags; |
695 | __le32 rxon_filter_flags; | 695 | __le32 rxon_filter_flags; |
696 | __le32 switch_time; | 696 | __le32 switch_time; |
697 | __le32 reserved[2][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; | 697 | __le32 reserved[2][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; |
698 | } __packed; | 698 | } __packed; |
699 | 699 | ||
700 | /** | 700 | /** |
701 | * struct iwl6000_channel_switch_cmd | 701 | * struct iwl6000_channel_switch_cmd |
702 | * @band: 0- 5.2GHz, 1- 2.4GHz | 702 | * @band: 0- 5.2GHz, 1- 2.4GHz |
703 | * @expect_beacon: 0- resume transmits after channel switch | 703 | * @expect_beacon: 0- resume transmits after channel switch |
704 | * 1- wait for beacon to resume transmits | 704 | * 1- wait for beacon to resume transmits |
705 | * @channel: new channel number | 705 | * @channel: new channel number |
706 | * @rxon_flags: Rx on flags | 706 | * @rxon_flags: Rx on flags |
707 | * @rxon_filter_flags: filtering parameters | 707 | * @rxon_filter_flags: filtering parameters |
708 | * @switch_time: switch time in extended beacon format | 708 | * @switch_time: switch time in extended beacon format |
709 | * @reserved: reserved bytes | 709 | * @reserved: reserved bytes |
710 | */ | 710 | */ |
711 | struct iwl6000_channel_switch_cmd { | 711 | struct iwl6000_channel_switch_cmd { |
712 | u8 band; | 712 | u8 band; |
713 | u8 expect_beacon; | 713 | u8 expect_beacon; |
714 | __le16 channel; | 714 | __le16 channel; |
715 | __le32 rxon_flags; | 715 | __le32 rxon_flags; |
716 | __le32 rxon_filter_flags; | 716 | __le32 rxon_filter_flags; |
717 | __le32 switch_time; | 717 | __le32 switch_time; |
718 | __le32 reserved[3][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; | 718 | __le32 reserved[3][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; |
719 | } __packed; | 719 | } __packed; |
720 | 720 | ||
721 | /* | 721 | /* |
722 | * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) | 722 | * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) |
723 | */ | 723 | */ |
724 | struct iwl_csa_notification { | 724 | struct iwl_csa_notification { |
725 | __le16 band; | 725 | __le16 band; |
726 | __le16 channel; | 726 | __le16 channel; |
727 | __le32 status; /* 0 - OK, 1 - fail */ | 727 | __le32 status; /* 0 - OK, 1 - fail */ |
728 | } __packed; | 728 | } __packed; |
729 | 729 | ||
730 | /****************************************************************************** | 730 | /****************************************************************************** |
731 | * (2) | 731 | * (2) |
732 | * Quality-of-Service (QOS) Commands & Responses: | 732 | * Quality-of-Service (QOS) Commands & Responses: |
733 | * | 733 | * |
734 | *****************************************************************************/ | 734 | *****************************************************************************/ |
735 | 735 | ||
736 | /** | 736 | /** |
737 | * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM | 737 | * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM |
738 | * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd | 738 | * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd |
739 | * | 739 | * |
740 | * @cw_min: Contention window, start value in numbers of slots. | 740 | * @cw_min: Contention window, start value in numbers of slots. |
741 | * Should be a power-of-2, minus 1. Device's default is 0x0f. | 741 | * Should be a power-of-2, minus 1. Device's default is 0x0f. |
742 | * @cw_max: Contention window, max value in numbers of slots. | 742 | * @cw_max: Contention window, max value in numbers of slots. |
743 | * Should be a power-of-2, minus 1. Device's default is 0x3f. | 743 | * Should be a power-of-2, minus 1. Device's default is 0x3f. |
744 | * @aifsn: Number of slots in Arbitration Interframe Space (before | 744 | * @aifsn: Number of slots in Arbitration Interframe Space (before |
745 | * performing random backoff timing prior to Tx). Device default 1. | 745 | * performing random backoff timing prior to Tx). Device default 1. |
746 | * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. | 746 | * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. |
747 | * | 747 | * |
748 | * Device will automatically increase contention window by (2*CW) + 1 for each | 748 | * Device will automatically increase contention window by (2*CW) + 1 for each |
749 | * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW | 749 | * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW |
750 | * value, to cap the CW value. | 750 | * value, to cap the CW value. |
751 | */ | 751 | */ |
752 | struct iwl_ac_qos { | 752 | struct iwl_ac_qos { |
753 | __le16 cw_min; | 753 | __le16 cw_min; |
754 | __le16 cw_max; | 754 | __le16 cw_max; |
755 | u8 aifsn; | 755 | u8 aifsn; |
756 | u8 reserved1; | 756 | u8 reserved1; |
757 | __le16 edca_txop; | 757 | __le16 edca_txop; |
758 | } __packed; | 758 | } __packed; |
759 | 759 | ||
760 | /* QoS flags defines */ | 760 | /* QoS flags defines */ |
761 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) | 761 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) |
762 | #define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02) | 762 | #define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02) |
763 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10) | 763 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10) |
764 | 764 | ||
765 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ | 765 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ |
766 | #define AC_NUM 4 | 766 | #define AC_NUM 4 |
767 | 767 | ||
768 | /* | 768 | /* |
769 | * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) | 769 | * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) |
770 | * | 770 | * |
771 | * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs | 771 | * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs |
772 | * 0: Background, 1: Best Effort, 2: Video, 3: Voice. | 772 | * 0: Background, 1: Best Effort, 2: Video, 3: Voice. |
773 | */ | 773 | */ |
774 | struct iwl_qosparam_cmd { | 774 | struct iwl_qosparam_cmd { |
775 | __le32 qos_flags; | 775 | __le32 qos_flags; |
776 | struct iwl_ac_qos ac[AC_NUM]; | 776 | struct iwl_ac_qos ac[AC_NUM]; |
777 | } __packed; | 777 | } __packed; |
778 | 778 | ||
779 | /****************************************************************************** | 779 | /****************************************************************************** |
780 | * (3) | 780 | * (3) |
781 | * Add/Modify Stations Commands & Responses: | 781 | * Add/Modify Stations Commands & Responses: |
782 | * | 782 | * |
783 | *****************************************************************************/ | 783 | *****************************************************************************/ |
784 | /* | 784 | /* |
785 | * Multi station support | 785 | * Multi station support |
786 | */ | 786 | */ |
787 | 787 | ||
788 | /* Special, dedicated locations within device's station table */ | 788 | /* Special, dedicated locations within device's station table */ |
789 | #define IWL_AP_ID 0 | 789 | #define IWL_AP_ID 0 |
790 | #define IWL_AP_ID_PAN 1 | 790 | #define IWL_AP_ID_PAN 1 |
791 | #define IWL_STA_ID 2 | 791 | #define IWL_STA_ID 2 |
792 | #define IWLAGN_PAN_BCAST_ID 14 | 792 | #define IWLAGN_PAN_BCAST_ID 14 |
793 | #define IWLAGN_BROADCAST_ID 15 | 793 | #define IWLAGN_BROADCAST_ID 15 |
794 | #define IWLAGN_STATION_COUNT 16 | 794 | #define IWLAGN_STATION_COUNT 16 |
795 | 795 | ||
796 | #define IWL_TID_NON_QOS IWL_MAX_TID_COUNT | 796 | #define IWL_TID_NON_QOS IWL_MAX_TID_COUNT |
797 | 797 | ||
798 | #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) | 798 | #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) |
799 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) | 799 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) |
800 | #define STA_FLG_PAN_STATION cpu_to_le32(1 << 13) | 800 | #define STA_FLG_PAN_STATION cpu_to_le32(1 << 13) |
801 | #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) | 801 | #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) |
802 | #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) | 802 | #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) |
803 | #define STA_FLG_MAX_AGG_SIZE_POS (19) | 803 | #define STA_FLG_MAX_AGG_SIZE_POS (19) |
804 | #define STA_FLG_MAX_AGG_SIZE_MSK cpu_to_le32(3 << 19) | 804 | #define STA_FLG_MAX_AGG_SIZE_MSK cpu_to_le32(3 << 19) |
805 | #define STA_FLG_HT40_EN_MSK cpu_to_le32(1 << 21) | 805 | #define STA_FLG_HT40_EN_MSK cpu_to_le32(1 << 21) |
806 | #define STA_FLG_MIMO_DIS_MSK cpu_to_le32(1 << 22) | 806 | #define STA_FLG_MIMO_DIS_MSK cpu_to_le32(1 << 22) |
807 | #define STA_FLG_AGG_MPDU_DENSITY_POS (23) | 807 | #define STA_FLG_AGG_MPDU_DENSITY_POS (23) |
808 | #define STA_FLG_AGG_MPDU_DENSITY_MSK cpu_to_le32(7 << 23) | 808 | #define STA_FLG_AGG_MPDU_DENSITY_MSK cpu_to_le32(7 << 23) |
809 | 809 | ||
810 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ | 810 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ |
811 | #define STA_CONTROL_MODIFY_MSK 0x01 | 811 | #define STA_CONTROL_MODIFY_MSK 0x01 |
812 | 812 | ||
813 | /* key flags __le16*/ | 813 | /* key flags __le16*/ |
814 | #define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007) | 814 | #define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007) |
815 | #define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000) | 815 | #define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000) |
816 | #define STA_KEY_FLG_WEP cpu_to_le16(0x0001) | 816 | #define STA_KEY_FLG_WEP cpu_to_le16(0x0001) |
817 | #define STA_KEY_FLG_CCMP cpu_to_le16(0x0002) | 817 | #define STA_KEY_FLG_CCMP cpu_to_le16(0x0002) |
818 | #define STA_KEY_FLG_TKIP cpu_to_le16(0x0003) | 818 | #define STA_KEY_FLG_TKIP cpu_to_le16(0x0003) |
819 | 819 | ||
820 | #define STA_KEY_FLG_KEYID_POS 8 | 820 | #define STA_KEY_FLG_KEYID_POS 8 |
821 | #define STA_KEY_FLG_INVALID cpu_to_le16(0x0800) | 821 | #define STA_KEY_FLG_INVALID cpu_to_le16(0x0800) |
822 | /* wep key is either from global key (0) or from station info array (1) */ | 822 | /* wep key is either from global key (0) or from station info array (1) */ |
823 | #define STA_KEY_FLG_MAP_KEY_MSK cpu_to_le16(0x0008) | 823 | #define STA_KEY_FLG_MAP_KEY_MSK cpu_to_le16(0x0008) |
824 | 824 | ||
825 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | 825 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ |
826 | #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) | 826 | #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) |
827 | #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) | 827 | #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) |
828 | #define STA_KEY_MAX_NUM 8 | 828 | #define STA_KEY_MAX_NUM 8 |
829 | #define STA_KEY_MAX_NUM_PAN 16 | 829 | #define STA_KEY_MAX_NUM_PAN 16 |
830 | /* must not match WEP_INVALID_OFFSET */ | 830 | /* must not match WEP_INVALID_OFFSET */ |
831 | #define IWLAGN_HW_KEY_DEFAULT 0xfe | 831 | #define IWLAGN_HW_KEY_DEFAULT 0xfe |
832 | 832 | ||
833 | /* Flags indicate whether to modify vs. don't change various station params */ | 833 | /* Flags indicate whether to modify vs. don't change various station params */ |
834 | #define STA_MODIFY_KEY_MASK 0x01 | 834 | #define STA_MODIFY_KEY_MASK 0x01 |
835 | #define STA_MODIFY_TID_DISABLE_TX 0x02 | 835 | #define STA_MODIFY_TID_DISABLE_TX 0x02 |
836 | #define STA_MODIFY_TX_RATE_MSK 0x04 | 836 | #define STA_MODIFY_TX_RATE_MSK 0x04 |
837 | #define STA_MODIFY_ADDBA_TID_MSK 0x08 | 837 | #define STA_MODIFY_ADDBA_TID_MSK 0x08 |
838 | #define STA_MODIFY_DELBA_TID_MSK 0x10 | 838 | #define STA_MODIFY_DELBA_TID_MSK 0x10 |
839 | #define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 | 839 | #define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 |
840 | 840 | ||
841 | /* Receiver address (actually, Rx station's index into station table), | 841 | /* Receiver address (actually, Rx station's index into station table), |
842 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ | 842 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ |
843 | #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) | 843 | #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) |
844 | 844 | ||
845 | /* agn */ | 845 | /* agn */ |
846 | struct iwl_keyinfo { | 846 | struct iwl_keyinfo { |
847 | __le16 key_flags; | 847 | __le16 key_flags; |
848 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | 848 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ |
849 | u8 reserved1; | 849 | u8 reserved1; |
850 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | 850 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ |
851 | u8 key_offset; | 851 | u8 key_offset; |
852 | u8 reserved2; | 852 | u8 reserved2; |
853 | u8 key[16]; /* 16-byte unicast decryption key */ | 853 | u8 key[16]; /* 16-byte unicast decryption key */ |
854 | __le64 tx_secur_seq_cnt; | 854 | __le64 tx_secur_seq_cnt; |
855 | __le64 hw_tkip_mic_rx_key; | 855 | __le64 hw_tkip_mic_rx_key; |
856 | __le64 hw_tkip_mic_tx_key; | 856 | __le64 hw_tkip_mic_tx_key; |
857 | } __packed; | 857 | } __packed; |
858 | 858 | ||
859 | /** | 859 | /** |
860 | * struct sta_id_modify | 860 | * struct sta_id_modify |
861 | * @addr[ETH_ALEN]: station's MAC address | 861 | * @addr[ETH_ALEN]: station's MAC address |
862 | * @sta_id: index of station in uCode's station table | 862 | * @sta_id: index of station in uCode's station table |
863 | * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change | 863 | * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change |
864 | * | 864 | * |
865 | * Driver selects unused table index when adding new station, | 865 | * Driver selects unused table index when adding new station, |
866 | * or the index to a pre-existing station entry when modifying that station. | 866 | * or the index to a pre-existing station entry when modifying that station. |
867 | * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). | 867 | * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). |
868 | * | 868 | * |
869 | * modify_mask flags select which parameters to modify vs. leave alone. | 869 | * modify_mask flags select which parameters to modify vs. leave alone. |
870 | */ | 870 | */ |
871 | struct sta_id_modify { | 871 | struct sta_id_modify { |
872 | u8 addr[ETH_ALEN]; | 872 | u8 addr[ETH_ALEN]; |
873 | __le16 reserved1; | 873 | __le16 reserved1; |
874 | u8 sta_id; | 874 | u8 sta_id; |
875 | u8 modify_mask; | 875 | u8 modify_mask; |
876 | __le16 reserved2; | 876 | __le16 reserved2; |
877 | } __packed; | 877 | } __packed; |
878 | 878 | ||
879 | /* | 879 | /* |
880 | * REPLY_ADD_STA = 0x18 (command) | 880 | * REPLY_ADD_STA = 0x18 (command) |
881 | * | 881 | * |
882 | * The device contains an internal table of per-station information, | 882 | * The device contains an internal table of per-station information, |
883 | * with info on security keys, aggregation parameters, and Tx rates for | 883 | * with info on security keys, aggregation parameters, and Tx rates for |
884 | * initial Tx attempt and any retries (agn devices uses | 884 | * initial Tx attempt and any retries (agn devices uses |
885 | * REPLY_TX_LINK_QUALITY_CMD, | 885 | * REPLY_TX_LINK_QUALITY_CMD, |
886 | * | 886 | * |
887 | * REPLY_ADD_STA sets up the table entry for one station, either creating | 887 | * REPLY_ADD_STA sets up the table entry for one station, either creating |
888 | * a new entry, or modifying a pre-existing one. | 888 | * a new entry, or modifying a pre-existing one. |
889 | * | 889 | * |
890 | * NOTE: RXON command (without "associated" bit set) wipes the station table | 890 | * NOTE: RXON command (without "associated" bit set) wipes the station table |
891 | * clean. Moving into RF_KILL state does this also. Driver must set up | 891 | * clean. Moving into RF_KILL state does this also. Driver must set up |
892 | * new station table before transmitting anything on the RXON channel | 892 | * new station table before transmitting anything on the RXON channel |
893 | * (except active scans or active measurements; those commands carry | 893 | * (except active scans or active measurements; those commands carry |
894 | * their own txpower/rate setup data). | 894 | * their own txpower/rate setup data). |
895 | * | 895 | * |
896 | * When getting started on a new channel, driver must set up the | 896 | * When getting started on a new channel, driver must set up the |
897 | * IWL_BROADCAST_ID entry (last entry in the table). For a client | 897 | * IWL_BROADCAST_ID entry (last entry in the table). For a client |
898 | * station in a BSS, once an AP is selected, driver sets up the AP STA | 898 | * station in a BSS, once an AP is selected, driver sets up the AP STA |
899 | * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP | 899 | * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP |
900 | * are all that are needed for a BSS client station. If the device is | 900 | * are all that are needed for a BSS client station. If the device is |
901 | * used as AP, or in an IBSS network, driver must set up station table | 901 | * used as AP, or in an IBSS network, driver must set up station table |
902 | * entries for all STAs in network, starting with index IWL_STA_ID. | 902 | * entries for all STAs in network, starting with index IWL_STA_ID. |
903 | */ | 903 | */ |
904 | 904 | ||
905 | struct iwl_addsta_cmd { | 905 | struct iwl_addsta_cmd { |
906 | u8 mode; /* 1: modify existing, 0: add new station */ | 906 | u8 mode; /* 1: modify existing, 0: add new station */ |
907 | u8 reserved[3]; | 907 | u8 reserved[3]; |
908 | struct sta_id_modify sta; | 908 | struct sta_id_modify sta; |
909 | struct iwl_keyinfo key; | 909 | struct iwl_keyinfo key; |
910 | __le32 station_flags; /* STA_FLG_* */ | 910 | __le32 station_flags; /* STA_FLG_* */ |
911 | __le32 station_flags_msk; /* STA_FLG_* */ | 911 | __le32 station_flags_msk; /* STA_FLG_* */ |
912 | 912 | ||
913 | /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) | 913 | /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) |
914 | * corresponding to bit (e.g. bit 5 controls TID 5). | 914 | * corresponding to bit (e.g. bit 5 controls TID 5). |
915 | * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ | 915 | * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ |
916 | __le16 tid_disable_tx; | 916 | __le16 tid_disable_tx; |
917 | __le16 legacy_reserved; | 917 | __le16 legacy_reserved; |
918 | 918 | ||
919 | /* TID for which to add block-ack support. | 919 | /* TID for which to add block-ack support. |
920 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | 920 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ |
921 | u8 add_immediate_ba_tid; | 921 | u8 add_immediate_ba_tid; |
922 | 922 | ||
923 | /* TID for which to remove block-ack support. | 923 | /* TID for which to remove block-ack support. |
924 | * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ | 924 | * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ |
925 | u8 remove_immediate_ba_tid; | 925 | u8 remove_immediate_ba_tid; |
926 | 926 | ||
927 | /* Starting Sequence Number for added block-ack support. | 927 | /* Starting Sequence Number for added block-ack support. |
928 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | 928 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ |
929 | __le16 add_immediate_ba_ssn; | 929 | __le16 add_immediate_ba_ssn; |
930 | 930 | ||
931 | /* | 931 | /* |
932 | * Number of packets OK to transmit to station even though | 932 | * Number of packets OK to transmit to station even though |
933 | * it is asleep -- used to synchronise PS-poll and u-APSD | 933 | * it is asleep -- used to synchronise PS-poll and u-APSD |
934 | * responses while ucode keeps track of STA sleep state. | 934 | * responses while ucode keeps track of STA sleep state. |
935 | */ | 935 | */ |
936 | __le16 sleep_tx_count; | 936 | __le16 sleep_tx_count; |
937 | 937 | ||
938 | __le16 reserved2; | 938 | __le16 reserved2; |
939 | } __packed; | 939 | } __packed; |
940 | 940 | ||
941 | 941 | ||
942 | #define ADD_STA_SUCCESS_MSK 0x1 | 942 | #define ADD_STA_SUCCESS_MSK 0x1 |
943 | #define ADD_STA_NO_ROOM_IN_TABLE 0x2 | 943 | #define ADD_STA_NO_ROOM_IN_TABLE 0x2 |
944 | #define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 | 944 | #define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 |
945 | #define ADD_STA_MODIFY_NON_EXIST_STA 0x8 | 945 | #define ADD_STA_MODIFY_NON_EXIST_STA 0x8 |
946 | /* | 946 | /* |
947 | * REPLY_ADD_STA = 0x18 (response) | 947 | * REPLY_ADD_STA = 0x18 (response) |
948 | */ | 948 | */ |
949 | struct iwl_add_sta_resp { | 949 | struct iwl_add_sta_resp { |
950 | u8 status; /* ADD_STA_* */ | 950 | u8 status; /* ADD_STA_* */ |
951 | } __packed; | 951 | } __packed; |
952 | 952 | ||
953 | #define REM_STA_SUCCESS_MSK 0x1 | 953 | #define REM_STA_SUCCESS_MSK 0x1 |
954 | /* | 954 | /* |
955 | * REPLY_REM_STA = 0x19 (response) | 955 | * REPLY_REM_STA = 0x19 (response) |
956 | */ | 956 | */ |
957 | struct iwl_rem_sta_resp { | 957 | struct iwl_rem_sta_resp { |
958 | u8 status; | 958 | u8 status; |
959 | } __packed; | 959 | } __packed; |
960 | 960 | ||
961 | /* | 961 | /* |
962 | * REPLY_REM_STA = 0x19 (command) | 962 | * REPLY_REM_STA = 0x19 (command) |
963 | */ | 963 | */ |
964 | struct iwl_rem_sta_cmd { | 964 | struct iwl_rem_sta_cmd { |
965 | u8 num_sta; /* number of removed stations */ | 965 | u8 num_sta; /* number of removed stations */ |
966 | u8 reserved[3]; | 966 | u8 reserved[3]; |
967 | u8 addr[ETH_ALEN]; /* MAC addr of the first station */ | 967 | u8 addr[ETH_ALEN]; /* MAC addr of the first station */ |
968 | u8 reserved2[2]; | 968 | u8 reserved2[2]; |
969 | } __packed; | 969 | } __packed; |
970 | 970 | ||
971 | 971 | ||
972 | /* WiFi queues mask */ | 972 | /* WiFi queues mask */ |
973 | #define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) | 973 | #define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) |
974 | #define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) | 974 | #define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) |
975 | #define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) | 975 | #define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) |
976 | #define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) | 976 | #define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) |
977 | #define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) | 977 | #define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) |
978 | 978 | ||
979 | /* PAN queues mask */ | 979 | /* PAN queues mask */ |
980 | #define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) | 980 | #define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) |
981 | #define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) | 981 | #define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) |
982 | #define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) | 982 | #define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) |
983 | #define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) | 983 | #define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) |
984 | #define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) | 984 | #define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) |
985 | #define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) | 985 | #define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) |
986 | 986 | ||
987 | #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) | 987 | #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) |
988 | 988 | ||
989 | #define IWL_DROP_SINGLE 0 | 989 | #define IWL_DROP_SINGLE 0 |
990 | #define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) | 990 | #define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) |
991 | 991 | ||
992 | /* | 992 | /* |
993 | * REPLY_TXFIFO_FLUSH = 0x1e(command and response) | 993 | * REPLY_TXFIFO_FLUSH = 0x1e(command and response) |
994 | * | 994 | * |
995 | * When using full FIFO flush this command checks the scheduler HW block WR/RD | 995 | * When using full FIFO flush this command checks the scheduler HW block WR/RD |
996 | * pointers to check if all the frames were transferred by DMA into the | 996 | * pointers to check if all the frames were transferred by DMA into the |
997 | * relevant TX FIFO queue. Only when the DMA is finished and the queue is | 997 | * relevant TX FIFO queue. Only when the DMA is finished and the queue is |
998 | * empty the command can finish. | 998 | * empty the command can finish. |
999 | * This command is used to flush the TXFIFO from transmit commands, it may | 999 | * This command is used to flush the TXFIFO from transmit commands, it may |
1000 | * operate on single or multiple queues, the command queue can't be flushed by | 1000 | * operate on single or multiple queues, the command queue can't be flushed by |
1001 | * this command. The command response is returned when all the queue flush | 1001 | * this command. The command response is returned when all the queue flush |
1002 | * operations are done. Each TX command flushed return response with the FLUSH | 1002 | * operations are done. Each TX command flushed return response with the FLUSH |
1003 | * status set in the TX response status. When FIFO flush operation is used, | 1003 | * status set in the TX response status. When FIFO flush operation is used, |
1004 | * the flush operation ends when both the scheduler DMA done and TXFIFO empty | 1004 | * the flush operation ends when both the scheduler DMA done and TXFIFO empty |
1005 | * are set. | 1005 | * are set. |
1006 | * | 1006 | * |
1007 | * @fifo_control: bit mask for which queues to flush | 1007 | * @fifo_control: bit mask for which queues to flush |
1008 | * @flush_control: flush controls | 1008 | * @flush_control: flush controls |
1009 | * 0: Dump single MSDU | 1009 | * 0: Dump single MSDU |
1010 | * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. | 1010 | * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. |
1011 | * 2: Dump all FIFO | 1011 | * 2: Dump all FIFO |
1012 | */ | 1012 | */ |
1013 | struct iwl_txfifo_flush_cmd { | 1013 | struct iwl_txfifo_flush_cmd { |
1014 | __le32 fifo_control; | 1014 | __le32 fifo_control; |
1015 | __le16 flush_control; | 1015 | __le16 flush_control; |
1016 | __le16 reserved; | 1016 | __le16 reserved; |
1017 | } __packed; | 1017 | } __packed; |
1018 | 1018 | ||
1019 | /* | 1019 | /* |
1020 | * REPLY_WEP_KEY = 0x20 | 1020 | * REPLY_WEP_KEY = 0x20 |
1021 | */ | 1021 | */ |
1022 | struct iwl_wep_key { | 1022 | struct iwl_wep_key { |
1023 | u8 key_index; | 1023 | u8 key_index; |
1024 | u8 key_offset; | 1024 | u8 key_offset; |
1025 | u8 reserved1[2]; | 1025 | u8 reserved1[2]; |
1026 | u8 key_size; | 1026 | u8 key_size; |
1027 | u8 reserved2[3]; | 1027 | u8 reserved2[3]; |
1028 | u8 key[16]; | 1028 | u8 key[16]; |
1029 | } __packed; | 1029 | } __packed; |
1030 | 1030 | ||
1031 | struct iwl_wep_cmd { | 1031 | struct iwl_wep_cmd { |
1032 | u8 num_keys; | 1032 | u8 num_keys; |
1033 | u8 global_key_type; | 1033 | u8 global_key_type; |
1034 | u8 flags; | 1034 | u8 flags; |
1035 | u8 reserved; | 1035 | u8 reserved; |
1036 | struct iwl_wep_key key[0]; | 1036 | struct iwl_wep_key key[0]; |
1037 | } __packed; | 1037 | } __packed; |
1038 | 1038 | ||
1039 | #define WEP_KEY_WEP_TYPE 1 | 1039 | #define WEP_KEY_WEP_TYPE 1 |
1040 | #define WEP_KEYS_MAX 4 | 1040 | #define WEP_KEYS_MAX 4 |
1041 | #define WEP_INVALID_OFFSET 0xff | 1041 | #define WEP_INVALID_OFFSET 0xff |
1042 | #define WEP_KEY_LEN_64 5 | 1042 | #define WEP_KEY_LEN_64 5 |
1043 | #define WEP_KEY_LEN_128 13 | 1043 | #define WEP_KEY_LEN_128 13 |
1044 | 1044 | ||
1045 | /****************************************************************************** | 1045 | /****************************************************************************** |
1046 | * (4) | 1046 | * (4) |
1047 | * Rx Responses: | 1047 | * Rx Responses: |
1048 | * | 1048 | * |
1049 | *****************************************************************************/ | 1049 | *****************************************************************************/ |
1050 | 1050 | ||
1051 | #define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0) | 1051 | #define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0) |
1052 | #define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1) | 1052 | #define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1) |
1053 | 1053 | ||
1054 | #define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0) | 1054 | #define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0) |
1055 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) | 1055 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) |
1056 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) | 1056 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) |
1057 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) | 1057 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) |
1058 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0 | 1058 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK 0x70 |
1059 | #define RX_RES_PHY_FLAGS_ANTENNA_POS 4 | 1059 | #define RX_RES_PHY_FLAGS_ANTENNA_POS 4 |
1060 | #define RX_RES_PHY_FLAGS_AGG_MSK cpu_to_le16(1 << 7) | ||
1060 | 1061 | ||
1061 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) | 1062 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) |
1062 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) | 1063 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) |
1063 | #define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) | 1064 | #define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) |
1064 | #define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) | 1065 | #define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) |
1065 | #define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) | 1066 | #define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) |
1066 | #define RX_RES_STATUS_SEC_TYPE_ERR (0x7 << 8) | 1067 | #define RX_RES_STATUS_SEC_TYPE_ERR (0x7 << 8) |
1067 | 1068 | ||
1068 | #define RX_RES_STATUS_STATION_FOUND (1<<6) | 1069 | #define RX_RES_STATUS_STATION_FOUND (1<<6) |
1069 | #define RX_RES_STATUS_NO_STATION_INFO_MISMATCH (1<<7) | 1070 | #define RX_RES_STATUS_NO_STATION_INFO_MISMATCH (1<<7) |
1070 | 1071 | ||
1071 | #define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) | 1072 | #define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) |
1072 | #define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) | 1073 | #define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) |
1073 | #define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) | 1074 | #define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) |
1074 | #define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) | 1075 | #define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) |
1075 | #define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) | 1076 | #define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) |
1076 | 1077 | ||
1077 | #define RX_MPDU_RES_STATUS_ICV_OK (0x20) | 1078 | #define RX_MPDU_RES_STATUS_ICV_OK (0x20) |
1078 | #define RX_MPDU_RES_STATUS_MIC_OK (0x40) | 1079 | #define RX_MPDU_RES_STATUS_MIC_OK (0x40) |
1079 | #define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7) | 1080 | #define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7) |
1080 | #define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) | 1081 | #define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) |
1081 | 1082 | ||
1082 | 1083 | ||
1083 | #define IWLAGN_RX_RES_PHY_CNT 8 | 1084 | #define IWLAGN_RX_RES_PHY_CNT 8 |
1084 | #define IWLAGN_RX_RES_AGC_IDX 1 | 1085 | #define IWLAGN_RX_RES_AGC_IDX 1 |
1085 | #define IWLAGN_RX_RES_RSSI_AB_IDX 2 | 1086 | #define IWLAGN_RX_RES_RSSI_AB_IDX 2 |
1086 | #define IWLAGN_RX_RES_RSSI_C_IDX 3 | 1087 | #define IWLAGN_RX_RES_RSSI_C_IDX 3 |
1087 | #define IWLAGN_OFDM_AGC_MSK 0xfe00 | 1088 | #define IWLAGN_OFDM_AGC_MSK 0xfe00 |
1088 | #define IWLAGN_OFDM_AGC_BIT_POS 9 | 1089 | #define IWLAGN_OFDM_AGC_BIT_POS 9 |
1089 | #define IWLAGN_OFDM_RSSI_INBAND_A_BITMSK 0x00ff | 1090 | #define IWLAGN_OFDM_RSSI_INBAND_A_BITMSK 0x00ff |
1090 | #define IWLAGN_OFDM_RSSI_ALLBAND_A_BITMSK 0xff00 | 1091 | #define IWLAGN_OFDM_RSSI_ALLBAND_A_BITMSK 0xff00 |
1091 | #define IWLAGN_OFDM_RSSI_A_BIT_POS 0 | 1092 | #define IWLAGN_OFDM_RSSI_A_BIT_POS 0 |
1092 | #define IWLAGN_OFDM_RSSI_INBAND_B_BITMSK 0xff0000 | 1093 | #define IWLAGN_OFDM_RSSI_INBAND_B_BITMSK 0xff0000 |
1093 | #define IWLAGN_OFDM_RSSI_ALLBAND_B_BITMSK 0xff000000 | 1094 | #define IWLAGN_OFDM_RSSI_ALLBAND_B_BITMSK 0xff000000 |
1094 | #define IWLAGN_OFDM_RSSI_B_BIT_POS 16 | 1095 | #define IWLAGN_OFDM_RSSI_B_BIT_POS 16 |
1095 | #define IWLAGN_OFDM_RSSI_INBAND_C_BITMSK 0x00ff | 1096 | #define IWLAGN_OFDM_RSSI_INBAND_C_BITMSK 0x00ff |
1096 | #define IWLAGN_OFDM_RSSI_ALLBAND_C_BITMSK 0xff00 | 1097 | #define IWLAGN_OFDM_RSSI_ALLBAND_C_BITMSK 0xff00 |
1097 | #define IWLAGN_OFDM_RSSI_C_BIT_POS 0 | 1098 | #define IWLAGN_OFDM_RSSI_C_BIT_POS 0 |
1098 | 1099 | ||
1099 | struct iwlagn_non_cfg_phy { | 1100 | struct iwlagn_non_cfg_phy { |
1100 | __le32 non_cfg_phy[IWLAGN_RX_RES_PHY_CNT]; /* up to 8 phy entries */ | 1101 | __le32 non_cfg_phy[IWLAGN_RX_RES_PHY_CNT]; /* up to 8 phy entries */ |
1101 | } __packed; | 1102 | } __packed; |
1102 | 1103 | ||
1103 | 1104 | ||
1104 | /* | 1105 | /* |
1105 | * REPLY_RX = 0xc3 (response only, not a command) | 1106 | * REPLY_RX = 0xc3 (response only, not a command) |
1106 | * Used only for legacy (non 11n) frames. | 1107 | * Used only for legacy (non 11n) frames. |
1107 | */ | 1108 | */ |
1108 | struct iwl_rx_phy_res { | 1109 | struct iwl_rx_phy_res { |
1109 | u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ | 1110 | u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ |
1110 | u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ | 1111 | u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ |
1111 | u8 stat_id; /* configurable DSP phy data set ID */ | 1112 | u8 stat_id; /* configurable DSP phy data set ID */ |
1112 | u8 reserved1; | 1113 | u8 reserved1; |
1113 | __le64 timestamp; /* TSF at on air rise */ | 1114 | __le64 timestamp; /* TSF at on air rise */ |
1114 | __le32 beacon_time_stamp; /* beacon at on-air rise */ | 1115 | __le32 beacon_time_stamp; /* beacon at on-air rise */ |
1115 | __le16 phy_flags; /* general phy flags: band, modulation, ... */ | 1116 | __le16 phy_flags; /* general phy flags: band, modulation, ... */ |
1116 | __le16 channel; /* channel number */ | 1117 | __le16 channel; /* channel number */ |
1117 | u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */ | 1118 | u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */ |
1118 | __le32 rate_n_flags; /* RATE_MCS_* */ | 1119 | __le32 rate_n_flags; /* RATE_MCS_* */ |
1119 | __le16 byte_count; /* frame's byte-count */ | 1120 | __le16 byte_count; /* frame's byte-count */ |
1120 | __le16 frame_time; /* frame's time on the air */ | 1121 | __le16 frame_time; /* frame's time on the air */ |
1121 | } __packed; | 1122 | } __packed; |
1122 | 1123 | ||
1123 | struct iwl_rx_mpdu_res_start { | 1124 | struct iwl_rx_mpdu_res_start { |
1124 | __le16 byte_count; | 1125 | __le16 byte_count; |
1125 | __le16 reserved; | 1126 | __le16 reserved; |
1126 | } __packed; | 1127 | } __packed; |
1127 | 1128 | ||
1128 | 1129 | ||
1129 | /****************************************************************************** | 1130 | /****************************************************************************** |
1130 | * (5) | 1131 | * (5) |
1131 | * Tx Commands & Responses: | 1132 | * Tx Commands & Responses: |
1132 | * | 1133 | * |
1133 | * Driver must place each REPLY_TX command into one of the prioritized Tx | 1134 | * Driver must place each REPLY_TX command into one of the prioritized Tx |
1134 | * queues in host DRAM, shared between driver and device (see comments for | 1135 | * queues in host DRAM, shared between driver and device (see comments for |
1135 | * SCD registers and Tx/Rx Queues). When the device's Tx scheduler and uCode | 1136 | * SCD registers and Tx/Rx Queues). When the device's Tx scheduler and uCode |
1136 | * are preparing to transmit, the device pulls the Tx command over the PCI | 1137 | * are preparing to transmit, the device pulls the Tx command over the PCI |
1137 | * bus via one of the device's Tx DMA channels, to fill an internal FIFO | 1138 | * bus via one of the device's Tx DMA channels, to fill an internal FIFO |
1138 | * from which data will be transmitted. | 1139 | * from which data will be transmitted. |
1139 | * | 1140 | * |
1140 | * uCode handles all timing and protocol related to control frames | 1141 | * uCode handles all timing and protocol related to control frames |
1141 | * (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler | 1142 | * (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler |
1142 | * handle reception of block-acks; uCode updates the host driver via | 1143 | * handle reception of block-acks; uCode updates the host driver via |
1143 | * REPLY_COMPRESSED_BA. | 1144 | * REPLY_COMPRESSED_BA. |
1144 | * | 1145 | * |
1145 | * uCode handles retrying Tx when an ACK is expected but not received. | 1146 | * uCode handles retrying Tx when an ACK is expected but not received. |
1146 | * This includes trying lower data rates than the one requested in the Tx | 1147 | * This includes trying lower data rates than the one requested in the Tx |
1147 | * command, as set up by the REPLY_TX_LINK_QUALITY_CMD (agn). | 1148 | * command, as set up by the REPLY_TX_LINK_QUALITY_CMD (agn). |
1148 | * | 1149 | * |
1149 | * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. | 1150 | * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. |
1150 | * This command must be executed after every RXON command, before Tx can occur. | 1151 | * This command must be executed after every RXON command, before Tx can occur. |
1151 | *****************************************************************************/ | 1152 | *****************************************************************************/ |
1152 | 1153 | ||
1153 | /* REPLY_TX Tx flags field */ | 1154 | /* REPLY_TX Tx flags field */ |
1154 | 1155 | ||
1155 | /* | 1156 | /* |
1156 | * 1: Use RTS/CTS protocol or CTS-to-self if spec allows it | 1157 | * 1: Use RTS/CTS protocol or CTS-to-self if spec allows it |
1157 | * before this frame. if CTS-to-self required check | 1158 | * before this frame. if CTS-to-self required check |
1158 | * RXON_FLG_SELF_CTS_EN status. | 1159 | * RXON_FLG_SELF_CTS_EN status. |
1159 | */ | 1160 | */ |
1160 | #define TX_CMD_FLG_PROT_REQUIRE_MSK cpu_to_le32(1 << 0) | 1161 | #define TX_CMD_FLG_PROT_REQUIRE_MSK cpu_to_le32(1 << 0) |
1161 | 1162 | ||
1162 | /* 1: Expect ACK from receiving station | 1163 | /* 1: Expect ACK from receiving station |
1163 | * 0: Don't expect ACK (MAC header's duration field s/b 0) | 1164 | * 0: Don't expect ACK (MAC header's duration field s/b 0) |
1164 | * Set this for unicast frames, but not broadcast/multicast. */ | 1165 | * Set this for unicast frames, but not broadcast/multicast. */ |
1165 | #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) | 1166 | #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) |
1166 | 1167 | ||
1167 | /* For agn devices: | 1168 | /* For agn devices: |
1168 | * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). | 1169 | * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). |
1169 | * Tx command's initial_rate_index indicates first rate to try; | 1170 | * Tx command's initial_rate_index indicates first rate to try; |
1170 | * uCode walks through table for additional Tx attempts. | 1171 | * uCode walks through table for additional Tx attempts. |
1171 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. | 1172 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. |
1172 | * This rate will be used for all Tx attempts; it will not be scaled. */ | 1173 | * This rate will be used for all Tx attempts; it will not be scaled. */ |
1173 | #define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4) | 1174 | #define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4) |
1174 | 1175 | ||
1175 | /* 1: Expect immediate block-ack. | 1176 | /* 1: Expect immediate block-ack. |
1176 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ | 1177 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ |
1177 | #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) | 1178 | #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) |
1178 | 1179 | ||
1179 | /* Tx antenna selection field; reserved (0) for agn devices. */ | 1180 | /* Tx antenna selection field; reserved (0) for agn devices. */ |
1180 | #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) | 1181 | #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) |
1181 | 1182 | ||
1182 | /* 1: Ignore Bluetooth priority for this frame. | 1183 | /* 1: Ignore Bluetooth priority for this frame. |
1183 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ | 1184 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ |
1184 | #define TX_CMD_FLG_IGNORE_BT cpu_to_le32(1 << 12) | 1185 | #define TX_CMD_FLG_IGNORE_BT cpu_to_le32(1 << 12) |
1185 | 1186 | ||
1186 | /* 1: uCode overrides sequence control field in MAC header. | 1187 | /* 1: uCode overrides sequence control field in MAC header. |
1187 | * 0: Driver provides sequence control field in MAC header. | 1188 | * 0: Driver provides sequence control field in MAC header. |
1188 | * Set this for management frames, non-QOS data frames, non-unicast frames, | 1189 | * Set this for management frames, non-QOS data frames, non-unicast frames, |
1189 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ | 1190 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ |
1190 | #define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13) | 1191 | #define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13) |
1191 | 1192 | ||
1192 | /* 1: This frame is non-last MPDU; more fragments are coming. | 1193 | /* 1: This frame is non-last MPDU; more fragments are coming. |
1193 | * 0: Last fragment, or not using fragmentation. */ | 1194 | * 0: Last fragment, or not using fragmentation. */ |
1194 | #define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14) | 1195 | #define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14) |
1195 | 1196 | ||
1196 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. | 1197 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. |
1197 | * 0: No TSF required in outgoing frame. | 1198 | * 0: No TSF required in outgoing frame. |
1198 | * Set this for transmitting beacons and probe responses. */ | 1199 | * Set this for transmitting beacons and probe responses. */ |
1199 | #define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16) | 1200 | #define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16) |
1200 | 1201 | ||
1201 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword | 1202 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword |
1202 | * alignment of frame's payload data field. | 1203 | * alignment of frame's payload data field. |
1203 | * 0: No pad | 1204 | * 0: No pad |
1204 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 | 1205 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 |
1205 | * field (but not both). Driver must align frame data (i.e. data following | 1206 | * field (but not both). Driver must align frame data (i.e. data following |
1206 | * MAC header) to DWORD boundary. */ | 1207 | * MAC header) to DWORD boundary. */ |
1207 | #define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20) | 1208 | #define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20) |
1208 | 1209 | ||
1209 | /* accelerate aggregation support | 1210 | /* accelerate aggregation support |
1210 | * 0 - no CCMP encryption; 1 - CCMP encryption */ | 1211 | * 0 - no CCMP encryption; 1 - CCMP encryption */ |
1211 | #define TX_CMD_FLG_AGG_CCMP_MSK cpu_to_le32(1 << 22) | 1212 | #define TX_CMD_FLG_AGG_CCMP_MSK cpu_to_le32(1 << 22) |
1212 | 1213 | ||
1213 | /* HCCA-AP - disable duration overwriting. */ | 1214 | /* HCCA-AP - disable duration overwriting. */ |
1214 | #define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25) | 1215 | #define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25) |
1215 | 1216 | ||
1216 | 1217 | ||
1217 | /* | 1218 | /* |
1218 | * TX command security control | 1219 | * TX command security control |
1219 | */ | 1220 | */ |
1220 | #define TX_CMD_SEC_WEP 0x01 | 1221 | #define TX_CMD_SEC_WEP 0x01 |
1221 | #define TX_CMD_SEC_CCM 0x02 | 1222 | #define TX_CMD_SEC_CCM 0x02 |
1222 | #define TX_CMD_SEC_TKIP 0x03 | 1223 | #define TX_CMD_SEC_TKIP 0x03 |
1223 | #define TX_CMD_SEC_MSK 0x03 | 1224 | #define TX_CMD_SEC_MSK 0x03 |
1224 | #define TX_CMD_SEC_SHIFT 6 | 1225 | #define TX_CMD_SEC_SHIFT 6 |
1225 | #define TX_CMD_SEC_KEY128 0x08 | 1226 | #define TX_CMD_SEC_KEY128 0x08 |
1226 | 1227 | ||
1227 | /* | 1228 | /* |
1228 | * security overhead sizes | 1229 | * security overhead sizes |
1229 | */ | 1230 | */ |
1230 | #define WEP_IV_LEN 4 | 1231 | #define WEP_IV_LEN 4 |
1231 | #define WEP_ICV_LEN 4 | 1232 | #define WEP_ICV_LEN 4 |
1232 | #define CCMP_MIC_LEN 8 | 1233 | #define CCMP_MIC_LEN 8 |
1233 | #define TKIP_ICV_LEN 4 | 1234 | #define TKIP_ICV_LEN 4 |
1234 | 1235 | ||
1235 | /* | 1236 | /* |
1236 | * REPLY_TX = 0x1c (command) | 1237 | * REPLY_TX = 0x1c (command) |
1237 | */ | 1238 | */ |
1238 | 1239 | ||
1239 | /* | 1240 | /* |
1240 | * 4965 uCode updates these Tx attempt count values in host DRAM. | 1241 | * 4965 uCode updates these Tx attempt count values in host DRAM. |
1241 | * Used for managing Tx retries when expecting block-acks. | 1242 | * Used for managing Tx retries when expecting block-acks. |
1242 | * Driver should set these fields to 0. | 1243 | * Driver should set these fields to 0. |
1243 | */ | 1244 | */ |
1244 | struct iwl_dram_scratch { | 1245 | struct iwl_dram_scratch { |
1245 | u8 try_cnt; /* Tx attempts */ | 1246 | u8 try_cnt; /* Tx attempts */ |
1246 | u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */ | 1247 | u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */ |
1247 | __le16 reserved; | 1248 | __le16 reserved; |
1248 | } __packed; | 1249 | } __packed; |
1249 | 1250 | ||
1250 | struct iwl_tx_cmd { | 1251 | struct iwl_tx_cmd { |
1251 | /* | 1252 | /* |
1252 | * MPDU byte count: | 1253 | * MPDU byte count: |
1253 | * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, | 1254 | * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, |
1254 | * + 8 byte IV for CCM or TKIP (not used for WEP) | 1255 | * + 8 byte IV for CCM or TKIP (not used for WEP) |
1255 | * + Data payload | 1256 | * + Data payload |
1256 | * + 8-byte MIC (not used for CCM/WEP) | 1257 | * + 8-byte MIC (not used for CCM/WEP) |
1257 | * NOTE: Does not include Tx command bytes, post-MAC pad bytes, | 1258 | * NOTE: Does not include Tx command bytes, post-MAC pad bytes, |
1258 | * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i | 1259 | * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i |
1259 | * Range: 14-2342 bytes. | 1260 | * Range: 14-2342 bytes. |
1260 | */ | 1261 | */ |
1261 | __le16 len; | 1262 | __le16 len; |
1262 | 1263 | ||
1263 | /* | 1264 | /* |
1264 | * MPDU or MSDU byte count for next frame. | 1265 | * MPDU or MSDU byte count for next frame. |
1265 | * Used for fragmentation and bursting, but not 11n aggregation. | 1266 | * Used for fragmentation and bursting, but not 11n aggregation. |
1266 | * Same as "len", but for next frame. Set to 0 if not applicable. | 1267 | * Same as "len", but for next frame. Set to 0 if not applicable. |
1267 | */ | 1268 | */ |
1268 | __le16 next_frame_len; | 1269 | __le16 next_frame_len; |
1269 | 1270 | ||
1270 | __le32 tx_flags; /* TX_CMD_FLG_* */ | 1271 | __le32 tx_flags; /* TX_CMD_FLG_* */ |
1271 | 1272 | ||
1272 | /* uCode may modify this field of the Tx command (in host DRAM!). | 1273 | /* uCode may modify this field of the Tx command (in host DRAM!). |
1273 | * Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */ | 1274 | * Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */ |
1274 | struct iwl_dram_scratch scratch; | 1275 | struct iwl_dram_scratch scratch; |
1275 | 1276 | ||
1276 | /* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */ | 1277 | /* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */ |
1277 | __le32 rate_n_flags; /* RATE_MCS_* */ | 1278 | __le32 rate_n_flags; /* RATE_MCS_* */ |
1278 | 1279 | ||
1279 | /* Index of destination station in uCode's station table */ | 1280 | /* Index of destination station in uCode's station table */ |
1280 | u8 sta_id; | 1281 | u8 sta_id; |
1281 | 1282 | ||
1282 | /* Type of security encryption: CCM or TKIP */ | 1283 | /* Type of security encryption: CCM or TKIP */ |
1283 | u8 sec_ctl; /* TX_CMD_SEC_* */ | 1284 | u8 sec_ctl; /* TX_CMD_SEC_* */ |
1284 | 1285 | ||
1285 | /* | 1286 | /* |
1286 | * Index into rate table (see REPLY_TX_LINK_QUALITY_CMD) for initial | 1287 | * Index into rate table (see REPLY_TX_LINK_QUALITY_CMD) for initial |
1287 | * Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set. Normally "0" for | 1288 | * Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set. Normally "0" for |
1288 | * data frames, this field may be used to selectively reduce initial | 1289 | * data frames, this field may be used to selectively reduce initial |
1289 | * rate (via non-0 value) for special frames (e.g. management), while | 1290 | * rate (via non-0 value) for special frames (e.g. management), while |
1290 | * still supporting rate scaling for all frames. | 1291 | * still supporting rate scaling for all frames. |
1291 | */ | 1292 | */ |
1292 | u8 initial_rate_index; | 1293 | u8 initial_rate_index; |
1293 | u8 reserved; | 1294 | u8 reserved; |
1294 | u8 key[16]; | 1295 | u8 key[16]; |
1295 | __le16 next_frame_flags; | 1296 | __le16 next_frame_flags; |
1296 | __le16 reserved2; | 1297 | __le16 reserved2; |
1297 | union { | 1298 | union { |
1298 | __le32 life_time; | 1299 | __le32 life_time; |
1299 | __le32 attempt; | 1300 | __le32 attempt; |
1300 | } stop_time; | 1301 | } stop_time; |
1301 | 1302 | ||
1302 | /* Host DRAM physical address pointer to "scratch" in this command. | 1303 | /* Host DRAM physical address pointer to "scratch" in this command. |
1303 | * Must be dword aligned. "0" in dram_lsb_ptr disables usage. */ | 1304 | * Must be dword aligned. "0" in dram_lsb_ptr disables usage. */ |
1304 | __le32 dram_lsb_ptr; | 1305 | __le32 dram_lsb_ptr; |
1305 | u8 dram_msb_ptr; | 1306 | u8 dram_msb_ptr; |
1306 | 1307 | ||
1307 | u8 rts_retry_limit; /*byte 50 */ | 1308 | u8 rts_retry_limit; /*byte 50 */ |
1308 | u8 data_retry_limit; /*byte 51 */ | 1309 | u8 data_retry_limit; /*byte 51 */ |
1309 | u8 tid_tspec; | 1310 | u8 tid_tspec; |
1310 | union { | 1311 | union { |
1311 | __le16 pm_frame_timeout; | 1312 | __le16 pm_frame_timeout; |
1312 | __le16 attempt_duration; | 1313 | __le16 attempt_duration; |
1313 | } timeout; | 1314 | } timeout; |
1314 | 1315 | ||
1315 | /* | 1316 | /* |
1316 | * Duration of EDCA burst Tx Opportunity, in 32-usec units. | 1317 | * Duration of EDCA burst Tx Opportunity, in 32-usec units. |
1317 | * Set this if txop time is not specified by HCCA protocol (e.g. by AP). | 1318 | * Set this if txop time is not specified by HCCA protocol (e.g. by AP). |
1318 | */ | 1319 | */ |
1319 | __le16 driver_txop; | 1320 | __le16 driver_txop; |
1320 | 1321 | ||
1321 | /* | 1322 | /* |
1322 | * MAC header goes here, followed by 2 bytes padding if MAC header | 1323 | * MAC header goes here, followed by 2 bytes padding if MAC header |
1323 | * length is 26 or 30 bytes, followed by payload data | 1324 | * length is 26 or 30 bytes, followed by payload data |
1324 | */ | 1325 | */ |
1325 | u8 payload[0]; | 1326 | u8 payload[0]; |
1326 | struct ieee80211_hdr hdr[0]; | 1327 | struct ieee80211_hdr hdr[0]; |
1327 | } __packed; | 1328 | } __packed; |
1328 | 1329 | ||
1329 | /* | 1330 | /* |
1330 | * TX command response is sent after *agn* transmission attempts. | 1331 | * TX command response is sent after *agn* transmission attempts. |
1331 | * | 1332 | * |
1332 | * both postpone and abort status are expected behavior from uCode. there is | 1333 | * both postpone and abort status are expected behavior from uCode. there is |
1333 | * no special operation required from driver; except for RFKILL_FLUSH, | 1334 | * no special operation required from driver; except for RFKILL_FLUSH, |
1334 | * which required tx flush host command to flush all the tx frames in queues | 1335 | * which required tx flush host command to flush all the tx frames in queues |
1335 | */ | 1336 | */ |
1336 | enum { | 1337 | enum { |
1337 | TX_STATUS_SUCCESS = 0x01, | 1338 | TX_STATUS_SUCCESS = 0x01, |
1338 | TX_STATUS_DIRECT_DONE = 0x02, | 1339 | TX_STATUS_DIRECT_DONE = 0x02, |
1339 | /* postpone TX */ | 1340 | /* postpone TX */ |
1340 | TX_STATUS_POSTPONE_DELAY = 0x40, | 1341 | TX_STATUS_POSTPONE_DELAY = 0x40, |
1341 | TX_STATUS_POSTPONE_FEW_BYTES = 0x41, | 1342 | TX_STATUS_POSTPONE_FEW_BYTES = 0x41, |
1342 | TX_STATUS_POSTPONE_BT_PRIO = 0x42, | 1343 | TX_STATUS_POSTPONE_BT_PRIO = 0x42, |
1343 | TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43, | 1344 | TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43, |
1344 | TX_STATUS_POSTPONE_CALC_TTAK = 0x44, | 1345 | TX_STATUS_POSTPONE_CALC_TTAK = 0x44, |
1345 | /* abort TX */ | 1346 | /* abort TX */ |
1346 | TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81, | 1347 | TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81, |
1347 | TX_STATUS_FAIL_SHORT_LIMIT = 0x82, | 1348 | TX_STATUS_FAIL_SHORT_LIMIT = 0x82, |
1348 | TX_STATUS_FAIL_LONG_LIMIT = 0x83, | 1349 | TX_STATUS_FAIL_LONG_LIMIT = 0x83, |
1349 | TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, | 1350 | TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, |
1350 | TX_STATUS_FAIL_DRAIN_FLOW = 0x85, | 1351 | TX_STATUS_FAIL_DRAIN_FLOW = 0x85, |
1351 | TX_STATUS_FAIL_RFKILL_FLUSH = 0x86, | 1352 | TX_STATUS_FAIL_RFKILL_FLUSH = 0x86, |
1352 | TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, | 1353 | TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, |
1353 | TX_STATUS_FAIL_DEST_PS = 0x88, | 1354 | TX_STATUS_FAIL_DEST_PS = 0x88, |
1354 | TX_STATUS_FAIL_HOST_ABORTED = 0x89, | 1355 | TX_STATUS_FAIL_HOST_ABORTED = 0x89, |
1355 | TX_STATUS_FAIL_BT_RETRY = 0x8a, | 1356 | TX_STATUS_FAIL_BT_RETRY = 0x8a, |
1356 | TX_STATUS_FAIL_STA_INVALID = 0x8b, | 1357 | TX_STATUS_FAIL_STA_INVALID = 0x8b, |
1357 | TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, | 1358 | TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, |
1358 | TX_STATUS_FAIL_TID_DISABLE = 0x8d, | 1359 | TX_STATUS_FAIL_TID_DISABLE = 0x8d, |
1359 | TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e, | 1360 | TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e, |
1360 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, | 1361 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, |
1361 | TX_STATUS_FAIL_PASSIVE_NO_RX = 0x90, | 1362 | TX_STATUS_FAIL_PASSIVE_NO_RX = 0x90, |
1362 | TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, | 1363 | TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, |
1363 | }; | 1364 | }; |
1364 | 1365 | ||
1365 | #define TX_PACKET_MODE_REGULAR 0x0000 | 1366 | #define TX_PACKET_MODE_REGULAR 0x0000 |
1366 | #define TX_PACKET_MODE_BURST_SEQ 0x0100 | 1367 | #define TX_PACKET_MODE_BURST_SEQ 0x0100 |
1367 | #define TX_PACKET_MODE_BURST_FIRST 0x0200 | 1368 | #define TX_PACKET_MODE_BURST_FIRST 0x0200 |
1368 | 1369 | ||
1369 | enum { | 1370 | enum { |
1370 | TX_POWER_PA_NOT_ACTIVE = 0x0, | 1371 | TX_POWER_PA_NOT_ACTIVE = 0x0, |
1371 | }; | 1372 | }; |
1372 | 1373 | ||
1373 | enum { | 1374 | enum { |
1374 | TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ | 1375 | TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ |
1375 | TX_STATUS_DELAY_MSK = 0x00000040, | 1376 | TX_STATUS_DELAY_MSK = 0x00000040, |
1376 | TX_STATUS_ABORT_MSK = 0x00000080, | 1377 | TX_STATUS_ABORT_MSK = 0x00000080, |
1377 | TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ | 1378 | TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ |
1378 | TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ | 1379 | TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ |
1379 | TX_RESERVED = 0x00780000, /* bits 19:22 */ | 1380 | TX_RESERVED = 0x00780000, /* bits 19:22 */ |
1380 | TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ | 1381 | TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ |
1381 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ | 1382 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ |
1382 | }; | 1383 | }; |
1383 | 1384 | ||
1384 | /* ******************************* | 1385 | /* ******************************* |
1385 | * TX aggregation status | 1386 | * TX aggregation status |
1386 | ******************************* */ | 1387 | ******************************* */ |
1387 | 1388 | ||
1388 | enum { | 1389 | enum { |
1389 | AGG_TX_STATE_TRANSMITTED = 0x00, | 1390 | AGG_TX_STATE_TRANSMITTED = 0x00, |
1390 | AGG_TX_STATE_UNDERRUN_MSK = 0x01, | 1391 | AGG_TX_STATE_UNDERRUN_MSK = 0x01, |
1391 | AGG_TX_STATE_BT_PRIO_MSK = 0x02, | 1392 | AGG_TX_STATE_BT_PRIO_MSK = 0x02, |
1392 | AGG_TX_STATE_FEW_BYTES_MSK = 0x04, | 1393 | AGG_TX_STATE_FEW_BYTES_MSK = 0x04, |
1393 | AGG_TX_STATE_ABORT_MSK = 0x08, | 1394 | AGG_TX_STATE_ABORT_MSK = 0x08, |
1394 | AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10, | 1395 | AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10, |
1395 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20, | 1396 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20, |
1396 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK = 0x40, | 1397 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK = 0x40, |
1397 | AGG_TX_STATE_SCD_QUERY_MSK = 0x80, | 1398 | AGG_TX_STATE_SCD_QUERY_MSK = 0x80, |
1398 | AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100, | 1399 | AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100, |
1399 | AGG_TX_STATE_RESPONSE_MSK = 0x1ff, | 1400 | AGG_TX_STATE_RESPONSE_MSK = 0x1ff, |
1400 | AGG_TX_STATE_DUMP_TX_MSK = 0x200, | 1401 | AGG_TX_STATE_DUMP_TX_MSK = 0x200, |
1401 | AGG_TX_STATE_DELAY_TX_MSK = 0x400 | 1402 | AGG_TX_STATE_DELAY_TX_MSK = 0x400 |
1402 | }; | 1403 | }; |
1403 | 1404 | ||
1404 | #define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */ | 1405 | #define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */ |
1405 | #define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */ | 1406 | #define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */ |
1406 | 1407 | ||
1407 | #define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ | 1408 | #define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ |
1408 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ | 1409 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ |
1409 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) | 1410 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) |
1410 | 1411 | ||
1411 | /* # tx attempts for first frame in aggregation */ | 1412 | /* # tx attempts for first frame in aggregation */ |
1412 | #define AGG_TX_STATE_TRY_CNT_POS 12 | 1413 | #define AGG_TX_STATE_TRY_CNT_POS 12 |
1413 | #define AGG_TX_STATE_TRY_CNT_MSK 0xf000 | 1414 | #define AGG_TX_STATE_TRY_CNT_MSK 0xf000 |
1414 | 1415 | ||
1415 | /* Command ID and sequence number of Tx command for this frame */ | 1416 | /* Command ID and sequence number of Tx command for this frame */ |
1416 | #define AGG_TX_STATE_SEQ_NUM_POS 16 | 1417 | #define AGG_TX_STATE_SEQ_NUM_POS 16 |
1417 | #define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000 | 1418 | #define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000 |
1418 | 1419 | ||
1419 | /* | 1420 | /* |
1420 | * REPLY_TX = 0x1c (response) | 1421 | * REPLY_TX = 0x1c (response) |
1421 | * | 1422 | * |
1422 | * This response may be in one of two slightly different formats, indicated | 1423 | * This response may be in one of two slightly different formats, indicated |
1423 | * by the frame_count field: | 1424 | * by the frame_count field: |
1424 | * | 1425 | * |
1425 | * 1) No aggregation (frame_count == 1). This reports Tx results for | 1426 | * 1) No aggregation (frame_count == 1). This reports Tx results for |
1426 | * a single frame. Multiple attempts, at various bit rates, may have | 1427 | * a single frame. Multiple attempts, at various bit rates, may have |
1427 | * been made for this frame. | 1428 | * been made for this frame. |
1428 | * | 1429 | * |
1429 | * 2) Aggregation (frame_count > 1). This reports Tx results for | 1430 | * 2) Aggregation (frame_count > 1). This reports Tx results for |
1430 | * 2 or more frames that used block-acknowledge. All frames were | 1431 | * 2 or more frames that used block-acknowledge. All frames were |
1431 | * transmitted at same rate. Rate scaling may have been used if first | 1432 | * transmitted at same rate. Rate scaling may have been used if first |
1432 | * frame in this new agg block failed in previous agg block(s). | 1433 | * frame in this new agg block failed in previous agg block(s). |
1433 | * | 1434 | * |
1434 | * Note that, for aggregation, ACK (block-ack) status is not delivered here; | 1435 | * Note that, for aggregation, ACK (block-ack) status is not delivered here; |
1435 | * block-ack has not been received by the time the agn device records | 1436 | * block-ack has not been received by the time the agn device records |
1436 | * this status. | 1437 | * this status. |
1437 | * This status relates to reasons the tx might have been blocked or aborted | 1438 | * This status relates to reasons the tx might have been blocked or aborted |
1438 | * within the sending station (this agn device), rather than whether it was | 1439 | * within the sending station (this agn device), rather than whether it was |
1439 | * received successfully by the destination station. | 1440 | * received successfully by the destination station. |
1440 | */ | 1441 | */ |
1441 | struct agg_tx_status { | 1442 | struct agg_tx_status { |
1442 | __le16 status; | 1443 | __le16 status; |
1443 | __le16 sequence; | 1444 | __le16 sequence; |
1444 | } __packed; | 1445 | } __packed; |
1445 | 1446 | ||
1446 | /* | 1447 | /* |
1447 | * definitions for initial rate index field | 1448 | * definitions for initial rate index field |
1448 | * bits [3:0] initial rate index | 1449 | * bits [3:0] initial rate index |
1449 | * bits [6:4] rate table color, used for the initial rate | 1450 | * bits [6:4] rate table color, used for the initial rate |
1450 | * bit-7 invalid rate indication | 1451 | * bit-7 invalid rate indication |
1451 | * i.e. rate was not chosen from rate table | 1452 | * i.e. rate was not chosen from rate table |
1452 | * or rate table color was changed during frame retries | 1453 | * or rate table color was changed during frame retries |
1453 | * refer tlc rate info | 1454 | * refer tlc rate info |
1454 | */ | 1455 | */ |
1455 | 1456 | ||
1456 | #define IWL50_TX_RES_INIT_RATE_INDEX_POS 0 | 1457 | #define IWL50_TX_RES_INIT_RATE_INDEX_POS 0 |
1457 | #define IWL50_TX_RES_INIT_RATE_INDEX_MSK 0x0f | 1458 | #define IWL50_TX_RES_INIT_RATE_INDEX_MSK 0x0f |
1458 | #define IWL50_TX_RES_RATE_TABLE_COLOR_POS 4 | 1459 | #define IWL50_TX_RES_RATE_TABLE_COLOR_POS 4 |
1459 | #define IWL50_TX_RES_RATE_TABLE_COLOR_MSK 0x70 | 1460 | #define IWL50_TX_RES_RATE_TABLE_COLOR_MSK 0x70 |
1460 | #define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80 | 1461 | #define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80 |
1461 | 1462 | ||
1462 | /* refer to ra_tid */ | 1463 | /* refer to ra_tid */ |
1463 | #define IWLAGN_TX_RES_TID_POS 0 | 1464 | #define IWLAGN_TX_RES_TID_POS 0 |
1464 | #define IWLAGN_TX_RES_TID_MSK 0x0f | 1465 | #define IWLAGN_TX_RES_TID_MSK 0x0f |
1465 | #define IWLAGN_TX_RES_RA_POS 4 | 1466 | #define IWLAGN_TX_RES_RA_POS 4 |
1466 | #define IWLAGN_TX_RES_RA_MSK 0xf0 | 1467 | #define IWLAGN_TX_RES_RA_MSK 0xf0 |
1467 | 1468 | ||
1468 | struct iwlagn_tx_resp { | 1469 | struct iwlagn_tx_resp { |
1469 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ | 1470 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ |
1470 | u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ | 1471 | u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ |
1471 | u8 failure_rts; /* # failures due to unsuccessful RTS */ | 1472 | u8 failure_rts; /* # failures due to unsuccessful RTS */ |
1472 | u8 failure_frame; /* # failures due to no ACK (unused for agg) */ | 1473 | u8 failure_frame; /* # failures due to no ACK (unused for agg) */ |
1473 | 1474 | ||
1474 | /* For non-agg: Rate at which frame was successful. | 1475 | /* For non-agg: Rate at which frame was successful. |
1475 | * For agg: Rate at which all frames were transmitted. */ | 1476 | * For agg: Rate at which all frames were transmitted. */ |
1476 | __le32 rate_n_flags; /* RATE_MCS_* */ | 1477 | __le32 rate_n_flags; /* RATE_MCS_* */ |
1477 | 1478 | ||
1478 | /* For non-agg: RTS + CTS + frame tx attempts time + ACK. | 1479 | /* For non-agg: RTS + CTS + frame tx attempts time + ACK. |
1479 | * For agg: RTS + CTS + aggregation tx time + block-ack time. */ | 1480 | * For agg: RTS + CTS + aggregation tx time + block-ack time. */ |
1480 | __le16 wireless_media_time; /* uSecs */ | 1481 | __le16 wireless_media_time; /* uSecs */ |
1481 | 1482 | ||
1482 | u8 pa_status; /* RF power amplifier measurement (not used) */ | 1483 | u8 pa_status; /* RF power amplifier measurement (not used) */ |
1483 | u8 pa_integ_res_a[3]; | 1484 | u8 pa_integ_res_a[3]; |
1484 | u8 pa_integ_res_b[3]; | 1485 | u8 pa_integ_res_b[3]; |
1485 | u8 pa_integ_res_C[3]; | 1486 | u8 pa_integ_res_C[3]; |
1486 | 1487 | ||
1487 | __le32 tfd_info; | 1488 | __le32 tfd_info; |
1488 | __le16 seq_ctl; | 1489 | __le16 seq_ctl; |
1489 | __le16 byte_cnt; | 1490 | __le16 byte_cnt; |
1490 | u8 tlc_info; | 1491 | u8 tlc_info; |
1491 | u8 ra_tid; /* tid (0:3), sta_id (4:7) */ | 1492 | u8 ra_tid; /* tid (0:3), sta_id (4:7) */ |
1492 | __le16 frame_ctrl; | 1493 | __le16 frame_ctrl; |
1493 | /* | 1494 | /* |
1494 | * For non-agg: frame status TX_STATUS_* | 1495 | * For non-agg: frame status TX_STATUS_* |
1495 | * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status | 1496 | * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status |
1496 | * fields follow this one, up to frame_count. | 1497 | * fields follow this one, up to frame_count. |
1497 | * Bit fields: | 1498 | * Bit fields: |
1498 | * 11- 0: AGG_TX_STATE_* status code | 1499 | * 11- 0: AGG_TX_STATE_* status code |
1499 | * 15-12: Retry count for 1st frame in aggregation (retries | 1500 | * 15-12: Retry count for 1st frame in aggregation (retries |
1500 | * occur if tx failed for this frame when it was a | 1501 | * occur if tx failed for this frame when it was a |
1501 | * member of a previous aggregation block). If rate | 1502 | * member of a previous aggregation block). If rate |
1502 | * scaling is used, retry count indicates the rate | 1503 | * scaling is used, retry count indicates the rate |
1503 | * table entry used for all frames in the new agg. | 1504 | * table entry used for all frames in the new agg. |
1504 | * 31-16: Sequence # for this frame's Tx cmd (not SSN!) | 1505 | * 31-16: Sequence # for this frame's Tx cmd (not SSN!) |
1505 | */ | 1506 | */ |
1506 | struct agg_tx_status status; /* TX status (in aggregation - | 1507 | struct agg_tx_status status; /* TX status (in aggregation - |
1507 | * status of 1st frame) */ | 1508 | * status of 1st frame) */ |
1508 | } __packed; | 1509 | } __packed; |
1509 | /* | 1510 | /* |
1510 | * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) | 1511 | * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) |
1511 | * | 1512 | * |
1512 | * Reports Block-Acknowledge from recipient station | 1513 | * Reports Block-Acknowledge from recipient station |
1513 | */ | 1514 | */ |
1514 | struct iwl_compressed_ba_resp { | 1515 | struct iwl_compressed_ba_resp { |
1515 | __le32 sta_addr_lo32; | 1516 | __le32 sta_addr_lo32; |
1516 | __le16 sta_addr_hi16; | 1517 | __le16 sta_addr_hi16; |
1517 | __le16 reserved; | 1518 | __le16 reserved; |
1518 | 1519 | ||
1519 | /* Index of recipient (BA-sending) station in uCode's station table */ | 1520 | /* Index of recipient (BA-sending) station in uCode's station table */ |
1520 | u8 sta_id; | 1521 | u8 sta_id; |
1521 | u8 tid; | 1522 | u8 tid; |
1522 | __le16 seq_ctl; | 1523 | __le16 seq_ctl; |
1523 | __le64 bitmap; | 1524 | __le64 bitmap; |
1524 | __le16 scd_flow; | 1525 | __le16 scd_flow; |
1525 | __le16 scd_ssn; | 1526 | __le16 scd_ssn; |
1526 | u8 txed; /* number of frames sent */ | 1527 | u8 txed; /* number of frames sent */ |
1527 | u8 txed_2_done; /* number of frames acked */ | 1528 | u8 txed_2_done; /* number of frames acked */ |
1528 | } __packed; | 1529 | } __packed; |
1529 | 1530 | ||
1530 | /* | 1531 | /* |
1531 | * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) | 1532 | * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) |
1532 | * | 1533 | * |
1533 | */ | 1534 | */ |
1534 | 1535 | ||
1535 | /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ | 1536 | /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ |
1536 | #define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) | 1537 | #define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) |
1537 | 1538 | ||
1538 | /* # of EDCA prioritized tx fifos */ | 1539 | /* # of EDCA prioritized tx fifos */ |
1539 | #define LINK_QUAL_AC_NUM AC_NUM | 1540 | #define LINK_QUAL_AC_NUM AC_NUM |
1540 | 1541 | ||
1541 | /* # entries in rate scale table to support Tx retries */ | 1542 | /* # entries in rate scale table to support Tx retries */ |
1542 | #define LINK_QUAL_MAX_RETRY_NUM 16 | 1543 | #define LINK_QUAL_MAX_RETRY_NUM 16 |
1543 | 1544 | ||
1544 | /* Tx antenna selection values */ | 1545 | /* Tx antenna selection values */ |
1545 | #define LINK_QUAL_ANT_A_MSK (1 << 0) | 1546 | #define LINK_QUAL_ANT_A_MSK (1 << 0) |
1546 | #define LINK_QUAL_ANT_B_MSK (1 << 1) | 1547 | #define LINK_QUAL_ANT_B_MSK (1 << 1) |
1547 | #define LINK_QUAL_ANT_MSK (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK) | 1548 | #define LINK_QUAL_ANT_MSK (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK) |
1548 | 1549 | ||
1549 | 1550 | ||
1550 | /** | 1551 | /** |
1551 | * struct iwl_link_qual_general_params | 1552 | * struct iwl_link_qual_general_params |
1552 | * | 1553 | * |
1553 | * Used in REPLY_TX_LINK_QUALITY_CMD | 1554 | * Used in REPLY_TX_LINK_QUALITY_CMD |
1554 | */ | 1555 | */ |
1555 | struct iwl_link_qual_general_params { | 1556 | struct iwl_link_qual_general_params { |
1556 | u8 flags; | 1557 | u8 flags; |
1557 | 1558 | ||
1558 | /* No entries at or above this (driver chosen) index contain MIMO */ | 1559 | /* No entries at or above this (driver chosen) index contain MIMO */ |
1559 | u8 mimo_delimiter; | 1560 | u8 mimo_delimiter; |
1560 | 1561 | ||
1561 | /* Best single antenna to use for single stream (legacy, SISO). */ | 1562 | /* Best single antenna to use for single stream (legacy, SISO). */ |
1562 | u8 single_stream_ant_msk; /* LINK_QUAL_ANT_* */ | 1563 | u8 single_stream_ant_msk; /* LINK_QUAL_ANT_* */ |
1563 | 1564 | ||
1564 | /* Best antennas to use for MIMO (unused for 4965, assumes both). */ | 1565 | /* Best antennas to use for MIMO (unused for 4965, assumes both). */ |
1565 | u8 dual_stream_ant_msk; /* LINK_QUAL_ANT_* */ | 1566 | u8 dual_stream_ant_msk; /* LINK_QUAL_ANT_* */ |
1566 | 1567 | ||
1567 | /* | 1568 | /* |
1568 | * If driver needs to use different initial rates for different | 1569 | * If driver needs to use different initial rates for different |
1569 | * EDCA QOS access categories (as implemented by tx fifos 0-3), | 1570 | * EDCA QOS access categories (as implemented by tx fifos 0-3), |
1570 | * this table will set that up, by indicating the indexes in the | 1571 | * this table will set that up, by indicating the indexes in the |
1571 | * rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table at which to start. | 1572 | * rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table at which to start. |
1572 | * Otherwise, driver should set all entries to 0. | 1573 | * Otherwise, driver should set all entries to 0. |
1573 | * | 1574 | * |
1574 | * Entry usage: | 1575 | * Entry usage: |
1575 | * 0 = Background, 1 = Best Effort (normal), 2 = Video, 3 = Voice | 1576 | * 0 = Background, 1 = Best Effort (normal), 2 = Video, 3 = Voice |
1576 | * TX FIFOs above 3 use same value (typically 0) as TX FIFO 3. | 1577 | * TX FIFOs above 3 use same value (typically 0) as TX FIFO 3. |
1577 | */ | 1578 | */ |
1578 | u8 start_rate_index[LINK_QUAL_AC_NUM]; | 1579 | u8 start_rate_index[LINK_QUAL_AC_NUM]; |
1579 | } __packed; | 1580 | } __packed; |
1580 | 1581 | ||
1581 | #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ | 1582 | #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ |
1582 | #define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) | 1583 | #define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) |
1583 | #define LINK_QUAL_AGG_TIME_LIMIT_MIN (100) | 1584 | #define LINK_QUAL_AGG_TIME_LIMIT_MIN (100) |
1584 | 1585 | ||
1585 | #define LINK_QUAL_AGG_DISABLE_START_DEF (3) | 1586 | #define LINK_QUAL_AGG_DISABLE_START_DEF (3) |
1586 | #define LINK_QUAL_AGG_DISABLE_START_MAX (255) | 1587 | #define LINK_QUAL_AGG_DISABLE_START_MAX (255) |
1587 | #define LINK_QUAL_AGG_DISABLE_START_MIN (0) | 1588 | #define LINK_QUAL_AGG_DISABLE_START_MIN (0) |
1588 | 1589 | ||
1589 | #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) | 1590 | #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) |
1590 | #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) | 1591 | #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) |
1591 | #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) | 1592 | #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) |
1592 | 1593 | ||
1593 | /** | 1594 | /** |
1594 | * struct iwl_link_qual_agg_params | 1595 | * struct iwl_link_qual_agg_params |
1595 | * | 1596 | * |
1596 | * Used in REPLY_TX_LINK_QUALITY_CMD | 1597 | * Used in REPLY_TX_LINK_QUALITY_CMD |
1597 | */ | 1598 | */ |
1598 | struct iwl_link_qual_agg_params { | 1599 | struct iwl_link_qual_agg_params { |
1599 | 1600 | ||
1600 | /* | 1601 | /* |
1601 | *Maximum number of uSec in aggregation. | 1602 | *Maximum number of uSec in aggregation. |
1602 | * default set to 4000 (4 milliseconds) if not configured in .cfg | 1603 | * default set to 4000 (4 milliseconds) if not configured in .cfg |
1603 | */ | 1604 | */ |
1604 | __le16 agg_time_limit; | 1605 | __le16 agg_time_limit; |
1605 | 1606 | ||
1606 | /* | 1607 | /* |
1607 | * Number of Tx retries allowed for a frame, before that frame will | 1608 | * Number of Tx retries allowed for a frame, before that frame will |
1608 | * no longer be considered for the start of an aggregation sequence | 1609 | * no longer be considered for the start of an aggregation sequence |
1609 | * (scheduler will then try to tx it as single frame). | 1610 | * (scheduler will then try to tx it as single frame). |
1610 | * Driver should set this to 3. | 1611 | * Driver should set this to 3. |
1611 | */ | 1612 | */ |
1612 | u8 agg_dis_start_th; | 1613 | u8 agg_dis_start_th; |
1613 | 1614 | ||
1614 | /* | 1615 | /* |
1615 | * Maximum number of frames in aggregation. | 1616 | * Maximum number of frames in aggregation. |
1616 | * 0 = no limit (default). 1 = no aggregation. | 1617 | * 0 = no limit (default). 1 = no aggregation. |
1617 | * Other values = max # frames in aggregation. | 1618 | * Other values = max # frames in aggregation. |
1618 | */ | 1619 | */ |
1619 | u8 agg_frame_cnt_limit; | 1620 | u8 agg_frame_cnt_limit; |
1620 | 1621 | ||
1621 | __le32 reserved; | 1622 | __le32 reserved; |
1622 | } __packed; | 1623 | } __packed; |
1623 | 1624 | ||
1624 | /* | 1625 | /* |
1625 | * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) | 1626 | * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) |
1626 | * | 1627 | * |
1627 | * For agn devices | 1628 | * For agn devices |
1628 | * | 1629 | * |
1629 | * Each station in the agn device's internal station table has its own table | 1630 | * Each station in the agn device's internal station table has its own table |
1630 | * of 16 | 1631 | * of 16 |
1631 | * Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when | 1632 | * Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when |
1632 | * an ACK is not received. This command replaces the entire table for | 1633 | * an ACK is not received. This command replaces the entire table for |
1633 | * one station. | 1634 | * one station. |
1634 | * | 1635 | * |
1635 | * NOTE: Station must already be in agn device's station table. | 1636 | * NOTE: Station must already be in agn device's station table. |
1636 | * Use REPLY_ADD_STA. | 1637 | * Use REPLY_ADD_STA. |
1637 | * | 1638 | * |
1638 | * The rate scaling procedures described below work well. Of course, other | 1639 | * The rate scaling procedures described below work well. Of course, other |
1639 | * procedures are possible, and may work better for particular environments. | 1640 | * procedures are possible, and may work better for particular environments. |
1640 | * | 1641 | * |
1641 | * | 1642 | * |
1642 | * FILLING THE RATE TABLE | 1643 | * FILLING THE RATE TABLE |
1643 | * | 1644 | * |
1644 | * Given a particular initial rate and mode, as determined by the rate | 1645 | * Given a particular initial rate and mode, as determined by the rate |
1645 | * scaling algorithm described below, the Linux driver uses the following | 1646 | * scaling algorithm described below, the Linux driver uses the following |
1646 | * formula to fill the rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table in the | 1647 | * formula to fill the rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table in the |
1647 | * Link Quality command: | 1648 | * Link Quality command: |
1648 | * | 1649 | * |
1649 | * | 1650 | * |
1650 | * 1) If using High-throughput (HT) (SISO or MIMO) initial rate: | 1651 | * 1) If using High-throughput (HT) (SISO or MIMO) initial rate: |
1651 | * a) Use this same initial rate for first 3 entries. | 1652 | * a) Use this same initial rate for first 3 entries. |
1652 | * b) Find next lower available rate using same mode (SISO or MIMO), | 1653 | * b) Find next lower available rate using same mode (SISO or MIMO), |
1653 | * use for next 3 entries. If no lower rate available, switch to | 1654 | * use for next 3 entries. If no lower rate available, switch to |
1654 | * legacy mode (no HT40 channel, no MIMO, no short guard interval). | 1655 | * legacy mode (no HT40 channel, no MIMO, no short guard interval). |
1655 | * c) If using MIMO, set command's mimo_delimiter to number of entries | 1656 | * c) If using MIMO, set command's mimo_delimiter to number of entries |
1656 | * using MIMO (3 or 6). | 1657 | * using MIMO (3 or 6). |
1657 | * d) After trying 2 HT rates, switch to legacy mode (no HT40 channel, | 1658 | * d) After trying 2 HT rates, switch to legacy mode (no HT40 channel, |
1658 | * no MIMO, no short guard interval), at the next lower bit rate | 1659 | * no MIMO, no short guard interval), at the next lower bit rate |
1659 | * (e.g. if second HT bit rate was 54, try 48 legacy), and follow | 1660 | * (e.g. if second HT bit rate was 54, try 48 legacy), and follow |
1660 | * legacy procedure for remaining table entries. | 1661 | * legacy procedure for remaining table entries. |
1661 | * | 1662 | * |
1662 | * 2) If using legacy initial rate: | 1663 | * 2) If using legacy initial rate: |
1663 | * a) Use the initial rate for only one entry. | 1664 | * a) Use the initial rate for only one entry. |
1664 | * b) For each following entry, reduce the rate to next lower available | 1665 | * b) For each following entry, reduce the rate to next lower available |
1665 | * rate, until reaching the lowest available rate. | 1666 | * rate, until reaching the lowest available rate. |
1666 | * c) When reducing rate, also switch antenna selection. | 1667 | * c) When reducing rate, also switch antenna selection. |
1667 | * d) Once lowest available rate is reached, repeat this rate until | 1668 | * d) Once lowest available rate is reached, repeat this rate until |
1668 | * rate table is filled (16 entries), switching antenna each entry. | 1669 | * rate table is filled (16 entries), switching antenna each entry. |
1669 | * | 1670 | * |
1670 | * | 1671 | * |
1671 | * ACCUMULATING HISTORY | 1672 | * ACCUMULATING HISTORY |
1672 | * | 1673 | * |
1673 | * The rate scaling algorithm for agn devices, as implemented in Linux driver, | 1674 | * The rate scaling algorithm for agn devices, as implemented in Linux driver, |
1674 | * uses two sets of frame Tx success history: One for the current/active | 1675 | * uses two sets of frame Tx success history: One for the current/active |
1675 | * modulation mode, and one for a speculative/search mode that is being | 1676 | * modulation mode, and one for a speculative/search mode that is being |
1676 | * attempted. If the speculative mode turns out to be more effective (i.e. | 1677 | * attempted. If the speculative mode turns out to be more effective (i.e. |
1677 | * actual transfer rate is better), then the driver continues to use the | 1678 | * actual transfer rate is better), then the driver continues to use the |
1678 | * speculative mode as the new current active mode. | 1679 | * speculative mode as the new current active mode. |
1679 | * | 1680 | * |
1680 | * Each history set contains, separately for each possible rate, data for a | 1681 | * Each history set contains, separately for each possible rate, data for a |
1681 | * sliding window of the 62 most recent tx attempts at that rate. The data | 1682 | * sliding window of the 62 most recent tx attempts at that rate. The data |
1682 | * includes a shifting bitmap of success(1)/failure(0), and sums of successful | 1683 | * includes a shifting bitmap of success(1)/failure(0), and sums of successful |
1683 | * and attempted frames, from which the driver can additionally calculate a | 1684 | * and attempted frames, from which the driver can additionally calculate a |
1684 | * success ratio (success / attempted) and number of failures | 1685 | * success ratio (success / attempted) and number of failures |
1685 | * (attempted - success), and control the size of the window (attempted). | 1686 | * (attempted - success), and control the size of the window (attempted). |
1686 | * The driver uses the bit map to remove successes from the success sum, as | 1687 | * The driver uses the bit map to remove successes from the success sum, as |
1687 | * the oldest tx attempts fall out of the window. | 1688 | * the oldest tx attempts fall out of the window. |
1688 | * | 1689 | * |
1689 | * When the agn device makes multiple tx attempts for a given frame, each | 1690 | * When the agn device makes multiple tx attempts for a given frame, each |
1690 | * attempt might be at a different rate, and have different modulation | 1691 | * attempt might be at a different rate, and have different modulation |
1691 | * characteristics (e.g. antenna, fat channel, short guard interval), as set | 1692 | * characteristics (e.g. antenna, fat channel, short guard interval), as set |
1692 | * up in the rate scaling table in the Link Quality command. The driver must | 1693 | * up in the rate scaling table in the Link Quality command. The driver must |
1693 | * determine which rate table entry was used for each tx attempt, to determine | 1694 | * determine which rate table entry was used for each tx attempt, to determine |
1694 | * which rate-specific history to update, and record only those attempts that | 1695 | * which rate-specific history to update, and record only those attempts that |
1695 | * match the modulation characteristics of the history set. | 1696 | * match the modulation characteristics of the history set. |
1696 | * | 1697 | * |
1697 | * When using block-ack (aggregation), all frames are transmitted at the same | 1698 | * When using block-ack (aggregation), all frames are transmitted at the same |
1698 | * rate, since there is no per-attempt acknowledgment from the destination | 1699 | * rate, since there is no per-attempt acknowledgment from the destination |
1699 | * station. The Tx response struct iwl_tx_resp indicates the Tx rate in | 1700 | * station. The Tx response struct iwl_tx_resp indicates the Tx rate in |
1700 | * rate_n_flags field. After receiving a block-ack, the driver can update | 1701 | * rate_n_flags field. After receiving a block-ack, the driver can update |
1701 | * history for the entire block all at once. | 1702 | * history for the entire block all at once. |
1702 | * | 1703 | * |
1703 | * | 1704 | * |
1704 | * FINDING BEST STARTING RATE: | 1705 | * FINDING BEST STARTING RATE: |
1705 | * | 1706 | * |
1706 | * When working with a selected initial modulation mode (see below), the | 1707 | * When working with a selected initial modulation mode (see below), the |
1707 | * driver attempts to find a best initial rate. The initial rate is the | 1708 | * driver attempts to find a best initial rate. The initial rate is the |
1708 | * first entry in the Link Quality command's rate table. | 1709 | * first entry in the Link Quality command's rate table. |
1709 | * | 1710 | * |
1710 | * 1) Calculate actual throughput (success ratio * expected throughput, see | 1711 | * 1) Calculate actual throughput (success ratio * expected throughput, see |
1711 | * table below) for current initial rate. Do this only if enough frames | 1712 | * table below) for current initial rate. Do this only if enough frames |
1712 | * have been attempted to make the value meaningful: at least 6 failed | 1713 | * have been attempted to make the value meaningful: at least 6 failed |
1713 | * tx attempts, or at least 8 successes. If not enough, don't try rate | 1714 | * tx attempts, or at least 8 successes. If not enough, don't try rate |
1714 | * scaling yet. | 1715 | * scaling yet. |
1715 | * | 1716 | * |
1716 | * 2) Find available rates adjacent to current initial rate. Available means: | 1717 | * 2) Find available rates adjacent to current initial rate. Available means: |
1717 | * a) supported by hardware && | 1718 | * a) supported by hardware && |
1718 | * b) supported by association && | 1719 | * b) supported by association && |
1719 | * c) within any constraints selected by user | 1720 | * c) within any constraints selected by user |
1720 | * | 1721 | * |
1721 | * 3) Gather measured throughputs for adjacent rates. These might not have | 1722 | * 3) Gather measured throughputs for adjacent rates. These might not have |
1722 | * enough history to calculate a throughput. That's okay, we might try | 1723 | * enough history to calculate a throughput. That's okay, we might try |
1723 | * using one of them anyway! | 1724 | * using one of them anyway! |
1724 | * | 1725 | * |
1725 | * 4) Try decreasing rate if, for current rate: | 1726 | * 4) Try decreasing rate if, for current rate: |
1726 | * a) success ratio is < 15% || | 1727 | * a) success ratio is < 15% || |
1727 | * b) lower adjacent rate has better measured throughput || | 1728 | * b) lower adjacent rate has better measured throughput || |
1728 | * c) higher adjacent rate has worse throughput, and lower is unmeasured | 1729 | * c) higher adjacent rate has worse throughput, and lower is unmeasured |
1729 | * | 1730 | * |
1730 | * As a sanity check, if decrease was determined above, leave rate | 1731 | * As a sanity check, if decrease was determined above, leave rate |
1731 | * unchanged if: | 1732 | * unchanged if: |
1732 | * a) lower rate unavailable | 1733 | * a) lower rate unavailable |
1733 | * b) success ratio at current rate > 85% (very good) | 1734 | * b) success ratio at current rate > 85% (very good) |
1734 | * c) current measured throughput is better than expected throughput | 1735 | * c) current measured throughput is better than expected throughput |
1735 | * of lower rate (under perfect 100% tx conditions, see table below) | 1736 | * of lower rate (under perfect 100% tx conditions, see table below) |
1736 | * | 1737 | * |
1737 | * 5) Try increasing rate if, for current rate: | 1738 | * 5) Try increasing rate if, for current rate: |
1738 | * a) success ratio is < 15% || | 1739 | * a) success ratio is < 15% || |
1739 | * b) both adjacent rates' throughputs are unmeasured (try it!) || | 1740 | * b) both adjacent rates' throughputs are unmeasured (try it!) || |
1740 | * b) higher adjacent rate has better measured throughput || | 1741 | * b) higher adjacent rate has better measured throughput || |
1741 | * c) lower adjacent rate has worse throughput, and higher is unmeasured | 1742 | * c) lower adjacent rate has worse throughput, and higher is unmeasured |
1742 | * | 1743 | * |
1743 | * As a sanity check, if increase was determined above, leave rate | 1744 | * As a sanity check, if increase was determined above, leave rate |
1744 | * unchanged if: | 1745 | * unchanged if: |
1745 | * a) success ratio at current rate < 70%. This is not particularly | 1746 | * a) success ratio at current rate < 70%. This is not particularly |
1746 | * good performance; higher rate is sure to have poorer success. | 1747 | * good performance; higher rate is sure to have poorer success. |
1747 | * | 1748 | * |
1748 | * 6) Re-evaluate the rate after each tx frame. If working with block- | 1749 | * 6) Re-evaluate the rate after each tx frame. If working with block- |
1749 | * acknowledge, history and statistics may be calculated for the entire | 1750 | * acknowledge, history and statistics may be calculated for the entire |
1750 | * block (including prior history that fits within the history windows), | 1751 | * block (including prior history that fits within the history windows), |
1751 | * before re-evaluation. | 1752 | * before re-evaluation. |
1752 | * | 1753 | * |
1753 | * FINDING BEST STARTING MODULATION MODE: | 1754 | * FINDING BEST STARTING MODULATION MODE: |
1754 | * | 1755 | * |
1755 | * After working with a modulation mode for a "while" (and doing rate scaling), | 1756 | * After working with a modulation mode for a "while" (and doing rate scaling), |
1756 | * the driver searches for a new initial mode in an attempt to improve | 1757 | * the driver searches for a new initial mode in an attempt to improve |
1757 | * throughput. The "while" is measured by numbers of attempted frames: | 1758 | * throughput. The "while" is measured by numbers of attempted frames: |
1758 | * | 1759 | * |
1759 | * For legacy mode, search for new mode after: | 1760 | * For legacy mode, search for new mode after: |
1760 | * 480 successful frames, or 160 failed frames | 1761 | * 480 successful frames, or 160 failed frames |
1761 | * For high-throughput modes (SISO or MIMO), search for new mode after: | 1762 | * For high-throughput modes (SISO or MIMO), search for new mode after: |
1762 | * 4500 successful frames, or 400 failed frames | 1763 | * 4500 successful frames, or 400 failed frames |
1763 | * | 1764 | * |
1764 | * Mode switch possibilities are (3 for each mode): | 1765 | * Mode switch possibilities are (3 for each mode): |
1765 | * | 1766 | * |
1766 | * For legacy: | 1767 | * For legacy: |
1767 | * Change antenna, try SISO (if HT association), try MIMO (if HT association) | 1768 | * Change antenna, try SISO (if HT association), try MIMO (if HT association) |
1768 | * For SISO: | 1769 | * For SISO: |
1769 | * Change antenna, try MIMO, try shortened guard interval (SGI) | 1770 | * Change antenna, try MIMO, try shortened guard interval (SGI) |
1770 | * For MIMO: | 1771 | * For MIMO: |
1771 | * Try SISO antenna A, SISO antenna B, try shortened guard interval (SGI) | 1772 | * Try SISO antenna A, SISO antenna B, try shortened guard interval (SGI) |
1772 | * | 1773 | * |
1773 | * When trying a new mode, use the same bit rate as the old/current mode when | 1774 | * When trying a new mode, use the same bit rate as the old/current mode when |
1774 | * trying antenna switches and shortened guard interval. When switching to | 1775 | * trying antenna switches and shortened guard interval. When switching to |
1775 | * SISO from MIMO or legacy, or to MIMO from SISO or legacy, use a rate | 1776 | * SISO from MIMO or legacy, or to MIMO from SISO or legacy, use a rate |
1776 | * for which the expected throughput (under perfect conditions) is about the | 1777 | * for which the expected throughput (under perfect conditions) is about the |
1777 | * same or slightly better than the actual measured throughput delivered by | 1778 | * same or slightly better than the actual measured throughput delivered by |
1778 | * the old/current mode. | 1779 | * the old/current mode. |
1779 | * | 1780 | * |
1780 | * Actual throughput can be estimated by multiplying the expected throughput | 1781 | * Actual throughput can be estimated by multiplying the expected throughput |
1781 | * by the success ratio (successful / attempted tx frames). Frame size is | 1782 | * by the success ratio (successful / attempted tx frames). Frame size is |
1782 | * not considered in this calculation; it assumes that frame size will average | 1783 | * not considered in this calculation; it assumes that frame size will average |
1783 | * out to be fairly consistent over several samples. The following are | 1784 | * out to be fairly consistent over several samples. The following are |
1784 | * metric values for expected throughput assuming 100% success ratio. | 1785 | * metric values for expected throughput assuming 100% success ratio. |
1785 | * Only G band has support for CCK rates: | 1786 | * Only G band has support for CCK rates: |
1786 | * | 1787 | * |
1787 | * RATE: 1 2 5 11 6 9 12 18 24 36 48 54 60 | 1788 | * RATE: 1 2 5 11 6 9 12 18 24 36 48 54 60 |
1788 | * | 1789 | * |
1789 | * G: 7 13 35 58 40 57 72 98 121 154 177 186 186 | 1790 | * G: 7 13 35 58 40 57 72 98 121 154 177 186 186 |
1790 | * A: 0 0 0 0 40 57 72 98 121 154 177 186 186 | 1791 | * A: 0 0 0 0 40 57 72 98 121 154 177 186 186 |
1791 | * SISO 20MHz: 0 0 0 0 42 42 76 102 124 159 183 193 202 | 1792 | * SISO 20MHz: 0 0 0 0 42 42 76 102 124 159 183 193 202 |
1792 | * SGI SISO 20MHz: 0 0 0 0 46 46 82 110 132 168 192 202 211 | 1793 | * SGI SISO 20MHz: 0 0 0 0 46 46 82 110 132 168 192 202 211 |
1793 | * MIMO 20MHz: 0 0 0 0 74 74 123 155 179 214 236 244 251 | 1794 | * MIMO 20MHz: 0 0 0 0 74 74 123 155 179 214 236 244 251 |
1794 | * SGI MIMO 20MHz: 0 0 0 0 81 81 131 164 188 222 243 251 257 | 1795 | * SGI MIMO 20MHz: 0 0 0 0 81 81 131 164 188 222 243 251 257 |
1795 | * SISO 40MHz: 0 0 0 0 77 77 127 160 184 220 242 250 257 | 1796 | * SISO 40MHz: 0 0 0 0 77 77 127 160 184 220 242 250 257 |
1796 | * SGI SISO 40MHz: 0 0 0 0 83 83 135 169 193 229 250 257 264 | 1797 | * SGI SISO 40MHz: 0 0 0 0 83 83 135 169 193 229 250 257 264 |
1797 | * MIMO 40MHz: 0 0 0 0 123 123 182 214 235 264 279 285 289 | 1798 | * MIMO 40MHz: 0 0 0 0 123 123 182 214 235 264 279 285 289 |
1798 | * SGI MIMO 40MHz: 0 0 0 0 131 131 191 222 242 270 284 289 293 | 1799 | * SGI MIMO 40MHz: 0 0 0 0 131 131 191 222 242 270 284 289 293 |
1799 | * | 1800 | * |
1800 | * After the new mode has been tried for a short while (minimum of 6 failed | 1801 | * After the new mode has been tried for a short while (minimum of 6 failed |
1801 | * frames or 8 successful frames), compare success ratio and actual throughput | 1802 | * frames or 8 successful frames), compare success ratio and actual throughput |
1802 | * estimate of the new mode with the old. If either is better with the new | 1803 | * estimate of the new mode with the old. If either is better with the new |
1803 | * mode, continue to use the new mode. | 1804 | * mode, continue to use the new mode. |
1804 | * | 1805 | * |
1805 | * Continue comparing modes until all 3 possibilities have been tried. | 1806 | * Continue comparing modes until all 3 possibilities have been tried. |
1806 | * If moving from legacy to HT, try all 3 possibilities from the new HT | 1807 | * If moving from legacy to HT, try all 3 possibilities from the new HT |
1807 | * mode. After trying all 3, a best mode is found. Continue to use this mode | 1808 | * mode. After trying all 3, a best mode is found. Continue to use this mode |
1808 | * for the longer "while" described above (e.g. 480 successful frames for | 1809 | * for the longer "while" described above (e.g. 480 successful frames for |
1809 | * legacy), and then repeat the search process. | 1810 | * legacy), and then repeat the search process. |
1810 | * | 1811 | * |
1811 | */ | 1812 | */ |
1812 | struct iwl_link_quality_cmd { | 1813 | struct iwl_link_quality_cmd { |
1813 | 1814 | ||
1814 | /* Index of destination/recipient station in uCode's station table */ | 1815 | /* Index of destination/recipient station in uCode's station table */ |
1815 | u8 sta_id; | 1816 | u8 sta_id; |
1816 | u8 reserved1; | 1817 | u8 reserved1; |
1817 | __le16 control; /* not used */ | 1818 | __le16 control; /* not used */ |
1818 | struct iwl_link_qual_general_params general_params; | 1819 | struct iwl_link_qual_general_params general_params; |
1819 | struct iwl_link_qual_agg_params agg_params; | 1820 | struct iwl_link_qual_agg_params agg_params; |
1820 | 1821 | ||
1821 | /* | 1822 | /* |
1822 | * Rate info; when using rate-scaling, Tx command's initial_rate_index | 1823 | * Rate info; when using rate-scaling, Tx command's initial_rate_index |
1823 | * specifies 1st Tx rate attempted, via index into this table. | 1824 | * specifies 1st Tx rate attempted, via index into this table. |
1824 | * agn devices works its way through table when retrying Tx. | 1825 | * agn devices works its way through table when retrying Tx. |
1825 | */ | 1826 | */ |
1826 | struct { | 1827 | struct { |
1827 | __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ | 1828 | __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ |
1828 | } rs_table[LINK_QUAL_MAX_RETRY_NUM]; | 1829 | } rs_table[LINK_QUAL_MAX_RETRY_NUM]; |
1829 | __le32 reserved2; | 1830 | __le32 reserved2; |
1830 | } __packed; | 1831 | } __packed; |
1831 | 1832 | ||
1832 | /* | 1833 | /* |
1833 | * BT configuration enable flags: | 1834 | * BT configuration enable flags: |
1834 | * bit 0 - 1: BT channel announcement enabled | 1835 | * bit 0 - 1: BT channel announcement enabled |
1835 | * 0: disable | 1836 | * 0: disable |
1836 | * bit 1 - 1: priority of BT device enabled | 1837 | * bit 1 - 1: priority of BT device enabled |
1837 | * 0: disable | 1838 | * 0: disable |
1838 | * bit 2 - 1: BT 2 wire support enabled | 1839 | * bit 2 - 1: BT 2 wire support enabled |
1839 | * 0: disable | 1840 | * 0: disable |
1840 | */ | 1841 | */ |
1841 | #define BT_COEX_DISABLE (0x0) | 1842 | #define BT_COEX_DISABLE (0x0) |
1842 | #define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0) | 1843 | #define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0) |
1843 | #define BT_ENABLE_PRIORITY BIT(1) | 1844 | #define BT_ENABLE_PRIORITY BIT(1) |
1844 | #define BT_ENABLE_2_WIRE BIT(2) | 1845 | #define BT_ENABLE_2_WIRE BIT(2) |
1845 | 1846 | ||
1846 | #define BT_COEX_DISABLE (0x0) | 1847 | #define BT_COEX_DISABLE (0x0) |
1847 | #define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY) | 1848 | #define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY) |
1848 | 1849 | ||
1849 | #define BT_LEAD_TIME_MIN (0x0) | 1850 | #define BT_LEAD_TIME_MIN (0x0) |
1850 | #define BT_LEAD_TIME_DEF (0x1E) | 1851 | #define BT_LEAD_TIME_DEF (0x1E) |
1851 | #define BT_LEAD_TIME_MAX (0xFF) | 1852 | #define BT_LEAD_TIME_MAX (0xFF) |
1852 | 1853 | ||
1853 | #define BT_MAX_KILL_MIN (0x1) | 1854 | #define BT_MAX_KILL_MIN (0x1) |
1854 | #define BT_MAX_KILL_DEF (0x5) | 1855 | #define BT_MAX_KILL_DEF (0x5) |
1855 | #define BT_MAX_KILL_MAX (0xFF) | 1856 | #define BT_MAX_KILL_MAX (0xFF) |
1856 | 1857 | ||
1857 | #define BT_DURATION_LIMIT_DEF 625 | 1858 | #define BT_DURATION_LIMIT_DEF 625 |
1858 | #define BT_DURATION_LIMIT_MAX 1250 | 1859 | #define BT_DURATION_LIMIT_MAX 1250 |
1859 | #define BT_DURATION_LIMIT_MIN 625 | 1860 | #define BT_DURATION_LIMIT_MIN 625 |
1860 | 1861 | ||
1861 | #define BT_ON_THRESHOLD_DEF 4 | 1862 | #define BT_ON_THRESHOLD_DEF 4 |
1862 | #define BT_ON_THRESHOLD_MAX 1000 | 1863 | #define BT_ON_THRESHOLD_MAX 1000 |
1863 | #define BT_ON_THRESHOLD_MIN 1 | 1864 | #define BT_ON_THRESHOLD_MIN 1 |
1864 | 1865 | ||
1865 | #define BT_FRAG_THRESHOLD_DEF 0 | 1866 | #define BT_FRAG_THRESHOLD_DEF 0 |
1866 | #define BT_FRAG_THRESHOLD_MAX 0 | 1867 | #define BT_FRAG_THRESHOLD_MAX 0 |
1867 | #define BT_FRAG_THRESHOLD_MIN 0 | 1868 | #define BT_FRAG_THRESHOLD_MIN 0 |
1868 | 1869 | ||
1869 | #define BT_AGG_THRESHOLD_DEF 1200 | 1870 | #define BT_AGG_THRESHOLD_DEF 1200 |
1870 | #define BT_AGG_THRESHOLD_MAX 8000 | 1871 | #define BT_AGG_THRESHOLD_MAX 8000 |
1871 | #define BT_AGG_THRESHOLD_MIN 400 | 1872 | #define BT_AGG_THRESHOLD_MIN 400 |
1872 | 1873 | ||
1873 | /* | 1874 | /* |
1874 | * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) | 1875 | * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) |
1875 | * | 1876 | * |
1876 | * agn devices support hardware handshake with Bluetooth device on | 1877 | * agn devices support hardware handshake with Bluetooth device on |
1877 | * same platform. Bluetooth device alerts wireless device when it will Tx; | 1878 | * same platform. Bluetooth device alerts wireless device when it will Tx; |
1878 | * wireless device can delay or kill its own Tx to accommodate. | 1879 | * wireless device can delay or kill its own Tx to accommodate. |
1879 | */ | 1880 | */ |
1880 | struct iwl_bt_cmd { | 1881 | struct iwl_bt_cmd { |
1881 | u8 flags; | 1882 | u8 flags; |
1882 | u8 lead_time; | 1883 | u8 lead_time; |
1883 | u8 max_kill; | 1884 | u8 max_kill; |
1884 | u8 reserved; | 1885 | u8 reserved; |
1885 | __le32 kill_ack_mask; | 1886 | __le32 kill_ack_mask; |
1886 | __le32 kill_cts_mask; | 1887 | __le32 kill_cts_mask; |
1887 | } __packed; | 1888 | } __packed; |
1888 | 1889 | ||
1889 | #define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0) | 1890 | #define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0) |
1890 | 1891 | ||
1891 | #define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) | 1892 | #define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) |
1892 | #define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3 | 1893 | #define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3 |
1893 | #define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0 | 1894 | #define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0 |
1894 | #define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1 | 1895 | #define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1 |
1895 | #define IWLAGN_BT_FLAG_COEX_MODE_3W 2 | 1896 | #define IWLAGN_BT_FLAG_COEX_MODE_3W 2 |
1896 | #define IWLAGN_BT_FLAG_COEX_MODE_4W 3 | 1897 | #define IWLAGN_BT_FLAG_COEX_MODE_4W 3 |
1897 | 1898 | ||
1898 | #define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6) | 1899 | #define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6) |
1899 | /* Disable Sync PSPoll on SCO/eSCO */ | 1900 | /* Disable Sync PSPoll on SCO/eSCO */ |
1900 | #define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE BIT(7) | 1901 | #define IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE BIT(7) |
1901 | 1902 | ||
1902 | #define IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD -75 /* dBm */ | 1903 | #define IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD -75 /* dBm */ |
1903 | #define IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD -65 /* dBm */ | 1904 | #define IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD -65 /* dBm */ |
1904 | 1905 | ||
1905 | #define IWLAGN_BT_PRIO_BOOST_MAX 0xFF | 1906 | #define IWLAGN_BT_PRIO_BOOST_MAX 0xFF |
1906 | #define IWLAGN_BT_PRIO_BOOST_MIN 0x00 | 1907 | #define IWLAGN_BT_PRIO_BOOST_MIN 0x00 |
1907 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 | 1908 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 |
1908 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT32 0xF0F0F0F0 | 1909 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT32 0xF0F0F0F0 |
1909 | 1910 | ||
1910 | #define IWLAGN_BT_MAX_KILL_DEFAULT 5 | 1911 | #define IWLAGN_BT_MAX_KILL_DEFAULT 5 |
1911 | 1912 | ||
1912 | #define IWLAGN_BT3_T7_DEFAULT 1 | 1913 | #define IWLAGN_BT3_T7_DEFAULT 1 |
1913 | 1914 | ||
1914 | enum iwl_bt_kill_idx { | 1915 | enum iwl_bt_kill_idx { |
1915 | IWL_BT_KILL_DEFAULT = 0, | 1916 | IWL_BT_KILL_DEFAULT = 0, |
1916 | IWL_BT_KILL_OVERRIDE = 1, | 1917 | IWL_BT_KILL_OVERRIDE = 1, |
1917 | IWL_BT_KILL_REDUCE = 2, | 1918 | IWL_BT_KILL_REDUCE = 2, |
1918 | }; | 1919 | }; |
1919 | 1920 | ||
1920 | #define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000) | 1921 | #define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000) |
1921 | #define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000) | 1922 | #define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000) |
1922 | #define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff) | 1923 | #define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff) |
1923 | #define IWLAGN_BT_KILL_ACK_CTS_MASK_REDUCE cpu_to_le32(0) | 1924 | #define IWLAGN_BT_KILL_ACK_CTS_MASK_REDUCE cpu_to_le32(0) |
1924 | 1925 | ||
1925 | #define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 | 1926 | #define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 |
1926 | 1927 | ||
1927 | #define IWLAGN_BT3_T2_DEFAULT 0xc | 1928 | #define IWLAGN_BT3_T2_DEFAULT 0xc |
1928 | 1929 | ||
1929 | #define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) | 1930 | #define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) |
1930 | #define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1)) | 1931 | #define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1)) |
1931 | #define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) | 1932 | #define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) |
1932 | #define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) | 1933 | #define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) |
1933 | #define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) | 1934 | #define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) |
1934 | #define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) | 1935 | #define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) |
1935 | #define IWLAGN_BT_VALID_REDUCED_TX_PWR cpu_to_le16(BIT(6)) | 1936 | #define IWLAGN_BT_VALID_REDUCED_TX_PWR cpu_to_le16(BIT(6)) |
1936 | #define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) | 1937 | #define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) |
1937 | 1938 | ||
1938 | #define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \ | 1939 | #define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \ |
1939 | IWLAGN_BT_VALID_BOOST | \ | 1940 | IWLAGN_BT_VALID_BOOST | \ |
1940 | IWLAGN_BT_VALID_MAX_KILL | \ | 1941 | IWLAGN_BT_VALID_MAX_KILL | \ |
1941 | IWLAGN_BT_VALID_3W_TIMERS | \ | 1942 | IWLAGN_BT_VALID_3W_TIMERS | \ |
1942 | IWLAGN_BT_VALID_KILL_ACK_MASK | \ | 1943 | IWLAGN_BT_VALID_KILL_ACK_MASK | \ |
1943 | IWLAGN_BT_VALID_KILL_CTS_MASK | \ | 1944 | IWLAGN_BT_VALID_KILL_CTS_MASK | \ |
1944 | IWLAGN_BT_VALID_REDUCED_TX_PWR | \ | 1945 | IWLAGN_BT_VALID_REDUCED_TX_PWR | \ |
1945 | IWLAGN_BT_VALID_3W_LUT) | 1946 | IWLAGN_BT_VALID_3W_LUT) |
1946 | 1947 | ||
1947 | #define IWLAGN_BT_REDUCED_TX_PWR BIT(0) | 1948 | #define IWLAGN_BT_REDUCED_TX_PWR BIT(0) |
1948 | 1949 | ||
1949 | #define IWLAGN_BT_DECISION_LUT_SIZE 12 | 1950 | #define IWLAGN_BT_DECISION_LUT_SIZE 12 |
1950 | 1951 | ||
1951 | struct iwl_basic_bt_cmd { | 1952 | struct iwl_basic_bt_cmd { |
1952 | u8 flags; | 1953 | u8 flags; |
1953 | u8 ledtime; /* unused */ | 1954 | u8 ledtime; /* unused */ |
1954 | u8 max_kill; | 1955 | u8 max_kill; |
1955 | u8 bt3_timer_t7_value; | 1956 | u8 bt3_timer_t7_value; |
1956 | __le32 kill_ack_mask; | 1957 | __le32 kill_ack_mask; |
1957 | __le32 kill_cts_mask; | 1958 | __le32 kill_cts_mask; |
1958 | u8 bt3_prio_sample_time; | 1959 | u8 bt3_prio_sample_time; |
1959 | u8 bt3_timer_t2_value; | 1960 | u8 bt3_timer_t2_value; |
1960 | __le16 bt4_reaction_time; /* unused */ | 1961 | __le16 bt4_reaction_time; /* unused */ |
1961 | __le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE]; | 1962 | __le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE]; |
1962 | /* | 1963 | /* |
1963 | * bit 0: use reduced tx power for control frame | 1964 | * bit 0: use reduced tx power for control frame |
1964 | * bit 1 - 7: reserved | 1965 | * bit 1 - 7: reserved |
1965 | */ | 1966 | */ |
1966 | u8 reduce_txpower; | 1967 | u8 reduce_txpower; |
1967 | u8 reserved; | 1968 | u8 reserved; |
1968 | __le16 valid; | 1969 | __le16 valid; |
1969 | }; | 1970 | }; |
1970 | 1971 | ||
1971 | struct iwl_bt_cmd_v1 { | 1972 | struct iwl_bt_cmd_v1 { |
1972 | struct iwl_basic_bt_cmd basic; | 1973 | struct iwl_basic_bt_cmd basic; |
1973 | u8 prio_boost; | 1974 | u8 prio_boost; |
1974 | /* | 1975 | /* |
1975 | * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask | 1976 | * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask |
1976 | * if configure the following patterns | 1977 | * if configure the following patterns |
1977 | */ | 1978 | */ |
1978 | u8 tx_prio_boost; /* SW boost of WiFi tx priority */ | 1979 | u8 tx_prio_boost; /* SW boost of WiFi tx priority */ |
1979 | __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ | 1980 | __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ |
1980 | }; | 1981 | }; |
1981 | 1982 | ||
1982 | struct iwl_bt_cmd_v2 { | 1983 | struct iwl_bt_cmd_v2 { |
1983 | struct iwl_basic_bt_cmd basic; | 1984 | struct iwl_basic_bt_cmd basic; |
1984 | __le32 prio_boost; | 1985 | __le32 prio_boost; |
1985 | /* | 1986 | /* |
1986 | * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask | 1987 | * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask |
1987 | * if configure the following patterns | 1988 | * if configure the following patterns |
1988 | */ | 1989 | */ |
1989 | u8 reserved; | 1990 | u8 reserved; |
1990 | u8 tx_prio_boost; /* SW boost of WiFi tx priority */ | 1991 | u8 tx_prio_boost; /* SW boost of WiFi tx priority */ |
1991 | __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ | 1992 | __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ |
1992 | }; | 1993 | }; |
1993 | 1994 | ||
1994 | #define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) | 1995 | #define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) |
1995 | 1996 | ||
1996 | struct iwlagn_bt_sco_cmd { | 1997 | struct iwlagn_bt_sco_cmd { |
1997 | __le32 flags; | 1998 | __le32 flags; |
1998 | }; | 1999 | }; |
1999 | 2000 | ||
2000 | /****************************************************************************** | 2001 | /****************************************************************************** |
2001 | * (6) | 2002 | * (6) |
2002 | * Spectrum Management (802.11h) Commands, Responses, Notifications: | 2003 | * Spectrum Management (802.11h) Commands, Responses, Notifications: |
2003 | * | 2004 | * |
2004 | *****************************************************************************/ | 2005 | *****************************************************************************/ |
2005 | 2006 | ||
2006 | /* | 2007 | /* |
2007 | * Spectrum Management | 2008 | * Spectrum Management |
2008 | */ | 2009 | */ |
2009 | #define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ | 2010 | #define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ |
2010 | RXON_FILTER_CTL2HOST_MSK | \ | 2011 | RXON_FILTER_CTL2HOST_MSK | \ |
2011 | RXON_FILTER_ACCEPT_GRP_MSK | \ | 2012 | RXON_FILTER_ACCEPT_GRP_MSK | \ |
2012 | RXON_FILTER_DIS_DECRYPT_MSK | \ | 2013 | RXON_FILTER_DIS_DECRYPT_MSK | \ |
2013 | RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ | 2014 | RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ |
2014 | RXON_FILTER_ASSOC_MSK | \ | 2015 | RXON_FILTER_ASSOC_MSK | \ |
2015 | RXON_FILTER_BCON_AWARE_MSK) | 2016 | RXON_FILTER_BCON_AWARE_MSK) |
2016 | 2017 | ||
2017 | struct iwl_measure_channel { | 2018 | struct iwl_measure_channel { |
2018 | __le32 duration; /* measurement duration in extended beacon | 2019 | __le32 duration; /* measurement duration in extended beacon |
2019 | * format */ | 2020 | * format */ |
2020 | u8 channel; /* channel to measure */ | 2021 | u8 channel; /* channel to measure */ |
2021 | u8 type; /* see enum iwl_measure_type */ | 2022 | u8 type; /* see enum iwl_measure_type */ |
2022 | __le16 reserved; | 2023 | __le16 reserved; |
2023 | } __packed; | 2024 | } __packed; |
2024 | 2025 | ||
2025 | /* | 2026 | /* |
2026 | * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) | 2027 | * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) |
2027 | */ | 2028 | */ |
2028 | struct iwl_spectrum_cmd { | 2029 | struct iwl_spectrum_cmd { |
2029 | __le16 len; /* number of bytes starting from token */ | 2030 | __le16 len; /* number of bytes starting from token */ |
2030 | u8 token; /* token id */ | 2031 | u8 token; /* token id */ |
2031 | u8 id; /* measurement id -- 0 or 1 */ | 2032 | u8 id; /* measurement id -- 0 or 1 */ |
2032 | u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ | 2033 | u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ |
2033 | u8 periodic; /* 1 = periodic */ | 2034 | u8 periodic; /* 1 = periodic */ |
2034 | __le16 path_loss_timeout; | 2035 | __le16 path_loss_timeout; |
2035 | __le32 start_time; /* start time in extended beacon format */ | 2036 | __le32 start_time; /* start time in extended beacon format */ |
2036 | __le32 reserved2; | 2037 | __le32 reserved2; |
2037 | __le32 flags; /* rxon flags */ | 2038 | __le32 flags; /* rxon flags */ |
2038 | __le32 filter_flags; /* rxon filter flags */ | 2039 | __le32 filter_flags; /* rxon filter flags */ |
2039 | __le16 channel_count; /* minimum 1, maximum 10 */ | 2040 | __le16 channel_count; /* minimum 1, maximum 10 */ |
2040 | __le16 reserved3; | 2041 | __le16 reserved3; |
2041 | struct iwl_measure_channel channels[10]; | 2042 | struct iwl_measure_channel channels[10]; |
2042 | } __packed; | 2043 | } __packed; |
2043 | 2044 | ||
2044 | /* | 2045 | /* |
2045 | * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) | 2046 | * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) |
2046 | */ | 2047 | */ |
2047 | struct iwl_spectrum_resp { | 2048 | struct iwl_spectrum_resp { |
2048 | u8 token; | 2049 | u8 token; |
2049 | u8 id; /* id of the prior command replaced, or 0xff */ | 2050 | u8 id; /* id of the prior command replaced, or 0xff */ |
2050 | __le16 status; /* 0 - command will be handled | 2051 | __le16 status; /* 0 - command will be handled |
2051 | * 1 - cannot handle (conflicts with another | 2052 | * 1 - cannot handle (conflicts with another |
2052 | * measurement) */ | 2053 | * measurement) */ |
2053 | } __packed; | 2054 | } __packed; |
2054 | 2055 | ||
2055 | enum iwl_measurement_state { | 2056 | enum iwl_measurement_state { |
2056 | IWL_MEASUREMENT_START = 0, | 2057 | IWL_MEASUREMENT_START = 0, |
2057 | IWL_MEASUREMENT_STOP = 1, | 2058 | IWL_MEASUREMENT_STOP = 1, |
2058 | }; | 2059 | }; |
2059 | 2060 | ||
2060 | enum iwl_measurement_status { | 2061 | enum iwl_measurement_status { |
2061 | IWL_MEASUREMENT_OK = 0, | 2062 | IWL_MEASUREMENT_OK = 0, |
2062 | IWL_MEASUREMENT_CONCURRENT = 1, | 2063 | IWL_MEASUREMENT_CONCURRENT = 1, |
2063 | IWL_MEASUREMENT_CSA_CONFLICT = 2, | 2064 | IWL_MEASUREMENT_CSA_CONFLICT = 2, |
2064 | IWL_MEASUREMENT_TGH_CONFLICT = 3, | 2065 | IWL_MEASUREMENT_TGH_CONFLICT = 3, |
2065 | /* 4-5 reserved */ | 2066 | /* 4-5 reserved */ |
2066 | IWL_MEASUREMENT_STOPPED = 6, | 2067 | IWL_MEASUREMENT_STOPPED = 6, |
2067 | IWL_MEASUREMENT_TIMEOUT = 7, | 2068 | IWL_MEASUREMENT_TIMEOUT = 7, |
2068 | IWL_MEASUREMENT_PERIODIC_FAILED = 8, | 2069 | IWL_MEASUREMENT_PERIODIC_FAILED = 8, |
2069 | }; | 2070 | }; |
2070 | 2071 | ||
2071 | #define NUM_ELEMENTS_IN_HISTOGRAM 8 | 2072 | #define NUM_ELEMENTS_IN_HISTOGRAM 8 |
2072 | 2073 | ||
2073 | struct iwl_measurement_histogram { | 2074 | struct iwl_measurement_histogram { |
2074 | __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ | 2075 | __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ |
2075 | __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ | 2076 | __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ |
2076 | } __packed; | 2077 | } __packed; |
2077 | 2078 | ||
2078 | /* clear channel availability counters */ | 2079 | /* clear channel availability counters */ |
2079 | struct iwl_measurement_cca_counters { | 2080 | struct iwl_measurement_cca_counters { |
2080 | __le32 ofdm; | 2081 | __le32 ofdm; |
2081 | __le32 cck; | 2082 | __le32 cck; |
2082 | } __packed; | 2083 | } __packed; |
2083 | 2084 | ||
2084 | enum iwl_measure_type { | 2085 | enum iwl_measure_type { |
2085 | IWL_MEASURE_BASIC = (1 << 0), | 2086 | IWL_MEASURE_BASIC = (1 << 0), |
2086 | IWL_MEASURE_CHANNEL_LOAD = (1 << 1), | 2087 | IWL_MEASURE_CHANNEL_LOAD = (1 << 1), |
2087 | IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), | 2088 | IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), |
2088 | IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), | 2089 | IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), |
2089 | IWL_MEASURE_FRAME = (1 << 4), | 2090 | IWL_MEASURE_FRAME = (1 << 4), |
2090 | /* bits 5:6 are reserved */ | 2091 | /* bits 5:6 are reserved */ |
2091 | IWL_MEASURE_IDLE = (1 << 7), | 2092 | IWL_MEASURE_IDLE = (1 << 7), |
2092 | }; | 2093 | }; |
2093 | 2094 | ||
2094 | /* | 2095 | /* |
2095 | * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) | 2096 | * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) |
2096 | */ | 2097 | */ |
2097 | struct iwl_spectrum_notification { | 2098 | struct iwl_spectrum_notification { |
2098 | u8 id; /* measurement id -- 0 or 1 */ | 2099 | u8 id; /* measurement id -- 0 or 1 */ |
2099 | u8 token; | 2100 | u8 token; |
2100 | u8 channel_index; /* index in measurement channel list */ | 2101 | u8 channel_index; /* index in measurement channel list */ |
2101 | u8 state; /* 0 - start, 1 - stop */ | 2102 | u8 state; /* 0 - start, 1 - stop */ |
2102 | __le32 start_time; /* lower 32-bits of TSF */ | 2103 | __le32 start_time; /* lower 32-bits of TSF */ |
2103 | u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ | 2104 | u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ |
2104 | u8 channel; | 2105 | u8 channel; |
2105 | u8 type; /* see enum iwl_measurement_type */ | 2106 | u8 type; /* see enum iwl_measurement_type */ |
2106 | u8 reserved1; | 2107 | u8 reserved1; |
2107 | /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only | 2108 | /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only |
2108 | * valid if applicable for measurement type requested. */ | 2109 | * valid if applicable for measurement type requested. */ |
2109 | __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ | 2110 | __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ |
2110 | __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ | 2111 | __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ |
2111 | __le32 cca_time; /* channel load time in usecs */ | 2112 | __le32 cca_time; /* channel load time in usecs */ |
2112 | u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - | 2113 | u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - |
2113 | * unidentified */ | 2114 | * unidentified */ |
2114 | u8 reserved2[3]; | 2115 | u8 reserved2[3]; |
2115 | struct iwl_measurement_histogram histogram; | 2116 | struct iwl_measurement_histogram histogram; |
2116 | __le32 stop_time; /* lower 32-bits of TSF */ | 2117 | __le32 stop_time; /* lower 32-bits of TSF */ |
2117 | __le32 status; /* see iwl_measurement_status */ | 2118 | __le32 status; /* see iwl_measurement_status */ |
2118 | } __packed; | 2119 | } __packed; |
2119 | 2120 | ||
2120 | /****************************************************************************** | 2121 | /****************************************************************************** |
2121 | * (7) | 2122 | * (7) |
2122 | * Power Management Commands, Responses, Notifications: | 2123 | * Power Management Commands, Responses, Notifications: |
2123 | * | 2124 | * |
2124 | *****************************************************************************/ | 2125 | *****************************************************************************/ |
2125 | 2126 | ||
2126 | /** | 2127 | /** |
2127 | * struct iwl_powertable_cmd - Power Table Command | 2128 | * struct iwl_powertable_cmd - Power Table Command |
2128 | * @flags: See below: | 2129 | * @flags: See below: |
2129 | * | 2130 | * |
2130 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) | 2131 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) |
2131 | * | 2132 | * |
2132 | * PM allow: | 2133 | * PM allow: |
2133 | * bit 0 - '0' Driver not allow power management | 2134 | * bit 0 - '0' Driver not allow power management |
2134 | * '1' Driver allow PM (use rest of parameters) | 2135 | * '1' Driver allow PM (use rest of parameters) |
2135 | * | 2136 | * |
2136 | * uCode send sleep notifications: | 2137 | * uCode send sleep notifications: |
2137 | * bit 1 - '0' Don't send sleep notification | 2138 | * bit 1 - '0' Don't send sleep notification |
2138 | * '1' send sleep notification (SEND_PM_NOTIFICATION) | 2139 | * '1' send sleep notification (SEND_PM_NOTIFICATION) |
2139 | * | 2140 | * |
2140 | * Sleep over DTIM | 2141 | * Sleep over DTIM |
2141 | * bit 2 - '0' PM have to walk up every DTIM | 2142 | * bit 2 - '0' PM have to walk up every DTIM |
2142 | * '1' PM could sleep over DTIM till listen Interval. | 2143 | * '1' PM could sleep over DTIM till listen Interval. |
2143 | * | 2144 | * |
2144 | * PCI power managed | 2145 | * PCI power managed |
2145 | * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1) | 2146 | * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1) |
2146 | * '1' !(PCI_CFG_LINK_CTRL & 0x1) | 2147 | * '1' !(PCI_CFG_LINK_CTRL & 0x1) |
2147 | * | 2148 | * |
2148 | * Fast PD | 2149 | * Fast PD |
2149 | * bit 4 - '1' Put radio to sleep when receiving frame for others | 2150 | * bit 4 - '1' Put radio to sleep when receiving frame for others |
2150 | * | 2151 | * |
2151 | * Force sleep Modes | 2152 | * Force sleep Modes |
2152 | * bit 31/30- '00' use both mac/xtal sleeps | 2153 | * bit 31/30- '00' use both mac/xtal sleeps |
2153 | * '01' force Mac sleep | 2154 | * '01' force Mac sleep |
2154 | * '10' force xtal sleep | 2155 | * '10' force xtal sleep |
2155 | * '11' Illegal set | 2156 | * '11' Illegal set |
2156 | * | 2157 | * |
2157 | * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then | 2158 | * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then |
2158 | * ucode assume sleep over DTIM is allowed and we don't need to wake up | 2159 | * ucode assume sleep over DTIM is allowed and we don't need to wake up |
2159 | * for every DTIM. | 2160 | * for every DTIM. |
2160 | */ | 2161 | */ |
2161 | #define IWL_POWER_VEC_SIZE 5 | 2162 | #define IWL_POWER_VEC_SIZE 5 |
2162 | 2163 | ||
2163 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) | 2164 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) |
2164 | #define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) | 2165 | #define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) |
2165 | #define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) | 2166 | #define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) |
2166 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) | 2167 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) |
2167 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) | 2168 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) |
2168 | #define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) | 2169 | #define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) |
2169 | #define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) | 2170 | #define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) |
2170 | #define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) | 2171 | #define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) |
2171 | #define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) | 2172 | #define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) |
2172 | #define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8)) | 2173 | #define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8)) |
2173 | #define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9)) | 2174 | #define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9)) |
2174 | 2175 | ||
2175 | struct iwl_powertable_cmd { | 2176 | struct iwl_powertable_cmd { |
2176 | __le16 flags; | 2177 | __le16 flags; |
2177 | u8 keep_alive_seconds; | 2178 | u8 keep_alive_seconds; |
2178 | u8 debug_flags; | 2179 | u8 debug_flags; |
2179 | __le32 rx_data_timeout; | 2180 | __le32 rx_data_timeout; |
2180 | __le32 tx_data_timeout; | 2181 | __le32 tx_data_timeout; |
2181 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; | 2182 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; |
2182 | __le32 keep_alive_beacons; | 2183 | __le32 keep_alive_beacons; |
2183 | } __packed; | 2184 | } __packed; |
2184 | 2185 | ||
2185 | /* | 2186 | /* |
2186 | * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) | 2187 | * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) |
2187 | * all devices identical. | 2188 | * all devices identical. |
2188 | */ | 2189 | */ |
2189 | struct iwl_sleep_notification { | 2190 | struct iwl_sleep_notification { |
2190 | u8 pm_sleep_mode; | 2191 | u8 pm_sleep_mode; |
2191 | u8 pm_wakeup_src; | 2192 | u8 pm_wakeup_src; |
2192 | __le16 reserved; | 2193 | __le16 reserved; |
2193 | __le32 sleep_time; | 2194 | __le32 sleep_time; |
2194 | __le32 tsf_low; | 2195 | __le32 tsf_low; |
2195 | __le32 bcon_timer; | 2196 | __le32 bcon_timer; |
2196 | } __packed; | 2197 | } __packed; |
2197 | 2198 | ||
2198 | /* Sleep states. all devices identical. */ | 2199 | /* Sleep states. all devices identical. */ |
2199 | enum { | 2200 | enum { |
2200 | IWL_PM_NO_SLEEP = 0, | 2201 | IWL_PM_NO_SLEEP = 0, |
2201 | IWL_PM_SLP_MAC = 1, | 2202 | IWL_PM_SLP_MAC = 1, |
2202 | IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, | 2203 | IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, |
2203 | IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, | 2204 | IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, |
2204 | IWL_PM_SLP_PHY = 4, | 2205 | IWL_PM_SLP_PHY = 4, |
2205 | IWL_PM_SLP_REPENT = 5, | 2206 | IWL_PM_SLP_REPENT = 5, |
2206 | IWL_PM_WAKEUP_BY_TIMER = 6, | 2207 | IWL_PM_WAKEUP_BY_TIMER = 6, |
2207 | IWL_PM_WAKEUP_BY_DRIVER = 7, | 2208 | IWL_PM_WAKEUP_BY_DRIVER = 7, |
2208 | IWL_PM_WAKEUP_BY_RFKILL = 8, | 2209 | IWL_PM_WAKEUP_BY_RFKILL = 8, |
2209 | /* 3 reserved */ | 2210 | /* 3 reserved */ |
2210 | IWL_PM_NUM_OF_MODES = 12, | 2211 | IWL_PM_NUM_OF_MODES = 12, |
2211 | }; | 2212 | }; |
2212 | 2213 | ||
2213 | /* | 2214 | /* |
2214 | * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response) | 2215 | * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response) |
2215 | */ | 2216 | */ |
2216 | #define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */ | 2217 | #define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */ |
2217 | #define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */ | 2218 | #define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */ |
2218 | #define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ | 2219 | #define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ |
2219 | struct iwl_card_state_cmd { | 2220 | struct iwl_card_state_cmd { |
2220 | __le32 status; /* CARD_STATE_CMD_* request new power state */ | 2221 | __le32 status; /* CARD_STATE_CMD_* request new power state */ |
2221 | } __packed; | 2222 | } __packed; |
2222 | 2223 | ||
2223 | /* | 2224 | /* |
2224 | * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) | 2225 | * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) |
2225 | */ | 2226 | */ |
2226 | struct iwl_card_state_notif { | 2227 | struct iwl_card_state_notif { |
2227 | __le32 flags; | 2228 | __le32 flags; |
2228 | } __packed; | 2229 | } __packed; |
2229 | 2230 | ||
2230 | #define HW_CARD_DISABLED 0x01 | 2231 | #define HW_CARD_DISABLED 0x01 |
2231 | #define SW_CARD_DISABLED 0x02 | 2232 | #define SW_CARD_DISABLED 0x02 |
2232 | #define CT_CARD_DISABLED 0x04 | 2233 | #define CT_CARD_DISABLED 0x04 |
2233 | #define RXON_CARD_DISABLED 0x10 | 2234 | #define RXON_CARD_DISABLED 0x10 |
2234 | 2235 | ||
2235 | struct iwl_ct_kill_config { | 2236 | struct iwl_ct_kill_config { |
2236 | __le32 reserved; | 2237 | __le32 reserved; |
2237 | __le32 critical_temperature_M; | 2238 | __le32 critical_temperature_M; |
2238 | __le32 critical_temperature_R; | 2239 | __le32 critical_temperature_R; |
2239 | } __packed; | 2240 | } __packed; |
2240 | 2241 | ||
2241 | /* 1000, and 6x00 */ | 2242 | /* 1000, and 6x00 */ |
2242 | struct iwl_ct_kill_throttling_config { | 2243 | struct iwl_ct_kill_throttling_config { |
2243 | __le32 critical_temperature_exit; | 2244 | __le32 critical_temperature_exit; |
2244 | __le32 reserved; | 2245 | __le32 reserved; |
2245 | __le32 critical_temperature_enter; | 2246 | __le32 critical_temperature_enter; |
2246 | } __packed; | 2247 | } __packed; |
2247 | 2248 | ||
2248 | /****************************************************************************** | 2249 | /****************************************************************************** |
2249 | * (8) | 2250 | * (8) |
2250 | * Scan Commands, Responses, Notifications: | 2251 | * Scan Commands, Responses, Notifications: |
2251 | * | 2252 | * |
2252 | *****************************************************************************/ | 2253 | *****************************************************************************/ |
2253 | 2254 | ||
2254 | #define SCAN_CHANNEL_TYPE_PASSIVE cpu_to_le32(0) | 2255 | #define SCAN_CHANNEL_TYPE_PASSIVE cpu_to_le32(0) |
2255 | #define SCAN_CHANNEL_TYPE_ACTIVE cpu_to_le32(1) | 2256 | #define SCAN_CHANNEL_TYPE_ACTIVE cpu_to_le32(1) |
2256 | 2257 | ||
2257 | /** | 2258 | /** |
2258 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table | 2259 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table |
2259 | * | 2260 | * |
2260 | * One for each channel in the scan list. | 2261 | * One for each channel in the scan list. |
2261 | * Each channel can independently select: | 2262 | * Each channel can independently select: |
2262 | * 1) SSID for directed active scans | 2263 | * 1) SSID for directed active scans |
2263 | * 2) Txpower setting (for rate specified within Tx command) | 2264 | * 2) Txpower setting (for rate specified within Tx command) |
2264 | * 3) How long to stay on-channel (behavior may be modified by quiet_time, | 2265 | * 3) How long to stay on-channel (behavior may be modified by quiet_time, |
2265 | * quiet_plcp_th, good_CRC_th) | 2266 | * quiet_plcp_th, good_CRC_th) |
2266 | * | 2267 | * |
2267 | * To avoid uCode errors, make sure the following are true (see comments | 2268 | * To avoid uCode errors, make sure the following are true (see comments |
2268 | * under struct iwl_scan_cmd about max_out_time and quiet_time): | 2269 | * under struct iwl_scan_cmd about max_out_time and quiet_time): |
2269 | * 1) If using passive_dwell (i.e. passive_dwell != 0): | 2270 | * 1) If using passive_dwell (i.e. passive_dwell != 0): |
2270 | * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) | 2271 | * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) |
2271 | * 2) quiet_time <= active_dwell | 2272 | * 2) quiet_time <= active_dwell |
2272 | * 3) If restricting off-channel time (i.e. max_out_time !=0): | 2273 | * 3) If restricting off-channel time (i.e. max_out_time !=0): |
2273 | * passive_dwell < max_out_time | 2274 | * passive_dwell < max_out_time |
2274 | * active_dwell < max_out_time | 2275 | * active_dwell < max_out_time |
2275 | */ | 2276 | */ |
2276 | 2277 | ||
2277 | struct iwl_scan_channel { | 2278 | struct iwl_scan_channel { |
2278 | /* | 2279 | /* |
2279 | * type is defined as: | 2280 | * type is defined as: |
2280 | * 0:0 1 = active, 0 = passive | 2281 | * 0:0 1 = active, 0 = passive |
2281 | * 1:20 SSID direct bit map; if a bit is set, then corresponding | 2282 | * 1:20 SSID direct bit map; if a bit is set, then corresponding |
2282 | * SSID IE is transmitted in probe request. | 2283 | * SSID IE is transmitted in probe request. |
2283 | * 21:31 reserved | 2284 | * 21:31 reserved |
2284 | */ | 2285 | */ |
2285 | __le32 type; | 2286 | __le32 type; |
2286 | __le16 channel; /* band is selected by iwl_scan_cmd "flags" field */ | 2287 | __le16 channel; /* band is selected by iwl_scan_cmd "flags" field */ |
2287 | u8 tx_gain; /* gain for analog radio */ | 2288 | u8 tx_gain; /* gain for analog radio */ |
2288 | u8 dsp_atten; /* gain for DSP */ | 2289 | u8 dsp_atten; /* gain for DSP */ |
2289 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ | 2290 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ |
2290 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ | 2291 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ |
2291 | } __packed; | 2292 | } __packed; |
2292 | 2293 | ||
2293 | /* set number of direct probes __le32 type */ | 2294 | /* set number of direct probes __le32 type */ |
2294 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) | 2295 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) |
2295 | 2296 | ||
2296 | /** | 2297 | /** |
2297 | * struct iwl_ssid_ie - directed scan network information element | 2298 | * struct iwl_ssid_ie - directed scan network information element |
2298 | * | 2299 | * |
2299 | * Up to 20 of these may appear in REPLY_SCAN_CMD, | 2300 | * Up to 20 of these may appear in REPLY_SCAN_CMD, |
2300 | * selected by "type" bit field in struct iwl_scan_channel; | 2301 | * selected by "type" bit field in struct iwl_scan_channel; |
2301 | * each channel may select different ssids from among the 20 entries. | 2302 | * each channel may select different ssids from among the 20 entries. |
2302 | * SSID IEs get transmitted in reverse order of entry. | 2303 | * SSID IEs get transmitted in reverse order of entry. |
2303 | */ | 2304 | */ |
2304 | struct iwl_ssid_ie { | 2305 | struct iwl_ssid_ie { |
2305 | u8 id; | 2306 | u8 id; |
2306 | u8 len; | 2307 | u8 len; |
2307 | u8 ssid[32]; | 2308 | u8 ssid[32]; |
2308 | } __packed; | 2309 | } __packed; |
2309 | 2310 | ||
2310 | #define PROBE_OPTION_MAX 20 | 2311 | #define PROBE_OPTION_MAX 20 |
2311 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) | 2312 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) |
2312 | #define IWL_GOOD_CRC_TH_DISABLED 0 | 2313 | #define IWL_GOOD_CRC_TH_DISABLED 0 |
2313 | #define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) | 2314 | #define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) |
2314 | #define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) | 2315 | #define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) |
2315 | #define IWL_MAX_CMD_SIZE 4096 | 2316 | #define IWL_MAX_CMD_SIZE 4096 |
2316 | 2317 | ||
2317 | /* | 2318 | /* |
2318 | * REPLY_SCAN_CMD = 0x80 (command) | 2319 | * REPLY_SCAN_CMD = 0x80 (command) |
2319 | * | 2320 | * |
2320 | * The hardware scan command is very powerful; the driver can set it up to | 2321 | * The hardware scan command is very powerful; the driver can set it up to |
2321 | * maintain (relatively) normal network traffic while doing a scan in the | 2322 | * maintain (relatively) normal network traffic while doing a scan in the |
2322 | * background. The max_out_time and suspend_time control the ratio of how | 2323 | * background. The max_out_time and suspend_time control the ratio of how |
2323 | * long the device stays on an associated network channel ("service channel") | 2324 | * long the device stays on an associated network channel ("service channel") |
2324 | * vs. how long it's away from the service channel, i.e. tuned to other channels | 2325 | * vs. how long it's away from the service channel, i.e. tuned to other channels |
2325 | * for scanning. | 2326 | * for scanning. |
2326 | * | 2327 | * |
2327 | * max_out_time is the max time off-channel (in usec), and suspend_time | 2328 | * max_out_time is the max time off-channel (in usec), and suspend_time |
2328 | * is how long (in "extended beacon" format) that the scan is "suspended" | 2329 | * is how long (in "extended beacon" format) that the scan is "suspended" |
2329 | * after returning to the service channel. That is, suspend_time is the | 2330 | * after returning to the service channel. That is, suspend_time is the |
2330 | * time that we stay on the service channel, doing normal work, between | 2331 | * time that we stay on the service channel, doing normal work, between |
2331 | * scan segments. The driver may set these parameters differently to support | 2332 | * scan segments. The driver may set these parameters differently to support |
2332 | * scanning when associated vs. not associated, and light vs. heavy traffic | 2333 | * scanning when associated vs. not associated, and light vs. heavy traffic |
2333 | * loads when associated. | 2334 | * loads when associated. |
2334 | * | 2335 | * |
2335 | * After receiving this command, the device's scan engine does the following; | 2336 | * After receiving this command, the device's scan engine does the following; |
2336 | * | 2337 | * |
2337 | * 1) Sends SCAN_START notification to driver | 2338 | * 1) Sends SCAN_START notification to driver |
2338 | * 2) Checks to see if it has time to do scan for one channel | 2339 | * 2) Checks to see if it has time to do scan for one channel |
2339 | * 3) Sends NULL packet, with power-save (PS) bit set to 1, | 2340 | * 3) Sends NULL packet, with power-save (PS) bit set to 1, |
2340 | * to tell AP that we're going off-channel | 2341 | * to tell AP that we're going off-channel |
2341 | * 4) Tunes to first channel in scan list, does active or passive scan | 2342 | * 4) Tunes to first channel in scan list, does active or passive scan |
2342 | * 5) Sends SCAN_RESULT notification to driver | 2343 | * 5) Sends SCAN_RESULT notification to driver |
2343 | * 6) Checks to see if it has time to do scan on *next* channel in list | 2344 | * 6) Checks to see if it has time to do scan on *next* channel in list |
2344 | * 7) Repeats 4-6 until it no longer has time to scan the next channel | 2345 | * 7) Repeats 4-6 until it no longer has time to scan the next channel |
2345 | * before max_out_time expires | 2346 | * before max_out_time expires |
2346 | * 8) Returns to service channel | 2347 | * 8) Returns to service channel |
2347 | * 9) Sends NULL packet with PS=0 to tell AP that we're back | 2348 | * 9) Sends NULL packet with PS=0 to tell AP that we're back |
2348 | * 10) Stays on service channel until suspend_time expires | 2349 | * 10) Stays on service channel until suspend_time expires |
2349 | * 11) Repeats entire process 2-10 until list is complete | 2350 | * 11) Repeats entire process 2-10 until list is complete |
2350 | * 12) Sends SCAN_COMPLETE notification | 2351 | * 12) Sends SCAN_COMPLETE notification |
2351 | * | 2352 | * |
2352 | * For fast, efficient scans, the scan command also has support for staying on | 2353 | * For fast, efficient scans, the scan command also has support for staying on |
2353 | * a channel for just a short time, if doing active scanning and getting no | 2354 | * a channel for just a short time, if doing active scanning and getting no |
2354 | * responses to the transmitted probe request. This time is controlled by | 2355 | * responses to the transmitted probe request. This time is controlled by |
2355 | * quiet_time, and the number of received packets below which a channel is | 2356 | * quiet_time, and the number of received packets below which a channel is |
2356 | * considered "quiet" is controlled by quiet_plcp_threshold. | 2357 | * considered "quiet" is controlled by quiet_plcp_threshold. |
2357 | * | 2358 | * |
2358 | * For active scanning on channels that have regulatory restrictions against | 2359 | * For active scanning on channels that have regulatory restrictions against |
2359 | * blindly transmitting, the scan can listen before transmitting, to make sure | 2360 | * blindly transmitting, the scan can listen before transmitting, to make sure |
2360 | * that there is already legitimate activity on the channel. If enough | 2361 | * that there is already legitimate activity on the channel. If enough |
2361 | * packets are cleanly received on the channel (controlled by good_CRC_th, | 2362 | * packets are cleanly received on the channel (controlled by good_CRC_th, |
2362 | * typical value 1), the scan engine starts transmitting probe requests. | 2363 | * typical value 1), the scan engine starts transmitting probe requests. |
2363 | * | 2364 | * |
2364 | * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. | 2365 | * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. |
2365 | * | 2366 | * |
2366 | * To avoid uCode errors, see timing restrictions described under | 2367 | * To avoid uCode errors, see timing restrictions described under |
2367 | * struct iwl_scan_channel. | 2368 | * struct iwl_scan_channel. |
2368 | */ | 2369 | */ |
2369 | 2370 | ||
2370 | enum iwl_scan_flags { | 2371 | enum iwl_scan_flags { |
2371 | /* BIT(0) currently unused */ | 2372 | /* BIT(0) currently unused */ |
2372 | IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1), | 2373 | IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1), |
2373 | /* bits 2-7 reserved */ | 2374 | /* bits 2-7 reserved */ |
2374 | }; | 2375 | }; |
2375 | 2376 | ||
2376 | struct iwl_scan_cmd { | 2377 | struct iwl_scan_cmd { |
2377 | __le16 len; | 2378 | __le16 len; |
2378 | u8 scan_flags; /* scan flags: see enum iwl_scan_flags */ | 2379 | u8 scan_flags; /* scan flags: see enum iwl_scan_flags */ |
2379 | u8 channel_count; /* # channels in channel list */ | 2380 | u8 channel_count; /* # channels in channel list */ |
2380 | __le16 quiet_time; /* dwell only this # millisecs on quiet channel | 2381 | __le16 quiet_time; /* dwell only this # millisecs on quiet channel |
2381 | * (only for active scan) */ | 2382 | * (only for active scan) */ |
2382 | __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ | 2383 | __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ |
2383 | __le16 good_CRC_th; /* passive -> active promotion threshold */ | 2384 | __le16 good_CRC_th; /* passive -> active promotion threshold */ |
2384 | __le16 rx_chain; /* RXON_RX_CHAIN_* */ | 2385 | __le16 rx_chain; /* RXON_RX_CHAIN_* */ |
2385 | __le32 max_out_time; /* max usec to be away from associated (service) | 2386 | __le32 max_out_time; /* max usec to be away from associated (service) |
2386 | * channel */ | 2387 | * channel */ |
2387 | __le32 suspend_time; /* pause scan this long (in "extended beacon | 2388 | __le32 suspend_time; /* pause scan this long (in "extended beacon |
2388 | * format") when returning to service chnl: | 2389 | * format") when returning to service chnl: |
2389 | */ | 2390 | */ |
2390 | __le32 flags; /* RXON_FLG_* */ | 2391 | __le32 flags; /* RXON_FLG_* */ |
2391 | __le32 filter_flags; /* RXON_FILTER_* */ | 2392 | __le32 filter_flags; /* RXON_FILTER_* */ |
2392 | 2393 | ||
2393 | /* For active scans (set to all-0s for passive scans). | 2394 | /* For active scans (set to all-0s for passive scans). |
2394 | * Does not include payload. Must specify Tx rate; no rate scaling. */ | 2395 | * Does not include payload. Must specify Tx rate; no rate scaling. */ |
2395 | struct iwl_tx_cmd tx_cmd; | 2396 | struct iwl_tx_cmd tx_cmd; |
2396 | 2397 | ||
2397 | /* For directed active scans (set to all-0s otherwise) */ | 2398 | /* For directed active scans (set to all-0s otherwise) */ |
2398 | struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; | 2399 | struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; |
2399 | 2400 | ||
2400 | /* | 2401 | /* |
2401 | * Probe request frame, followed by channel list. | 2402 | * Probe request frame, followed by channel list. |
2402 | * | 2403 | * |
2403 | * Size of probe request frame is specified by byte count in tx_cmd. | 2404 | * Size of probe request frame is specified by byte count in tx_cmd. |
2404 | * Channel list follows immediately after probe request frame. | 2405 | * Channel list follows immediately after probe request frame. |
2405 | * Number of channels in list is specified by channel_count. | 2406 | * Number of channels in list is specified by channel_count. |
2406 | * Each channel in list is of type: | 2407 | * Each channel in list is of type: |
2407 | * | 2408 | * |
2408 | * struct iwl_scan_channel channels[0]; | 2409 | * struct iwl_scan_channel channels[0]; |
2409 | * | 2410 | * |
2410 | * NOTE: Only one band of channels can be scanned per pass. You | 2411 | * NOTE: Only one band of channels can be scanned per pass. You |
2411 | * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait | 2412 | * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait |
2412 | * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) | 2413 | * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) |
2413 | * before requesting another scan. | 2414 | * before requesting another scan. |
2414 | */ | 2415 | */ |
2415 | u8 data[0]; | 2416 | u8 data[0]; |
2416 | } __packed; | 2417 | } __packed; |
2417 | 2418 | ||
2418 | /* Can abort will notify by complete notification with abort status. */ | 2419 | /* Can abort will notify by complete notification with abort status. */ |
2419 | #define CAN_ABORT_STATUS cpu_to_le32(0x1) | 2420 | #define CAN_ABORT_STATUS cpu_to_le32(0x1) |
2420 | /* complete notification statuses */ | 2421 | /* complete notification statuses */ |
2421 | #define ABORT_STATUS 0x2 | 2422 | #define ABORT_STATUS 0x2 |
2422 | 2423 | ||
2423 | /* | 2424 | /* |
2424 | * REPLY_SCAN_CMD = 0x80 (response) | 2425 | * REPLY_SCAN_CMD = 0x80 (response) |
2425 | */ | 2426 | */ |
2426 | struct iwl_scanreq_notification { | 2427 | struct iwl_scanreq_notification { |
2427 | __le32 status; /* 1: okay, 2: cannot fulfill request */ | 2428 | __le32 status; /* 1: okay, 2: cannot fulfill request */ |
2428 | } __packed; | 2429 | } __packed; |
2429 | 2430 | ||
2430 | /* | 2431 | /* |
2431 | * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) | 2432 | * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) |
2432 | */ | 2433 | */ |
2433 | struct iwl_scanstart_notification { | 2434 | struct iwl_scanstart_notification { |
2434 | __le32 tsf_low; | 2435 | __le32 tsf_low; |
2435 | __le32 tsf_high; | 2436 | __le32 tsf_high; |
2436 | __le32 beacon_timer; | 2437 | __le32 beacon_timer; |
2437 | u8 channel; | 2438 | u8 channel; |
2438 | u8 band; | 2439 | u8 band; |
2439 | u8 reserved[2]; | 2440 | u8 reserved[2]; |
2440 | __le32 status; | 2441 | __le32 status; |
2441 | } __packed; | 2442 | } __packed; |
2442 | 2443 | ||
2443 | #define SCAN_OWNER_STATUS 0x1 | 2444 | #define SCAN_OWNER_STATUS 0x1 |
2444 | #define MEASURE_OWNER_STATUS 0x2 | 2445 | #define MEASURE_OWNER_STATUS 0x2 |
2445 | 2446 | ||
2446 | #define IWL_PROBE_STATUS_OK 0 | 2447 | #define IWL_PROBE_STATUS_OK 0 |
2447 | #define IWL_PROBE_STATUS_TX_FAILED BIT(0) | 2448 | #define IWL_PROBE_STATUS_TX_FAILED BIT(0) |
2448 | /* error statuses combined with TX_FAILED */ | 2449 | /* error statuses combined with TX_FAILED */ |
2449 | #define IWL_PROBE_STATUS_FAIL_TTL BIT(1) | 2450 | #define IWL_PROBE_STATUS_FAIL_TTL BIT(1) |
2450 | #define IWL_PROBE_STATUS_FAIL_BT BIT(2) | 2451 | #define IWL_PROBE_STATUS_FAIL_BT BIT(2) |
2451 | 2452 | ||
2452 | #define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ | 2453 | #define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ |
2453 | /* | 2454 | /* |
2454 | * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) | 2455 | * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) |
2455 | */ | 2456 | */ |
2456 | struct iwl_scanresults_notification { | 2457 | struct iwl_scanresults_notification { |
2457 | u8 channel; | 2458 | u8 channel; |
2458 | u8 band; | 2459 | u8 band; |
2459 | u8 probe_status; | 2460 | u8 probe_status; |
2460 | u8 num_probe_not_sent; /* not enough time to send */ | 2461 | u8 num_probe_not_sent; /* not enough time to send */ |
2461 | __le32 tsf_low; | 2462 | __le32 tsf_low; |
2462 | __le32 tsf_high; | 2463 | __le32 tsf_high; |
2463 | __le32 statistics[NUMBER_OF_STATISTICS]; | 2464 | __le32 statistics[NUMBER_OF_STATISTICS]; |
2464 | } __packed; | 2465 | } __packed; |
2465 | 2466 | ||
2466 | /* | 2467 | /* |
2467 | * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) | 2468 | * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) |
2468 | */ | 2469 | */ |
2469 | struct iwl_scancomplete_notification { | 2470 | struct iwl_scancomplete_notification { |
2470 | u8 scanned_channels; | 2471 | u8 scanned_channels; |
2471 | u8 status; | 2472 | u8 status; |
2472 | u8 bt_status; /* BT On/Off status */ | 2473 | u8 bt_status; /* BT On/Off status */ |
2473 | u8 last_channel; | 2474 | u8 last_channel; |
2474 | __le32 tsf_low; | 2475 | __le32 tsf_low; |
2475 | __le32 tsf_high; | 2476 | __le32 tsf_high; |
2476 | } __packed; | 2477 | } __packed; |
2477 | 2478 | ||
2478 | 2479 | ||
2479 | /****************************************************************************** | 2480 | /****************************************************************************** |
2480 | * (9) | 2481 | * (9) |
2481 | * IBSS/AP Commands and Notifications: | 2482 | * IBSS/AP Commands and Notifications: |
2482 | * | 2483 | * |
2483 | *****************************************************************************/ | 2484 | *****************************************************************************/ |
2484 | 2485 | ||
2485 | enum iwl_ibss_manager { | 2486 | enum iwl_ibss_manager { |
2486 | IWL_NOT_IBSS_MANAGER = 0, | 2487 | IWL_NOT_IBSS_MANAGER = 0, |
2487 | IWL_IBSS_MANAGER = 1, | 2488 | IWL_IBSS_MANAGER = 1, |
2488 | }; | 2489 | }; |
2489 | 2490 | ||
2490 | /* | 2491 | /* |
2491 | * BEACON_NOTIFICATION = 0x90 (notification only, not a command) | 2492 | * BEACON_NOTIFICATION = 0x90 (notification only, not a command) |
2492 | */ | 2493 | */ |
2493 | 2494 | ||
2494 | struct iwlagn_beacon_notif { | 2495 | struct iwlagn_beacon_notif { |
2495 | struct iwlagn_tx_resp beacon_notify_hdr; | 2496 | struct iwlagn_tx_resp beacon_notify_hdr; |
2496 | __le32 low_tsf; | 2497 | __le32 low_tsf; |
2497 | __le32 high_tsf; | 2498 | __le32 high_tsf; |
2498 | __le32 ibss_mgr_status; | 2499 | __le32 ibss_mgr_status; |
2499 | } __packed; | 2500 | } __packed; |
2500 | 2501 | ||
2501 | /* | 2502 | /* |
2502 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) | 2503 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) |
2503 | */ | 2504 | */ |
2504 | 2505 | ||
2505 | struct iwl_tx_beacon_cmd { | 2506 | struct iwl_tx_beacon_cmd { |
2506 | struct iwl_tx_cmd tx; | 2507 | struct iwl_tx_cmd tx; |
2507 | __le16 tim_idx; | 2508 | __le16 tim_idx; |
2508 | u8 tim_size; | 2509 | u8 tim_size; |
2509 | u8 reserved1; | 2510 | u8 reserved1; |
2510 | struct ieee80211_hdr frame[0]; /* beacon frame */ | 2511 | struct ieee80211_hdr frame[0]; /* beacon frame */ |
2511 | } __packed; | 2512 | } __packed; |
2512 | 2513 | ||
2513 | /****************************************************************************** | 2514 | /****************************************************************************** |
2514 | * (10) | 2515 | * (10) |
2515 | * Statistics Commands and Notifications: | 2516 | * Statistics Commands and Notifications: |
2516 | * | 2517 | * |
2517 | *****************************************************************************/ | 2518 | *****************************************************************************/ |
2518 | 2519 | ||
2519 | #define IWL_TEMP_CONVERT 260 | 2520 | #define IWL_TEMP_CONVERT 260 |
2520 | 2521 | ||
2521 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 | 2522 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 |
2522 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 | 2523 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 |
2523 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | 2524 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 |
2524 | 2525 | ||
2525 | /* Used for passing to driver number of successes and failures per rate */ | 2526 | /* Used for passing to driver number of successes and failures per rate */ |
2526 | struct rate_histogram { | 2527 | struct rate_histogram { |
2527 | union { | 2528 | union { |
2528 | __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; | 2529 | __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; |
2529 | __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; | 2530 | __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; |
2530 | __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; | 2531 | __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; |
2531 | } success; | 2532 | } success; |
2532 | union { | 2533 | union { |
2533 | __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; | 2534 | __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; |
2534 | __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; | 2535 | __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; |
2535 | __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; | 2536 | __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; |
2536 | } failed; | 2537 | } failed; |
2537 | } __packed; | 2538 | } __packed; |
2538 | 2539 | ||
2539 | /* statistics command response */ | 2540 | /* statistics command response */ |
2540 | 2541 | ||
2541 | struct statistics_dbg { | 2542 | struct statistics_dbg { |
2542 | __le32 burst_check; | 2543 | __le32 burst_check; |
2543 | __le32 burst_count; | 2544 | __le32 burst_count; |
2544 | __le32 wait_for_silence_timeout_cnt; | 2545 | __le32 wait_for_silence_timeout_cnt; |
2545 | __le32 reserved[3]; | 2546 | __le32 reserved[3]; |
2546 | } __packed; | 2547 | } __packed; |
2547 | 2548 | ||
2548 | struct statistics_rx_phy { | 2549 | struct statistics_rx_phy { |
2549 | __le32 ina_cnt; | 2550 | __le32 ina_cnt; |
2550 | __le32 fina_cnt; | 2551 | __le32 fina_cnt; |
2551 | __le32 plcp_err; | 2552 | __le32 plcp_err; |
2552 | __le32 crc32_err; | 2553 | __le32 crc32_err; |
2553 | __le32 overrun_err; | 2554 | __le32 overrun_err; |
2554 | __le32 early_overrun_err; | 2555 | __le32 early_overrun_err; |
2555 | __le32 crc32_good; | 2556 | __le32 crc32_good; |
2556 | __le32 false_alarm_cnt; | 2557 | __le32 false_alarm_cnt; |
2557 | __le32 fina_sync_err_cnt; | 2558 | __le32 fina_sync_err_cnt; |
2558 | __le32 sfd_timeout; | 2559 | __le32 sfd_timeout; |
2559 | __le32 fina_timeout; | 2560 | __le32 fina_timeout; |
2560 | __le32 unresponded_rts; | 2561 | __le32 unresponded_rts; |
2561 | __le32 rxe_frame_limit_overrun; | 2562 | __le32 rxe_frame_limit_overrun; |
2562 | __le32 sent_ack_cnt; | 2563 | __le32 sent_ack_cnt; |
2563 | __le32 sent_cts_cnt; | 2564 | __le32 sent_cts_cnt; |
2564 | __le32 sent_ba_rsp_cnt; | 2565 | __le32 sent_ba_rsp_cnt; |
2565 | __le32 dsp_self_kill; | 2566 | __le32 dsp_self_kill; |
2566 | __le32 mh_format_err; | 2567 | __le32 mh_format_err; |
2567 | __le32 re_acq_main_rssi_sum; | 2568 | __le32 re_acq_main_rssi_sum; |
2568 | __le32 reserved3; | 2569 | __le32 reserved3; |
2569 | } __packed; | 2570 | } __packed; |
2570 | 2571 | ||
2571 | struct statistics_rx_ht_phy { | 2572 | struct statistics_rx_ht_phy { |
2572 | __le32 plcp_err; | 2573 | __le32 plcp_err; |
2573 | __le32 overrun_err; | 2574 | __le32 overrun_err; |
2574 | __le32 early_overrun_err; | 2575 | __le32 early_overrun_err; |
2575 | __le32 crc32_good; | 2576 | __le32 crc32_good; |
2576 | __le32 crc32_err; | 2577 | __le32 crc32_err; |
2577 | __le32 mh_format_err; | 2578 | __le32 mh_format_err; |
2578 | __le32 agg_crc32_good; | 2579 | __le32 agg_crc32_good; |
2579 | __le32 agg_mpdu_cnt; | 2580 | __le32 agg_mpdu_cnt; |
2580 | __le32 agg_cnt; | 2581 | __le32 agg_cnt; |
2581 | __le32 unsupport_mcs; | 2582 | __le32 unsupport_mcs; |
2582 | } __packed; | 2583 | } __packed; |
2583 | 2584 | ||
2584 | #define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) | 2585 | #define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) |
2585 | 2586 | ||
2586 | struct statistics_rx_non_phy { | 2587 | struct statistics_rx_non_phy { |
2587 | __le32 bogus_cts; /* CTS received when not expecting CTS */ | 2588 | __le32 bogus_cts; /* CTS received when not expecting CTS */ |
2588 | __le32 bogus_ack; /* ACK received when not expecting ACK */ | 2589 | __le32 bogus_ack; /* ACK received when not expecting ACK */ |
2589 | __le32 non_bssid_frames; /* number of frames with BSSID that | 2590 | __le32 non_bssid_frames; /* number of frames with BSSID that |
2590 | * doesn't belong to the STA BSSID */ | 2591 | * doesn't belong to the STA BSSID */ |
2591 | __le32 filtered_frames; /* count frames that were dumped in the | 2592 | __le32 filtered_frames; /* count frames that were dumped in the |
2592 | * filtering process */ | 2593 | * filtering process */ |
2593 | __le32 non_channel_beacons; /* beacons with our bss id but not on | 2594 | __le32 non_channel_beacons; /* beacons with our bss id but not on |
2594 | * our serving channel */ | 2595 | * our serving channel */ |
2595 | __le32 channel_beacons; /* beacons with our bss id and in our | 2596 | __le32 channel_beacons; /* beacons with our bss id and in our |
2596 | * serving channel */ | 2597 | * serving channel */ |
2597 | __le32 num_missed_bcon; /* number of missed beacons */ | 2598 | __le32 num_missed_bcon; /* number of missed beacons */ |
2598 | __le32 adc_rx_saturation_time; /* count in 0.8us units the time the | 2599 | __le32 adc_rx_saturation_time; /* count in 0.8us units the time the |
2599 | * ADC was in saturation */ | 2600 | * ADC was in saturation */ |
2600 | __le32 ina_detection_search_time;/* total time (in 0.8us) searched | 2601 | __le32 ina_detection_search_time;/* total time (in 0.8us) searched |
2601 | * for INA */ | 2602 | * for INA */ |
2602 | __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ | 2603 | __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ |
2603 | __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ | 2604 | __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ |
2604 | __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ | 2605 | __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ |
2605 | __le32 interference_data_flag; /* flag for interference data | 2606 | __le32 interference_data_flag; /* flag for interference data |
2606 | * availability. 1 when data is | 2607 | * availability. 1 when data is |
2607 | * available. */ | 2608 | * available. */ |
2608 | __le32 channel_load; /* counts RX Enable time in uSec */ | 2609 | __le32 channel_load; /* counts RX Enable time in uSec */ |
2609 | __le32 dsp_false_alarms; /* DSP false alarm (both OFDM | 2610 | __le32 dsp_false_alarms; /* DSP false alarm (both OFDM |
2610 | * and CCK) counter */ | 2611 | * and CCK) counter */ |
2611 | __le32 beacon_rssi_a; | 2612 | __le32 beacon_rssi_a; |
2612 | __le32 beacon_rssi_b; | 2613 | __le32 beacon_rssi_b; |
2613 | __le32 beacon_rssi_c; | 2614 | __le32 beacon_rssi_c; |
2614 | __le32 beacon_energy_a; | 2615 | __le32 beacon_energy_a; |
2615 | __le32 beacon_energy_b; | 2616 | __le32 beacon_energy_b; |
2616 | __le32 beacon_energy_c; | 2617 | __le32 beacon_energy_c; |
2617 | } __packed; | 2618 | } __packed; |
2618 | 2619 | ||
2619 | struct statistics_rx_non_phy_bt { | 2620 | struct statistics_rx_non_phy_bt { |
2620 | struct statistics_rx_non_phy common; | 2621 | struct statistics_rx_non_phy common; |
2621 | /* additional stats for bt */ | 2622 | /* additional stats for bt */ |
2622 | __le32 num_bt_kills; | 2623 | __le32 num_bt_kills; |
2623 | __le32 reserved[2]; | 2624 | __le32 reserved[2]; |
2624 | } __packed; | 2625 | } __packed; |
2625 | 2626 | ||
2626 | struct statistics_rx { | 2627 | struct statistics_rx { |
2627 | struct statistics_rx_phy ofdm; | 2628 | struct statistics_rx_phy ofdm; |
2628 | struct statistics_rx_phy cck; | 2629 | struct statistics_rx_phy cck; |
2629 | struct statistics_rx_non_phy general; | 2630 | struct statistics_rx_non_phy general; |
2630 | struct statistics_rx_ht_phy ofdm_ht; | 2631 | struct statistics_rx_ht_phy ofdm_ht; |
2631 | } __packed; | 2632 | } __packed; |
2632 | 2633 | ||
2633 | struct statistics_rx_bt { | 2634 | struct statistics_rx_bt { |
2634 | struct statistics_rx_phy ofdm; | 2635 | struct statistics_rx_phy ofdm; |
2635 | struct statistics_rx_phy cck; | 2636 | struct statistics_rx_phy cck; |
2636 | struct statistics_rx_non_phy_bt general; | 2637 | struct statistics_rx_non_phy_bt general; |
2637 | struct statistics_rx_ht_phy ofdm_ht; | 2638 | struct statistics_rx_ht_phy ofdm_ht; |
2638 | } __packed; | 2639 | } __packed; |
2639 | 2640 | ||
2640 | /** | 2641 | /** |
2641 | * struct statistics_tx_power - current tx power | 2642 | * struct statistics_tx_power - current tx power |
2642 | * | 2643 | * |
2643 | * @ant_a: current tx power on chain a in 1/2 dB step | 2644 | * @ant_a: current tx power on chain a in 1/2 dB step |
2644 | * @ant_b: current tx power on chain b in 1/2 dB step | 2645 | * @ant_b: current tx power on chain b in 1/2 dB step |
2645 | * @ant_c: current tx power on chain c in 1/2 dB step | 2646 | * @ant_c: current tx power on chain c in 1/2 dB step |
2646 | */ | 2647 | */ |
2647 | struct statistics_tx_power { | 2648 | struct statistics_tx_power { |
2648 | u8 ant_a; | 2649 | u8 ant_a; |
2649 | u8 ant_b; | 2650 | u8 ant_b; |
2650 | u8 ant_c; | 2651 | u8 ant_c; |
2651 | u8 reserved; | 2652 | u8 reserved; |
2652 | } __packed; | 2653 | } __packed; |
2653 | 2654 | ||
2654 | struct statistics_tx_non_phy_agg { | 2655 | struct statistics_tx_non_phy_agg { |
2655 | __le32 ba_timeout; | 2656 | __le32 ba_timeout; |
2656 | __le32 ba_reschedule_frames; | 2657 | __le32 ba_reschedule_frames; |
2657 | __le32 scd_query_agg_frame_cnt; | 2658 | __le32 scd_query_agg_frame_cnt; |
2658 | __le32 scd_query_no_agg; | 2659 | __le32 scd_query_no_agg; |
2659 | __le32 scd_query_agg; | 2660 | __le32 scd_query_agg; |
2660 | __le32 scd_query_mismatch; | 2661 | __le32 scd_query_mismatch; |
2661 | __le32 frame_not_ready; | 2662 | __le32 frame_not_ready; |
2662 | __le32 underrun; | 2663 | __le32 underrun; |
2663 | __le32 bt_prio_kill; | 2664 | __le32 bt_prio_kill; |
2664 | __le32 rx_ba_rsp_cnt; | 2665 | __le32 rx_ba_rsp_cnt; |
2665 | } __packed; | 2666 | } __packed; |
2666 | 2667 | ||
2667 | struct statistics_tx { | 2668 | struct statistics_tx { |
2668 | __le32 preamble_cnt; | 2669 | __le32 preamble_cnt; |
2669 | __le32 rx_detected_cnt; | 2670 | __le32 rx_detected_cnt; |
2670 | __le32 bt_prio_defer_cnt; | 2671 | __le32 bt_prio_defer_cnt; |
2671 | __le32 bt_prio_kill_cnt; | 2672 | __le32 bt_prio_kill_cnt; |
2672 | __le32 few_bytes_cnt; | 2673 | __le32 few_bytes_cnt; |
2673 | __le32 cts_timeout; | 2674 | __le32 cts_timeout; |
2674 | __le32 ack_timeout; | 2675 | __le32 ack_timeout; |
2675 | __le32 expected_ack_cnt; | 2676 | __le32 expected_ack_cnt; |
2676 | __le32 actual_ack_cnt; | 2677 | __le32 actual_ack_cnt; |
2677 | __le32 dump_msdu_cnt; | 2678 | __le32 dump_msdu_cnt; |
2678 | __le32 burst_abort_next_frame_mismatch_cnt; | 2679 | __le32 burst_abort_next_frame_mismatch_cnt; |
2679 | __le32 burst_abort_missing_next_frame_cnt; | 2680 | __le32 burst_abort_missing_next_frame_cnt; |
2680 | __le32 cts_timeout_collision; | 2681 | __le32 cts_timeout_collision; |
2681 | __le32 ack_or_ba_timeout_collision; | 2682 | __le32 ack_or_ba_timeout_collision; |
2682 | struct statistics_tx_non_phy_agg agg; | 2683 | struct statistics_tx_non_phy_agg agg; |
2683 | /* | 2684 | /* |
2684 | * "tx_power" are optional parameters provided by uCode, | 2685 | * "tx_power" are optional parameters provided by uCode, |
2685 | * 6000 series is the only device provide the information, | 2686 | * 6000 series is the only device provide the information, |
2686 | * Those are reserved fields for all the other devices | 2687 | * Those are reserved fields for all the other devices |
2687 | */ | 2688 | */ |
2688 | struct statistics_tx_power tx_power; | 2689 | struct statistics_tx_power tx_power; |
2689 | __le32 reserved1; | 2690 | __le32 reserved1; |
2690 | } __packed; | 2691 | } __packed; |
2691 | 2692 | ||
2692 | 2693 | ||
2693 | struct statistics_div { | 2694 | struct statistics_div { |
2694 | __le32 tx_on_a; | 2695 | __le32 tx_on_a; |
2695 | __le32 tx_on_b; | 2696 | __le32 tx_on_b; |
2696 | __le32 exec_time; | 2697 | __le32 exec_time; |
2697 | __le32 probe_time; | 2698 | __le32 probe_time; |
2698 | __le32 reserved1; | 2699 | __le32 reserved1; |
2699 | __le32 reserved2; | 2700 | __le32 reserved2; |
2700 | } __packed; | 2701 | } __packed; |
2701 | 2702 | ||
2702 | struct statistics_general_common { | 2703 | struct statistics_general_common { |
2703 | __le32 temperature; /* radio temperature */ | 2704 | __le32 temperature; /* radio temperature */ |
2704 | __le32 temperature_m; /* radio voltage */ | 2705 | __le32 temperature_m; /* radio voltage */ |
2705 | struct statistics_dbg dbg; | 2706 | struct statistics_dbg dbg; |
2706 | __le32 sleep_time; | 2707 | __le32 sleep_time; |
2707 | __le32 slots_out; | 2708 | __le32 slots_out; |
2708 | __le32 slots_idle; | 2709 | __le32 slots_idle; |
2709 | __le32 ttl_timestamp; | 2710 | __le32 ttl_timestamp; |
2710 | struct statistics_div div; | 2711 | struct statistics_div div; |
2711 | __le32 rx_enable_counter; | 2712 | __le32 rx_enable_counter; |
2712 | /* | 2713 | /* |
2713 | * num_of_sos_states: | 2714 | * num_of_sos_states: |
2714 | * count the number of times we have to re-tune | 2715 | * count the number of times we have to re-tune |
2715 | * in order to get out of bad PHY status | 2716 | * in order to get out of bad PHY status |
2716 | */ | 2717 | */ |
2717 | __le32 num_of_sos_states; | 2718 | __le32 num_of_sos_states; |
2718 | } __packed; | 2719 | } __packed; |
2719 | 2720 | ||
2720 | struct statistics_bt_activity { | 2721 | struct statistics_bt_activity { |
2721 | /* Tx statistics */ | 2722 | /* Tx statistics */ |
2722 | __le32 hi_priority_tx_req_cnt; | 2723 | __le32 hi_priority_tx_req_cnt; |
2723 | __le32 hi_priority_tx_denied_cnt; | 2724 | __le32 hi_priority_tx_denied_cnt; |
2724 | __le32 lo_priority_tx_req_cnt; | 2725 | __le32 lo_priority_tx_req_cnt; |
2725 | __le32 lo_priority_tx_denied_cnt; | 2726 | __le32 lo_priority_tx_denied_cnt; |
2726 | /* Rx statistics */ | 2727 | /* Rx statistics */ |
2727 | __le32 hi_priority_rx_req_cnt; | 2728 | __le32 hi_priority_rx_req_cnt; |
2728 | __le32 hi_priority_rx_denied_cnt; | 2729 | __le32 hi_priority_rx_denied_cnt; |
2729 | __le32 lo_priority_rx_req_cnt; | 2730 | __le32 lo_priority_rx_req_cnt; |
2730 | __le32 lo_priority_rx_denied_cnt; | 2731 | __le32 lo_priority_rx_denied_cnt; |
2731 | } __packed; | 2732 | } __packed; |
2732 | 2733 | ||
2733 | struct statistics_general { | 2734 | struct statistics_general { |
2734 | struct statistics_general_common common; | 2735 | struct statistics_general_common common; |
2735 | __le32 reserved2; | 2736 | __le32 reserved2; |
2736 | __le32 reserved3; | 2737 | __le32 reserved3; |
2737 | } __packed; | 2738 | } __packed; |
2738 | 2739 | ||
2739 | struct statistics_general_bt { | 2740 | struct statistics_general_bt { |
2740 | struct statistics_general_common common; | 2741 | struct statistics_general_common common; |
2741 | struct statistics_bt_activity activity; | 2742 | struct statistics_bt_activity activity; |
2742 | __le32 reserved2; | 2743 | __le32 reserved2; |
2743 | __le32 reserved3; | 2744 | __le32 reserved3; |
2744 | } __packed; | 2745 | } __packed; |
2745 | 2746 | ||
2746 | #define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0) | 2747 | #define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0) |
2747 | #define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1) | 2748 | #define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1) |
2748 | #define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2) | 2749 | #define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2) |
2749 | 2750 | ||
2750 | /* | 2751 | /* |
2751 | * REPLY_STATISTICS_CMD = 0x9c, | 2752 | * REPLY_STATISTICS_CMD = 0x9c, |
2752 | * all devices identical. | 2753 | * all devices identical. |
2753 | * | 2754 | * |
2754 | * This command triggers an immediate response containing uCode statistics. | 2755 | * This command triggers an immediate response containing uCode statistics. |
2755 | * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. | 2756 | * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. |
2756 | * | 2757 | * |
2757 | * If the CLEAR_STATS configuration flag is set, uCode will clear its | 2758 | * If the CLEAR_STATS configuration flag is set, uCode will clear its |
2758 | * internal copy of the statistics (counters) after issuing the response. | 2759 | * internal copy of the statistics (counters) after issuing the response. |
2759 | * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). | 2760 | * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). |
2760 | * | 2761 | * |
2761 | * If the DISABLE_NOTIF configuration flag is set, uCode will not issue | 2762 | * If the DISABLE_NOTIF configuration flag is set, uCode will not issue |
2762 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag | 2763 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag |
2763 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. | 2764 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. |
2764 | */ | 2765 | */ |
2765 | #define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */ | 2766 | #define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */ |
2766 | #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ | 2767 | #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ |
2767 | struct iwl_statistics_cmd { | 2768 | struct iwl_statistics_cmd { |
2768 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ | 2769 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ |
2769 | } __packed; | 2770 | } __packed; |
2770 | 2771 | ||
2771 | /* | 2772 | /* |
2772 | * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) | 2773 | * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) |
2773 | * | 2774 | * |
2774 | * By default, uCode issues this notification after receiving a beacon | 2775 | * By default, uCode issues this notification after receiving a beacon |
2775 | * while associated. To disable this behavior, set DISABLE_NOTIF flag in the | 2776 | * while associated. To disable this behavior, set DISABLE_NOTIF flag in the |
2776 | * REPLY_STATISTICS_CMD 0x9c, above. | 2777 | * REPLY_STATISTICS_CMD 0x9c, above. |
2777 | * | 2778 | * |
2778 | * Statistics counters continue to increment beacon after beacon, but are | 2779 | * Statistics counters continue to increment beacon after beacon, but are |
2779 | * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD | 2780 | * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD |
2780 | * 0x9c with CLEAR_STATS bit set (see above). | 2781 | * 0x9c with CLEAR_STATS bit set (see above). |
2781 | * | 2782 | * |
2782 | * uCode also issues this notification during scans. uCode clears statistics | 2783 | * uCode also issues this notification during scans. uCode clears statistics |
2783 | * appropriately so that each notification contains statistics for only the | 2784 | * appropriately so that each notification contains statistics for only the |
2784 | * one channel that has just been scanned. | 2785 | * one channel that has just been scanned. |
2785 | */ | 2786 | */ |
2786 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) | 2787 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) |
2787 | #define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8) | 2788 | #define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8) |
2788 | 2789 | ||
2789 | struct iwl_notif_statistics { | 2790 | struct iwl_notif_statistics { |
2790 | __le32 flag; | 2791 | __le32 flag; |
2791 | struct statistics_rx rx; | 2792 | struct statistics_rx rx; |
2792 | struct statistics_tx tx; | 2793 | struct statistics_tx tx; |
2793 | struct statistics_general general; | 2794 | struct statistics_general general; |
2794 | } __packed; | 2795 | } __packed; |
2795 | 2796 | ||
2796 | struct iwl_bt_notif_statistics { | 2797 | struct iwl_bt_notif_statistics { |
2797 | __le32 flag; | 2798 | __le32 flag; |
2798 | struct statistics_rx_bt rx; | 2799 | struct statistics_rx_bt rx; |
2799 | struct statistics_tx tx; | 2800 | struct statistics_tx tx; |
2800 | struct statistics_general_bt general; | 2801 | struct statistics_general_bt general; |
2801 | } __packed; | 2802 | } __packed; |
2802 | 2803 | ||
2803 | /* | 2804 | /* |
2804 | * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) | 2805 | * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) |
2805 | * | 2806 | * |
2806 | * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed | 2807 | * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed |
2807 | * in regardless of how many missed beacons, which mean when driver receive the | 2808 | * in regardless of how many missed beacons, which mean when driver receive the |
2808 | * notification, inside the command, it can find all the beacons information | 2809 | * notification, inside the command, it can find all the beacons information |
2809 | * which include number of total missed beacons, number of consecutive missed | 2810 | * which include number of total missed beacons, number of consecutive missed |
2810 | * beacons, number of beacons received and number of beacons expected to | 2811 | * beacons, number of beacons received and number of beacons expected to |
2811 | * receive. | 2812 | * receive. |
2812 | * | 2813 | * |
2813 | * If uCode detected consecutive_missed_beacons > 5, it will reset the radio | 2814 | * If uCode detected consecutive_missed_beacons > 5, it will reset the radio |
2814 | * in order to bring the radio/PHY back to working state; which has no relation | 2815 | * in order to bring the radio/PHY back to working state; which has no relation |
2815 | * to when driver will perform sensitivity calibration. | 2816 | * to when driver will perform sensitivity calibration. |
2816 | * | 2817 | * |
2817 | * Driver should set it own missed_beacon_threshold to decide when to perform | 2818 | * Driver should set it own missed_beacon_threshold to decide when to perform |
2818 | * sensitivity calibration based on number of consecutive missed beacons in | 2819 | * sensitivity calibration based on number of consecutive missed beacons in |
2819 | * order to improve overall performance, especially in noisy environment. | 2820 | * order to improve overall performance, especially in noisy environment. |
2820 | * | 2821 | * |
2821 | */ | 2822 | */ |
2822 | 2823 | ||
2823 | #define IWL_MISSED_BEACON_THRESHOLD_MIN (1) | 2824 | #define IWL_MISSED_BEACON_THRESHOLD_MIN (1) |
2824 | #define IWL_MISSED_BEACON_THRESHOLD_DEF (5) | 2825 | #define IWL_MISSED_BEACON_THRESHOLD_DEF (5) |
2825 | #define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF | 2826 | #define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF |
2826 | 2827 | ||
2827 | struct iwl_missed_beacon_notif { | 2828 | struct iwl_missed_beacon_notif { |
2828 | __le32 consecutive_missed_beacons; | 2829 | __le32 consecutive_missed_beacons; |
2829 | __le32 total_missed_becons; | 2830 | __le32 total_missed_becons; |
2830 | __le32 num_expected_beacons; | 2831 | __le32 num_expected_beacons; |
2831 | __le32 num_recvd_beacons; | 2832 | __le32 num_recvd_beacons; |
2832 | } __packed; | 2833 | } __packed; |
2833 | 2834 | ||
2834 | 2835 | ||
2835 | /****************************************************************************** | 2836 | /****************************************************************************** |
2836 | * (11) | 2837 | * (11) |
2837 | * Rx Calibration Commands: | 2838 | * Rx Calibration Commands: |
2838 | * | 2839 | * |
2839 | * With the uCode used for open source drivers, most Tx calibration (except | 2840 | * With the uCode used for open source drivers, most Tx calibration (except |
2840 | * for Tx Power) and most Rx calibration is done by uCode during the | 2841 | * for Tx Power) and most Rx calibration is done by uCode during the |
2841 | * "initialize" phase of uCode boot. Driver must calibrate only: | 2842 | * "initialize" phase of uCode boot. Driver must calibrate only: |
2842 | * | 2843 | * |
2843 | * 1) Tx power (depends on temperature), described elsewhere | 2844 | * 1) Tx power (depends on temperature), described elsewhere |
2844 | * 2) Receiver gain balance (optimize MIMO, and detect disconnected antennas) | 2845 | * 2) Receiver gain balance (optimize MIMO, and detect disconnected antennas) |
2845 | * 3) Receiver sensitivity (to optimize signal detection) | 2846 | * 3) Receiver sensitivity (to optimize signal detection) |
2846 | * | 2847 | * |
2847 | *****************************************************************************/ | 2848 | *****************************************************************************/ |
2848 | 2849 | ||
2849 | /** | 2850 | /** |
2850 | * SENSITIVITY_CMD = 0xa8 (command, has simple generic response) | 2851 | * SENSITIVITY_CMD = 0xa8 (command, has simple generic response) |
2851 | * | 2852 | * |
2852 | * This command sets up the Rx signal detector for a sensitivity level that | 2853 | * This command sets up the Rx signal detector for a sensitivity level that |
2853 | * is high enough to lock onto all signals within the associated network, | 2854 | * is high enough to lock onto all signals within the associated network, |
2854 | * but low enough to ignore signals that are below a certain threshold, so as | 2855 | * but low enough to ignore signals that are below a certain threshold, so as |
2855 | * not to have too many "false alarms". False alarms are signals that the | 2856 | * not to have too many "false alarms". False alarms are signals that the |
2856 | * Rx DSP tries to lock onto, but then discards after determining that they | 2857 | * Rx DSP tries to lock onto, but then discards after determining that they |
2857 | * are noise. | 2858 | * are noise. |
2858 | * | 2859 | * |
2859 | * The optimum number of false alarms is between 5 and 50 per 200 TUs | 2860 | * The optimum number of false alarms is between 5 and 50 per 200 TUs |
2860 | * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e. | 2861 | * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e. |
2861 | * time listening, not transmitting). Driver must adjust sensitivity so that | 2862 | * time listening, not transmitting). Driver must adjust sensitivity so that |
2862 | * the ratio of actual false alarms to actual Rx time falls within this range. | 2863 | * the ratio of actual false alarms to actual Rx time falls within this range. |
2863 | * | 2864 | * |
2864 | * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each | 2865 | * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each |
2865 | * received beacon. These provide information to the driver to analyze the | 2866 | * received beacon. These provide information to the driver to analyze the |
2866 | * sensitivity. Don't analyze statistics that come in from scanning, or any | 2867 | * sensitivity. Don't analyze statistics that come in from scanning, or any |
2867 | * other non-associated-network source. Pertinent statistics include: | 2868 | * other non-associated-network source. Pertinent statistics include: |
2868 | * | 2869 | * |
2869 | * From "general" statistics (struct statistics_rx_non_phy): | 2870 | * From "general" statistics (struct statistics_rx_non_phy): |
2870 | * | 2871 | * |
2871 | * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level) | 2872 | * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level) |
2872 | * Measure of energy of desired signal. Used for establishing a level | 2873 | * Measure of energy of desired signal. Used for establishing a level |
2873 | * below which the device does not detect signals. | 2874 | * below which the device does not detect signals. |
2874 | * | 2875 | * |
2875 | * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB) | 2876 | * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB) |
2876 | * Measure of background noise in silent period after beacon. | 2877 | * Measure of background noise in silent period after beacon. |
2877 | * | 2878 | * |
2878 | * channel_load | 2879 | * channel_load |
2879 | * uSecs of actual Rx time during beacon period (varies according to | 2880 | * uSecs of actual Rx time during beacon period (varies according to |
2880 | * how much time was spent transmitting). | 2881 | * how much time was spent transmitting). |
2881 | * | 2882 | * |
2882 | * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately: | 2883 | * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately: |
2883 | * | 2884 | * |
2884 | * false_alarm_cnt | 2885 | * false_alarm_cnt |
2885 | * Signal locks abandoned early (before phy-level header). | 2886 | * Signal locks abandoned early (before phy-level header). |
2886 | * | 2887 | * |
2887 | * plcp_err | 2888 | * plcp_err |
2888 | * Signal locks abandoned late (during phy-level header). | 2889 | * Signal locks abandoned late (during phy-level header). |
2889 | * | 2890 | * |
2890 | * NOTE: Both false_alarm_cnt and plcp_err increment monotonically from | 2891 | * NOTE: Both false_alarm_cnt and plcp_err increment monotonically from |
2891 | * beacon to beacon, i.e. each value is an accumulation of all errors | 2892 | * beacon to beacon, i.e. each value is an accumulation of all errors |
2892 | * before and including the latest beacon. Values will wrap around to 0 | 2893 | * before and including the latest beacon. Values will wrap around to 0 |
2893 | * after counting up to 2^32 - 1. Driver must differentiate vs. | 2894 | * after counting up to 2^32 - 1. Driver must differentiate vs. |
2894 | * previous beacon's values to determine # false alarms in the current | 2895 | * previous beacon's values to determine # false alarms in the current |
2895 | * beacon period. | 2896 | * beacon period. |
2896 | * | 2897 | * |
2897 | * Total number of false alarms = false_alarms + plcp_errs | 2898 | * Total number of false alarms = false_alarms + plcp_errs |
2898 | * | 2899 | * |
2899 | * For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd | 2900 | * For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd |
2900 | * (notice that the start points for OFDM are at or close to settings for | 2901 | * (notice that the start points for OFDM are at or close to settings for |
2901 | * maximum sensitivity): | 2902 | * maximum sensitivity): |
2902 | * | 2903 | * |
2903 | * START / MIN / MAX | 2904 | * START / MIN / MAX |
2904 | * HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX 90 / 85 / 120 | 2905 | * HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX 90 / 85 / 120 |
2905 | * HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX 170 / 170 / 210 | 2906 | * HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX 170 / 170 / 210 |
2906 | * HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX 105 / 105 / 140 | 2907 | * HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX 105 / 105 / 140 |
2907 | * HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX 220 / 220 / 270 | 2908 | * HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX 220 / 220 / 270 |
2908 | * | 2909 | * |
2909 | * If actual rate of OFDM false alarms (+ plcp_errors) is too high | 2910 | * If actual rate of OFDM false alarms (+ plcp_errors) is too high |
2910 | * (greater than 50 for each 204.8 msecs listening), reduce sensitivity | 2911 | * (greater than 50 for each 204.8 msecs listening), reduce sensitivity |
2911 | * by *adding* 1 to all 4 of the table entries above, up to the max for | 2912 | * by *adding* 1 to all 4 of the table entries above, up to the max for |
2912 | * each entry. Conversely, if false alarm rate is too low (less than 5 | 2913 | * each entry. Conversely, if false alarm rate is too low (less than 5 |
2913 | * for each 204.8 msecs listening), *subtract* 1 from each entry to | 2914 | * for each 204.8 msecs listening), *subtract* 1 from each entry to |
2914 | * increase sensitivity. | 2915 | * increase sensitivity. |
2915 | * | 2916 | * |
2916 | * For CCK sensitivity, keep track of the following: | 2917 | * For CCK sensitivity, keep track of the following: |
2917 | * | 2918 | * |
2918 | * 1). 20-beacon history of maximum background noise, indicated by | 2919 | * 1). 20-beacon history of maximum background noise, indicated by |
2919 | * (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the | 2920 | * (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the |
2920 | * 3 receivers. For any given beacon, the "silence reference" is | 2921 | * 3 receivers. For any given beacon, the "silence reference" is |
2921 | * the maximum of last 60 samples (20 beacons * 3 receivers). | 2922 | * the maximum of last 60 samples (20 beacons * 3 receivers). |
2922 | * | 2923 | * |
2923 | * 2). 10-beacon history of strongest signal level, as indicated | 2924 | * 2). 10-beacon history of strongest signal level, as indicated |
2924 | * by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers, | 2925 | * by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers, |
2925 | * i.e. the strength of the signal through the best receiver at the | 2926 | * i.e. the strength of the signal through the best receiver at the |
2926 | * moment. These measurements are "upside down", with lower values | 2927 | * moment. These measurements are "upside down", with lower values |
2927 | * for stronger signals, so max energy will be *minimum* value. | 2928 | * for stronger signals, so max energy will be *minimum* value. |
2928 | * | 2929 | * |
2929 | * Then for any given beacon, the driver must determine the *weakest* | 2930 | * Then for any given beacon, the driver must determine the *weakest* |
2930 | * of the strongest signals; this is the minimum level that needs to be | 2931 | * of the strongest signals; this is the minimum level that needs to be |
2931 | * successfully detected, when using the best receiver at the moment. | 2932 | * successfully detected, when using the best receiver at the moment. |
2932 | * "Max cck energy" is the maximum (higher value means lower energy!) | 2933 | * "Max cck energy" is the maximum (higher value means lower energy!) |
2933 | * of the last 10 minima. Once this is determined, driver must add | 2934 | * of the last 10 minima. Once this is determined, driver must add |
2934 | * a little margin by adding "6" to it. | 2935 | * a little margin by adding "6" to it. |
2935 | * | 2936 | * |
2936 | * 3). Number of consecutive beacon periods with too few false alarms. | 2937 | * 3). Number of consecutive beacon periods with too few false alarms. |
2937 | * Reset this to 0 at the first beacon period that falls within the | 2938 | * Reset this to 0 at the first beacon period that falls within the |
2938 | * "good" range (5 to 50 false alarms per 204.8 milliseconds rx). | 2939 | * "good" range (5 to 50 false alarms per 204.8 milliseconds rx). |
2939 | * | 2940 | * |
2940 | * Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd | 2941 | * Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd |
2941 | * (notice that the start points for CCK are at maximum sensitivity): | 2942 | * (notice that the start points for CCK are at maximum sensitivity): |
2942 | * | 2943 | * |
2943 | * START / MIN / MAX | 2944 | * START / MIN / MAX |
2944 | * HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX 125 / 125 / 200 | 2945 | * HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX 125 / 125 / 200 |
2945 | * HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX 200 / 200 / 400 | 2946 | * HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX 200 / 200 / 400 |
2946 | * HD_MIN_ENERGY_CCK_DET_INDEX 100 / 0 / 100 | 2947 | * HD_MIN_ENERGY_CCK_DET_INDEX 100 / 0 / 100 |
2947 | * | 2948 | * |
2948 | * If actual rate of CCK false alarms (+ plcp_errors) is too high | 2949 | * If actual rate of CCK false alarms (+ plcp_errors) is too high |
2949 | * (greater than 50 for each 204.8 msecs listening), method for reducing | 2950 | * (greater than 50 for each 204.8 msecs listening), method for reducing |
2950 | * sensitivity is: | 2951 | * sensitivity is: |
2951 | * | 2952 | * |
2952 | * 1) *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, | 2953 | * 1) *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, |
2953 | * up to max 400. | 2954 | * up to max 400. |
2954 | * | 2955 | * |
2955 | * 2) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160, | 2956 | * 2) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160, |
2956 | * sensitivity has been reduced a significant amount; bring it up to | 2957 | * sensitivity has been reduced a significant amount; bring it up to |
2957 | * a moderate 161. Otherwise, *add* 3, up to max 200. | 2958 | * a moderate 161. Otherwise, *add* 3, up to max 200. |
2958 | * | 2959 | * |
2959 | * 3) a) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160, | 2960 | * 3) a) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160, |
2960 | * sensitivity has been reduced only a moderate or small amount; | 2961 | * sensitivity has been reduced only a moderate or small amount; |
2961 | * *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX, | 2962 | * *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX, |
2962 | * down to min 0. Otherwise (if gain has been significantly reduced), | 2963 | * down to min 0. Otherwise (if gain has been significantly reduced), |
2963 | * don't change the HD_MIN_ENERGY_CCK_DET_INDEX value. | 2964 | * don't change the HD_MIN_ENERGY_CCK_DET_INDEX value. |
2964 | * | 2965 | * |
2965 | * b) Save a snapshot of the "silence reference". | 2966 | * b) Save a snapshot of the "silence reference". |
2966 | * | 2967 | * |
2967 | * If actual rate of CCK false alarms (+ plcp_errors) is too low | 2968 | * If actual rate of CCK false alarms (+ plcp_errors) is too low |
2968 | * (less than 5 for each 204.8 msecs listening), method for increasing | 2969 | * (less than 5 for each 204.8 msecs listening), method for increasing |
2969 | * sensitivity is used only if: | 2970 | * sensitivity is used only if: |
2970 | * | 2971 | * |
2971 | * 1a) Previous beacon did not have too many false alarms | 2972 | * 1a) Previous beacon did not have too many false alarms |
2972 | * 1b) AND difference between previous "silence reference" and current | 2973 | * 1b) AND difference between previous "silence reference" and current |
2973 | * "silence reference" (prev - current) is 2 or more, | 2974 | * "silence reference" (prev - current) is 2 or more, |
2974 | * OR 2) 100 or more consecutive beacon periods have had rate of | 2975 | * OR 2) 100 or more consecutive beacon periods have had rate of |
2975 | * less than 5 false alarms per 204.8 milliseconds rx time. | 2976 | * less than 5 false alarms per 204.8 milliseconds rx time. |
2976 | * | 2977 | * |
2977 | * Method for increasing sensitivity: | 2978 | * Method for increasing sensitivity: |
2978 | * | 2979 | * |
2979 | * 1) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX, | 2980 | * 1) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX, |
2980 | * down to min 125. | 2981 | * down to min 125. |
2981 | * | 2982 | * |
2982 | * 2) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, | 2983 | * 2) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, |
2983 | * down to min 200. | 2984 | * down to min 200. |
2984 | * | 2985 | * |
2985 | * 3) *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100. | 2986 | * 3) *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100. |
2986 | * | 2987 | * |
2987 | * If actual rate of CCK false alarms (+ plcp_errors) is within good range | 2988 | * If actual rate of CCK false alarms (+ plcp_errors) is within good range |
2988 | * (between 5 and 50 for each 204.8 msecs listening): | 2989 | * (between 5 and 50 for each 204.8 msecs listening): |
2989 | * | 2990 | * |
2990 | * 1) Save a snapshot of the silence reference. | 2991 | * 1) Save a snapshot of the silence reference. |
2991 | * | 2992 | * |
2992 | * 2) If previous beacon had too many CCK false alarms (+ plcp_errors), | 2993 | * 2) If previous beacon had too many CCK false alarms (+ plcp_errors), |
2993 | * give some extra margin to energy threshold by *subtracting* 8 | 2994 | * give some extra margin to energy threshold by *subtracting* 8 |
2994 | * from value in HD_MIN_ENERGY_CCK_DET_INDEX. | 2995 | * from value in HD_MIN_ENERGY_CCK_DET_INDEX. |
2995 | * | 2996 | * |
2996 | * For all cases (too few, too many, good range), make sure that the CCK | 2997 | * For all cases (too few, too many, good range), make sure that the CCK |
2997 | * detection threshold (energy) is below the energy level for robust | 2998 | * detection threshold (energy) is below the energy level for robust |
2998 | * detection over the past 10 beacon periods, the "Max cck energy". | 2999 | * detection over the past 10 beacon periods, the "Max cck energy". |
2999 | * Lower values mean higher energy; this means making sure that the value | 3000 | * Lower values mean higher energy; this means making sure that the value |
3000 | * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". | 3001 | * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". |
3001 | * | 3002 | * |
3002 | */ | 3003 | */ |
3003 | 3004 | ||
3004 | /* | 3005 | /* |
3005 | * Table entries in SENSITIVITY_CMD (struct iwl_sensitivity_cmd) | 3006 | * Table entries in SENSITIVITY_CMD (struct iwl_sensitivity_cmd) |
3006 | */ | 3007 | */ |
3007 | #define HD_TABLE_SIZE (11) /* number of entries */ | 3008 | #define HD_TABLE_SIZE (11) /* number of entries */ |
3008 | #define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */ | 3009 | #define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */ |
3009 | #define HD_MIN_ENERGY_OFDM_DET_INDEX (1) | 3010 | #define HD_MIN_ENERGY_OFDM_DET_INDEX (1) |
3010 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) | 3011 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) |
3011 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) | 3012 | #define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) |
3012 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) | 3013 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) |
3013 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) | 3014 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) |
3014 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) | 3015 | #define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) |
3015 | #define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) | 3016 | #define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) |
3016 | #define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) | 3017 | #define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) |
3017 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) | 3018 | #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) |
3018 | #define HD_OFDM_ENERGY_TH_IN_INDEX (10) | 3019 | #define HD_OFDM_ENERGY_TH_IN_INDEX (10) |
3019 | 3020 | ||
3020 | /* | 3021 | /* |
3021 | * Additional table entries in enhance SENSITIVITY_CMD | 3022 | * Additional table entries in enhance SENSITIVITY_CMD |
3022 | */ | 3023 | */ |
3023 | #define HD_INA_NON_SQUARE_DET_OFDM_INDEX (11) | 3024 | #define HD_INA_NON_SQUARE_DET_OFDM_INDEX (11) |
3024 | #define HD_INA_NON_SQUARE_DET_CCK_INDEX (12) | 3025 | #define HD_INA_NON_SQUARE_DET_CCK_INDEX (12) |
3025 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX (13) | 3026 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX (13) |
3026 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX (14) | 3027 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX (14) |
3027 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (15) | 3028 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (15) |
3028 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX (16) | 3029 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX (16) |
3029 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX (17) | 3030 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX (17) |
3030 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX (18) | 3031 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX (18) |
3031 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (19) | 3032 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (19) |
3032 | #define HD_CCK_NON_SQUARE_DET_SLOPE_INDEX (20) | 3033 | #define HD_CCK_NON_SQUARE_DET_SLOPE_INDEX (20) |
3033 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX (21) | 3034 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX (21) |
3034 | #define HD_RESERVED (22) | 3035 | #define HD_RESERVED (22) |
3035 | 3036 | ||
3036 | /* number of entries for enhanced tbl */ | 3037 | /* number of entries for enhanced tbl */ |
3037 | #define ENHANCE_HD_TABLE_SIZE (23) | 3038 | #define ENHANCE_HD_TABLE_SIZE (23) |
3038 | 3039 | ||
3039 | /* number of additional entries for enhanced tbl */ | 3040 | /* number of additional entries for enhanced tbl */ |
3040 | #define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE) | 3041 | #define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE) |
3041 | 3042 | ||
3042 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA_V1 cpu_to_le16(0) | 3043 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA_V1 cpu_to_le16(0) |
3043 | #define HD_INA_NON_SQUARE_DET_CCK_DATA_V1 cpu_to_le16(0) | 3044 | #define HD_INA_NON_SQUARE_DET_CCK_DATA_V1 cpu_to_le16(0) |
3044 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1 cpu_to_le16(0) | 3045 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1 cpu_to_le16(0) |
3045 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(668) | 3046 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(668) |
3046 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4) | 3047 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4) |
3047 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(486) | 3048 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(486) |
3048 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(37) | 3049 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(37) |
3049 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(853) | 3050 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(853) |
3050 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4) | 3051 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4) |
3051 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(476) | 3052 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(476) |
3052 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(99) | 3053 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(99) |
3053 | 3054 | ||
3054 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA_V2 cpu_to_le16(1) | 3055 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA_V2 cpu_to_le16(1) |
3055 | #define HD_INA_NON_SQUARE_DET_CCK_DATA_V2 cpu_to_le16(1) | 3056 | #define HD_INA_NON_SQUARE_DET_CCK_DATA_V2 cpu_to_le16(1) |
3056 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2 cpu_to_le16(1) | 3057 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2 cpu_to_le16(1) |
3057 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(600) | 3058 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(600) |
3058 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(40) | 3059 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(40) |
3059 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(486) | 3060 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(486) |
3060 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(45) | 3061 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(45) |
3061 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(853) | 3062 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(853) |
3062 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(60) | 3063 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(60) |
3063 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(476) | 3064 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(476) |
3064 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(99) | 3065 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(99) |
3065 | 3066 | ||
3066 | 3067 | ||
3067 | /* Control field in struct iwl_sensitivity_cmd */ | 3068 | /* Control field in struct iwl_sensitivity_cmd */ |
3068 | #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0) | 3069 | #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0) |
3069 | #define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) | 3070 | #define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) |
3070 | 3071 | ||
3071 | /** | 3072 | /** |
3072 | * struct iwl_sensitivity_cmd | 3073 | * struct iwl_sensitivity_cmd |
3073 | * @control: (1) updates working table, (0) updates default table | 3074 | * @control: (1) updates working table, (0) updates default table |
3074 | * @table: energy threshold values, use HD_* as index into table | 3075 | * @table: energy threshold values, use HD_* as index into table |
3075 | * | 3076 | * |
3076 | * Always use "1" in "control" to update uCode's working table and DSP. | 3077 | * Always use "1" in "control" to update uCode's working table and DSP. |
3077 | */ | 3078 | */ |
3078 | struct iwl_sensitivity_cmd { | 3079 | struct iwl_sensitivity_cmd { |
3079 | __le16 control; /* always use "1" */ | 3080 | __le16 control; /* always use "1" */ |
3080 | __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ | 3081 | __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ |
3081 | } __packed; | 3082 | } __packed; |
3082 | 3083 | ||
3083 | /* | 3084 | /* |
3084 | * | 3085 | * |
3085 | */ | 3086 | */ |
3086 | struct iwl_enhance_sensitivity_cmd { | 3087 | struct iwl_enhance_sensitivity_cmd { |
3087 | __le16 control; /* always use "1" */ | 3088 | __le16 control; /* always use "1" */ |
3088 | __le16 enhance_table[ENHANCE_HD_TABLE_SIZE]; /* use HD_* as index */ | 3089 | __le16 enhance_table[ENHANCE_HD_TABLE_SIZE]; /* use HD_* as index */ |
3089 | } __packed; | 3090 | } __packed; |
3090 | 3091 | ||
3091 | 3092 | ||
3092 | /** | 3093 | /** |
3093 | * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) | 3094 | * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) |
3094 | * | 3095 | * |
3095 | * This command sets the relative gains of agn device's 3 radio receiver chains. | 3096 | * This command sets the relative gains of agn device's 3 radio receiver chains. |
3096 | * | 3097 | * |
3097 | * After the first association, driver should accumulate signal and noise | 3098 | * After the first association, driver should accumulate signal and noise |
3098 | * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 | 3099 | * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 |
3099 | * beacons from the associated network (don't collect statistics that come | 3100 | * beacons from the associated network (don't collect statistics that come |
3100 | * in from scanning, or any other non-network source). | 3101 | * in from scanning, or any other non-network source). |
3101 | * | 3102 | * |
3102 | * DISCONNECTED ANTENNA: | 3103 | * DISCONNECTED ANTENNA: |
3103 | * | 3104 | * |
3104 | * Driver should determine which antennas are actually connected, by comparing | 3105 | * Driver should determine which antennas are actually connected, by comparing |
3105 | * average beacon signal levels for the 3 Rx chains. Accumulate (add) the | 3106 | * average beacon signal levels for the 3 Rx chains. Accumulate (add) the |
3106 | * following values over 20 beacons, one accumulator for each of the chains | 3107 | * following values over 20 beacons, one accumulator for each of the chains |
3107 | * a/b/c, from struct statistics_rx_non_phy: | 3108 | * a/b/c, from struct statistics_rx_non_phy: |
3108 | * | 3109 | * |
3109 | * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB) | 3110 | * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB) |
3110 | * | 3111 | * |
3111 | * Find the strongest signal from among a/b/c. Compare the other two to the | 3112 | * Find the strongest signal from among a/b/c. Compare the other two to the |
3112 | * strongest. If any signal is more than 15 dB (times 20, unless you | 3113 | * strongest. If any signal is more than 15 dB (times 20, unless you |
3113 | * divide the accumulated values by 20) below the strongest, the driver | 3114 | * divide the accumulated values by 20) below the strongest, the driver |
3114 | * considers that antenna to be disconnected, and should not try to use that | 3115 | * considers that antenna to be disconnected, and should not try to use that |
3115 | * antenna/chain for Rx or Tx. If both A and B seem to be disconnected, | 3116 | * antenna/chain for Rx or Tx. If both A and B seem to be disconnected, |
3116 | * driver should declare the stronger one as connected, and attempt to use it | 3117 | * driver should declare the stronger one as connected, and attempt to use it |
3117 | * (A and B are the only 2 Tx chains!). | 3118 | * (A and B are the only 2 Tx chains!). |
3118 | * | 3119 | * |
3119 | * | 3120 | * |
3120 | * RX BALANCE: | 3121 | * RX BALANCE: |
3121 | * | 3122 | * |
3122 | * Driver should balance the 3 receivers (but just the ones that are connected | 3123 | * Driver should balance the 3 receivers (but just the ones that are connected |
3123 | * to antennas, see above) for gain, by comparing the average signal levels | 3124 | * to antennas, see above) for gain, by comparing the average signal levels |
3124 | * detected during the silence after each beacon (background noise). | 3125 | * detected during the silence after each beacon (background noise). |
3125 | * Accumulate (add) the following values over 20 beacons, one accumulator for | 3126 | * Accumulate (add) the following values over 20 beacons, one accumulator for |
3126 | * each of the chains a/b/c, from struct statistics_rx_non_phy: | 3127 | * each of the chains a/b/c, from struct statistics_rx_non_phy: |
3127 | * | 3128 | * |
3128 | * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB) | 3129 | * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB) |
3129 | * | 3130 | * |
3130 | * Find the weakest background noise level from among a/b/c. This Rx chain | 3131 | * Find the weakest background noise level from among a/b/c. This Rx chain |
3131 | * will be the reference, with 0 gain adjustment. Attenuate other channels by | 3132 | * will be the reference, with 0 gain adjustment. Attenuate other channels by |
3132 | * finding noise difference: | 3133 | * finding noise difference: |
3133 | * | 3134 | * |
3134 | * (accum_noise[i] - accum_noise[reference]) / 30 | 3135 | * (accum_noise[i] - accum_noise[reference]) / 30 |
3135 | * | 3136 | * |
3136 | * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB. | 3137 | * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB. |
3137 | * For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the | 3138 | * For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the |
3138 | * driver should limit the difference results to a range of 0-3 (0-4.5 dB), | 3139 | * driver should limit the difference results to a range of 0-3 (0-4.5 dB), |
3139 | * and set bit 2 to indicate "reduce gain". The value for the reference | 3140 | * and set bit 2 to indicate "reduce gain". The value for the reference |
3140 | * (weakest) chain should be "0". | 3141 | * (weakest) chain should be "0". |
3141 | * | 3142 | * |
3142 | * diff_gain_[abc] bit fields: | 3143 | * diff_gain_[abc] bit fields: |
3143 | * 2: (1) reduce gain, (0) increase gain | 3144 | * 2: (1) reduce gain, (0) increase gain |
3144 | * 1-0: amount of gain, units of 1.5 dB | 3145 | * 1-0: amount of gain, units of 1.5 dB |
3145 | */ | 3146 | */ |
3146 | 3147 | ||
3147 | /* Phy calibration command for series */ | 3148 | /* Phy calibration command for series */ |
3148 | enum { | 3149 | enum { |
3149 | IWL_PHY_CALIBRATE_DC_CMD = 8, | 3150 | IWL_PHY_CALIBRATE_DC_CMD = 8, |
3150 | IWL_PHY_CALIBRATE_LO_CMD = 9, | 3151 | IWL_PHY_CALIBRATE_LO_CMD = 9, |
3151 | IWL_PHY_CALIBRATE_TX_IQ_CMD = 11, | 3152 | IWL_PHY_CALIBRATE_TX_IQ_CMD = 11, |
3152 | IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, | 3153 | IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, |
3153 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, | 3154 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, |
3154 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, | 3155 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, |
3155 | IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, | 3156 | IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, |
3156 | }; | 3157 | }; |
3157 | 3158 | ||
3158 | /* This enum defines the bitmap of various calibrations to enable in both | 3159 | /* This enum defines the bitmap of various calibrations to enable in both |
3159 | * init ucode and runtime ucode through CALIBRATION_CFG_CMD. | 3160 | * init ucode and runtime ucode through CALIBRATION_CFG_CMD. |
3160 | */ | 3161 | */ |
3161 | enum iwl_ucode_calib_cfg { | 3162 | enum iwl_ucode_calib_cfg { |
3162 | IWL_CALIB_CFG_RX_BB_IDX = BIT(0), | 3163 | IWL_CALIB_CFG_RX_BB_IDX = BIT(0), |
3163 | IWL_CALIB_CFG_DC_IDX = BIT(1), | 3164 | IWL_CALIB_CFG_DC_IDX = BIT(1), |
3164 | IWL_CALIB_CFG_LO_IDX = BIT(2), | 3165 | IWL_CALIB_CFG_LO_IDX = BIT(2), |
3165 | IWL_CALIB_CFG_TX_IQ_IDX = BIT(3), | 3166 | IWL_CALIB_CFG_TX_IQ_IDX = BIT(3), |
3166 | IWL_CALIB_CFG_RX_IQ_IDX = BIT(4), | 3167 | IWL_CALIB_CFG_RX_IQ_IDX = BIT(4), |
3167 | IWL_CALIB_CFG_NOISE_IDX = BIT(5), | 3168 | IWL_CALIB_CFG_NOISE_IDX = BIT(5), |
3168 | IWL_CALIB_CFG_CRYSTAL_IDX = BIT(6), | 3169 | IWL_CALIB_CFG_CRYSTAL_IDX = BIT(6), |
3169 | IWL_CALIB_CFG_TEMPERATURE_IDX = BIT(7), | 3170 | IWL_CALIB_CFG_TEMPERATURE_IDX = BIT(7), |
3170 | IWL_CALIB_CFG_PAPD_IDX = BIT(8), | 3171 | IWL_CALIB_CFG_PAPD_IDX = BIT(8), |
3171 | IWL_CALIB_CFG_SENSITIVITY_IDX = BIT(9), | 3172 | IWL_CALIB_CFG_SENSITIVITY_IDX = BIT(9), |
3172 | IWL_CALIB_CFG_TX_PWR_IDX = BIT(10), | 3173 | IWL_CALIB_CFG_TX_PWR_IDX = BIT(10), |
3173 | }; | 3174 | }; |
3174 | 3175 | ||
3175 | #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(IWL_CALIB_CFG_RX_BB_IDX | \ | 3176 | #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(IWL_CALIB_CFG_RX_BB_IDX | \ |
3176 | IWL_CALIB_CFG_DC_IDX | \ | 3177 | IWL_CALIB_CFG_DC_IDX | \ |
3177 | IWL_CALIB_CFG_LO_IDX | \ | 3178 | IWL_CALIB_CFG_LO_IDX | \ |
3178 | IWL_CALIB_CFG_TX_IQ_IDX | \ | 3179 | IWL_CALIB_CFG_TX_IQ_IDX | \ |
3179 | IWL_CALIB_CFG_RX_IQ_IDX | \ | 3180 | IWL_CALIB_CFG_RX_IQ_IDX | \ |
3180 | IWL_CALIB_CFG_CRYSTAL_IDX) | 3181 | IWL_CALIB_CFG_CRYSTAL_IDX) |
3181 | 3182 | ||
3182 | #define IWL_CALIB_RT_CFG_ALL cpu_to_le32(IWL_CALIB_CFG_RX_BB_IDX | \ | 3183 | #define IWL_CALIB_RT_CFG_ALL cpu_to_le32(IWL_CALIB_CFG_RX_BB_IDX | \ |
3183 | IWL_CALIB_CFG_DC_IDX | \ | 3184 | IWL_CALIB_CFG_DC_IDX | \ |
3184 | IWL_CALIB_CFG_LO_IDX | \ | 3185 | IWL_CALIB_CFG_LO_IDX | \ |
3185 | IWL_CALIB_CFG_TX_IQ_IDX | \ | 3186 | IWL_CALIB_CFG_TX_IQ_IDX | \ |
3186 | IWL_CALIB_CFG_RX_IQ_IDX | \ | 3187 | IWL_CALIB_CFG_RX_IQ_IDX | \ |
3187 | IWL_CALIB_CFG_TEMPERATURE_IDX | \ | 3188 | IWL_CALIB_CFG_TEMPERATURE_IDX | \ |
3188 | IWL_CALIB_CFG_PAPD_IDX | \ | 3189 | IWL_CALIB_CFG_PAPD_IDX | \ |
3189 | IWL_CALIB_CFG_TX_PWR_IDX | \ | 3190 | IWL_CALIB_CFG_TX_PWR_IDX | \ |
3190 | IWL_CALIB_CFG_CRYSTAL_IDX) | 3191 | IWL_CALIB_CFG_CRYSTAL_IDX) |
3191 | 3192 | ||
3192 | #define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK cpu_to_le32(BIT(0)) | 3193 | #define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK cpu_to_le32(BIT(0)) |
3193 | 3194 | ||
3194 | struct iwl_calib_cfg_elmnt_s { | 3195 | struct iwl_calib_cfg_elmnt_s { |
3195 | __le32 is_enable; | 3196 | __le32 is_enable; |
3196 | __le32 start; | 3197 | __le32 start; |
3197 | __le32 send_res; | 3198 | __le32 send_res; |
3198 | __le32 apply_res; | 3199 | __le32 apply_res; |
3199 | __le32 reserved; | 3200 | __le32 reserved; |
3200 | } __packed; | 3201 | } __packed; |
3201 | 3202 | ||
3202 | struct iwl_calib_cfg_status_s { | 3203 | struct iwl_calib_cfg_status_s { |
3203 | struct iwl_calib_cfg_elmnt_s once; | 3204 | struct iwl_calib_cfg_elmnt_s once; |
3204 | struct iwl_calib_cfg_elmnt_s perd; | 3205 | struct iwl_calib_cfg_elmnt_s perd; |
3205 | __le32 flags; | 3206 | __le32 flags; |
3206 | } __packed; | 3207 | } __packed; |
3207 | 3208 | ||
3208 | struct iwl_calib_cfg_cmd { | 3209 | struct iwl_calib_cfg_cmd { |
3209 | struct iwl_calib_cfg_status_s ucd_calib_cfg; | 3210 | struct iwl_calib_cfg_status_s ucd_calib_cfg; |
3210 | struct iwl_calib_cfg_status_s drv_calib_cfg; | 3211 | struct iwl_calib_cfg_status_s drv_calib_cfg; |
3211 | __le32 reserved1; | 3212 | __le32 reserved1; |
3212 | } __packed; | 3213 | } __packed; |
3213 | 3214 | ||
3214 | struct iwl_calib_hdr { | 3215 | struct iwl_calib_hdr { |
3215 | u8 op_code; | 3216 | u8 op_code; |
3216 | u8 first_group; | 3217 | u8 first_group; |
3217 | u8 groups_num; | 3218 | u8 groups_num; |
3218 | u8 data_valid; | 3219 | u8 data_valid; |
3219 | } __packed; | 3220 | } __packed; |
3220 | 3221 | ||
3221 | struct iwl_calib_cmd { | 3222 | struct iwl_calib_cmd { |
3222 | struct iwl_calib_hdr hdr; | 3223 | struct iwl_calib_hdr hdr; |
3223 | u8 data[0]; | 3224 | u8 data[0]; |
3224 | } __packed; | 3225 | } __packed; |
3225 | 3226 | ||
3226 | struct iwl_calib_xtal_freq_cmd { | 3227 | struct iwl_calib_xtal_freq_cmd { |
3227 | struct iwl_calib_hdr hdr; | 3228 | struct iwl_calib_hdr hdr; |
3228 | u8 cap_pin1; | 3229 | u8 cap_pin1; |
3229 | u8 cap_pin2; | 3230 | u8 cap_pin2; |
3230 | u8 pad[2]; | 3231 | u8 pad[2]; |
3231 | } __packed; | 3232 | } __packed; |
3232 | 3233 | ||
3233 | #define DEFAULT_RADIO_SENSOR_OFFSET cpu_to_le16(2700) | 3234 | #define DEFAULT_RADIO_SENSOR_OFFSET cpu_to_le16(2700) |
3234 | struct iwl_calib_temperature_offset_cmd { | 3235 | struct iwl_calib_temperature_offset_cmd { |
3235 | struct iwl_calib_hdr hdr; | 3236 | struct iwl_calib_hdr hdr; |
3236 | __le16 radio_sensor_offset; | 3237 | __le16 radio_sensor_offset; |
3237 | __le16 reserved; | 3238 | __le16 reserved; |
3238 | } __packed; | 3239 | } __packed; |
3239 | 3240 | ||
3240 | struct iwl_calib_temperature_offset_v2_cmd { | 3241 | struct iwl_calib_temperature_offset_v2_cmd { |
3241 | struct iwl_calib_hdr hdr; | 3242 | struct iwl_calib_hdr hdr; |
3242 | __le16 radio_sensor_offset_high; | 3243 | __le16 radio_sensor_offset_high; |
3243 | __le16 radio_sensor_offset_low; | 3244 | __le16 radio_sensor_offset_low; |
3244 | __le16 burntVoltageRef; | 3245 | __le16 burntVoltageRef; |
3245 | __le16 reserved; | 3246 | __le16 reserved; |
3246 | } __packed; | 3247 | } __packed; |
3247 | 3248 | ||
3248 | /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ | 3249 | /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ |
3249 | struct iwl_calib_chain_noise_reset_cmd { | 3250 | struct iwl_calib_chain_noise_reset_cmd { |
3250 | struct iwl_calib_hdr hdr; | 3251 | struct iwl_calib_hdr hdr; |
3251 | u8 data[0]; | 3252 | u8 data[0]; |
3252 | }; | 3253 | }; |
3253 | 3254 | ||
3254 | /* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */ | 3255 | /* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */ |
3255 | struct iwl_calib_chain_noise_gain_cmd { | 3256 | struct iwl_calib_chain_noise_gain_cmd { |
3256 | struct iwl_calib_hdr hdr; | 3257 | struct iwl_calib_hdr hdr; |
3257 | u8 delta_gain_1; | 3258 | u8 delta_gain_1; |
3258 | u8 delta_gain_2; | 3259 | u8 delta_gain_2; |
3259 | u8 pad[2]; | 3260 | u8 pad[2]; |
3260 | } __packed; | 3261 | } __packed; |
3261 | 3262 | ||
3262 | /****************************************************************************** | 3263 | /****************************************************************************** |
3263 | * (12) | 3264 | * (12) |
3264 | * Miscellaneous Commands: | 3265 | * Miscellaneous Commands: |
3265 | * | 3266 | * |
3266 | *****************************************************************************/ | 3267 | *****************************************************************************/ |
3267 | 3268 | ||
3268 | /* | 3269 | /* |
3269 | * LEDs Command & Response | 3270 | * LEDs Command & Response |
3270 | * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) | 3271 | * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) |
3271 | * | 3272 | * |
3272 | * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), | 3273 | * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), |
3273 | * this command turns it on or off, or sets up a periodic blinking cycle. | 3274 | * this command turns it on or off, or sets up a periodic blinking cycle. |
3274 | */ | 3275 | */ |
3275 | struct iwl_led_cmd { | 3276 | struct iwl_led_cmd { |
3276 | __le32 interval; /* "interval" in uSec */ | 3277 | __le32 interval; /* "interval" in uSec */ |
3277 | u8 id; /* 1: Activity, 2: Link, 3: Tech */ | 3278 | u8 id; /* 1: Activity, 2: Link, 3: Tech */ |
3278 | u8 off; /* # intervals off while blinking; | 3279 | u8 off; /* # intervals off while blinking; |
3279 | * "0", with >0 "on" value, turns LED on */ | 3280 | * "0", with >0 "on" value, turns LED on */ |
3280 | u8 on; /* # intervals on while blinking; | 3281 | u8 on; /* # intervals on while blinking; |
3281 | * "0", regardless of "off", turns LED off */ | 3282 | * "0", regardless of "off", turns LED off */ |
3282 | u8 reserved; | 3283 | u8 reserved; |
3283 | } __packed; | 3284 | } __packed; |
3284 | 3285 | ||
3285 | /* | 3286 | /* |
3286 | * station priority table entries | 3287 | * station priority table entries |
3287 | * also used as potential "events" value for both | 3288 | * also used as potential "events" value for both |
3288 | * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD | 3289 | * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD |
3289 | */ | 3290 | */ |
3290 | 3291 | ||
3291 | /* | 3292 | /* |
3292 | * COEX events entry flag masks | 3293 | * COEX events entry flag masks |
3293 | * RP - Requested Priority | 3294 | * RP - Requested Priority |
3294 | * WP - Win Medium Priority: priority assigned when the contention has been won | 3295 | * WP - Win Medium Priority: priority assigned when the contention has been won |
3295 | */ | 3296 | */ |
3296 | #define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG (0x1) | 3297 | #define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG (0x1) |
3297 | #define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG (0x2) | 3298 | #define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG (0x2) |
3298 | #define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG (0x4) | 3299 | #define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG (0x4) |
3299 | 3300 | ||
3300 | #define COEX_CU_UNASSOC_IDLE_RP 4 | 3301 | #define COEX_CU_UNASSOC_IDLE_RP 4 |
3301 | #define COEX_CU_UNASSOC_MANUAL_SCAN_RP 4 | 3302 | #define COEX_CU_UNASSOC_MANUAL_SCAN_RP 4 |
3302 | #define COEX_CU_UNASSOC_AUTO_SCAN_RP 4 | 3303 | #define COEX_CU_UNASSOC_AUTO_SCAN_RP 4 |
3303 | #define COEX_CU_CALIBRATION_RP 4 | 3304 | #define COEX_CU_CALIBRATION_RP 4 |
3304 | #define COEX_CU_PERIODIC_CALIBRATION_RP 4 | 3305 | #define COEX_CU_PERIODIC_CALIBRATION_RP 4 |
3305 | #define COEX_CU_CONNECTION_ESTAB_RP 4 | 3306 | #define COEX_CU_CONNECTION_ESTAB_RP 4 |
3306 | #define COEX_CU_ASSOCIATED_IDLE_RP 4 | 3307 | #define COEX_CU_ASSOCIATED_IDLE_RP 4 |
3307 | #define COEX_CU_ASSOC_MANUAL_SCAN_RP 4 | 3308 | #define COEX_CU_ASSOC_MANUAL_SCAN_RP 4 |
3308 | #define COEX_CU_ASSOC_AUTO_SCAN_RP 4 | 3309 | #define COEX_CU_ASSOC_AUTO_SCAN_RP 4 |
3309 | #define COEX_CU_ASSOC_ACTIVE_LEVEL_RP 4 | 3310 | #define COEX_CU_ASSOC_ACTIVE_LEVEL_RP 4 |
3310 | #define COEX_CU_RF_ON_RP 6 | 3311 | #define COEX_CU_RF_ON_RP 6 |
3311 | #define COEX_CU_RF_OFF_RP 4 | 3312 | #define COEX_CU_RF_OFF_RP 4 |
3312 | #define COEX_CU_STAND_ALONE_DEBUG_RP 6 | 3313 | #define COEX_CU_STAND_ALONE_DEBUG_RP 6 |
3313 | #define COEX_CU_IPAN_ASSOC_LEVEL_RP 4 | 3314 | #define COEX_CU_IPAN_ASSOC_LEVEL_RP 4 |
3314 | #define COEX_CU_RSRVD1_RP 4 | 3315 | #define COEX_CU_RSRVD1_RP 4 |
3315 | #define COEX_CU_RSRVD2_RP 4 | 3316 | #define COEX_CU_RSRVD2_RP 4 |
3316 | 3317 | ||
3317 | #define COEX_CU_UNASSOC_IDLE_WP 3 | 3318 | #define COEX_CU_UNASSOC_IDLE_WP 3 |
3318 | #define COEX_CU_UNASSOC_MANUAL_SCAN_WP 3 | 3319 | #define COEX_CU_UNASSOC_MANUAL_SCAN_WP 3 |
3319 | #define COEX_CU_UNASSOC_AUTO_SCAN_WP 3 | 3320 | #define COEX_CU_UNASSOC_AUTO_SCAN_WP 3 |
3320 | #define COEX_CU_CALIBRATION_WP 3 | 3321 | #define COEX_CU_CALIBRATION_WP 3 |
3321 | #define COEX_CU_PERIODIC_CALIBRATION_WP 3 | 3322 | #define COEX_CU_PERIODIC_CALIBRATION_WP 3 |
3322 | #define COEX_CU_CONNECTION_ESTAB_WP 3 | 3323 | #define COEX_CU_CONNECTION_ESTAB_WP 3 |
3323 | #define COEX_CU_ASSOCIATED_IDLE_WP 3 | 3324 | #define COEX_CU_ASSOCIATED_IDLE_WP 3 |
3324 | #define COEX_CU_ASSOC_MANUAL_SCAN_WP 3 | 3325 | #define COEX_CU_ASSOC_MANUAL_SCAN_WP 3 |
3325 | #define COEX_CU_ASSOC_AUTO_SCAN_WP 3 | 3326 | #define COEX_CU_ASSOC_AUTO_SCAN_WP 3 |
3326 | #define COEX_CU_ASSOC_ACTIVE_LEVEL_WP 3 | 3327 | #define COEX_CU_ASSOC_ACTIVE_LEVEL_WP 3 |
3327 | #define COEX_CU_RF_ON_WP 3 | 3328 | #define COEX_CU_RF_ON_WP 3 |
3328 | #define COEX_CU_RF_OFF_WP 3 | 3329 | #define COEX_CU_RF_OFF_WP 3 |
3329 | #define COEX_CU_STAND_ALONE_DEBUG_WP 6 | 3330 | #define COEX_CU_STAND_ALONE_DEBUG_WP 6 |
3330 | #define COEX_CU_IPAN_ASSOC_LEVEL_WP 3 | 3331 | #define COEX_CU_IPAN_ASSOC_LEVEL_WP 3 |
3331 | #define COEX_CU_RSRVD1_WP 3 | 3332 | #define COEX_CU_RSRVD1_WP 3 |
3332 | #define COEX_CU_RSRVD2_WP 3 | 3333 | #define COEX_CU_RSRVD2_WP 3 |
3333 | 3334 | ||
3334 | #define COEX_UNASSOC_IDLE_FLAGS 0 | 3335 | #define COEX_UNASSOC_IDLE_FLAGS 0 |
3335 | #define COEX_UNASSOC_MANUAL_SCAN_FLAGS \ | 3336 | #define COEX_UNASSOC_MANUAL_SCAN_FLAGS \ |
3336 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3337 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3337 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) | 3338 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) |
3338 | #define COEX_UNASSOC_AUTO_SCAN_FLAGS \ | 3339 | #define COEX_UNASSOC_AUTO_SCAN_FLAGS \ |
3339 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3340 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3340 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) | 3341 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) |
3341 | #define COEX_CALIBRATION_FLAGS \ | 3342 | #define COEX_CALIBRATION_FLAGS \ |
3342 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3343 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3343 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) | 3344 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) |
3344 | #define COEX_PERIODIC_CALIBRATION_FLAGS 0 | 3345 | #define COEX_PERIODIC_CALIBRATION_FLAGS 0 |
3345 | /* | 3346 | /* |
3346 | * COEX_CONNECTION_ESTAB: | 3347 | * COEX_CONNECTION_ESTAB: |
3347 | * we need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network. | 3348 | * we need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network. |
3348 | */ | 3349 | */ |
3349 | #define COEX_CONNECTION_ESTAB_FLAGS \ | 3350 | #define COEX_CONNECTION_ESTAB_FLAGS \ |
3350 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3351 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3351 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG | \ | 3352 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG | \ |
3352 | COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG) | 3353 | COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG) |
3353 | #define COEX_ASSOCIATED_IDLE_FLAGS 0 | 3354 | #define COEX_ASSOCIATED_IDLE_FLAGS 0 |
3354 | #define COEX_ASSOC_MANUAL_SCAN_FLAGS \ | 3355 | #define COEX_ASSOC_MANUAL_SCAN_FLAGS \ |
3355 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3356 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3356 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) | 3357 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) |
3357 | #define COEX_ASSOC_AUTO_SCAN_FLAGS \ | 3358 | #define COEX_ASSOC_AUTO_SCAN_FLAGS \ |
3358 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3359 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3359 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) | 3360 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) |
3360 | #define COEX_ASSOC_ACTIVE_LEVEL_FLAGS 0 | 3361 | #define COEX_ASSOC_ACTIVE_LEVEL_FLAGS 0 |
3361 | #define COEX_RF_ON_FLAGS 0 | 3362 | #define COEX_RF_ON_FLAGS 0 |
3362 | #define COEX_RF_OFF_FLAGS 0 | 3363 | #define COEX_RF_OFF_FLAGS 0 |
3363 | #define COEX_STAND_ALONE_DEBUG_FLAGS \ | 3364 | #define COEX_STAND_ALONE_DEBUG_FLAGS \ |
3364 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3365 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3365 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) | 3366 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG) |
3366 | #define COEX_IPAN_ASSOC_LEVEL_FLAGS \ | 3367 | #define COEX_IPAN_ASSOC_LEVEL_FLAGS \ |
3367 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3368 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3368 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG | \ | 3369 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG | \ |
3369 | COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG) | 3370 | COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG) |
3370 | #define COEX_RSRVD1_FLAGS 0 | 3371 | #define COEX_RSRVD1_FLAGS 0 |
3371 | #define COEX_RSRVD2_FLAGS 0 | 3372 | #define COEX_RSRVD2_FLAGS 0 |
3372 | /* | 3373 | /* |
3373 | * COEX_CU_RF_ON is the event wrapping all radio ownership. | 3374 | * COEX_CU_RF_ON is the event wrapping all radio ownership. |
3374 | * We need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network. | 3375 | * We need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network. |
3375 | */ | 3376 | */ |
3376 | #define COEX_CU_RF_ON_FLAGS \ | 3377 | #define COEX_CU_RF_ON_FLAGS \ |
3377 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ | 3378 | (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG | \ |
3378 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG | \ | 3379 | COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG | \ |
3379 | COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG) | 3380 | COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG) |
3380 | 3381 | ||
3381 | 3382 | ||
3382 | enum { | 3383 | enum { |
3383 | /* un-association part */ | 3384 | /* un-association part */ |
3384 | COEX_UNASSOC_IDLE = 0, | 3385 | COEX_UNASSOC_IDLE = 0, |
3385 | COEX_UNASSOC_MANUAL_SCAN = 1, | 3386 | COEX_UNASSOC_MANUAL_SCAN = 1, |
3386 | COEX_UNASSOC_AUTO_SCAN = 2, | 3387 | COEX_UNASSOC_AUTO_SCAN = 2, |
3387 | /* calibration */ | 3388 | /* calibration */ |
3388 | COEX_CALIBRATION = 3, | 3389 | COEX_CALIBRATION = 3, |
3389 | COEX_PERIODIC_CALIBRATION = 4, | 3390 | COEX_PERIODIC_CALIBRATION = 4, |
3390 | /* connection */ | 3391 | /* connection */ |
3391 | COEX_CONNECTION_ESTAB = 5, | 3392 | COEX_CONNECTION_ESTAB = 5, |
3392 | /* association part */ | 3393 | /* association part */ |
3393 | COEX_ASSOCIATED_IDLE = 6, | 3394 | COEX_ASSOCIATED_IDLE = 6, |
3394 | COEX_ASSOC_MANUAL_SCAN = 7, | 3395 | COEX_ASSOC_MANUAL_SCAN = 7, |
3395 | COEX_ASSOC_AUTO_SCAN = 8, | 3396 | COEX_ASSOC_AUTO_SCAN = 8, |
3396 | COEX_ASSOC_ACTIVE_LEVEL = 9, | 3397 | COEX_ASSOC_ACTIVE_LEVEL = 9, |
3397 | /* RF ON/OFF */ | 3398 | /* RF ON/OFF */ |
3398 | COEX_RF_ON = 10, | 3399 | COEX_RF_ON = 10, |
3399 | COEX_RF_OFF = 11, | 3400 | COEX_RF_OFF = 11, |
3400 | COEX_STAND_ALONE_DEBUG = 12, | 3401 | COEX_STAND_ALONE_DEBUG = 12, |
3401 | /* IPAN */ | 3402 | /* IPAN */ |
3402 | COEX_IPAN_ASSOC_LEVEL = 13, | 3403 | COEX_IPAN_ASSOC_LEVEL = 13, |
3403 | /* reserved */ | 3404 | /* reserved */ |
3404 | COEX_RSRVD1 = 14, | 3405 | COEX_RSRVD1 = 14, |
3405 | COEX_RSRVD2 = 15, | 3406 | COEX_RSRVD2 = 15, |
3406 | COEX_NUM_OF_EVENTS = 16 | 3407 | COEX_NUM_OF_EVENTS = 16 |
3407 | }; | 3408 | }; |
3408 | 3409 | ||
3409 | /* | 3410 | /* |
3410 | * Coexistence WIFI/WIMAX Command | 3411 | * Coexistence WIFI/WIMAX Command |
3411 | * COEX_PRIORITY_TABLE_CMD = 0x5a | 3412 | * COEX_PRIORITY_TABLE_CMD = 0x5a |
3412 | * | 3413 | * |
3413 | */ | 3414 | */ |
3414 | struct iwl_wimax_coex_event_entry { | 3415 | struct iwl_wimax_coex_event_entry { |
3415 | u8 request_prio; | 3416 | u8 request_prio; |
3416 | u8 win_medium_prio; | 3417 | u8 win_medium_prio; |
3417 | u8 reserved; | 3418 | u8 reserved; |
3418 | u8 flags; | 3419 | u8 flags; |
3419 | } __packed; | 3420 | } __packed; |
3420 | 3421 | ||
3421 | /* COEX flag masks */ | 3422 | /* COEX flag masks */ |
3422 | 3423 | ||
3423 | /* Station table is valid */ | 3424 | /* Station table is valid */ |
3424 | #define COEX_FLAGS_STA_TABLE_VALID_MSK (0x1) | 3425 | #define COEX_FLAGS_STA_TABLE_VALID_MSK (0x1) |
3425 | /* UnMask wake up src at unassociated sleep */ | 3426 | /* UnMask wake up src at unassociated sleep */ |
3426 | #define COEX_FLAGS_UNASSOC_WA_UNMASK_MSK (0x4) | 3427 | #define COEX_FLAGS_UNASSOC_WA_UNMASK_MSK (0x4) |
3427 | /* UnMask wake up src at associated sleep */ | 3428 | /* UnMask wake up src at associated sleep */ |
3428 | #define COEX_FLAGS_ASSOC_WA_UNMASK_MSK (0x8) | 3429 | #define COEX_FLAGS_ASSOC_WA_UNMASK_MSK (0x8) |
3429 | /* Enable CoEx feature. */ | 3430 | /* Enable CoEx feature. */ |
3430 | #define COEX_FLAGS_COEX_ENABLE_MSK (0x80) | 3431 | #define COEX_FLAGS_COEX_ENABLE_MSK (0x80) |
3431 | 3432 | ||
3432 | struct iwl_wimax_coex_cmd { | 3433 | struct iwl_wimax_coex_cmd { |
3433 | u8 flags; | 3434 | u8 flags; |
3434 | u8 reserved[3]; | 3435 | u8 reserved[3]; |
3435 | struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS]; | 3436 | struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS]; |
3436 | } __packed; | 3437 | } __packed; |
3437 | 3438 | ||
3438 | /* | 3439 | /* |
3439 | * Coexistence MEDIUM NOTIFICATION | 3440 | * Coexistence MEDIUM NOTIFICATION |
3440 | * COEX_MEDIUM_NOTIFICATION = 0x5b | 3441 | * COEX_MEDIUM_NOTIFICATION = 0x5b |
3441 | * | 3442 | * |
3442 | * notification from uCode to host to indicate medium changes | 3443 | * notification from uCode to host to indicate medium changes |
3443 | * | 3444 | * |
3444 | */ | 3445 | */ |
3445 | /* | 3446 | /* |
3446 | * status field | 3447 | * status field |
3447 | * bit 0 - 2: medium status | 3448 | * bit 0 - 2: medium status |
3448 | * bit 3: medium change indication | 3449 | * bit 3: medium change indication |
3449 | * bit 4 - 31: reserved | 3450 | * bit 4 - 31: reserved |
3450 | */ | 3451 | */ |
3451 | /* status option values, (0 - 2 bits) */ | 3452 | /* status option values, (0 - 2 bits) */ |
3452 | #define COEX_MEDIUM_BUSY (0x0) /* radio belongs to WiMAX */ | 3453 | #define COEX_MEDIUM_BUSY (0x0) /* radio belongs to WiMAX */ |
3453 | #define COEX_MEDIUM_ACTIVE (0x1) /* radio belongs to WiFi */ | 3454 | #define COEX_MEDIUM_ACTIVE (0x1) /* radio belongs to WiFi */ |
3454 | #define COEX_MEDIUM_PRE_RELEASE (0x2) /* received radio release */ | 3455 | #define COEX_MEDIUM_PRE_RELEASE (0x2) /* received radio release */ |
3455 | #define COEX_MEDIUM_MSK (0x7) | 3456 | #define COEX_MEDIUM_MSK (0x7) |
3456 | 3457 | ||
3457 | /* send notification status (1 bit) */ | 3458 | /* send notification status (1 bit) */ |
3458 | #define COEX_MEDIUM_CHANGED (0x8) | 3459 | #define COEX_MEDIUM_CHANGED (0x8) |
3459 | #define COEX_MEDIUM_CHANGED_MSK (0x8) | 3460 | #define COEX_MEDIUM_CHANGED_MSK (0x8) |
3460 | #define COEX_MEDIUM_SHIFT (3) | 3461 | #define COEX_MEDIUM_SHIFT (3) |
3461 | 3462 | ||
3462 | struct iwl_coex_medium_notification { | 3463 | struct iwl_coex_medium_notification { |
3463 | __le32 status; | 3464 | __le32 status; |
3464 | __le32 events; | 3465 | __le32 events; |
3465 | } __packed; | 3466 | } __packed; |
3466 | 3467 | ||
3467 | /* | 3468 | /* |
3468 | * Coexistence EVENT Command | 3469 | * Coexistence EVENT Command |
3469 | * COEX_EVENT_CMD = 0x5c | 3470 | * COEX_EVENT_CMD = 0x5c |
3470 | * | 3471 | * |
3471 | * send from host to uCode for coex event request. | 3472 | * send from host to uCode for coex event request. |
3472 | */ | 3473 | */ |
3473 | /* flags options */ | 3474 | /* flags options */ |
3474 | #define COEX_EVENT_REQUEST_MSK (0x1) | 3475 | #define COEX_EVENT_REQUEST_MSK (0x1) |
3475 | 3476 | ||
3476 | struct iwl_coex_event_cmd { | 3477 | struct iwl_coex_event_cmd { |
3477 | u8 flags; | 3478 | u8 flags; |
3478 | u8 event; | 3479 | u8 event; |
3479 | __le16 reserved; | 3480 | __le16 reserved; |
3480 | } __packed; | 3481 | } __packed; |
3481 | 3482 | ||
3482 | struct iwl_coex_event_resp { | 3483 | struct iwl_coex_event_resp { |
3483 | __le32 status; | 3484 | __le32 status; |
3484 | } __packed; | 3485 | } __packed; |
3485 | 3486 | ||
3486 | 3487 | ||
3487 | /****************************************************************************** | 3488 | /****************************************************************************** |
3488 | * Bluetooth Coexistence commands | 3489 | * Bluetooth Coexistence commands |
3489 | * | 3490 | * |
3490 | *****************************************************************************/ | 3491 | *****************************************************************************/ |
3491 | 3492 | ||
3492 | /* | 3493 | /* |
3493 | * BT Status notification | 3494 | * BT Status notification |
3494 | * REPLY_BT_COEX_PROFILE_NOTIF = 0xce | 3495 | * REPLY_BT_COEX_PROFILE_NOTIF = 0xce |
3495 | */ | 3496 | */ |
3496 | enum iwl_bt_coex_profile_traffic_load { | 3497 | enum iwl_bt_coex_profile_traffic_load { |
3497 | IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0, | 3498 | IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0, |
3498 | IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1, | 3499 | IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1, |
3499 | IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2, | 3500 | IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2, |
3500 | IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3, | 3501 | IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3, |
3501 | /* | 3502 | /* |
3502 | * There are no more even though below is a u8, the | 3503 | * There are no more even though below is a u8, the |
3503 | * indication from the BT device only has two bits. | 3504 | * indication from the BT device only has two bits. |
3504 | */ | 3505 | */ |
3505 | }; | 3506 | }; |
3506 | 3507 | ||
3507 | #define BT_SESSION_ACTIVITY_1_UART_MSG 0x1 | 3508 | #define BT_SESSION_ACTIVITY_1_UART_MSG 0x1 |
3508 | #define BT_SESSION_ACTIVITY_2_UART_MSG 0x2 | 3509 | #define BT_SESSION_ACTIVITY_2_UART_MSG 0x2 |
3509 | 3510 | ||
3510 | /* BT UART message - Share Part (BT -> WiFi) */ | 3511 | /* BT UART message - Share Part (BT -> WiFi) */ |
3511 | #define BT_UART_MSG_FRAME1MSGTYPE_POS (0) | 3512 | #define BT_UART_MSG_FRAME1MSGTYPE_POS (0) |
3512 | #define BT_UART_MSG_FRAME1MSGTYPE_MSK \ | 3513 | #define BT_UART_MSG_FRAME1MSGTYPE_MSK \ |
3513 | (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS) | 3514 | (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS) |
3514 | #define BT_UART_MSG_FRAME1SSN_POS (3) | 3515 | #define BT_UART_MSG_FRAME1SSN_POS (3) |
3515 | #define BT_UART_MSG_FRAME1SSN_MSK \ | 3516 | #define BT_UART_MSG_FRAME1SSN_MSK \ |
3516 | (0x3 << BT_UART_MSG_FRAME1SSN_POS) | 3517 | (0x3 << BT_UART_MSG_FRAME1SSN_POS) |
3517 | #define BT_UART_MSG_FRAME1UPDATEREQ_POS (5) | 3518 | #define BT_UART_MSG_FRAME1UPDATEREQ_POS (5) |
3518 | #define BT_UART_MSG_FRAME1UPDATEREQ_MSK \ | 3519 | #define BT_UART_MSG_FRAME1UPDATEREQ_MSK \ |
3519 | (0x1 << BT_UART_MSG_FRAME1UPDATEREQ_POS) | 3520 | (0x1 << BT_UART_MSG_FRAME1UPDATEREQ_POS) |
3520 | #define BT_UART_MSG_FRAME1RESERVED_POS (6) | 3521 | #define BT_UART_MSG_FRAME1RESERVED_POS (6) |
3521 | #define BT_UART_MSG_FRAME1RESERVED_MSK \ | 3522 | #define BT_UART_MSG_FRAME1RESERVED_MSK \ |
3522 | (0x3 << BT_UART_MSG_FRAME1RESERVED_POS) | 3523 | (0x3 << BT_UART_MSG_FRAME1RESERVED_POS) |
3523 | 3524 | ||
3524 | #define BT_UART_MSG_FRAME2OPENCONNECTIONS_POS (0) | 3525 | #define BT_UART_MSG_FRAME2OPENCONNECTIONS_POS (0) |
3525 | #define BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK \ | 3526 | #define BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK \ |
3526 | (0x3 << BT_UART_MSG_FRAME2OPENCONNECTIONS_POS) | 3527 | (0x3 << BT_UART_MSG_FRAME2OPENCONNECTIONS_POS) |
3527 | #define BT_UART_MSG_FRAME2TRAFFICLOAD_POS (2) | 3528 | #define BT_UART_MSG_FRAME2TRAFFICLOAD_POS (2) |
3528 | #define BT_UART_MSG_FRAME2TRAFFICLOAD_MSK \ | 3529 | #define BT_UART_MSG_FRAME2TRAFFICLOAD_MSK \ |
3529 | (0x3 << BT_UART_MSG_FRAME2TRAFFICLOAD_POS) | 3530 | (0x3 << BT_UART_MSG_FRAME2TRAFFICLOAD_POS) |
3530 | #define BT_UART_MSG_FRAME2CHLSEQN_POS (4) | 3531 | #define BT_UART_MSG_FRAME2CHLSEQN_POS (4) |
3531 | #define BT_UART_MSG_FRAME2CHLSEQN_MSK \ | 3532 | #define BT_UART_MSG_FRAME2CHLSEQN_MSK \ |
3532 | (0x1 << BT_UART_MSG_FRAME2CHLSEQN_POS) | 3533 | (0x1 << BT_UART_MSG_FRAME2CHLSEQN_POS) |
3533 | #define BT_UART_MSG_FRAME2INBAND_POS (5) | 3534 | #define BT_UART_MSG_FRAME2INBAND_POS (5) |
3534 | #define BT_UART_MSG_FRAME2INBAND_MSK \ | 3535 | #define BT_UART_MSG_FRAME2INBAND_MSK \ |
3535 | (0x1 << BT_UART_MSG_FRAME2INBAND_POS) | 3536 | (0x1 << BT_UART_MSG_FRAME2INBAND_POS) |
3536 | #define BT_UART_MSG_FRAME2RESERVED_POS (6) | 3537 | #define BT_UART_MSG_FRAME2RESERVED_POS (6) |
3537 | #define BT_UART_MSG_FRAME2RESERVED_MSK \ | 3538 | #define BT_UART_MSG_FRAME2RESERVED_MSK \ |
3538 | (0x3 << BT_UART_MSG_FRAME2RESERVED_POS) | 3539 | (0x3 << BT_UART_MSG_FRAME2RESERVED_POS) |
3539 | 3540 | ||
3540 | #define BT_UART_MSG_FRAME3SCOESCO_POS (0) | 3541 | #define BT_UART_MSG_FRAME3SCOESCO_POS (0) |
3541 | #define BT_UART_MSG_FRAME3SCOESCO_MSK \ | 3542 | #define BT_UART_MSG_FRAME3SCOESCO_MSK \ |
3542 | (0x1 << BT_UART_MSG_FRAME3SCOESCO_POS) | 3543 | (0x1 << BT_UART_MSG_FRAME3SCOESCO_POS) |
3543 | #define BT_UART_MSG_FRAME3SNIFF_POS (1) | 3544 | #define BT_UART_MSG_FRAME3SNIFF_POS (1) |
3544 | #define BT_UART_MSG_FRAME3SNIFF_MSK \ | 3545 | #define BT_UART_MSG_FRAME3SNIFF_MSK \ |
3545 | (0x1 << BT_UART_MSG_FRAME3SNIFF_POS) | 3546 | (0x1 << BT_UART_MSG_FRAME3SNIFF_POS) |
3546 | #define BT_UART_MSG_FRAME3A2DP_POS (2) | 3547 | #define BT_UART_MSG_FRAME3A2DP_POS (2) |
3547 | #define BT_UART_MSG_FRAME3A2DP_MSK \ | 3548 | #define BT_UART_MSG_FRAME3A2DP_MSK \ |
3548 | (0x1 << BT_UART_MSG_FRAME3A2DP_POS) | 3549 | (0x1 << BT_UART_MSG_FRAME3A2DP_POS) |
3549 | #define BT_UART_MSG_FRAME3ACL_POS (3) | 3550 | #define BT_UART_MSG_FRAME3ACL_POS (3) |
3550 | #define BT_UART_MSG_FRAME3ACL_MSK \ | 3551 | #define BT_UART_MSG_FRAME3ACL_MSK \ |
3551 | (0x1 << BT_UART_MSG_FRAME3ACL_POS) | 3552 | (0x1 << BT_UART_MSG_FRAME3ACL_POS) |
3552 | #define BT_UART_MSG_FRAME3MASTER_POS (4) | 3553 | #define BT_UART_MSG_FRAME3MASTER_POS (4) |
3553 | #define BT_UART_MSG_FRAME3MASTER_MSK \ | 3554 | #define BT_UART_MSG_FRAME3MASTER_MSK \ |
3554 | (0x1 << BT_UART_MSG_FRAME3MASTER_POS) | 3555 | (0x1 << BT_UART_MSG_FRAME3MASTER_POS) |
3555 | #define BT_UART_MSG_FRAME3OBEX_POS (5) | 3556 | #define BT_UART_MSG_FRAME3OBEX_POS (5) |
3556 | #define BT_UART_MSG_FRAME3OBEX_MSK \ | 3557 | #define BT_UART_MSG_FRAME3OBEX_MSK \ |
3557 | (0x1 << BT_UART_MSG_FRAME3OBEX_POS) | 3558 | (0x1 << BT_UART_MSG_FRAME3OBEX_POS) |
3558 | #define BT_UART_MSG_FRAME3RESERVED_POS (6) | 3559 | #define BT_UART_MSG_FRAME3RESERVED_POS (6) |
3559 | #define BT_UART_MSG_FRAME3RESERVED_MSK \ | 3560 | #define BT_UART_MSG_FRAME3RESERVED_MSK \ |
3560 | (0x3 << BT_UART_MSG_FRAME3RESERVED_POS) | 3561 | (0x3 << BT_UART_MSG_FRAME3RESERVED_POS) |
3561 | 3562 | ||
3562 | #define BT_UART_MSG_FRAME4IDLEDURATION_POS (0) | 3563 | #define BT_UART_MSG_FRAME4IDLEDURATION_POS (0) |
3563 | #define BT_UART_MSG_FRAME4IDLEDURATION_MSK \ | 3564 | #define BT_UART_MSG_FRAME4IDLEDURATION_MSK \ |
3564 | (0x3F << BT_UART_MSG_FRAME4IDLEDURATION_POS) | 3565 | (0x3F << BT_UART_MSG_FRAME4IDLEDURATION_POS) |
3565 | #define BT_UART_MSG_FRAME4RESERVED_POS (6) | 3566 | #define BT_UART_MSG_FRAME4RESERVED_POS (6) |
3566 | #define BT_UART_MSG_FRAME4RESERVED_MSK \ | 3567 | #define BT_UART_MSG_FRAME4RESERVED_MSK \ |
3567 | (0x3 << BT_UART_MSG_FRAME4RESERVED_POS) | 3568 | (0x3 << BT_UART_MSG_FRAME4RESERVED_POS) |
3568 | 3569 | ||
3569 | #define BT_UART_MSG_FRAME5TXACTIVITY_POS (0) | 3570 | #define BT_UART_MSG_FRAME5TXACTIVITY_POS (0) |
3570 | #define BT_UART_MSG_FRAME5TXACTIVITY_MSK \ | 3571 | #define BT_UART_MSG_FRAME5TXACTIVITY_MSK \ |
3571 | (0x3 << BT_UART_MSG_FRAME5TXACTIVITY_POS) | 3572 | (0x3 << BT_UART_MSG_FRAME5TXACTIVITY_POS) |
3572 | #define BT_UART_MSG_FRAME5RXACTIVITY_POS (2) | 3573 | #define BT_UART_MSG_FRAME5RXACTIVITY_POS (2) |
3573 | #define BT_UART_MSG_FRAME5RXACTIVITY_MSK \ | 3574 | #define BT_UART_MSG_FRAME5RXACTIVITY_MSK \ |
3574 | (0x3 << BT_UART_MSG_FRAME5RXACTIVITY_POS) | 3575 | (0x3 << BT_UART_MSG_FRAME5RXACTIVITY_POS) |
3575 | #define BT_UART_MSG_FRAME5ESCORETRANSMIT_POS (4) | 3576 | #define BT_UART_MSG_FRAME5ESCORETRANSMIT_POS (4) |
3576 | #define BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK \ | 3577 | #define BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK \ |
3577 | (0x3 << BT_UART_MSG_FRAME5ESCORETRANSMIT_POS) | 3578 | (0x3 << BT_UART_MSG_FRAME5ESCORETRANSMIT_POS) |
3578 | #define BT_UART_MSG_FRAME5RESERVED_POS (6) | 3579 | #define BT_UART_MSG_FRAME5RESERVED_POS (6) |
3579 | #define BT_UART_MSG_FRAME5RESERVED_MSK \ | 3580 | #define BT_UART_MSG_FRAME5RESERVED_MSK \ |
3580 | (0x3 << BT_UART_MSG_FRAME5RESERVED_POS) | 3581 | (0x3 << BT_UART_MSG_FRAME5RESERVED_POS) |
3581 | 3582 | ||
3582 | #define BT_UART_MSG_FRAME6SNIFFINTERVAL_POS (0) | 3583 | #define BT_UART_MSG_FRAME6SNIFFINTERVAL_POS (0) |
3583 | #define BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK \ | 3584 | #define BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK \ |
3584 | (0x1F << BT_UART_MSG_FRAME6SNIFFINTERVAL_POS) | 3585 | (0x1F << BT_UART_MSG_FRAME6SNIFFINTERVAL_POS) |
3585 | #define BT_UART_MSG_FRAME6DISCOVERABLE_POS (5) | 3586 | #define BT_UART_MSG_FRAME6DISCOVERABLE_POS (5) |
3586 | #define BT_UART_MSG_FRAME6DISCOVERABLE_MSK \ | 3587 | #define BT_UART_MSG_FRAME6DISCOVERABLE_MSK \ |
3587 | (0x1 << BT_UART_MSG_FRAME6DISCOVERABLE_POS) | 3588 | (0x1 << BT_UART_MSG_FRAME6DISCOVERABLE_POS) |
3588 | #define BT_UART_MSG_FRAME6RESERVED_POS (6) | 3589 | #define BT_UART_MSG_FRAME6RESERVED_POS (6) |
3589 | #define BT_UART_MSG_FRAME6RESERVED_MSK \ | 3590 | #define BT_UART_MSG_FRAME6RESERVED_MSK \ |
3590 | (0x3 << BT_UART_MSG_FRAME6RESERVED_POS) | 3591 | (0x3 << BT_UART_MSG_FRAME6RESERVED_POS) |
3591 | 3592 | ||
3592 | #define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0) | 3593 | #define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0) |
3593 | #define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \ | 3594 | #define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \ |
3594 | (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS) | 3595 | (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS) |
3595 | #define BT_UART_MSG_FRAME7PAGE_POS (3) | 3596 | #define BT_UART_MSG_FRAME7PAGE_POS (3) |
3596 | #define BT_UART_MSG_FRAME7PAGE_MSK \ | 3597 | #define BT_UART_MSG_FRAME7PAGE_MSK \ |
3597 | (0x1 << BT_UART_MSG_FRAME7PAGE_POS) | 3598 | (0x1 << BT_UART_MSG_FRAME7PAGE_POS) |
3598 | #define BT_UART_MSG_FRAME7INQUIRY_POS (4) | 3599 | #define BT_UART_MSG_FRAME7INQUIRY_POS (4) |
3599 | #define BT_UART_MSG_FRAME7INQUIRY_MSK \ | 3600 | #define BT_UART_MSG_FRAME7INQUIRY_MSK \ |
3600 | (0x1 << BT_UART_MSG_FRAME7INQUIRY_POS) | 3601 | (0x1 << BT_UART_MSG_FRAME7INQUIRY_POS) |
3601 | #define BT_UART_MSG_FRAME7CONNECTABLE_POS (5) | 3602 | #define BT_UART_MSG_FRAME7CONNECTABLE_POS (5) |
3602 | #define BT_UART_MSG_FRAME7CONNECTABLE_MSK \ | 3603 | #define BT_UART_MSG_FRAME7CONNECTABLE_MSK \ |
3603 | (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS) | 3604 | (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS) |
3604 | #define BT_UART_MSG_FRAME7RESERVED_POS (6) | 3605 | #define BT_UART_MSG_FRAME7RESERVED_POS (6) |
3605 | #define BT_UART_MSG_FRAME7RESERVED_MSK \ | 3606 | #define BT_UART_MSG_FRAME7RESERVED_MSK \ |
3606 | (0x3 << BT_UART_MSG_FRAME7RESERVED_POS) | 3607 | (0x3 << BT_UART_MSG_FRAME7RESERVED_POS) |
3607 | 3608 | ||
3608 | /* BT Session Activity 2 UART message (BT -> WiFi) */ | 3609 | /* BT Session Activity 2 UART message (BT -> WiFi) */ |
3609 | #define BT_UART_MSG_2_FRAME1RESERVED1_POS (5) | 3610 | #define BT_UART_MSG_2_FRAME1RESERVED1_POS (5) |
3610 | #define BT_UART_MSG_2_FRAME1RESERVED1_MSK \ | 3611 | #define BT_UART_MSG_2_FRAME1RESERVED1_MSK \ |
3611 | (0x1<<BT_UART_MSG_2_FRAME1RESERVED1_POS) | 3612 | (0x1<<BT_UART_MSG_2_FRAME1RESERVED1_POS) |
3612 | #define BT_UART_MSG_2_FRAME1RESERVED2_POS (6) | 3613 | #define BT_UART_MSG_2_FRAME1RESERVED2_POS (6) |
3613 | #define BT_UART_MSG_2_FRAME1RESERVED2_MSK \ | 3614 | #define BT_UART_MSG_2_FRAME1RESERVED2_MSK \ |
3614 | (0x3<<BT_UART_MSG_2_FRAME1RESERVED2_POS) | 3615 | (0x3<<BT_UART_MSG_2_FRAME1RESERVED2_POS) |
3615 | 3616 | ||
3616 | #define BT_UART_MSG_2_FRAME2AGGTRAFFICLOAD_POS (0) | 3617 | #define BT_UART_MSG_2_FRAME2AGGTRAFFICLOAD_POS (0) |
3617 | #define BT_UART_MSG_2_FRAME2AGGTRAFFICLOAD_MSK \ | 3618 | #define BT_UART_MSG_2_FRAME2AGGTRAFFICLOAD_MSK \ |
3618 | (0x3F<<BT_UART_MSG_2_FRAME2AGGTRAFFICLOAD_POS) | 3619 | (0x3F<<BT_UART_MSG_2_FRAME2AGGTRAFFICLOAD_POS) |
3619 | #define BT_UART_MSG_2_FRAME2RESERVED_POS (6) | 3620 | #define BT_UART_MSG_2_FRAME2RESERVED_POS (6) |
3620 | #define BT_UART_MSG_2_FRAME2RESERVED_MSK \ | 3621 | #define BT_UART_MSG_2_FRAME2RESERVED_MSK \ |
3621 | (0x3<<BT_UART_MSG_2_FRAME2RESERVED_POS) | 3622 | (0x3<<BT_UART_MSG_2_FRAME2RESERVED_POS) |
3622 | 3623 | ||
3623 | #define BT_UART_MSG_2_FRAME3BRLASTTXPOWER_POS (0) | 3624 | #define BT_UART_MSG_2_FRAME3BRLASTTXPOWER_POS (0) |
3624 | #define BT_UART_MSG_2_FRAME3BRLASTTXPOWER_MSK \ | 3625 | #define BT_UART_MSG_2_FRAME3BRLASTTXPOWER_MSK \ |
3625 | (0xF<<BT_UART_MSG_2_FRAME3BRLASTTXPOWER_POS) | 3626 | (0xF<<BT_UART_MSG_2_FRAME3BRLASTTXPOWER_POS) |
3626 | #define BT_UART_MSG_2_FRAME3INQPAGESRMODE_POS (4) | 3627 | #define BT_UART_MSG_2_FRAME3INQPAGESRMODE_POS (4) |
3627 | #define BT_UART_MSG_2_FRAME3INQPAGESRMODE_MSK \ | 3628 | #define BT_UART_MSG_2_FRAME3INQPAGESRMODE_MSK \ |
3628 | (0x1<<BT_UART_MSG_2_FRAME3INQPAGESRMODE_POS) | 3629 | (0x1<<BT_UART_MSG_2_FRAME3INQPAGESRMODE_POS) |
3629 | #define BT_UART_MSG_2_FRAME3LEMASTER_POS (5) | 3630 | #define BT_UART_MSG_2_FRAME3LEMASTER_POS (5) |
3630 | #define BT_UART_MSG_2_FRAME3LEMASTER_MSK \ | 3631 | #define BT_UART_MSG_2_FRAME3LEMASTER_MSK \ |
3631 | (0x1<<BT_UART_MSG_2_FRAME3LEMASTER_POS) | 3632 | (0x1<<BT_UART_MSG_2_FRAME3LEMASTER_POS) |
3632 | #define BT_UART_MSG_2_FRAME3RESERVED_POS (6) | 3633 | #define BT_UART_MSG_2_FRAME3RESERVED_POS (6) |
3633 | #define BT_UART_MSG_2_FRAME3RESERVED_MSK \ | 3634 | #define BT_UART_MSG_2_FRAME3RESERVED_MSK \ |
3634 | (0x3<<BT_UART_MSG_2_FRAME3RESERVED_POS) | 3635 | (0x3<<BT_UART_MSG_2_FRAME3RESERVED_POS) |
3635 | 3636 | ||
3636 | #define BT_UART_MSG_2_FRAME4LELASTTXPOWER_POS (0) | 3637 | #define BT_UART_MSG_2_FRAME4LELASTTXPOWER_POS (0) |
3637 | #define BT_UART_MSG_2_FRAME4LELASTTXPOWER_MSK \ | 3638 | #define BT_UART_MSG_2_FRAME4LELASTTXPOWER_MSK \ |
3638 | (0xF<<BT_UART_MSG_2_FRAME4LELASTTXPOWER_POS) | 3639 | (0xF<<BT_UART_MSG_2_FRAME4LELASTTXPOWER_POS) |
3639 | #define BT_UART_MSG_2_FRAME4NUMLECONN_POS (4) | 3640 | #define BT_UART_MSG_2_FRAME4NUMLECONN_POS (4) |
3640 | #define BT_UART_MSG_2_FRAME4NUMLECONN_MSK \ | 3641 | #define BT_UART_MSG_2_FRAME4NUMLECONN_MSK \ |
3641 | (0x3<<BT_UART_MSG_2_FRAME4NUMLECONN_POS) | 3642 | (0x3<<BT_UART_MSG_2_FRAME4NUMLECONN_POS) |
3642 | #define BT_UART_MSG_2_FRAME4RESERVED_POS (6) | 3643 | #define BT_UART_MSG_2_FRAME4RESERVED_POS (6) |
3643 | #define BT_UART_MSG_2_FRAME4RESERVED_MSK \ | 3644 | #define BT_UART_MSG_2_FRAME4RESERVED_MSK \ |
3644 | (0x3<<BT_UART_MSG_2_FRAME4RESERVED_POS) | 3645 | (0x3<<BT_UART_MSG_2_FRAME4RESERVED_POS) |
3645 | 3646 | ||
3646 | #define BT_UART_MSG_2_FRAME5BTMINRSSI_POS (0) | 3647 | #define BT_UART_MSG_2_FRAME5BTMINRSSI_POS (0) |
3647 | #define BT_UART_MSG_2_FRAME5BTMINRSSI_MSK \ | 3648 | #define BT_UART_MSG_2_FRAME5BTMINRSSI_MSK \ |
3648 | (0xF<<BT_UART_MSG_2_FRAME5BTMINRSSI_POS) | 3649 | (0xF<<BT_UART_MSG_2_FRAME5BTMINRSSI_POS) |
3649 | #define BT_UART_MSG_2_FRAME5LESCANINITMODE_POS (4) | 3650 | #define BT_UART_MSG_2_FRAME5LESCANINITMODE_POS (4) |
3650 | #define BT_UART_MSG_2_FRAME5LESCANINITMODE_MSK \ | 3651 | #define BT_UART_MSG_2_FRAME5LESCANINITMODE_MSK \ |
3651 | (0x1<<BT_UART_MSG_2_FRAME5LESCANINITMODE_POS) | 3652 | (0x1<<BT_UART_MSG_2_FRAME5LESCANINITMODE_POS) |
3652 | #define BT_UART_MSG_2_FRAME5LEADVERMODE_POS (5) | 3653 | #define BT_UART_MSG_2_FRAME5LEADVERMODE_POS (5) |
3653 | #define BT_UART_MSG_2_FRAME5LEADVERMODE_MSK \ | 3654 | #define BT_UART_MSG_2_FRAME5LEADVERMODE_MSK \ |
3654 | (0x1<<BT_UART_MSG_2_FRAME5LEADVERMODE_POS) | 3655 | (0x1<<BT_UART_MSG_2_FRAME5LEADVERMODE_POS) |
3655 | #define BT_UART_MSG_2_FRAME5RESERVED_POS (6) | 3656 | #define BT_UART_MSG_2_FRAME5RESERVED_POS (6) |
3656 | #define BT_UART_MSG_2_FRAME5RESERVED_MSK \ | 3657 | #define BT_UART_MSG_2_FRAME5RESERVED_MSK \ |
3657 | (0x3<<BT_UART_MSG_2_FRAME5RESERVED_POS) | 3658 | (0x3<<BT_UART_MSG_2_FRAME5RESERVED_POS) |
3658 | 3659 | ||
3659 | #define BT_UART_MSG_2_FRAME6LECONNINTERVAL_POS (0) | 3660 | #define BT_UART_MSG_2_FRAME6LECONNINTERVAL_POS (0) |
3660 | #define BT_UART_MSG_2_FRAME6LECONNINTERVAL_MSK \ | 3661 | #define BT_UART_MSG_2_FRAME6LECONNINTERVAL_MSK \ |
3661 | (0x1F<<BT_UART_MSG_2_FRAME6LECONNINTERVAL_POS) | 3662 | (0x1F<<BT_UART_MSG_2_FRAME6LECONNINTERVAL_POS) |
3662 | #define BT_UART_MSG_2_FRAME6RFU_POS (5) | 3663 | #define BT_UART_MSG_2_FRAME6RFU_POS (5) |
3663 | #define BT_UART_MSG_2_FRAME6RFU_MSK \ | 3664 | #define BT_UART_MSG_2_FRAME6RFU_MSK \ |
3664 | (0x1<<BT_UART_MSG_2_FRAME6RFU_POS) | 3665 | (0x1<<BT_UART_MSG_2_FRAME6RFU_POS) |
3665 | #define BT_UART_MSG_2_FRAME6RESERVED_POS (6) | 3666 | #define BT_UART_MSG_2_FRAME6RESERVED_POS (6) |
3666 | #define BT_UART_MSG_2_FRAME6RESERVED_MSK \ | 3667 | #define BT_UART_MSG_2_FRAME6RESERVED_MSK \ |
3667 | (0x3<<BT_UART_MSG_2_FRAME6RESERVED_POS) | 3668 | (0x3<<BT_UART_MSG_2_FRAME6RESERVED_POS) |
3668 | 3669 | ||
3669 | #define BT_UART_MSG_2_FRAME7LECONNSLAVELAT_POS (0) | 3670 | #define BT_UART_MSG_2_FRAME7LECONNSLAVELAT_POS (0) |
3670 | #define BT_UART_MSG_2_FRAME7LECONNSLAVELAT_MSK \ | 3671 | #define BT_UART_MSG_2_FRAME7LECONNSLAVELAT_MSK \ |
3671 | (0x7<<BT_UART_MSG_2_FRAME7LECONNSLAVELAT_POS) | 3672 | (0x7<<BT_UART_MSG_2_FRAME7LECONNSLAVELAT_POS) |
3672 | #define BT_UART_MSG_2_FRAME7LEPROFILE1_POS (3) | 3673 | #define BT_UART_MSG_2_FRAME7LEPROFILE1_POS (3) |
3673 | #define BT_UART_MSG_2_FRAME7LEPROFILE1_MSK \ | 3674 | #define BT_UART_MSG_2_FRAME7LEPROFILE1_MSK \ |
3674 | (0x1<<BT_UART_MSG_2_FRAME7LEPROFILE1_POS) | 3675 | (0x1<<BT_UART_MSG_2_FRAME7LEPROFILE1_POS) |
3675 | #define BT_UART_MSG_2_FRAME7LEPROFILE2_POS (4) | 3676 | #define BT_UART_MSG_2_FRAME7LEPROFILE2_POS (4) |
3676 | #define BT_UART_MSG_2_FRAME7LEPROFILE2_MSK \ | 3677 | #define BT_UART_MSG_2_FRAME7LEPROFILE2_MSK \ |
3677 | (0x1<<BT_UART_MSG_2_FRAME7LEPROFILE2_POS) | 3678 | (0x1<<BT_UART_MSG_2_FRAME7LEPROFILE2_POS) |
3678 | #define BT_UART_MSG_2_FRAME7LEPROFILEOTHER_POS (5) | 3679 | #define BT_UART_MSG_2_FRAME7LEPROFILEOTHER_POS (5) |
3679 | #define BT_UART_MSG_2_FRAME7LEPROFILEOTHER_MSK \ | 3680 | #define BT_UART_MSG_2_FRAME7LEPROFILEOTHER_MSK \ |
3680 | (0x1<<BT_UART_MSG_2_FRAME7LEPROFILEOTHER_POS) | 3681 | (0x1<<BT_UART_MSG_2_FRAME7LEPROFILEOTHER_POS) |
3681 | #define BT_UART_MSG_2_FRAME7RESERVED_POS (6) | 3682 | #define BT_UART_MSG_2_FRAME7RESERVED_POS (6) |
3682 | #define BT_UART_MSG_2_FRAME7RESERVED_MSK \ | 3683 | #define BT_UART_MSG_2_FRAME7RESERVED_MSK \ |
3683 | (0x3<<BT_UART_MSG_2_FRAME7RESERVED_POS) | 3684 | (0x3<<BT_UART_MSG_2_FRAME7RESERVED_POS) |
3684 | 3685 | ||
3685 | 3686 | ||
3686 | #define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62) | 3687 | #define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62) |
3687 | #define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) | 3688 | #define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) |
3688 | 3689 | ||
3689 | struct iwl_bt_uart_msg { | 3690 | struct iwl_bt_uart_msg { |
3690 | u8 header; | 3691 | u8 header; |
3691 | u8 frame1; | 3692 | u8 frame1; |
3692 | u8 frame2; | 3693 | u8 frame2; |
3693 | u8 frame3; | 3694 | u8 frame3; |
3694 | u8 frame4; | 3695 | u8 frame4; |
3695 | u8 frame5; | 3696 | u8 frame5; |
3696 | u8 frame6; | 3697 | u8 frame6; |
3697 | u8 frame7; | 3698 | u8 frame7; |
3698 | } __attribute__((packed)); | 3699 | } __attribute__((packed)); |
3699 | 3700 | ||
3700 | struct iwl_bt_coex_profile_notif { | 3701 | struct iwl_bt_coex_profile_notif { |
3701 | struct iwl_bt_uart_msg last_bt_uart_msg; | 3702 | struct iwl_bt_uart_msg last_bt_uart_msg; |
3702 | u8 bt_status; /* 0 - off, 1 - on */ | 3703 | u8 bt_status; /* 0 - off, 1 - on */ |
3703 | u8 bt_traffic_load; /* 0 .. 3? */ | 3704 | u8 bt_traffic_load; /* 0 .. 3? */ |
3704 | u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ | 3705 | u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ |
3705 | u8 reserved; | 3706 | u8 reserved; |
3706 | } __attribute__((packed)); | 3707 | } __attribute__((packed)); |
3707 | 3708 | ||
3708 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 | 3709 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 |
3709 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 | 3710 | #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 |
3710 | #define IWL_BT_COEX_PRIO_TBL_PRIO_POS 1 | 3711 | #define IWL_BT_COEX_PRIO_TBL_PRIO_POS 1 |
3711 | #define IWL_BT_COEX_PRIO_TBL_PRIO_MASK 0x0e | 3712 | #define IWL_BT_COEX_PRIO_TBL_PRIO_MASK 0x0e |
3712 | #define IWL_BT_COEX_PRIO_TBL_RESERVED_POS 4 | 3713 | #define IWL_BT_COEX_PRIO_TBL_RESERVED_POS 4 |
3713 | #define IWL_BT_COEX_PRIO_TBL_RESERVED_MASK 0xf0 | 3714 | #define IWL_BT_COEX_PRIO_TBL_RESERVED_MASK 0xf0 |
3714 | #define IWL_BT_COEX_PRIO_TBL_PRIO_SHIFT 1 | 3715 | #define IWL_BT_COEX_PRIO_TBL_PRIO_SHIFT 1 |
3715 | 3716 | ||
3716 | /* | 3717 | /* |
3717 | * BT Coexistence Priority table | 3718 | * BT Coexistence Priority table |
3718 | * REPLY_BT_COEX_PRIO_TABLE = 0xcc | 3719 | * REPLY_BT_COEX_PRIO_TABLE = 0xcc |
3719 | */ | 3720 | */ |
3720 | enum bt_coex_prio_table_events { | 3721 | enum bt_coex_prio_table_events { |
3721 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, | 3722 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, |
3722 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, | 3723 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, |
3723 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, | 3724 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, |
3724 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, /* DC calib */ | 3725 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, /* DC calib */ |
3725 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, | 3726 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, |
3726 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, | 3727 | BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, |
3727 | BT_COEX_PRIO_TBL_EVT_DTIM = 6, | 3728 | BT_COEX_PRIO_TBL_EVT_DTIM = 6, |
3728 | BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, | 3729 | BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, |
3729 | BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, | 3730 | BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, |
3730 | BT_COEX_PRIO_TBL_EVT_RESERVED0 = 9, | 3731 | BT_COEX_PRIO_TBL_EVT_RESERVED0 = 9, |
3731 | BT_COEX_PRIO_TBL_EVT_RESERVED1 = 10, | 3732 | BT_COEX_PRIO_TBL_EVT_RESERVED1 = 10, |
3732 | BT_COEX_PRIO_TBL_EVT_RESERVED2 = 11, | 3733 | BT_COEX_PRIO_TBL_EVT_RESERVED2 = 11, |
3733 | BT_COEX_PRIO_TBL_EVT_RESERVED3 = 12, | 3734 | BT_COEX_PRIO_TBL_EVT_RESERVED3 = 12, |
3734 | BT_COEX_PRIO_TBL_EVT_RESERVED4 = 13, | 3735 | BT_COEX_PRIO_TBL_EVT_RESERVED4 = 13, |
3735 | BT_COEX_PRIO_TBL_EVT_RESERVED5 = 14, | 3736 | BT_COEX_PRIO_TBL_EVT_RESERVED5 = 14, |
3736 | BT_COEX_PRIO_TBL_EVT_RESERVED6 = 15, | 3737 | BT_COEX_PRIO_TBL_EVT_RESERVED6 = 15, |
3737 | /* BT_COEX_PRIO_TBL_EVT_MAX should always be last */ | 3738 | /* BT_COEX_PRIO_TBL_EVT_MAX should always be last */ |
3738 | BT_COEX_PRIO_TBL_EVT_MAX, | 3739 | BT_COEX_PRIO_TBL_EVT_MAX, |
3739 | }; | 3740 | }; |
3740 | 3741 | ||
3741 | enum bt_coex_prio_table_priorities { | 3742 | enum bt_coex_prio_table_priorities { |
3742 | BT_COEX_PRIO_TBL_DISABLED = 0, | 3743 | BT_COEX_PRIO_TBL_DISABLED = 0, |
3743 | BT_COEX_PRIO_TBL_PRIO_LOW = 1, | 3744 | BT_COEX_PRIO_TBL_PRIO_LOW = 1, |
3744 | BT_COEX_PRIO_TBL_PRIO_HIGH = 2, | 3745 | BT_COEX_PRIO_TBL_PRIO_HIGH = 2, |
3745 | BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, | 3746 | BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, |
3746 | BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, | 3747 | BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, |
3747 | BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, | 3748 | BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, |
3748 | BT_COEX_PRIO_TBL_PRIO_RSRVD1 = 6, | 3749 | BT_COEX_PRIO_TBL_PRIO_RSRVD1 = 6, |
3749 | BT_COEX_PRIO_TBL_PRIO_RSRVD2 = 7, | 3750 | BT_COEX_PRIO_TBL_PRIO_RSRVD2 = 7, |
3750 | BT_COEX_PRIO_TBL_MAX, | 3751 | BT_COEX_PRIO_TBL_MAX, |
3751 | }; | 3752 | }; |
3752 | 3753 | ||
3753 | struct iwl_bt_coex_prio_table_cmd { | 3754 | struct iwl_bt_coex_prio_table_cmd { |
3754 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; | 3755 | u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; |
3755 | } __attribute__((packed)); | 3756 | } __attribute__((packed)); |
3756 | 3757 | ||
3757 | #define IWL_BT_COEX_ENV_CLOSE 0 | 3758 | #define IWL_BT_COEX_ENV_CLOSE 0 |
3758 | #define IWL_BT_COEX_ENV_OPEN 1 | 3759 | #define IWL_BT_COEX_ENV_OPEN 1 |
3759 | /* | 3760 | /* |
3760 | * BT Protection Envelope | 3761 | * BT Protection Envelope |
3761 | * REPLY_BT_COEX_PROT_ENV = 0xcd | 3762 | * REPLY_BT_COEX_PROT_ENV = 0xcd |
3762 | */ | 3763 | */ |
3763 | struct iwl_bt_coex_prot_env_cmd { | 3764 | struct iwl_bt_coex_prot_env_cmd { |
3764 | u8 action; /* 0 = closed, 1 = open */ | 3765 | u8 action; /* 0 = closed, 1 = open */ |
3765 | u8 type; /* 0 .. 15 */ | 3766 | u8 type; /* 0 .. 15 */ |
3766 | u8 reserved[2]; | 3767 | u8 reserved[2]; |
3767 | } __attribute__((packed)); | 3768 | } __attribute__((packed)); |
3768 | 3769 | ||
3769 | /* | 3770 | /* |
3770 | * REPLY_D3_CONFIG | 3771 | * REPLY_D3_CONFIG |
3771 | */ | 3772 | */ |
3772 | enum iwlagn_d3_wakeup_filters { | 3773 | enum iwlagn_d3_wakeup_filters { |
3773 | IWLAGN_D3_WAKEUP_RFKILL = BIT(0), | 3774 | IWLAGN_D3_WAKEUP_RFKILL = BIT(0), |
3774 | IWLAGN_D3_WAKEUP_SYSASSERT = BIT(1), | 3775 | IWLAGN_D3_WAKEUP_SYSASSERT = BIT(1), |
3775 | }; | 3776 | }; |
3776 | 3777 | ||
3777 | struct iwlagn_d3_config_cmd { | 3778 | struct iwlagn_d3_config_cmd { |
3778 | __le32 min_sleep_time; | 3779 | __le32 min_sleep_time; |
3779 | __le32 wakeup_flags; | 3780 | __le32 wakeup_flags; |
3780 | } __packed; | 3781 | } __packed; |
3781 | 3782 | ||
3782 | /* | 3783 | /* |
3783 | * REPLY_WOWLAN_PATTERNS | 3784 | * REPLY_WOWLAN_PATTERNS |
3784 | */ | 3785 | */ |
3785 | #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 | 3786 | #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 |
3786 | #define IWLAGN_WOWLAN_MAX_PATTERN_LEN 128 | 3787 | #define IWLAGN_WOWLAN_MAX_PATTERN_LEN 128 |
3787 | 3788 | ||
3788 | struct iwlagn_wowlan_pattern { | 3789 | struct iwlagn_wowlan_pattern { |
3789 | u8 mask[IWLAGN_WOWLAN_MAX_PATTERN_LEN / 8]; | 3790 | u8 mask[IWLAGN_WOWLAN_MAX_PATTERN_LEN / 8]; |
3790 | u8 pattern[IWLAGN_WOWLAN_MAX_PATTERN_LEN]; | 3791 | u8 pattern[IWLAGN_WOWLAN_MAX_PATTERN_LEN]; |
3791 | u8 mask_size; | 3792 | u8 mask_size; |
3792 | u8 pattern_size; | 3793 | u8 pattern_size; |
3793 | __le16 reserved; | 3794 | __le16 reserved; |
3794 | } __packed; | 3795 | } __packed; |
3795 | 3796 | ||
3796 | #define IWLAGN_WOWLAN_MAX_PATTERNS 20 | 3797 | #define IWLAGN_WOWLAN_MAX_PATTERNS 20 |
3797 | 3798 | ||
3798 | struct iwlagn_wowlan_patterns_cmd { | 3799 | struct iwlagn_wowlan_patterns_cmd { |
3799 | __le32 n_patterns; | 3800 | __le32 n_patterns; |
3800 | struct iwlagn_wowlan_pattern patterns[]; | 3801 | struct iwlagn_wowlan_pattern patterns[]; |
3801 | } __packed; | 3802 | } __packed; |
3802 | 3803 | ||
3803 | /* | 3804 | /* |
3804 | * REPLY_WOWLAN_WAKEUP_FILTER | 3805 | * REPLY_WOWLAN_WAKEUP_FILTER |
3805 | */ | 3806 | */ |
3806 | enum iwlagn_wowlan_wakeup_filters { | 3807 | enum iwlagn_wowlan_wakeup_filters { |
3807 | IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET = BIT(0), | 3808 | IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET = BIT(0), |
3808 | IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH = BIT(1), | 3809 | IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH = BIT(1), |
3809 | IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), | 3810 | IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), |
3810 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), | 3811 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), |
3811 | IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), | 3812 | IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), |
3812 | IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5), | 3813 | IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5), |
3813 | IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6), | 3814 | IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6), |
3814 | IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(7), | 3815 | IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(7), |
3815 | IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(8), | 3816 | IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(8), |
3816 | }; | 3817 | }; |
3817 | 3818 | ||
3818 | struct iwlagn_wowlan_wakeup_filter_cmd { | 3819 | struct iwlagn_wowlan_wakeup_filter_cmd { |
3819 | __le32 enabled; | 3820 | __le32 enabled; |
3820 | __le16 non_qos_seq; | 3821 | __le16 non_qos_seq; |
3821 | __le16 reserved; | 3822 | __le16 reserved; |
3822 | __le16 qos_seq[8]; | 3823 | __le16 qos_seq[8]; |
3823 | }; | 3824 | }; |
3824 | 3825 | ||
3825 | /* | 3826 | /* |
3826 | * REPLY_WOWLAN_TSC_RSC_PARAMS | 3827 | * REPLY_WOWLAN_TSC_RSC_PARAMS |
3827 | */ | 3828 | */ |
3828 | #define IWLAGN_NUM_RSC 16 | 3829 | #define IWLAGN_NUM_RSC 16 |
3829 | 3830 | ||
3830 | struct tkip_sc { | 3831 | struct tkip_sc { |
3831 | __le16 iv16; | 3832 | __le16 iv16; |
3832 | __le16 pad; | 3833 | __le16 pad; |
3833 | __le32 iv32; | 3834 | __le32 iv32; |
3834 | } __packed; | 3835 | } __packed; |
3835 | 3836 | ||
3836 | struct iwlagn_tkip_rsc_tsc { | 3837 | struct iwlagn_tkip_rsc_tsc { |
3837 | struct tkip_sc unicast_rsc[IWLAGN_NUM_RSC]; | 3838 | struct tkip_sc unicast_rsc[IWLAGN_NUM_RSC]; |
3838 | struct tkip_sc multicast_rsc[IWLAGN_NUM_RSC]; | 3839 | struct tkip_sc multicast_rsc[IWLAGN_NUM_RSC]; |
3839 | struct tkip_sc tsc; | 3840 | struct tkip_sc tsc; |
3840 | } __packed; | 3841 | } __packed; |
3841 | 3842 | ||
3842 | struct aes_sc { | 3843 | struct aes_sc { |
3843 | __le64 pn; | 3844 | __le64 pn; |
3844 | } __packed; | 3845 | } __packed; |
3845 | 3846 | ||
3846 | struct iwlagn_aes_rsc_tsc { | 3847 | struct iwlagn_aes_rsc_tsc { |
3847 | struct aes_sc unicast_rsc[IWLAGN_NUM_RSC]; | 3848 | struct aes_sc unicast_rsc[IWLAGN_NUM_RSC]; |
3848 | struct aes_sc multicast_rsc[IWLAGN_NUM_RSC]; | 3849 | struct aes_sc multicast_rsc[IWLAGN_NUM_RSC]; |
3849 | struct aes_sc tsc; | 3850 | struct aes_sc tsc; |
3850 | } __packed; | 3851 | } __packed; |
3851 | 3852 | ||
3852 | union iwlagn_all_tsc_rsc { | 3853 | union iwlagn_all_tsc_rsc { |
3853 | struct iwlagn_tkip_rsc_tsc tkip; | 3854 | struct iwlagn_tkip_rsc_tsc tkip; |
3854 | struct iwlagn_aes_rsc_tsc aes; | 3855 | struct iwlagn_aes_rsc_tsc aes; |
3855 | }; | 3856 | }; |
3856 | 3857 | ||
3857 | struct iwlagn_wowlan_rsc_tsc_params_cmd { | 3858 | struct iwlagn_wowlan_rsc_tsc_params_cmd { |
3858 | union iwlagn_all_tsc_rsc all_tsc_rsc; | 3859 | union iwlagn_all_tsc_rsc all_tsc_rsc; |
3859 | } __packed; | 3860 | } __packed; |
3860 | 3861 | ||
3861 | /* | 3862 | /* |
3862 | * REPLY_WOWLAN_TKIP_PARAMS | 3863 | * REPLY_WOWLAN_TKIP_PARAMS |
3863 | */ | 3864 | */ |
3864 | #define IWLAGN_MIC_KEY_SIZE 8 | 3865 | #define IWLAGN_MIC_KEY_SIZE 8 |
3865 | #define IWLAGN_P1K_SIZE 5 | 3866 | #define IWLAGN_P1K_SIZE 5 |
3866 | struct iwlagn_mic_keys { | 3867 | struct iwlagn_mic_keys { |
3867 | u8 tx[IWLAGN_MIC_KEY_SIZE]; | 3868 | u8 tx[IWLAGN_MIC_KEY_SIZE]; |
3868 | u8 rx_unicast[IWLAGN_MIC_KEY_SIZE]; | 3869 | u8 rx_unicast[IWLAGN_MIC_KEY_SIZE]; |
3869 | u8 rx_mcast[IWLAGN_MIC_KEY_SIZE]; | 3870 | u8 rx_mcast[IWLAGN_MIC_KEY_SIZE]; |
3870 | } __packed; | 3871 | } __packed; |
3871 | 3872 | ||
3872 | struct iwlagn_p1k_cache { | 3873 | struct iwlagn_p1k_cache { |
3873 | __le16 p1k[IWLAGN_P1K_SIZE]; | 3874 | __le16 p1k[IWLAGN_P1K_SIZE]; |
3874 | } __packed; | 3875 | } __packed; |
3875 | 3876 | ||
3876 | #define IWLAGN_NUM_RX_P1K_CACHE 2 | 3877 | #define IWLAGN_NUM_RX_P1K_CACHE 2 |
3877 | 3878 | ||
3878 | struct iwlagn_wowlan_tkip_params_cmd { | 3879 | struct iwlagn_wowlan_tkip_params_cmd { |
3879 | struct iwlagn_mic_keys mic_keys; | 3880 | struct iwlagn_mic_keys mic_keys; |
3880 | struct iwlagn_p1k_cache tx; | 3881 | struct iwlagn_p1k_cache tx; |
3881 | struct iwlagn_p1k_cache rx_uni[IWLAGN_NUM_RX_P1K_CACHE]; | 3882 | struct iwlagn_p1k_cache rx_uni[IWLAGN_NUM_RX_P1K_CACHE]; |
3882 | struct iwlagn_p1k_cache rx_multi[IWLAGN_NUM_RX_P1K_CACHE]; | 3883 | struct iwlagn_p1k_cache rx_multi[IWLAGN_NUM_RX_P1K_CACHE]; |
3883 | } __packed; | 3884 | } __packed; |
3884 | 3885 | ||
3885 | /* | 3886 | /* |
3886 | * REPLY_WOWLAN_KEK_KCK_MATERIAL | 3887 | * REPLY_WOWLAN_KEK_KCK_MATERIAL |
3887 | */ | 3888 | */ |
3888 | 3889 | ||
3889 | #define IWLAGN_KCK_MAX_SIZE 32 | 3890 | #define IWLAGN_KCK_MAX_SIZE 32 |
3890 | #define IWLAGN_KEK_MAX_SIZE 32 | 3891 | #define IWLAGN_KEK_MAX_SIZE 32 |
3891 | 3892 | ||
3892 | struct iwlagn_wowlan_kek_kck_material_cmd { | 3893 | struct iwlagn_wowlan_kek_kck_material_cmd { |
3893 | u8 kck[IWLAGN_KCK_MAX_SIZE]; | 3894 | u8 kck[IWLAGN_KCK_MAX_SIZE]; |
3894 | u8 kek[IWLAGN_KEK_MAX_SIZE]; | 3895 | u8 kek[IWLAGN_KEK_MAX_SIZE]; |
3895 | __le16 kck_len; | 3896 | __le16 kck_len; |
3896 | __le16 kek_len; | 3897 | __le16 kek_len; |
3897 | __le64 replay_ctr; | 3898 | __le64 replay_ctr; |
3898 | } __packed; | 3899 | } __packed; |
3899 | 3900 | ||
3900 | /* | 3901 | /* |
3901 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) | 3902 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) |
3902 | */ | 3903 | */ |
3903 | 3904 | ||
3904 | /* | 3905 | /* |
3905 | * Minimum slot time in TU | 3906 | * Minimum slot time in TU |
3906 | */ | 3907 | */ |
3907 | #define IWL_MIN_SLOT_TIME 20 | 3908 | #define IWL_MIN_SLOT_TIME 20 |
3908 | 3909 | ||
3909 | /** | 3910 | /** |
3910 | * struct iwl_wipan_slot | 3911 | * struct iwl_wipan_slot |
3911 | * @width: Time in TU | 3912 | * @width: Time in TU |
3912 | * @type: | 3913 | * @type: |
3913 | * 0 - BSS | 3914 | * 0 - BSS |
3914 | * 1 - PAN | 3915 | * 1 - PAN |
3915 | */ | 3916 | */ |
3916 | struct iwl_wipan_slot { | 3917 | struct iwl_wipan_slot { |
3917 | __le16 width; | 3918 | __le16 width; |
3918 | u8 type; | 3919 | u8 type; |
3919 | u8 reserved; | 3920 | u8 reserved; |
3920 | } __packed; | 3921 | } __packed; |
3921 | 3922 | ||
3922 | #define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_CTS BIT(1) /* reserved */ | 3923 | #define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_CTS BIT(1) /* reserved */ |
3923 | #define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_QUIET BIT(2) /* reserved */ | 3924 | #define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_QUIET BIT(2) /* reserved */ |
3924 | #define IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE BIT(3) /* reserved */ | 3925 | #define IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE BIT(3) /* reserved */ |
3925 | #define IWL_WIPAN_PARAMS_FLG_FILTER_BEACON_NOTIF BIT(4) | 3926 | #define IWL_WIPAN_PARAMS_FLG_FILTER_BEACON_NOTIF BIT(4) |
3926 | #define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5) | 3927 | #define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5) |
3927 | 3928 | ||
3928 | /** | 3929 | /** |
3929 | * struct iwl_wipan_params_cmd | 3930 | * struct iwl_wipan_params_cmd |
3930 | * @flags: | 3931 | * @flags: |
3931 | * bit0: reserved | 3932 | * bit0: reserved |
3932 | * bit1: CP leave channel with CTS | 3933 | * bit1: CP leave channel with CTS |
3933 | * bit2: CP leave channel qith Quiet | 3934 | * bit2: CP leave channel qith Quiet |
3934 | * bit3: slotted mode | 3935 | * bit3: slotted mode |
3935 | * 1 - work in slotted mode | 3936 | * 1 - work in slotted mode |
3936 | * 0 - work in non slotted mode | 3937 | * 0 - work in non slotted mode |
3937 | * bit4: filter beacon notification | 3938 | * bit4: filter beacon notification |
3938 | * bit5: full tx slotted mode. if this flag is set, | 3939 | * bit5: full tx slotted mode. if this flag is set, |
3939 | * uCode will perform leaving channel methods in context switch | 3940 | * uCode will perform leaving channel methods in context switch |
3940 | * also when working in same channel mode | 3941 | * also when working in same channel mode |
3941 | * @num_slots: 1 - 10 | 3942 | * @num_slots: 1 - 10 |
3942 | */ | 3943 | */ |
3943 | struct iwl_wipan_params_cmd { | 3944 | struct iwl_wipan_params_cmd { |
3944 | __le16 flags; | 3945 | __le16 flags; |
3945 | u8 reserved; | 3946 | u8 reserved; |
3946 | u8 num_slots; | 3947 | u8 num_slots; |
3947 | struct iwl_wipan_slot slots[10]; | 3948 | struct iwl_wipan_slot slots[10]; |
3948 | } __packed; | 3949 | } __packed; |
3949 | 3950 | ||
3950 | /* | 3951 | /* |
3951 | * REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9 | 3952 | * REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9 |
3952 | * | 3953 | * |
3953 | * TODO: Figure out what this is used for, | 3954 | * TODO: Figure out what this is used for, |
3954 | * it can only switch between 2.4 GHz | 3955 | * it can only switch between 2.4 GHz |
3955 | * channels!! | 3956 | * channels!! |
3956 | */ | 3957 | */ |
3957 | 3958 | ||
3958 | struct iwl_wipan_p2p_channel_switch_cmd { | 3959 | struct iwl_wipan_p2p_channel_switch_cmd { |
3959 | __le16 channel; | 3960 | __le16 channel; |
3960 | __le16 reserved; | 3961 | __le16 reserved; |
3961 | }; | 3962 | }; |
3962 | 3963 | ||
3963 | /* | 3964 | /* |
3964 | * REPLY_WIPAN_NOA_NOTIFICATION = 0xbc | 3965 | * REPLY_WIPAN_NOA_NOTIFICATION = 0xbc |
3965 | * | 3966 | * |
3966 | * This is used by the device to notify us of the | 3967 | * This is used by the device to notify us of the |
3967 | * NoA schedule it determined so we can forward it | 3968 | * NoA schedule it determined so we can forward it |
3968 | * to userspace for inclusion in probe responses. | 3969 | * to userspace for inclusion in probe responses. |
3969 | * | 3970 | * |
3970 | * In beacons, the NoA schedule is simply appended | 3971 | * In beacons, the NoA schedule is simply appended |
3971 | * to the frame we give the device. | 3972 | * to the frame we give the device. |
3972 | */ | 3973 | */ |
3973 | 3974 | ||
3974 | struct iwl_wipan_noa_descriptor { | 3975 | struct iwl_wipan_noa_descriptor { |
3975 | u8 count; | 3976 | u8 count; |
3976 | __le32 duration; | 3977 | __le32 duration; |
3977 | __le32 interval; | 3978 | __le32 interval; |
3978 | __le32 starttime; | 3979 | __le32 starttime; |
3979 | } __packed; | 3980 | } __packed; |
3980 | 3981 | ||
3981 | struct iwl_wipan_noa_attribute { | 3982 | struct iwl_wipan_noa_attribute { |
3982 | u8 id; | 3983 | u8 id; |
3983 | __le16 length; | 3984 | __le16 length; |
3984 | u8 index; | 3985 | u8 index; |
3985 | u8 ct_window; | 3986 | u8 ct_window; |
3986 | struct iwl_wipan_noa_descriptor descr0, descr1; | 3987 | struct iwl_wipan_noa_descriptor descr0, descr1; |
3987 | u8 reserved; | 3988 | u8 reserved; |
3988 | } __packed; | 3989 | } __packed; |
3989 | 3990 | ||
3990 | struct iwl_wipan_noa_notification { | 3991 | struct iwl_wipan_noa_notification { |
3991 | u32 noa_active; | 3992 | u32 noa_active; |
3992 | struct iwl_wipan_noa_attribute noa_attribute; | 3993 | struct iwl_wipan_noa_attribute noa_attribute; |
3993 | } __packed; | 3994 | } __packed; |
3994 | 3995 | ||
3995 | #endif /* __iwl_commands_h__ */ | 3996 | #endif /* __iwl_commands_h__ */ |
3996 | 3997 |
drivers/net/wireless/iwlwifi/dvm/dev.h
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | 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 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License along with | 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., | 15 | * this program; if not, write to the Free Software Foundation, Inc., |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
17 | * | 17 | * |
18 | * The full GNU General Public License is included in this distribution in the | 18 | * The full GNU General Public License is included in this distribution in the |
19 | * file called LICENSE. | 19 | * file called LICENSE. |
20 | * | 20 | * |
21 | * Contact Information: | 21 | * Contact Information: |
22 | * Intel Linux Wireless <ilw@linux.intel.com> | 22 | * Intel Linux Wireless <ilw@linux.intel.com> |
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | /* | 26 | /* |
27 | * Please use this file (dev.h) for driver implementation definitions. | 27 | * Please use this file (dev.h) for driver implementation definitions. |
28 | * Please use commands.h for uCode API definitions. | 28 | * Please use commands.h for uCode API definitions. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #ifndef __iwl_dev_h__ | 31 | #ifndef __iwl_dev_h__ |
32 | #define __iwl_dev_h__ | 32 | #define __iwl_dev_h__ |
33 | 33 | ||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | 40 | ||
41 | #include "iwl-fw.h" | 41 | #include "iwl-fw.h" |
42 | #include "iwl-eeprom-parse.h" | 42 | #include "iwl-eeprom-parse.h" |
43 | #include "iwl-csr.h" | 43 | #include "iwl-csr.h" |
44 | #include "iwl-debug.h" | 44 | #include "iwl-debug.h" |
45 | #include "iwl-agn-hw.h" | 45 | #include "iwl-agn-hw.h" |
46 | #include "iwl-op-mode.h" | 46 | #include "iwl-op-mode.h" |
47 | #include "iwl-notif-wait.h" | 47 | #include "iwl-notif-wait.h" |
48 | #include "iwl-trans.h" | 48 | #include "iwl-trans.h" |
49 | 49 | ||
50 | #include "led.h" | 50 | #include "led.h" |
51 | #include "power.h" | 51 | #include "power.h" |
52 | #include "rs.h" | 52 | #include "rs.h" |
53 | #include "tt.h" | 53 | #include "tt.h" |
54 | 54 | ||
55 | #include "iwl-test.h" | 55 | #include "iwl-test.h" |
56 | 56 | ||
57 | /* CT-KILL constants */ | 57 | /* CT-KILL constants */ |
58 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ | 58 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ |
59 | #define CT_KILL_THRESHOLD 114 /* in Celsius */ | 59 | #define CT_KILL_THRESHOLD 114 /* in Celsius */ |
60 | #define CT_KILL_EXIT_THRESHOLD 95 /* in Celsius */ | 60 | #define CT_KILL_EXIT_THRESHOLD 95 /* in Celsius */ |
61 | 61 | ||
62 | /* Default noise level to report when noise measurement is not available. | 62 | /* Default noise level to report when noise measurement is not available. |
63 | * This may be because we're: | 63 | * This may be because we're: |
64 | * 1) Not associated no beacon statistics being sent to driver) | 64 | * 1) Not associated no beacon statistics being sent to driver) |
65 | * 2) Scanning (noise measurement does not apply to associated channel) | 65 | * 2) Scanning (noise measurement does not apply to associated channel) |
66 | * Use default noise value of -127 ... this is below the range of measurable | 66 | * Use default noise value of -127 ... this is below the range of measurable |
67 | * Rx dBm for all agn devices, so it can indicate "unmeasurable" to user. | 67 | * Rx dBm for all agn devices, so it can indicate "unmeasurable" to user. |
68 | * Also, -127 works better than 0 when averaging frames with/without | 68 | * Also, -127 works better than 0 when averaging frames with/without |
69 | * noise info (e.g. averaging might be done in app); measured dBm values are | 69 | * noise info (e.g. averaging might be done in app); measured dBm values are |
70 | * always negative ... using a negative value as the default keeps all | 70 | * always negative ... using a negative value as the default keeps all |
71 | * averages within an s8's (used in some apps) range of negative values. */ | 71 | * averages within an s8's (used in some apps) range of negative values. */ |
72 | #define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) | 72 | #define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * RTS threshold here is total size [2347] minus 4 FCS bytes | 75 | * RTS threshold here is total size [2347] minus 4 FCS bytes |
76 | * Per spec: | 76 | * Per spec: |
77 | * a value of 0 means RTS on all data/management packets | 77 | * a value of 0 means RTS on all data/management packets |
78 | * a value > max MSDU size means no RTS | 78 | * a value > max MSDU size means no RTS |
79 | * else RTS for data/management frames where MPDU is larger | 79 | * else RTS for data/management frames where MPDU is larger |
80 | * than RTS value. | 80 | * than RTS value. |
81 | */ | 81 | */ |
82 | #define DEFAULT_RTS_THRESHOLD 2347U | 82 | #define DEFAULT_RTS_THRESHOLD 2347U |
83 | #define MIN_RTS_THRESHOLD 0U | 83 | #define MIN_RTS_THRESHOLD 0U |
84 | #define MAX_RTS_THRESHOLD 2347U | 84 | #define MAX_RTS_THRESHOLD 2347U |
85 | #define MAX_MSDU_SIZE 2304U | 85 | #define MAX_MSDU_SIZE 2304U |
86 | #define MAX_MPDU_SIZE 2346U | 86 | #define MAX_MPDU_SIZE 2346U |
87 | #define DEFAULT_BEACON_INTERVAL 200U | 87 | #define DEFAULT_BEACON_INTERVAL 200U |
88 | #define DEFAULT_SHORT_RETRY_LIMIT 7U | 88 | #define DEFAULT_SHORT_RETRY_LIMIT 7U |
89 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 89 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
90 | 90 | ||
91 | #define IWL_NUM_SCAN_RATES (2) | 91 | #define IWL_NUM_SCAN_RATES (2) |
92 | 92 | ||
93 | 93 | ||
94 | #define IEEE80211_DATA_LEN 2304 | 94 | #define IEEE80211_DATA_LEN 2304 |
95 | #define IEEE80211_4ADDR_LEN 30 | 95 | #define IEEE80211_4ADDR_LEN 30 |
96 | #define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) | 96 | #define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) |
97 | #define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) | 97 | #define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) |
98 | 98 | ||
99 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 | 99 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 |
100 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 | 100 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 |
101 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | 101 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 |
102 | 102 | ||
103 | #define IWL_SUPPORTED_RATES_IE_LEN 8 | 103 | #define IWL_SUPPORTED_RATES_IE_LEN 8 |
104 | 104 | ||
105 | #define IWL_INVALID_RATE 0xFF | 105 | #define IWL_INVALID_RATE 0xFF |
106 | #define IWL_INVALID_VALUE -1 | 106 | #define IWL_INVALID_VALUE -1 |
107 | 107 | ||
108 | union iwl_ht_rate_supp { | 108 | union iwl_ht_rate_supp { |
109 | u16 rates; | 109 | u16 rates; |
110 | struct { | 110 | struct { |
111 | u8 siso_rate; | 111 | u8 siso_rate; |
112 | u8 mimo_rate; | 112 | u8 mimo_rate; |
113 | }; | 113 | }; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct iwl_ht_config { | 116 | struct iwl_ht_config { |
117 | bool single_chain_sufficient; | 117 | bool single_chain_sufficient; |
118 | enum ieee80211_smps_mode smps; /* current smps mode */ | 118 | enum ieee80211_smps_mode smps; /* current smps mode */ |
119 | }; | 119 | }; |
120 | 120 | ||
121 | /* QoS structures */ | 121 | /* QoS structures */ |
122 | struct iwl_qos_info { | 122 | struct iwl_qos_info { |
123 | int qos_active; | 123 | int qos_active; |
124 | struct iwl_qosparam_cmd def_qos_parm; | 124 | struct iwl_qosparam_cmd def_qos_parm; |
125 | }; | 125 | }; |
126 | 126 | ||
127 | /** | 127 | /** |
128 | * enum iwl_agg_state | 128 | * enum iwl_agg_state |
129 | * | 129 | * |
130 | * The state machine of the BA agreement establishment / tear down. | 130 | * The state machine of the BA agreement establishment / tear down. |
131 | * These states relate to a specific RA / TID. | 131 | * These states relate to a specific RA / TID. |
132 | * | 132 | * |
133 | * @IWL_AGG_OFF: aggregation is not used | 133 | * @IWL_AGG_OFF: aggregation is not used |
134 | * @IWL_AGG_STARTING: aggregation are starting (between start and oper) | 134 | * @IWL_AGG_STARTING: aggregation are starting (between start and oper) |
135 | * @IWL_AGG_ON: aggregation session is up | 135 | * @IWL_AGG_ON: aggregation session is up |
136 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the | 136 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the |
137 | * HW queue to be empty from packets for this RA /TID. | 137 | * HW queue to be empty from packets for this RA /TID. |
138 | * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the | 138 | * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the |
139 | * HW queue to be empty from packets for this RA /TID. | 139 | * HW queue to be empty from packets for this RA /TID. |
140 | */ | 140 | */ |
141 | enum iwl_agg_state { | 141 | enum iwl_agg_state { |
142 | IWL_AGG_OFF = 0, | 142 | IWL_AGG_OFF = 0, |
143 | IWL_AGG_STARTING, | 143 | IWL_AGG_STARTING, |
144 | IWL_AGG_ON, | 144 | IWL_AGG_ON, |
145 | IWL_EMPTYING_HW_QUEUE_ADDBA, | 145 | IWL_EMPTYING_HW_QUEUE_ADDBA, |
146 | IWL_EMPTYING_HW_QUEUE_DELBA, | 146 | IWL_EMPTYING_HW_QUEUE_DELBA, |
147 | }; | 147 | }; |
148 | 148 | ||
149 | /** | 149 | /** |
150 | * struct iwl_ht_agg - aggregation state machine | 150 | * struct iwl_ht_agg - aggregation state machine |
151 | 151 | ||
152 | * This structs holds the states for the BA agreement establishment and tear | 152 | * This structs holds the states for the BA agreement establishment and tear |
153 | * down. It also holds the state during the BA session itself. This struct is | 153 | * down. It also holds the state during the BA session itself. This struct is |
154 | * duplicated for each RA / TID. | 154 | * duplicated for each RA / TID. |
155 | 155 | ||
156 | * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the | 156 | * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the |
157 | * Tx response (REPLY_TX), and the block ack notification | 157 | * Tx response (REPLY_TX), and the block ack notification |
158 | * (REPLY_COMPRESSED_BA). | 158 | * (REPLY_COMPRESSED_BA). |
159 | * @state: state of the BA agreement establishment / tear down. | 159 | * @state: state of the BA agreement establishment / tear down. |
160 | * @txq_id: Tx queue used by the BA session | 160 | * @txq_id: Tx queue used by the BA session |
161 | * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or | 161 | * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or |
162 | * the first packet to be sent in legacy HW queue in Tx AGG stop flow. | 162 | * the first packet to be sent in legacy HW queue in Tx AGG stop flow. |
163 | * Basically when next_reclaimed reaches ssn, we can tell mac80211 that | 163 | * Basically when next_reclaimed reaches ssn, we can tell mac80211 that |
164 | * we are ready to finish the Tx AGG stop / start flow. | 164 | * we are ready to finish the Tx AGG stop / start flow. |
165 | * @wait_for_ba: Expect block-ack before next Tx reply | 165 | * @wait_for_ba: Expect block-ack before next Tx reply |
166 | */ | 166 | */ |
167 | struct iwl_ht_agg { | 167 | struct iwl_ht_agg { |
168 | u32 rate_n_flags; | 168 | u32 rate_n_flags; |
169 | enum iwl_agg_state state; | 169 | enum iwl_agg_state state; |
170 | u16 txq_id; | 170 | u16 txq_id; |
171 | u16 ssn; | 171 | u16 ssn; |
172 | bool wait_for_ba; | 172 | bool wait_for_ba; |
173 | }; | 173 | }; |
174 | 174 | ||
175 | /** | 175 | /** |
176 | * struct iwl_tid_data - one for each RA / TID | 176 | * struct iwl_tid_data - one for each RA / TID |
177 | 177 | ||
178 | * This structs holds the states for each RA / TID. | 178 | * This structs holds the states for each RA / TID. |
179 | 179 | ||
180 | * @seq_number: the next WiFi sequence number to use | 180 | * @seq_number: the next WiFi sequence number to use |
181 | * @next_reclaimed: the WiFi sequence number of the next packet to be acked. | 181 | * @next_reclaimed: the WiFi sequence number of the next packet to be acked. |
182 | * This is basically (last acked packet++). | 182 | * This is basically (last acked packet++). |
183 | * @agg: aggregation state machine | 183 | * @agg: aggregation state machine |
184 | */ | 184 | */ |
185 | struct iwl_tid_data { | 185 | struct iwl_tid_data { |
186 | u16 seq_number; | 186 | u16 seq_number; |
187 | u16 next_reclaimed; | 187 | u16 next_reclaimed; |
188 | struct iwl_ht_agg agg; | 188 | struct iwl_ht_agg agg; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | /* | 191 | /* |
192 | * Structure should be accessed with sta_lock held. When station addition | 192 | * Structure should be accessed with sta_lock held. When station addition |
193 | * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only | 193 | * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only |
194 | * the commands (iwl_addsta_cmd and iwl_link_quality_cmd) without sta_lock | 194 | * the commands (iwl_addsta_cmd and iwl_link_quality_cmd) without sta_lock |
195 | * held. | 195 | * held. |
196 | */ | 196 | */ |
197 | struct iwl_station_entry { | 197 | struct iwl_station_entry { |
198 | struct iwl_addsta_cmd sta; | 198 | struct iwl_addsta_cmd sta; |
199 | u8 used, ctxid; | 199 | u8 used, ctxid; |
200 | struct iwl_link_quality_cmd *lq; | 200 | struct iwl_link_quality_cmd *lq; |
201 | }; | 201 | }; |
202 | 202 | ||
203 | /* | 203 | /* |
204 | * iwl_station_priv: Driver's private station information | 204 | * iwl_station_priv: Driver's private station information |
205 | * | 205 | * |
206 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) | 206 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) |
207 | * in the structure for use by driver. This structure is places in that | 207 | * in the structure for use by driver. This structure is places in that |
208 | * space. | 208 | * space. |
209 | */ | 209 | */ |
210 | struct iwl_station_priv { | 210 | struct iwl_station_priv { |
211 | struct iwl_rxon_context *ctx; | 211 | struct iwl_rxon_context *ctx; |
212 | struct iwl_lq_sta lq_sta; | 212 | struct iwl_lq_sta lq_sta; |
213 | atomic_t pending_frames; | 213 | atomic_t pending_frames; |
214 | bool client; | 214 | bool client; |
215 | bool asleep; | 215 | bool asleep; |
216 | u8 max_agg_bufsize; | 216 | u8 max_agg_bufsize; |
217 | u8 sta_id; | 217 | u8 sta_id; |
218 | }; | 218 | }; |
219 | 219 | ||
220 | /** | 220 | /** |
221 | * struct iwl_vif_priv - driver's private per-interface information | 221 | * struct iwl_vif_priv - driver's private per-interface information |
222 | * | 222 | * |
223 | * When mac80211 allocates a virtual interface, it can allocate | 223 | * When mac80211 allocates a virtual interface, it can allocate |
224 | * space for us to put data into. | 224 | * space for us to put data into. |
225 | */ | 225 | */ |
226 | struct iwl_vif_priv { | 226 | struct iwl_vif_priv { |
227 | struct iwl_rxon_context *ctx; | 227 | struct iwl_rxon_context *ctx; |
228 | u8 ibss_bssid_sta_id; | 228 | u8 ibss_bssid_sta_id; |
229 | }; | 229 | }; |
230 | 230 | ||
231 | struct iwl_sensitivity_ranges { | 231 | struct iwl_sensitivity_ranges { |
232 | u16 min_nrg_cck; | 232 | u16 min_nrg_cck; |
233 | 233 | ||
234 | u16 nrg_th_cck; | 234 | u16 nrg_th_cck; |
235 | u16 nrg_th_ofdm; | 235 | u16 nrg_th_ofdm; |
236 | 236 | ||
237 | u16 auto_corr_min_ofdm; | 237 | u16 auto_corr_min_ofdm; |
238 | u16 auto_corr_min_ofdm_mrc; | 238 | u16 auto_corr_min_ofdm_mrc; |
239 | u16 auto_corr_min_ofdm_x1; | 239 | u16 auto_corr_min_ofdm_x1; |
240 | u16 auto_corr_min_ofdm_mrc_x1; | 240 | u16 auto_corr_min_ofdm_mrc_x1; |
241 | 241 | ||
242 | u16 auto_corr_max_ofdm; | 242 | u16 auto_corr_max_ofdm; |
243 | u16 auto_corr_max_ofdm_mrc; | 243 | u16 auto_corr_max_ofdm_mrc; |
244 | u16 auto_corr_max_ofdm_x1; | 244 | u16 auto_corr_max_ofdm_x1; |
245 | u16 auto_corr_max_ofdm_mrc_x1; | 245 | u16 auto_corr_max_ofdm_mrc_x1; |
246 | 246 | ||
247 | u16 auto_corr_max_cck; | 247 | u16 auto_corr_max_cck; |
248 | u16 auto_corr_max_cck_mrc; | 248 | u16 auto_corr_max_cck_mrc; |
249 | u16 auto_corr_min_cck; | 249 | u16 auto_corr_min_cck; |
250 | u16 auto_corr_min_cck_mrc; | 250 | u16 auto_corr_min_cck_mrc; |
251 | 251 | ||
252 | u16 barker_corr_th_min; | 252 | u16 barker_corr_th_min; |
253 | u16 barker_corr_th_min_mrc; | 253 | u16 barker_corr_th_min_mrc; |
254 | u16 nrg_th_cca; | 254 | u16 nrg_th_cca; |
255 | }; | 255 | }; |
256 | 256 | ||
257 | 257 | ||
258 | #define KELVIN_TO_CELSIUS(x) ((x)-273) | 258 | #define KELVIN_TO_CELSIUS(x) ((x)-273) |
259 | #define CELSIUS_TO_KELVIN(x) ((x)+273) | 259 | #define CELSIUS_TO_KELVIN(x) ((x)+273) |
260 | 260 | ||
261 | 261 | ||
262 | /****************************************************************************** | 262 | /****************************************************************************** |
263 | * | 263 | * |
264 | * Functions implemented in core module which are forward declared here | 264 | * Functions implemented in core module which are forward declared here |
265 | * for use by iwl-[4-5].c | 265 | * for use by iwl-[4-5].c |
266 | * | 266 | * |
267 | * NOTE: The implementation of these functions are not hardware specific | 267 | * NOTE: The implementation of these functions are not hardware specific |
268 | * which is why they are in the core module files. | 268 | * which is why they are in the core module files. |
269 | * | 269 | * |
270 | * Naming convention -- | 270 | * Naming convention -- |
271 | * iwl_ <-- Is part of iwlwifi | 271 | * iwl_ <-- Is part of iwlwifi |
272 | * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) | 272 | * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) |
273 | * | 273 | * |
274 | ****************************************************************************/ | 274 | ****************************************************************************/ |
275 | extern void iwl_update_chain_flags(struct iwl_priv *priv); | 275 | extern void iwl_update_chain_flags(struct iwl_priv *priv); |
276 | extern const u8 iwl_bcast_addr[ETH_ALEN]; | 276 | extern const u8 iwl_bcast_addr[ETH_ALEN]; |
277 | 277 | ||
278 | #define IWL_OPERATION_MODE_AUTO 0 | 278 | #define IWL_OPERATION_MODE_AUTO 0 |
279 | #define IWL_OPERATION_MODE_HT_ONLY 1 | 279 | #define IWL_OPERATION_MODE_HT_ONLY 1 |
280 | #define IWL_OPERATION_MODE_MIXED 2 | 280 | #define IWL_OPERATION_MODE_MIXED 2 |
281 | #define IWL_OPERATION_MODE_20MHZ 3 | 281 | #define IWL_OPERATION_MODE_20MHZ 3 |
282 | 282 | ||
283 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 | 283 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 |
284 | 284 | ||
285 | /* Sensitivity and chain noise calibration */ | 285 | /* Sensitivity and chain noise calibration */ |
286 | #define INITIALIZATION_VALUE 0xFFFF | 286 | #define INITIALIZATION_VALUE 0xFFFF |
287 | #define IWL_CAL_NUM_BEACONS 16 | 287 | #define IWL_CAL_NUM_BEACONS 16 |
288 | #define MAXIMUM_ALLOWED_PATHLOSS 15 | 288 | #define MAXIMUM_ALLOWED_PATHLOSS 15 |
289 | 289 | ||
290 | #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3 | 290 | #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3 |
291 | 291 | ||
292 | #define MAX_FA_OFDM 50 | 292 | #define MAX_FA_OFDM 50 |
293 | #define MIN_FA_OFDM 5 | 293 | #define MIN_FA_OFDM 5 |
294 | #define MAX_FA_CCK 50 | 294 | #define MAX_FA_CCK 50 |
295 | #define MIN_FA_CCK 5 | 295 | #define MIN_FA_CCK 5 |
296 | 296 | ||
297 | #define AUTO_CORR_STEP_OFDM 1 | 297 | #define AUTO_CORR_STEP_OFDM 1 |
298 | 298 | ||
299 | #define AUTO_CORR_STEP_CCK 3 | 299 | #define AUTO_CORR_STEP_CCK 3 |
300 | #define AUTO_CORR_MAX_TH_CCK 160 | 300 | #define AUTO_CORR_MAX_TH_CCK 160 |
301 | 301 | ||
302 | #define NRG_DIFF 2 | 302 | #define NRG_DIFF 2 |
303 | #define NRG_STEP_CCK 2 | 303 | #define NRG_STEP_CCK 2 |
304 | #define NRG_MARGIN 8 | 304 | #define NRG_MARGIN 8 |
305 | #define MAX_NUMBER_CCK_NO_FA 100 | 305 | #define MAX_NUMBER_CCK_NO_FA 100 |
306 | 306 | ||
307 | #define AUTO_CORR_CCK_MIN_VAL_DEF (125) | 307 | #define AUTO_CORR_CCK_MIN_VAL_DEF (125) |
308 | 308 | ||
309 | #define CHAIN_A 0 | 309 | #define CHAIN_A 0 |
310 | #define CHAIN_B 1 | 310 | #define CHAIN_B 1 |
311 | #define CHAIN_C 2 | 311 | #define CHAIN_C 2 |
312 | #define CHAIN_NOISE_DELTA_GAIN_INIT_VAL 4 | 312 | #define CHAIN_NOISE_DELTA_GAIN_INIT_VAL 4 |
313 | #define ALL_BAND_FILTER 0xFF00 | 313 | #define ALL_BAND_FILTER 0xFF00 |
314 | #define IN_BAND_FILTER 0xFF | 314 | #define IN_BAND_FILTER 0xFF |
315 | #define MIN_AVERAGE_NOISE_MAX_VALUE 0xFFFFFFFF | 315 | #define MIN_AVERAGE_NOISE_MAX_VALUE 0xFFFFFFFF |
316 | 316 | ||
317 | #define NRG_NUM_PREV_STAT_L 20 | 317 | #define NRG_NUM_PREV_STAT_L 20 |
318 | #define NUM_RX_CHAINS 3 | 318 | #define NUM_RX_CHAINS 3 |
319 | 319 | ||
320 | enum iwlagn_false_alarm_state { | 320 | enum iwlagn_false_alarm_state { |
321 | IWL_FA_TOO_MANY = 0, | 321 | IWL_FA_TOO_MANY = 0, |
322 | IWL_FA_TOO_FEW = 1, | 322 | IWL_FA_TOO_FEW = 1, |
323 | IWL_FA_GOOD_RANGE = 2, | 323 | IWL_FA_GOOD_RANGE = 2, |
324 | }; | 324 | }; |
325 | 325 | ||
326 | enum iwlagn_chain_noise_state { | 326 | enum iwlagn_chain_noise_state { |
327 | IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ | 327 | IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ |
328 | IWL_CHAIN_NOISE_ACCUMULATE, | 328 | IWL_CHAIN_NOISE_ACCUMULATE, |
329 | IWL_CHAIN_NOISE_CALIBRATED, | 329 | IWL_CHAIN_NOISE_CALIBRATED, |
330 | IWL_CHAIN_NOISE_DONE, | 330 | IWL_CHAIN_NOISE_DONE, |
331 | }; | 331 | }; |
332 | 332 | ||
333 | /* Sensitivity calib data */ | 333 | /* Sensitivity calib data */ |
334 | struct iwl_sensitivity_data { | 334 | struct iwl_sensitivity_data { |
335 | u32 auto_corr_ofdm; | 335 | u32 auto_corr_ofdm; |
336 | u32 auto_corr_ofdm_mrc; | 336 | u32 auto_corr_ofdm_mrc; |
337 | u32 auto_corr_ofdm_x1; | 337 | u32 auto_corr_ofdm_x1; |
338 | u32 auto_corr_ofdm_mrc_x1; | 338 | u32 auto_corr_ofdm_mrc_x1; |
339 | u32 auto_corr_cck; | 339 | u32 auto_corr_cck; |
340 | u32 auto_corr_cck_mrc; | 340 | u32 auto_corr_cck_mrc; |
341 | 341 | ||
342 | u32 last_bad_plcp_cnt_ofdm; | 342 | u32 last_bad_plcp_cnt_ofdm; |
343 | u32 last_fa_cnt_ofdm; | 343 | u32 last_fa_cnt_ofdm; |
344 | u32 last_bad_plcp_cnt_cck; | 344 | u32 last_bad_plcp_cnt_cck; |
345 | u32 last_fa_cnt_cck; | 345 | u32 last_fa_cnt_cck; |
346 | 346 | ||
347 | u32 nrg_curr_state; | 347 | u32 nrg_curr_state; |
348 | u32 nrg_prev_state; | 348 | u32 nrg_prev_state; |
349 | u32 nrg_value[10]; | 349 | u32 nrg_value[10]; |
350 | u8 nrg_silence_rssi[NRG_NUM_PREV_STAT_L]; | 350 | u8 nrg_silence_rssi[NRG_NUM_PREV_STAT_L]; |
351 | u32 nrg_silence_ref; | 351 | u32 nrg_silence_ref; |
352 | u32 nrg_energy_idx; | 352 | u32 nrg_energy_idx; |
353 | u32 nrg_silence_idx; | 353 | u32 nrg_silence_idx; |
354 | u32 nrg_th_cck; | 354 | u32 nrg_th_cck; |
355 | s32 nrg_auto_corr_silence_diff; | 355 | s32 nrg_auto_corr_silence_diff; |
356 | u32 num_in_cck_no_fa; | 356 | u32 num_in_cck_no_fa; |
357 | u32 nrg_th_ofdm; | 357 | u32 nrg_th_ofdm; |
358 | 358 | ||
359 | u16 barker_corr_th_min; | 359 | u16 barker_corr_th_min; |
360 | u16 barker_corr_th_min_mrc; | 360 | u16 barker_corr_th_min_mrc; |
361 | u16 nrg_th_cca; | 361 | u16 nrg_th_cca; |
362 | }; | 362 | }; |
363 | 363 | ||
364 | /* Chain noise (differential Rx gain) calib data */ | 364 | /* Chain noise (differential Rx gain) calib data */ |
365 | struct iwl_chain_noise_data { | 365 | struct iwl_chain_noise_data { |
366 | u32 active_chains; | 366 | u32 active_chains; |
367 | u32 chain_noise_a; | 367 | u32 chain_noise_a; |
368 | u32 chain_noise_b; | 368 | u32 chain_noise_b; |
369 | u32 chain_noise_c; | 369 | u32 chain_noise_c; |
370 | u32 chain_signal_a; | 370 | u32 chain_signal_a; |
371 | u32 chain_signal_b; | 371 | u32 chain_signal_b; |
372 | u32 chain_signal_c; | 372 | u32 chain_signal_c; |
373 | u16 beacon_count; | 373 | u16 beacon_count; |
374 | u8 disconn_array[NUM_RX_CHAINS]; | 374 | u8 disconn_array[NUM_RX_CHAINS]; |
375 | u8 delta_gain_code[NUM_RX_CHAINS]; | 375 | u8 delta_gain_code[NUM_RX_CHAINS]; |
376 | u8 radio_write; | 376 | u8 radio_write; |
377 | u8 state; | 377 | u8 state; |
378 | }; | 378 | }; |
379 | 379 | ||
380 | enum { | 380 | enum { |
381 | MEASUREMENT_READY = (1 << 0), | 381 | MEASUREMENT_READY = (1 << 0), |
382 | MEASUREMENT_ACTIVE = (1 << 1), | 382 | MEASUREMENT_ACTIVE = (1 << 1), |
383 | }; | 383 | }; |
384 | 384 | ||
385 | /* reply_tx_statistics (for _agn devices) */ | 385 | /* reply_tx_statistics (for _agn devices) */ |
386 | struct reply_tx_error_statistics { | 386 | struct reply_tx_error_statistics { |
387 | u32 pp_delay; | 387 | u32 pp_delay; |
388 | u32 pp_few_bytes; | 388 | u32 pp_few_bytes; |
389 | u32 pp_bt_prio; | 389 | u32 pp_bt_prio; |
390 | u32 pp_quiet_period; | 390 | u32 pp_quiet_period; |
391 | u32 pp_calc_ttak; | 391 | u32 pp_calc_ttak; |
392 | u32 int_crossed_retry; | 392 | u32 int_crossed_retry; |
393 | u32 short_limit; | 393 | u32 short_limit; |
394 | u32 long_limit; | 394 | u32 long_limit; |
395 | u32 fifo_underrun; | 395 | u32 fifo_underrun; |
396 | u32 drain_flow; | 396 | u32 drain_flow; |
397 | u32 rfkill_flush; | 397 | u32 rfkill_flush; |
398 | u32 life_expire; | 398 | u32 life_expire; |
399 | u32 dest_ps; | 399 | u32 dest_ps; |
400 | u32 host_abort; | 400 | u32 host_abort; |
401 | u32 bt_retry; | 401 | u32 bt_retry; |
402 | u32 sta_invalid; | 402 | u32 sta_invalid; |
403 | u32 frag_drop; | 403 | u32 frag_drop; |
404 | u32 tid_disable; | 404 | u32 tid_disable; |
405 | u32 fifo_flush; | 405 | u32 fifo_flush; |
406 | u32 insuff_cf_poll; | 406 | u32 insuff_cf_poll; |
407 | u32 fail_hw_drop; | 407 | u32 fail_hw_drop; |
408 | u32 sta_color_mismatch; | 408 | u32 sta_color_mismatch; |
409 | u32 unknown; | 409 | u32 unknown; |
410 | }; | 410 | }; |
411 | 411 | ||
412 | /* reply_agg_tx_statistics (for _agn devices) */ | 412 | /* reply_agg_tx_statistics (for _agn devices) */ |
413 | struct reply_agg_tx_error_statistics { | 413 | struct reply_agg_tx_error_statistics { |
414 | u32 underrun; | 414 | u32 underrun; |
415 | u32 bt_prio; | 415 | u32 bt_prio; |
416 | u32 few_bytes; | 416 | u32 few_bytes; |
417 | u32 abort; | 417 | u32 abort; |
418 | u32 last_sent_ttl; | 418 | u32 last_sent_ttl; |
419 | u32 last_sent_try; | 419 | u32 last_sent_try; |
420 | u32 last_sent_bt_kill; | 420 | u32 last_sent_bt_kill; |
421 | u32 scd_query; | 421 | u32 scd_query; |
422 | u32 bad_crc32; | 422 | u32 bad_crc32; |
423 | u32 response; | 423 | u32 response; |
424 | u32 dump_tx; | 424 | u32 dump_tx; |
425 | u32 delay_tx; | 425 | u32 delay_tx; |
426 | u32 unknown; | 426 | u32 unknown; |
427 | }; | 427 | }; |
428 | 428 | ||
429 | /* | 429 | /* |
430 | * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds | 430 | * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds |
431 | * to perform continuous uCode event logging operation if enabled | 431 | * to perform continuous uCode event logging operation if enabled |
432 | */ | 432 | */ |
433 | #define UCODE_TRACE_PERIOD (10) | 433 | #define UCODE_TRACE_PERIOD (10) |
434 | 434 | ||
435 | /* | 435 | /* |
436 | * iwl_event_log: current uCode event log position | 436 | * iwl_event_log: current uCode event log position |
437 | * | 437 | * |
438 | * @ucode_trace: enable/disable ucode continuous trace timer | 438 | * @ucode_trace: enable/disable ucode continuous trace timer |
439 | * @num_wraps: how many times the event buffer wraps | 439 | * @num_wraps: how many times the event buffer wraps |
440 | * @next_entry: the entry just before the next one that uCode would fill | 440 | * @next_entry: the entry just before the next one that uCode would fill |
441 | * @non_wraps_count: counter for no wrap detected when dump ucode events | 441 | * @non_wraps_count: counter for no wrap detected when dump ucode events |
442 | * @wraps_once_count: counter for wrap once detected when dump ucode events | 442 | * @wraps_once_count: counter for wrap once detected when dump ucode events |
443 | * @wraps_more_count: counter for wrap more than once detected | 443 | * @wraps_more_count: counter for wrap more than once detected |
444 | * when dump ucode events | 444 | * when dump ucode events |
445 | */ | 445 | */ |
446 | struct iwl_event_log { | 446 | struct iwl_event_log { |
447 | bool ucode_trace; | 447 | bool ucode_trace; |
448 | u32 num_wraps; | 448 | u32 num_wraps; |
449 | u32 next_entry; | 449 | u32 next_entry; |
450 | int non_wraps_count; | 450 | int non_wraps_count; |
451 | int wraps_once_count; | 451 | int wraps_once_count; |
452 | int wraps_more_count; | 452 | int wraps_more_count; |
453 | }; | 453 | }; |
454 | 454 | ||
455 | #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) | 455 | #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) |
456 | 456 | ||
457 | /* BT Antenna Coupling Threshold (dB) */ | 457 | /* BT Antenna Coupling Threshold (dB) */ |
458 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) | 458 | #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) |
459 | 459 | ||
460 | /* Firmware reload counter and Timestamp */ | 460 | /* Firmware reload counter and Timestamp */ |
461 | #define IWL_MIN_RELOAD_DURATION 1000 /* 1000 ms */ | 461 | #define IWL_MIN_RELOAD_DURATION 1000 /* 1000 ms */ |
462 | #define IWL_MAX_CONTINUE_RELOAD_CNT 4 | 462 | #define IWL_MAX_CONTINUE_RELOAD_CNT 4 |
463 | 463 | ||
464 | 464 | ||
465 | struct iwl_rf_reset { | 465 | struct iwl_rf_reset { |
466 | int reset_request_count; | 466 | int reset_request_count; |
467 | int reset_success_count; | 467 | int reset_success_count; |
468 | int reset_reject_count; | 468 | int reset_reject_count; |
469 | unsigned long last_reset_jiffies; | 469 | unsigned long last_reset_jiffies; |
470 | }; | 470 | }; |
471 | 471 | ||
472 | enum iwl_rxon_context_id { | 472 | enum iwl_rxon_context_id { |
473 | IWL_RXON_CTX_BSS, | 473 | IWL_RXON_CTX_BSS, |
474 | IWL_RXON_CTX_PAN, | 474 | IWL_RXON_CTX_PAN, |
475 | 475 | ||
476 | NUM_IWL_RXON_CTX | 476 | NUM_IWL_RXON_CTX |
477 | }; | 477 | }; |
478 | 478 | ||
479 | /* extend beacon time format bit shifting */ | 479 | /* extend beacon time format bit shifting */ |
480 | /* | 480 | /* |
481 | * for _agn devices | 481 | * for _agn devices |
482 | * bits 31:22 - extended | 482 | * bits 31:22 - extended |
483 | * bits 21:0 - interval | 483 | * bits 21:0 - interval |
484 | */ | 484 | */ |
485 | #define IWLAGN_EXT_BEACON_TIME_POS 22 | 485 | #define IWLAGN_EXT_BEACON_TIME_POS 22 |
486 | 486 | ||
487 | struct iwl_rxon_context { | 487 | struct iwl_rxon_context { |
488 | struct ieee80211_vif *vif; | 488 | struct ieee80211_vif *vif; |
489 | 489 | ||
490 | u8 mcast_queue; | 490 | u8 mcast_queue; |
491 | u8 ac_to_queue[IEEE80211_NUM_ACS]; | 491 | u8 ac_to_queue[IEEE80211_NUM_ACS]; |
492 | u8 ac_to_fifo[IEEE80211_NUM_ACS]; | 492 | u8 ac_to_fifo[IEEE80211_NUM_ACS]; |
493 | 493 | ||
494 | /* | 494 | /* |
495 | * We could use the vif to indicate active, but we | 495 | * We could use the vif to indicate active, but we |
496 | * also need it to be active during disabling when | 496 | * also need it to be active during disabling when |
497 | * we already removed the vif for type setting. | 497 | * we already removed the vif for type setting. |
498 | */ | 498 | */ |
499 | bool always_active, is_active; | 499 | bool always_active, is_active; |
500 | 500 | ||
501 | bool ht_need_multiple_chains; | 501 | bool ht_need_multiple_chains; |
502 | 502 | ||
503 | enum iwl_rxon_context_id ctxid; | 503 | enum iwl_rxon_context_id ctxid; |
504 | 504 | ||
505 | u32 interface_modes, exclusive_interface_modes; | 505 | u32 interface_modes, exclusive_interface_modes; |
506 | u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; | 506 | u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; |
507 | 507 | ||
508 | /* | 508 | /* |
509 | * We declare this const so it can only be | 509 | * We declare this const so it can only be |
510 | * changed via explicit cast within the | 510 | * changed via explicit cast within the |
511 | * routines that actually update the physical | 511 | * routines that actually update the physical |
512 | * hardware. | 512 | * hardware. |
513 | */ | 513 | */ |
514 | const struct iwl_rxon_cmd active; | 514 | const struct iwl_rxon_cmd active; |
515 | struct iwl_rxon_cmd staging; | 515 | struct iwl_rxon_cmd staging; |
516 | 516 | ||
517 | struct iwl_rxon_time_cmd timing; | 517 | struct iwl_rxon_time_cmd timing; |
518 | 518 | ||
519 | struct iwl_qos_info qos_data; | 519 | struct iwl_qos_info qos_data; |
520 | 520 | ||
521 | u8 bcast_sta_id, ap_sta_id; | 521 | u8 bcast_sta_id, ap_sta_id; |
522 | 522 | ||
523 | u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; | 523 | u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; |
524 | u8 qos_cmd; | 524 | u8 qos_cmd; |
525 | u8 wep_key_cmd; | 525 | u8 wep_key_cmd; |
526 | 526 | ||
527 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; | 527 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; |
528 | u8 key_mapping_keys; | 528 | u8 key_mapping_keys; |
529 | 529 | ||
530 | __le32 station_flags; | 530 | __le32 station_flags; |
531 | 531 | ||
532 | int beacon_int; | 532 | int beacon_int; |
533 | 533 | ||
534 | struct { | 534 | struct { |
535 | bool non_gf_sta_present; | 535 | bool non_gf_sta_present; |
536 | u8 protection; | 536 | u8 protection; |
537 | bool enabled, is_40mhz; | 537 | bool enabled, is_40mhz; |
538 | u8 extension_chan_offset; | 538 | u8 extension_chan_offset; |
539 | } ht; | 539 | } ht; |
540 | }; | 540 | }; |
541 | 541 | ||
542 | enum iwl_scan_type { | 542 | enum iwl_scan_type { |
543 | IWL_SCAN_NORMAL, | 543 | IWL_SCAN_NORMAL, |
544 | IWL_SCAN_RADIO_RESET, | 544 | IWL_SCAN_RADIO_RESET, |
545 | IWL_SCAN_ROC, | 545 | IWL_SCAN_ROC, |
546 | }; | 546 | }; |
547 | 547 | ||
548 | /** | 548 | /** |
549 | * struct iwl_hw_params | 549 | * struct iwl_hw_params |
550 | * | 550 | * |
551 | * Holds the module parameters | 551 | * Holds the module parameters |
552 | * | 552 | * |
553 | * @tx_chains_num: Number of TX chains | 553 | * @tx_chains_num: Number of TX chains |
554 | * @rx_chains_num: Number of RX chains | 554 | * @rx_chains_num: Number of RX chains |
555 | * @ct_kill_threshold: temperature threshold - in hw dependent unit | 555 | * @ct_kill_threshold: temperature threshold - in hw dependent unit |
556 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit | 556 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit |
557 | * relevant for 1000, 6000 and up | 557 | * relevant for 1000, 6000 and up |
558 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 558 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
559 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | 559 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic |
560 | */ | 560 | */ |
561 | struct iwl_hw_params { | 561 | struct iwl_hw_params { |
562 | u8 tx_chains_num; | 562 | u8 tx_chains_num; |
563 | u8 rx_chains_num; | 563 | u8 rx_chains_num; |
564 | bool use_rts_for_aggregation; | 564 | bool use_rts_for_aggregation; |
565 | u32 ct_kill_threshold; | 565 | u32 ct_kill_threshold; |
566 | u32 ct_kill_exit_threshold; | 566 | u32 ct_kill_exit_threshold; |
567 | 567 | ||
568 | const struct iwl_sensitivity_ranges *sens; | 568 | const struct iwl_sensitivity_ranges *sens; |
569 | }; | 569 | }; |
570 | 570 | ||
571 | struct iwl_lib_ops { | 571 | struct iwl_lib_ops { |
572 | /* set hw dependent parameters */ | 572 | /* set hw dependent parameters */ |
573 | void (*set_hw_params)(struct iwl_priv *priv); | 573 | void (*set_hw_params)(struct iwl_priv *priv); |
574 | int (*set_channel_switch)(struct iwl_priv *priv, | 574 | int (*set_channel_switch)(struct iwl_priv *priv, |
575 | struct ieee80211_channel_switch *ch_switch); | 575 | struct ieee80211_channel_switch *ch_switch); |
576 | /* device specific configuration */ | 576 | /* device specific configuration */ |
577 | void (*nic_config)(struct iwl_priv *priv); | 577 | void (*nic_config)(struct iwl_priv *priv); |
578 | 578 | ||
579 | /* temperature */ | 579 | /* temperature */ |
580 | void (*temperature)(struct iwl_priv *priv); | 580 | void (*temperature)(struct iwl_priv *priv); |
581 | }; | 581 | }; |
582 | 582 | ||
583 | struct iwl_wipan_noa_data { | 583 | struct iwl_wipan_noa_data { |
584 | struct rcu_head rcu_head; | 584 | struct rcu_head rcu_head; |
585 | u32 length; | 585 | u32 length; |
586 | u8 data[]; | 586 | u8 data[]; |
587 | }; | 587 | }; |
588 | 588 | ||
589 | /* Calibration disabling bit mask */ | 589 | /* Calibration disabling bit mask */ |
590 | enum { | 590 | enum { |
591 | IWL_CALIB_ENABLE_ALL = 0, | 591 | IWL_CALIB_ENABLE_ALL = 0, |
592 | 592 | ||
593 | IWL_SENSITIVITY_CALIB_DISABLED = BIT(0), | 593 | IWL_SENSITIVITY_CALIB_DISABLED = BIT(0), |
594 | IWL_CHAIN_NOISE_CALIB_DISABLED = BIT(1), | 594 | IWL_CHAIN_NOISE_CALIB_DISABLED = BIT(1), |
595 | IWL_TX_POWER_CALIB_DISABLED = BIT(2), | 595 | IWL_TX_POWER_CALIB_DISABLED = BIT(2), |
596 | 596 | ||
597 | IWL_CALIB_DISABLE_ALL = 0xFFFFFFFF, | 597 | IWL_CALIB_DISABLE_ALL = 0xFFFFFFFF, |
598 | }; | 598 | }; |
599 | 599 | ||
600 | #define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ | 600 | #define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ |
601 | ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) | 601 | ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) |
602 | 602 | ||
603 | #define IWL_MAC80211_GET_DVM(_hw) \ | 603 | #define IWL_MAC80211_GET_DVM(_hw) \ |
604 | ((struct iwl_priv *) ((struct iwl_op_mode *) \ | 604 | ((struct iwl_priv *) ((struct iwl_op_mode *) \ |
605 | (_hw)->priv)->op_mode_specific) | 605 | (_hw)->priv)->op_mode_specific) |
606 | 606 | ||
607 | struct iwl_priv { | 607 | struct iwl_priv { |
608 | 608 | ||
609 | struct iwl_trans *trans; | 609 | struct iwl_trans *trans; |
610 | struct device *dev; /* for debug prints only */ | 610 | struct device *dev; /* for debug prints only */ |
611 | const struct iwl_cfg *cfg; | 611 | const struct iwl_cfg *cfg; |
612 | const struct iwl_fw *fw; | 612 | const struct iwl_fw *fw; |
613 | const struct iwl_lib_ops *lib; | 613 | const struct iwl_lib_ops *lib; |
614 | unsigned long status; | 614 | unsigned long status; |
615 | 615 | ||
616 | spinlock_t sta_lock; | 616 | spinlock_t sta_lock; |
617 | struct mutex mutex; | 617 | struct mutex mutex; |
618 | 618 | ||
619 | unsigned long transport_queue_stop; | 619 | unsigned long transport_queue_stop; |
620 | bool passive_no_rx; | 620 | bool passive_no_rx; |
621 | #define IWL_INVALID_MAC80211_QUEUE 0xff | 621 | #define IWL_INVALID_MAC80211_QUEUE 0xff |
622 | u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; | 622 | u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; |
623 | atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; | 623 | atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; |
624 | 624 | ||
625 | unsigned long agg_q_alloc[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; | 625 | unsigned long agg_q_alloc[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; |
626 | 626 | ||
627 | /* ieee device used by generic ieee processing code */ | 627 | /* ieee device used by generic ieee processing code */ |
628 | struct ieee80211_hw *hw; | 628 | struct ieee80211_hw *hw; |
629 | 629 | ||
630 | struct list_head calib_results; | 630 | struct list_head calib_results; |
631 | 631 | ||
632 | struct workqueue_struct *workqueue; | 632 | struct workqueue_struct *workqueue; |
633 | 633 | ||
634 | struct iwl_hw_params hw_params; | 634 | struct iwl_hw_params hw_params; |
635 | 635 | ||
636 | enum ieee80211_band band; | 636 | enum ieee80211_band band; |
637 | u8 valid_contexts; | 637 | u8 valid_contexts; |
638 | 638 | ||
639 | int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, | 639 | int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, |
640 | struct iwl_rx_cmd_buffer *rxb, | 640 | struct iwl_rx_cmd_buffer *rxb, |
641 | struct iwl_device_cmd *cmd); | 641 | struct iwl_device_cmd *cmd); |
642 | 642 | ||
643 | struct iwl_notif_wait_data notif_wait; | 643 | struct iwl_notif_wait_data notif_wait; |
644 | 644 | ||
645 | /* spectrum measurement report caching */ | 645 | /* spectrum measurement report caching */ |
646 | struct iwl_spectrum_notification measure_report; | 646 | struct iwl_spectrum_notification measure_report; |
647 | u8 measurement_status; | 647 | u8 measurement_status; |
648 | 648 | ||
649 | #define IWL_OWNERSHIP_DRIVER 0 | 649 | #define IWL_OWNERSHIP_DRIVER 0 |
650 | #define IWL_OWNERSHIP_TM 1 | 650 | #define IWL_OWNERSHIP_TM 1 |
651 | u8 ucode_owner; | 651 | u8 ucode_owner; |
652 | 652 | ||
653 | /* ucode beacon time */ | 653 | /* ucode beacon time */ |
654 | u32 ucode_beacon_time; | 654 | u32 ucode_beacon_time; |
655 | int missed_beacon_threshold; | 655 | int missed_beacon_threshold; |
656 | 656 | ||
657 | /* track IBSS manager (last beacon) status */ | 657 | /* track IBSS manager (last beacon) status */ |
658 | u32 ibss_manager; | 658 | u32 ibss_manager; |
659 | 659 | ||
660 | /* jiffies when last recovery from statistics was performed */ | 660 | /* jiffies when last recovery from statistics was performed */ |
661 | unsigned long rx_statistics_jiffies; | 661 | unsigned long rx_statistics_jiffies; |
662 | 662 | ||
663 | /*counters */ | 663 | /*counters */ |
664 | u32 rx_handlers_stats[REPLY_MAX]; | 664 | u32 rx_handlers_stats[REPLY_MAX]; |
665 | 665 | ||
666 | /* rf reset */ | 666 | /* rf reset */ |
667 | struct iwl_rf_reset rf_reset; | 667 | struct iwl_rf_reset rf_reset; |
668 | 668 | ||
669 | /* firmware reload counter and timestamp */ | 669 | /* firmware reload counter and timestamp */ |
670 | unsigned long reload_jiffies; | 670 | unsigned long reload_jiffies; |
671 | int reload_count; | 671 | int reload_count; |
672 | bool ucode_loaded; | 672 | bool ucode_loaded; |
673 | bool init_ucode_run; /* Don't run init uCode again */ | 673 | bool init_ucode_run; /* Don't run init uCode again */ |
674 | 674 | ||
675 | u8 plcp_delta_threshold; | 675 | u8 plcp_delta_threshold; |
676 | 676 | ||
677 | /* thermal calibration */ | 677 | /* thermal calibration */ |
678 | s32 temperature; /* Celsius */ | 678 | s32 temperature; /* Celsius */ |
679 | s32 last_temperature; | 679 | s32 last_temperature; |
680 | 680 | ||
681 | struct iwl_wipan_noa_data __rcu *noa_data; | 681 | struct iwl_wipan_noa_data __rcu *noa_data; |
682 | 682 | ||
683 | /* Scan related variables */ | 683 | /* Scan related variables */ |
684 | unsigned long scan_start; | 684 | unsigned long scan_start; |
685 | unsigned long scan_start_tsf; | 685 | unsigned long scan_start_tsf; |
686 | void *scan_cmd; | 686 | void *scan_cmd; |
687 | enum ieee80211_band scan_band; | 687 | enum ieee80211_band scan_band; |
688 | struct cfg80211_scan_request *scan_request; | 688 | struct cfg80211_scan_request *scan_request; |
689 | struct ieee80211_vif *scan_vif; | 689 | struct ieee80211_vif *scan_vif; |
690 | enum iwl_scan_type scan_type; | 690 | enum iwl_scan_type scan_type; |
691 | u8 scan_tx_ant[IEEE80211_NUM_BANDS]; | 691 | u8 scan_tx_ant[IEEE80211_NUM_BANDS]; |
692 | u8 mgmt_tx_ant; | 692 | u8 mgmt_tx_ant; |
693 | 693 | ||
694 | /* max number of station keys */ | 694 | /* max number of station keys */ |
695 | u8 sta_key_max_num; | 695 | u8 sta_key_max_num; |
696 | 696 | ||
697 | bool new_scan_threshold_behaviour; | 697 | bool new_scan_threshold_behaviour; |
698 | 698 | ||
699 | bool wowlan; | 699 | bool wowlan; |
700 | 700 | ||
701 | /* EEPROM MAC addresses */ | 701 | /* EEPROM MAC addresses */ |
702 | struct mac_address addresses[2]; | 702 | struct mac_address addresses[2]; |
703 | 703 | ||
704 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; | 704 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; |
705 | 705 | ||
706 | __le16 switch_channel; | 706 | __le16 switch_channel; |
707 | 707 | ||
708 | u8 start_calib; | 708 | u8 start_calib; |
709 | struct iwl_sensitivity_data sensitivity_data; | 709 | struct iwl_sensitivity_data sensitivity_data; |
710 | struct iwl_chain_noise_data chain_noise_data; | 710 | struct iwl_chain_noise_data chain_noise_data; |
711 | __le16 sensitivity_tbl[HD_TABLE_SIZE]; | 711 | __le16 sensitivity_tbl[HD_TABLE_SIZE]; |
712 | __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES]; | 712 | __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES]; |
713 | 713 | ||
714 | struct iwl_ht_config current_ht_config; | 714 | struct iwl_ht_config current_ht_config; |
715 | 715 | ||
716 | /* Rate scaling data */ | 716 | /* Rate scaling data */ |
717 | u8 retry_rate; | 717 | u8 retry_rate; |
718 | 718 | ||
719 | int activity_timer_active; | 719 | int activity_timer_active; |
720 | 720 | ||
721 | struct iwl_power_mgr power_data; | 721 | struct iwl_power_mgr power_data; |
722 | struct iwl_tt_mgmt thermal_throttle; | 722 | struct iwl_tt_mgmt thermal_throttle; |
723 | 723 | ||
724 | /* station table variables */ | 724 | /* station table variables */ |
725 | int num_stations; | 725 | int num_stations; |
726 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; | 726 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; |
727 | unsigned long ucode_key_table; | 727 | unsigned long ucode_key_table; |
728 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | 728 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; |
729 | atomic_t num_aux_in_flight; | 729 | atomic_t num_aux_in_flight; |
730 | 730 | ||
731 | u8 mac80211_registered; | 731 | u8 mac80211_registered; |
732 | 732 | ||
733 | /* Indication if ieee80211_ops->open has been called */ | 733 | /* Indication if ieee80211_ops->open has been called */ |
734 | u8 is_open; | 734 | u8 is_open; |
735 | 735 | ||
736 | enum nl80211_iftype iw_mode; | 736 | enum nl80211_iftype iw_mode; |
737 | 737 | ||
738 | /* Last Rx'd beacon timestamp */ | 738 | /* Last Rx'd beacon timestamp */ |
739 | u64 timestamp; | 739 | u64 timestamp; |
740 | 740 | ||
741 | struct { | 741 | struct { |
742 | __le32 flag; | 742 | __le32 flag; |
743 | struct statistics_general_common common; | 743 | struct statistics_general_common common; |
744 | struct statistics_rx_non_phy rx_non_phy; | 744 | struct statistics_rx_non_phy rx_non_phy; |
745 | struct statistics_rx_phy rx_ofdm; | 745 | struct statistics_rx_phy rx_ofdm; |
746 | struct statistics_rx_ht_phy rx_ofdm_ht; | 746 | struct statistics_rx_ht_phy rx_ofdm_ht; |
747 | struct statistics_rx_phy rx_cck; | 747 | struct statistics_rx_phy rx_cck; |
748 | struct statistics_tx tx; | 748 | struct statistics_tx tx; |
749 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 749 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
750 | struct statistics_bt_activity bt_activity; | 750 | struct statistics_bt_activity bt_activity; |
751 | __le32 num_bt_kills, accum_num_bt_kills; | 751 | __le32 num_bt_kills, accum_num_bt_kills; |
752 | #endif | 752 | #endif |
753 | spinlock_t lock; | 753 | spinlock_t lock; |
754 | } statistics; | 754 | } statistics; |
755 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 755 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
756 | struct { | 756 | struct { |
757 | struct statistics_general_common common; | 757 | struct statistics_general_common common; |
758 | struct statistics_rx_non_phy rx_non_phy; | 758 | struct statistics_rx_non_phy rx_non_phy; |
759 | struct statistics_rx_phy rx_ofdm; | 759 | struct statistics_rx_phy rx_ofdm; |
760 | struct statistics_rx_ht_phy rx_ofdm_ht; | 760 | struct statistics_rx_ht_phy rx_ofdm_ht; |
761 | struct statistics_rx_phy rx_cck; | 761 | struct statistics_rx_phy rx_cck; |
762 | struct statistics_tx tx; | 762 | struct statistics_tx tx; |
763 | struct statistics_bt_activity bt_activity; | 763 | struct statistics_bt_activity bt_activity; |
764 | } accum_stats, delta_stats, max_delta_stats; | 764 | } accum_stats, delta_stats, max_delta_stats; |
765 | #endif | 765 | #endif |
766 | 766 | ||
767 | /* | 767 | /* |
768 | * reporting the number of tids has AGG on. 0 means | 768 | * reporting the number of tids has AGG on. 0 means |
769 | * no AGGREGATION | 769 | * no AGGREGATION |
770 | */ | 770 | */ |
771 | u8 agg_tids_count; | 771 | u8 agg_tids_count; |
772 | 772 | ||
773 | struct iwl_rx_phy_res last_phy_res; | 773 | struct iwl_rx_phy_res last_phy_res; |
774 | u32 ampdu_ref; | ||
774 | bool last_phy_res_valid; | 775 | bool last_phy_res_valid; |
775 | 776 | ||
776 | /* | 777 | /* |
777 | * chain noise reset and gain commands are the | 778 | * chain noise reset and gain commands are the |
778 | * two extra calibration commands follows the standard | 779 | * two extra calibration commands follows the standard |
779 | * phy calibration commands | 780 | * phy calibration commands |
780 | */ | 781 | */ |
781 | u8 phy_calib_chain_noise_reset_cmd; | 782 | u8 phy_calib_chain_noise_reset_cmd; |
782 | u8 phy_calib_chain_noise_gain_cmd; | 783 | u8 phy_calib_chain_noise_gain_cmd; |
783 | 784 | ||
784 | /* counts reply_tx error */ | 785 | /* counts reply_tx error */ |
785 | struct reply_tx_error_statistics reply_tx_stats; | 786 | struct reply_tx_error_statistics reply_tx_stats; |
786 | struct reply_agg_tx_error_statistics reply_agg_tx_stats; | 787 | struct reply_agg_tx_error_statistics reply_agg_tx_stats; |
787 | 788 | ||
788 | /* remain-on-channel offload support */ | 789 | /* remain-on-channel offload support */ |
789 | struct ieee80211_channel *hw_roc_channel; | 790 | struct ieee80211_channel *hw_roc_channel; |
790 | struct delayed_work hw_roc_disable_work; | 791 | struct delayed_work hw_roc_disable_work; |
791 | enum nl80211_channel_type hw_roc_chantype; | 792 | enum nl80211_channel_type hw_roc_chantype; |
792 | int hw_roc_duration; | 793 | int hw_roc_duration; |
793 | bool hw_roc_setup, hw_roc_start_notified; | 794 | bool hw_roc_setup, hw_roc_start_notified; |
794 | 795 | ||
795 | /* bt coex */ | 796 | /* bt coex */ |
796 | u8 bt_enable_flag; | 797 | u8 bt_enable_flag; |
797 | u8 bt_status; | 798 | u8 bt_status; |
798 | u8 bt_traffic_load, last_bt_traffic_load; | 799 | u8 bt_traffic_load, last_bt_traffic_load; |
799 | bool bt_ch_announce; | 800 | bool bt_ch_announce; |
800 | bool bt_full_concurrent; | 801 | bool bt_full_concurrent; |
801 | bool bt_ant_couple_ok; | 802 | bool bt_ant_couple_ok; |
802 | __le32 kill_ack_mask; | 803 | __le32 kill_ack_mask; |
803 | __le32 kill_cts_mask; | 804 | __le32 kill_cts_mask; |
804 | __le16 bt_valid; | 805 | __le16 bt_valid; |
805 | bool reduced_txpower; | 806 | bool reduced_txpower; |
806 | u16 bt_on_thresh; | 807 | u16 bt_on_thresh; |
807 | u16 bt_duration; | 808 | u16 bt_duration; |
808 | u16 dynamic_frag_thresh; | 809 | u16 dynamic_frag_thresh; |
809 | u8 bt_ci_compliance; | 810 | u8 bt_ci_compliance; |
810 | struct work_struct bt_traffic_change_work; | 811 | struct work_struct bt_traffic_change_work; |
811 | bool bt_enable_pspoll; | 812 | bool bt_enable_pspoll; |
812 | struct iwl_rxon_context *cur_rssi_ctx; | 813 | struct iwl_rxon_context *cur_rssi_ctx; |
813 | bool bt_is_sco; | 814 | bool bt_is_sco; |
814 | 815 | ||
815 | struct work_struct restart; | 816 | struct work_struct restart; |
816 | struct work_struct scan_completed; | 817 | struct work_struct scan_completed; |
817 | struct work_struct abort_scan; | 818 | struct work_struct abort_scan; |
818 | 819 | ||
819 | struct work_struct beacon_update; | 820 | struct work_struct beacon_update; |
820 | struct iwl_rxon_context *beacon_ctx; | 821 | struct iwl_rxon_context *beacon_ctx; |
821 | struct sk_buff *beacon_skb; | 822 | struct sk_buff *beacon_skb; |
822 | void *beacon_cmd; | 823 | void *beacon_cmd; |
823 | 824 | ||
824 | struct work_struct tt_work; | 825 | struct work_struct tt_work; |
825 | struct work_struct ct_enter; | 826 | struct work_struct ct_enter; |
826 | struct work_struct ct_exit; | 827 | struct work_struct ct_exit; |
827 | struct work_struct start_internal_scan; | 828 | struct work_struct start_internal_scan; |
828 | struct work_struct tx_flush; | 829 | struct work_struct tx_flush; |
829 | struct work_struct bt_full_concurrency; | 830 | struct work_struct bt_full_concurrency; |
830 | struct work_struct bt_runtime_config; | 831 | struct work_struct bt_runtime_config; |
831 | 832 | ||
832 | struct delayed_work scan_check; | 833 | struct delayed_work scan_check; |
833 | 834 | ||
834 | /* TX Power settings */ | 835 | /* TX Power settings */ |
835 | s8 tx_power_user_lmt; | 836 | s8 tx_power_user_lmt; |
836 | s8 tx_power_next; | 837 | s8 tx_power_next; |
837 | 838 | ||
838 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 839 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
839 | /* debugfs */ | 840 | /* debugfs */ |
840 | struct dentry *debugfs_dir; | 841 | struct dentry *debugfs_dir; |
841 | u32 dbgfs_sram_offset, dbgfs_sram_len; | 842 | u32 dbgfs_sram_offset, dbgfs_sram_len; |
842 | bool disable_ht40; | 843 | bool disable_ht40; |
843 | void *wowlan_sram; | 844 | void *wowlan_sram; |
844 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 845 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
845 | 846 | ||
846 | struct iwl_eeprom_data *eeprom_data; | 847 | struct iwl_eeprom_data *eeprom_data; |
847 | /* eeprom blob for debugfs/testmode */ | 848 | /* eeprom blob for debugfs/testmode */ |
848 | u8 *eeprom_blob; | 849 | u8 *eeprom_blob; |
849 | size_t eeprom_blob_size; | 850 | size_t eeprom_blob_size; |
850 | 851 | ||
851 | struct work_struct txpower_work; | 852 | struct work_struct txpower_work; |
852 | u32 calib_disabled; | 853 | u32 calib_disabled; |
853 | struct work_struct run_time_calib_work; | 854 | struct work_struct run_time_calib_work; |
854 | struct timer_list statistics_periodic; | 855 | struct timer_list statistics_periodic; |
855 | struct timer_list ucode_trace; | 856 | struct timer_list ucode_trace; |
856 | 857 | ||
857 | struct iwl_event_log event_log; | 858 | struct iwl_event_log event_log; |
858 | 859 | ||
859 | struct led_classdev led; | 860 | struct led_classdev led; |
860 | unsigned long blink_on, blink_off; | 861 | unsigned long blink_on, blink_off; |
861 | bool led_registered; | 862 | bool led_registered; |
862 | 863 | ||
863 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 864 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
864 | struct iwl_test tst; | 865 | struct iwl_test tst; |
865 | u32 tm_fixed_rate; | 866 | u32 tm_fixed_rate; |
866 | #endif | 867 | #endif |
867 | 868 | ||
868 | /* WoWLAN GTK rekey data */ | 869 | /* WoWLAN GTK rekey data */ |
869 | u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; | 870 | u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; |
870 | __le64 replay_ctr; | 871 | __le64 replay_ctr; |
871 | __le16 last_seq_ctl; | 872 | __le16 last_seq_ctl; |
872 | bool have_rekey_data; | 873 | bool have_rekey_data; |
873 | 874 | ||
874 | /* device_pointers: pointers to ucode event tables */ | 875 | /* device_pointers: pointers to ucode event tables */ |
875 | struct { | 876 | struct { |
876 | u32 error_event_table; | 877 | u32 error_event_table; |
877 | u32 log_event_table; | 878 | u32 log_event_table; |
878 | } device_pointers; | 879 | } device_pointers; |
879 | 880 | ||
880 | /* indicator of loaded ucode image */ | 881 | /* indicator of loaded ucode image */ |
881 | enum iwl_ucode_type cur_ucode; | 882 | enum iwl_ucode_type cur_ucode; |
882 | }; /*iwl_priv */ | 883 | }; /*iwl_priv */ |
883 | 884 | ||
884 | static inline struct iwl_rxon_context * | 885 | static inline struct iwl_rxon_context * |
885 | iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) | 886 | iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) |
886 | { | 887 | { |
887 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 888 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
888 | 889 | ||
889 | return vif_priv->ctx; | 890 | return vif_priv->ctx; |
890 | } | 891 | } |
891 | 892 | ||
892 | #define for_each_context(priv, ctx) \ | 893 | #define for_each_context(priv, ctx) \ |
893 | for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \ | 894 | for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \ |
894 | ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ | 895 | ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ |
895 | if (priv->valid_contexts & BIT(ctx->ctxid)) | 896 | if (priv->valid_contexts & BIT(ctx->ctxid)) |
896 | 897 | ||
897 | static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) | 898 | static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) |
898 | { | 899 | { |
899 | return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; | 900 | return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; |
900 | } | 901 | } |
901 | 902 | ||
902 | static inline int iwl_is_associated(struct iwl_priv *priv, | 903 | static inline int iwl_is_associated(struct iwl_priv *priv, |
903 | enum iwl_rxon_context_id ctxid) | 904 | enum iwl_rxon_context_id ctxid) |
904 | { | 905 | { |
905 | return iwl_is_associated_ctx(&priv->contexts[ctxid]); | 906 | return iwl_is_associated_ctx(&priv->contexts[ctxid]); |
906 | } | 907 | } |
907 | 908 | ||
908 | static inline int iwl_is_any_associated(struct iwl_priv *priv) | 909 | static inline int iwl_is_any_associated(struct iwl_priv *priv) |
909 | { | 910 | { |
910 | struct iwl_rxon_context *ctx; | 911 | struct iwl_rxon_context *ctx; |
911 | for_each_context(priv, ctx) | 912 | for_each_context(priv, ctx) |
912 | if (iwl_is_associated_ctx(ctx)) | 913 | if (iwl_is_associated_ctx(ctx)) |
913 | return true; | 914 | return true; |
914 | return false; | 915 | return false; |
915 | } | 916 | } |
916 | 917 | ||
917 | #endif /* __iwl_dev_h__ */ | 918 | #endif /* __iwl_dev_h__ */ |
918 | 919 |
drivers/net/wireless/iwlwifi/dvm/rx.c
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portionhelp of the ieee80211 subsystem header files. | 6 | * as portionhelp of the ieee80211 subsystem header files. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of version 2 of the GNU General Public License as | 9 | * under the terms of version 2 of the GNU General Public License as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | 12 | * This program is distributed in the hope that it will be useful, but WITHOUT |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
15 | * more details. | 15 | * more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License along with | 17 | * You should have received a copy of the GNU General Public License along with |
18 | * this program; if not, write to the Free Software Foundation, Inc., | 18 | * this program; if not, write to the Free Software Foundation, Inc., |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution in the | 21 | * The full GNU General Public License is included in this distribution in the |
22 | * file called LICENSE. | 22 | * file called LICENSE. |
23 | * | 23 | * |
24 | * Contact Information: | 24 | * Contact Information: |
25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
34 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
35 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
36 | #include "dev.h" | 36 | #include "dev.h" |
37 | #include "calib.h" | 37 | #include "calib.h" |
38 | #include "agn.h" | 38 | #include "agn.h" |
39 | 39 | ||
40 | #define IWL_CMD_ENTRY(x) [x] = #x | 40 | #define IWL_CMD_ENTRY(x) [x] = #x |
41 | 41 | ||
42 | const char *iwl_dvm_cmd_strings[REPLY_MAX] = { | 42 | const char *iwl_dvm_cmd_strings[REPLY_MAX] = { |
43 | IWL_CMD_ENTRY(REPLY_ALIVE), | 43 | IWL_CMD_ENTRY(REPLY_ALIVE), |
44 | IWL_CMD_ENTRY(REPLY_ERROR), | 44 | IWL_CMD_ENTRY(REPLY_ERROR), |
45 | IWL_CMD_ENTRY(REPLY_ECHO), | 45 | IWL_CMD_ENTRY(REPLY_ECHO), |
46 | IWL_CMD_ENTRY(REPLY_RXON), | 46 | IWL_CMD_ENTRY(REPLY_RXON), |
47 | IWL_CMD_ENTRY(REPLY_RXON_ASSOC), | 47 | IWL_CMD_ENTRY(REPLY_RXON_ASSOC), |
48 | IWL_CMD_ENTRY(REPLY_QOS_PARAM), | 48 | IWL_CMD_ENTRY(REPLY_QOS_PARAM), |
49 | IWL_CMD_ENTRY(REPLY_RXON_TIMING), | 49 | IWL_CMD_ENTRY(REPLY_RXON_TIMING), |
50 | IWL_CMD_ENTRY(REPLY_ADD_STA), | 50 | IWL_CMD_ENTRY(REPLY_ADD_STA), |
51 | IWL_CMD_ENTRY(REPLY_REMOVE_STA), | 51 | IWL_CMD_ENTRY(REPLY_REMOVE_STA), |
52 | IWL_CMD_ENTRY(REPLY_REMOVE_ALL_STA), | 52 | IWL_CMD_ENTRY(REPLY_REMOVE_ALL_STA), |
53 | IWL_CMD_ENTRY(REPLY_TXFIFO_FLUSH), | 53 | IWL_CMD_ENTRY(REPLY_TXFIFO_FLUSH), |
54 | IWL_CMD_ENTRY(REPLY_WEPKEY), | 54 | IWL_CMD_ENTRY(REPLY_WEPKEY), |
55 | IWL_CMD_ENTRY(REPLY_TX), | 55 | IWL_CMD_ENTRY(REPLY_TX), |
56 | IWL_CMD_ENTRY(REPLY_LEDS_CMD), | 56 | IWL_CMD_ENTRY(REPLY_LEDS_CMD), |
57 | IWL_CMD_ENTRY(REPLY_TX_LINK_QUALITY_CMD), | 57 | IWL_CMD_ENTRY(REPLY_TX_LINK_QUALITY_CMD), |
58 | IWL_CMD_ENTRY(COEX_PRIORITY_TABLE_CMD), | 58 | IWL_CMD_ENTRY(COEX_PRIORITY_TABLE_CMD), |
59 | IWL_CMD_ENTRY(COEX_MEDIUM_NOTIFICATION), | 59 | IWL_CMD_ENTRY(COEX_MEDIUM_NOTIFICATION), |
60 | IWL_CMD_ENTRY(COEX_EVENT_CMD), | 60 | IWL_CMD_ENTRY(COEX_EVENT_CMD), |
61 | IWL_CMD_ENTRY(REPLY_QUIET_CMD), | 61 | IWL_CMD_ENTRY(REPLY_QUIET_CMD), |
62 | IWL_CMD_ENTRY(REPLY_CHANNEL_SWITCH), | 62 | IWL_CMD_ENTRY(REPLY_CHANNEL_SWITCH), |
63 | IWL_CMD_ENTRY(CHANNEL_SWITCH_NOTIFICATION), | 63 | IWL_CMD_ENTRY(CHANNEL_SWITCH_NOTIFICATION), |
64 | IWL_CMD_ENTRY(REPLY_SPECTRUM_MEASUREMENT_CMD), | 64 | IWL_CMD_ENTRY(REPLY_SPECTRUM_MEASUREMENT_CMD), |
65 | IWL_CMD_ENTRY(SPECTRUM_MEASURE_NOTIFICATION), | 65 | IWL_CMD_ENTRY(SPECTRUM_MEASURE_NOTIFICATION), |
66 | IWL_CMD_ENTRY(POWER_TABLE_CMD), | 66 | IWL_CMD_ENTRY(POWER_TABLE_CMD), |
67 | IWL_CMD_ENTRY(PM_SLEEP_NOTIFICATION), | 67 | IWL_CMD_ENTRY(PM_SLEEP_NOTIFICATION), |
68 | IWL_CMD_ENTRY(PM_DEBUG_STATISTIC_NOTIFIC), | 68 | IWL_CMD_ENTRY(PM_DEBUG_STATISTIC_NOTIFIC), |
69 | IWL_CMD_ENTRY(REPLY_SCAN_CMD), | 69 | IWL_CMD_ENTRY(REPLY_SCAN_CMD), |
70 | IWL_CMD_ENTRY(REPLY_SCAN_ABORT_CMD), | 70 | IWL_CMD_ENTRY(REPLY_SCAN_ABORT_CMD), |
71 | IWL_CMD_ENTRY(SCAN_START_NOTIFICATION), | 71 | IWL_CMD_ENTRY(SCAN_START_NOTIFICATION), |
72 | IWL_CMD_ENTRY(SCAN_RESULTS_NOTIFICATION), | 72 | IWL_CMD_ENTRY(SCAN_RESULTS_NOTIFICATION), |
73 | IWL_CMD_ENTRY(SCAN_COMPLETE_NOTIFICATION), | 73 | IWL_CMD_ENTRY(SCAN_COMPLETE_NOTIFICATION), |
74 | IWL_CMD_ENTRY(BEACON_NOTIFICATION), | 74 | IWL_CMD_ENTRY(BEACON_NOTIFICATION), |
75 | IWL_CMD_ENTRY(REPLY_TX_BEACON), | 75 | IWL_CMD_ENTRY(REPLY_TX_BEACON), |
76 | IWL_CMD_ENTRY(WHO_IS_AWAKE_NOTIFICATION), | 76 | IWL_CMD_ENTRY(WHO_IS_AWAKE_NOTIFICATION), |
77 | IWL_CMD_ENTRY(QUIET_NOTIFICATION), | 77 | IWL_CMD_ENTRY(QUIET_NOTIFICATION), |
78 | IWL_CMD_ENTRY(REPLY_TX_PWR_TABLE_CMD), | 78 | IWL_CMD_ENTRY(REPLY_TX_PWR_TABLE_CMD), |
79 | IWL_CMD_ENTRY(MEASURE_ABORT_NOTIFICATION), | 79 | IWL_CMD_ENTRY(MEASURE_ABORT_NOTIFICATION), |
80 | IWL_CMD_ENTRY(REPLY_BT_CONFIG), | 80 | IWL_CMD_ENTRY(REPLY_BT_CONFIG), |
81 | IWL_CMD_ENTRY(REPLY_STATISTICS_CMD), | 81 | IWL_CMD_ENTRY(REPLY_STATISTICS_CMD), |
82 | IWL_CMD_ENTRY(STATISTICS_NOTIFICATION), | 82 | IWL_CMD_ENTRY(STATISTICS_NOTIFICATION), |
83 | IWL_CMD_ENTRY(REPLY_CARD_STATE_CMD), | 83 | IWL_CMD_ENTRY(REPLY_CARD_STATE_CMD), |
84 | IWL_CMD_ENTRY(CARD_STATE_NOTIFICATION), | 84 | IWL_CMD_ENTRY(CARD_STATE_NOTIFICATION), |
85 | IWL_CMD_ENTRY(MISSED_BEACONS_NOTIFICATION), | 85 | IWL_CMD_ENTRY(MISSED_BEACONS_NOTIFICATION), |
86 | IWL_CMD_ENTRY(REPLY_CT_KILL_CONFIG_CMD), | 86 | IWL_CMD_ENTRY(REPLY_CT_KILL_CONFIG_CMD), |
87 | IWL_CMD_ENTRY(SENSITIVITY_CMD), | 87 | IWL_CMD_ENTRY(SENSITIVITY_CMD), |
88 | IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD), | 88 | IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD), |
89 | IWL_CMD_ENTRY(REPLY_RX_PHY_CMD), | 89 | IWL_CMD_ENTRY(REPLY_RX_PHY_CMD), |
90 | IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD), | 90 | IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD), |
91 | IWL_CMD_ENTRY(REPLY_COMPRESSED_BA), | 91 | IWL_CMD_ENTRY(REPLY_COMPRESSED_BA), |
92 | IWL_CMD_ENTRY(CALIBRATION_CFG_CMD), | 92 | IWL_CMD_ENTRY(CALIBRATION_CFG_CMD), |
93 | IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION), | 93 | IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION), |
94 | IWL_CMD_ENTRY(CALIBRATION_COMPLETE_NOTIFICATION), | 94 | IWL_CMD_ENTRY(CALIBRATION_COMPLETE_NOTIFICATION), |
95 | IWL_CMD_ENTRY(REPLY_TX_POWER_DBM_CMD), | 95 | IWL_CMD_ENTRY(REPLY_TX_POWER_DBM_CMD), |
96 | IWL_CMD_ENTRY(TEMPERATURE_NOTIFICATION), | 96 | IWL_CMD_ENTRY(TEMPERATURE_NOTIFICATION), |
97 | IWL_CMD_ENTRY(TX_ANT_CONFIGURATION_CMD), | 97 | IWL_CMD_ENTRY(TX_ANT_CONFIGURATION_CMD), |
98 | IWL_CMD_ENTRY(REPLY_BT_COEX_PROFILE_NOTIF), | 98 | IWL_CMD_ENTRY(REPLY_BT_COEX_PROFILE_NOTIF), |
99 | IWL_CMD_ENTRY(REPLY_BT_COEX_PRIO_TABLE), | 99 | IWL_CMD_ENTRY(REPLY_BT_COEX_PRIO_TABLE), |
100 | IWL_CMD_ENTRY(REPLY_BT_COEX_PROT_ENV), | 100 | IWL_CMD_ENTRY(REPLY_BT_COEX_PROT_ENV), |
101 | IWL_CMD_ENTRY(REPLY_WIPAN_PARAMS), | 101 | IWL_CMD_ENTRY(REPLY_WIPAN_PARAMS), |
102 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON), | 102 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON), |
103 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON_TIMING), | 103 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON_TIMING), |
104 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON_ASSOC), | 104 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON_ASSOC), |
105 | IWL_CMD_ENTRY(REPLY_WIPAN_QOS_PARAM), | 105 | IWL_CMD_ENTRY(REPLY_WIPAN_QOS_PARAM), |
106 | IWL_CMD_ENTRY(REPLY_WIPAN_WEPKEY), | 106 | IWL_CMD_ENTRY(REPLY_WIPAN_WEPKEY), |
107 | IWL_CMD_ENTRY(REPLY_WIPAN_P2P_CHANNEL_SWITCH), | 107 | IWL_CMD_ENTRY(REPLY_WIPAN_P2P_CHANNEL_SWITCH), |
108 | IWL_CMD_ENTRY(REPLY_WIPAN_NOA_NOTIFICATION), | 108 | IWL_CMD_ENTRY(REPLY_WIPAN_NOA_NOTIFICATION), |
109 | IWL_CMD_ENTRY(REPLY_WIPAN_DEACTIVATION_COMPLETE), | 109 | IWL_CMD_ENTRY(REPLY_WIPAN_DEACTIVATION_COMPLETE), |
110 | IWL_CMD_ENTRY(REPLY_WOWLAN_PATTERNS), | 110 | IWL_CMD_ENTRY(REPLY_WOWLAN_PATTERNS), |
111 | IWL_CMD_ENTRY(REPLY_WOWLAN_WAKEUP_FILTER), | 111 | IWL_CMD_ENTRY(REPLY_WOWLAN_WAKEUP_FILTER), |
112 | IWL_CMD_ENTRY(REPLY_WOWLAN_TSC_RSC_PARAMS), | 112 | IWL_CMD_ENTRY(REPLY_WOWLAN_TSC_RSC_PARAMS), |
113 | IWL_CMD_ENTRY(REPLY_WOWLAN_TKIP_PARAMS), | 113 | IWL_CMD_ENTRY(REPLY_WOWLAN_TKIP_PARAMS), |
114 | IWL_CMD_ENTRY(REPLY_WOWLAN_KEK_KCK_MATERIAL), | 114 | IWL_CMD_ENTRY(REPLY_WOWLAN_KEK_KCK_MATERIAL), |
115 | IWL_CMD_ENTRY(REPLY_WOWLAN_GET_STATUS), | 115 | IWL_CMD_ENTRY(REPLY_WOWLAN_GET_STATUS), |
116 | IWL_CMD_ENTRY(REPLY_D3_CONFIG), | 116 | IWL_CMD_ENTRY(REPLY_D3_CONFIG), |
117 | }; | 117 | }; |
118 | #undef IWL_CMD_ENTRY | 118 | #undef IWL_CMD_ENTRY |
119 | 119 | ||
120 | /****************************************************************************** | 120 | /****************************************************************************** |
121 | * | 121 | * |
122 | * Generic RX handler implementations | 122 | * Generic RX handler implementations |
123 | * | 123 | * |
124 | ******************************************************************************/ | 124 | ******************************************************************************/ |
125 | 125 | ||
126 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, | 126 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, |
127 | struct iwl_rx_cmd_buffer *rxb, | 127 | struct iwl_rx_cmd_buffer *rxb, |
128 | struct iwl_device_cmd *cmd) | 128 | struct iwl_device_cmd *cmd) |
129 | { | 129 | { |
130 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 130 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
131 | struct iwl_error_resp *err_resp = (void *)pkt->data; | 131 | struct iwl_error_resp *err_resp = (void *)pkt->data; |
132 | 132 | ||
133 | IWL_ERR(priv, "Error Reply type 0x%08X cmd REPLY_ERROR (0x%02X) " | 133 | IWL_ERR(priv, "Error Reply type 0x%08X cmd REPLY_ERROR (0x%02X) " |
134 | "seq 0x%04X ser 0x%08X\n", | 134 | "seq 0x%04X ser 0x%08X\n", |
135 | le32_to_cpu(err_resp->error_type), | 135 | le32_to_cpu(err_resp->error_type), |
136 | err_resp->cmd_id, | 136 | err_resp->cmd_id, |
137 | le16_to_cpu(err_resp->bad_cmd_seq_num), | 137 | le16_to_cpu(err_resp->bad_cmd_seq_num), |
138 | le32_to_cpu(err_resp->error_info)); | 138 | le32_to_cpu(err_resp->error_info)); |
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
141 | 141 | ||
142 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | 142 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
143 | struct iwl_device_cmd *cmd) | 143 | struct iwl_device_cmd *cmd) |
144 | { | 144 | { |
145 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 145 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
146 | struct iwl_csa_notification *csa = (void *)pkt->data; | 146 | struct iwl_csa_notification *csa = (void *)pkt->data; |
147 | /* | 147 | /* |
148 | * MULTI-FIXME | 148 | * MULTI-FIXME |
149 | * See iwlagn_mac_channel_switch. | 149 | * See iwlagn_mac_channel_switch. |
150 | */ | 150 | */ |
151 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 151 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
152 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | 152 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; |
153 | 153 | ||
154 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) | 154 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
155 | return 0; | 155 | return 0; |
156 | 156 | ||
157 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { | 157 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { |
158 | rxon->channel = csa->channel; | 158 | rxon->channel = csa->channel; |
159 | ctx->staging.channel = csa->channel; | 159 | ctx->staging.channel = csa->channel; |
160 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", | 160 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", |
161 | le16_to_cpu(csa->channel)); | 161 | le16_to_cpu(csa->channel)); |
162 | iwl_chswitch_done(priv, true); | 162 | iwl_chswitch_done(priv, true); |
163 | } else { | 163 | } else { |
164 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | 164 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", |
165 | le16_to_cpu(csa->channel)); | 165 | le16_to_cpu(csa->channel)); |
166 | iwl_chswitch_done(priv, false); | 166 | iwl_chswitch_done(priv, false); |
167 | } | 167 | } |
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | 171 | ||
172 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | 172 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, |
173 | struct iwl_rx_cmd_buffer *rxb, | 173 | struct iwl_rx_cmd_buffer *rxb, |
174 | struct iwl_device_cmd *cmd) | 174 | struct iwl_device_cmd *cmd) |
175 | { | 175 | { |
176 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 176 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
177 | struct iwl_spectrum_notification *report = (void *)pkt->data; | 177 | struct iwl_spectrum_notification *report = (void *)pkt->data; |
178 | 178 | ||
179 | if (!report->state) { | 179 | if (!report->state) { |
180 | IWL_DEBUG_11H(priv, | 180 | IWL_DEBUG_11H(priv, |
181 | "Spectrum Measure Notification: Start\n"); | 181 | "Spectrum Measure Notification: Start\n"); |
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
184 | 184 | ||
185 | memcpy(&priv->measure_report, report, sizeof(*report)); | 185 | memcpy(&priv->measure_report, report, sizeof(*report)); |
186 | priv->measurement_status |= MEASUREMENT_READY; | 186 | priv->measurement_status |= MEASUREMENT_READY; |
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
189 | 189 | ||
190 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | 190 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, |
191 | struct iwl_rx_cmd_buffer *rxb, | 191 | struct iwl_rx_cmd_buffer *rxb, |
192 | struct iwl_device_cmd *cmd) | 192 | struct iwl_device_cmd *cmd) |
193 | { | 193 | { |
194 | #ifdef CONFIG_IWLWIFI_DEBUG | 194 | #ifdef CONFIG_IWLWIFI_DEBUG |
195 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 195 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
196 | struct iwl_sleep_notification *sleep = (void *)pkt->data; | 196 | struct iwl_sleep_notification *sleep = (void *)pkt->data; |
197 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | 197 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", |
198 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 198 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
199 | #endif | 199 | #endif |
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 203 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
204 | struct iwl_rx_cmd_buffer *rxb, | 204 | struct iwl_rx_cmd_buffer *rxb, |
205 | struct iwl_device_cmd *cmd) | 205 | struct iwl_device_cmd *cmd) |
206 | { | 206 | { |
207 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 207 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
208 | u32 __maybe_unused len = | 208 | u32 __maybe_unused len = |
209 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 209 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
210 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 210 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
211 | "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len); | 211 | "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len); |
212 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); | 212 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); |
213 | return 0; | 213 | return 0; |
214 | } | 214 | } |
215 | 215 | ||
216 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, | 216 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, |
217 | struct iwl_rx_cmd_buffer *rxb, | 217 | struct iwl_rx_cmd_buffer *rxb, |
218 | struct iwl_device_cmd *cmd) | 218 | struct iwl_device_cmd *cmd) |
219 | { | 219 | { |
220 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 220 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
221 | struct iwlagn_beacon_notif *beacon = (void *)pkt->data; | 221 | struct iwlagn_beacon_notif *beacon = (void *)pkt->data; |
222 | #ifdef CONFIG_IWLWIFI_DEBUG | 222 | #ifdef CONFIG_IWLWIFI_DEBUG |
223 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | 223 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); |
224 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 224 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
225 | 225 | ||
226 | IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " | 226 | IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " |
227 | "tsf:0x%.8x%.8x rate:%d\n", | 227 | "tsf:0x%.8x%.8x rate:%d\n", |
228 | status & TX_STATUS_MSK, | 228 | status & TX_STATUS_MSK, |
229 | beacon->beacon_notify_hdr.failure_frame, | 229 | beacon->beacon_notify_hdr.failure_frame, |
230 | le32_to_cpu(beacon->ibss_mgr_status), | 230 | le32_to_cpu(beacon->ibss_mgr_status), |
231 | le32_to_cpu(beacon->high_tsf), | 231 | le32_to_cpu(beacon->high_tsf), |
232 | le32_to_cpu(beacon->low_tsf), rate); | 232 | le32_to_cpu(beacon->low_tsf), rate); |
233 | #endif | 233 | #endif |
234 | 234 | ||
235 | priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); | 235 | priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); |
236 | 236 | ||
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | /** | 240 | /** |
241 | * iwl_good_plcp_health - checks for plcp error. | 241 | * iwl_good_plcp_health - checks for plcp error. |
242 | * | 242 | * |
243 | * When the plcp error is exceeding the thresholds, reset the radio | 243 | * When the plcp error is exceeding the thresholds, reset the radio |
244 | * to improve the throughput. | 244 | * to improve the throughput. |
245 | */ | 245 | */ |
246 | static bool iwlagn_good_plcp_health(struct iwl_priv *priv, | 246 | static bool iwlagn_good_plcp_health(struct iwl_priv *priv, |
247 | struct statistics_rx_phy *cur_ofdm, | 247 | struct statistics_rx_phy *cur_ofdm, |
248 | struct statistics_rx_ht_phy *cur_ofdm_ht, | 248 | struct statistics_rx_ht_phy *cur_ofdm_ht, |
249 | unsigned int msecs) | 249 | unsigned int msecs) |
250 | { | 250 | { |
251 | int delta; | 251 | int delta; |
252 | int threshold = priv->plcp_delta_threshold; | 252 | int threshold = priv->plcp_delta_threshold; |
253 | 253 | ||
254 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | 254 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { |
255 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 255 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); |
256 | return true; | 256 | return true; |
257 | } | 257 | } |
258 | 258 | ||
259 | delta = le32_to_cpu(cur_ofdm->plcp_err) - | 259 | delta = le32_to_cpu(cur_ofdm->plcp_err) - |
260 | le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) + | 260 | le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) + |
261 | le32_to_cpu(cur_ofdm_ht->plcp_err) - | 261 | le32_to_cpu(cur_ofdm_ht->plcp_err) - |
262 | le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err); | 262 | le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err); |
263 | 263 | ||
264 | /* Can be negative if firmware reset statistics */ | 264 | /* Can be negative if firmware reset statistics */ |
265 | if (delta <= 0) | 265 | if (delta <= 0) |
266 | return true; | 266 | return true; |
267 | 267 | ||
268 | if ((delta * 100 / msecs) > threshold) { | 268 | if ((delta * 100 / msecs) > threshold) { |
269 | IWL_DEBUG_RADIO(priv, | 269 | IWL_DEBUG_RADIO(priv, |
270 | "plcp health threshold %u delta %d msecs %u\n", | 270 | "plcp health threshold %u delta %d msecs %u\n", |
271 | threshold, delta, msecs); | 271 | threshold, delta, msecs); |
272 | return false; | 272 | return false; |
273 | } | 273 | } |
274 | 274 | ||
275 | return true; | 275 | return true; |
276 | } | 276 | } |
277 | 277 | ||
278 | int iwl_force_rf_reset(struct iwl_priv *priv, bool external) | 278 | int iwl_force_rf_reset(struct iwl_priv *priv, bool external) |
279 | { | 279 | { |
280 | struct iwl_rf_reset *rf_reset; | 280 | struct iwl_rf_reset *rf_reset; |
281 | 281 | ||
282 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 282 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
283 | return -EAGAIN; | 283 | return -EAGAIN; |
284 | 284 | ||
285 | if (!iwl_is_any_associated(priv)) { | 285 | if (!iwl_is_any_associated(priv)) { |
286 | IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); | 286 | IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); |
287 | return -ENOLINK; | 287 | return -ENOLINK; |
288 | } | 288 | } |
289 | 289 | ||
290 | rf_reset = &priv->rf_reset; | 290 | rf_reset = &priv->rf_reset; |
291 | rf_reset->reset_request_count++; | 291 | rf_reset->reset_request_count++; |
292 | if (!external && rf_reset->last_reset_jiffies && | 292 | if (!external && rf_reset->last_reset_jiffies && |
293 | time_after(rf_reset->last_reset_jiffies + | 293 | time_after(rf_reset->last_reset_jiffies + |
294 | IWL_DELAY_NEXT_FORCE_RF_RESET, jiffies)) { | 294 | IWL_DELAY_NEXT_FORCE_RF_RESET, jiffies)) { |
295 | IWL_DEBUG_INFO(priv, "RF reset rejected\n"); | 295 | IWL_DEBUG_INFO(priv, "RF reset rejected\n"); |
296 | rf_reset->reset_reject_count++; | 296 | rf_reset->reset_reject_count++; |
297 | return -EAGAIN; | 297 | return -EAGAIN; |
298 | } | 298 | } |
299 | rf_reset->reset_success_count++; | 299 | rf_reset->reset_success_count++; |
300 | rf_reset->last_reset_jiffies = jiffies; | 300 | rf_reset->last_reset_jiffies = jiffies; |
301 | 301 | ||
302 | /* | 302 | /* |
303 | * There is no easy and better way to force reset the radio, | 303 | * There is no easy and better way to force reset the radio, |
304 | * the only known method is switching channel which will force to | 304 | * the only known method is switching channel which will force to |
305 | * reset and tune the radio. | 305 | * reset and tune the radio. |
306 | * Use internal short scan (single channel) operation to should | 306 | * Use internal short scan (single channel) operation to should |
307 | * achieve this objective. | 307 | * achieve this objective. |
308 | * Driver should reset the radio when number of consecutive missed | 308 | * Driver should reset the radio when number of consecutive missed |
309 | * beacon, or any other uCode error condition detected. | 309 | * beacon, or any other uCode error condition detected. |
310 | */ | 310 | */ |
311 | IWL_DEBUG_INFO(priv, "perform radio reset.\n"); | 311 | IWL_DEBUG_INFO(priv, "perform radio reset.\n"); |
312 | iwl_internal_short_hw_scan(priv); | 312 | iwl_internal_short_hw_scan(priv); |
313 | return 0; | 313 | return 0; |
314 | } | 314 | } |
315 | 315 | ||
316 | 316 | ||
317 | static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | 317 | static void iwlagn_recover_from_statistics(struct iwl_priv *priv, |
318 | struct statistics_rx_phy *cur_ofdm, | 318 | struct statistics_rx_phy *cur_ofdm, |
319 | struct statistics_rx_ht_phy *cur_ofdm_ht, | 319 | struct statistics_rx_ht_phy *cur_ofdm_ht, |
320 | struct statistics_tx *tx, | 320 | struct statistics_tx *tx, |
321 | unsigned long stamp) | 321 | unsigned long stamp) |
322 | { | 322 | { |
323 | unsigned int msecs; | 323 | unsigned int msecs; |
324 | 324 | ||
325 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 325 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
326 | return; | 326 | return; |
327 | 327 | ||
328 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); | 328 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); |
329 | 329 | ||
330 | /* Only gather statistics and update time stamp when not associated */ | 330 | /* Only gather statistics and update time stamp when not associated */ |
331 | if (!iwl_is_any_associated(priv)) | 331 | if (!iwl_is_any_associated(priv)) |
332 | return; | 332 | return; |
333 | 333 | ||
334 | /* Do not check/recover when do not have enough statistics data */ | 334 | /* Do not check/recover when do not have enough statistics data */ |
335 | if (msecs < 99) | 335 | if (msecs < 99) |
336 | return; | 336 | return; |
337 | 337 | ||
338 | if (iwlwifi_mod_params.plcp_check && | 338 | if (iwlwifi_mod_params.plcp_check && |
339 | !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) | 339 | !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) |
340 | iwl_force_rf_reset(priv, false); | 340 | iwl_force_rf_reset(priv, false); |
341 | } | 341 | } |
342 | 342 | ||
343 | /* Calculate noise level, based on measurements during network silence just | 343 | /* Calculate noise level, based on measurements during network silence just |
344 | * before arriving beacon. This measurement can be done only if we know | 344 | * before arriving beacon. This measurement can be done only if we know |
345 | * exactly when to expect beacons, therefore only when we're associated. */ | 345 | * exactly when to expect beacons, therefore only when we're associated. */ |
346 | static void iwlagn_rx_calc_noise(struct iwl_priv *priv) | 346 | static void iwlagn_rx_calc_noise(struct iwl_priv *priv) |
347 | { | 347 | { |
348 | struct statistics_rx_non_phy *rx_info; | 348 | struct statistics_rx_non_phy *rx_info; |
349 | int num_active_rx = 0; | 349 | int num_active_rx = 0; |
350 | int total_silence = 0; | 350 | int total_silence = 0; |
351 | int bcn_silence_a, bcn_silence_b, bcn_silence_c; | 351 | int bcn_silence_a, bcn_silence_b, bcn_silence_c; |
352 | int last_rx_noise; | 352 | int last_rx_noise; |
353 | 353 | ||
354 | rx_info = &priv->statistics.rx_non_phy; | 354 | rx_info = &priv->statistics.rx_non_phy; |
355 | 355 | ||
356 | bcn_silence_a = | 356 | bcn_silence_a = |
357 | le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | 357 | le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; |
358 | bcn_silence_b = | 358 | bcn_silence_b = |
359 | le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; | 359 | le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; |
360 | bcn_silence_c = | 360 | bcn_silence_c = |
361 | le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; | 361 | le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; |
362 | 362 | ||
363 | if (bcn_silence_a) { | 363 | if (bcn_silence_a) { |
364 | total_silence += bcn_silence_a; | 364 | total_silence += bcn_silence_a; |
365 | num_active_rx++; | 365 | num_active_rx++; |
366 | } | 366 | } |
367 | if (bcn_silence_b) { | 367 | if (bcn_silence_b) { |
368 | total_silence += bcn_silence_b; | 368 | total_silence += bcn_silence_b; |
369 | num_active_rx++; | 369 | num_active_rx++; |
370 | } | 370 | } |
371 | if (bcn_silence_c) { | 371 | if (bcn_silence_c) { |
372 | total_silence += bcn_silence_c; | 372 | total_silence += bcn_silence_c; |
373 | num_active_rx++; | 373 | num_active_rx++; |
374 | } | 374 | } |
375 | 375 | ||
376 | /* Average among active antennas */ | 376 | /* Average among active antennas */ |
377 | if (num_active_rx) | 377 | if (num_active_rx) |
378 | last_rx_noise = (total_silence / num_active_rx) - 107; | 378 | last_rx_noise = (total_silence / num_active_rx) - 107; |
379 | else | 379 | else |
380 | last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 380 | last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; |
381 | 381 | ||
382 | IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", | 382 | IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", |
383 | bcn_silence_a, bcn_silence_b, bcn_silence_c, | 383 | bcn_silence_a, bcn_silence_b, bcn_silence_c, |
384 | last_rx_noise); | 384 | last_rx_noise); |
385 | } | 385 | } |
386 | 386 | ||
387 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 387 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
388 | /* | 388 | /* |
389 | * based on the assumption of all statistics counter are in DWORD | 389 | * based on the assumption of all statistics counter are in DWORD |
390 | * FIXME: This function is for debugging, do not deal with | 390 | * FIXME: This function is for debugging, do not deal with |
391 | * the case of counters roll-over. | 391 | * the case of counters roll-over. |
392 | */ | 392 | */ |
393 | static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta, | 393 | static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta, |
394 | __le32 *max_delta, __le32 *accum, int size) | 394 | __le32 *max_delta, __le32 *accum, int size) |
395 | { | 395 | { |
396 | int i; | 396 | int i; |
397 | 397 | ||
398 | for (i = 0; | 398 | for (i = 0; |
399 | i < size / sizeof(__le32); | 399 | i < size / sizeof(__le32); |
400 | i++, prev++, cur++, delta++, max_delta++, accum++) { | 400 | i++, prev++, cur++, delta++, max_delta++, accum++) { |
401 | if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) { | 401 | if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) { |
402 | *delta = cpu_to_le32( | 402 | *delta = cpu_to_le32( |
403 | le32_to_cpu(*cur) - le32_to_cpu(*prev)); | 403 | le32_to_cpu(*cur) - le32_to_cpu(*prev)); |
404 | le32_add_cpu(accum, le32_to_cpu(*delta)); | 404 | le32_add_cpu(accum, le32_to_cpu(*delta)); |
405 | if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta)) | 405 | if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta)) |
406 | *max_delta = *delta; | 406 | *max_delta = *delta; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | } | 409 | } |
410 | 410 | ||
411 | static void | 411 | static void |
412 | iwlagn_accumulative_statistics(struct iwl_priv *priv, | 412 | iwlagn_accumulative_statistics(struct iwl_priv *priv, |
413 | struct statistics_general_common *common, | 413 | struct statistics_general_common *common, |
414 | struct statistics_rx_non_phy *rx_non_phy, | 414 | struct statistics_rx_non_phy *rx_non_phy, |
415 | struct statistics_rx_phy *rx_ofdm, | 415 | struct statistics_rx_phy *rx_ofdm, |
416 | struct statistics_rx_ht_phy *rx_ofdm_ht, | 416 | struct statistics_rx_ht_phy *rx_ofdm_ht, |
417 | struct statistics_rx_phy *rx_cck, | 417 | struct statistics_rx_phy *rx_cck, |
418 | struct statistics_tx *tx, | 418 | struct statistics_tx *tx, |
419 | struct statistics_bt_activity *bt_activity) | 419 | struct statistics_bt_activity *bt_activity) |
420 | { | 420 | { |
421 | #define ACCUM(_name) \ | 421 | #define ACCUM(_name) \ |
422 | accum_stats((__le32 *)&priv->statistics._name, \ | 422 | accum_stats((__le32 *)&priv->statistics._name, \ |
423 | (__le32 *)_name, \ | 423 | (__le32 *)_name, \ |
424 | (__le32 *)&priv->delta_stats._name, \ | 424 | (__le32 *)&priv->delta_stats._name, \ |
425 | (__le32 *)&priv->max_delta_stats._name, \ | 425 | (__le32 *)&priv->max_delta_stats._name, \ |
426 | (__le32 *)&priv->accum_stats._name, \ | 426 | (__le32 *)&priv->accum_stats._name, \ |
427 | sizeof(*_name)); | 427 | sizeof(*_name)); |
428 | 428 | ||
429 | ACCUM(common); | 429 | ACCUM(common); |
430 | ACCUM(rx_non_phy); | 430 | ACCUM(rx_non_phy); |
431 | ACCUM(rx_ofdm); | 431 | ACCUM(rx_ofdm); |
432 | ACCUM(rx_ofdm_ht); | 432 | ACCUM(rx_ofdm_ht); |
433 | ACCUM(rx_cck); | 433 | ACCUM(rx_cck); |
434 | ACCUM(tx); | 434 | ACCUM(tx); |
435 | if (bt_activity) | 435 | if (bt_activity) |
436 | ACCUM(bt_activity); | 436 | ACCUM(bt_activity); |
437 | #undef ACCUM | 437 | #undef ACCUM |
438 | } | 438 | } |
439 | #else | 439 | #else |
440 | static inline void | 440 | static inline void |
441 | iwlagn_accumulative_statistics(struct iwl_priv *priv, | 441 | iwlagn_accumulative_statistics(struct iwl_priv *priv, |
442 | struct statistics_general_common *common, | 442 | struct statistics_general_common *common, |
443 | struct statistics_rx_non_phy *rx_non_phy, | 443 | struct statistics_rx_non_phy *rx_non_phy, |
444 | struct statistics_rx_phy *rx_ofdm, | 444 | struct statistics_rx_phy *rx_ofdm, |
445 | struct statistics_rx_ht_phy *rx_ofdm_ht, | 445 | struct statistics_rx_ht_phy *rx_ofdm_ht, |
446 | struct statistics_rx_phy *rx_cck, | 446 | struct statistics_rx_phy *rx_cck, |
447 | struct statistics_tx *tx, | 447 | struct statistics_tx *tx, |
448 | struct statistics_bt_activity *bt_activity) | 448 | struct statistics_bt_activity *bt_activity) |
449 | { | 449 | { |
450 | } | 450 | } |
451 | #endif | 451 | #endif |
452 | 452 | ||
453 | static int iwlagn_rx_statistics(struct iwl_priv *priv, | 453 | static int iwlagn_rx_statistics(struct iwl_priv *priv, |
454 | struct iwl_rx_cmd_buffer *rxb, | 454 | struct iwl_rx_cmd_buffer *rxb, |
455 | struct iwl_device_cmd *cmd) | 455 | struct iwl_device_cmd *cmd) |
456 | { | 456 | { |
457 | unsigned long stamp = jiffies; | 457 | unsigned long stamp = jiffies; |
458 | const int reg_recalib_period = 60; | 458 | const int reg_recalib_period = 60; |
459 | int change; | 459 | int change; |
460 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 460 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
461 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 461 | u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
462 | __le32 *flag; | 462 | __le32 *flag; |
463 | struct statistics_general_common *common; | 463 | struct statistics_general_common *common; |
464 | struct statistics_rx_non_phy *rx_non_phy; | 464 | struct statistics_rx_non_phy *rx_non_phy; |
465 | struct statistics_rx_phy *rx_ofdm; | 465 | struct statistics_rx_phy *rx_ofdm; |
466 | struct statistics_rx_ht_phy *rx_ofdm_ht; | 466 | struct statistics_rx_ht_phy *rx_ofdm_ht; |
467 | struct statistics_rx_phy *rx_cck; | 467 | struct statistics_rx_phy *rx_cck; |
468 | struct statistics_tx *tx; | 468 | struct statistics_tx *tx; |
469 | struct statistics_bt_activity *bt_activity; | 469 | struct statistics_bt_activity *bt_activity; |
470 | 470 | ||
471 | len -= sizeof(struct iwl_cmd_header); /* skip header */ | 471 | len -= sizeof(struct iwl_cmd_header); /* skip header */ |
472 | 472 | ||
473 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", | 473 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", |
474 | len); | 474 | len); |
475 | 475 | ||
476 | spin_lock(&priv->statistics.lock); | 476 | spin_lock(&priv->statistics.lock); |
477 | 477 | ||
478 | if (len == sizeof(struct iwl_bt_notif_statistics)) { | 478 | if (len == sizeof(struct iwl_bt_notif_statistics)) { |
479 | struct iwl_bt_notif_statistics *stats; | 479 | struct iwl_bt_notif_statistics *stats; |
480 | stats = (void *)&pkt->data; | 480 | stats = (void *)&pkt->data; |
481 | flag = &stats->flag; | 481 | flag = &stats->flag; |
482 | common = &stats->general.common; | 482 | common = &stats->general.common; |
483 | rx_non_phy = &stats->rx.general.common; | 483 | rx_non_phy = &stats->rx.general.common; |
484 | rx_ofdm = &stats->rx.ofdm; | 484 | rx_ofdm = &stats->rx.ofdm; |
485 | rx_ofdm_ht = &stats->rx.ofdm_ht; | 485 | rx_ofdm_ht = &stats->rx.ofdm_ht; |
486 | rx_cck = &stats->rx.cck; | 486 | rx_cck = &stats->rx.cck; |
487 | tx = &stats->tx; | 487 | tx = &stats->tx; |
488 | bt_activity = &stats->general.activity; | 488 | bt_activity = &stats->general.activity; |
489 | 489 | ||
490 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 490 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
491 | /* handle this exception directly */ | 491 | /* handle this exception directly */ |
492 | priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills; | 492 | priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills; |
493 | le32_add_cpu(&priv->statistics.accum_num_bt_kills, | 493 | le32_add_cpu(&priv->statistics.accum_num_bt_kills, |
494 | le32_to_cpu(stats->rx.general.num_bt_kills)); | 494 | le32_to_cpu(stats->rx.general.num_bt_kills)); |
495 | #endif | 495 | #endif |
496 | } else if (len == sizeof(struct iwl_notif_statistics)) { | 496 | } else if (len == sizeof(struct iwl_notif_statistics)) { |
497 | struct iwl_notif_statistics *stats; | 497 | struct iwl_notif_statistics *stats; |
498 | stats = (void *)&pkt->data; | 498 | stats = (void *)&pkt->data; |
499 | flag = &stats->flag; | 499 | flag = &stats->flag; |
500 | common = &stats->general.common; | 500 | common = &stats->general.common; |
501 | rx_non_phy = &stats->rx.general; | 501 | rx_non_phy = &stats->rx.general; |
502 | rx_ofdm = &stats->rx.ofdm; | 502 | rx_ofdm = &stats->rx.ofdm; |
503 | rx_ofdm_ht = &stats->rx.ofdm_ht; | 503 | rx_ofdm_ht = &stats->rx.ofdm_ht; |
504 | rx_cck = &stats->rx.cck; | 504 | rx_cck = &stats->rx.cck; |
505 | tx = &stats->tx; | 505 | tx = &stats->tx; |
506 | bt_activity = NULL; | 506 | bt_activity = NULL; |
507 | } else { | 507 | } else { |
508 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", | 508 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", |
509 | len, sizeof(struct iwl_bt_notif_statistics), | 509 | len, sizeof(struct iwl_bt_notif_statistics), |
510 | sizeof(struct iwl_notif_statistics)); | 510 | sizeof(struct iwl_notif_statistics)); |
511 | spin_unlock(&priv->statistics.lock); | 511 | spin_unlock(&priv->statistics.lock); |
512 | return 0; | 512 | return 0; |
513 | } | 513 | } |
514 | 514 | ||
515 | change = common->temperature != priv->statistics.common.temperature || | 515 | change = common->temperature != priv->statistics.common.temperature || |
516 | (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) != | 516 | (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) != |
517 | (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK); | 517 | (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK); |
518 | 518 | ||
519 | iwlagn_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm, | 519 | iwlagn_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm, |
520 | rx_ofdm_ht, rx_cck, tx, bt_activity); | 520 | rx_ofdm_ht, rx_cck, tx, bt_activity); |
521 | 521 | ||
522 | iwlagn_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp); | 522 | iwlagn_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp); |
523 | 523 | ||
524 | priv->statistics.flag = *flag; | 524 | priv->statistics.flag = *flag; |
525 | memcpy(&priv->statistics.common, common, sizeof(*common)); | 525 | memcpy(&priv->statistics.common, common, sizeof(*common)); |
526 | memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy)); | 526 | memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy)); |
527 | memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm)); | 527 | memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm)); |
528 | memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht)); | 528 | memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht)); |
529 | memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck)); | 529 | memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck)); |
530 | memcpy(&priv->statistics.tx, tx, sizeof(*tx)); | 530 | memcpy(&priv->statistics.tx, tx, sizeof(*tx)); |
531 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 531 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
532 | if (bt_activity) | 532 | if (bt_activity) |
533 | memcpy(&priv->statistics.bt_activity, bt_activity, | 533 | memcpy(&priv->statistics.bt_activity, bt_activity, |
534 | sizeof(*bt_activity)); | 534 | sizeof(*bt_activity)); |
535 | #endif | 535 | #endif |
536 | 536 | ||
537 | priv->rx_statistics_jiffies = stamp; | 537 | priv->rx_statistics_jiffies = stamp; |
538 | 538 | ||
539 | set_bit(STATUS_STATISTICS, &priv->status); | 539 | set_bit(STATUS_STATISTICS, &priv->status); |
540 | 540 | ||
541 | /* Reschedule the statistics timer to occur in | 541 | /* Reschedule the statistics timer to occur in |
542 | * reg_recalib_period seconds to ensure we get a | 542 | * reg_recalib_period seconds to ensure we get a |
543 | * thermal update even if the uCode doesn't give | 543 | * thermal update even if the uCode doesn't give |
544 | * us one */ | 544 | * us one */ |
545 | mod_timer(&priv->statistics_periodic, jiffies + | 545 | mod_timer(&priv->statistics_periodic, jiffies + |
546 | msecs_to_jiffies(reg_recalib_period * 1000)); | 546 | msecs_to_jiffies(reg_recalib_period * 1000)); |
547 | 547 | ||
548 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | 548 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
549 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 549 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { |
550 | iwlagn_rx_calc_noise(priv); | 550 | iwlagn_rx_calc_noise(priv); |
551 | queue_work(priv->workqueue, &priv->run_time_calib_work); | 551 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
552 | } | 552 | } |
553 | if (priv->lib->temperature && change) | 553 | if (priv->lib->temperature && change) |
554 | priv->lib->temperature(priv); | 554 | priv->lib->temperature(priv); |
555 | 555 | ||
556 | spin_unlock(&priv->statistics.lock); | 556 | spin_unlock(&priv->statistics.lock); |
557 | 557 | ||
558 | return 0; | 558 | return 0; |
559 | } | 559 | } |
560 | 560 | ||
561 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | 561 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, |
562 | struct iwl_rx_cmd_buffer *rxb, | 562 | struct iwl_rx_cmd_buffer *rxb, |
563 | struct iwl_device_cmd *cmd) | 563 | struct iwl_device_cmd *cmd) |
564 | { | 564 | { |
565 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 565 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
566 | struct iwl_notif_statistics *stats = (void *)pkt->data; | 566 | struct iwl_notif_statistics *stats = (void *)pkt->data; |
567 | 567 | ||
568 | if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { | 568 | if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { |
569 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 569 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
570 | memset(&priv->accum_stats, 0, | 570 | memset(&priv->accum_stats, 0, |
571 | sizeof(priv->accum_stats)); | 571 | sizeof(priv->accum_stats)); |
572 | memset(&priv->delta_stats, 0, | 572 | memset(&priv->delta_stats, 0, |
573 | sizeof(priv->delta_stats)); | 573 | sizeof(priv->delta_stats)); |
574 | memset(&priv->max_delta_stats, 0, | 574 | memset(&priv->max_delta_stats, 0, |
575 | sizeof(priv->max_delta_stats)); | 575 | sizeof(priv->max_delta_stats)); |
576 | #endif | 576 | #endif |
577 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | 577 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); |
578 | } | 578 | } |
579 | iwlagn_rx_statistics(priv, rxb, cmd); | 579 | iwlagn_rx_statistics(priv, rxb, cmd); |
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | 582 | ||
583 | /* Handle notification from uCode that card's power state is changing | 583 | /* Handle notification from uCode that card's power state is changing |
584 | * due to software, hardware, or critical temperature RFKILL */ | 584 | * due to software, hardware, or critical temperature RFKILL */ |
585 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | 585 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, |
586 | struct iwl_rx_cmd_buffer *rxb, | 586 | struct iwl_rx_cmd_buffer *rxb, |
587 | struct iwl_device_cmd *cmd) | 587 | struct iwl_device_cmd *cmd) |
588 | { | 588 | { |
589 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 589 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
590 | struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; | 590 | struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; |
591 | u32 flags = le32_to_cpu(card_state_notif->flags); | 591 | u32 flags = le32_to_cpu(card_state_notif->flags); |
592 | unsigned long status = priv->status; | 592 | unsigned long status = priv->status; |
593 | 593 | ||
594 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | 594 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", |
595 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 595 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
596 | (flags & SW_CARD_DISABLED) ? "Kill" : "On", | 596 | (flags & SW_CARD_DISABLED) ? "Kill" : "On", |
597 | (flags & CT_CARD_DISABLED) ? | 597 | (flags & CT_CARD_DISABLED) ? |
598 | "Reached" : "Not reached"); | 598 | "Reached" : "Not reached"); |
599 | 599 | ||
600 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | | 600 | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | |
601 | CT_CARD_DISABLED)) { | 601 | CT_CARD_DISABLED)) { |
602 | 602 | ||
603 | iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET, | 603 | iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET, |
604 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 604 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
605 | 605 | ||
606 | iwl_write_direct32(priv->trans, HBUS_TARG_MBX_C, | 606 | iwl_write_direct32(priv->trans, HBUS_TARG_MBX_C, |
607 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | 607 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
608 | 608 | ||
609 | if (!(flags & RXON_CARD_DISABLED)) { | 609 | if (!(flags & RXON_CARD_DISABLED)) { |
610 | iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR, | 610 | iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR, |
611 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 611 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
612 | iwl_write_direct32(priv->trans, HBUS_TARG_MBX_C, | 612 | iwl_write_direct32(priv->trans, HBUS_TARG_MBX_C, |
613 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); | 613 | HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); |
614 | } | 614 | } |
615 | if (flags & CT_CARD_DISABLED) | 615 | if (flags & CT_CARD_DISABLED) |
616 | iwl_tt_enter_ct_kill(priv); | 616 | iwl_tt_enter_ct_kill(priv); |
617 | } | 617 | } |
618 | if (!(flags & CT_CARD_DISABLED)) | 618 | if (!(flags & CT_CARD_DISABLED)) |
619 | iwl_tt_exit_ct_kill(priv); | 619 | iwl_tt_exit_ct_kill(priv); |
620 | 620 | ||
621 | if (flags & HW_CARD_DISABLED) | 621 | if (flags & HW_CARD_DISABLED) |
622 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 622 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
623 | else | 623 | else |
624 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 624 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
625 | 625 | ||
626 | 626 | ||
627 | if (!(flags & RXON_CARD_DISABLED)) | 627 | if (!(flags & RXON_CARD_DISABLED)) |
628 | iwl_scan_cancel(priv); | 628 | iwl_scan_cancel(priv); |
629 | 629 | ||
630 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 630 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
631 | test_bit(STATUS_RF_KILL_HW, &priv->status))) | 631 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
632 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 632 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
633 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | 633 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
634 | else | 634 | else |
635 | wake_up(&priv->trans->wait_command_queue); | 635 | wake_up(&priv->trans->wait_command_queue); |
636 | return 0; | 636 | return 0; |
637 | } | 637 | } |
638 | 638 | ||
639 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | 639 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, |
640 | struct iwl_rx_cmd_buffer *rxb, | 640 | struct iwl_rx_cmd_buffer *rxb, |
641 | struct iwl_device_cmd *cmd) | 641 | struct iwl_device_cmd *cmd) |
642 | 642 | ||
643 | { | 643 | { |
644 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 644 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
645 | struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; | 645 | struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; |
646 | 646 | ||
647 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > | 647 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > |
648 | priv->missed_beacon_threshold) { | 648 | priv->missed_beacon_threshold) { |
649 | IWL_DEBUG_CALIB(priv, | 649 | IWL_DEBUG_CALIB(priv, |
650 | "missed bcn cnsq %d totl %d rcd %d expctd %d\n", | 650 | "missed bcn cnsq %d totl %d rcd %d expctd %d\n", |
651 | le32_to_cpu(missed_beacon->consecutive_missed_beacons), | 651 | le32_to_cpu(missed_beacon->consecutive_missed_beacons), |
652 | le32_to_cpu(missed_beacon->total_missed_becons), | 652 | le32_to_cpu(missed_beacon->total_missed_becons), |
653 | le32_to_cpu(missed_beacon->num_recvd_beacons), | 653 | le32_to_cpu(missed_beacon->num_recvd_beacons), |
654 | le32_to_cpu(missed_beacon->num_expected_beacons)); | 654 | le32_to_cpu(missed_beacon->num_expected_beacons)); |
655 | if (!test_bit(STATUS_SCANNING, &priv->status)) | 655 | if (!test_bit(STATUS_SCANNING, &priv->status)) |
656 | iwl_init_sensitivity(priv); | 656 | iwl_init_sensitivity(priv); |
657 | } | 657 | } |
658 | return 0; | 658 | return 0; |
659 | } | 659 | } |
660 | 660 | ||
661 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | 661 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). |
662 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | 662 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ |
663 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | 663 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, |
664 | struct iwl_rx_cmd_buffer *rxb, | 664 | struct iwl_rx_cmd_buffer *rxb, |
665 | struct iwl_device_cmd *cmd) | 665 | struct iwl_device_cmd *cmd) |
666 | { | 666 | { |
667 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 667 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
668 | 668 | ||
669 | priv->last_phy_res_valid = true; | 669 | priv->last_phy_res_valid = true; |
670 | priv->ampdu_ref++; | ||
670 | memcpy(&priv->last_phy_res, pkt->data, | 671 | memcpy(&priv->last_phy_res, pkt->data, |
671 | sizeof(struct iwl_rx_phy_res)); | 672 | sizeof(struct iwl_rx_phy_res)); |
672 | return 0; | 673 | return 0; |
673 | } | 674 | } |
674 | 675 | ||
675 | /* | 676 | /* |
676 | * returns non-zero if packet should be dropped | 677 | * returns non-zero if packet should be dropped |
677 | */ | 678 | */ |
678 | static int iwlagn_set_decrypted_flag(struct iwl_priv *priv, | 679 | static int iwlagn_set_decrypted_flag(struct iwl_priv *priv, |
679 | struct ieee80211_hdr *hdr, | 680 | struct ieee80211_hdr *hdr, |
680 | u32 decrypt_res, | 681 | u32 decrypt_res, |
681 | struct ieee80211_rx_status *stats) | 682 | struct ieee80211_rx_status *stats) |
682 | { | 683 | { |
683 | u16 fc = le16_to_cpu(hdr->frame_control); | 684 | u16 fc = le16_to_cpu(hdr->frame_control); |
684 | 685 | ||
685 | /* | 686 | /* |
686 | * All contexts have the same setting here due to it being | 687 | * All contexts have the same setting here due to it being |
687 | * a module parameter, so OK to check any context. | 688 | * a module parameter, so OK to check any context. |
688 | */ | 689 | */ |
689 | if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags & | 690 | if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags & |
690 | RXON_FILTER_DIS_DECRYPT_MSK) | 691 | RXON_FILTER_DIS_DECRYPT_MSK) |
691 | return 0; | 692 | return 0; |
692 | 693 | ||
693 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | 694 | if (!(fc & IEEE80211_FCTL_PROTECTED)) |
694 | return 0; | 695 | return 0; |
695 | 696 | ||
696 | IWL_DEBUG_RX(priv, "decrypt_res:0x%x\n", decrypt_res); | 697 | IWL_DEBUG_RX(priv, "decrypt_res:0x%x\n", decrypt_res); |
697 | switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { | 698 | switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { |
698 | case RX_RES_STATUS_SEC_TYPE_TKIP: | 699 | case RX_RES_STATUS_SEC_TYPE_TKIP: |
699 | /* The uCode has got a bad phase 1 Key, pushes the packet. | 700 | /* The uCode has got a bad phase 1 Key, pushes the packet. |
700 | * Decryption will be done in SW. */ | 701 | * Decryption will be done in SW. */ |
701 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | 702 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == |
702 | RX_RES_STATUS_BAD_KEY_TTAK) | 703 | RX_RES_STATUS_BAD_KEY_TTAK) |
703 | break; | 704 | break; |
704 | 705 | ||
705 | case RX_RES_STATUS_SEC_TYPE_WEP: | 706 | case RX_RES_STATUS_SEC_TYPE_WEP: |
706 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | 707 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == |
707 | RX_RES_STATUS_BAD_ICV_MIC) { | 708 | RX_RES_STATUS_BAD_ICV_MIC) { |
708 | /* bad ICV, the packet is destroyed since the | 709 | /* bad ICV, the packet is destroyed since the |
709 | * decryption is inplace, drop it */ | 710 | * decryption is inplace, drop it */ |
710 | IWL_DEBUG_RX(priv, "Packet destroyed\n"); | 711 | IWL_DEBUG_RX(priv, "Packet destroyed\n"); |
711 | return -1; | 712 | return -1; |
712 | } | 713 | } |
713 | case RX_RES_STATUS_SEC_TYPE_CCMP: | 714 | case RX_RES_STATUS_SEC_TYPE_CCMP: |
714 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | 715 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == |
715 | RX_RES_STATUS_DECRYPT_OK) { | 716 | RX_RES_STATUS_DECRYPT_OK) { |
716 | IWL_DEBUG_RX(priv, "hw decrypt successfully!!!\n"); | 717 | IWL_DEBUG_RX(priv, "hw decrypt successfully!!!\n"); |
717 | stats->flag |= RX_FLAG_DECRYPTED; | 718 | stats->flag |= RX_FLAG_DECRYPTED; |
718 | } | 719 | } |
719 | break; | 720 | break; |
720 | 721 | ||
721 | default: | 722 | default: |
722 | break; | 723 | break; |
723 | } | 724 | } |
724 | return 0; | 725 | return 0; |
725 | } | 726 | } |
726 | 727 | ||
727 | static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | 728 | static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, |
728 | struct ieee80211_hdr *hdr, | 729 | struct ieee80211_hdr *hdr, |
729 | u16 len, | 730 | u16 len, |
730 | u32 ampdu_status, | 731 | u32 ampdu_status, |
731 | struct iwl_rx_cmd_buffer *rxb, | 732 | struct iwl_rx_cmd_buffer *rxb, |
732 | struct ieee80211_rx_status *stats) | 733 | struct ieee80211_rx_status *stats) |
733 | { | 734 | { |
734 | struct sk_buff *skb; | 735 | struct sk_buff *skb; |
735 | __le16 fc = hdr->frame_control; | 736 | __le16 fc = hdr->frame_control; |
736 | struct iwl_rxon_context *ctx; | 737 | struct iwl_rxon_context *ctx; |
737 | unsigned int hdrlen, fraglen; | 738 | unsigned int hdrlen, fraglen; |
738 | 739 | ||
739 | /* We only process data packets if the interface is open */ | 740 | /* We only process data packets if the interface is open */ |
740 | if (unlikely(!priv->is_open)) { | 741 | if (unlikely(!priv->is_open)) { |
741 | IWL_DEBUG_DROP_LIMIT(priv, | 742 | IWL_DEBUG_DROP_LIMIT(priv, |
742 | "Dropping packet while interface is not open.\n"); | 743 | "Dropping packet while interface is not open.\n"); |
743 | return; | 744 | return; |
744 | } | 745 | } |
745 | 746 | ||
746 | /* In case of HW accelerated crypto and bad decryption, drop */ | 747 | /* In case of HW accelerated crypto and bad decryption, drop */ |
747 | if (!iwlwifi_mod_params.sw_crypto && | 748 | if (!iwlwifi_mod_params.sw_crypto && |
748 | iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | 749 | iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats)) |
749 | return; | 750 | return; |
750 | 751 | ||
751 | /* Dont use dev_alloc_skb(), we'll have enough headroom once | 752 | /* Dont use dev_alloc_skb(), we'll have enough headroom once |
752 | * ieee80211_hdr pulled. | 753 | * ieee80211_hdr pulled. |
753 | */ | 754 | */ |
754 | skb = alloc_skb(128, GFP_ATOMIC); | 755 | skb = alloc_skb(128, GFP_ATOMIC); |
755 | if (!skb) { | 756 | if (!skb) { |
756 | IWL_ERR(priv, "alloc_skb failed\n"); | 757 | IWL_ERR(priv, "alloc_skb failed\n"); |
757 | return; | 758 | return; |
758 | } | 759 | } |
759 | /* If frame is small enough to fit in skb->head, pull it completely. | 760 | /* If frame is small enough to fit in skb->head, pull it completely. |
760 | * If not, only pull ieee80211_hdr so that splice() or TCP coalesce | 761 | * If not, only pull ieee80211_hdr so that splice() or TCP coalesce |
761 | * are more efficient. | 762 | * are more efficient. |
762 | */ | 763 | */ |
763 | hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr); | 764 | hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr); |
764 | 765 | ||
765 | memcpy(skb_put(skb, hdrlen), hdr, hdrlen); | 766 | memcpy(skb_put(skb, hdrlen), hdr, hdrlen); |
766 | fraglen = len - hdrlen; | 767 | fraglen = len - hdrlen; |
767 | 768 | ||
768 | if (fraglen) { | 769 | if (fraglen) { |
769 | int offset = (void *)hdr + hdrlen - | 770 | int offset = (void *)hdr + hdrlen - |
770 | rxb_addr(rxb) + rxb_offset(rxb); | 771 | rxb_addr(rxb) + rxb_offset(rxb); |
771 | 772 | ||
772 | skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, | 773 | skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, |
773 | fraglen, rxb->truesize); | 774 | fraglen, rxb->truesize); |
774 | } | 775 | } |
775 | 776 | ||
776 | /* | 777 | /* |
777 | * Wake any queues that were stopped due to a passive channel tx | 778 | * Wake any queues that were stopped due to a passive channel tx |
778 | * failure. This can happen because the regulatory enforcement in | 779 | * failure. This can happen because the regulatory enforcement in |
779 | * the device waits for a beacon before allowing transmission, | 780 | * the device waits for a beacon before allowing transmission, |
780 | * sometimes even after already having transmitted frames for the | 781 | * sometimes even after already having transmitted frames for the |
781 | * association because the new RXON may reset the information. | 782 | * association because the new RXON may reset the information. |
782 | */ | 783 | */ |
783 | if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { | 784 | if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { |
784 | for_each_context(priv, ctx) { | 785 | for_each_context(priv, ctx) { |
785 | if (!ether_addr_equal(hdr->addr3, | 786 | if (!ether_addr_equal(hdr->addr3, |
786 | ctx->active.bssid_addr)) | 787 | ctx->active.bssid_addr)) |
787 | continue; | 788 | continue; |
788 | iwlagn_lift_passive_no_rx(priv); | 789 | iwlagn_lift_passive_no_rx(priv); |
789 | } | 790 | } |
790 | } | 791 | } |
791 | 792 | ||
792 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 793 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
793 | 794 | ||
794 | ieee80211_rx(priv->hw, skb); | 795 | ieee80211_rx(priv->hw, skb); |
795 | } | 796 | } |
796 | 797 | ||
797 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | 798 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) |
798 | { | 799 | { |
799 | u32 decrypt_out = 0; | 800 | u32 decrypt_out = 0; |
800 | 801 | ||
801 | if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == | 802 | if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == |
802 | RX_RES_STATUS_STATION_FOUND) | 803 | RX_RES_STATUS_STATION_FOUND) |
803 | decrypt_out |= (RX_RES_STATUS_STATION_FOUND | | 804 | decrypt_out |= (RX_RES_STATUS_STATION_FOUND | |
804 | RX_RES_STATUS_NO_STATION_INFO_MISMATCH); | 805 | RX_RES_STATUS_NO_STATION_INFO_MISMATCH); |
805 | 806 | ||
806 | decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); | 807 | decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); |
807 | 808 | ||
808 | /* packet was not encrypted */ | 809 | /* packet was not encrypted */ |
809 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | 810 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == |
810 | RX_RES_STATUS_SEC_TYPE_NONE) | 811 | RX_RES_STATUS_SEC_TYPE_NONE) |
811 | return decrypt_out; | 812 | return decrypt_out; |
812 | 813 | ||
813 | /* packet was encrypted with unknown alg */ | 814 | /* packet was encrypted with unknown alg */ |
814 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | 815 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == |
815 | RX_RES_STATUS_SEC_TYPE_ERR) | 816 | RX_RES_STATUS_SEC_TYPE_ERR) |
816 | return decrypt_out; | 817 | return decrypt_out; |
817 | 818 | ||
818 | /* decryption was not done in HW */ | 819 | /* decryption was not done in HW */ |
819 | if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != | 820 | if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != |
820 | RX_MPDU_RES_STATUS_DEC_DONE_MSK) | 821 | RX_MPDU_RES_STATUS_DEC_DONE_MSK) |
821 | return decrypt_out; | 822 | return decrypt_out; |
822 | 823 | ||
823 | switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { | 824 | switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { |
824 | 825 | ||
825 | case RX_RES_STATUS_SEC_TYPE_CCMP: | 826 | case RX_RES_STATUS_SEC_TYPE_CCMP: |
826 | /* alg is CCM: check MIC only */ | 827 | /* alg is CCM: check MIC only */ |
827 | if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) | 828 | if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) |
828 | /* Bad MIC */ | 829 | /* Bad MIC */ |
829 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | 830 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; |
830 | else | 831 | else |
831 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | 832 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; |
832 | 833 | ||
833 | break; | 834 | break; |
834 | 835 | ||
835 | case RX_RES_STATUS_SEC_TYPE_TKIP: | 836 | case RX_RES_STATUS_SEC_TYPE_TKIP: |
836 | if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { | 837 | if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { |
837 | /* Bad TTAK */ | 838 | /* Bad TTAK */ |
838 | decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; | 839 | decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; |
839 | break; | 840 | break; |
840 | } | 841 | } |
841 | /* fall through if TTAK OK */ | 842 | /* fall through if TTAK OK */ |
842 | default: | 843 | default: |
843 | if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) | 844 | if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) |
844 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | 845 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; |
845 | else | 846 | else |
846 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | 847 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; |
847 | break; | 848 | break; |
848 | } | 849 | } |
849 | 850 | ||
850 | IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", | 851 | IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", |
851 | decrypt_in, decrypt_out); | 852 | decrypt_in, decrypt_out); |
852 | 853 | ||
853 | return decrypt_out; | 854 | return decrypt_out; |
854 | } | 855 | } |
855 | 856 | ||
856 | /* Calc max signal level (dBm) among 3 possible receivers */ | 857 | /* Calc max signal level (dBm) among 3 possible receivers */ |
857 | static int iwlagn_calc_rssi(struct iwl_priv *priv, | 858 | static int iwlagn_calc_rssi(struct iwl_priv *priv, |
858 | struct iwl_rx_phy_res *rx_resp) | 859 | struct iwl_rx_phy_res *rx_resp) |
859 | { | 860 | { |
860 | /* data from PHY/DSP regarding signal strength, etc., | 861 | /* data from PHY/DSP regarding signal strength, etc., |
861 | * contents are always there, not configurable by host | 862 | * contents are always there, not configurable by host |
862 | */ | 863 | */ |
863 | struct iwlagn_non_cfg_phy *ncphy = | 864 | struct iwlagn_non_cfg_phy *ncphy = |
864 | (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf; | 865 | (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf; |
865 | u32 val, rssi_a, rssi_b, rssi_c, max_rssi; | 866 | u32 val, rssi_a, rssi_b, rssi_c, max_rssi; |
866 | u8 agc; | 867 | u8 agc; |
867 | 868 | ||
868 | val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]); | 869 | val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]); |
869 | agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS; | 870 | agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS; |
870 | 871 | ||
871 | /* Find max rssi among 3 possible receivers. | 872 | /* Find max rssi among 3 possible receivers. |
872 | * These values are measured by the digital signal processor (DSP). | 873 | * These values are measured by the digital signal processor (DSP). |
873 | * They should stay fairly constant even as the signal strength varies, | 874 | * They should stay fairly constant even as the signal strength varies, |
874 | * if the radio's automatic gain control (AGC) is working right. | 875 | * if the radio's automatic gain control (AGC) is working right. |
875 | * AGC value (see below) will provide the "interesting" info. | 876 | * AGC value (see below) will provide the "interesting" info. |
876 | */ | 877 | */ |
877 | val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]); | 878 | val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]); |
878 | rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >> | 879 | rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >> |
879 | IWLAGN_OFDM_RSSI_A_BIT_POS; | 880 | IWLAGN_OFDM_RSSI_A_BIT_POS; |
880 | rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >> | 881 | rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >> |
881 | IWLAGN_OFDM_RSSI_B_BIT_POS; | 882 | IWLAGN_OFDM_RSSI_B_BIT_POS; |
882 | val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]); | 883 | val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]); |
883 | rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >> | 884 | rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >> |
884 | IWLAGN_OFDM_RSSI_C_BIT_POS; | 885 | IWLAGN_OFDM_RSSI_C_BIT_POS; |
885 | 886 | ||
886 | max_rssi = max_t(u32, rssi_a, rssi_b); | 887 | max_rssi = max_t(u32, rssi_a, rssi_b); |
887 | max_rssi = max_t(u32, max_rssi, rssi_c); | 888 | max_rssi = max_t(u32, max_rssi, rssi_c); |
888 | 889 | ||
889 | IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", | 890 | IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", |
890 | rssi_a, rssi_b, rssi_c, max_rssi, agc); | 891 | rssi_a, rssi_b, rssi_c, max_rssi, agc); |
891 | 892 | ||
892 | /* dBm = max_rssi dB - agc dB - constant. | 893 | /* dBm = max_rssi dB - agc dB - constant. |
893 | * Higher AGC (higher radio gain) means lower signal. */ | 894 | * Higher AGC (higher radio gain) means lower signal. */ |
894 | return max_rssi - agc - IWLAGN_RSSI_OFFSET; | 895 | return max_rssi - agc - IWLAGN_RSSI_OFFSET; |
895 | } | 896 | } |
896 | 897 | ||
897 | /* Called for REPLY_RX_MPDU_CMD */ | 898 | /* Called for REPLY_RX_MPDU_CMD */ |
898 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | 899 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, |
899 | struct iwl_rx_cmd_buffer *rxb, | 900 | struct iwl_rx_cmd_buffer *rxb, |
900 | struct iwl_device_cmd *cmd) | 901 | struct iwl_device_cmd *cmd) |
901 | { | 902 | { |
902 | struct ieee80211_hdr *header; | 903 | struct ieee80211_hdr *header; |
903 | struct ieee80211_rx_status rx_status; | 904 | struct ieee80211_rx_status rx_status; |
904 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 905 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
905 | struct iwl_rx_phy_res *phy_res; | 906 | struct iwl_rx_phy_res *phy_res; |
906 | __le32 rx_pkt_status; | 907 | __le32 rx_pkt_status; |
907 | struct iwl_rx_mpdu_res_start *amsdu; | 908 | struct iwl_rx_mpdu_res_start *amsdu; |
908 | u32 len; | 909 | u32 len; |
909 | u32 ampdu_status; | 910 | u32 ampdu_status; |
910 | u32 rate_n_flags; | 911 | u32 rate_n_flags; |
911 | 912 | ||
912 | if (!priv->last_phy_res_valid) { | 913 | if (!priv->last_phy_res_valid) { |
913 | IWL_ERR(priv, "MPDU frame without cached PHY data\n"); | 914 | IWL_ERR(priv, "MPDU frame without cached PHY data\n"); |
914 | return 0; | 915 | return 0; |
915 | } | 916 | } |
916 | phy_res = &priv->last_phy_res; | 917 | phy_res = &priv->last_phy_res; |
917 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; | 918 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; |
918 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); | 919 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); |
919 | len = le16_to_cpu(amsdu->byte_count); | 920 | len = le16_to_cpu(amsdu->byte_count); |
920 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); | 921 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); |
921 | ampdu_status = iwlagn_translate_rx_status(priv, | 922 | ampdu_status = iwlagn_translate_rx_status(priv, |
922 | le32_to_cpu(rx_pkt_status)); | 923 | le32_to_cpu(rx_pkt_status)); |
923 | 924 | ||
924 | if ((unlikely(phy_res->cfg_phy_cnt > 20))) { | 925 | if ((unlikely(phy_res->cfg_phy_cnt > 20))) { |
925 | IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d\n", | 926 | IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d\n", |
926 | phy_res->cfg_phy_cnt); | 927 | phy_res->cfg_phy_cnt); |
927 | return 0; | 928 | return 0; |
928 | } | 929 | } |
929 | 930 | ||
930 | if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || | 931 | if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || |
931 | !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { | 932 | !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { |
932 | IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", | 933 | IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", |
933 | le32_to_cpu(rx_pkt_status)); | 934 | le32_to_cpu(rx_pkt_status)); |
934 | return 0; | 935 | return 0; |
935 | } | 936 | } |
936 | 937 | ||
937 | /* This will be used in several places later */ | 938 | /* This will be used in several places later */ |
938 | rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); | 939 | rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); |
939 | 940 | ||
940 | /* rx_status carries information about the packet to mac80211 */ | 941 | /* rx_status carries information about the packet to mac80211 */ |
941 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); | 942 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); |
942 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 943 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
943 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 944 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
944 | rx_status.freq = | 945 | rx_status.freq = |
945 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), | 946 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), |
946 | rx_status.band); | 947 | rx_status.band); |
947 | rx_status.rate_idx = | 948 | rx_status.rate_idx = |
948 | iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); | 949 | iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); |
949 | rx_status.flag = 0; | 950 | rx_status.flag = 0; |
950 | 951 | ||
951 | /* TSF isn't reliable. In order to allow smooth user experience, | 952 | /* TSF isn't reliable. In order to allow smooth user experience, |
952 | * this W/A doesn't propagate it to the mac80211 */ | 953 | * this W/A doesn't propagate it to the mac80211 */ |
953 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ | 954 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ |
954 | 955 | ||
955 | priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); | 956 | priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); |
956 | 957 | ||
957 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 958 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ |
958 | rx_status.signal = iwlagn_calc_rssi(priv, phy_res); | 959 | rx_status.signal = iwlagn_calc_rssi(priv, phy_res); |
959 | 960 | ||
960 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", | 961 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", |
961 | rx_status.signal, (unsigned long long)rx_status.mactime); | 962 | rx_status.signal, (unsigned long long)rx_status.mactime); |
962 | 963 | ||
963 | /* | 964 | /* |
964 | * "antenna number" | 965 | * "antenna number" |
965 | * | 966 | * |
966 | * It seems that the antenna field in the phy flags value | 967 | * It seems that the antenna field in the phy flags value |
967 | * is actually a bit field. This is undefined by radiotap, | 968 | * is actually a bit field. This is undefined by radiotap, |
968 | * it wants an actual antenna number but I always get "7" | 969 | * it wants an actual antenna number but I always get "7" |
969 | * for most legacy frames I receive indicating that the | 970 | * for most legacy frames I receive indicating that the |
970 | * same frame was received on all three RX chains. | 971 | * same frame was received on all three RX chains. |
971 | * | 972 | * |
972 | * I think this field should be removed in favor of a | 973 | * I think this field should be removed in favor of a |
973 | * new 802.11n radiotap field "RX chains" that is defined | 974 | * new 802.11n radiotap field "RX chains" that is defined |
974 | * as a bitmask. | 975 | * as a bitmask. |
975 | */ | 976 | */ |
976 | rx_status.antenna = | 977 | rx_status.antenna = |
977 | (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) | 978 | (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) |
978 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; | 979 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; |
979 | 980 | ||
980 | /* set the preamble flag if appropriate */ | 981 | /* set the preamble flag if appropriate */ |
981 | if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | 982 | if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) |
982 | rx_status.flag |= RX_FLAG_SHORTPRE; | 983 | rx_status.flag |= RX_FLAG_SHORTPRE; |
984 | |||
985 | if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) { | ||
986 | /* | ||
987 | * We know which subframes of an A-MPDU belong | ||
988 | * together since we get a single PHY response | ||
989 | * from the firmware for all of them | ||
990 | */ | ||
991 | rx_status.flag |= RX_FLAG_AMPDU_DETAILS; | ||
992 | rx_status.ampdu_reference = priv->ampdu_ref; | ||
993 | } | ||
983 | 994 | ||
984 | /* Set up the HT phy flags */ | 995 | /* Set up the HT phy flags */ |
985 | if (rate_n_flags & RATE_MCS_HT_MSK) | 996 | if (rate_n_flags & RATE_MCS_HT_MSK) |
986 | rx_status.flag |= RX_FLAG_HT; | 997 | rx_status.flag |= RX_FLAG_HT; |
987 | if (rate_n_flags & RATE_MCS_HT40_MSK) | 998 | if (rate_n_flags & RATE_MCS_HT40_MSK) |
988 | rx_status.flag |= RX_FLAG_40MHZ; | 999 | rx_status.flag |= RX_FLAG_40MHZ; |
989 | if (rate_n_flags & RATE_MCS_SGI_MSK) | 1000 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
990 | rx_status.flag |= RX_FLAG_SHORT_GI; | 1001 | rx_status.flag |= RX_FLAG_SHORT_GI; |
991 | if (rate_n_flags & RATE_MCS_GF_MSK) | 1002 | if (rate_n_flags & RATE_MCS_GF_MSK) |
992 | rx_status.flag |= RX_FLAG_HT_GF; | 1003 | rx_status.flag |= RX_FLAG_HT_GF; |
993 | 1004 | ||
994 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, | 1005 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, |
995 | rxb, &rx_status); | 1006 | rxb, &rx_status); |
996 | return 0; | 1007 | return 0; |
997 | } | 1008 | } |
998 | 1009 | ||
999 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | 1010 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, |
1000 | struct iwl_rx_cmd_buffer *rxb, | 1011 | struct iwl_rx_cmd_buffer *rxb, |
1001 | struct iwl_device_cmd *cmd) | 1012 | struct iwl_device_cmd *cmd) |
1002 | { | 1013 | { |
1003 | struct iwl_wipan_noa_data *new_data, *old_data; | 1014 | struct iwl_wipan_noa_data *new_data, *old_data; |
1004 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1015 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1005 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; | 1016 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; |
1006 | 1017 | ||
1007 | /* no condition -- we're in softirq */ | 1018 | /* no condition -- we're in softirq */ |
1008 | old_data = rcu_dereference_protected(priv->noa_data, true); | 1019 | old_data = rcu_dereference_protected(priv->noa_data, true); |
1009 | 1020 | ||
1010 | if (noa_notif->noa_active) { | 1021 | if (noa_notif->noa_active) { |
1011 | u32 len = le16_to_cpu(noa_notif->noa_attribute.length); | 1022 | u32 len = le16_to_cpu(noa_notif->noa_attribute.length); |
1012 | u32 copylen = len; | 1023 | u32 copylen = len; |
1013 | 1024 | ||
1014 | /* EID, len, OUI, subtype */ | 1025 | /* EID, len, OUI, subtype */ |
1015 | len += 1 + 1 + 3 + 1; | 1026 | len += 1 + 1 + 3 + 1; |
1016 | /* P2P id, P2P length */ | 1027 | /* P2P id, P2P length */ |
1017 | len += 1 + 2; | 1028 | len += 1 + 2; |
1018 | copylen += 1 + 2; | 1029 | copylen += 1 + 2; |
1019 | 1030 | ||
1020 | new_data = kmalloc(sizeof(*new_data) + len, GFP_ATOMIC); | 1031 | new_data = kmalloc(sizeof(*new_data) + len, GFP_ATOMIC); |
1021 | if (new_data) { | 1032 | if (new_data) { |
1022 | new_data->length = len; | 1033 | new_data->length = len; |
1023 | new_data->data[0] = WLAN_EID_VENDOR_SPECIFIC; | 1034 | new_data->data[0] = WLAN_EID_VENDOR_SPECIFIC; |
1024 | new_data->data[1] = len - 2; /* not counting EID, len */ | 1035 | new_data->data[1] = len - 2; /* not counting EID, len */ |
1025 | new_data->data[2] = (WLAN_OUI_WFA >> 16) & 0xff; | 1036 | new_data->data[2] = (WLAN_OUI_WFA >> 16) & 0xff; |
1026 | new_data->data[3] = (WLAN_OUI_WFA >> 8) & 0xff; | 1037 | new_data->data[3] = (WLAN_OUI_WFA >> 8) & 0xff; |
1027 | new_data->data[4] = (WLAN_OUI_WFA >> 0) & 0xff; | 1038 | new_data->data[4] = (WLAN_OUI_WFA >> 0) & 0xff; |
1028 | new_data->data[5] = WLAN_OUI_TYPE_WFA_P2P; | 1039 | new_data->data[5] = WLAN_OUI_TYPE_WFA_P2P; |
1029 | memcpy(&new_data->data[6], &noa_notif->noa_attribute, | 1040 | memcpy(&new_data->data[6], &noa_notif->noa_attribute, |
1030 | copylen); | 1041 | copylen); |
1031 | } | 1042 | } |
1032 | } else | 1043 | } else |
1033 | new_data = NULL; | 1044 | new_data = NULL; |
1034 | 1045 | ||
1035 | rcu_assign_pointer(priv->noa_data, new_data); | 1046 | rcu_assign_pointer(priv->noa_data, new_data); |
1036 | 1047 | ||
1037 | if (old_data) | 1048 | if (old_data) |
1038 | kfree_rcu(old_data, rcu_head); | 1049 | kfree_rcu(old_data, rcu_head); |
1039 | 1050 | ||
1040 | return 0; | 1051 | return 0; |
1041 | } | 1052 | } |
1042 | 1053 | ||
1043 | /** | 1054 | /** |
1044 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks | 1055 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks |
1045 | * | 1056 | * |
1046 | * Setup the RX handlers for each of the reply types sent from the uCode | 1057 | * Setup the RX handlers for each of the reply types sent from the uCode |
1047 | * to the host. | 1058 | * to the host. |
1048 | */ | 1059 | */ |
1049 | void iwl_setup_rx_handlers(struct iwl_priv *priv) | 1060 | void iwl_setup_rx_handlers(struct iwl_priv *priv) |
1050 | { | 1061 | { |
1051 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | 1062 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
1052 | struct iwl_device_cmd *cmd); | 1063 | struct iwl_device_cmd *cmd); |
1053 | 1064 | ||
1054 | handlers = priv->rx_handlers; | 1065 | handlers = priv->rx_handlers; |
1055 | 1066 | ||
1056 | handlers[REPLY_ERROR] = iwlagn_rx_reply_error; | 1067 | handlers[REPLY_ERROR] = iwlagn_rx_reply_error; |
1057 | handlers[CHANNEL_SWITCH_NOTIFICATION] = iwlagn_rx_csa; | 1068 | handlers[CHANNEL_SWITCH_NOTIFICATION] = iwlagn_rx_csa; |
1058 | handlers[SPECTRUM_MEASURE_NOTIFICATION] = | 1069 | handlers[SPECTRUM_MEASURE_NOTIFICATION] = |
1059 | iwlagn_rx_spectrum_measure_notif; | 1070 | iwlagn_rx_spectrum_measure_notif; |
1060 | handlers[PM_SLEEP_NOTIFICATION] = iwlagn_rx_pm_sleep_notif; | 1071 | handlers[PM_SLEEP_NOTIFICATION] = iwlagn_rx_pm_sleep_notif; |
1061 | handlers[PM_DEBUG_STATISTIC_NOTIFIC] = | 1072 | handlers[PM_DEBUG_STATISTIC_NOTIFIC] = |
1062 | iwlagn_rx_pm_debug_statistics_notif; | 1073 | iwlagn_rx_pm_debug_statistics_notif; |
1063 | handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; | 1074 | handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; |
1064 | handlers[REPLY_ADD_STA] = iwl_add_sta_callback; | 1075 | handlers[REPLY_ADD_STA] = iwl_add_sta_callback; |
1065 | 1076 | ||
1066 | handlers[REPLY_WIPAN_NOA_NOTIFICATION] = iwlagn_rx_noa_notification; | 1077 | handlers[REPLY_WIPAN_NOA_NOTIFICATION] = iwlagn_rx_noa_notification; |
1067 | 1078 | ||
1068 | /* | 1079 | /* |
1069 | * The same handler is used for both the REPLY to a discrete | 1080 | * The same handler is used for both the REPLY to a discrete |
1070 | * statistics request from the host as well as for the periodic | 1081 | * statistics request from the host as well as for the periodic |
1071 | * statistics notifications (after received beacons) from the uCode. | 1082 | * statistics notifications (after received beacons) from the uCode. |
1072 | */ | 1083 | */ |
1073 | handlers[REPLY_STATISTICS_CMD] = iwlagn_rx_reply_statistics; | 1084 | handlers[REPLY_STATISTICS_CMD] = iwlagn_rx_reply_statistics; |
1074 | handlers[STATISTICS_NOTIFICATION] = iwlagn_rx_statistics; | 1085 | handlers[STATISTICS_NOTIFICATION] = iwlagn_rx_statistics; |
1075 | 1086 | ||
1076 | iwl_setup_rx_scan_handlers(priv); | 1087 | iwl_setup_rx_scan_handlers(priv); |
1077 | 1088 | ||
1078 | handlers[CARD_STATE_NOTIFICATION] = iwlagn_rx_card_state_notif; | 1089 | handlers[CARD_STATE_NOTIFICATION] = iwlagn_rx_card_state_notif; |
1079 | handlers[MISSED_BEACONS_NOTIFICATION] = | 1090 | handlers[MISSED_BEACONS_NOTIFICATION] = |
1080 | iwlagn_rx_missed_beacon_notif; | 1091 | iwlagn_rx_missed_beacon_notif; |
1081 | 1092 | ||
1082 | /* Rx handlers */ | 1093 | /* Rx handlers */ |
1083 | handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy; | 1094 | handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy; |
1084 | handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx; | 1095 | handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx; |
1085 | 1096 | ||
1086 | /* block ack */ | 1097 | /* block ack */ |
1087 | handlers[REPLY_COMPRESSED_BA] = | 1098 | handlers[REPLY_COMPRESSED_BA] = |
1088 | iwlagn_rx_reply_compressed_ba; | 1099 | iwlagn_rx_reply_compressed_ba; |
1089 | 1100 | ||
1090 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 1101 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
1091 | 1102 | ||
1092 | /* set up notification wait support */ | 1103 | /* set up notification wait support */ |
1093 | iwl_notification_wait_init(&priv->notif_wait); | 1104 | iwl_notification_wait_init(&priv->notif_wait); |
1094 | 1105 | ||
1095 | /* Set up BT Rx handlers */ | 1106 | /* Set up BT Rx handlers */ |
1096 | if (priv->cfg->bt_params) | 1107 | if (priv->cfg->bt_params) |
1097 | iwlagn_bt_rx_handler_setup(priv); | 1108 | iwlagn_bt_rx_handler_setup(priv); |
1098 | } | 1109 | } |
1099 | 1110 | ||
1100 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, | 1111 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, |
1101 | struct iwl_device_cmd *cmd) | 1112 | struct iwl_device_cmd *cmd) |
1102 | { | 1113 | { |
1103 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1114 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1104 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1115 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1105 | int err = 0; | 1116 | int err = 0; |
1106 | 1117 | ||
1107 | /* | 1118 | /* |
1108 | * Do the notification wait before RX handlers so | 1119 | * Do the notification wait before RX handlers so |
1109 | * even if the RX handler consumes the RXB we have | 1120 | * even if the RX handler consumes the RXB we have |
1110 | * access to it in the notification wait entry. | 1121 | * access to it in the notification wait entry. |
1111 | */ | 1122 | */ |
1112 | iwl_notification_wait_notify(&priv->notif_wait, pkt); | 1123 | iwl_notification_wait_notify(&priv->notif_wait, pkt); |
1113 | 1124 | ||
1114 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 1125 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
1115 | /* | 1126 | /* |
1116 | * RX data may be forwarded to userspace in one | 1127 | * RX data may be forwarded to userspace in one |
1117 | * of two cases: the user owns the fw through testmode or when | 1128 | * of two cases: the user owns the fw through testmode or when |
1118 | * the user requested to monitor the rx w/o affecting the regular flow. | 1129 | * the user requested to monitor the rx w/o affecting the regular flow. |
1119 | * In these cases the iwl_test object will handle forwarding the rx | 1130 | * In these cases the iwl_test object will handle forwarding the rx |
1120 | * data to user space. | 1131 | * data to user space. |
1121 | * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow | 1132 | * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow |
1122 | * continues. | 1133 | * continues. |
1123 | */ | 1134 | */ |
1124 | iwl_test_rx(&priv->tst, rxb); | 1135 | iwl_test_rx(&priv->tst, rxb); |
1125 | #endif | 1136 | #endif |
1126 | 1137 | ||
1127 | if (priv->ucode_owner != IWL_OWNERSHIP_TM) { | 1138 | if (priv->ucode_owner != IWL_OWNERSHIP_TM) { |
1128 | /* Based on type of command response or notification, | 1139 | /* Based on type of command response or notification, |
1129 | * handle those that need handling via function in | 1140 | * handle those that need handling via function in |
1130 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 1141 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
1131 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 1142 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
1132 | priv->rx_handlers_stats[pkt->hdr.cmd]++; | 1143 | priv->rx_handlers_stats[pkt->hdr.cmd]++; |
1133 | err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); | 1144 | err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); |
1134 | } else { | 1145 | } else { |
1135 | /* No handling needed */ | 1146 | /* No handling needed */ |
1136 | IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", | 1147 | IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", |
1137 | iwl_dvm_get_cmd_string(pkt->hdr.cmd), | 1148 | iwl_dvm_get_cmd_string(pkt->hdr.cmd), |
1138 | pkt->hdr.cmd); | 1149 | pkt->hdr.cmd); |
1139 | } | 1150 | } |
1140 | } | 1151 | } |
1141 | return err; | 1152 | return err; |
1142 | } | 1153 | } |
1143 | 1154 |
drivers/net/wireless/iwlwifi/iwl-devtrace.h
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | 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 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License along with | 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., | 15 | * this program; if not, write to the Free Software Foundation, Inc., |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
17 | * | 17 | * |
18 | * The full GNU General Public License is included in this distribution in the | 18 | * The full GNU General Public License is included in this distribution in the |
19 | * file called LICENSE. | 19 | * file called LICENSE. |
20 | * | 20 | * |
21 | * Contact Information: | 21 | * Contact Information: |
22 | * Intel Linux Wireless <ilw@linux.intel.com> | 22 | * Intel Linux Wireless <ilw@linux.intel.com> |
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | 26 | ||
27 | #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) | 27 | #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) |
28 | #define __IWLWIFI_DEVICE_TRACE | 28 | #define __IWLWIFI_DEVICE_TRACE |
29 | 29 | ||
30 | #include <linux/tracepoint.h> | 30 | #include <linux/tracepoint.h> |
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | #include "iwl-trans.h" | ||
32 | 33 | ||
33 | 34 | ||
34 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) | 35 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) |
35 | #undef TRACE_EVENT | 36 | #undef TRACE_EVENT |
36 | #define TRACE_EVENT(name, proto, ...) \ | 37 | #define TRACE_EVENT(name, proto, ...) \ |
37 | static inline void trace_ ## name(proto) {} | 38 | static inline void trace_ ## name(proto) {} |
38 | #undef DECLARE_EVENT_CLASS | 39 | #undef DECLARE_EVENT_CLASS |
39 | #define DECLARE_EVENT_CLASS(...) | 40 | #define DECLARE_EVENT_CLASS(...) |
40 | #undef DEFINE_EVENT | 41 | #undef DEFINE_EVENT |
41 | #define DEFINE_EVENT(evt_class, name, proto, ...) \ | 42 | #define DEFINE_EVENT(evt_class, name, proto, ...) \ |
42 | static inline void trace_ ## name(proto) {} | 43 | static inline void trace_ ## name(proto) {} |
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | #define DEV_ENTRY __string(dev, dev_name(dev)) | 46 | #define DEV_ENTRY __string(dev, dev_name(dev)) |
46 | #define DEV_ASSIGN __assign_str(dev, dev_name(dev)) | 47 | #define DEV_ASSIGN __assign_str(dev, dev_name(dev)) |
47 | 48 | ||
48 | #undef TRACE_SYSTEM | 49 | #undef TRACE_SYSTEM |
49 | #define TRACE_SYSTEM iwlwifi_io | 50 | #define TRACE_SYSTEM iwlwifi_io |
50 | 51 | ||
51 | TRACE_EVENT(iwlwifi_dev_ioread32, | 52 | TRACE_EVENT(iwlwifi_dev_ioread32, |
52 | TP_PROTO(const struct device *dev, u32 offs, u32 val), | 53 | TP_PROTO(const struct device *dev, u32 offs, u32 val), |
53 | TP_ARGS(dev, offs, val), | 54 | TP_ARGS(dev, offs, val), |
54 | TP_STRUCT__entry( | 55 | TP_STRUCT__entry( |
55 | DEV_ENTRY | 56 | DEV_ENTRY |
56 | __field(u32, offs) | 57 | __field(u32, offs) |
57 | __field(u32, val) | 58 | __field(u32, val) |
58 | ), | 59 | ), |
59 | TP_fast_assign( | 60 | TP_fast_assign( |
60 | DEV_ASSIGN; | 61 | DEV_ASSIGN; |
61 | __entry->offs = offs; | 62 | __entry->offs = offs; |
62 | __entry->val = val; | 63 | __entry->val = val; |
63 | ), | 64 | ), |
64 | TP_printk("[%s] read io[%#x] = %#x", | 65 | TP_printk("[%s] read io[%#x] = %#x", |
65 | __get_str(dev), __entry->offs, __entry->val) | 66 | __get_str(dev), __entry->offs, __entry->val) |
66 | ); | 67 | ); |
67 | 68 | ||
68 | TRACE_EVENT(iwlwifi_dev_iowrite8, | 69 | TRACE_EVENT(iwlwifi_dev_iowrite8, |
69 | TP_PROTO(const struct device *dev, u32 offs, u8 val), | 70 | TP_PROTO(const struct device *dev, u32 offs, u8 val), |
70 | TP_ARGS(dev, offs, val), | 71 | TP_ARGS(dev, offs, val), |
71 | TP_STRUCT__entry( | 72 | TP_STRUCT__entry( |
72 | DEV_ENTRY | 73 | DEV_ENTRY |
73 | __field(u32, offs) | 74 | __field(u32, offs) |
74 | __field(u8, val) | 75 | __field(u8, val) |
75 | ), | 76 | ), |
76 | TP_fast_assign( | 77 | TP_fast_assign( |
77 | DEV_ASSIGN; | 78 | DEV_ASSIGN; |
78 | __entry->offs = offs; | 79 | __entry->offs = offs; |
79 | __entry->val = val; | 80 | __entry->val = val; |
80 | ), | 81 | ), |
81 | TP_printk("[%s] write io[%#x] = %#x)", | 82 | TP_printk("[%s] write io[%#x] = %#x)", |
82 | __get_str(dev), __entry->offs, __entry->val) | 83 | __get_str(dev), __entry->offs, __entry->val) |
83 | ); | 84 | ); |
84 | 85 | ||
85 | TRACE_EVENT(iwlwifi_dev_iowrite32, | 86 | TRACE_EVENT(iwlwifi_dev_iowrite32, |
86 | TP_PROTO(const struct device *dev, u32 offs, u32 val), | 87 | TP_PROTO(const struct device *dev, u32 offs, u32 val), |
87 | TP_ARGS(dev, offs, val), | 88 | TP_ARGS(dev, offs, val), |
88 | TP_STRUCT__entry( | 89 | TP_STRUCT__entry( |
89 | DEV_ENTRY | 90 | DEV_ENTRY |
90 | __field(u32, offs) | 91 | __field(u32, offs) |
91 | __field(u32, val) | 92 | __field(u32, val) |
92 | ), | 93 | ), |
93 | TP_fast_assign( | 94 | TP_fast_assign( |
94 | DEV_ASSIGN; | 95 | DEV_ASSIGN; |
95 | __entry->offs = offs; | 96 | __entry->offs = offs; |
96 | __entry->val = val; | 97 | __entry->val = val; |
97 | ), | 98 | ), |
98 | TP_printk("[%s] write io[%#x] = %#x)", | 99 | TP_printk("[%s] write io[%#x] = %#x)", |
99 | __get_str(dev), __entry->offs, __entry->val) | 100 | __get_str(dev), __entry->offs, __entry->val) |
100 | ); | 101 | ); |
101 | 102 | ||
102 | TRACE_EVENT(iwlwifi_dev_irq, | 103 | TRACE_EVENT(iwlwifi_dev_irq, |
103 | TP_PROTO(const struct device *dev), | 104 | TP_PROTO(const struct device *dev), |
104 | TP_ARGS(dev), | 105 | TP_ARGS(dev), |
105 | TP_STRUCT__entry( | 106 | TP_STRUCT__entry( |
106 | DEV_ENTRY | 107 | DEV_ENTRY |
107 | ), | 108 | ), |
108 | TP_fast_assign( | 109 | TP_fast_assign( |
109 | DEV_ASSIGN; | 110 | DEV_ASSIGN; |
110 | ), | 111 | ), |
111 | /* TP_printk("") doesn't compile */ | 112 | /* TP_printk("") doesn't compile */ |
112 | TP_printk("%d", 0) | 113 | TP_printk("%d", 0) |
113 | ); | 114 | ); |
114 | 115 | ||
115 | TRACE_EVENT(iwlwifi_dev_ict_read, | 116 | TRACE_EVENT(iwlwifi_dev_ict_read, |
116 | TP_PROTO(const struct device *dev, u32 index, u32 value), | 117 | TP_PROTO(const struct device *dev, u32 index, u32 value), |
117 | TP_ARGS(dev, index, value), | 118 | TP_ARGS(dev, index, value), |
118 | TP_STRUCT__entry( | 119 | TP_STRUCT__entry( |
119 | DEV_ENTRY | 120 | DEV_ENTRY |
120 | __field(u32, index) | 121 | __field(u32, index) |
121 | __field(u32, value) | 122 | __field(u32, value) |
122 | ), | 123 | ), |
123 | TP_fast_assign( | 124 | TP_fast_assign( |
124 | DEV_ASSIGN; | 125 | DEV_ASSIGN; |
125 | __entry->index = index; | 126 | __entry->index = index; |
126 | __entry->value = value; | 127 | __entry->value = value; |
127 | ), | 128 | ), |
128 | TP_printk("[%s] read ict[%d] = %#.8x", | 129 | TP_printk("[%s] read ict[%d] = %#.8x", |
129 | __get_str(dev), __entry->index, __entry->value) | 130 | __get_str(dev), __entry->index, __entry->value) |
130 | ); | 131 | ); |
131 | 132 | ||
132 | #undef TRACE_SYSTEM | 133 | #undef TRACE_SYSTEM |
133 | #define TRACE_SYSTEM iwlwifi_ucode | 134 | #define TRACE_SYSTEM iwlwifi_ucode |
134 | 135 | ||
135 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | 136 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, |
136 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), | 137 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), |
137 | TP_ARGS(dev, time, data, ev), | 138 | TP_ARGS(dev, time, data, ev), |
138 | TP_STRUCT__entry( | 139 | TP_STRUCT__entry( |
139 | DEV_ENTRY | 140 | DEV_ENTRY |
140 | 141 | ||
141 | __field(u32, time) | 142 | __field(u32, time) |
142 | __field(u32, data) | 143 | __field(u32, data) |
143 | __field(u32, ev) | 144 | __field(u32, ev) |
144 | ), | 145 | ), |
145 | TP_fast_assign( | 146 | TP_fast_assign( |
146 | DEV_ASSIGN; | 147 | DEV_ASSIGN; |
147 | __entry->time = time; | 148 | __entry->time = time; |
148 | __entry->data = data; | 149 | __entry->data = data; |
149 | __entry->ev = ev; | 150 | __entry->ev = ev; |
150 | ), | 151 | ), |
151 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", | 152 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", |
152 | __get_str(dev), __entry->time, __entry->data, __entry->ev) | 153 | __get_str(dev), __entry->time, __entry->data, __entry->ev) |
153 | ); | 154 | ); |
154 | 155 | ||
155 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | 156 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, |
156 | TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), | 157 | TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), |
157 | TP_ARGS(dev, wraps, n_entry, p_entry), | 158 | TP_ARGS(dev, wraps, n_entry, p_entry), |
158 | TP_STRUCT__entry( | 159 | TP_STRUCT__entry( |
159 | DEV_ENTRY | 160 | DEV_ENTRY |
160 | 161 | ||
161 | __field(u32, wraps) | 162 | __field(u32, wraps) |
162 | __field(u32, n_entry) | 163 | __field(u32, n_entry) |
163 | __field(u32, p_entry) | 164 | __field(u32, p_entry) |
164 | ), | 165 | ), |
165 | TP_fast_assign( | 166 | TP_fast_assign( |
166 | DEV_ASSIGN; | 167 | DEV_ASSIGN; |
167 | __entry->wraps = wraps; | 168 | __entry->wraps = wraps; |
168 | __entry->n_entry = n_entry; | 169 | __entry->n_entry = n_entry; |
169 | __entry->p_entry = p_entry; | 170 | __entry->p_entry = p_entry; |
170 | ), | 171 | ), |
171 | TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", | 172 | TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", |
172 | __get_str(dev), __entry->wraps, __entry->n_entry, | 173 | __get_str(dev), __entry->wraps, __entry->n_entry, |
173 | __entry->p_entry) | 174 | __entry->p_entry) |
174 | ); | 175 | ); |
175 | 176 | ||
176 | #undef TRACE_SYSTEM | 177 | #undef TRACE_SYSTEM |
177 | #define TRACE_SYSTEM iwlwifi_msg | 178 | #define TRACE_SYSTEM iwlwifi_msg |
178 | 179 | ||
179 | #define MAX_MSG_LEN 110 | 180 | #define MAX_MSG_LEN 110 |
180 | 181 | ||
181 | DECLARE_EVENT_CLASS(iwlwifi_msg_event, | 182 | DECLARE_EVENT_CLASS(iwlwifi_msg_event, |
182 | TP_PROTO(struct va_format *vaf), | 183 | TP_PROTO(struct va_format *vaf), |
183 | TP_ARGS(vaf), | 184 | TP_ARGS(vaf), |
184 | TP_STRUCT__entry( | 185 | TP_STRUCT__entry( |
185 | __dynamic_array(char, msg, MAX_MSG_LEN) | 186 | __dynamic_array(char, msg, MAX_MSG_LEN) |
186 | ), | 187 | ), |
187 | TP_fast_assign( | 188 | TP_fast_assign( |
188 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | 189 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), |
189 | MAX_MSG_LEN, vaf->fmt, | 190 | MAX_MSG_LEN, vaf->fmt, |
190 | *vaf->va) >= MAX_MSG_LEN); | 191 | *vaf->va) >= MAX_MSG_LEN); |
191 | ), | 192 | ), |
192 | TP_printk("%s", __get_str(msg)) | 193 | TP_printk("%s", __get_str(msg)) |
193 | ); | 194 | ); |
194 | 195 | ||
195 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err, | 196 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err, |
196 | TP_PROTO(struct va_format *vaf), | 197 | TP_PROTO(struct va_format *vaf), |
197 | TP_ARGS(vaf) | 198 | TP_ARGS(vaf) |
198 | ); | 199 | ); |
199 | 200 | ||
200 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn, | 201 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn, |
201 | TP_PROTO(struct va_format *vaf), | 202 | TP_PROTO(struct va_format *vaf), |
202 | TP_ARGS(vaf) | 203 | TP_ARGS(vaf) |
203 | ); | 204 | ); |
204 | 205 | ||
205 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info, | 206 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info, |
206 | TP_PROTO(struct va_format *vaf), | 207 | TP_PROTO(struct va_format *vaf), |
207 | TP_ARGS(vaf) | 208 | TP_ARGS(vaf) |
208 | ); | 209 | ); |
209 | 210 | ||
210 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit, | 211 | DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit, |
211 | TP_PROTO(struct va_format *vaf), | 212 | TP_PROTO(struct va_format *vaf), |
212 | TP_ARGS(vaf) | 213 | TP_ARGS(vaf) |
213 | ); | 214 | ); |
214 | 215 | ||
215 | TRACE_EVENT(iwlwifi_dbg, | 216 | TRACE_EVENT(iwlwifi_dbg, |
216 | TP_PROTO(u32 level, bool in_interrupt, const char *function, | 217 | TP_PROTO(u32 level, bool in_interrupt, const char *function, |
217 | struct va_format *vaf), | 218 | struct va_format *vaf), |
218 | TP_ARGS(level, in_interrupt, function, vaf), | 219 | TP_ARGS(level, in_interrupt, function, vaf), |
219 | TP_STRUCT__entry( | 220 | TP_STRUCT__entry( |
220 | __field(u32, level) | 221 | __field(u32, level) |
221 | __field(u8, in_interrupt) | 222 | __field(u8, in_interrupt) |
222 | __string(function, function) | 223 | __string(function, function) |
223 | __dynamic_array(char, msg, MAX_MSG_LEN) | 224 | __dynamic_array(char, msg, MAX_MSG_LEN) |
224 | ), | 225 | ), |
225 | TP_fast_assign( | 226 | TP_fast_assign( |
226 | __entry->level = level; | 227 | __entry->level = level; |
227 | __entry->in_interrupt = in_interrupt; | 228 | __entry->in_interrupt = in_interrupt; |
228 | __assign_str(function, function); | 229 | __assign_str(function, function); |
229 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | 230 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), |
230 | MAX_MSG_LEN, vaf->fmt, | 231 | MAX_MSG_LEN, vaf->fmt, |
231 | *vaf->va) >= MAX_MSG_LEN); | 232 | *vaf->va) >= MAX_MSG_LEN); |
232 | ), | 233 | ), |
233 | TP_printk("%s", (char *)__get_dynamic_array(msg)) | 234 | TP_printk("%s", (char *)__get_dynamic_array(msg)) |
234 | ); | 235 | ); |
235 | 236 | ||
236 | #undef TRACE_SYSTEM | 237 | #undef TRACE_SYSTEM |
237 | #define TRACE_SYSTEM iwlwifi | 238 | #define TRACE_SYSTEM iwlwifi |
238 | 239 | ||
239 | TRACE_EVENT(iwlwifi_dev_hcmd, | 240 | TRACE_EVENT(iwlwifi_dev_hcmd, |
240 | TP_PROTO(const struct device *dev, u32 flags, | 241 | TP_PROTO(const struct device *dev, |
241 | const void *hcmd0, size_t len0, | 242 | struct iwl_host_cmd *cmd, u16 total_size, |
242 | const void *hcmd1, size_t len1, | 243 | const void *hdr, size_t hdr_len), |
243 | const void *hcmd2, size_t len2), | 244 | TP_ARGS(dev, cmd, total_size, hdr, hdr_len), |
244 | TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), | ||
245 | TP_STRUCT__entry( | 245 | TP_STRUCT__entry( |
246 | DEV_ENTRY | 246 | DEV_ENTRY |
247 | __dynamic_array(u8, hcmd0, len0) | 247 | __dynamic_array(u8, hcmd, total_size) |
248 | __dynamic_array(u8, hcmd1, len1) | ||
249 | __dynamic_array(u8, hcmd2, len2) | ||
250 | __field(u32, flags) | 248 | __field(u32, flags) |
251 | ), | 249 | ), |
252 | TP_fast_assign( | 250 | TP_fast_assign( |
251 | int i, offset = hdr_len; | ||
252 | |||
253 | DEV_ASSIGN; | 253 | DEV_ASSIGN; |
254 | memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); | 254 | __entry->flags = cmd->flags; |
255 | memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); | 255 | memcpy(__get_dynamic_array(hcmd), hdr, hdr_len); |
256 | memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); | 256 | |
257 | __entry->flags = flags; | 257 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
258 | if (!cmd->len[i]) | ||
259 | continue; | ||
260 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | ||
261 | continue; | ||
262 | memcpy((u8 *)__get_dynamic_array(hcmd) + offset, | ||
263 | cmd->data[i], cmd->len[i]); | ||
264 | offset += cmd->len[i]; | ||
265 | } | ||
258 | ), | 266 | ), |
259 | TP_printk("[%s] hcmd %#.2x (%ssync)", | 267 | TP_printk("[%s] hcmd %#.2x (%ssync)", |
260 | __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0], | 268 | __get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0], |
261 | __entry->flags & CMD_ASYNC ? "a" : "") | 269 | __entry->flags & CMD_ASYNC ? "a" : "") |
262 | ); | 270 | ); |
263 | 271 | ||
264 | TRACE_EVENT(iwlwifi_dev_rx, | 272 | TRACE_EVENT(iwlwifi_dev_rx, |
265 | TP_PROTO(const struct device *dev, void *rxbuf, size_t len), | 273 | TP_PROTO(const struct device *dev, void *rxbuf, size_t len), |
266 | TP_ARGS(dev, rxbuf, len), | 274 | TP_ARGS(dev, rxbuf, len), |
267 | TP_STRUCT__entry( | 275 | TP_STRUCT__entry( |
268 | DEV_ENTRY | 276 | DEV_ENTRY |
269 | __dynamic_array(u8, rxbuf, len) | 277 | __dynamic_array(u8, rxbuf, len) |
270 | ), | 278 | ), |
271 | TP_fast_assign( | 279 | TP_fast_assign( |
272 | DEV_ASSIGN; | 280 | DEV_ASSIGN; |
273 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); | 281 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); |
274 | ), | 282 | ), |
275 | TP_printk("[%s] RX cmd %#.2x", | 283 | TP_printk("[%s] RX cmd %#.2x", |
276 | __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) | 284 | __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) |
277 | ); | 285 | ); |
278 | 286 | ||
279 | TRACE_EVENT(iwlwifi_dev_tx, | 287 | TRACE_EVENT(iwlwifi_dev_tx, |
280 | TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, | 288 | TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, |
281 | void *buf0, size_t buf0_len, | 289 | void *buf0, size_t buf0_len, |
282 | void *buf1, size_t buf1_len), | 290 | void *buf1, size_t buf1_len), |
283 | TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), | 291 | TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), |
284 | TP_STRUCT__entry( | 292 | TP_STRUCT__entry( |
285 | DEV_ENTRY | 293 | DEV_ENTRY |
286 | 294 | ||
287 | __field(size_t, framelen) | 295 | __field(size_t, framelen) |
288 | __dynamic_array(u8, tfd, tfdlen) | 296 | __dynamic_array(u8, tfd, tfdlen) |
289 | 297 | ||
290 | /* | 298 | /* |
291 | * Do not insert between or below these items, | 299 | * Do not insert between or below these items, |
292 | * we want to keep the frame together (except | 300 | * we want to keep the frame together (except |
293 | * for the possible padding). | 301 | * for the possible padding). |
294 | */ | 302 | */ |
295 | __dynamic_array(u8, buf0, buf0_len) | 303 | __dynamic_array(u8, buf0, buf0_len) |
296 | __dynamic_array(u8, buf1, buf1_len) | 304 | __dynamic_array(u8, buf1, buf1_len) |
297 | ), | 305 | ), |
298 | TP_fast_assign( | 306 | TP_fast_assign( |
299 | DEV_ASSIGN; | 307 | DEV_ASSIGN; |
300 | __entry->framelen = buf0_len + buf1_len; | 308 | __entry->framelen = buf0_len + buf1_len; |
301 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); | 309 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); |
302 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); | 310 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); |
303 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); | 311 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); |
304 | ), | 312 | ), |
305 | TP_printk("[%s] TX %.2x (%zu bytes)", | 313 | TP_printk("[%s] TX %.2x (%zu bytes)", |
306 | __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], | 314 | __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], |
307 | __entry->framelen) | 315 | __entry->framelen) |
308 | ); | 316 | ); |
309 | 317 | ||
310 | TRACE_EVENT(iwlwifi_dev_ucode_error, | 318 | TRACE_EVENT(iwlwifi_dev_ucode_error, |
311 | TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, | 319 | TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, |
312 | u32 data1, u32 data2, u32 line, u32 blink1, | 320 | u32 data1, u32 data2, u32 line, u32 blink1, |
313 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, | 321 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, |
314 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, | 322 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, |
315 | u32 brd_ver), | 323 | u32 brd_ver), |
316 | TP_ARGS(dev, desc, tsf_low, data1, data2, line, | 324 | TP_ARGS(dev, desc, tsf_low, data1, data2, line, |
317 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, | 325 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, |
318 | gp3, ucode_ver, hw_ver, brd_ver), | 326 | gp3, ucode_ver, hw_ver, brd_ver), |
319 | TP_STRUCT__entry( | 327 | TP_STRUCT__entry( |
320 | DEV_ENTRY | 328 | DEV_ENTRY |
321 | __field(u32, desc) | 329 | __field(u32, desc) |
322 | __field(u32, tsf_low) | 330 | __field(u32, tsf_low) |
323 | __field(u32, data1) | 331 | __field(u32, data1) |
324 | __field(u32, data2) | 332 | __field(u32, data2) |
325 | __field(u32, line) | 333 | __field(u32, line) |
326 | __field(u32, blink1) | 334 | __field(u32, blink1) |
327 | __field(u32, blink2) | 335 | __field(u32, blink2) |
328 | __field(u32, ilink1) | 336 | __field(u32, ilink1) |
329 | __field(u32, ilink2) | 337 | __field(u32, ilink2) |
330 | __field(u32, bcon_time) | 338 | __field(u32, bcon_time) |
331 | __field(u32, gp1) | 339 | __field(u32, gp1) |
332 | __field(u32, gp2) | 340 | __field(u32, gp2) |
333 | __field(u32, gp3) | 341 | __field(u32, gp3) |
334 | __field(u32, ucode_ver) | 342 | __field(u32, ucode_ver) |
335 | __field(u32, hw_ver) | 343 | __field(u32, hw_ver) |
336 | __field(u32, brd_ver) | 344 | __field(u32, brd_ver) |
337 | ), | 345 | ), |
338 | TP_fast_assign( | 346 | TP_fast_assign( |
339 | DEV_ASSIGN; | 347 | DEV_ASSIGN; |
340 | __entry->desc = desc; | 348 | __entry->desc = desc; |
341 | __entry->tsf_low = tsf_low; | 349 | __entry->tsf_low = tsf_low; |
342 | __entry->data1 = data1; | 350 | __entry->data1 = data1; |
343 | __entry->data2 = data2; | 351 | __entry->data2 = data2; |
344 | __entry->line = line; | 352 | __entry->line = line; |
345 | __entry->blink1 = blink1; | 353 | __entry->blink1 = blink1; |
346 | __entry->blink2 = blink2; | 354 | __entry->blink2 = blink2; |
347 | __entry->ilink1 = ilink1; | 355 | __entry->ilink1 = ilink1; |
348 | __entry->ilink2 = ilink2; | 356 | __entry->ilink2 = ilink2; |
349 | __entry->bcon_time = bcon_time; | 357 | __entry->bcon_time = bcon_time; |
350 | __entry->gp1 = gp1; | 358 | __entry->gp1 = gp1; |
351 | __entry->gp2 = gp2; | 359 | __entry->gp2 = gp2; |
352 | __entry->gp3 = gp3; | 360 | __entry->gp3 = gp3; |
353 | __entry->ucode_ver = ucode_ver; | 361 | __entry->ucode_ver = ucode_ver; |
354 | __entry->hw_ver = hw_ver; | 362 | __entry->hw_ver = hw_ver; |
355 | __entry->brd_ver = brd_ver; | 363 | __entry->brd_ver = brd_ver; |
356 | ), | 364 | ), |
357 | TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " | 365 | TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " |
358 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " | 366 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " |
359 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " | 367 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " |
360 | "hw 0x%08X brd 0x%08X", | 368 | "hw 0x%08X brd 0x%08X", |
361 | __get_str(dev), __entry->desc, __entry->tsf_low, | 369 | __get_str(dev), __entry->desc, __entry->tsf_low, |
362 | __entry->data1, | 370 | __entry->data1, |
363 | __entry->data2, __entry->line, __entry->blink1, | 371 | __entry->data2, __entry->line, __entry->blink1, |
364 | __entry->blink2, __entry->ilink1, __entry->ilink2, | 372 | __entry->blink2, __entry->ilink1, __entry->ilink2, |
365 | __entry->bcon_time, __entry->gp1, __entry->gp2, | 373 | __entry->bcon_time, __entry->gp1, __entry->gp2, |
366 | __entry->gp3, __entry->ucode_ver, __entry->hw_ver, | 374 | __entry->gp3, __entry->ucode_ver, __entry->hw_ver, |
367 | __entry->brd_ver) | 375 | __entry->brd_ver) |
368 | ); | 376 | ); |
369 | 377 | ||
370 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 378 | TRACE_EVENT(iwlwifi_dev_ucode_event, |
371 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), | 379 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), |
372 | TP_ARGS(dev, time, data, ev), | 380 | TP_ARGS(dev, time, data, ev), |
373 | TP_STRUCT__entry( | 381 | TP_STRUCT__entry( |
374 | DEV_ENTRY | 382 | DEV_ENTRY |
375 | 383 | ||
376 | __field(u32, time) | 384 | __field(u32, time) |
377 | __field(u32, data) | 385 | __field(u32, data) |
378 | __field(u32, ev) | 386 | __field(u32, ev) |
379 | ), | 387 | ), |
380 | TP_fast_assign( | 388 | TP_fast_assign( |
381 | DEV_ASSIGN; | 389 | DEV_ASSIGN; |
382 | __entry->time = time; | 390 | __entry->time = time; |
383 | __entry->data = data; | 391 | __entry->data = data; |
384 | __entry->ev = ev; | 392 | __entry->ev = ev; |
385 | ), | 393 | ), |
386 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", | 394 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", |
387 | __get_str(dev), __entry->time, __entry->data, __entry->ev) | 395 | __get_str(dev), __entry->time, __entry->data, __entry->ev) |
388 | ); | 396 | ); |
389 | #endif /* __IWLWIFI_DEVICE_TRACE */ | 397 | #endif /* __IWLWIFI_DEVICE_TRACE */ |
390 | 398 | ||
391 | #undef TRACE_INCLUDE_PATH | 399 | #undef TRACE_INCLUDE_PATH |
392 | #define TRACE_INCLUDE_PATH . | 400 | #define TRACE_INCLUDE_PATH . |
393 | #undef TRACE_INCLUDE_FILE | 401 | #undef TRACE_INCLUDE_FILE |
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | 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. | 4 | * redistributing this file, you may do so under either license. |
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 11 | * it under the terms of version 2 of the GNU General Public License as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, but | 14 | * This program is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * General Public License for more details. | 17 | * General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 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 | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
22 | * USA | 22 | * USA |
23 | * | 23 | * |
24 | * The full GNU General Public License is included in this distribution | 24 | * The full GNU General Public License is included in this distribution |
25 | * in the file called LICENSE.GPL. | 25 | * in the file called LICENSE.GPL. |
26 | * | 26 | * |
27 | * Contact Information: | 27 | * Contact Information: |
28 | * Intel Linux Wireless <ilw@linux.intel.com> | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
37 | * modification, are permitted provided that the following conditions | 37 | * modification, are permitted provided that the following conditions |
38 | * are met: | 38 | * are met: |
39 | * | 39 | * |
40 | * * Redistributions of source code must retain the above copyright | 40 | * * Redistributions of source code must retain the above copyright |
41 | * notice, this list of conditions and the following disclaimer. | 41 | * notice, this list of conditions and the following disclaimer. |
42 | * * Redistributions in binary form must reproduce the above copyright | 42 | * * Redistributions in binary form must reproduce the above copyright |
43 | * notice, this list of conditions and the following disclaimer in | 43 | * notice, this list of conditions and the following disclaimer in |
44 | * the documentation and/or other materials provided with the | 44 | * the documentation and/or other materials provided with the |
45 | * distribution. | 45 | * distribution. |
46 | * * Neither the name Intel Corporation nor the names of its | 46 | * * Neither the name Intel Corporation nor the names of its |
47 | * contributors may be used to endorse or promote products derived | 47 | * contributors may be used to endorse or promote products derived |
48 | * from this software without specific prior written permission. | 48 | * from this software without specific prior written permission. |
49 | * | 49 | * |
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
62 | #ifndef __iwl_eeprom_parse_h__ | 62 | #ifndef __iwl_eeprom_parse_h__ |
63 | #define __iwl_eeprom_parse_h__ | 63 | #define __iwl_eeprom_parse_h__ |
64 | 64 | ||
65 | #include <linux/types.h> | 65 | #include <linux/types.h> |
66 | #include <linux/if_ether.h> | 66 | #include <linux/if_ether.h> |
67 | #include "iwl-trans.h" | 67 | #include "iwl-trans.h" |
68 | 68 | ||
69 | /* SKU Capabilities (actual values from EEPROM definition) */ | 69 | /* SKU Capabilities (actual values from EEPROM definition) */ |
70 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) | 70 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) |
71 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) | 71 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) |
72 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) | 72 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) |
73 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) | 73 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) |
74 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) | 74 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) |
75 | 75 | ||
76 | /* radio config bits (actual values from EEPROM definition) */ | 76 | /* radio config bits (actual values from EEPROM definition) */ |
77 | #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ | 77 | #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ |
78 | #define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ | 78 | #define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ |
79 | #define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ | 79 | #define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ |
80 | #define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ | 80 | #define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ |
81 | #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ | 81 | #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ |
82 | #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ | 82 | #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ |
83 | 83 | ||
84 | struct iwl_eeprom_data { | 84 | struct iwl_eeprom_data { |
85 | int n_hw_addrs; | 85 | int n_hw_addrs; |
86 | u8 hw_addr[ETH_ALEN]; | 86 | u8 hw_addr[ETH_ALEN]; |
87 | 87 | ||
88 | u16 radio_config; | ||
89 | |||
90 | u8 calib_version; | 88 | u8 calib_version; |
91 | __le16 calib_voltage; | 89 | __le16 calib_voltage; |
92 | 90 | ||
93 | __le16 raw_temperature; | 91 | __le16 raw_temperature; |
94 | __le16 kelvin_temperature; | 92 | __le16 kelvin_temperature; |
95 | __le16 kelvin_voltage; | 93 | __le16 kelvin_voltage; |
96 | __le16 xtal_calib[2]; | 94 | __le16 xtal_calib[2]; |
97 | 95 | ||
98 | u16 sku; | 96 | u16 sku; |
99 | u16 radio_cfg; | 97 | u16 radio_cfg; |
100 | u16 eeprom_version; | 98 | u16 eeprom_version; |
101 | s8 max_tx_pwr_half_dbm; | 99 | s8 max_tx_pwr_half_dbm; |
102 | 100 | ||
103 | u8 valid_tx_ant, valid_rx_ant; | 101 | u8 valid_tx_ant, valid_rx_ant; |
104 | 102 | ||
105 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 103 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
106 | struct ieee80211_channel channels[]; | 104 | struct ieee80211_channel channels[]; |
107 | }; | 105 | }; |
108 | 106 | ||
109 | /** | 107 | /** |
110 | * iwl_parse_eeprom_data - parse EEPROM data and return values | 108 | * iwl_parse_eeprom_data - parse EEPROM data and return values |
111 | * | 109 | * |
112 | * @dev: device pointer we're parsing for, for debug only | 110 | * @dev: device pointer we're parsing for, for debug only |
113 | * @cfg: device configuration for parsing and overrides | 111 | * @cfg: device configuration for parsing and overrides |
114 | * @eeprom: the EEPROM data | 112 | * @eeprom: the EEPROM data |
115 | * @eeprom_size: length of the EEPROM data | 113 | * @eeprom_size: length of the EEPROM data |
116 | * | 114 | * |
117 | * This function parses all EEPROM values we need and then | 115 | * This function parses all EEPROM values we need and then |
118 | * returns a (newly allocated) struct containing all the | 116 | * returns a (newly allocated) struct containing all the |
119 | * relevant values for driver use. The struct must be freed | 117 | * relevant values for driver use. The struct must be freed |
120 | * later with iwl_free_eeprom_data(). | 118 | * later with iwl_free_eeprom_data(). |
121 | */ | 119 | */ |
122 | struct iwl_eeprom_data * | 120 | struct iwl_eeprom_data * |
123 | iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, | 121 | iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, |
124 | const u8 *eeprom, size_t eeprom_size); | 122 | const u8 *eeprom, size_t eeprom_size); |
125 | 123 | ||
126 | /** | 124 | /** |
127 | * iwl_free_eeprom_data - free EEPROM data | 125 | * iwl_free_eeprom_data - free EEPROM data |
128 | * @data: the data to free | 126 | * @data: the data to free |
129 | */ | 127 | */ |
130 | static inline void iwl_free_eeprom_data(struct iwl_eeprom_data *data) | 128 | static inline void iwl_free_eeprom_data(struct iwl_eeprom_data *data) |
131 | { | 129 | { |
132 | kfree(data); | 130 | kfree(data); |
133 | } | 131 | } |
134 | 132 | ||
135 | int iwl_eeprom_check_version(struct iwl_eeprom_data *data, | 133 | int iwl_eeprom_check_version(struct iwl_eeprom_data *data, |
136 | struct iwl_trans *trans); | 134 | struct iwl_trans *trans); |
137 | 135 | ||
138 | #endif /* __iwl_eeprom_parse_h__ */ | 136 | #endif /* __iwl_eeprom_parse_h__ */ |
139 | 137 |
drivers/net/wireless/iwlwifi/pcie/tx.c
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of version 2 of the GNU General Public License as | 9 | * under the terms of version 2 of the GNU General Public License as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | 12 | * This program is distributed in the hope that it will be useful, but WITHOUT |
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
15 | * more details. | 15 | * more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License along with | 17 | * You should have received a copy of the GNU General Public License along with |
18 | * this program; if not, write to the Free Software Foundation, Inc., | 18 | * this program; if not, write to the Free Software Foundation, Inc., |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution in the | 21 | * The full GNU General Public License is included in this distribution in the |
22 | * file called LICENSE. | 22 | * file called LICENSE. |
23 | * | 23 | * |
24 | * Contact Information: | 24 | * Contact Information: |
25 | * Intel Linux Wireless <ilw@linux.intel.com> | 25 | * Intel Linux Wireless <ilw@linux.intel.com> |
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | 32 | ||
33 | #include "iwl-debug.h" | 33 | #include "iwl-debug.h" |
34 | #include "iwl-csr.h" | 34 | #include "iwl-csr.h" |
35 | #include "iwl-prph.h" | 35 | #include "iwl-prph.h" |
36 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
37 | #include "iwl-op-mode.h" | 37 | #include "iwl-op-mode.h" |
38 | #include "internal.h" | 38 | #include "internal.h" |
39 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 39 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
40 | #include "dvm/commands.h" | 40 | #include "dvm/commands.h" |
41 | 41 | ||
42 | #define IWL_TX_CRC_SIZE 4 | 42 | #define IWL_TX_CRC_SIZE 4 |
43 | #define IWL_TX_DELIMITER_SIZE 4 | 43 | #define IWL_TX_DELIMITER_SIZE 4 |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 46 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
47 | */ | 47 | */ |
48 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 48 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
49 | struct iwl_tx_queue *txq, | 49 | struct iwl_tx_queue *txq, |
50 | u16 byte_cnt) | 50 | u16 byte_cnt) |
51 | { | 51 | { |
52 | struct iwlagn_scd_bc_tbl *scd_bc_tbl; | 52 | struct iwlagn_scd_bc_tbl *scd_bc_tbl; |
53 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 53 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
54 | int write_ptr = txq->q.write_ptr; | 54 | int write_ptr = txq->q.write_ptr; |
55 | int txq_id = txq->q.id; | 55 | int txq_id = txq->q.id; |
56 | u8 sec_ctl = 0; | 56 | u8 sec_ctl = 0; |
57 | u8 sta_id = 0; | 57 | u8 sta_id = 0; |
58 | u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; | 58 | u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; |
59 | __le16 bc_ent; | 59 | __le16 bc_ent; |
60 | struct iwl_tx_cmd *tx_cmd = | 60 | struct iwl_tx_cmd *tx_cmd = |
61 | (void *) txq->entries[txq->q.write_ptr].cmd->payload; | 61 | (void *) txq->entries[txq->q.write_ptr].cmd->payload; |
62 | 62 | ||
63 | scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; | 63 | scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; |
64 | 64 | ||
65 | WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); | 65 | WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); |
66 | 66 | ||
67 | sta_id = tx_cmd->sta_id; | 67 | sta_id = tx_cmd->sta_id; |
68 | sec_ctl = tx_cmd->sec_ctl; | 68 | sec_ctl = tx_cmd->sec_ctl; |
69 | 69 | ||
70 | switch (sec_ctl & TX_CMD_SEC_MSK) { | 70 | switch (sec_ctl & TX_CMD_SEC_MSK) { |
71 | case TX_CMD_SEC_CCM: | 71 | case TX_CMD_SEC_CCM: |
72 | len += CCMP_MIC_LEN; | 72 | len += CCMP_MIC_LEN; |
73 | break; | 73 | break; |
74 | case TX_CMD_SEC_TKIP: | 74 | case TX_CMD_SEC_TKIP: |
75 | len += TKIP_ICV_LEN; | 75 | len += TKIP_ICV_LEN; |
76 | break; | 76 | break; |
77 | case TX_CMD_SEC_WEP: | 77 | case TX_CMD_SEC_WEP: |
78 | len += WEP_IV_LEN + WEP_ICV_LEN; | 78 | len += WEP_IV_LEN + WEP_ICV_LEN; |
79 | break; | 79 | break; |
80 | } | 80 | } |
81 | 81 | ||
82 | bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); | 82 | bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); |
83 | 83 | ||
84 | scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; | 84 | scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; |
85 | 85 | ||
86 | if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) | 86 | if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) |
87 | scd_bc_tbl[txq_id]. | 87 | scd_bc_tbl[txq_id]. |
88 | tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; | 88 | tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; |
89 | } | 89 | } |
90 | 90 | ||
91 | /** | 91 | /** |
92 | * iwl_txq_update_write_ptr - Send new write index to hardware | 92 | * iwl_txq_update_write_ptr - Send new write index to hardware |
93 | */ | 93 | */ |
94 | void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | 94 | void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) |
95 | { | 95 | { |
96 | u32 reg = 0; | 96 | u32 reg = 0; |
97 | int txq_id = txq->q.id; | 97 | int txq_id = txq->q.id; |
98 | 98 | ||
99 | if (txq->need_update == 0) | 99 | if (txq->need_update == 0) |
100 | return; | 100 | return; |
101 | 101 | ||
102 | if (trans->cfg->base_params->shadow_reg_enable) { | 102 | if (trans->cfg->base_params->shadow_reg_enable) { |
103 | /* shadow register enabled */ | 103 | /* shadow register enabled */ |
104 | iwl_write32(trans, HBUS_TARG_WRPTR, | 104 | iwl_write32(trans, HBUS_TARG_WRPTR, |
105 | txq->q.write_ptr | (txq_id << 8)); | 105 | txq->q.write_ptr | (txq_id << 8)); |
106 | } else { | 106 | } else { |
107 | struct iwl_trans_pcie *trans_pcie = | 107 | struct iwl_trans_pcie *trans_pcie = |
108 | IWL_TRANS_GET_PCIE_TRANS(trans); | 108 | IWL_TRANS_GET_PCIE_TRANS(trans); |
109 | /* if we're trying to save power */ | 109 | /* if we're trying to save power */ |
110 | if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) { | 110 | if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) { |
111 | /* wake up nic if it's powered down ... | 111 | /* wake up nic if it's powered down ... |
112 | * uCode will wake up, and interrupt us again, so next | 112 | * uCode will wake up, and interrupt us again, so next |
113 | * time we'll skip this part. */ | 113 | * time we'll skip this part. */ |
114 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); | 114 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); |
115 | 115 | ||
116 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | 116 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
117 | IWL_DEBUG_INFO(trans, | 117 | IWL_DEBUG_INFO(trans, |
118 | "Tx queue %d requesting wakeup," | 118 | "Tx queue %d requesting wakeup," |
119 | " GP1 = 0x%x\n", txq_id, reg); | 119 | " GP1 = 0x%x\n", txq_id, reg); |
120 | iwl_set_bit(trans, CSR_GP_CNTRL, | 120 | iwl_set_bit(trans, CSR_GP_CNTRL, |
121 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 121 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
122 | return; | 122 | return; |
123 | } | 123 | } |
124 | 124 | ||
125 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 125 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
126 | txq->q.write_ptr | (txq_id << 8)); | 126 | txq->q.write_ptr | (txq_id << 8)); |
127 | 127 | ||
128 | /* | 128 | /* |
129 | * else not in power-save mode, | 129 | * else not in power-save mode, |
130 | * uCode will never sleep when we're | 130 | * uCode will never sleep when we're |
131 | * trying to tx (during RFKILL, we're not trying to tx). | 131 | * trying to tx (during RFKILL, we're not trying to tx). |
132 | */ | 132 | */ |
133 | } else | 133 | } else |
134 | iwl_write32(trans, HBUS_TARG_WRPTR, | 134 | iwl_write32(trans, HBUS_TARG_WRPTR, |
135 | txq->q.write_ptr | (txq_id << 8)); | 135 | txq->q.write_ptr | (txq_id << 8)); |
136 | } | 136 | } |
137 | txq->need_update = 0; | 137 | txq->need_update = 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | 140 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) |
141 | { | 141 | { |
142 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | 142 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; |
143 | 143 | ||
144 | dma_addr_t addr = get_unaligned_le32(&tb->lo); | 144 | dma_addr_t addr = get_unaligned_le32(&tb->lo); |
145 | if (sizeof(dma_addr_t) > sizeof(u32)) | 145 | if (sizeof(dma_addr_t) > sizeof(u32)) |
146 | addr |= | 146 | addr |= |
147 | ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; | 147 | ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; |
148 | 148 | ||
149 | return addr; | 149 | return addr; |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) | 152 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) |
153 | { | 153 | { |
154 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | 154 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; |
155 | 155 | ||
156 | return le16_to_cpu(tb->hi_n_len) >> 4; | 156 | return le16_to_cpu(tb->hi_n_len) >> 4; |
157 | } | 157 | } |
158 | 158 | ||
159 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | 159 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, |
160 | dma_addr_t addr, u16 len) | 160 | dma_addr_t addr, u16 len) |
161 | { | 161 | { |
162 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | 162 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; |
163 | u16 hi_n_len = len << 4; | 163 | u16 hi_n_len = len << 4; |
164 | 164 | ||
165 | put_unaligned_le32(addr, &tb->lo); | 165 | put_unaligned_le32(addr, &tb->lo); |
166 | if (sizeof(dma_addr_t) > sizeof(u32)) | 166 | if (sizeof(dma_addr_t) > sizeof(u32)) |
167 | hi_n_len |= ((addr >> 16) >> 16) & 0xF; | 167 | hi_n_len |= ((addr >> 16) >> 16) & 0xF; |
168 | 168 | ||
169 | tb->hi_n_len = cpu_to_le16(hi_n_len); | 169 | tb->hi_n_len = cpu_to_le16(hi_n_len); |
170 | 170 | ||
171 | tfd->num_tbs = idx + 1; | 171 | tfd->num_tbs = idx + 1; |
172 | } | 172 | } |
173 | 173 | ||
174 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | 174 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) |
175 | { | 175 | { |
176 | return tfd->num_tbs & 0x1f; | 176 | return tfd->num_tbs & 0x1f; |
177 | } | 177 | } |
178 | 178 | ||
179 | static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | 179 | static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, |
180 | struct iwl_tfd *tfd, enum dma_data_direction dma_dir) | 180 | struct iwl_tfd *tfd, enum dma_data_direction dma_dir) |
181 | { | 181 | { |
182 | int i; | 182 | int i; |
183 | int num_tbs; | 183 | int num_tbs; |
184 | 184 | ||
185 | /* Sanity check on number of chunks */ | 185 | /* Sanity check on number of chunks */ |
186 | num_tbs = iwl_tfd_get_num_tbs(tfd); | 186 | num_tbs = iwl_tfd_get_num_tbs(tfd); |
187 | 187 | ||
188 | if (num_tbs >= IWL_NUM_OF_TBS) { | 188 | if (num_tbs >= IWL_NUM_OF_TBS) { |
189 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); | 189 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); |
190 | /* @todo issue fatal error, it is quite serious situation */ | 190 | /* @todo issue fatal error, it is quite serious situation */ |
191 | return; | 191 | return; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* Unmap tx_cmd */ | 194 | /* Unmap tx_cmd */ |
195 | if (num_tbs) | 195 | if (num_tbs) |
196 | dma_unmap_single(trans->dev, | 196 | dma_unmap_single(trans->dev, |
197 | dma_unmap_addr(meta, mapping), | 197 | dma_unmap_addr(meta, mapping), |
198 | dma_unmap_len(meta, len), | 198 | dma_unmap_len(meta, len), |
199 | DMA_BIDIRECTIONAL); | 199 | DMA_BIDIRECTIONAL); |
200 | 200 | ||
201 | /* Unmap chunks, if any. */ | 201 | /* Unmap chunks, if any. */ |
202 | for (i = 1; i < num_tbs; i++) | 202 | for (i = 1; i < num_tbs; i++) |
203 | dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), | 203 | dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), |
204 | iwl_tfd_tb_get_len(tfd, i), dma_dir); | 204 | iwl_tfd_tb_get_len(tfd, i), dma_dir); |
205 | 205 | ||
206 | tfd->num_tbs = 0; | 206 | tfd->num_tbs = 0; |
207 | } | 207 | } |
208 | 208 | ||
209 | /** | 209 | /** |
210 | * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | 210 | * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] |
211 | * @trans - transport private data | 211 | * @trans - transport private data |
212 | * @txq - tx queue | 212 | * @txq - tx queue |
213 | * @dma_dir - the direction of the DMA mapping | 213 | * @dma_dir - the direction of the DMA mapping |
214 | * | 214 | * |
215 | * Does NOT advance any TFD circular buffer read/write indexes | 215 | * Does NOT advance any TFD circular buffer read/write indexes |
216 | * Does NOT free the TFD itself (which is within circular buffer) | 216 | * Does NOT free the TFD itself (which is within circular buffer) |
217 | */ | 217 | */ |
218 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 218 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, |
219 | enum dma_data_direction dma_dir) | 219 | enum dma_data_direction dma_dir) |
220 | { | 220 | { |
221 | struct iwl_tfd *tfd_tmp = txq->tfds; | 221 | struct iwl_tfd *tfd_tmp = txq->tfds; |
222 | 222 | ||
223 | /* rd_ptr is bounded by n_bd and idx is bounded by n_window */ | 223 | /* rd_ptr is bounded by n_bd and idx is bounded by n_window */ |
224 | int rd_ptr = txq->q.read_ptr; | 224 | int rd_ptr = txq->q.read_ptr; |
225 | int idx = get_cmd_index(&txq->q, rd_ptr); | 225 | int idx = get_cmd_index(&txq->q, rd_ptr); |
226 | 226 | ||
227 | lockdep_assert_held(&txq->lock); | 227 | lockdep_assert_held(&txq->lock); |
228 | 228 | ||
229 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ | 229 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ |
230 | iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], | 230 | iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], |
231 | dma_dir); | 231 | dma_dir); |
232 | 232 | ||
233 | /* free SKB */ | 233 | /* free SKB */ |
234 | if (txq->entries) { | 234 | if (txq->entries) { |
235 | struct sk_buff *skb; | 235 | struct sk_buff *skb; |
236 | 236 | ||
237 | skb = txq->entries[idx].skb; | 237 | skb = txq->entries[idx].skb; |
238 | 238 | ||
239 | /* Can be called from irqs-disabled context | 239 | /* Can be called from irqs-disabled context |
240 | * If skb is not NULL, it means that the whole queue is being | 240 | * If skb is not NULL, it means that the whole queue is being |
241 | * freed and that the queue is not empty - free the skb | 241 | * freed and that the queue is not empty - free the skb |
242 | */ | 242 | */ |
243 | if (skb) { | 243 | if (skb) { |
244 | iwl_op_mode_free_skb(trans->op_mode, skb); | 244 | iwl_op_mode_free_skb(trans->op_mode, skb); |
245 | txq->entries[idx].skb = NULL; | 245 | txq->entries[idx].skb = NULL; |
246 | } | 246 | } |
247 | } | 247 | } |
248 | } | 248 | } |
249 | 249 | ||
250 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | 250 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, |
251 | struct iwl_tx_queue *txq, | 251 | struct iwl_tx_queue *txq, |
252 | dma_addr_t addr, u16 len, | 252 | dma_addr_t addr, u16 len, |
253 | u8 reset) | 253 | u8 reset) |
254 | { | 254 | { |
255 | struct iwl_queue *q; | 255 | struct iwl_queue *q; |
256 | struct iwl_tfd *tfd, *tfd_tmp; | 256 | struct iwl_tfd *tfd, *tfd_tmp; |
257 | u32 num_tbs; | 257 | u32 num_tbs; |
258 | 258 | ||
259 | q = &txq->q; | 259 | q = &txq->q; |
260 | tfd_tmp = txq->tfds; | 260 | tfd_tmp = txq->tfds; |
261 | tfd = &tfd_tmp[q->write_ptr]; | 261 | tfd = &tfd_tmp[q->write_ptr]; |
262 | 262 | ||
263 | if (reset) | 263 | if (reset) |
264 | memset(tfd, 0, sizeof(*tfd)); | 264 | memset(tfd, 0, sizeof(*tfd)); |
265 | 265 | ||
266 | num_tbs = iwl_tfd_get_num_tbs(tfd); | 266 | num_tbs = iwl_tfd_get_num_tbs(tfd); |
267 | 267 | ||
268 | /* Each TFD can point to a maximum 20 Tx buffers */ | 268 | /* Each TFD can point to a maximum 20 Tx buffers */ |
269 | if (num_tbs >= IWL_NUM_OF_TBS) { | 269 | if (num_tbs >= IWL_NUM_OF_TBS) { |
270 | IWL_ERR(trans, "Error can not send more than %d chunks\n", | 270 | IWL_ERR(trans, "Error can not send more than %d chunks\n", |
271 | IWL_NUM_OF_TBS); | 271 | IWL_NUM_OF_TBS); |
272 | return -EINVAL; | 272 | return -EINVAL; |
273 | } | 273 | } |
274 | 274 | ||
275 | if (WARN_ON(addr & ~DMA_BIT_MASK(36))) | 275 | if (WARN_ON(addr & ~DMA_BIT_MASK(36))) |
276 | return -EINVAL; | 276 | return -EINVAL; |
277 | 277 | ||
278 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | 278 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) |
279 | IWL_ERR(trans, "Unaligned address = %llx\n", | 279 | IWL_ERR(trans, "Unaligned address = %llx\n", |
280 | (unsigned long long)addr); | 280 | (unsigned long long)addr); |
281 | 281 | ||
282 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | 282 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); |
283 | 283 | ||
284 | return 0; | 284 | return 0; |
285 | } | 285 | } |
286 | 286 | ||
287 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** | 287 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** |
288 | * DMA services | 288 | * DMA services |
289 | * | 289 | * |
290 | * Theory of operation | 290 | * Theory of operation |
291 | * | 291 | * |
292 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer | 292 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer |
293 | * of buffer descriptors, each of which points to one or more data buffers for | 293 | * of buffer descriptors, each of which points to one or more data buffers for |
294 | * the device to read from or fill. Driver and device exchange status of each | 294 | * the device to read from or fill. Driver and device exchange status of each |
295 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | 295 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty |
296 | * entries in each circular buffer, to protect against confusing empty and full | 296 | * entries in each circular buffer, to protect against confusing empty and full |
297 | * queue states. | 297 | * queue states. |
298 | * | 298 | * |
299 | * The device reads or writes the data in the queues via the device's several | 299 | * The device reads or writes the data in the queues via the device's several |
300 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | 300 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. |
301 | * | 301 | * |
302 | * For Tx queue, there are low mark and high mark limits. If, after queuing | 302 | * For Tx queue, there are low mark and high mark limits. If, after queuing |
303 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | 303 | * the packet for Tx, free space become < low mark, Tx queue stopped. When |
304 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | 304 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, |
305 | * Tx queue resumed. | 305 | * Tx queue resumed. |
306 | * | 306 | * |
307 | ***************************************************/ | 307 | ***************************************************/ |
308 | 308 | ||
309 | int iwl_queue_space(const struct iwl_queue *q) | 309 | int iwl_queue_space(const struct iwl_queue *q) |
310 | { | 310 | { |
311 | int s = q->read_ptr - q->write_ptr; | 311 | int s = q->read_ptr - q->write_ptr; |
312 | 312 | ||
313 | if (q->read_ptr > q->write_ptr) | 313 | if (q->read_ptr > q->write_ptr) |
314 | s -= q->n_bd; | 314 | s -= q->n_bd; |
315 | 315 | ||
316 | if (s <= 0) | 316 | if (s <= 0) |
317 | s += q->n_window; | 317 | s += q->n_window; |
318 | /* keep some reserve to not confuse empty and full situations */ | 318 | /* keep some reserve to not confuse empty and full situations */ |
319 | s -= 2; | 319 | s -= 2; |
320 | if (s < 0) | 320 | if (s < 0) |
321 | s = 0; | 321 | s = 0; |
322 | return s; | 322 | return s; |
323 | } | 323 | } |
324 | 324 | ||
325 | /** | 325 | /** |
326 | * iwl_queue_init - Initialize queue's high/low-water and read/write indexes | 326 | * iwl_queue_init - Initialize queue's high/low-water and read/write indexes |
327 | */ | 327 | */ |
328 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) | 328 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) |
329 | { | 329 | { |
330 | q->n_bd = count; | 330 | q->n_bd = count; |
331 | q->n_window = slots_num; | 331 | q->n_window = slots_num; |
332 | q->id = id; | 332 | q->id = id; |
333 | 333 | ||
334 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | 334 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap |
335 | * and iwl_queue_dec_wrap are broken. */ | 335 | * and iwl_queue_dec_wrap are broken. */ |
336 | if (WARN_ON(!is_power_of_2(count))) | 336 | if (WARN_ON(!is_power_of_2(count))) |
337 | return -EINVAL; | 337 | return -EINVAL; |
338 | 338 | ||
339 | /* slots_num must be power-of-two size, otherwise | 339 | /* slots_num must be power-of-two size, otherwise |
340 | * get_cmd_index is broken. */ | 340 | * get_cmd_index is broken. */ |
341 | if (WARN_ON(!is_power_of_2(slots_num))) | 341 | if (WARN_ON(!is_power_of_2(slots_num))) |
342 | return -EINVAL; | 342 | return -EINVAL; |
343 | 343 | ||
344 | q->low_mark = q->n_window / 4; | 344 | q->low_mark = q->n_window / 4; |
345 | if (q->low_mark < 4) | 345 | if (q->low_mark < 4) |
346 | q->low_mark = 4; | 346 | q->low_mark = 4; |
347 | 347 | ||
348 | q->high_mark = q->n_window / 8; | 348 | q->high_mark = q->n_window / 8; |
349 | if (q->high_mark < 2) | 349 | if (q->high_mark < 2) |
350 | q->high_mark = 2; | 350 | q->high_mark = 2; |
351 | 351 | ||
352 | q->write_ptr = q->read_ptr = 0; | 352 | q->write_ptr = q->read_ptr = 0; |
353 | 353 | ||
354 | return 0; | 354 | return 0; |
355 | } | 355 | } |
356 | 356 | ||
357 | static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, | 357 | static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, |
358 | struct iwl_tx_queue *txq) | 358 | struct iwl_tx_queue *txq) |
359 | { | 359 | { |
360 | struct iwl_trans_pcie *trans_pcie = | 360 | struct iwl_trans_pcie *trans_pcie = |
361 | IWL_TRANS_GET_PCIE_TRANS(trans); | 361 | IWL_TRANS_GET_PCIE_TRANS(trans); |
362 | struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; | 362 | struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; |
363 | int txq_id = txq->q.id; | 363 | int txq_id = txq->q.id; |
364 | int read_ptr = txq->q.read_ptr; | 364 | int read_ptr = txq->q.read_ptr; |
365 | u8 sta_id = 0; | 365 | u8 sta_id = 0; |
366 | __le16 bc_ent; | 366 | __le16 bc_ent; |
367 | struct iwl_tx_cmd *tx_cmd = | 367 | struct iwl_tx_cmd *tx_cmd = |
368 | (void *)txq->entries[txq->q.read_ptr].cmd->payload; | 368 | (void *)txq->entries[txq->q.read_ptr].cmd->payload; |
369 | 369 | ||
370 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); | 370 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); |
371 | 371 | ||
372 | if (txq_id != trans_pcie->cmd_queue) | 372 | if (txq_id != trans_pcie->cmd_queue) |
373 | sta_id = tx_cmd->sta_id; | 373 | sta_id = tx_cmd->sta_id; |
374 | 374 | ||
375 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); | 375 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); |
376 | scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; | 376 | scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; |
377 | 377 | ||
378 | if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) | 378 | if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) |
379 | scd_bc_tbl[txq_id]. | 379 | scd_bc_tbl[txq_id]. |
380 | tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; | 380 | tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; |
381 | } | 381 | } |
382 | 382 | ||
383 | static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | 383 | static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, |
384 | u16 txq_id) | 384 | u16 txq_id) |
385 | { | 385 | { |
386 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 386 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
387 | u32 tbl_dw_addr; | 387 | u32 tbl_dw_addr; |
388 | u32 tbl_dw; | 388 | u32 tbl_dw; |
389 | u16 scd_q2ratid; | 389 | u16 scd_q2ratid; |
390 | 390 | ||
391 | scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK; | 391 | scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK; |
392 | 392 | ||
393 | tbl_dw_addr = trans_pcie->scd_base_addr + | 393 | tbl_dw_addr = trans_pcie->scd_base_addr + |
394 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); | 394 | SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); |
395 | 395 | ||
396 | tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); | 396 | tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); |
397 | 397 | ||
398 | if (txq_id & 0x1) | 398 | if (txq_id & 0x1) |
399 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); | 399 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); |
400 | else | 400 | else |
401 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); | 401 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); |
402 | 402 | ||
403 | iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); | 403 | iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); |
404 | 404 | ||
405 | return 0; | 405 | return 0; |
406 | } | 406 | } |
407 | 407 | ||
408 | static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) | 408 | static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) |
409 | { | 409 | { |
410 | /* Simply stop the queue, but don't change any configuration; | 410 | /* Simply stop the queue, but don't change any configuration; |
411 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | 411 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ |
412 | iwl_write_prph(trans, | 412 | iwl_write_prph(trans, |
413 | SCD_QUEUE_STATUS_BITS(txq_id), | 413 | SCD_QUEUE_STATUS_BITS(txq_id), |
414 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | 414 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| |
415 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | 415 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); |
416 | } | 416 | } |
417 | 417 | ||
418 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | 418 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, |
419 | int sta_id, int tid, int frame_limit, u16 ssn) | 419 | int sta_id, int tid, int frame_limit, u16 ssn) |
420 | { | 420 | { |
421 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 421 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
422 | 422 | ||
423 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) | 423 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) |
424 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 424 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
425 | 425 | ||
426 | /* Stop this Tx queue before configuring it */ | 426 | /* Stop this Tx queue before configuring it */ |
427 | iwl_txq_set_inactive(trans, txq_id); | 427 | iwl_txq_set_inactive(trans, txq_id); |
428 | 428 | ||
429 | /* Set this queue as a chain-building queue unless it is CMD queue */ | 429 | /* Set this queue as a chain-building queue unless it is CMD queue */ |
430 | if (txq_id != trans_pcie->cmd_queue) | 430 | if (txq_id != trans_pcie->cmd_queue) |
431 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 431 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); |
432 | 432 | ||
433 | /* If this queue is mapped to a certain station: it is an AGG queue */ | 433 | /* If this queue is mapped to a certain station: it is an AGG queue */ |
434 | if (sta_id != IWL_INVALID_STATION) { | 434 | if (sta_id != IWL_INVALID_STATION) { |
435 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | 435 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); |
436 | 436 | ||
437 | /* Map receiver-address / traffic-ID to this queue */ | 437 | /* Map receiver-address / traffic-ID to this queue */ |
438 | iwl_txq_set_ratid_map(trans, ra_tid, txq_id); | 438 | iwl_txq_set_ratid_map(trans, ra_tid, txq_id); |
439 | 439 | ||
440 | /* enable aggregations for the queue */ | 440 | /* enable aggregations for the queue */ |
441 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 441 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); |
442 | } else { | 442 | } else { |
443 | /* | 443 | /* |
444 | * disable aggregations for the queue, this will also make the | 444 | * disable aggregations for the queue, this will also make the |
445 | * ra_tid mapping configuration irrelevant since it is now a | 445 | * ra_tid mapping configuration irrelevant since it is now a |
446 | * non-AGG queue. | 446 | * non-AGG queue. |
447 | */ | 447 | */ |
448 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 448 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); |
449 | } | 449 | } |
450 | 450 | ||
451 | /* Place first TFD at index corresponding to start sequence number. | 451 | /* Place first TFD at index corresponding to start sequence number. |
452 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | 452 | * Assumes that ssn_idx is valid (!= 0xFFF) */ |
453 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); | 453 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); |
454 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); | 454 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); |
455 | 455 | ||
456 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 456 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
457 | (ssn & 0xff) | (txq_id << 8)); | 457 | (ssn & 0xff) | (txq_id << 8)); |
458 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 458 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); |
459 | 459 | ||
460 | /* Set up Tx window size and frame limit for this queue */ | 460 | /* Set up Tx window size and frame limit for this queue */ |
461 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 461 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
462 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 462 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
463 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 463 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
464 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 464 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
465 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 465 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
466 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 466 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
467 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 467 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
468 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 468 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
469 | 469 | ||
470 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 470 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ |
471 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), | 471 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), |
472 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 472 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
473 | (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | | 473 | (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | |
474 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | | 474 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | |
475 | SCD_QUEUE_STTS_REG_MSK); | 475 | SCD_QUEUE_STTS_REG_MSK); |
476 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", | 476 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", |
477 | txq_id, fifo, ssn & 0xff); | 477 | txq_id, fifo, ssn & 0xff); |
478 | } | 478 | } |
479 | 479 | ||
480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) |
481 | { | 481 | { |
482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
483 | u16 rd_ptr, wr_ptr; | 483 | u16 rd_ptr, wr_ptr; |
484 | int n_bd = trans_pcie->txq[txq_id].q.n_bd; | 484 | int n_bd = trans_pcie->txq[txq_id].q.n_bd; |
485 | 485 | ||
486 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { | 486 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { |
487 | WARN_ONCE(1, "queue %d not used", txq_id); | 487 | WARN_ONCE(1, "queue %d not used", txq_id); |
488 | return; | 488 | return; |
489 | } | 489 | } |
490 | 490 | ||
491 | rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); | 491 | rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); |
492 | wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); | 492 | wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); |
493 | 493 | ||
494 | WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", | 494 | WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", |
495 | txq_id, rd_ptr, wr_ptr); | 495 | txq_id, rd_ptr, wr_ptr); |
496 | 496 | ||
497 | iwl_txq_set_inactive(trans, txq_id); | 497 | iwl_txq_set_inactive(trans, txq_id); |
498 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 498 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
499 | } | 499 | } |
500 | 500 | ||
501 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ | 501 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ |
502 | 502 | ||
503 | /** | 503 | /** |
504 | * iwl_enqueue_hcmd - enqueue a uCode command | 504 | * iwl_enqueue_hcmd - enqueue a uCode command |
505 | * @priv: device private data point | 505 | * @priv: device private data point |
506 | * @cmd: a point to the ucode command structure | 506 | * @cmd: a point to the ucode command structure |
507 | * | 507 | * |
508 | * The function returns < 0 values to indicate the operation is | 508 | * The function returns < 0 values to indicate the operation is |
509 | * failed. On success, it turns the index (> 0) of command in the | 509 | * failed. On success, it turns the index (> 0) of command in the |
510 | * command queue. | 510 | * command queue. |
511 | */ | 511 | */ |
512 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 512 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
513 | { | 513 | { |
514 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 514 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
515 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 515 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
516 | struct iwl_queue *q = &txq->q; | 516 | struct iwl_queue *q = &txq->q; |
517 | struct iwl_device_cmd *out_cmd; | 517 | struct iwl_device_cmd *out_cmd; |
518 | struct iwl_cmd_meta *out_meta; | 518 | struct iwl_cmd_meta *out_meta; |
519 | dma_addr_t phys_addr; | 519 | dma_addr_t phys_addr; |
520 | u32 idx; | 520 | u32 idx; |
521 | u16 copy_size, cmd_size; | 521 | u16 copy_size, cmd_size; |
522 | bool had_nocopy = false; | 522 | bool had_nocopy = false; |
523 | int i; | 523 | int i; |
524 | u32 cmd_pos; | 524 | u32 cmd_pos; |
525 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
526 | const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {}; | ||
527 | int trace_lens[IWL_MAX_CMD_TFDS + 1] = {}; | ||
528 | int trace_idx; | ||
529 | #endif | ||
530 | 525 | ||
531 | copy_size = sizeof(out_cmd->hdr); | 526 | copy_size = sizeof(out_cmd->hdr); |
532 | cmd_size = sizeof(out_cmd->hdr); | 527 | cmd_size = sizeof(out_cmd->hdr); |
533 | 528 | ||
534 | /* need one for the header if the first is NOCOPY */ | 529 | /* need one for the header if the first is NOCOPY */ |
535 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); | 530 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); |
536 | 531 | ||
537 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 532 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
538 | if (!cmd->len[i]) | 533 | if (!cmd->len[i]) |
539 | continue; | 534 | continue; |
540 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { | 535 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { |
541 | had_nocopy = true; | 536 | had_nocopy = true; |
542 | } else { | 537 | } else { |
543 | /* NOCOPY must not be followed by normal! */ | 538 | /* NOCOPY must not be followed by normal! */ |
544 | if (WARN_ON(had_nocopy)) | 539 | if (WARN_ON(had_nocopy)) |
545 | return -EINVAL; | 540 | return -EINVAL; |
546 | copy_size += cmd->len[i]; | 541 | copy_size += cmd->len[i]; |
547 | } | 542 | } |
548 | cmd_size += cmd->len[i]; | 543 | cmd_size += cmd->len[i]; |
549 | } | 544 | } |
550 | 545 | ||
551 | /* | 546 | /* |
552 | * If any of the command structures end up being larger than | 547 | * If any of the command structures end up being larger than |
553 | * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically | 548 | * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically |
554 | * allocated into separate TFDs, then we will need to | 549 | * allocated into separate TFDs, then we will need to |
555 | * increase the size of the buffers. | 550 | * increase the size of the buffers. |
556 | */ | 551 | */ |
557 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) | 552 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) |
558 | return -EINVAL; | 553 | return -EINVAL; |
559 | 554 | ||
560 | spin_lock_bh(&txq->lock); | 555 | spin_lock_bh(&txq->lock); |
561 | 556 | ||
562 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 557 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
563 | spin_unlock_bh(&txq->lock); | 558 | spin_unlock_bh(&txq->lock); |
564 | 559 | ||
565 | IWL_ERR(trans, "No space in command queue\n"); | 560 | IWL_ERR(trans, "No space in command queue\n"); |
566 | iwl_op_mode_cmd_queue_full(trans->op_mode); | 561 | iwl_op_mode_cmd_queue_full(trans->op_mode); |
567 | return -ENOSPC; | 562 | return -ENOSPC; |
568 | } | 563 | } |
569 | 564 | ||
570 | idx = get_cmd_index(q, q->write_ptr); | 565 | idx = get_cmd_index(q, q->write_ptr); |
571 | out_cmd = txq->entries[idx].cmd; | 566 | out_cmd = txq->entries[idx].cmd; |
572 | out_meta = &txq->entries[idx].meta; | 567 | out_meta = &txq->entries[idx].meta; |
573 | 568 | ||
574 | memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ | 569 | memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ |
575 | if (cmd->flags & CMD_WANT_SKB) | 570 | if (cmd->flags & CMD_WANT_SKB) |
576 | out_meta->source = cmd; | 571 | out_meta->source = cmd; |
577 | 572 | ||
578 | /* set up the header */ | 573 | /* set up the header */ |
579 | 574 | ||
580 | out_cmd->hdr.cmd = cmd->id; | 575 | out_cmd->hdr.cmd = cmd->id; |
581 | out_cmd->hdr.flags = 0; | 576 | out_cmd->hdr.flags = 0; |
582 | out_cmd->hdr.sequence = | 577 | out_cmd->hdr.sequence = |
583 | cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | | 578 | cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | |
584 | INDEX_TO_SEQ(q->write_ptr)); | 579 | INDEX_TO_SEQ(q->write_ptr)); |
585 | 580 | ||
586 | /* and copy the data that needs to be copied */ | 581 | /* and copy the data that needs to be copied */ |
587 | cmd_pos = offsetof(struct iwl_device_cmd, payload); | 582 | cmd_pos = offsetof(struct iwl_device_cmd, payload); |
588 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 583 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
589 | if (!cmd->len[i]) | 584 | if (!cmd->len[i]) |
590 | continue; | 585 | continue; |
591 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) | 586 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) |
592 | break; | 587 | break; |
593 | memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); | 588 | memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); |
594 | cmd_pos += cmd->len[i]; | 589 | cmd_pos += cmd->len[i]; |
595 | } | 590 | } |
596 | 591 | ||
597 | WARN_ON_ONCE(txq->entries[idx].copy_cmd); | 592 | WARN_ON_ONCE(txq->entries[idx].copy_cmd); |
598 | 593 | ||
599 | /* | 594 | /* |
600 | * since out_cmd will be the source address of the FH, it will write | 595 | * since out_cmd will be the source address of the FH, it will write |
601 | * the retry count there. So when the user needs to receivce the HCMD | 596 | * the retry count there. So when the user needs to receivce the HCMD |
602 | * that corresponds to the response in the response handler, it needs | 597 | * that corresponds to the response in the response handler, it needs |
603 | * to set CMD_WANT_HCMD. | 598 | * to set CMD_WANT_HCMD. |
604 | */ | 599 | */ |
605 | if (cmd->flags & CMD_WANT_HCMD) { | 600 | if (cmd->flags & CMD_WANT_HCMD) { |
606 | txq->entries[idx].copy_cmd = | 601 | txq->entries[idx].copy_cmd = |
607 | kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); | 602 | kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); |
608 | if (unlikely(!txq->entries[idx].copy_cmd)) { | 603 | if (unlikely(!txq->entries[idx].copy_cmd)) { |
609 | idx = -ENOMEM; | 604 | idx = -ENOMEM; |
610 | goto out; | 605 | goto out; |
611 | } | 606 | } |
612 | } | 607 | } |
613 | 608 | ||
614 | IWL_DEBUG_HC(trans, | 609 | IWL_DEBUG_HC(trans, |
615 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", | 610 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", |
616 | trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), | 611 | trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), |
617 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), | 612 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), |
618 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); | 613 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); |
619 | 614 | ||
620 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, | 615 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, |
621 | DMA_BIDIRECTIONAL); | 616 | DMA_BIDIRECTIONAL); |
622 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { | 617 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { |
623 | idx = -ENOMEM; | 618 | idx = -ENOMEM; |
624 | goto out; | 619 | goto out; |
625 | } | 620 | } |
626 | 621 | ||
627 | dma_unmap_addr_set(out_meta, mapping, phys_addr); | 622 | dma_unmap_addr_set(out_meta, mapping, phys_addr); |
628 | dma_unmap_len_set(out_meta, len, copy_size); | 623 | dma_unmap_len_set(out_meta, len, copy_size); |
629 | 624 | ||
630 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); | 625 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); |
631 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
632 | trace_bufs[0] = &out_cmd->hdr; | ||
633 | trace_lens[0] = copy_size; | ||
634 | trace_idx = 1; | ||
635 | #endif | ||
636 | 626 | ||
637 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 627 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
638 | if (!cmd->len[i]) | 628 | if (!cmd->len[i]) |
639 | continue; | 629 | continue; |
640 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | 630 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) |
641 | continue; | 631 | continue; |
642 | phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], | 632 | phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], |
643 | cmd->len[i], DMA_BIDIRECTIONAL); | 633 | cmd->len[i], DMA_BIDIRECTIONAL); |
644 | if (dma_mapping_error(trans->dev, phys_addr)) { | 634 | if (dma_mapping_error(trans->dev, phys_addr)) { |
645 | iwl_unmap_tfd(trans, out_meta, | 635 | iwl_unmap_tfd(trans, out_meta, |
646 | &txq->tfds[q->write_ptr], | 636 | &txq->tfds[q->write_ptr], |
647 | DMA_BIDIRECTIONAL); | 637 | DMA_BIDIRECTIONAL); |
648 | idx = -ENOMEM; | 638 | idx = -ENOMEM; |
649 | goto out; | 639 | goto out; |
650 | } | 640 | } |
651 | 641 | ||
652 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, | 642 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, |
653 | cmd->len[i], 0); | 643 | cmd->len[i], 0); |
654 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
655 | trace_bufs[trace_idx] = cmd->data[i]; | ||
656 | trace_lens[trace_idx] = cmd->len[i]; | ||
657 | trace_idx++; | ||
658 | #endif | ||
659 | } | 644 | } |
660 | 645 | ||
661 | out_meta->flags = cmd->flags; | 646 | out_meta->flags = cmd->flags; |
662 | 647 | ||
663 | txq->need_update = 1; | 648 | txq->need_update = 1; |
664 | 649 | ||
665 | /* check that tracing gets all possible blocks */ | 650 | trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, |
666 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); | 651 | &out_cmd->hdr, copy_size); |
667 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | ||
668 | trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags, | ||
669 | trace_bufs[0], trace_lens[0], | ||
670 | trace_bufs[1], trace_lens[1], | ||
671 | trace_bufs[2], trace_lens[2]); | ||
672 | #endif | ||
673 | 652 | ||
674 | /* start timer if queue currently empty */ | 653 | /* start timer if queue currently empty */ |
675 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) | 654 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) |
676 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | 655 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); |
677 | 656 | ||
678 | /* Increment and update queue's write index */ | 657 | /* Increment and update queue's write index */ |
679 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 658 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
680 | iwl_txq_update_write_ptr(trans, txq); | 659 | iwl_txq_update_write_ptr(trans, txq); |
681 | 660 | ||
682 | out: | 661 | out: |
683 | spin_unlock_bh(&txq->lock); | 662 | spin_unlock_bh(&txq->lock); |
684 | return idx; | 663 | return idx; |
685 | } | 664 | } |
686 | 665 | ||
687 | static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie, | 666 | static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie, |
688 | struct iwl_tx_queue *txq) | 667 | struct iwl_tx_queue *txq) |
689 | { | 668 | { |
690 | if (!trans_pcie->wd_timeout) | 669 | if (!trans_pcie->wd_timeout) |
691 | return; | 670 | return; |
692 | 671 | ||
693 | /* | 672 | /* |
694 | * if empty delete timer, otherwise move timer forward | 673 | * if empty delete timer, otherwise move timer forward |
695 | * since we're making progress on this queue | 674 | * since we're making progress on this queue |
696 | */ | 675 | */ |
697 | if (txq->q.read_ptr == txq->q.write_ptr) | 676 | if (txq->q.read_ptr == txq->q.write_ptr) |
698 | del_timer(&txq->stuck_timer); | 677 | del_timer(&txq->stuck_timer); |
699 | else | 678 | else |
700 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | 679 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); |
701 | } | 680 | } |
702 | 681 | ||
703 | /** | 682 | /** |
704 | * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd | 683 | * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd |
705 | * | 684 | * |
706 | * When FW advances 'R' index, all entries between old and new 'R' index | 685 | * When FW advances 'R' index, all entries between old and new 'R' index |
707 | * need to be reclaimed. As result, some free space forms. If there is | 686 | * need to be reclaimed. As result, some free space forms. If there is |
708 | * enough free space (> low mark), wake the stack that feeds us. | 687 | * enough free space (> low mark), wake the stack that feeds us. |
709 | */ | 688 | */ |
710 | static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | 689 | static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, |
711 | int idx) | 690 | int idx) |
712 | { | 691 | { |
713 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 692 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
714 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 693 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
715 | struct iwl_queue *q = &txq->q; | 694 | struct iwl_queue *q = &txq->q; |
716 | int nfreed = 0; | 695 | int nfreed = 0; |
717 | 696 | ||
718 | lockdep_assert_held(&txq->lock); | 697 | lockdep_assert_held(&txq->lock); |
719 | 698 | ||
720 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | 699 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { |
721 | IWL_ERR(trans, | 700 | IWL_ERR(trans, |
722 | "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", | 701 | "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", |
723 | __func__, txq_id, idx, q->n_bd, | 702 | __func__, txq_id, idx, q->n_bd, |
724 | q->write_ptr, q->read_ptr); | 703 | q->write_ptr, q->read_ptr); |
725 | return; | 704 | return; |
726 | } | 705 | } |
727 | 706 | ||
728 | for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; | 707 | for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; |
729 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 708 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
730 | 709 | ||
731 | if (nfreed++ > 0) { | 710 | if (nfreed++ > 0) { |
732 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", | 711 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", |
733 | idx, q->write_ptr, q->read_ptr); | 712 | idx, q->write_ptr, q->read_ptr); |
734 | iwl_op_mode_nic_error(trans->op_mode); | 713 | iwl_op_mode_nic_error(trans->op_mode); |
735 | } | 714 | } |
736 | 715 | ||
737 | } | 716 | } |
738 | 717 | ||
739 | iwl_queue_progress(trans_pcie, txq); | 718 | iwl_queue_progress(trans_pcie, txq); |
740 | } | 719 | } |
741 | 720 | ||
742 | /** | 721 | /** |
743 | * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them | 722 | * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them |
744 | * @rxb: Rx buffer to reclaim | 723 | * @rxb: Rx buffer to reclaim |
745 | * @handler_status: return value of the handler of the command | 724 | * @handler_status: return value of the handler of the command |
746 | * (put in setup_rx_handlers) | 725 | * (put in setup_rx_handlers) |
747 | * | 726 | * |
748 | * If an Rx buffer has an async callback associated with it the callback | 727 | * If an Rx buffer has an async callback associated with it the callback |
749 | * will be executed. The attached skb (if present) will only be freed | 728 | * will be executed. The attached skb (if present) will only be freed |
750 | * if the callback returns 1 | 729 | * if the callback returns 1 |
751 | */ | 730 | */ |
752 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | 731 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, |
753 | int handler_status) | 732 | int handler_status) |
754 | { | 733 | { |
755 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 734 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
756 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 735 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
757 | int txq_id = SEQ_TO_QUEUE(sequence); | 736 | int txq_id = SEQ_TO_QUEUE(sequence); |
758 | int index = SEQ_TO_INDEX(sequence); | 737 | int index = SEQ_TO_INDEX(sequence); |
759 | int cmd_index; | 738 | int cmd_index; |
760 | struct iwl_device_cmd *cmd; | 739 | struct iwl_device_cmd *cmd; |
761 | struct iwl_cmd_meta *meta; | 740 | struct iwl_cmd_meta *meta; |
762 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 741 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
763 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 742 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
764 | 743 | ||
765 | /* If a Tx command is being handled and it isn't in the actual | 744 | /* If a Tx command is being handled and it isn't in the actual |
766 | * command queue then there a command routing bug has been introduced | 745 | * command queue then there a command routing bug has been introduced |
767 | * in the queue management code. */ | 746 | * in the queue management code. */ |
768 | if (WARN(txq_id != trans_pcie->cmd_queue, | 747 | if (WARN(txq_id != trans_pcie->cmd_queue, |
769 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", | 748 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", |
770 | txq_id, trans_pcie->cmd_queue, sequence, | 749 | txq_id, trans_pcie->cmd_queue, sequence, |
771 | trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, | 750 | trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, |
772 | trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { | 751 | trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { |
773 | iwl_print_hex_error(trans, pkt, 32); | 752 | iwl_print_hex_error(trans, pkt, 32); |
774 | return; | 753 | return; |
775 | } | 754 | } |
776 | 755 | ||
777 | spin_lock(&txq->lock); | 756 | spin_lock(&txq->lock); |
778 | 757 | ||
779 | cmd_index = get_cmd_index(&txq->q, index); | 758 | cmd_index = get_cmd_index(&txq->q, index); |
780 | cmd = txq->entries[cmd_index].cmd; | 759 | cmd = txq->entries[cmd_index].cmd; |
781 | meta = &txq->entries[cmd_index].meta; | 760 | meta = &txq->entries[cmd_index].meta; |
782 | 761 | ||
783 | iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); | 762 | iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); |
784 | 763 | ||
785 | /* Input error checking is done when commands are added to queue. */ | 764 | /* Input error checking is done when commands are added to queue. */ |
786 | if (meta->flags & CMD_WANT_SKB) { | 765 | if (meta->flags & CMD_WANT_SKB) { |
787 | struct page *p = rxb_steal_page(rxb); | 766 | struct page *p = rxb_steal_page(rxb); |
788 | 767 | ||
789 | meta->source->resp_pkt = pkt; | 768 | meta->source->resp_pkt = pkt; |
790 | meta->source->_rx_page_addr = (unsigned long)page_address(p); | 769 | meta->source->_rx_page_addr = (unsigned long)page_address(p); |
791 | meta->source->_rx_page_order = trans_pcie->rx_page_order; | 770 | meta->source->_rx_page_order = trans_pcie->rx_page_order; |
792 | meta->source->handler_status = handler_status; | 771 | meta->source->handler_status = handler_status; |
793 | } | 772 | } |
794 | 773 | ||
795 | iwl_hcmd_queue_reclaim(trans, txq_id, index); | 774 | iwl_hcmd_queue_reclaim(trans, txq_id, index); |
796 | 775 | ||
797 | if (!(meta->flags & CMD_ASYNC)) { | 776 | if (!(meta->flags & CMD_ASYNC)) { |
798 | if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 777 | if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
799 | IWL_WARN(trans, | 778 | IWL_WARN(trans, |
800 | "HCMD_ACTIVE already clear for command %s\n", | 779 | "HCMD_ACTIVE already clear for command %s\n", |
801 | trans_pcie_get_cmd_string(trans_pcie, | 780 | trans_pcie_get_cmd_string(trans_pcie, |
802 | cmd->hdr.cmd)); | 781 | cmd->hdr.cmd)); |
803 | } | 782 | } |
804 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 783 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
805 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", | 784 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", |
806 | trans_pcie_get_cmd_string(trans_pcie, | 785 | trans_pcie_get_cmd_string(trans_pcie, |
807 | cmd->hdr.cmd)); | 786 | cmd->hdr.cmd)); |
808 | wake_up(&trans->wait_command_queue); | 787 | wake_up(&trans->wait_command_queue); |
809 | } | 788 | } |
810 | 789 | ||
811 | meta->flags = 0; | 790 | meta->flags = 0; |
812 | 791 | ||
813 | spin_unlock(&txq->lock); | 792 | spin_unlock(&txq->lock); |
814 | } | 793 | } |
815 | 794 | ||
816 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 795 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
817 | 796 | ||
818 | static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 797 | static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
819 | { | 798 | { |
820 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 799 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
821 | int ret; | 800 | int ret; |
822 | 801 | ||
823 | /* An asynchronous command can not expect an SKB to be set. */ | 802 | /* An asynchronous command can not expect an SKB to be set. */ |
824 | if (WARN_ON(cmd->flags & CMD_WANT_SKB)) | 803 | if (WARN_ON(cmd->flags & CMD_WANT_SKB)) |
825 | return -EINVAL; | 804 | return -EINVAL; |
826 | 805 | ||
827 | 806 | ||
828 | ret = iwl_enqueue_hcmd(trans, cmd); | 807 | ret = iwl_enqueue_hcmd(trans, cmd); |
829 | if (ret < 0) { | 808 | if (ret < 0) { |
830 | IWL_ERR(trans, | 809 | IWL_ERR(trans, |
831 | "Error sending %s: enqueue_hcmd failed: %d\n", | 810 | "Error sending %s: enqueue_hcmd failed: %d\n", |
832 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); | 811 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); |
833 | return ret; | 812 | return ret; |
834 | } | 813 | } |
835 | return 0; | 814 | return 0; |
836 | } | 815 | } |
837 | 816 | ||
838 | static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 817 | static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
839 | { | 818 | { |
840 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 819 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
841 | int cmd_idx; | 820 | int cmd_idx; |
842 | int ret; | 821 | int ret; |
843 | 822 | ||
844 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 823 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
845 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 824 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
846 | 825 | ||
847 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, | 826 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, |
848 | &trans_pcie->status))) { | 827 | &trans_pcie->status))) { |
849 | IWL_ERR(trans, "Command %s: a command is already active!\n", | 828 | IWL_ERR(trans, "Command %s: a command is already active!\n", |
850 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 829 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
851 | return -EIO; | 830 | return -EIO; |
852 | } | 831 | } |
853 | 832 | ||
854 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 833 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
855 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 834 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
856 | 835 | ||
857 | cmd_idx = iwl_enqueue_hcmd(trans, cmd); | 836 | cmd_idx = iwl_enqueue_hcmd(trans, cmd); |
858 | if (cmd_idx < 0) { | 837 | if (cmd_idx < 0) { |
859 | ret = cmd_idx; | 838 | ret = cmd_idx; |
860 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 839 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
861 | IWL_ERR(trans, | 840 | IWL_ERR(trans, |
862 | "Error sending %s: enqueue_hcmd failed: %d\n", | 841 | "Error sending %s: enqueue_hcmd failed: %d\n", |
863 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); | 842 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); |
864 | return ret; | 843 | return ret; |
865 | } | 844 | } |
866 | 845 | ||
867 | ret = wait_event_timeout(trans->wait_command_queue, | 846 | ret = wait_event_timeout(trans->wait_command_queue, |
868 | !test_bit(STATUS_HCMD_ACTIVE, | 847 | !test_bit(STATUS_HCMD_ACTIVE, |
869 | &trans_pcie->status), | 848 | &trans_pcie->status), |
870 | HOST_COMPLETE_TIMEOUT); | 849 | HOST_COMPLETE_TIMEOUT); |
871 | if (!ret) { | 850 | if (!ret) { |
872 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 851 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
873 | struct iwl_tx_queue *txq = | 852 | struct iwl_tx_queue *txq = |
874 | &trans_pcie->txq[trans_pcie->cmd_queue]; | 853 | &trans_pcie->txq[trans_pcie->cmd_queue]; |
875 | struct iwl_queue *q = &txq->q; | 854 | struct iwl_queue *q = &txq->q; |
876 | 855 | ||
877 | IWL_ERR(trans, | 856 | IWL_ERR(trans, |
878 | "Error sending %s: time out after %dms.\n", | 857 | "Error sending %s: time out after %dms.\n", |
879 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), | 858 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), |
880 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 859 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
881 | 860 | ||
882 | IWL_ERR(trans, | 861 | IWL_ERR(trans, |
883 | "Current CMD queue read_ptr %d write_ptr %d\n", | 862 | "Current CMD queue read_ptr %d write_ptr %d\n", |
884 | q->read_ptr, q->write_ptr); | 863 | q->read_ptr, q->write_ptr); |
885 | 864 | ||
886 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 865 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
887 | IWL_DEBUG_INFO(trans, | 866 | IWL_DEBUG_INFO(trans, |
888 | "Clearing HCMD_ACTIVE for command %s\n", | 867 | "Clearing HCMD_ACTIVE for command %s\n", |
889 | trans_pcie_get_cmd_string(trans_pcie, | 868 | trans_pcie_get_cmd_string(trans_pcie, |
890 | cmd->id)); | 869 | cmd->id)); |
891 | ret = -ETIMEDOUT; | 870 | ret = -ETIMEDOUT; |
892 | goto cancel; | 871 | goto cancel; |
893 | } | 872 | } |
894 | } | 873 | } |
895 | 874 | ||
896 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { | 875 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { |
897 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 876 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
898 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 877 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
899 | ret = -EIO; | 878 | ret = -EIO; |
900 | goto cancel; | 879 | goto cancel; |
901 | } | 880 | } |
902 | 881 | ||
903 | return 0; | 882 | return 0; |
904 | 883 | ||
905 | cancel: | 884 | cancel: |
906 | if (cmd->flags & CMD_WANT_SKB) { | 885 | if (cmd->flags & CMD_WANT_SKB) { |
907 | /* | 886 | /* |
908 | * Cancel the CMD_WANT_SKB flag for the cmd in the | 887 | * Cancel the CMD_WANT_SKB flag for the cmd in the |
909 | * TX cmd queue. Otherwise in case the cmd comes | 888 | * TX cmd queue. Otherwise in case the cmd comes |
910 | * in later, it will possibly set an invalid | 889 | * in later, it will possibly set an invalid |
911 | * address (cmd->meta.source). | 890 | * address (cmd->meta.source). |
912 | */ | 891 | */ |
913 | trans_pcie->txq[trans_pcie->cmd_queue]. | 892 | trans_pcie->txq[trans_pcie->cmd_queue]. |
914 | entries[cmd_idx].meta.flags &= ~CMD_WANT_SKB; | 893 | entries[cmd_idx].meta.flags &= ~CMD_WANT_SKB; |
915 | } | 894 | } |
916 | 895 | ||
917 | if (cmd->resp_pkt) { | 896 | if (cmd->resp_pkt) { |
918 | iwl_free_resp(cmd); | 897 | iwl_free_resp(cmd); |
919 | cmd->resp_pkt = NULL; | 898 | cmd->resp_pkt = NULL; |
920 | } | 899 | } |
921 | 900 | ||
922 | return ret; | 901 | return ret; |
923 | } | 902 | } |
924 | 903 | ||
925 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 904 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
926 | { | 905 | { |
927 | if (cmd->flags & CMD_ASYNC) | 906 | if (cmd->flags & CMD_ASYNC) |
928 | return iwl_send_cmd_async(trans, cmd); | 907 | return iwl_send_cmd_async(trans, cmd); |
929 | 908 | ||
930 | return iwl_send_cmd_sync(trans, cmd); | 909 | return iwl_send_cmd_sync(trans, cmd); |
931 | } | 910 | } |
932 | 911 | ||
933 | /* Frees buffers until index _not_ inclusive */ | 912 | /* Frees buffers until index _not_ inclusive */ |
934 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | 913 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, |
935 | struct sk_buff_head *skbs) | 914 | struct sk_buff_head *skbs) |
936 | { | 915 | { |
937 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 916 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
938 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 917 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
939 | struct iwl_queue *q = &txq->q; | 918 | struct iwl_queue *q = &txq->q; |
940 | int last_to_free; | 919 | int last_to_free; |
941 | int freed = 0; | 920 | int freed = 0; |
942 | 921 | ||
943 | /* This function is not meant to release cmd queue*/ | 922 | /* This function is not meant to release cmd queue*/ |
944 | if (WARN_ON(txq_id == trans_pcie->cmd_queue)) | 923 | if (WARN_ON(txq_id == trans_pcie->cmd_queue)) |
945 | return 0; | 924 | return 0; |
946 | 925 | ||
947 | lockdep_assert_held(&txq->lock); | 926 | lockdep_assert_held(&txq->lock); |
948 | 927 | ||
949 | /*Since we free until index _not_ inclusive, the one before index is | 928 | /*Since we free until index _not_ inclusive, the one before index is |
950 | * the last we will free. This one must be used */ | 929 | * the last we will free. This one must be used */ |
951 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); | 930 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); |
952 | 931 | ||
953 | if ((index >= q->n_bd) || | 932 | if ((index >= q->n_bd) || |
954 | (iwl_queue_used(q, last_to_free) == 0)) { | 933 | (iwl_queue_used(q, last_to_free) == 0)) { |
955 | IWL_ERR(trans, | 934 | IWL_ERR(trans, |
956 | "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", | 935 | "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", |
957 | __func__, txq_id, last_to_free, q->n_bd, | 936 | __func__, txq_id, last_to_free, q->n_bd, |
958 | q->write_ptr, q->read_ptr); | 937 | q->write_ptr, q->read_ptr); |
959 | return 0; | 938 | return 0; |
960 | } | 939 | } |
961 | 940 | ||
962 | if (WARN_ON(!skb_queue_empty(skbs))) | 941 | if (WARN_ON(!skb_queue_empty(skbs))) |
963 | return 0; | 942 | return 0; |
964 | 943 | ||
965 | for (; | 944 | for (; |
966 | q->read_ptr != index; | 945 | q->read_ptr != index; |
967 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 946 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
968 | 947 | ||
969 | if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) | 948 | if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) |
970 | continue; | 949 | continue; |
971 | 950 | ||
972 | __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); | 951 | __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); |
973 | 952 | ||
974 | txq->entries[txq->q.read_ptr].skb = NULL; | 953 | txq->entries[txq->q.read_ptr].skb = NULL; |
975 | 954 | ||
976 | iwlagn_txq_inval_byte_cnt_tbl(trans, txq); | 955 | iwlagn_txq_inval_byte_cnt_tbl(trans, txq); |
977 | 956 | ||
978 | iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); | 957 | iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); |
979 | freed++; | 958 | freed++; |
980 | } | 959 | } |
981 | 960 | ||
982 | iwl_queue_progress(trans_pcie, txq); | 961 | iwl_queue_progress(trans_pcie, txq); |
983 | 962 | ||
984 | return freed; | 963 | return freed; |
985 | } | 964 | } |
986 | 965 |