diff options
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/init.c')
| -rw-r--r-- | drivers/net/wireless/ti/wlcore/init.c | 97 |
1 files changed, 58 insertions, 39 deletions
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 9f89255eb6e..199e9412086 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -41,19 +41,37 @@ int wl1271_init_templates_config(struct wl1271 *wl) /* send empty templates for fw memory reservation */ ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, - CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, + wl->scan_templ_id_2_4, NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, - CMD_TEMPL_CFG_PROBE_REQ_5, + wl->scan_templ_id_5, NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; + if (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL) { + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + wl->sched_scan_templ_id_2_4, + NULL, + WL1271_CMD_TEMPL_MAX_SIZE, + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + wl->sched_scan_templ_id_5, + NULL, + WL1271_CMD_TEMPL_MAX_SIZE, + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + } + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, CMD_TEMPL_NULL_DATA, NULL, sizeof(struct wl12xx_null_data_template), @@ -125,7 +143,7 @@ int wl1271_init_templates_config(struct wl1271 *wl) if (ret < 0) return ret; - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { + for (i = 0; i < WLCORE_MAX_KLV_TEMPLATES; i++) { ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, CMD_TEMPL_KLV, NULL, sizeof(struct ieee80211_qos_hdr), @@ -269,8 +287,8 @@ static int wl1271_init_sta_beacon_filter(struct wl1271 *wl, if (ret < 0) return ret; - /* enable beacon filtering */ - ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); + /* disable beacon filtering until we get the first beacon */ + ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); if (ret < 0) return ret; @@ -355,15 +373,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl, struct ieee80211_vif *vif) { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); - int ret, i; - - /* disable all keep-alive templates */ - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_acx_keep_alive_config(wl, wlvif, i, - ACX_KEEP_ALIVE_TPL_INVALID); - if (ret < 0) - return ret; - } + int ret; /* disable the keep-alive feature */ ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); @@ -452,14 +462,17 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) * If the basic rates contain OFDM rates, use OFDM only * rates for unicast TX as well. Else use all supported rates. */ - if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) + if (wl->ofdm_only_ap && (wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) supported_rates = CONF_TX_OFDM_RATES; else - supported_rates = CONF_TX_AP_ENABLED_RATES; + supported_rates = CONF_TX_ENABLED_RATES; /* unconditionally enable HT rates */ supported_rates |= CONF_TX_MCS_RATES; + /* get extra MIMO or wide-chan rates where the HW supports it */ + supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); + /* configure unicast TX rate classes */ for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { rc.enabled_rates = supported_rates; @@ -551,29 +564,31 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); int ret, i; - /* - * consider all existing roles before configuring psm. - * TODO: reconfigure on interface removal. - */ - if (!wl->ap_count) { - if (is_ap) { - /* Configure for power always on */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - return ret; - } else if (!wl->sta_count) { - if (wl->quirks & WLCORE_QUIRK_NO_ELP) { - /* Configure for power always on */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - return ret; - } else { - /* Configure for ELP power saving */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - if (ret < 0) - return ret; - } - } + /* consider all existing roles before configuring psm. */ + + if (wl->ap_count == 0 && is_ap) { /* first AP */ + /* Configure for power always on */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + if (ret < 0) + return ret; + + /* unmask ap events */ + wl->event_mask |= wl->ap_event_mask; + ret = wl1271_event_unmask(wl); + if (ret < 0) + return ret; + /* first STA, no APs */ + } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { + u8 sta_auth = wl->conf.conn.sta_sleep_auth; + /* Configure for power according to debugfs */ + if (sta_auth != WL1271_PSM_ILLEGAL) + ret = wl1271_acx_sleep_auth(wl, sta_auth); + /* Configure for ELP power saving */ + else + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); + + if (ret < 0) + return ret; } /* Mode specific init */ @@ -669,6 +684,10 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wlcore_cmd_regdomain_config_locked(wl); + if (ret < 0) + return ret; + /* Bluetooth WLAN coexistence */ ret = wl1271_init_pta(wl); if (ret < 0) |
