iwlwifi: move iwl_set_rate to iwl-agn-rxon.c
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-core.c
1 /******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/sched.h>
32 #include <linux/slab.h>
33 #include <net/mac80211.h>
34
35 #include "iwl-eeprom.h"
36 #include "iwl-debug.h"
37 #include "iwl-core.h"
38 #include "iwl-io.h"
39 #include "iwl-power.h"
40 #include "iwl-shared.h"
41 #include "iwl-agn.h"
42 #include "iwl-trans.h"
43
44 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
45
46 void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
47 {
48 /*
49 * MULTI-FIXME
50 * See iwlagn_mac_channel_switch.
51 */
52 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
53
54 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
55 return;
56
57 if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
58 ieee80211_chswitch_done(ctx->vif, is_success);
59 }
60
61 #ifdef CONFIG_IWLWIFI_DEBUG
62 void iwl_print_rx_config_cmd(struct iwl_priv *priv,
63 enum iwl_rxon_context_id ctxid)
64 {
65 struct iwl_rxon_context *ctx = &priv->contexts[ctxid];
66 struct iwl_rxon_cmd *rxon = &ctx->staging;
67
68 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
69 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
70 IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
71 IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
72 IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
73 le32_to_cpu(rxon->filter_flags));
74 IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
75 IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
76 rxon->ofdm_basic_rates);
77 IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
78 IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
79 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
80 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
81 }
82 #endif
83
84 void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
85 {
86 unsigned int reload_msec;
87 unsigned long reload_jiffies;
88
89 #ifdef CONFIG_IWLWIFI_DEBUG
90 if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
91 iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
92 #endif
93
94 /* uCode is no longer loaded. */
95 priv->ucode_loaded = false;
96
97 /* Set the FW error flag -- cleared on iwl_down */
98 set_bit(STATUS_FW_ERROR, &priv->status);
99
100 /* Cancel currently queued command. */
101 clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status);
102
103 iwl_abort_notification_waits(&priv->notif_wait);
104
105 /* Keep the restart process from trying to send host
106 * commands by clearing the ready bit */
107 clear_bit(STATUS_READY, &priv->status);
108
109 wake_up(&trans(priv)->wait_command_queue);
110
111 if (!ondemand) {
112 /*
113 * If firmware keep reloading, then it indicate something
114 * serious wrong and firmware having problem to recover
115 * from it. Instead of keep trying which will fill the syslog
116 * and hang the system, let's just stop it
117 */
118 reload_jiffies = jiffies;
119 reload_msec = jiffies_to_msecs((long) reload_jiffies -
120 (long) priv->reload_jiffies);
121 priv->reload_jiffies = reload_jiffies;
122 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
123 priv->reload_count++;
124 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
125 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
126 return;
127 }
128 } else
129 priv->reload_count = 0;
130 }
131
132 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
133 if (iwlagn_mod_params.restart_fw) {
134 IWL_DEBUG_FW_ERRORS(priv,
135 "Restarting adapter due to uCode error.\n");
136 queue_work(priv->workqueue, &priv->restart);
137 } else
138 IWL_DEBUG_FW_ERRORS(priv,
139 "Detected FW error, but not restarting\n");
140 }
141 }
142
143 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
144 {
145 int ret;
146 s8 prev_tx_power;
147 bool defer;
148 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
149
150 lockdep_assert_held(&priv->mutex);
151
152 if (priv->tx_power_user_lmt == tx_power && !force)
153 return 0;
154
155 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
156 IWL_WARN(priv,
157 "Requested user TXPOWER %d below lower limit %d.\n",
158 tx_power,
159 IWLAGN_TX_POWER_TARGET_POWER_MIN);
160 return -EINVAL;
161 }
162
163 if (tx_power > priv->tx_power_device_lmt) {
164 IWL_WARN(priv,
165 "Requested user TXPOWER %d above upper limit %d.\n",
166 tx_power, priv->tx_power_device_lmt);
167 return -EINVAL;
168 }
169
170 if (!iwl_is_ready_rf(priv))
171 return -EIO;
172
173 /* scan complete and commit_rxon use tx_power_next value,
174 * it always need to be updated for newest request */
175 priv->tx_power_next = tx_power;
176
177 /* do not set tx power when scanning or channel changing */
178 defer = test_bit(STATUS_SCANNING, &priv->status) ||
179 memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
180 if (defer && !force) {
181 IWL_DEBUG_INFO(priv, "Deferring tx power set\n");
182 return 0;
183 }
184
185 prev_tx_power = priv->tx_power_user_lmt;
186 priv->tx_power_user_lmt = tx_power;
187
188 ret = iwlagn_send_tx_power(priv);
189
190 /* if fail to set tx_power, restore the orig. tx power */
191 if (ret) {
192 priv->tx_power_user_lmt = prev_tx_power;
193 priv->tx_power_next = prev_tx_power;
194 }
195 return ret;
196 }
197
198 void iwl_send_bt_config(struct iwl_priv *priv)
199 {
200 struct iwl_bt_cmd bt_cmd = {
201 .lead_time = BT_LEAD_TIME_DEF,
202 .max_kill = BT_MAX_KILL_DEF,
203 .kill_ack_mask = 0,
204 .kill_cts_mask = 0,
205 };
206
207 if (!iwlagn_mod_params.bt_coex_active)
208 bt_cmd.flags = BT_COEX_DISABLE;
209 else
210 bt_cmd.flags = BT_COEX_ENABLE;
211
212 priv->bt_enable_flag = bt_cmd.flags;
213 IWL_DEBUG_INFO(priv, "BT coex %s\n",
214 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
215
216 if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
217 CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
218 IWL_ERR(priv, "failed to send BT Coex Config\n");
219 }
220
221 int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
222 {
223 struct iwl_statistics_cmd statistics_cmd = {
224 .configuration_flags =
225 clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
226 };
227
228 if (flags & CMD_ASYNC)
229 return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
230 CMD_ASYNC,
231 sizeof(struct iwl_statistics_cmd),
232 &statistics_cmd);
233 else
234 return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
235 CMD_SYNC,
236 sizeof(struct iwl_statistics_cmd),
237 &statistics_cmd);
238 }
239
240
241
242
243 #ifdef CONFIG_IWLWIFI_DEBUGFS
244
245 #define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
246
247 void iwl_reset_traffic_log(struct iwl_priv *priv)
248 {
249 priv->tx_traffic_idx = 0;
250 priv->rx_traffic_idx = 0;
251 if (priv->tx_traffic)
252 memset(priv->tx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE);
253 if (priv->rx_traffic)
254 memset(priv->rx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE);
255 }
256
257 int iwl_alloc_traffic_mem(struct iwl_priv *priv)
258 {
259 u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE;
260
261 if (iwl_have_debug_level(IWL_DL_TX)) {
262 if (!priv->tx_traffic) {
263 priv->tx_traffic =
264 kzalloc(traffic_size, GFP_KERNEL);
265 if (!priv->tx_traffic)
266 return -ENOMEM;
267 }
268 }
269 if (iwl_have_debug_level(IWL_DL_RX)) {
270 if (!priv->rx_traffic) {
271 priv->rx_traffic =
272 kzalloc(traffic_size, GFP_KERNEL);
273 if (!priv->rx_traffic)
274 return -ENOMEM;
275 }
276 }
277 iwl_reset_traffic_log(priv);
278 return 0;
279 }
280
281 void iwl_free_traffic_mem(struct iwl_priv *priv)
282 {
283 kfree(priv->tx_traffic);
284 priv->tx_traffic = NULL;
285
286 kfree(priv->rx_traffic);
287 priv->rx_traffic = NULL;
288 }
289
290 void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
291 u16 length, struct ieee80211_hdr *header)
292 {
293 __le16 fc;
294 u16 len;
295
296 if (likely(!iwl_have_debug_level(IWL_DL_TX)))
297 return;
298
299 if (!priv->tx_traffic)
300 return;
301
302 fc = header->frame_control;
303 if (ieee80211_is_data(fc)) {
304 len = (length > IWL_TRAFFIC_ENTRY_SIZE)
305 ? IWL_TRAFFIC_ENTRY_SIZE : length;
306 memcpy((priv->tx_traffic +
307 (priv->tx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)),
308 header, len);
309 priv->tx_traffic_idx =
310 (priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES;
311 }
312 }
313
314 void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
315 u16 length, struct ieee80211_hdr *header)
316 {
317 __le16 fc;
318 u16 len;
319
320 if (likely(!iwl_have_debug_level(IWL_DL_RX)))
321 return;
322
323 if (!priv->rx_traffic)
324 return;
325
326 fc = header->frame_control;
327 if (ieee80211_is_data(fc)) {
328 len = (length > IWL_TRAFFIC_ENTRY_SIZE)
329 ? IWL_TRAFFIC_ENTRY_SIZE : length;
330 memcpy((priv->rx_traffic +
331 (priv->rx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)),
332 header, len);
333 priv->rx_traffic_idx =
334 (priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES;
335 }
336 }
337
338 const char *get_mgmt_string(int cmd)
339 {
340 switch (cmd) {
341 IWL_CMD(MANAGEMENT_ASSOC_REQ);
342 IWL_CMD(MANAGEMENT_ASSOC_RESP);
343 IWL_CMD(MANAGEMENT_REASSOC_REQ);
344 IWL_CMD(MANAGEMENT_REASSOC_RESP);
345 IWL_CMD(MANAGEMENT_PROBE_REQ);
346 IWL_CMD(MANAGEMENT_PROBE_RESP);
347 IWL_CMD(MANAGEMENT_BEACON);
348 IWL_CMD(MANAGEMENT_ATIM);
349 IWL_CMD(MANAGEMENT_DISASSOC);
350 IWL_CMD(MANAGEMENT_AUTH);
351 IWL_CMD(MANAGEMENT_DEAUTH);
352 IWL_CMD(MANAGEMENT_ACTION);
353 default:
354 return "UNKNOWN";
355
356 }
357 }
358
359 const char *get_ctrl_string(int cmd)
360 {
361 switch (cmd) {
362 IWL_CMD(CONTROL_BACK_REQ);
363 IWL_CMD(CONTROL_BACK);
364 IWL_CMD(CONTROL_PSPOLL);
365 IWL_CMD(CONTROL_RTS);
366 IWL_CMD(CONTROL_CTS);
367 IWL_CMD(CONTROL_ACK);
368 IWL_CMD(CONTROL_CFEND);
369 IWL_CMD(CONTROL_CFENDACK);
370 default:
371 return "UNKNOWN";
372
373 }
374 }
375
376 void iwl_clear_traffic_stats(struct iwl_priv *priv)
377 {
378 memset(&priv->tx_stats, 0, sizeof(struct traffic_stats));
379 memset(&priv->rx_stats, 0, sizeof(struct traffic_stats));
380 }
381
382 /*
383 * if CONFIG_IWLWIFI_DEBUGFS defined, iwl_update_stats function will
384 * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass.
385 * Use debugFs to display the rx/rx_statistics
386 * if CONFIG_IWLWIFI_DEBUGFS not being defined, then no MGMT and CTRL
387 * information will be recorded, but DATA pkt still will be recorded
388 * for the reason of iwl_led.c need to control the led blinking based on
389 * number of tx and rx data.
390 *
391 */
392 void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
393 {
394 struct traffic_stats *stats;
395
396 if (is_tx)
397 stats = &priv->tx_stats;
398 else
399 stats = &priv->rx_stats;
400
401 if (ieee80211_is_mgmt(fc)) {
402 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
403 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
404 stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
405 break;
406 case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
407 stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
408 break;
409 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
410 stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
411 break;
412 case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
413 stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
414 break;
415 case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
416 stats->mgmt[MANAGEMENT_PROBE_REQ]++;
417 break;
418 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
419 stats->mgmt[MANAGEMENT_PROBE_RESP]++;
420 break;
421 case cpu_to_le16(IEEE80211_STYPE_BEACON):
422 stats->mgmt[MANAGEMENT_BEACON]++;
423 break;
424 case cpu_to_le16(IEEE80211_STYPE_ATIM):
425 stats->mgmt[MANAGEMENT_ATIM]++;
426 break;
427 case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
428 stats->mgmt[MANAGEMENT_DISASSOC]++;
429 break;
430 case cpu_to_le16(IEEE80211_STYPE_AUTH):
431 stats->mgmt[MANAGEMENT_AUTH]++;
432 break;
433 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
434 stats->mgmt[MANAGEMENT_DEAUTH]++;
435 break;
436 case cpu_to_le16(IEEE80211_STYPE_ACTION):
437 stats->mgmt[MANAGEMENT_ACTION]++;
438 break;
439 }
440 } else if (ieee80211_is_ctl(fc)) {
441 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
442 case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
443 stats->ctrl[CONTROL_BACK_REQ]++;
444 break;
445 case cpu_to_le16(IEEE80211_STYPE_BACK):
446 stats->ctrl[CONTROL_BACK]++;
447 break;
448 case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
449 stats->ctrl[CONTROL_PSPOLL]++;
450 break;
451 case cpu_to_le16(IEEE80211_STYPE_RTS):
452 stats->ctrl[CONTROL_RTS]++;
453 break;
454 case cpu_to_le16(IEEE80211_STYPE_CTS):
455 stats->ctrl[CONTROL_CTS]++;
456 break;
457 case cpu_to_le16(IEEE80211_STYPE_ACK):
458 stats->ctrl[CONTROL_ACK]++;
459 break;
460 case cpu_to_le16(IEEE80211_STYPE_CFEND):
461 stats->ctrl[CONTROL_CFEND]++;
462 break;
463 case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
464 stats->ctrl[CONTROL_CFENDACK]++;
465 break;
466 }
467 } else {
468 /* data */
469 stats->data_cnt++;
470 stats->data_bytes += len;
471 }
472 }
473 #endif
474
475 int iwl_force_rf_reset(struct iwl_priv *priv, bool external)
476 {
477 struct iwl_rf_reset *rf_reset;
478
479 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
480 return -EAGAIN;
481
482 if (!iwl_is_any_associated(priv)) {
483 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
484 return -ENOLINK;
485 }
486
487 rf_reset = &priv->rf_reset;
488 rf_reset->reset_request_count++;
489 if (!external && rf_reset->last_reset_jiffies &&
490 time_after(rf_reset->last_reset_jiffies +
491 IWL_DELAY_NEXT_FORCE_RF_RESET, jiffies)) {
492 IWL_DEBUG_INFO(priv, "RF reset rejected\n");
493 rf_reset->reset_reject_count++;
494 return -EAGAIN;
495 }
496 rf_reset->reset_success_count++;
497 rf_reset->last_reset_jiffies = jiffies;
498
499 /*
500 * There is no easy and better way to force reset the radio,
501 * the only known method is switching channel which will force to
502 * reset and tune the radio.
503 * Use internal short scan (single channel) operation to should
504 * achieve this objective.
505 * Driver should reset the radio when number of consecutive missed
506 * beacon, or any other uCode error condition detected.
507 */
508 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
509 iwl_internal_short_hw_scan(priv);
510 return 0;
511 }
512
513
514 int iwl_cmd_echo_test(struct iwl_priv *priv)
515 {
516 int ret;
517 struct iwl_host_cmd cmd = {
518 .id = REPLY_ECHO,
519 .len = { 0 },
520 .flags = CMD_SYNC,
521 };
522
523 ret = iwl_dvm_send_cmd(priv, &cmd);
524 if (ret)
525 IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
526 else
527 IWL_DEBUG_INFO(priv, "echo testing pass\n");
528 return ret;
529 }
This page took 0.042395 seconds and 5 git commands to generate.