init.c revision 001e39a8effd5a9774153ca6ca67849a93b95852
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 573df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky if (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL) { 583df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 593df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky CMD_TEMPL_APP_PROBE_REQ_2_4, NULL, 603df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky WL1271_CMD_TEMPL_MAX_SIZE, 613df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky 0, WL1271_RATE_AUTOMATIC); 623df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky if (ret < 0) 633df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky return ret; 643df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky 653df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 663df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky CMD_TEMPL_APP_PROBE_REQ_5, NULL, 673df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky WL1271_CMD_TEMPL_MAX_SIZE, 683df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky 0, WL1271_RATE_AUTOMATIC); 693df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky if (ret < 0) 703df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky return ret; 713df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky } 723df74f46d88e39a032eb2cc3f2a571b66082acbaYoni Divinsky 73cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 74cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_NULL_DATA, NULL, 75bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_null_data_template), 76606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 77f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 78f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 79f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 80cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 81cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_PS_POLL, NULL, 82bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_ps_poll_template), 83606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 84f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 85f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 86f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 87cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 88cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_QOS_NULL_DATA, NULL, 89f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof 9097127e67218e5970a5a7df0513ded730b19a67e9Eliad Peller (struct ieee80211_qos_hdr), 91606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 92f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 93f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 94f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 95cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 96cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_PROBE_RESPONSE, NULL, 97154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 98606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 99f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 100f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 101f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 102cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 103cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_BEACON, NULL, 104154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 105606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 106f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 107f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 108f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 1095ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller max_size = sizeof(struct wl12xx_arp_rsp_template) + 1105ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller WL1271_EXTRA_SPACE_MAX; 111cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 112cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_ARP_RSP, NULL, 1135ec8a448e0e978103bc5ca7136084b5e2b36989eEliad Peller max_size, 114c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 0, WL1271_RATE_AUTOMATIC); 115c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller if (ret < 0) 116c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller return ret; 117c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 11892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* 11992c77c734f958474ac73af670834bc32cb833e54Eliad Peller * Put very large empty placeholders for all templates. These 12092c77c734f958474ac73af670834bc32cb833e54Eliad Peller * reserve memory for later. 12192c77c734f958474ac73af670834bc32cb833e54Eliad Peller */ 122cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 123cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_AP_PROBE_RESPONSE, NULL, 12492c77c734f958474ac73af670834bc32cb833e54Eliad Peller WL1271_CMD_TEMPL_MAX_SIZE, 12592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 12692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 12792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 12892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 129cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 130cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_AP_BEACON, NULL, 13192c77c734f958474ac73af670834bc32cb833e54Eliad Peller WL1271_CMD_TEMPL_MAX_SIZE, 13292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 13392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 13492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 13592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 136cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 137cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_DEAUTH_AP, NULL, 13892c77c734f958474ac73af670834bc32cb833e54Eliad Peller sizeof 13992c77c734f958474ac73af670834bc32cb833e54Eliad Peller (struct wl12xx_disconn_template), 14092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 14192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 14292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 14392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 144001e39a8effd5a9774153ca6ca67849a93b95852Eliad Peller for (i = 0; i < WLCORE_MAX_KLV_TEMPLATES; i++) { 145cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, 146cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_KLV, NULL, 14797127e67218e5970a5a7df0513ded730b19a67e9Eliad Peller sizeof(struct ieee80211_qos_hdr), 14897127e67218e5970a5a7df0513ded730b19a67e9Eliad Peller i, WL1271_RATE_AUTOMATIC); 149bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen if (ret < 0) 150bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen return ret; 151bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen } 152bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen 153f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 154f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 155f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 15687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_init_deauth_template(struct wl1271 *wl, 15787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif) 158e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 159e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct wl12xx_disconn_template *tmpl; 160e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 161af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 162e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 163e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); 164e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!tmpl) { 165e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 166e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 167e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 168e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 169e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 170e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_DEAUTH); 171e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 17287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 173cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, wlvif->role_id, 174cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_DEAUTH_AP, 175af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller tmpl, sizeof(*tmpl), 0, rate); 176e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 177e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 178e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(tmpl); 179e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 180e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 181e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 182784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_null_template(struct wl1271 *wl, 183784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 184e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 18587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 186e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_hdr_3addr *nullfunc; 187e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 188af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 189e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 190e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); 191e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!nullfunc) { 192e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 193e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 194e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 195e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 196e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 197e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_NULLFUNC | 198e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 199e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 200e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* nullfunc->addr1 is filled by FW */ 201e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 202784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); 203784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(nullfunc->addr3, vif->addr, ETH_ALEN); 204e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 20587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 206cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, wlvif->role_id, 207cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_NULL_DATA, nullfunc, 208af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller sizeof(*nullfunc), 0, rate); 209e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 210e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 211e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(nullfunc); 212e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 213e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 214e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 215784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_qos_null_template(struct wl1271 *wl, 216784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 217e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 21887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 219e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_qos_hdr *qosnull; 220e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 221af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 222e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 223e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); 224e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!qosnull) { 225e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 226e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 227e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 228e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 229e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 230e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_QOS_NULLFUNC | 231e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 232e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 233e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* qosnull->addr1 is filled by FW */ 234e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 235784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(qosnull->addr2, vif->addr, ETH_ALEN); 236784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(qosnull->addr3, vif->addr, ETH_ALEN); 237e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 23887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 239cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller ret = wl1271_cmd_template_set(wl, wlvif->role_id, 240cdaac6281170ee2934ad443cb60fbdd6cf318b64Eliad Peller CMD_TEMPL_QOS_NULL_DATA, qosnull, 241af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller sizeof(*qosnull), 0, rate); 242e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 243e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 244e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(qosnull); 245e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 246e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 247e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 24892c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_rx_config(struct wl1271 *wl) 249e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 250e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 251e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 25292c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_acx_rx_msdu_life_time(wl); 253e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 254e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 255e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 256e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 257e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 258e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 2590603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_phy_vif_config(struct wl1271 *wl, 2600603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 261f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2640603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_slot(wl, wlvif, DEFAULT_SLOT_TIME); 265f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 266f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2680603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_service_period_timeout(wl, wlvif); 269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2720603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rts_threshold(wl, wlvif, wl->hw->wiphy->rts_threshold); 273f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 279a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsovstatic int wl1271_init_sta_beacon_filter(struct wl1271 *wl, 280a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov struct wl12xx_vif *wlvif) 281f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 282f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 283f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 284a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_acx_beacon_filter_table(wl, wlvif); 285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 287f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 288a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov /* enable beacon filtering */ 289a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); 290f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 291f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 292f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 293f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 294f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 295f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 29612419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_pta(struct wl1271 *wl) 297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3003be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller ret = wl12xx_acx_sg_cfg(wl); 301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 302f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 303f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3047fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); 305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 306f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 307f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 31112419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_energy_detection(struct wl1271 *wl) 312f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 313f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 314f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 315f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_cca_threshold(wl); 316f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 317f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 318f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 319f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 320f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 321f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3220603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_init_beacon_broadcast(struct wl1271 *wl, 3230603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 324f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 325f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 326f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3270603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_bcn_dtim_options(wl, wlvif); 328f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 329f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 330f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 331f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 332f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 333f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 33495dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yarivstatic int wl12xx_init_fwlog(struct wl1271 *wl) 33595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv{ 33695dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv int ret; 33795dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 3386f7dd16cb125468a5393861c22fbecfb52dd9653Luciano Coelho if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) 33995dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return 0; 34095dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 34195dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv ret = wl12xx_cmd_config_fwlog(wl); 34295dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv if (ret < 0) 34395dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return ret; 34495dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 34595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return 0; 34695dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv} 34795dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 34892c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic sta initialization (non vif-specific) */ 34930d0c8fd5b87d1c5486705d6420545a21533e115Eliad Pellerstatic int wl1271_sta_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 350e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 351e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 352e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 353c8bde243421d759844264cf11e4248e7862c2722Eliad Peller /* PS config */ 354d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller ret = wl12xx_acx_config_ps(wl, wlvif); 355c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) 356c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 357c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 358ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi /* FM WLAN coexistence */ 359ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi ret = wl1271_acx_fm_coex(wl); 360ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi if (ret < 0) 361ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi return ret; 362ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 36330d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_acx_sta_rate_policies(wl, wlvif); 364e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 365e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 366e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 367e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 368e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 369e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 3700603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_sta_hw_init_post_mem(struct wl1271 *wl, 3710603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct ieee80211_vif *vif) 372e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 3730603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 374001e39a8effd5a9774153ca6ca67849a93b95852Eliad Peller int ret; 375e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 376e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable the keep-alive feature */ 3770603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); 378e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 379e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 380e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 381e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 382e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 383e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 38492c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic ap initialization (non vif-specific) */ 38587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 386e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 38770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int ret; 388e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 38987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_init_ap_rates(wl, wlvif); 390e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 392e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 393e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 395e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 396784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerint wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif) 397e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 39887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 400e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 40187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_init_deauth_template(wl, wlvif); 402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 404e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 405784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_null_template(wl, vif); 406e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 407e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 408e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 409784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_qos_null_template(wl, vif); 410e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 411e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 412e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 413521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov /* 414521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * when operating as AP we want to receive external beacons for 415521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * configuring ERP protection. 416521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov */ 4170603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 418521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov if (ret < 0) 419521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov return ret; 420521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov 421e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 422e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 423e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 424784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl, 425784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 426c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov{ 427784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller return wl1271_ap_init_templates(wl, vif); 428c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov} 429c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov 43087fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerint wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) 43170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov{ 43270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int i, ret; 43370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov struct conf_tx_rate_class rc; 43470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov u32 supported_rates; 43570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 43687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", 43787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wlvif->basic_rate_set); 43870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 43987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if (wlvif->basic_rate_set == 0) 44070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return -EINVAL; 44170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 44287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wlvif->basic_rate_set; 44370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 44470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 44570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 446e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx); 44770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 44870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 44970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 45070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* use the min basic rate for AP broadcast/multicast */ 45187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 45270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 45370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 45470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 455e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx); 45670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 45770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 45870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 45970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* 46070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * If the basic rates contain OFDM rates, use OFDM only 46170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * rates for unicast TX as well. Else use all supported rates. 46270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov */ 46387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) 46470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_OFDM_RATES; 46570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov else 46670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_AP_ENABLED_RATES; 46770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 4681a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov /* unconditionally enable HT rates */ 4691a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov supported_rates |= CONF_TX_MCS_RATES; 4701a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov 471ebc7e57ddd01ffa4c996dde7095746259693755dArik Nemtsov /* get extra MIMO or wide-chan rates where the HW supports it */ 472ebc7e57ddd01ffa4c996dde7095746259693755dArik Nemtsov supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); 473ebc7e57ddd01ffa4c996dde7095746259693755dArik Nemtsov 47470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* configure unicast TX rate classes */ 47570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { 47670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = supported_rates; 47770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 47870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 47970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 480e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, 481e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller wlvif->ap.ucast_rate_idx[i]); 48270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 48370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 48470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov } 48570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 48670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return 0; 48770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov} 48870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 489536129c8ad35de87ff2f864f205a54ac32bfebccEliad Pellerstatic int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) 4904b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 4914b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* Reset the BA RX indicators */ 492d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_allowed = true; 4930f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov wl->ba_rx_session_count = 0; 4944b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 4950f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* BA is supported in STA/AP modes */ 496536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller if (wlvif->bss_type != BSS_TYPE_AP_BSS && 497536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller wlvif->bss_type != BSS_TYPE_STA_BSS) { 498d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = false; 4990f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov return 0; 5000f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov } 5014b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 502d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = true; 5034b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5040f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* 802.11n initiator BA session setting */ 5050603d891c5b5153f667a79357d4652824c22b54eEliad Peller return wl12xx_acx_set_ba_initiator_policy(wl, wlvif); 5064b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 5074b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 50892c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specifc initialization */ 5090603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 51092c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 51192c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 51292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5130603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0); 51492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 51592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 51692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 51792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Initialize connection monitoring thresholds */ 5180603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_conn_monit_params(wl, wlvif, false); 51992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52292c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacon filtering */ 523a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_init_sta_beacon_filter(wl, wlvif); 52492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacons and broadcast settings */ 5280603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_init_beacon_broadcast(wl, wlvif); 52992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 53292c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure rssi/snr averaging weights */ 5330603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif); 53492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 53792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 53892c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 53992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54092c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specific intialization */ 5410603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 54292c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 54392c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 54492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5450603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ap_max_tx_retry(wl, wlvif); 54692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 54792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 54892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* initialize Tx power */ 5506bd650299046f00df6d7374c7f61c5afe6df6696Eliad Peller ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level); 55192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 55292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 55392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 55492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 55592c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 55692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 55792c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) 558f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 55987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 560243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo struct conf_tx_ac_category *conf_ac; 561f2054df5170734eacd1db82138c70746ec8387deKalle Valo struct conf_tx_tid *conf_tid; 562536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 56392c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret, i; 56492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5652f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* consider all existing roles before configuring psm. */ 5662f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov 5672f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (wl->ap_count == 0 && is_ap) { /* first AP */ 5682f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for power always on */ 5692f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 5702f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (ret < 0) 5712f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov return ret; 5722f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* first STA, no APs */ 5732f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { 5742f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov u8 sta_auth = wl->conf.conn.sta_sleep_auth; 5752f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for power according to debugfs */ 5762f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (sta_auth != WL1271_PSM_ILLEGAL) 5772f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov ret = wl1271_acx_sleep_auth(wl, sta_auth); 5782f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for power always on */ 5792f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov else if (wl->quirks & WLCORE_QUIRK_NO_ELP) 580a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 5812f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for ELP power saving */ 5822f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov else 5832f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 5842f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov 5852f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (ret < 0) 5862f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov return ret; 587a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } 588a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller 58992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init */ 59092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) { 59187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_hw_init(wl, wlvif); 59292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 59392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 59492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5950603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_ap_role(wl, wlvif); 59692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 59792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 59892c77c734f958474ac73af670834bc32cb833e54Eliad Peller } else { 59930d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_sta_hw_init(wl, wlvif); 60092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6030603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_sta_role(wl, wlvif); 60492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60692c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 60792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6080603d891c5b5153f667a79357d4652824c22b54eEliad Peller wl12xx_init_phy_vif_config(wl, wlvif); 60992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 61092c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Default TID/AC configuration */ 61192c77c734f958474ac73af670834bc32cb833e54Eliad Peller BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); 61292c77c734f958474ac73af670834bc32cb833e54Eliad Peller for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 61392c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_ac = &wl->conf.tx.ac_conf[i]; 6140603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac, 6150603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->cw_min, conf_ac->cw_max, 6160603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->aifsn, conf_ac->tx_op_limit); 61792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 61892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 61992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 62092c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid = &wl->conf.tx.tid_conf[i]; 6210603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_tid_cfg(wl, wlvif, 62292c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->queue_id, 62392c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->channel_type, 62492c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->tsid, 62592c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ps_scheme, 62692c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ack_policy, 62792c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[0], 62892c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[1]); 62992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 63092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 63192c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 63292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 63392c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure HW encryption */ 6340603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_feature_cfg(wl, wlvif); 63592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 63692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 63792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 63892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init - post mem init */ 63992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) 64092c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_ap_hw_init_post_mem(wl, vif); 64192c77c734f958474ac73af670834bc32cb833e54Eliad Peller else 6420603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_sta_hw_init_post_mem(wl, vif); 64392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 64592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 64692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure initiator BA sessions policies */ 648536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller ret = wl1271_set_ba_policies(wl, wlvif); 64992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 65092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 65192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6528a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov ret = wlcore_hw_init_vif(wl, wlvif); 6538a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov if (ret < 0) 6548a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov return ret; 6558a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov 65692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 65792c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 65892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 65992c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_hw_init(struct wl1271 *wl) 66092c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 66192c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 66292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6639d68d1eea7fb4d05b5bd037da6a66329d640b2f1Luciano Coelho /* Chip-specific hw init */ 6649d68d1eea7fb4d05b5bd037da6a66329d640b2f1Luciano Coelho ret = wl->ops->hw_init(wl); 66548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 66648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 66748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 66892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Init templates */ 66992c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_init_templates_config(wl); 67092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 67192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 672644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen 67392c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_acx_mem_cfg(wl); 67492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 67592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 67692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 67792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure the FW logger */ 67892c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_init_fwlog(wl); 679f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 680f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 681f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 682801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov /* Bluetooth WLAN coexistence */ 683801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_init_pta(wl); 684801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov if (ret < 0) 685801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov return ret; 686801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov 687f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default memory configuration */ 688f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_mem_config(wl); 689f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 690f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 692f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX config */ 69308c1d1c7042330e2280a7718be4ad88c2e8f8268Eliad Peller ret = wl12xx_init_rx_config(wl); 694f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 695f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 696f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 6976e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = wl1271_acx_dco_itrim_params(wl); 6986e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (ret < 0) 6996e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out_free_memmap; 7006e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 701f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Configure TX patch complete interrupt behavior */ 702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_tx_config_options(wl); 703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 704f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 705f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 706f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX complete interrupt pacing */ 707f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_rx_interrupt(wl); 708f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Energy detection */ 712f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_energy_detection(wl); 713f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 714f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 716f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default fragmentation threshold */ 7175f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold); 718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 719f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 721f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Enable data path */ 72294210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho ret = wl1271_cmd_data_path(wl, 1); 723f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 724f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 725f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 72638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen /* configure PM */ 72738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = wl1271_acx_pm_config(wl); 72838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (ret < 0) 72938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out_free_memmap; 73038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 731fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller ret = wl12xx_acx_set_rate_mgmt_params(wl); 732fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller if (ret < 0) 733fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller goto out_free_memmap; 734fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 7359487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller /* configure hangover */ 7369487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller ret = wl12xx_acx_config_hangover(wl); 7379487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller if (ret < 0) 7389487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller goto out_free_memmap; 7399487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 740f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 741f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 742f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap: 743f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wl->target_mem_map); 744344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen wl->target_mem_map = NULL; 745f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 746f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 747f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 748