init.c revision 3df74f46d88e39a032eb2cc3f2a571b66082acba
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 144bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; 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); 374e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret, i; 375e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 376e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable all keep-alive templates */ 377e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 3780603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_config(wl, wlvif, i, 379e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ACX_KEEP_ALIVE_TPL_INVALID); 380e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 381e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 382e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 383e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 384e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable the keep-alive feature */ 3850603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); 386e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 387e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 388e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 389e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 390e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 39292c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic ap initialization (non vif-specific) */ 39387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 39570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int ret; 396e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 39787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_init_ap_rates(wl, wlvif); 398e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 400e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 401e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 404784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerint wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif) 405e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 40687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 407e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 408e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 40987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_init_deauth_template(wl, wlvif); 410e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 411e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 412e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 413784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_null_template(wl, vif); 414e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 415e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 416e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 417784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_qos_null_template(wl, vif); 418e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 419e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 420e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 421521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov /* 422521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * when operating as AP we want to receive external beacons for 423521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * configuring ERP protection. 424521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov */ 4250603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 426521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov if (ret < 0) 427521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov return ret; 428521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov 429e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 430e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 431e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 432784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl, 433784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 434c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov{ 435784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller return wl1271_ap_init_templates(wl, vif); 436c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov} 437c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov 43887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerint wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) 43970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov{ 44070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int i, ret; 44170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov struct conf_tx_rate_class rc; 44270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov u32 supported_rates; 44370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 44487fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", 44587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wlvif->basic_rate_set); 44670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 44787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if (wlvif->basic_rate_set == 0) 44870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return -EINVAL; 44970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 45087fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wlvif->basic_rate_set; 45170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 45270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 45370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 454e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.mgmt_rate_idx); 45570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 45670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 45770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 45870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* use the min basic rate for AP broadcast/multicast */ 45987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 46070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 46170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 46270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 463e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, wlvif->ap.bcast_rate_idx); 46470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 46570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 46670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 46770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* 46870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * If the basic rates contain OFDM rates, use OFDM only 46970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * rates for unicast TX as well. Else use all supported rates. 47070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov */ 47187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) 47270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_OFDM_RATES; 47370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov else 47470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_AP_ENABLED_RATES; 47570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 4761a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov /* unconditionally enable HT rates */ 4771a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov supported_rates |= CONF_TX_MCS_RATES; 4781a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov 479ebc7e57ddd01ffa4c996dde7095746259693755dArik Nemtsov /* get extra MIMO or wide-chan rates where the HW supports it */ 480ebc7e57ddd01ffa4c996dde7095746259693755dArik Nemtsov supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); 481ebc7e57ddd01ffa4c996dde7095746259693755dArik Nemtsov 48270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* configure unicast TX rate classes */ 48370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { 48470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = supported_rates; 48570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 48670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 48770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 488e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller ret = wl1271_acx_ap_rate_policy(wl, &rc, 489e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller wlvif->ap.ucast_rate_idx[i]); 49070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 49170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 49270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov } 49370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 49470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return 0; 49570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov} 49670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 497536129c8ad35de87ff2f864f205a54ac32bfebccEliad Pellerstatic int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) 4984b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 4994b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* Reset the BA RX indicators */ 500d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_allowed = true; 5010f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov wl->ba_rx_session_count = 0; 5024b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5030f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* BA is supported in STA/AP modes */ 504536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller if (wlvif->bss_type != BSS_TYPE_AP_BSS && 505536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller wlvif->bss_type != BSS_TYPE_STA_BSS) { 506d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = false; 5070f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov return 0; 5080f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov } 5094b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 510d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = true; 5114b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 5120f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* 802.11n initiator BA session setting */ 5130603d891c5b5153f667a79357d4652824c22b54eEliad Peller return wl12xx_acx_set_ba_initiator_policy(wl, wlvif); 5144b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 5154b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 51692c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specifc initialization */ 5170603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 51892c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 51992c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 52092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5210603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0); 52292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52592c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Initialize connection monitoring thresholds */ 5260603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_conn_monit_params(wl, wlvif, false); 52792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 53092c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacon filtering */ 531a693534b1a46ee934606cec52b12baeaebba0342Arik Nemtsov ret = wl1271_init_sta_beacon_filter(wl, wlvif); 53292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 53592c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacons and broadcast settings */ 5360603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_init_beacon_broadcast(wl, wlvif); 53792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 54092c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure rssi/snr averaging weights */ 5410603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif); 54292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 54392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 54492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 54692c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 54792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54892c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specific intialization */ 5490603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 55092c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 55192c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 55292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5530603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ap_max_tx_retry(wl, wlvif); 55492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 55592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 55692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 55792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* initialize Tx power */ 5586bd650299046f00df6d7374c7f61c5afe6df6696Eliad Peller ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level); 55992c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 56092c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 56192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 56292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 56392c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 56492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 56592c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) 566f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 56787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 568243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo struct conf_tx_ac_category *conf_ac; 569f2054df5170734eacd1db82138c70746ec8387deKalle Valo struct conf_tx_tid *conf_tid; 570536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 57192c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret, i; 57292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5732f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* consider all existing roles before configuring psm. */ 5742f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov 5752f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (wl->ap_count == 0 && is_ap) { /* first AP */ 5762f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for power always on */ 5772f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 5782f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (ret < 0) 5792f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov return ret; 5802f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* first STA, no APs */ 5812f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { 5822f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov u8 sta_auth = wl->conf.conn.sta_sleep_auth; 5832f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for power according to debugfs */ 5842f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (sta_auth != WL1271_PSM_ILLEGAL) 5852f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov ret = wl1271_acx_sleep_auth(wl, sta_auth); 5862f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for power always on */ 5872f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov else if (wl->quirks & WLCORE_QUIRK_NO_ELP) 588a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 5892f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov /* Configure for ELP power saving */ 5902f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov else 5912f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 5922f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov 5932f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov if (ret < 0) 5942f18cf7c3b99779465def78318b4243d1f66cce8Arik Nemtsov return ret; 595a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } 596a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller 59792c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init */ 59892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) { 59987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_hw_init(wl, wlvif); 60092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6030603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_ap_role(wl, wlvif); 60492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60692c77c734f958474ac73af670834bc32cb833e54Eliad Peller } else { 60730d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_sta_hw_init(wl, wlvif); 60892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 61092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6110603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_sta_role(wl, wlvif); 61292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 61392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 61492c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 61592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6160603d891c5b5153f667a79357d4652824c22b54eEliad Peller wl12xx_init_phy_vif_config(wl, wlvif); 61792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 61892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Default TID/AC configuration */ 61992c77c734f958474ac73af670834bc32cb833e54Eliad Peller BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); 62092c77c734f958474ac73af670834bc32cb833e54Eliad Peller for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 62192c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_ac = &wl->conf.tx.ac_conf[i]; 6220603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac, 6230603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->cw_min, conf_ac->cw_max, 6240603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->aifsn, conf_ac->tx_op_limit); 62592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 62692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 62792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 62892c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid = &wl->conf.tx.tid_conf[i]; 6290603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_tid_cfg(wl, wlvif, 63092c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->queue_id, 63192c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->channel_type, 63292c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->tsid, 63392c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ps_scheme, 63492c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ack_policy, 63592c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[0], 63692c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[1]); 63792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 63892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 63992c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 64092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64192c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure HW encryption */ 6420603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_feature_cfg(wl, wlvif); 64392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 64492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 64592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64692c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init - post mem init */ 64792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) 64892c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_ap_hw_init_post_mem(wl, vif); 64992c77c734f958474ac73af670834bc32cb833e54Eliad Peller else 6500603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_sta_hw_init_post_mem(wl, vif); 65192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 65292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 65392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 65492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 65592c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure initiator BA sessions policies */ 656536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller ret = wl1271_set_ba_policies(wl, wlvif); 65792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 65892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 65992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6608a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov ret = wlcore_hw_init_vif(wl, wlvif); 6618a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov if (ret < 0) 6628a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov return ret; 6638a9affc08d676a9fe627361ab6767cdec0740af3Arik Nemtsov 66492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 66592c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 66692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 66792c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_hw_init(struct wl1271 *wl) 66892c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 66992c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 67092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6719d68d1eea7fb4d05b5bd037da6a66329d640b2f1Luciano Coelho /* Chip-specific hw init */ 6729d68d1eea7fb4d05b5bd037da6a66329d640b2f1Luciano Coelho ret = wl->ops->hw_init(wl); 67348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 67448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 67548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 67692c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Init templates */ 67792c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_init_templates_config(wl); 67892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 67992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 680644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen 68192c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_acx_mem_cfg(wl); 68292c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 68392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 68492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 68592c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure the FW logger */ 68692c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_init_fwlog(wl); 687f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 688f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 689f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 690801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov /* Bluetooth WLAN coexistence */ 691801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_init_pta(wl); 692801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov if (ret < 0) 693801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov return ret; 694801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov 695f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default memory configuration */ 696f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_mem_config(wl); 697f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 698f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 699f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 700f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX config */ 70108c1d1c7042330e2280a7718be4ad88c2e8f8268Eliad Peller ret = wl12xx_init_rx_config(wl); 702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 704f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 7056e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = wl1271_acx_dco_itrim_params(wl); 7066e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (ret < 0) 7076e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out_free_memmap; 7086e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Configure TX patch complete interrupt behavior */ 710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_tx_config_options(wl); 711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 712f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 713f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 714f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX complete interrupt pacing */ 715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_rx_interrupt(wl); 716f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 717f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 719f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Energy detection */ 720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_energy_detection(wl); 721f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 722f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 723f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 724f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default fragmentation threshold */ 7255f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold); 726f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 727f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 728f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 729f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Enable data path */ 73094210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho ret = wl1271_cmd_data_path(wl, 1); 731f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 732f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 733f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 73438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen /* configure PM */ 73538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = wl1271_acx_pm_config(wl); 73638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (ret < 0) 73738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out_free_memmap; 73838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 739fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller ret = wl12xx_acx_set_rate_mgmt_params(wl); 740fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller if (ret < 0) 741fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller goto out_free_memmap; 742fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 7439487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller /* configure hangover */ 7449487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller ret = wl12xx_acx_config_hangover(wl); 7459487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller if (ret < 0) 7469487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller goto out_free_memmap; 7479487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 748f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 749f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 750f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap: 751f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wl->target_mem_map); 752344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen wl->target_mem_map = NULL; 753f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 754f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 755f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 756