init.c revision e0fe371b74326a85029fe8720506e021fe73905a
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"
34f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
35e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovint wl1271_sta_init_templates_config(struct wl1271 *wl)
36f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
37bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen	int ret, i;
38f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
39f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* send empty templates for fw memory reservation */
40f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
41ea559b460509b241cc1a3f36eebe0b2b634b3cf2Guy Eilam				      WL1271_CMD_TEMPL_MAX_SIZE,
42606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen				      0, WL1271_RATE_AUTOMATIC);
43f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
44f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
45f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
4611eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
47ea559b460509b241cc1a3f36eebe0b2b634b3cf2Guy Eilam				      NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
4811eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen				      WL1271_RATE_AUTOMATIC);
4911eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen	if (ret < 0)
5011eb54298fa7197cb4187f8a3474ead0709f76ffJuuso Oikarinen		return ret;
51abb0b3bfb2d2411034b721df21c31964265b851eTeemu Paasikivi
52f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
53bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen				      sizeof(struct wl12xx_null_data_template),
54606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen				      0, WL1271_RATE_AUTOMATIC);
55f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
56f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
57f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
58f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
59bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen				      sizeof(struct wl12xx_ps_poll_template),
60606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen				      0, WL1271_RATE_AUTOMATIC);
61f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
62f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
63f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
64f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
65f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				      sizeof
66bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen				      (struct wl12xx_qos_null_data_template),
67606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen				      0, WL1271_RATE_AUTOMATIC);
68f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
69f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
70f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
71f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
72f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				      sizeof
73bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen				      (struct wl12xx_probe_resp_template),
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,
79f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				      sizeof
80bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen				      (struct wl12xx_beacon_template),
81606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen				      0, WL1271_RATE_AUTOMATIC);
82f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
83f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
84f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
85c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
86c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller				      sizeof
87c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller				      (struct wl12xx_arp_rsp_template),
88c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller				      0, WL1271_RATE_AUTOMATIC);
89c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller	if (ret < 0)
90c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller		return ret;
91c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller
92bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen	for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
93bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
94606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen					      WL1271_CMD_TEMPL_MAX_SIZE, i,
95606c1487ac894798121bc2c64d27c1953c5a6210Juuso Oikarinen					      WL1271_RATE_AUTOMATIC);
96bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen		if (ret < 0)
97bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen			return ret;
98bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen	}
99bfb24c9e16921f0e57fcec5180ffa20929832545Juuso Oikarinen
100f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
101f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
102f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
103e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_deauth_template(struct wl1271 *wl)
104e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
105e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	struct wl12xx_disconn_template *tmpl;
106e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
107e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
108e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
109e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (!tmpl) {
110e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = -ENOMEM;
111e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		goto out;
112e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
113e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
114e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
115e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					     IEEE80211_STYPE_DEAUTH);
116e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
117e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
118e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      tmpl, sizeof(*tmpl), 0,
119e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      wl1271_tx_min_rate_get(wl));
120e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
121e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout:
122e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	kfree(tmpl);
123e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return ret;
124e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
125e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
126e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_null_template(struct wl1271 *wl)
127e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
128e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	struct ieee80211_hdr_3addr *nullfunc;
129e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
130e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
131e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL);
132e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (!nullfunc) {
133e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = -ENOMEM;
134e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		goto out;
135e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
136e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
137e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
138e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					      IEEE80211_STYPE_NULLFUNC |
139e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					      IEEE80211_FCTL_FROMDS);
140e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
141e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* nullfunc->addr1 is filled by FW */
142e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
143e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN);
144e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN);
145e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
146e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
147e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof(*nullfunc), 0,
148e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      wl1271_tx_min_rate_get(wl));
149e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
150e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout:
151e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	kfree(nullfunc);
152e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return ret;
153e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
154e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
155e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_qos_null_template(struct wl1271 *wl)
156e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
157e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	struct ieee80211_qos_hdr *qosnull;
158e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
159e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
160e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL);
161e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (!qosnull) {
162e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = -ENOMEM;
163e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		goto out;
164e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
165e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
166e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
167e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					     IEEE80211_STYPE_QOS_NULLFUNC |
168e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					     IEEE80211_FCTL_FROMDS);
169e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
170e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* qosnull->addr1 is filled by FW */
171e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
172e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN);
173e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN);
174e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
175e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
176e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof(*qosnull), 0,
177e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      wl1271_tx_min_rate_get(wl));
178e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
179e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovout:
180e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	kfree(qosnull);
181e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return ret;
182e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
183e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
184e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_init_templates_config(struct wl1271 *wl)
185e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
186e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
187e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
188e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/*
189e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	 * Put very large empty placeholders for all templates. These
190e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	 * reserve memory for later.
191e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	 */
192e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
193e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof
194e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      (struct wl12xx_probe_resp_template),
195e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      0, WL1271_RATE_AUTOMATIC);
196e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
197e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
198e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
199e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL,
200e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof
201e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      (struct wl12xx_beacon_template),
202e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      0, WL1271_RATE_AUTOMATIC);
203e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
204e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
205e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
206e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL,
207e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof
208e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      (struct wl12xx_disconn_template),
209e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      0, WL1271_RATE_AUTOMATIC);
210e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
211e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
212e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
213e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
214e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof(struct wl12xx_null_data_template),
215e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      0, WL1271_RATE_AUTOMATIC);
216e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
217e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
218e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
219e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
220e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      sizeof
221e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      (struct wl12xx_qos_null_data_template),
222e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				      0, WL1271_RATE_AUTOMATIC);
223e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
224e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
225e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
226e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
227e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
228e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
229f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
230f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
231f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
232f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2338793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinen	ret = wl1271_acx_rx_msdu_life_time(wl);
234f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
235f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
236f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
237f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_rx_config(wl, config, filter);
238f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
239f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
240f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
241f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
242f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
243f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
24412419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_phy_config(struct wl1271 *wl)
245f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
248f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_pd_threshold(wl);
249f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
250f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
251f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
252f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME);
253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
256f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_service_period_timeout(wl);
257f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2608793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinen	ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold);
261f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
264f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
265f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
266f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_beacon_filter(struct wl1271 *wl)
268f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2711922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen	/* disable beacon filtering at this stage */
2721922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen	ret = wl1271_acx_beacon_filter_opt(wl, false);
273f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_beacon_filter_table(wl);
277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
280f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
281f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
282f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
28312419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_pta(struct wl1271 *wl)
284f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2871b00f546fc4271d94c1bccb1955ce64d9ace1000Juuso Oikarinen	ret = wl1271_acx_sg_cfg(wl);
288f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
289f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
290f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2917fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen	ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
292f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
293f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
294f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
295f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
29812419cce88fa591a846a542d35cff43b69d9e271Luciano Coelhoint wl1271_init_energy_detection(struct wl1271 *wl)
299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
300f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
302f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_cca_threshold(wl);
303f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
304f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
306f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
307f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhostatic int wl1271_init_beacon_broadcast(struct wl1271 *wl)
310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
311f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
312f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
313f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_bcn_dtim_options(wl);
314f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
315f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
316f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
317f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
318f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
319f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
320e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_sta_hw_init(struct wl1271 *wl)
321e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
322e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
323e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
324e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_ext_radio_parms(wl);
325e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
326e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
327e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
328e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_sta_init_templates_config(wl);
329e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
330e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
331e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
332e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0);
333e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
334e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
335e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
336e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Initialize connection monitoring thresholds */
337e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_conn_monit_params(wl, false);
338e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
339e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
340e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
341e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Beacon filtering */
342e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_init_beacon_filter(wl);
343e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
344e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
345e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
346e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Bluetooth WLAN coexistence */
347e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_init_pta(wl);
348e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
349e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
350e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
351e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Beacons and broadcast settings */
352e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_init_beacon_broadcast(wl);
353e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
354e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
355e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
356e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Configure for ELP power saving */
357e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
358e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
359e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
360e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
361e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Configure rssi/snr averaging weights */
362e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_rssi_snr_avg_weights(wl);
363e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
364e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
365e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
366e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_sta_rate_policies(wl);
367e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
368e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
369e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
370e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
371e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
372e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
373e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
374e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
375e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret, i;
376e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
377e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key);
378e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0) {
379e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		wl1271_warning("couldn't set default key");
380e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
381e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
382e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
383e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* disable all keep-alive templates */
384e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
385e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_acx_keep_alive_config(wl, i,
386e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov						   ACX_KEEP_ALIVE_TPL_INVALID);
387e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		if (ret < 0)
388e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov			return ret;
389e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
390e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
391e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* disable the keep-alive feature */
392e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_keep_alive_mode(wl, false);
393e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
394e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
395e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
396e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
397e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
398e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
399e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_hw_init(struct wl1271 *wl)
400e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
401e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret, i;
402e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
403e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_ap_init_templates_config(wl);
404e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
405e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
406e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
407e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Configure for power always on */
408e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
409e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
410e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
411e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
412e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Configure initial TX rate classes */
413e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
414e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_acx_ap_rate_policy(wl,
415e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov				&wl->conf.tx.ap_rc_conf[i], i);
416e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		if (ret < 0)
417e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov			return ret;
418e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	}
419e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
420e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_ap_rate_policy(wl,
421e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					&wl->conf.tx.ap_mgmt_conf,
422e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					ACX_TX_AP_MODE_MGMT_RATE);
423e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
424e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
425e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
426e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_ap_rate_policy(wl,
427e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					&wl->conf.tx.ap_bcst_conf,
428e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov					ACX_TX_AP_MODE_BCST_RATE);
429e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
430e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
431e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
432e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_max_tx_retry(wl);
433e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
434e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
435e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
436e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
437e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
438e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
439e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsovstatic int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
440e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov{
441e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	int ret;
442e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
443e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_ap_init_deauth_template(wl);
444e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
445e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
446e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
447e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_ap_init_null_template(wl);
448e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
449e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
450e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
451e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_ap_init_qos_null_template(wl);
452e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (ret < 0)
453e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		return ret;
454e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
455e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	return 0;
456e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov}
457e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov
458f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_hw_init(struct wl1271 *wl)
459f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
460243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	struct conf_tx_ac_category *conf_ac;
461f2054df5170734eacd1db82138c70746ec8387deKalle Valo	struct conf_tx_tid *conf_tid;
462243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	int ret, i;
463e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
464f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
46598b5dd5ded8cb59b598b2c0c396100054779eda7Luciano Coelho	ret = wl1271_cmd_general_parms(wl);
4664a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho	if (ret < 0)
467f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
468f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
46998b5dd5ded8cb59b598b2c0c396100054779eda7Luciano Coelho	ret = wl1271_cmd_radio_parms(wl);
4704a90406b876cade9bb8d9c95b048d60fb979ba6bLuciano Coelho	if (ret < 0)
471f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
472f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
473e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Mode specific init */
474e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (is_ap)
475e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_ap_hw_init(wl);
476e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	else
477e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_sta_hw_init(wl);
478644a48607cd40954b6fb095b39a3ccaa0204191eJuuso Oikarinen
479f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
480f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
481f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
482f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Default memory configuration */
483f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_init_mem_config(wl);
484f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
485f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
486f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
487f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* RX config */
488f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_init_rx_config(wl,
489eb5b28d021a1b96050f7af46e9140eb0051cc6d8Juuso Oikarinen				    RX_CFG_PROMISCUOUS | RX_CFG_TSF,
490eb5b28d021a1b96050f7af46e9140eb0051cc6d8Juuso Oikarinen				    RX_FILTER_OPTION_DEF);
491f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
492f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	   RX_FILTER_OPTION_FILTER_ALL); */
493f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
494f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
495f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
496f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* PHY layer config */
497f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_init_phy_config(wl);
498f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
499f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
500f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5016e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	ret = wl1271_acx_dco_itrim_params(wl);
5026e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	if (ret < 0)
5036e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho		goto out_free_memmap;
5046e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
505f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Configure TX patch complete interrupt behavior */
506f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_tx_config_options(wl);
507f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
508f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
509f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
510f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* RX complete interrupt pacing */
511f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_init_rx_interrupt(wl);
512f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
513f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
514f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
515f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Energy detection */
516f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_init_energy_detection(wl);
517f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
518f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
519f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
520f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Default fragmentation threshold */
52168d069c45f73e8aeda0249891daec1f7e2f0e067Arik Nemtsov	ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
522f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
523f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
524f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5259987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen	/* Default TID/AC configuration */
5269987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen	BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
527f2054df5170734eacd1db82138c70746ec8387deKalle Valo	for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
5289987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen		conf_ac = &wl->conf.tx.ac_conf[i];
5299987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen		ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
5309987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen					conf_ac->cw_max, conf_ac->aifsn,
5319987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen					conf_ac->tx_op_limit);
5329987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen		if (ret < 0)
5339987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen			goto out_free_memmap;
5349987a9da3eda093ceeff14ad4926adb130a0d0eaJuuso Oikarinen
535f2054df5170734eacd1db82138c70746ec8387deKalle Valo		conf_tid = &wl->conf.tx.tid_conf[i];
536f2054df5170734eacd1db82138c70746ec8387deKalle Valo		ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
537f2054df5170734eacd1db82138c70746ec8387deKalle Valo					 conf_tid->channel_type,
538f2054df5170734eacd1db82138c70746ec8387deKalle Valo					 conf_tid->tsid,
539f2054df5170734eacd1db82138c70746ec8387deKalle Valo					 conf_tid->ps_scheme,
540f2054df5170734eacd1db82138c70746ec8387deKalle Valo					 conf_tid->ack_policy,
541f2054df5170734eacd1db82138c70746ec8387deKalle Valo					 conf_tid->apsd_conf[0],
542f2054df5170734eacd1db82138c70746ec8387deKalle Valo					 conf_tid->apsd_conf[1]);
543f2054df5170734eacd1db82138c70746ec8387deKalle Valo		if (ret < 0)
544f2054df5170734eacd1db82138c70746ec8387deKalle Valo			goto out_free_memmap;
545f2054df5170734eacd1db82138c70746ec8387deKalle Valo	}
546f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
547f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Enable data path */
54894210897e2b7df8446fdecd360342149e5b4a400Luciano Coelho	ret = wl1271_cmd_data_path(wl, 1);
549f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
550f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
551f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
552f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* Configure HW encryption */
553e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	ret = wl1271_acx_feature_cfg(wl);
554f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
555f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out_free_memmap;
556f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
55738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	/* configure PM */
55838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	ret = wl1271_acx_pm_config(wl);
55938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	if (ret < 0)
56038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen		goto out_free_memmap;
56138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
562e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	/* Mode specific init - post mem init */
563e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	if (is_ap)
564e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_ap_hw_init_post_mem(wl);
565e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov	else
566e0fe371b74326a85029fe8720506e021fe73905aArik Nemtsov		ret = wl1271_sta_hw_init_post_mem(wl);
567c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
56800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	if (ret < 0)
56900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		goto out_free_memmap;
57000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
571f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
572f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
573f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho out_free_memmap:
574f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(wl->target_mem_map);
575344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	wl->target_mem_map = NULL;
576f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
577f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
578f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
579