init.c revision 6bd650299046f00df6d7374c7f61c5afe6df6696
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 2800d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "init.h" 29f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include "wl12xx_80211.h" 3000d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "acx.h" 3100d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "cmd.h" 3200d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "reg.h" 33e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov#include "tx.h" 3448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi#include "io.h" 35f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3692c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_templates_config(struct wl1271 *wl) 37f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 38bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen int ret, i; 39f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 40f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* send empty templates for fw memory reservation */ 41f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 42154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 43606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 44f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 45f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 46f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 4711eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 48154037d1681caaff7d33521b84017ee58b396438Eliad Peller NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0, 4911eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen WL1271_RATE_AUTOMATIC); 5011eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen if (ret < 0) 5111eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen return ret; 52abb0b3bfb2d2411034b721df21c31964265b851eTeemu Paasikivi 53f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 54bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_null_data_template), 55606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 56f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 57f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 58f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 59f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, 60bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen sizeof(struct wl12xx_ps_poll_template), 61606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 62f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 63f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 64f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 65f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 66f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho sizeof 67bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen (struct wl12xx_qos_null_data_template), 68606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 69f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 70f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 71f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 72f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, 73154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 74606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 75f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 76f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 77f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 78f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, 79154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, 80606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen 0, WL1271_RATE_AUTOMATIC); 81f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 82f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 83f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 84c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL, 85c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller sizeof 86c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller (struct wl12xx_arp_rsp_template), 87c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 0, WL1271_RATE_AUTOMATIC); 88c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller if (ret < 0) 89c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller return ret; 90c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller 9192c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* 9292c77c734f958474ac73af670834bc32cb833e54Eliad Peller * Put very large empty placeholders for all templates. These 9392c77c734f958474ac73af670834bc32cb833e54Eliad Peller * reserve memory for later. 9492c77c734f958474ac73af670834bc32cb833e54Eliad Peller */ 9592c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL, 9692c77c734f958474ac73af670834bc32cb833e54Eliad Peller WL1271_CMD_TEMPL_MAX_SIZE, 9792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 9892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 9992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 10092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 10192c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL, 10292c77c734f958474ac73af670834bc32cb833e54Eliad Peller WL1271_CMD_TEMPL_MAX_SIZE, 10392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 10492c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 10592c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 10692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 10792c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL, 10892c77c734f958474ac73af670834bc32cb833e54Eliad Peller sizeof 10992c77c734f958474ac73af670834bc32cb833e54Eliad Peller (struct wl12xx_disconn_template), 11092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 0, WL1271_RATE_AUTOMATIC); 11192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 11292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 11392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 114bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 115bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, 116154037d1681caaff7d33521b84017ee58b396438Eliad Peller WL1271_CMD_TEMPL_DFLT_SIZE, i, 117606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen WL1271_RATE_AUTOMATIC); 118bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen if (ret < 0) 119bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen return ret; 120bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen } 121bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen 122f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 123f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 124f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 12587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_init_deauth_template(struct wl1271 *wl, 12687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif) 127e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 128e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct wl12xx_disconn_template *tmpl; 129e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 130af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 131e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 132e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); 133e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!tmpl) { 134e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 135e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 136e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 137e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 138e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 139e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_DEAUTH); 140e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 14187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 142e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, 143af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller tmpl, sizeof(*tmpl), 0, rate); 144e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 145e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 146e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(tmpl); 147e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 148e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 149e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 150784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_null_template(struct wl1271 *wl, 151784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 152e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 15387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 154e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov struct ieee80211_hdr_3addr *nullfunc; 155e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 156af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 157e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 158e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); 159e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!nullfunc) { 160e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 161e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 162e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 163e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 164e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 165e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_NULLFUNC | 166e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 167e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 168e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* nullfunc->addr1 is filled by FW */ 169e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 170784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); 171784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(nullfunc->addr3, vif->addr, ETH_ALEN); 172e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 17387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 174e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, 175af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller sizeof(*nullfunc), 0, rate); 176e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 177e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 178e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(nullfunc); 179e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 180e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 181e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 182784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_qos_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_qos_hdr *qosnull; 187e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 188af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller u32 rate; 189e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 190e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); 191e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (!qosnull) { 192e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = -ENOMEM; 193e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov goto out; 194e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 195e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 196e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | 197e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_STYPE_QOS_NULLFUNC | 198e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov IEEE80211_FCTL_FROMDS); 199e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 200e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* qosnull->addr1 is filled by FW */ 201e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 202784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(qosnull->addr2, vif->addr, ETH_ALEN); 203784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller memcpy(qosnull->addr3, vif->addr, ETH_ALEN); 204e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 20587fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 206e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, 207af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller sizeof(*qosnull), 0, rate); 208e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 209e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout: 210e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov kfree(qosnull); 211e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 212e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 213e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 21492c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_rx_config(struct wl1271 *wl) 215e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 216e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 217e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 21892c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_acx_rx_msdu_life_time(wl); 219e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 220e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 221e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 222e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 223e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 224e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 22592c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_phy_config(struct wl1271 *wl) 226f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 227f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 228f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 22992c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_acx_pd_threshold(wl); 230f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 231f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 232f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 233f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 234f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 235f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2360603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_phy_vif_config(struct wl1271 *wl, 2370603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 238f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 239f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 240f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2410603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_slot(wl, wlvif, DEFAULT_SLOT_TIME); 242f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 243f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 244f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2450603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_service_period_timeout(wl, wlvif); 246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 248f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2490603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rts_threshold(wl, wlvif, wl->hw->wiphy->rts_threshold); 250f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 251f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 252f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2560603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_init_beacon_filter(struct wl1271 *wl, 2570603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 260f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2611922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen /* disable beacon filtering at this stage */ 2620603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 264f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 265f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2660603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_beacon_filter_table(wl, wlvif); 267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 268f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 272f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 27312419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_pta(struct wl1271 *wl) 274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2773be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller ret = wl12xx_acx_sg_cfg(wl); 278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 280f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2817fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); 282f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 283f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 284f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 287f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 28812419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_energy_detection(struct wl1271 *wl) 289f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 290f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 291f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 292f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_cca_threshold(wl); 293f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 294f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 295f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 2990603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_init_beacon_broadcast(struct wl1271 *wl, 3000603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif) 301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 302f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho int ret; 303f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 3040603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_bcn_dtim_options(wl, wlvif); 305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 306f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 307f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 31195dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yarivstatic int wl12xx_init_fwlog(struct wl1271 *wl) 31295dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv{ 31395dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv int ret; 31495dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 31595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) 31695dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return 0; 31795dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 31895dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv ret = wl12xx_cmd_config_fwlog(wl); 31995dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv if (ret < 0) 32095dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return ret; 32195dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 32295dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv return 0; 32395dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv} 32495dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv 32592c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic sta initialization (non vif-specific) */ 32630d0c8fd5b87d1c5486705d6420545a21533e115Eliad Pellerstatic int wl1271_sta_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 327e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 328e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 329e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 33049d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (wl->chip.id != CHIP_ID_1283_PG20) { 33149d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl1271_cmd_ext_radio_parms(wl); 33249d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (ret < 0) 33349d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi return ret; 33449d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi } 335e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 336c8bde243421d759844264cf11e4248e7862c2722Eliad Peller /* PS config */ 337d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller ret = wl12xx_acx_config_ps(wl, wlvif); 338c8bde243421d759844264cf11e4248e7862c2722Eliad Peller if (ret < 0) 339c8bde243421d759844264cf11e4248e7862c2722Eliad Peller return ret; 340c8bde243421d759844264cf11e4248e7862c2722Eliad Peller 341ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi /* FM WLAN coexistence */ 342ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi ret = wl1271_acx_fm_coex(wl); 343ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi if (ret < 0) 344ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi return ret; 345ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi 34630d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_acx_sta_rate_policies(wl, wlvif); 347e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 348e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 349e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 350e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 351e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 352e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 3530603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl1271_sta_hw_init_post_mem(struct wl1271 *wl, 3540603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct ieee80211_vif *vif) 355e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 3560603d891c5b5153f667a79357d4652824c22b54eEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 357e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret, i; 358e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 359e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable all keep-alive templates */ 360e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 3610603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_config(wl, wlvif, i, 362e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov ACX_KEEP_ALIVE_TPL_INVALID); 363e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 364e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 365e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov } 366e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 367e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov /* disable the keep-alive feature */ 3680603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); 369e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 370e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 371e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 372e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 373e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 374e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 37592c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic ap initialization (non vif-specific) */ 37687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerstatic int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif) 377e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 37870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int ret; 379e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 38087fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_init_ap_rates(wl, wlvif); 381e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 382e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 383e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 384e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 385e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 386e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 387784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerint wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif) 388e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{ 38987fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 390e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov int ret; 391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 39287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_init_deauth_template(wl, wlvif); 393e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 395e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 396784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_null_template(wl, vif); 397e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 398e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 400784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller ret = wl1271_ap_init_qos_null_template(wl, vif); 401e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov if (ret < 0) 402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return ret; 403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 404521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov /* 405521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * when operating as AP we want to receive external beacons for 406521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov * configuring ERP protection. 407521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov */ 4080603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 409521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov if (ret < 0) 410521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov return ret; 411521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov 412e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov return 0; 413e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov} 414e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov 415784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl, 416784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller struct ieee80211_vif *vif) 417c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov{ 418784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller return wl1271_ap_init_templates(wl, vif); 419c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov} 420c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov 42187fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Pellerint wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) 42270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov{ 42370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov int i, ret; 42470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov struct conf_tx_rate_class rc; 42570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov u32 supported_rates; 42670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 42787fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", 42887fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller wlvif->basic_rate_set); 42970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 43087fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if (wlvif->basic_rate_set == 0) 43170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return -EINVAL; 43270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 43387fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wlvif->basic_rate_set; 43470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 43570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 43670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 43770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE); 43870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 43970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 44070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 44170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* use the min basic rate for AP broadcast/multicast */ 44287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller rc.enabled_rates = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); 44370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 44470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 44570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 44670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE); 44770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 44870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 44970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 45070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* 45170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * If the basic rates contain OFDM rates, use OFDM only 45270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov * rates for unicast TX as well. Else use all supported rates. 45370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov */ 45487fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) 45570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_OFDM_RATES; 45670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov else 45770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov supported_rates = CONF_TX_AP_ENABLED_RATES; 45870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 4591a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov /* unconditionally enable HT rates */ 4601a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov supported_rates |= CONF_TX_MCS_RATES; 4611a8adb67f9c37cad9539dd9dcb289ce1411680fcArik Nemtsov 46270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov /* configure unicast TX rate classes */ 46370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { 46470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.enabled_rates = supported_rates; 46570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.short_retry_limit = 10; 46670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.long_retry_limit = 10; 46770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov rc.aflags = 0; 46870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov ret = wl1271_acx_ap_rate_policy(wl, &rc, i); 46970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov if (ret < 0) 47070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return ret; 47170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov } 47270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 47370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov return 0; 47470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov} 47570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov 476536129c8ad35de87ff2f864f205a54ac32bfebccEliad Pellerstatic int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) 4774b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{ 4784b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar /* Reset the BA RX indicators */ 479d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_allowed = true; 4800f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov wl->ba_rx_session_count = 0; 4814b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 4820f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* BA is supported in STA/AP modes */ 483536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller if (wlvif->bss_type != BSS_TYPE_AP_BSS && 484536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller wlvif->bss_type != BSS_TYPE_STA_BSS) { 485d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = false; 4860f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov return 0; 4870f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov } 4884b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 489d0802abdf9c60b1dadb097e806022f3449b0cc6bEliad Peller wlvif->ba_support = true; 4904b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 4910f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov /* 802.11n initiator BA session setting */ 4920603d891c5b5153f667a79357d4652824c22b54eEliad Peller return wl12xx_acx_set_ba_initiator_policy(wl, wlvif); 4934b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar} 4944b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar 49548a61477bdc04896bd96d259388a0c42a7019943Shahar Leviint wl1271_chip_specific_init(struct wl1271 *wl) 49648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi{ 49748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi int ret = 0; 49848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 49948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) { 50048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; 50148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 5020da13da767cd568c1fe2a7b5b936e86e521b5ae7Ido Yariv if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT) 50348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi /* Enable SDIO padding */ 50448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; 50548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 50648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi /* Must be before wl1271_acx_init_mem_config() */ 50748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap); 50848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 50948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi goto out; 51048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi } 51148a61477bdc04896bd96d259388a0c42a7019943Shahar Leviout: 51248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 51348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi} 51448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 51592c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specifc initialization */ 5160603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 51792c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 51892c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 51992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5200603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_group_address_tbl(wl, wlvif, true, NULL, 0); 52192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52492c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Initialize connection monitoring thresholds */ 5250603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_conn_monit_params(wl, wlvif, false); 52692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 52792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 52892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 52992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacon filtering */ 5300603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_init_beacon_filter(wl, wlvif); 53192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 53492c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Beacons and broadcast settings */ 5350603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_init_beacon_broadcast(wl, wlvif); 53692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 53792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 53848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 53992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure rssi/snr averaging weights */ 5400603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_rssi_snr_avg_weights(wl, wlvif); 54192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 54292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 54392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 54592c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 54692c77c734f958474ac73af670834bc32cb833e54Eliad Peller 54792c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specific intialization */ 5480603d891c5b5153f667a79357d4652824c22b54eEliad Pellerstatic int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 54992c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 55092c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 55192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5520603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ap_max_tx_retry(wl, wlvif); 55392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 55492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 55592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 55692c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* initialize Tx power */ 5576bd650299046f00df6d7374c7f61c5afe6df6696Eliad Peller ret = wl1271_acx_tx_power(wl, wlvif, wlvif->power_level); 55892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 55992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 56092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 56192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 56292c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 56392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 56492c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) 565f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{ 56687fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 567243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo struct conf_tx_ac_category *conf_ac; 568f2054df5170734eacd1db82138c70746ec8387deKalle Valo struct conf_tx_tid *conf_tid; 569536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 57092c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret, i; 57192c77c734f958474ac73af670834bc32cb833e54Eliad Peller 572a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller /* 573a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller * consider all existing roles before configuring psm. 574a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller * TODO: reconfigure on interface removal. 575a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller */ 576a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (!wl->ap_count) { 577a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (is_ap) { 578a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller /* Configure for power always on */ 579a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 580a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (ret < 0) 581a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller return ret; 582a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } else if (!wl->sta_count) { 583a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller /* Configure for ELP power saving */ 584a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 585a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller if (ret < 0) 586a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller return ret; 587a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } 588a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller } 589a4e4130dcea01f3e0dfcbfeaf0d815b971e6e515Eliad Peller 59092c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init */ 59192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) { 59287fbcb0f8c5c8fd57a4e3e7e638977c04ce1e0caEliad Peller ret = wl1271_ap_hw_init(wl, wlvif); 59392c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 59492c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 59592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 5960603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_ap_role(wl, wlvif); 59792c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 59892c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 59992c77c734f958474ac73af670834bc32cb833e54Eliad Peller } else { 60030d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller ret = wl1271_sta_hw_init(wl, wlvif); 60192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6040603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl12xx_init_sta_role(wl, wlvif); 60592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 60692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 60792c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 60892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 6090603d891c5b5153f667a79357d4652824c22b54eEliad Peller wl12xx_init_phy_vif_config(wl, wlvif); 61092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 61192c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Default TID/AC configuration */ 61292c77c734f958474ac73af670834bc32cb833e54Eliad Peller BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); 61392c77c734f958474ac73af670834bc32cb833e54Eliad Peller for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { 61492c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_ac = &wl->conf.tx.ac_conf[i]; 6150603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_ac_cfg(wl, wlvif, conf_ac->ac, 6160603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->cw_min, conf_ac->cw_max, 6170603d891c5b5153f667a79357d4652824c22b54eEliad Peller conf_ac->aifsn, conf_ac->tx_op_limit); 61892c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 61992c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 62092c77c734f958474ac73af670834bc32cb833e54Eliad Peller 62192c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid = &wl->conf.tx.tid_conf[i]; 6220603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_tid_cfg(wl, wlvif, 62392c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->queue_id, 62492c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->channel_type, 62592c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->tsid, 62692c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ps_scheme, 62792c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->ack_policy, 62892c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[0], 62992c77c734f958474ac73af670834bc32cb833e54Eliad Peller conf_tid->apsd_conf[1]); 63092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 63192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 63292c77c734f958474ac73af670834bc32cb833e54Eliad Peller } 63392c77c734f958474ac73af670834bc32cb833e54Eliad Peller 63492c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure HW encryption */ 6350603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_acx_feature_cfg(wl, wlvif); 63692c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 63792c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 63892c77c734f958474ac73af670834bc32cb833e54Eliad Peller 63992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Mode specific init - post mem init */ 64092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (is_ap) 64192c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_ap_hw_init_post_mem(wl, vif); 64292c77c734f958474ac73af670834bc32cb833e54Eliad Peller else 6430603d891c5b5153f667a79357d4652824c22b54eEliad Peller ret = wl1271_sta_hw_init_post_mem(wl, vif); 64492c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 64692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 64792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 64892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure initiator BA sessions policies */ 649536129c8ad35de87ff2f864f205a54ac32bfebccEliad Peller ret = wl1271_set_ba_policies(wl, wlvif); 65092c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 65192c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 65292c77c734f958474ac73af670834bc32cb833e54Eliad Peller 65392c77c734f958474ac73af670834bc32cb833e54Eliad Peller return 0; 65492c77c734f958474ac73af670834bc32cb833e54Eliad Peller} 65592c77c734f958474ac73af670834bc32cb833e54Eliad Peller 65692c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_hw_init(struct wl1271 *wl) 65792c77c734f958474ac73af670834bc32cb833e54Eliad Peller{ 65892c77c734f958474ac73af670834bc32cb833e54Eliad Peller int ret; 65992c77c734f958474ac73af670834bc32cb833e54Eliad Peller 66049d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) 66149d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl128x_cmd_general_parms(wl); 66249d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi else 66349d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl1271_cmd_general_parms(wl); 6644a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho if (ret < 0) 665f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 666f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 66749d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi if (wl->chip.id == CHIP_ID_1283_PG20) 66849d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl128x_cmd_radio_parms(wl); 66949d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi else 67049d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi ret = wl1271_cmd_radio_parms(wl); 6714a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho if (ret < 0) 672f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 673f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 67448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi /* Chip-specific init */ 67548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi ret = wl1271_chip_specific_init(wl); 67648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi if (ret < 0) 67748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi return ret; 67848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi 67992c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Init templates */ 68092c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl1271_init_templates_config(wl); 68192c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 68292c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 683644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen 68492c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_acx_mem_cfg(wl); 68592c77c734f958474ac73af670834bc32cb833e54Eliad Peller if (ret < 0) 68692c77c734f958474ac73af670834bc32cb833e54Eliad Peller return ret; 68792c77c734f958474ac73af670834bc32cb833e54Eliad Peller 68892c77c734f958474ac73af670834bc32cb833e54Eliad Peller /* Configure the FW logger */ 68992c77c734f958474ac73af670834bc32cb833e54Eliad Peller ret = wl12xx_init_fwlog(wl); 690f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 692f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 693801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov /* Bluetooth WLAN coexistence */ 694801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov ret = wl1271_init_pta(wl); 695801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov if (ret < 0) 696801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov return ret; 697801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov 698f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default memory configuration */ 699f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_mem_config(wl); 700f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 701f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX config */ 70408c1d1c7042330e2280a7718be4ad88c2e8f8268Eliad Peller ret = wl12xx_init_rx_config(wl); 705f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 706f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 707f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 708f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* PHY layer config */ 709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_phy_config(wl); 710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 712f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 7136e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho ret = wl1271_acx_dco_itrim_params(wl); 7146e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho if (ret < 0) 7156e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho goto out_free_memmap; 7166e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho 717f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Configure TX patch complete interrupt behavior */ 718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_tx_config_options(wl); 719f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 721f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 722f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* RX complete interrupt pacing */ 723f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_acx_init_rx_interrupt(wl); 724f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 725f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 726f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 727f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Energy detection */ 728f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho ret = wl1271_init_energy_detection(wl); 729f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 730f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 731f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 732f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Default fragmentation threshold */ 7335f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold); 734f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 735f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 736f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 737f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho /* Enable data path */ 73894210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho ret = wl1271_cmd_data_path(wl, 1); 739f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho if (ret < 0) 740f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho goto out_free_memmap; 741f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 74238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen /* configure PM */ 74338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen ret = wl1271_acx_pm_config(wl); 74438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen if (ret < 0) 74538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen goto out_free_memmap; 74638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen 747fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller ret = wl12xx_acx_set_rate_mgmt_params(wl); 748fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller if (ret < 0) 749fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller goto out_free_memmap; 750fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller 7519487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller /* configure hangover */ 7529487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller ret = wl12xx_acx_config_hangover(wl); 7539487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller if (ret < 0) 7549487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller goto out_free_memmap; 7559487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller 756f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return 0; 757f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 758f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap: 759f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho kfree(wl->target_mem_map); 760344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen wl->target_mem_map = NULL; 761f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho 762f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho return ret; 763f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho} 764