init.c revision 8a9affc08d676a9fe627361ab6767cdec0740af3
1f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho/* 2f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This file is part of wl1271 3f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 4f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Copyright (C) 2009 Nokia Corporation 5f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 6f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 8f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This program is free software; you can redistribute it and/or 9f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * modify it under the terms of the GNU General Public License 10f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * version 2 as published by the Free Software Foundation. 11f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 12f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This program is distributed in the hope that it will be useful, but 13f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * WITHOUT ANY WARRANTY; without even the implied warranty of 14f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * General Public License for more details. 16f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 17f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * You should have received a copy of the GNU General Public License 18f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * along with this program; if not, write to the Free Software 19f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 02110-1301 USA 21f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * 22f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho */ 23f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 24f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/kernel.h> 25f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/module.h> 265a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 27f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 280f4e31222a2c0b93f25a87effd2033cb78c7a79cLuciano Coelho#include "debug.h" 2900d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "init.h" 30f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include "wl12xx_80211.h" 3100d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "acx.h" 3200d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "cmd.h" 33e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov#include "tx.h" 3448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi#include "io.h" 358a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov#include "hw_ops.h" 36f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3792c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_templates_config(struct wl1271 *wl) 38f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 39bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen int ret, i; 405ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller size_t max_size; 41f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 42f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* send empty templates for fw memory reservation */ 43cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 44cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 45c08e371a683021cfb99632db799bea9b69d176e5Ido Reis WL1271_CMD_TEMPL_MAX_SIZE, 46606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 47f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 48f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 49f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 50cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 51cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_CFG_PROBE_REQ_5, 52c08e371a683021cfb99632db799bea9b69d176e5Ido Reis NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, 5311eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen WL1271_RATE_AUTOMATIC); 5411eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen if (ret < 0) 5511eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen return ret; 56abb0b3bfb2d2411034b721df21c31964265b851eTeemu Paasikivi 57cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 58cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_NULL_DATA, NULL, 59bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_null_data_template), 60606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 61f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 62f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 63f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 64cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 65cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_PS_POLL, NULL, 66bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_ps_poll_template), 67606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 68f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 69f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 70f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 71cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 72cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_QOS_NULL_DATA, NULL, 73f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof 7497127e67218e5970a5a7df0513ded730b19a67e9Eliad Peller (struct ieee80211_qos_hdr), 75606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 76f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 77f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 78f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 79cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 80cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_PROBE_RESPONSE, NULL, 81154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 82606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 83f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 84f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 85f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 86cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 87cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_BEACON, NULL, 88154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 89606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 90f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 91f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 92f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 935ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller max_size = sizeof(struct wl12xx_arp_rsp_template) + 945ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller WL1271_EXTRA_SPACE_MAX; 95cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 96cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_ARP_RSP, NULL, 975ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller max_size, 98c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 0, WL1271_RATE_AUTOMATIC); 99c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller if (ret < 0) 100c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller return ret; 101c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 10292c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* 10392c77c734f958474ac73af670834bc32cb833e54Eliad Peller * Put very large empty placeholders for all templates. These 10492c77c734f958474ac73af670834bc32cb833e54Eliad Peller * reserve memory for later. 10592c77c734f958474ac73af670834bc32cb833e54Eliad Peller */ 106cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 107cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_AP_PROBE_RESPONSE, NULL, 10892c77c734f958474ac73af670834bc32cb833e54Eliad Peller WL1271_CMD_TEMPL_MAX_SIZE, 10992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 11092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 11192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 11292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 113cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 114cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_AP_BEACON, NULL, 11592c77c734f958474ac73af670834bc32cb833e54Eliad Peller WL1271_CMD_TEMPL_MAX_SIZE, 11692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 11792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 11892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 11992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 120cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 121cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_DEAUTH_AP, NULL, 12292c77c734f958474ac73af670834bc32cb833e54Eliad Peller sizeof 12392c77c734f958474ac73af670834bc32cb833e54Eliad Peller (struct wl12xx_disconn_template), 12492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 12592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 12692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 12792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 128bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 129cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 130cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_KLV, NULL, 13197127e67218e5970a5a7df0513ded730b19a67e9Eliad Peller sizeof(struct ieee80211_qos_hdr), 13297127e67218e5970a5a7df0513ded730b19a67e9Eliad Peller i, WL1271_RATE_AUTOMATIC); 133bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen if (ret < 0) 134bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen return ret; 135bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen } 136bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen 137f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 138f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 139f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 14087fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_init_deauth_template(struct wl1271 *wl, 14187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif) 142e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 143e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct wl12xx_disconn_template *tmpl; 144e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 145af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 146e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 147e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); 148e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!tmpl) { 149e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 150e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 151e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 152e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 153e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 154e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_DEAUTH); 155e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 15687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 157cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, wlvif->role_id, 158cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_DEAUTH_AP, 159af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller tmpl, sizeof(*tmpl), 0, rate); 160e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 161e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 162e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(tmpl); 163e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 164e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 165e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 166784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_null_template(struct wl1271 *wl, 167784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 168e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 16987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 170e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_hdr_3addr *nullfunc; 171e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 172af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 173e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 174e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); 175e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!nullfunc) { 176e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 177e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 178e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 179e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 180e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 181e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_NULLFUNC | 182e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 183e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 184e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* nullfunc->addr1 is filled by FW */ 185e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 186784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); 187784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(nullfunc->addr3, vif->addr, ETH_ALEN); 188e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 18987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 190cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, wlvif->role_id, 191cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_NULL_DATA, nullfunc, 192af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller sizeof(*nullfunc), 0, rate); 193e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 194e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 195e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(nullfunc); 196e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 197e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 198e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 199784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_qos_null_template(struct wl1271 *wl, 200784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 201e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 20287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 203e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_qos_hdr *qosnull; 204e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 205af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 206e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 207e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); 208e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!qosnull) { 209e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 210e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 211e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 212e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 213e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 214e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_QOS_NULLFUNC | 215e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 216e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 217e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* qosnull->addr1 is filled by FW */ 218e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 219784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(qosnull->addr2, vif->addr, ETH_ALEN); 220784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(qosnull->addr3, vif->addr, ETH_ALEN); 221e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 22287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 223cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, wlvif->role_id, 224cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_QOS_NULL_DATA, qosnull, 225af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller sizeof(*qosnull), 0, rate); 226e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 227e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 228e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(qosnull); 229e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 230e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 231e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 23292c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_rx_config(struct wl1271 *wl) 233e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 234e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 235e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 23692c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_acx_rx_msdu_life_time(wl); 237e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 238e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 239e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 240e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 241e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 242e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 2430603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_phy_vif_config(struct wl1271 *wl, 2440603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 245f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2480603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_slot(wl, wlvif, DEFAULT_SLOT_TIME); 249f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 250f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 251f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2520603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_service_period_timeout(wl, wlvif); 253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2560603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rts_threshold(wl, wlvif, wl->hw->wiphy->rts_threshold); 257f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 260f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 261f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 263a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsovstatic int wl1271_init_sta_beacon_filter(struct wl1271 *wl, 264a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov struct wl12xx_vif *wlvif) 265f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 266f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 268a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_acx_beacon_filter_table(wl, wlvif); 269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 272a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov /* enable beacon filtering */ 273a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); 274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 28012419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_pta(struct wl1271 *wl) 281f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 282f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 283f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2843be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller ret = wl12xx_acx_sg_cfg(wl); 285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 287f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2887fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); 289f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 290f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 291f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 292f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 293f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 294f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 29512419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_energy_detection(struct wl1271 *wl) 296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_cca_threshold(wl); 300f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 302f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 303f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 304f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3060603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_init_beacon_broadcast(struct wl1271 *wl, 3070603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3110603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_bcn_dtim_options(wl, wlvif); 312f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 313f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 314f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 315f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 316f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 317f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 31895dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yarivstatic int wl12xx_init_fwlog(struct wl1271 *wl) 31995dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv{ 32095dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv int ret; 32195dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 3226f7dd16cb125468a5393861c22fbecfb52dd9653Luciano Coelho if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) 32395dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return 0; 32495dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 32595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv ret = wl12xx_cmd_config_fwlog(wl); 32695dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv if (ret < 0) 32795dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return ret; 32895dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 32995dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return 0; 33095dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv} 33195dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 33292c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic sta initialization (non vif-specific) */ 33330d0c8fd5b87d1c5486705d6420545a21533e115Eliad Pellerstatic int wl1271_sta_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 334e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 335e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 336e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 337c8bde243421d759844264cf11e4248e7862c2722Eliad Peller /* PS config */ 338d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller ret = wl12xx_acx_config_ps(wl, wlvif); 339c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) 340c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 341c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 342ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi /* FM WLAN coexistence */ 343ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi ret = wl1271_acx_fm_coex(wl); 344ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi if (ret < 0) 345ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi return ret; 346ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 34730d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_acx_sta_rate_policies(wl, wlvif); 348e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 349e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 350e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 351e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 352e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 353e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 3540603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_sta_hw_init_post_mem(struct wl1271 *wl, 3550603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct ieee80211_vif *vif) 356e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 3570603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 358e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret, i; 359e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 360e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable all keep-alive templates */ 361e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 3620603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_config(wl, wlvif, i, 363e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ACX_KEEP_ALIVE_TPL_INVALID); 364e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 365e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 366e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 367e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 368e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable the keep-alive feature */ 3690603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); 370e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 371e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 372e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 373e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 374e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 375e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 37692c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic ap initialization (non vif-specific) */ 37787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 378e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 37970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int ret; 380e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 38187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_init_ap_rates(wl, wlvif); 382e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 383e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 384e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 385e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 386e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 387e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 388784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerint wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif) 389e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 39087fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 392e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 39387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_init_deauth_template(wl, wlvif); 394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 395e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 396e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 397784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_null_template(wl, vif); 398e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 400e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 401784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_qos_null_template(wl, vif); 402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 404e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 405521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov /* 406521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * when operating as AP we want to receive external beacons for 407521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * configuring ERP protection. 408521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov */ 4090603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 410521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov if (ret < 0) 411521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov return ret; 412521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov 413e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 414e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 415e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 416784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl, 417784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 418c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov{ 419784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller return wl1271_ap_init_templates(wl, vif); 420c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov} 421c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov 42287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerint wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) 42370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov{ 42470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int i, ret; 42570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov struct conf_tx_rate_class rc; 42670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov u32 supported_rates; 42770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 42887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", 42987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wlvif->basic_rate_set); 43070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 43187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if (wlvif->basic_rate_set == 0) 43270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return -EINVAL; 43370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 43487fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wlvif->basic_rate_set; 43570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 43670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 43770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 438e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx); 43970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 44070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 44170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 44270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* use the min basic rate for AP broadcast/multicast */ 44387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 44470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 44570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 44670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 447e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx); 44870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 44970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 45070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 45170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* 45270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * If the basic rates contain OFDM rates, use OFDM only 45370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * rates for unicast TX as well. Else use all supported rates. 45470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov */ 45587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) 45670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_OFDM_RATES; 45770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov else 45870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_AP_ENABLED_RATES; 45970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 4601a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov /* unconditionally enable HT rates */ 4611a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov supported_rates |= CONF_TX_MCS_RATES; 4621a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov 46370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* configure unicast TX rate classes */ 46470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { 46570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = supported_rates; 46670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 46770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 46870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 469e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, 470e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller wlvif->ap.ucast_rate_idx[i]); 47170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 47270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 47370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov } 47470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 47570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return 0; 47670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov} 47770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 478536129c8ad35de87ff2f864f205a54ac32bfebccEliad Pellerstatic int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) 4794b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 4804b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* Reset the BA RX indicators */ 481d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_allowed = true; 4820f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov wl->ba_rx_session_count = 0; 4834b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 4840f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* BA is supported in STA/AP modes */ 485536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller if (wlvif->bss_type != BSS_TYPE_AP_BSS && 486536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller wlvif->bss_type != BSS_TYPE_STA_BSS) { 487d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = false; 4880f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov return 0; 4890f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov } 4904b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 491d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = true; 4924b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 4930f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* 802.11n initiator BA session setting */ 4940603d891c5b5153f667a79357d4652824c22b54eEliad Peller return wl12xx_acx_set_ba_initiator_policy(wl, wlvif); 4954b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 4964b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 49792c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specifc initialization */ 4980603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 49992c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 50092c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 50192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5020603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0); 50392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 50492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 50592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 50692c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Initialize connection monitoring thresholds */ 5070603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_conn_monit_params(wl, wlvif, false); 50892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 50992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 51092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 51192c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacon filtering */ 512a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_init_sta_beacon_filter(wl, wlvif); 51392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 51492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 51592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 51692c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacons and broadcast settings */ 5170603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_init_beacon_broadcast(wl, wlvif); 51892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 51992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 52192c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure rssi/snr averaging weights */ 5220603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif); 52392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 52792c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 52892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52992c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specific intialization */ 5300603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 53192c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 53292c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 53392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5340603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ap_max_tx_retry(wl, wlvif); 53592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 53892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* initialize Tx power */ 5396bd650299046f00df6d7374c7f61c5afe6df6696Eliad Peller ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level); 54092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 54192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 54292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 54492c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 54592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54692c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) 547f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 54887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 549243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo struct conf_tx_ac_category *conf_ac; 550f2054df5170734eacd1db82138c70746ec8387deKalle Valo struct conf_tx_tid *conf_tid; 551536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 55292c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret, i; 55392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 554a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller /* 555a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller * consider all existing roles before configuring psm. 556a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller * TODO: reconfigure on interface removal. 557a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller */ 558a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (!wl->ap_count) { 559a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (is_ap) { 560a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller /* Configure for power always on */ 561a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 562a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (ret < 0) 563a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller return ret; 564a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } else if (!wl->sta_count) { 565441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho if (wl->quirks & WLCORE_QUIRK_NO_ELP) { 566441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho /* Configure for power always on */ 567441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 568441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho if (ret < 0) 569441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho return ret; 570441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho } else { 571441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho /* Configure for ELP power saving */ 572441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 573441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho if (ret < 0) 574441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho return ret; 575441101f67818cf5aaba7081fb05c8604a55c0949Luciano Coelho } 576a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } 577a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } 578a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller 57992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init */ 58092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) { 58187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_hw_init(wl, wlvif); 58292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 58392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 58492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5850603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_ap_role(wl, wlvif); 58692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 58792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 58892c77c734f958474ac73af670834bc32cb833e54Eliad Peller } else { 58930d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_sta_hw_init(wl, wlvif); 59092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 59192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 59292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5930603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_sta_role(wl, wlvif); 59492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 59592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 59692c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 59792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5980603d891c5b5153f667a79357d4652824c22b54eEliad Peller wl12xx_init_phy_vif_config(wl, wlvif); 59992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 60092c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Default TID/AC configuration */ 60192c77c734f958474ac73af670834bc32cb833e54Eliad Peller BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); 60292c77c734f958474ac73af670834bc32cb833e54Eliad Peller for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 60392c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_ac = &wl->conf.tx.ac_conf[i]; 6040603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac, 6050603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->cw_min, conf_ac->cw_max, 6060603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->aifsn, conf_ac->tx_op_limit); 60792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 61092c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid = &wl->conf.tx.tid_conf[i]; 6110603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_tid_cfg(wl, wlvif, 61292c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->queue_id, 61392c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->channel_type, 61492c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->tsid, 61592c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ps_scheme, 61692c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ack_policy, 61792c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[0], 61892c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[1]); 61992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 62092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 62192c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 62292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 62392c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure HW encryption */ 6240603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_feature_cfg(wl, wlvif); 62592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 62692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 62792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 62892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init - post mem init */ 62992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) 63092c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_ap_hw_init_post_mem(wl, vif); 63192c77c734f958474ac73af670834bc32cb833e54Eliad Peller else 6320603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_sta_hw_init_post_mem(wl, vif); 63392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 63492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 63592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 63692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 63792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure initiator BA sessions policies */ 638536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller ret = wl1271_set_ba_policies(wl, wlvif); 63992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 64092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 64192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6428a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov ret = wlcore_hw_init_vif(wl, wlvif); 6438a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov if (ret < 0) 6448a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov return ret; 6458a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov 64692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 64792c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 64892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64992c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_hw_init(struct wl1271 *wl) 65092c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 65192c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 65292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6539d68d1eea7fb4d05b5bd037da6a66329d640b2f1Luciano Coelho /* Chip-specific hw init */ 6549d68d1eea7fb4d05b5bd037da6a66329d640b2f1Luciano Coelho ret = wl->ops->hw_init(wl); 65548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 65648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 65748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 65892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Init templates */ 65992c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_init_templates_config(wl); 66092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 66192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 662644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen 66392c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_acx_mem_cfg(wl); 66492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 66592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 66692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 66792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure the FW logger */ 66892c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_init_fwlog(wl); 669f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 670f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 671f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 672801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov /* Bluetooth WLAN coexistence */ 673801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_init_pta(wl); 674801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov if (ret < 0) 675801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov return ret; 676801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov 677f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default memory configuration */ 678f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_mem_config(wl); 679f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 680f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 681f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 682f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX config */ 68308c1d1c7042330e2280a7718be4ad88c2e8f8268Eliad Peller ret = wl12xx_init_rx_config(wl); 684f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 685f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 686f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6876e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = wl1271_acx_dco_itrim_params(wl); 6886e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (ret < 0) 6896e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out_free_memmap; 6906e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Configure TX patch complete interrupt behavior */ 692f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_tx_config_options(wl); 693f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 694f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 695f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 696f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX complete interrupt pacing */ 697f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_rx_interrupt(wl); 698f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 699f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 700f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 701f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Energy detection */ 702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_energy_detection(wl); 703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 704f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 705f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 706f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default fragmentation threshold */ 7075f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold); 708f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Enable data path */ 71294210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho ret = wl1271_cmd_data_path(wl, 1); 713f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 714f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 71638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen /* configure PM */ 71738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = wl1271_acx_pm_config(wl); 71838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (ret < 0) 71938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out_free_memmap; 72038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 721fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller ret = wl12xx_acx_set_rate_mgmt_params(wl); 722fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller if (ret < 0) 723fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller goto out_free_memmap; 724fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 7259487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller /* configure hangover */ 7269487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller ret = wl12xx_acx_config_hangover(wl); 7279487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller if (ret < 0) 7289487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller goto out_free_memmap; 7299487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 730f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 731f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 732f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap: 733f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wl->target_mem_map); 734344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen wl->target_mem_map = NULL; 735f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 736f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 737f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 738