Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
init.c
Go to the documentation of this file.
1 /*
2  * This file is part of wl1271
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  *
6  * Contact: Luciano Coelho <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23 
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
27 
28 #include "debug.h"
29 #include "init.h"
30 #include "wl12xx_80211.h"
31 #include "acx.h"
32 #include "cmd.h"
33 #include "tx.h"
34 #include "io.h"
35 #include "hw_ops.h"
36 
38 {
39  int ret, i;
40  size_t max_size;
41 
42  /* send empty templates for fw memory reservation */
47  if (ret < 0)
48  return ret;
49 
54  if (ret < 0)
55  return ret;
56 
62  if (ret < 0)
63  return ret;
64 
69  if (ret < 0)
70  return ret;
71  }
72 
75  sizeof(struct wl12xx_null_data_template),
77  if (ret < 0)
78  return ret;
79 
82  sizeof(struct wl12xx_ps_poll_template),
84  if (ret < 0)
85  return ret;
86 
89  sizeof
90  (struct ieee80211_qos_hdr),
92  if (ret < 0)
93  return ret;
94 
99  if (ret < 0)
100  return ret;
101 
106  if (ret < 0)
107  return ret;
108 
109  max_size = sizeof(struct wl12xx_arp_rsp_template) +
110  WL1271_EXTRA_SPACE_MAX;
113  max_size,
115  if (ret < 0)
116  return ret;
117 
118  /*
119  * Put very large empty placeholders for all templates. These
120  * reserve memory for later.
121  */
126  if (ret < 0)
127  return ret;
128 
133  if (ret < 0)
134  return ret;
135 
138  sizeof
139  (struct wl12xx_disconn_template),
141  if (ret < 0)
142  return ret;
143 
144  for (i = 0; i < WLCORE_MAX_KLV_TEMPLATES; i++) {
147  sizeof(struct ieee80211_qos_hdr),
149  if (ret < 0)
150  return ret;
151  }
152 
153  return 0;
154 }
155 
156 static int wl1271_ap_init_deauth_template(struct wl1271 *wl,
157  struct wl12xx_vif *wlvif)
158 {
159  struct wl12xx_disconn_template *tmpl;
160  int ret;
161  u32 rate;
162 
163  tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
164  if (!tmpl) {
165  ret = -ENOMEM;
166  goto out;
167  }
168 
169  tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
171 
172  rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
173  ret = wl1271_cmd_template_set(wl, wlvif->role_id,
175  tmpl, sizeof(*tmpl), 0, rate);
176 
177 out:
178  kfree(tmpl);
179  return ret;
180 }
181 
182 static int wl1271_ap_init_null_template(struct wl1271 *wl,
183  struct ieee80211_vif *vif)
184 {
185  struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
186  struct ieee80211_hdr_3addr *nullfunc;
187  int ret;
188  u32 rate;
189 
190  nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
191  if (!nullfunc) {
192  ret = -ENOMEM;
193  goto out;
194  }
195 
199 
200  /* nullfunc->addr1 is filled by FW */
201 
202  memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
203  memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);
204 
205  rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
206  ret = wl1271_cmd_template_set(wl, wlvif->role_id,
207  CMD_TEMPL_NULL_DATA, nullfunc,
208  sizeof(*nullfunc), 0, rate);
209 
210 out:
211  kfree(nullfunc);
212  return ret;
213 }
214 
215 static int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
216  struct ieee80211_vif *vif)
217 {
218  struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
219  struct ieee80211_qos_hdr *qosnull;
220  int ret;
221  u32 rate;
222 
223  qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
224  if (!qosnull) {
225  ret = -ENOMEM;
226  goto out;
227  }
228 
232 
233  /* qosnull->addr1 is filled by FW */
234 
235  memcpy(qosnull->addr2, vif->addr, ETH_ALEN);
236  memcpy(qosnull->addr3, vif->addr, ETH_ALEN);
237 
238  rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
239  ret = wl1271_cmd_template_set(wl, wlvif->role_id,
240  CMD_TEMPL_QOS_NULL_DATA, qosnull,
241  sizeof(*qosnull), 0, rate);
242 
243 out:
244  kfree(qosnull);
245  return ret;
246 }
247 
248 static int wl12xx_init_rx_config(struct wl1271 *wl)
249 {
250  int ret;
251 
253  if (ret < 0)
254  return ret;
255 
256  return 0;
257 }
258 
259 static int wl12xx_init_phy_vif_config(struct wl1271 *wl,
260  struct wl12xx_vif *wlvif)
261 {
262  int ret;
263 
264  ret = wl1271_acx_slot(wl, wlvif, DEFAULT_SLOT_TIME);
265  if (ret < 0)
266  return ret;
267 
268  ret = wl1271_acx_service_period_timeout(wl, wlvif);
269  if (ret < 0)
270  return ret;
271 
272  ret = wl1271_acx_rts_threshold(wl, wlvif, wl->hw->wiphy->rts_threshold);
273  if (ret < 0)
274  return ret;
275 
276  return 0;
277 }
278 
279 static int wl1271_init_sta_beacon_filter(struct wl1271 *wl,
280  struct wl12xx_vif *wlvif)
281 {
282  int ret;
283 
284  ret = wl1271_acx_beacon_filter_table(wl, wlvif);
285  if (ret < 0)
286  return ret;
287 
288  /* enable beacon filtering */
289  ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
290  if (ret < 0)
291  return ret;
292 
293  return 0;
294 }
295 
296 int wl1271_init_pta(struct wl1271 *wl)
297 {
298  int ret;
299 
300  ret = wl12xx_acx_sg_cfg(wl);
301  if (ret < 0)
302  return ret;
303 
304  ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
305  if (ret < 0)
306  return ret;
307 
308  return 0;
309 }
310 
312 {
313  int ret;
314 
315  ret = wl1271_acx_cca_threshold(wl);
316  if (ret < 0)
317  return ret;
318 
319  return 0;
320 }
321 
322 static int wl1271_init_beacon_broadcast(struct wl1271 *wl,
323  struct wl12xx_vif *wlvif)
324 {
325  int ret;
326 
327  ret = wl1271_acx_bcn_dtim_options(wl, wlvif);
328  if (ret < 0)
329  return ret;
330 
331  return 0;
332 }
333 
334 static int wl12xx_init_fwlog(struct wl1271 *wl)
335 {
336  int ret;
337 
339  return 0;
340 
341  ret = wl12xx_cmd_config_fwlog(wl);
342  if (ret < 0)
343  return ret;
344 
345  return 0;
346 }
347 
348 /* generic sta initialization (non vif-specific) */
349 static int wl1271_sta_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
350 {
351  int ret;
352 
353  /* PS config */
354  ret = wl12xx_acx_config_ps(wl, wlvif);
355  if (ret < 0)
356  return ret;
357 
358  /* FM WLAN coexistence */
359  ret = wl1271_acx_fm_coex(wl);
360  if (ret < 0)
361  return ret;
362 
363  ret = wl1271_acx_sta_rate_policies(wl, wlvif);
364  if (ret < 0)
365  return ret;
366 
367  return 0;
368 }
369 
370 static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl,
371  struct ieee80211_vif *vif)
372 {
373  struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
374  int ret;
375 
376  /* disable the keep-alive feature */
377  ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
378  if (ret < 0)
379  return ret;
380 
381  return 0;
382 }
383 
384 /* generic ap initialization (non vif-specific) */
385 static int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
386 {
387  int ret;
388 
389  ret = wl1271_init_ap_rates(wl, wlvif);
390  if (ret < 0)
391  return ret;
392 
393  return 0;
394 }
395 
396 int wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif)
397 {
398  struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
399  int ret;
400 
401  ret = wl1271_ap_init_deauth_template(wl, wlvif);
402  if (ret < 0)
403  return ret;
404 
405  ret = wl1271_ap_init_null_template(wl, vif);
406  if (ret < 0)
407  return ret;
408 
409  ret = wl1271_ap_init_qos_null_template(wl, vif);
410  if (ret < 0)
411  return ret;
412 
413  /*
414  * when operating as AP we want to receive external beacons for
415  * configuring ERP protection.
416  */
417  ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
418  if (ret < 0)
419  return ret;
420 
421  return 0;
422 }
423 
424 static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl,
425  struct ieee80211_vif *vif)
426 {
427  return wl1271_ap_init_templates(wl, vif);
428 }
429 
430 int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
431 {
432  int i, ret;
433  struct conf_tx_rate_class rc;
434  u32 supported_rates;
435 
436  wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x",
437  wlvif->basic_rate_set);
438 
439  if (wlvif->basic_rate_set == 0)
440  return -EINVAL;
441 
442  rc.enabled_rates = wlvif->basic_rate_set;
443  rc.long_retry_limit = 10;
444  rc.short_retry_limit = 10;
445  rc.aflags = 0;
446  ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx);
447  if (ret < 0)
448  return ret;
449 
450  /* use the min basic rate for AP broadcast/multicast */
452  rc.short_retry_limit = 10;
453  rc.long_retry_limit = 10;
454  rc.aflags = 0;
455  ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx);
456  if (ret < 0)
457  return ret;
458 
459  /*
460  * If the basic rates contain OFDM rates, use OFDM only
461  * rates for unicast TX as well. Else use all supported rates.
462  */
463  if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
464  supported_rates = CONF_TX_OFDM_RATES;
465  else
466  supported_rates = CONF_TX_AP_ENABLED_RATES;
467 
468  /* unconditionally enable HT rates */
469  supported_rates |= CONF_TX_MCS_RATES;
470 
471  /* get extra MIMO or wide-chan rates where the HW supports it */
472  supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif);
473 
474  /* configure unicast TX rate classes */
475  for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
476  rc.enabled_rates = supported_rates;
477  rc.short_retry_limit = 10;
478  rc.long_retry_limit = 10;
479  rc.aflags = 0;
480  ret = wl1271_acx_ap_rate_policy(wl, &rc,
481  wlvif->ap.ucast_rate_idx[i]);
482  if (ret < 0)
483  return ret;
484  }
485 
486  return 0;
487 }
488 
489 static int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
490 {
491  /* Reset the BA RX indicators */
492  wlvif->ba_allowed = true;
493  wl->ba_rx_session_count = 0;
494 
495  /* BA is supported in STA/AP modes */
496  if (wlvif->bss_type != BSS_TYPE_AP_BSS &&
497  wlvif->bss_type != BSS_TYPE_STA_BSS) {
498  wlvif->ba_support = false;
499  return 0;
500  }
501 
502  wlvif->ba_support = true;
503 
504  /* 802.11n initiator BA session setting */
505  return wl12xx_acx_set_ba_initiator_policy(wl, wlvif);
506 }
507 
508 /* vif-specifc initialization */
509 static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
510 {
511  int ret;
512 
513  ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0);
514  if (ret < 0)
515  return ret;
516 
517  /* Initialize connection monitoring thresholds */
518  ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
519  if (ret < 0)
520  return ret;
521 
522  /* Beacon filtering */
523  ret = wl1271_init_sta_beacon_filter(wl, wlvif);
524  if (ret < 0)
525  return ret;
526 
527  /* Beacons and broadcast settings */
528  ret = wl1271_init_beacon_broadcast(wl, wlvif);
529  if (ret < 0)
530  return ret;
531 
532  /* Configure rssi/snr averaging weights */
533  ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif);
534  if (ret < 0)
535  return ret;
536 
537  return 0;
538 }
539 
540 /* vif-specific intialization */
541 static int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
542 {
543  int ret;
544 
545  ret = wl1271_acx_ap_max_tx_retry(wl, wlvif);
546  if (ret < 0)
547  return ret;
548 
549  /* initialize Tx power */
550  ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level);
551  if (ret < 0)
552  return ret;
553 
554  return 0;
555 }
556 
557 int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
558 {
559  struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
560  struct conf_tx_ac_category *conf_ac;
561  struct conf_tx_tid *conf_tid;
562  bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
563  int ret, i;
564 
565  /* consider all existing roles before configuring psm. */
566 
567  if (wl->ap_count == 0 && is_ap) { /* first AP */
568  /* Configure for power always on */
570  if (ret < 0)
571  return ret;
572  /* first STA, no APs */
573  } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) {
574  u8 sta_auth = wl->conf.conn.sta_sleep_auth;
575  /* Configure for power according to debugfs */
576  if (sta_auth != WL1271_PSM_ILLEGAL)
577  ret = wl1271_acx_sleep_auth(wl, sta_auth);
578  /* Configure for power always on */
579  else if (wl->quirks & WLCORE_QUIRK_NO_ELP)
581  /* Configure for ELP power saving */
582  else
584 
585  if (ret < 0)
586  return ret;
587  }
588 
589  /* Mode specific init */
590  if (is_ap) {
591  ret = wl1271_ap_hw_init(wl, wlvif);
592  if (ret < 0)
593  return ret;
594 
595  ret = wl12xx_init_ap_role(wl, wlvif);
596  if (ret < 0)
597  return ret;
598  } else {
599  ret = wl1271_sta_hw_init(wl, wlvif);
600  if (ret < 0)
601  return ret;
602 
603  ret = wl12xx_init_sta_role(wl, wlvif);
604  if (ret < 0)
605  return ret;
606  }
607 
608  wl12xx_init_phy_vif_config(wl, wlvif);
609 
610  /* Default TID/AC configuration */
611  BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
612  for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
613  conf_ac = &wl->conf.tx.ac_conf[i];
614  ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac,
615  conf_ac->cw_min, conf_ac->cw_max,
616  conf_ac->aifsn, conf_ac->tx_op_limit);
617  if (ret < 0)
618  return ret;
619 
620  conf_tid = &wl->conf.tx.tid_conf[i];
621  ret = wl1271_acx_tid_cfg(wl, wlvif,
622  conf_tid->queue_id,
623  conf_tid->channel_type,
624  conf_tid->tsid,
625  conf_tid->ps_scheme,
626  conf_tid->ack_policy,
627  conf_tid->apsd_conf[0],
628  conf_tid->apsd_conf[1]);
629  if (ret < 0)
630  return ret;
631  }
632 
633  /* Configure HW encryption */
634  ret = wl1271_acx_feature_cfg(wl, wlvif);
635  if (ret < 0)
636  return ret;
637 
638  /* Mode specific init - post mem init */
639  if (is_ap)
640  ret = wl1271_ap_hw_init_post_mem(wl, vif);
641  else
642  ret = wl1271_sta_hw_init_post_mem(wl, vif);
643 
644  if (ret < 0)
645  return ret;
646 
647  /* Configure initiator BA sessions policies */
648  ret = wl1271_set_ba_policies(wl, wlvif);
649  if (ret < 0)
650  return ret;
651 
652  ret = wlcore_hw_init_vif(wl, wlvif);
653  if (ret < 0)
654  return ret;
655 
656  return 0;
657 }
658 
659 int wl1271_hw_init(struct wl1271 *wl)
660 {
661  int ret;
662 
663  /* Chip-specific hw init */
664  ret = wl->ops->hw_init(wl);
665  if (ret < 0)
666  return ret;
667 
668  /* Init templates */
670  if (ret < 0)
671  return ret;
672 
673  ret = wl12xx_acx_mem_cfg(wl);
674  if (ret < 0)
675  return ret;
676 
677  /* Configure the FW logger */
678  ret = wl12xx_init_fwlog(wl);
679  if (ret < 0)
680  return ret;
681 
682  /* Bluetooth WLAN coexistence */
683  ret = wl1271_init_pta(wl);
684  if (ret < 0)
685  return ret;
686 
687  /* Default memory configuration */
688  ret = wl1271_acx_init_mem_config(wl);
689  if (ret < 0)
690  return ret;
691 
692  /* RX config */
693  ret = wl12xx_init_rx_config(wl);
694  if (ret < 0)
695  goto out_free_memmap;
696 
697  ret = wl1271_acx_dco_itrim_params(wl);
698  if (ret < 0)
699  goto out_free_memmap;
700 
701  /* Configure TX patch complete interrupt behavior */
703  if (ret < 0)
704  goto out_free_memmap;
705 
706  /* RX complete interrupt pacing */
708  if (ret < 0)
709  goto out_free_memmap;
710 
711  /* Energy detection */
713  if (ret < 0)
714  goto out_free_memmap;
715 
716  /* Default fragmentation threshold */
717  ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
718  if (ret < 0)
719  goto out_free_memmap;
720 
721  /* Enable data path */
722  ret = wl1271_cmd_data_path(wl, 1);
723  if (ret < 0)
724  goto out_free_memmap;
725 
726  /* configure PM */
727  ret = wl1271_acx_pm_config(wl);
728  if (ret < 0)
729  goto out_free_memmap;
730 
732  if (ret < 0)
733  goto out_free_memmap;
734 
735  /* configure hangover */
736  ret = wl12xx_acx_config_hangover(wl);
737  if (ret < 0)
738  goto out_free_memmap;
739 
740  return 0;
741 
742  out_free_memmap:
743  kfree(wl->target_mem_map);
744  wl->target_mem_map = NULL;
745 
746  return ret;
747 }