2 * This file is part of wl1271
4 * Copyright (C) 2009 Nokia Corporation
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
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.
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.
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
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
30 #include "wl12xx_80211.h"
37 int wl1271_init_templates_config(struct wl1271 *wl)
42 /* send empty templates for fw memory reservation */
43 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
44 wl->scan_templ_id_2_4, NULL,
45 WL1271_CMD_TEMPL_MAX_SIZE,
46 0, WL1271_RATE_AUTOMATIC);
50 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
52 NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
53 WL1271_RATE_AUTOMATIC);
57 if (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL) {
58 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
59 wl->sched_scan_templ_id_2_4,
61 WL1271_CMD_TEMPL_MAX_SIZE,
62 0, WL1271_RATE_AUTOMATIC);
66 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
67 wl->sched_scan_templ_id_5,
69 WL1271_CMD_TEMPL_MAX_SIZE,
70 0, WL1271_RATE_AUTOMATIC);
75 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
76 CMD_TEMPL_NULL_DATA, NULL,
77 sizeof(struct wl12xx_null_data_template),
78 0, WL1271_RATE_AUTOMATIC);
82 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
83 CMD_TEMPL_PS_POLL, NULL,
84 sizeof(struct wl12xx_ps_poll_template),
85 0, WL1271_RATE_AUTOMATIC);
89 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
90 CMD_TEMPL_QOS_NULL_DATA, NULL,
92 (struct ieee80211_qos_hdr),
93 0, WL1271_RATE_AUTOMATIC);
97 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
98 CMD_TEMPL_PROBE_RESPONSE, NULL,
99 WL1271_CMD_TEMPL_DFLT_SIZE,
100 0, WL1271_RATE_AUTOMATIC);
104 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
105 CMD_TEMPL_BEACON, NULL,
106 WL1271_CMD_TEMPL_DFLT_SIZE,
107 0, WL1271_RATE_AUTOMATIC);
111 max_size = sizeof(struct wl12xx_arp_rsp_template) +
112 WL1271_EXTRA_SPACE_MAX;
113 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
114 CMD_TEMPL_ARP_RSP, NULL,
116 0, WL1271_RATE_AUTOMATIC);
121 * Put very large empty placeholders for all templates. These
122 * reserve memory for later.
124 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
125 CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
126 WL1271_CMD_TEMPL_MAX_SIZE,
127 0, WL1271_RATE_AUTOMATIC);
131 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
132 CMD_TEMPL_AP_BEACON, NULL,
133 WL1271_CMD_TEMPL_MAX_SIZE,
134 0, WL1271_RATE_AUTOMATIC);
138 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
139 CMD_TEMPL_DEAUTH_AP, NULL,
141 (struct wl12xx_disconn_template),
142 0, WL1271_RATE_AUTOMATIC);
146 for (i = 0; i < WLCORE_MAX_KLV_TEMPLATES; i++) {
147 ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
149 sizeof(struct ieee80211_qos_hdr),
150 i, WL1271_RATE_AUTOMATIC);
158 static int wl1271_ap_init_deauth_template(struct wl1271 *wl,
159 struct wl12xx_vif *wlvif)
161 struct wl12xx_disconn_template *tmpl;
165 tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
171 tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
172 IEEE80211_STYPE_DEAUTH);
174 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
175 ret = wl1271_cmd_template_set(wl, wlvif->role_id,
177 tmpl, sizeof(*tmpl), 0, rate);
184 static int wl1271_ap_init_null_template(struct wl1271 *wl,
185 struct ieee80211_vif *vif)
187 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
188 struct ieee80211_hdr_3addr *nullfunc;
192 nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
198 nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
199 IEEE80211_STYPE_NULLFUNC |
200 IEEE80211_FCTL_FROMDS);
202 /* nullfunc->addr1 is filled by FW */
204 memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
205 memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);
207 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
208 ret = wl1271_cmd_template_set(wl, wlvif->role_id,
209 CMD_TEMPL_NULL_DATA, nullfunc,
210 sizeof(*nullfunc), 0, rate);
217 static int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
218 struct ieee80211_vif *vif)
220 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
221 struct ieee80211_qos_hdr *qosnull;
225 qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
231 qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
232 IEEE80211_STYPE_QOS_NULLFUNC |
233 IEEE80211_FCTL_FROMDS);
235 /* qosnull->addr1 is filled by FW */
237 memcpy(qosnull->addr2, vif->addr, ETH_ALEN);
238 memcpy(qosnull->addr3, vif->addr, ETH_ALEN);
240 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
241 ret = wl1271_cmd_template_set(wl, wlvif->role_id,
242 CMD_TEMPL_QOS_NULL_DATA, qosnull,
243 sizeof(*qosnull), 0, rate);
250 static int wl12xx_init_rx_config(struct wl1271 *wl)
254 ret = wl1271_acx_rx_msdu_life_time(wl);
261 static int wl12xx_init_phy_vif_config(struct wl1271 *wl,
262 struct wl12xx_vif *wlvif)
266 ret = wl1271_acx_slot(wl, wlvif, DEFAULT_SLOT_TIME);
270 ret = wl1271_acx_service_period_timeout(wl, wlvif);
274 ret = wl1271_acx_rts_threshold(wl, wlvif, wl->hw->wiphy->rts_threshold);
281 static int wl1271_init_sta_beacon_filter(struct wl1271 *wl,
282 struct wl12xx_vif *wlvif)
286 ret = wl1271_acx_beacon_filter_table(wl, wlvif);
290 /* disable beacon filtering until we get the first beacon */
291 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
298 int wl1271_init_pta(struct wl1271 *wl)
302 ret = wl12xx_acx_sg_cfg(wl);
306 ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
313 int wl1271_init_energy_detection(struct wl1271 *wl)
317 ret = wl1271_acx_cca_threshold(wl);
324 static int wl1271_init_beacon_broadcast(struct wl1271 *wl,
325 struct wl12xx_vif *wlvif)
329 ret = wl1271_acx_bcn_dtim_options(wl, wlvif);
336 static int wl12xx_init_fwlog(struct wl1271 *wl)
340 if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
343 ret = wl12xx_cmd_config_fwlog(wl);
350 /* generic sta initialization (non vif-specific) */
351 static int wl1271_sta_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
356 ret = wl12xx_acx_config_ps(wl, wlvif);
360 /* FM WLAN coexistence */
361 ret = wl1271_acx_fm_coex(wl);
365 ret = wl1271_acx_sta_rate_policies(wl, wlvif);
372 static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl,
373 struct ieee80211_vif *vif)
375 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
378 /* disable the keep-alive feature */
379 ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
386 /* generic ap initialization (non vif-specific) */
387 static int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
391 ret = wl1271_init_ap_rates(wl, wlvif);
395 /* configure AP sleep, if enabled */
396 ret = wlcore_hw_ap_sleep(wl);
403 int wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif)
405 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
408 ret = wl1271_ap_init_deauth_template(wl, wlvif);
412 ret = wl1271_ap_init_null_template(wl, vif);
416 ret = wl1271_ap_init_qos_null_template(wl, vif);
421 * when operating as AP we want to receive external beacons for
422 * configuring ERP protection.
424 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
431 static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl,
432 struct ieee80211_vif *vif)
434 return wl1271_ap_init_templates(wl, vif);
437 int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif)
440 struct conf_tx_rate_class rc;
443 wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x",
444 wlvif->basic_rate_set);
446 if (wlvif->basic_rate_set == 0)
449 rc.enabled_rates = wlvif->basic_rate_set;
450 rc.long_retry_limit = 10;
451 rc.short_retry_limit = 10;
453 ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx);
457 /* use the min basic rate for AP broadcast/multicast */
458 rc.enabled_rates = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
459 rc.short_retry_limit = 10;
460 rc.long_retry_limit = 10;
462 ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx);
467 * If the basic rates contain OFDM rates, use OFDM only
468 * rates for unicast TX as well. Else use all supported rates.
470 if (wl->ofdm_only_ap && (wlvif->basic_rate_set & CONF_TX_OFDM_RATES))
471 supported_rates = CONF_TX_OFDM_RATES;
473 supported_rates = CONF_TX_ENABLED_RATES;
475 /* unconditionally enable HT rates */
476 supported_rates |= CONF_TX_MCS_RATES;
478 /* get extra MIMO or wide-chan rates where the HW supports it */
479 supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif);
481 /* configure unicast TX rate classes */
482 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
483 rc.enabled_rates = supported_rates;
484 rc.short_retry_limit = 10;
485 rc.long_retry_limit = 10;
487 ret = wl1271_acx_ap_rate_policy(wl, &rc,
488 wlvif->ap.ucast_rate_idx[i]);
496 static int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
498 /* Reset the BA RX indicators */
499 wlvif->ba_allowed = true;
500 wl->ba_rx_session_count = 0;
502 /* BA is supported in STA/AP modes */
503 if (wlvif->bss_type != BSS_TYPE_AP_BSS &&
504 wlvif->bss_type != BSS_TYPE_STA_BSS) {
505 wlvif->ba_support = false;
509 wlvif->ba_support = true;
511 /* 802.11n initiator BA session setting */
512 return wl12xx_acx_set_ba_initiator_policy(wl, wlvif);
515 /* vif-specifc initialization */
516 static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
520 ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0);
524 /* Initialize connection monitoring thresholds */
525 ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
529 /* Beacon filtering */
530 ret = wl1271_init_sta_beacon_filter(wl, wlvif);
534 /* Beacons and broadcast settings */
535 ret = wl1271_init_beacon_broadcast(wl, wlvif);
539 /* Configure rssi/snr averaging weights */
540 ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif);
547 /* vif-specific intialization */
548 static int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
552 ret = wl1271_acx_ap_max_tx_retry(wl, wlvif);
556 /* initialize Tx power */
557 ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level);
564 int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
566 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
567 struct conf_tx_ac_category *conf_ac;
568 struct conf_tx_tid *conf_tid;
569 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
572 /* consider all existing roles before configuring psm. */
574 if (wl->ap_count == 0 && is_ap) { /* first AP */
575 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
579 /* unmask ap events */
580 wl->event_mask |= wl->ap_event_mask;
581 ret = wl1271_event_unmask(wl);
584 /* first STA, no APs */
585 } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) {
586 u8 sta_auth = wl->conf.conn.sta_sleep_auth;
587 /* Configure for power according to debugfs */
588 if (sta_auth != WL1271_PSM_ILLEGAL)
589 ret = wl1271_acx_sleep_auth(wl, sta_auth);
590 /* Configure for ELP power saving */
592 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
598 /* Mode specific init */
600 ret = wl1271_ap_hw_init(wl, wlvif);
604 ret = wl12xx_init_ap_role(wl, wlvif);
608 ret = wl1271_sta_hw_init(wl, wlvif);
612 ret = wl12xx_init_sta_role(wl, wlvif);
617 wl12xx_init_phy_vif_config(wl, wlvif);
619 /* Default TID/AC configuration */
620 BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
621 for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
622 conf_ac = &wl->conf.tx.ac_conf[i];
623 ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac,
624 conf_ac->cw_min, conf_ac->cw_max,
625 conf_ac->aifsn, conf_ac->tx_op_limit);
629 conf_tid = &wl->conf.tx.tid_conf[i];
630 ret = wl1271_acx_tid_cfg(wl, wlvif,
632 conf_tid->channel_type,
635 conf_tid->ack_policy,
636 conf_tid->apsd_conf[0],
637 conf_tid->apsd_conf[1]);
642 /* Configure HW encryption */
643 ret = wl1271_acx_feature_cfg(wl, wlvif);
647 /* Mode specific init - post mem init */
649 ret = wl1271_ap_hw_init_post_mem(wl, vif);
651 ret = wl1271_sta_hw_init_post_mem(wl, vif);
656 /* Configure initiator BA sessions policies */
657 ret = wl1271_set_ba_policies(wl, wlvif);
661 ret = wlcore_hw_init_vif(wl, wlvif);
668 int wl1271_hw_init(struct wl1271 *wl)
672 /* Chip-specific hw init */
673 ret = wl->ops->hw_init(wl);
678 ret = wl1271_init_templates_config(wl);
682 ret = wl12xx_acx_mem_cfg(wl);
686 /* Configure the FW logger */
687 ret = wl12xx_init_fwlog(wl);
691 ret = wlcore_cmd_regdomain_config_locked(wl);
695 /* Bluetooth WLAN coexistence */
696 ret = wl1271_init_pta(wl);
700 /* Default memory configuration */
701 ret = wl1271_acx_init_mem_config(wl);
706 ret = wl12xx_init_rx_config(wl);
708 goto out_free_memmap;
710 ret = wl1271_acx_dco_itrim_params(wl);
712 goto out_free_memmap;
714 /* Configure TX patch complete interrupt behavior */
715 ret = wl1271_acx_tx_config_options(wl);
717 goto out_free_memmap;
719 /* RX complete interrupt pacing */
720 ret = wl1271_acx_init_rx_interrupt(wl);
722 goto out_free_memmap;
724 /* Energy detection */
725 ret = wl1271_init_energy_detection(wl);
727 goto out_free_memmap;
729 /* Default fragmentation threshold */
730 ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
732 goto out_free_memmap;
734 /* Enable data path */
735 ret = wl1271_cmd_data_path(wl, 1);
737 goto out_free_memmap;
740 ret = wl1271_acx_pm_config(wl);
742 goto out_free_memmap;
744 ret = wl12xx_acx_set_rate_mgmt_params(wl);
746 goto out_free_memmap;
748 /* configure hangover */
749 ret = wl12xx_acx_config_hangover(wl);
751 goto out_free_memmap;
756 kfree(wl->target_mem_map);
757 wl->target_mem_map = NULL;