init.c revision 92c77c734f958474ac73af670834bc32cb833e54
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
125e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_deauth_template(struct wl1271 *wl)
126e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
127e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	struct wl12xx_disconn_template *tmpl;
128e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
129af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	u32 rate;
130e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
131e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
132e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (!tmpl) {
133e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = -ENOMEM;
134e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		goto out;
135e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
136e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
137e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
138e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					     IEEE80211_STYPE_DEAUTH);
139e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
140af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
141e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
142af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller				      tmpl, sizeof(*tmpl), 0, rate);
143e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
144e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout:
145e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	kfree(tmpl);
146e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return ret;
147e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
148e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
149784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_null_template(struct wl1271 *wl,
150784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller					struct ieee80211_vif *vif)
151e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
152e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	struct ieee80211_hdr_3addr *nullfunc;
153e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
154af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	u32 rate;
155e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
156e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
157e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (!nullfunc) {
158e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = -ENOMEM;
159e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		goto out;
160e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
161e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
162e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
163e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					      IEEE80211_STYPE_NULLFUNC |
164e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					      IEEE80211_FCTL_FROMDS);
165e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
166e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* nullfunc->addr1 is filled by FW */
167e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
168784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
169784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);
170e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
171af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
172e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
173af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller				      sizeof(*nullfunc), 0, rate);
174e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
175e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout:
176e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	kfree(nullfunc);
177e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return ret;
178e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
179e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
180784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
181784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller					    struct ieee80211_vif *vif)
182e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
183e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	struct ieee80211_qos_hdr *qosnull;
184e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
185af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	u32 rate;
186e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
187e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
188e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (!qosnull) {
189e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = -ENOMEM;
190e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		goto out;
191e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
192e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
193e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
194e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					     IEEE80211_STYPE_QOS_NULLFUNC |
195e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					     IEEE80211_FCTL_FROMDS);
196e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
197e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* qosnull->addr1 is filled by FW */
198e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
199784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	memcpy(qosnull->addr2, vif->addr, ETH_ALEN);
200784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	memcpy(qosnull->addr3, vif->addr, ETH_ALEN);
201e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
202af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	rate = wl1271_tx_min_rate_get(wl, wl->basic_rate_set);
203e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
204af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller				      sizeof(*qosnull), 0, rate);
205e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
206e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout:
207e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	kfree(qosnull);
208e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return ret;
209e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
210e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
21192c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_rx_config(struct wl1271 *wl)
212e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
213e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
214e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
21592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_rx_msdu_life_time(wl);
216e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
217e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
218e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
219e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
220e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
221e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
22292c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_init_phy_config(struct wl1271 *wl)
223f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
224f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
225f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
22692c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_pd_threshold(wl);
227f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
228f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
229f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
230f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
231f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
232f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
23392c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_phy_vif_config(struct wl1271 *wl)
234f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
235f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
236f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
237f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME);
238f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
239f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
240f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
241f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_service_period_timeout(wl);
242f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
243f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
244f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2455f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold);
246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
248f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
249f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
250f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
251f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
252f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_beacon_filter(struct wl1271 *wl)
253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2561922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen	/* disable beacon filtering at this stage */
2571922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen	ret = wl1271_acx_beacon_filter_opt(wl, false);
258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
260f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
261f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_beacon_filter_table(wl);
262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
264f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
265f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
266f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
26812419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_pta(struct wl1271 *wl)
269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2723be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller	ret = wl12xx_acx_sg_cfg(wl);
273f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2767fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen	ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
280f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
281f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
282f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
28312419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_energy_detection(struct wl1271 *wl)
284f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
287f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_cca_threshold(wl);
288f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
289f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
290f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
291f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
292f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
293f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
294f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_beacon_broadcast(struct wl1271 *wl)
295f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_bcn_dtim_options(wl);
299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
300f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
302f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
303f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
304f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
30595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yarivstatic int wl12xx_init_fwlog(struct wl1271 *wl)
30695dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv{
30795dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv	int ret;
30895dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv
30995dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv	if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED)
31095dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv		return 0;
31195dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv
31295dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv	ret = wl12xx_cmd_config_fwlog(wl);
31395dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv	if (ret < 0)
31495dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv		return ret;
31595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv
31695dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv	return 0;
31795dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv}
31895dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv
31992c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic sta initialization (non vif-specific) */
320e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_sta_hw_init(struct wl1271 *wl)
321e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
322e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
323e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
32449d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi	if (wl->chip.id != CHIP_ID_1283_PG20) {
32549d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi		ret = wl1271_cmd_ext_radio_parms(wl);
32649d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi		if (ret < 0)
32749d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi			return ret;
32849d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi	}
329e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
330c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	/* PS config */
331c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	ret = wl1271_acx_config_ps(wl);
332c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	if (ret < 0)
333c8bde243421d759844264cf11e4248e7862c2722Eliad Peller		return ret;
334c8bde243421d759844264cf11e4248e7862c2722Eliad Peller
335ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	/* FM WLAN coexistence */
336ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	ret = wl1271_acx_fm_coex(wl);
337ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	if (ret < 0)
338ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		return ret;
339ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
340e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Configure for ELP power saving */
341e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
342e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
343e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
344e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
345e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_sta_rate_policies(wl);
346e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
347e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
348e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
349e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
350e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
351e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
352e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
353e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
354e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret, i;
355e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
356e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* disable all keep-alive templates */
357e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
358e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_acx_keep_alive_config(wl, i,
359e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov						   ACX_KEEP_ALIVE_TPL_INVALID);
360e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		if (ret < 0)
361e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov			return ret;
362e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
363e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
364e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* disable the keep-alive feature */
365e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_keep_alive_mode(wl, false);
366e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
367e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
368e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
369e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
370e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
371e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
37292c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* generic ap initialization (non vif-specific) */
373e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_hw_init(struct wl1271 *wl)
374e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
37570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	int ret;
376e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
377e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Configure for power always on */
378e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
379e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
380e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
381e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
38270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	ret = wl1271_init_ap_rates(wl);
383e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
384e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
385e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
386e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
387e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
388e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
389784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerint wl1271_ap_init_templates(struct wl1271 *wl, struct ieee80211_vif *vif)
390e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
392e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
393e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_ap_init_deauth_template(wl);
394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
395e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
396e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
397784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	ret = wl1271_ap_init_null_template(wl, vif);
398e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
400e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
401784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	ret = wl1271_ap_init_qos_null_template(wl, vif);
402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
404e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
405521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov	/*
406521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov	 * when operating as AP we want to receive external beacons for
407521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov	 * configuring ERP protection.
408521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov	 */
409f42bd2cbf1d5ff4b161ad2c59ff12d66558c8374Eliad Peller	ret = wl1271_acx_beacon_filter_opt(wl, false);
410521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov	if (ret < 0)
411521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov		return ret;
412521a4a23261354885c01bf75b42150629004ed83Arik Nemtsov
413e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
414e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
415e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
416784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Pellerstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl,
417784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller				      struct ieee80211_vif *vif)
418c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov{
419784f694d0f3ca927361aa0c26de1aa340eb5b275Eliad Peller	return wl1271_ap_init_templates(wl, vif);
420c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov}
421c45a85b5a3c0ca841a7ffc700bdece8ee01486beArik Nemtsov
42270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsovint wl1271_init_ap_rates(struct wl1271 *wl)
42370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov{
42470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	int i, ret;
42570f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	struct conf_tx_rate_class rc;
42670f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	u32 supported_rates;
42770f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov
42870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set);
42970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov
43070f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	if (wl->basic_rate_set == 0)
43170f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov		return -EINVAL;
43270f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov
43370f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	rc.enabled_rates = wl->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 */
442af7fbb28efff0c0d8fc0852ad6622e5437a7611eEliad Peller	rc.enabled_rates = wl1271_tx_min_rate_get(wl, wl->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	 */
45470f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	if ((wl->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
4764b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shaharstatic int wl1271_set_ba_policies(struct wl1271 *wl)
4774b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{
4784b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	/* Reset the BA RX indicators */
4794b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	wl->ba_rx_bitmap = 0;
48070559a06657c55aeefe2f06619d3592a08cc68acShahar Levi	wl->ba_allowed = true;
4810f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	wl->ba_rx_session_count = 0;
4824b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
4830f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	/* BA is supported in STA/AP modes */
4840f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	if (wl->bss_type != BSS_TYPE_AP_BSS &&
4850f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	    wl->bss_type != BSS_TYPE_STA_BSS) {
4860f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		wl->ba_support = false;
4870f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		return 0;
4880f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	}
4894b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
4900f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	wl->ba_support = true;
4914b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
4920f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	/* 802.11n initiator BA session setting */
4930f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	return wl12xx_acx_set_ba_initiator_policy(wl);
4944b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar}
4954b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
49648a61477bdc04896bd96d259388a0c42a7019943Shahar Leviint wl1271_chip_specific_init(struct wl1271 *wl)
49748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi{
49848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	int ret = 0;
49948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
50048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	if (wl->chip.id == CHIP_ID_1283_PG20) {
50148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
50248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
5030da13da767cd568c1fe2a7b5b936e86e521b5ae7Ido Yariv		if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
50448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi			/* Enable SDIO padding */
50548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi			host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
50648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
50748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		/* Must be before wl1271_acx_init_mem_config() */
50848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
50948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		if (ret < 0)
51048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi			goto out;
51148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	}
51248a61477bdc04896bd96d259388a0c42a7019943Shahar Leviout:
51348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	return ret;
51448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi}
51548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
51692c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specifc initialization */
51792c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_sta_role(struct wl1271 *wl, struct ieee80211_vif *vif)
51892c77c734f958474ac73af670834bc32cb833e54Eliad Peller{
51992c77c734f958474ac73af670834bc32cb833e54Eliad Peller	int ret;
52092c77c734f958474ac73af670834bc32cb833e54Eliad Peller
52192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0);
52292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
52392c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
52492c77c734f958474ac73af670834bc32cb833e54Eliad Peller
52592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Initialize connection monitoring thresholds */
52692c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_conn_monit_params(wl, false);
52792c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
52892c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
52992c77c734f958474ac73af670834bc32cb833e54Eliad Peller
53092c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Beacon filtering */
53192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_init_beacon_filter(wl);
53292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
53392c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
53492c77c734f958474ac73af670834bc32cb833e54Eliad Peller
53592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Beacons and broadcast settings */
53692c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_init_beacon_broadcast(wl);
53792c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
53892c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
53948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
54092c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Configure rssi/snr averaging weights */
54192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_rssi_snr_avg_weights(wl);
54292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
54392c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
54492c77c734f958474ac73af670834bc32cb833e54Eliad Peller
54592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	return 0;
54692c77c734f958474ac73af670834bc32cb833e54Eliad Peller}
54792c77c734f958474ac73af670834bc32cb833e54Eliad Peller
54892c77c734f958474ac73af670834bc32cb833e54Eliad Peller/* vif-specific intialization */
54992c77c734f958474ac73af670834bc32cb833e54Eliad Pellerstatic int wl12xx_init_ap_role(struct wl1271 *wl, struct ieee80211_vif *vif)
55092c77c734f958474ac73af670834bc32cb833e54Eliad Peller{
55192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	int ret;
55292c77c734f958474ac73af670834bc32cb833e54Eliad Peller
55392c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_ap_max_tx_retry(wl);
55492c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
55592c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
55692c77c734f958474ac73af670834bc32cb833e54Eliad Peller
55792c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* initialize Tx power */
55892c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_tx_power(wl, wl->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{
567243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	struct conf_tx_ac_category *conf_ac;
568f2054df5170734eacd1db82138c70746ec8387deKalle Valo	struct conf_tx_tid *conf_tid;
569e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
570f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
57192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	int ret, i;
57292c77c734f958474ac73af670834bc32cb833e54Eliad Peller
57392c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Mode specific init */
57492c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (is_ap) {
57592c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl1271_ap_hw_init(wl);
57692c77c734f958474ac73af670834bc32cb833e54Eliad Peller		if (ret < 0)
57792c77c734f958474ac73af670834bc32cb833e54Eliad Peller			return ret;
57892c77c734f958474ac73af670834bc32cb833e54Eliad Peller
57992c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl12xx_init_ap_role(wl, vif);
58092c77c734f958474ac73af670834bc32cb833e54Eliad Peller		if (ret < 0)
58192c77c734f958474ac73af670834bc32cb833e54Eliad Peller			return ret;
58292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	} else {
58392c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl1271_sta_hw_init(wl);
58492c77c734f958474ac73af670834bc32cb833e54Eliad Peller		if (ret < 0)
58592c77c734f958474ac73af670834bc32cb833e54Eliad Peller			return ret;
58692c77c734f958474ac73af670834bc32cb833e54Eliad Peller
58792c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl12xx_init_sta_role(wl, vif);
58892c77c734f958474ac73af670834bc32cb833e54Eliad Peller		if (ret < 0)
58992c77c734f958474ac73af670834bc32cb833e54Eliad Peller			return ret;
59092c77c734f958474ac73af670834bc32cb833e54Eliad Peller	}
59192c77c734f958474ac73af670834bc32cb833e54Eliad Peller
59292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	wl12xx_init_phy_vif_config(wl);
59392c77c734f958474ac73af670834bc32cb833e54Eliad Peller
59492c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Default TID/AC configuration */
59592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
59692c77c734f958474ac73af670834bc32cb833e54Eliad Peller	for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
59792c77c734f958474ac73af670834bc32cb833e54Eliad Peller		conf_ac = &wl->conf.tx.ac_conf[i];
59892c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
59992c77c734f958474ac73af670834bc32cb833e54Eliad Peller					conf_ac->cw_max, conf_ac->aifsn,
60092c77c734f958474ac73af670834bc32cb833e54Eliad Peller					conf_ac->tx_op_limit);
60192c77c734f958474ac73af670834bc32cb833e54Eliad Peller		if (ret < 0)
60292c77c734f958474ac73af670834bc32cb833e54Eliad Peller			return ret;
60392c77c734f958474ac73af670834bc32cb833e54Eliad Peller
60492c77c734f958474ac73af670834bc32cb833e54Eliad Peller		conf_tid = &wl->conf.tx.tid_conf[i];
60592c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl1271_acx_tid_cfg(wl,
60692c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->queue_id,
60792c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->channel_type,
60892c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->tsid,
60992c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->ps_scheme,
61092c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->ack_policy,
61192c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->apsd_conf[0],
61292c77c734f958474ac73af670834bc32cb833e54Eliad Peller					 conf_tid->apsd_conf[1]);
61392c77c734f958474ac73af670834bc32cb833e54Eliad Peller		if (ret < 0)
61492c77c734f958474ac73af670834bc32cb833e54Eliad Peller			return ret;
61592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	}
61692c77c734f958474ac73af670834bc32cb833e54Eliad Peller
61792c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Configure HW encryption */
61892c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_acx_feature_cfg(wl);
61992c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
62092c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
62192c77c734f958474ac73af670834bc32cb833e54Eliad Peller
62292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Mode specific init - post mem init */
62392c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (is_ap)
62492c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl1271_ap_hw_init_post_mem(wl, vif);
62592c77c734f958474ac73af670834bc32cb833e54Eliad Peller	else
62692c77c734f958474ac73af670834bc32cb833e54Eliad Peller		ret = wl1271_sta_hw_init_post_mem(wl);
62792c77c734f958474ac73af670834bc32cb833e54Eliad Peller
62892c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
62992c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
63092c77c734f958474ac73af670834bc32cb833e54Eliad Peller
63192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Configure initiator BA sessions policies */
63292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_set_ba_policies(wl);
63392c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
63492c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
63592c77c734f958474ac73af670834bc32cb833e54Eliad Peller
63692c77c734f958474ac73af670834bc32cb833e54Eliad Peller	return 0;
63792c77c734f958474ac73af670834bc32cb833e54Eliad Peller}
63892c77c734f958474ac73af670834bc32cb833e54Eliad Peller
63992c77c734f958474ac73af670834bc32cb833e54Eliad Pellerint wl1271_hw_init(struct wl1271 *wl)
64092c77c734f958474ac73af670834bc32cb833e54Eliad Peller{
64192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	int ret;
64292c77c734f958474ac73af670834bc32cb833e54Eliad Peller
64349d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi	if (wl->chip.id == CHIP_ID_1283_PG20)
64449d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi		ret = wl128x_cmd_general_parms(wl);
64549d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi	else
64649d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi		ret = wl1271_cmd_general_parms(wl);
6474a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho	if (ret < 0)
648f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
649f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
65049d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi	if (wl->chip.id == CHIP_ID_1283_PG20)
65149d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi		ret = wl128x_cmd_radio_parms(wl);
65249d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi	else
65349d750ca14cd49e76ab039b33b5a621e0a92b9fdShahar Levi		ret = wl1271_cmd_radio_parms(wl);
6544a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho	if (ret < 0)
655f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
656f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
65748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	/* Chip-specific init */
65848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	ret = wl1271_chip_specific_init(wl);
65948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	if (ret < 0)
66048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		return ret;
66148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
66292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Init templates */
66392c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl1271_init_templates_config(wl);
66492c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
66592c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
666644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen
66792c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl12xx_acx_mem_cfg(wl);
66892c77c734f958474ac73af670834bc32cb833e54Eliad Peller	if (ret < 0)
66992c77c734f958474ac73af670834bc32cb833e54Eliad Peller		return ret;
67092c77c734f958474ac73af670834bc32cb833e54Eliad Peller
67192c77c734f958474ac73af670834bc32cb833e54Eliad Peller	/* Configure the FW logger */
67292c77c734f958474ac73af670834bc32cb833e54Eliad Peller	ret = wl12xx_init_fwlog(wl);
673f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
674f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
675f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
676801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov	/* Bluetooth WLAN coexistence */
677801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov	ret = wl1271_init_pta(wl);
678801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov	if (ret < 0)
679801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov		return ret;
680801f870bc0524bad7ebef9cea52d20e4d4992e4aArik Nemtsov
681f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Default memory configuration */
682f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_init_mem_config(wl);
683f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
684f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
685f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
686f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* RX config */
68708c1d1c7042330e2280a7718be4ad88c2e8f8268Eliad Peller	ret = wl12xx_init_rx_config(wl);
688f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
689f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
690f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* PHY layer config */
692f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_init_phy_config(wl);
693f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
694f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
695f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
6966e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	ret = wl1271_acx_dco_itrim_params(wl);
6976e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	if (ret < 0)
6986e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho		goto out_free_memmap;
6996e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
700f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Configure TX patch complete interrupt behavior */
701f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_tx_config_options(wl);
702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
704f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
705f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* RX complete interrupt pacing */
706f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_init_rx_interrupt(wl);
707f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
708f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Energy detection */
711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_init_energy_detection(wl);
712f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
713f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
714f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Default fragmentation threshold */
7165f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
717f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
719f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Enable data path */
72194210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho	ret = wl1271_cmd_data_path(wl, 1);
722f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
723f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
724f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
72538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	/* configure PM */
72638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	ret = wl1271_acx_pm_config(wl);
72738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	if (ret < 0)
72838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen		goto out_free_memmap;
72938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
730fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	ret = wl12xx_acx_set_rate_mgmt_params(wl);
731fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	if (ret < 0)
732fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller		goto out_free_memmap;
733fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
7349487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	/* configure hangover */
7359487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	ret = wl12xx_acx_config_hangover(wl);
7369487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	if (ret < 0)
7379487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller		goto out_free_memmap;
7389487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
739f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
740f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
741f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap:
742f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(wl->target_mem_map);
743344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	wl->target_mem_map = NULL;
744f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
745f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
746f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
747