1f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho/*
2f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * This file is part of wl1271
3f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho *
4f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho * Copyright (C) 2008-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
2400d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "acx.h"
25f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
26f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/module.h>
27f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/platform_device.h>
28f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include <linux/spi/spi.h>
295a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
30f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
3100d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "wl12xx.h"
320f4e31222a2c0b93f25a87effd2033cb78c7a79cLuciano Coelho#include "debug.h"
33f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho#include "wl12xx_80211.h"
3400d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "reg.h"
3500d201001bd4e8a46e3d03c970abcb72256c368bShahar Levi#include "ps.h"
36f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
370603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
38f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
39f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_wake_up_condition *wake_up;
40f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
41f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
42f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx wake up conditions");
43f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
44f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
45f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!wake_up) {
46f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
47f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
48f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
49f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
500603d891c5b5153f667a79357d4652824c22b54eEliad Peller	wake_up->role_id = wlvif->role_id;
5151f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	wake_up->wake_up_event = wl->conf.conn.wake_up_event;
5251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	wake_up->listen_interval = wl->conf.conn.listen_interval;
53f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
54f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
55f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   wake_up, sizeof(*wake_up));
56f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
57f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("could not set wake up conditions: %d", ret);
58f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
59f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
60f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
61f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
62f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(wake_up);
63f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
64f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
65f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
66f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
67f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
68f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_sleep_auth *auth;
69f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
70f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
71f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx sleep auth");
72f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
73f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
74f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!auth) {
75f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
76f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
77f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
78f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
79f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	auth->sleep_auth = sleep_auth;
80f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
81f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
82f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
83f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
84f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(auth);
85f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
86f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
87f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
880603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
890603d891c5b5153f667a79357d4652824c22b54eEliad Peller			int power)
90f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
91f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_current_tx_power *acx;
92f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
93f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
94097f882153f0ec13617074fa3bdb683b8215e20cArik Nemtsov	wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power);
95f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
96f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (power < 0 || power > 25)
97f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return -EINVAL;
98f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
99f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
100f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
101f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
102f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
103f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
104f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1050603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
1066f6b5d49105eba1be0b2ef0c04a4571f20793778Juuso Oikarinen	acx->current_tx_power = power * 10;
107f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
108f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
109f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
110f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("configure of tx power failed: %d", ret);
111f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
112f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
113f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
114f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
115f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
116f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
117f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
118f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1190603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif)
120f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
121f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_feature_config *feature;
122f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
123f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
124f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx feature cfg");
125f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
126f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	feature = kzalloc(sizeof(*feature), GFP_KERNEL);
127f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!feature) {
128f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
129f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
130f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
131f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
132f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
1330603d891c5b5153f667a79357d4652824c22b54eEliad Peller	feature->role_id = wlvif->role_id;
134f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	feature->data_flow_options = 0;
135f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	feature->options = 0;
136f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
137f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
138f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   feature, sizeof(*feature));
139f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
140f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_error("Couldnt set HW encryption");
141f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
142f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
143f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
144f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
145f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(feature);
146f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
147f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
148f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
149f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
150f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		       size_t len)
151f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
152f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
153f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
154f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx mem map");
155f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
156f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
157f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0)
158f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
159f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
160f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
161f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
162f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1638793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinenint wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
164f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
165f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_rx_msdu_lifetime *acx;
166f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
167f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
168f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
169f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
170f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
171f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
172f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
173f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
174f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
175f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
176d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time);
177f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
178f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   acx, sizeof(*acx));
179f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
180f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set rx msdu life time: %d", ret);
181f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
182f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
183f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
184f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
185f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
186f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
187f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
188f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1890603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_slot(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1900603d891c5b5153f667a79357d4652824c22b54eEliad Peller		    enum acx_slot_type slot_time)
191f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
192f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_slot *slot;
193f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
194f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
195f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx slot");
196f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
197f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
198f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!slot) {
199f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
200f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
201f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
202f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2030603d891c5b5153f667a79357d4652824c22b54eEliad Peller	slot->role_id = wlvif->role_id;
204f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	slot->wone_index = STATION_WONE_INDEX;
205f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	slot->slot_time = slot_time;
206f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
207f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
208f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
209f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set slot time: %d", ret);
210f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
211f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
212f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
213f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
214f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(slot);
215f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
216f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
217f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2180603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_group_address_tbl(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2190603d891c5b5153f667a79357d4652824c22b54eEliad Peller				 bool enable, void *mc_list, u32 mc_list_len)
220f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
221f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_dot11_grp_addr_tbl *acx;
222f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
223f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
224f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx group address tbl");
225f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
226f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
227f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
228f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
229f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
230f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
231f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
232f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* MAC filtering */
2330603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
234c87dec9f189b884df215756e285b9281cf065206Juuso Oikarinen	acx->enabled = enable;
235c87dec9f189b884df215756e285b9281cf065206Juuso Oikarinen	acx->num_groups = mc_list_len;
236c87dec9f189b884df215756e285b9281cf065206Juuso Oikarinen	memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
237f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
238f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
239f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   acx, sizeof(*acx));
240f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
241f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set group addr table: %d", ret);
242f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
243f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
244f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
245f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
246f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
247f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
248f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
249f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2500603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_service_period_timeout(struct wl1271 *wl,
2510603d891c5b5153f667a79357d4652824c22b54eEliad Peller				      struct wl12xx_vif *wlvif)
252f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
253f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_rx_timeout *rx_timeout;
254f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
255f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
256f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
257f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!rx_timeout) {
258f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
259f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
260f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
261f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
262f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx service period timeout");
263f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2640603d891c5b5153f667a79357d4652824c22b54eEliad Peller	rx_timeout->role_id = wlvif->role_id;
265d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout);
266d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout);
267f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
268f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
269f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   rx_timeout, sizeof(*rx_timeout));
270f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
271f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set service period timeout: %d",
272f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho			       ret);
273f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
274f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
275f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
276f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
277f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(rx_timeout);
278f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
279f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
280f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2810603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_rts_threshold(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2820603d891c5b5153f667a79357d4652824c22b54eEliad Peller			     u32 rts_threshold)
283f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
284f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_rts_threshold *rts;
285f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
286f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
2875f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	/*
2885f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	 * If the RTS threshold is not configured or out of range, use the
2895f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	 * default value.
2905f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	 */
2915f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
2925f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov		rts_threshold = wl->conf.rx.rts_threshold;
2935f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov
2945f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
295f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
296f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	rts = kzalloc(sizeof(*rts), GFP_KERNEL);
297f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!rts) {
298f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
299f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
300f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
301f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
3020603d891c5b5153f667a79357d4652824c22b54eEliad Peller	rts->role_id = wlvif->role_id;
3035f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	rts->threshold = cpu_to_le16((u16)rts_threshold);
304f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
305f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
306f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
307f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set rts threshold: %d", ret);
308f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
309f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
310f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
311f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
312f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(rts);
313f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
314f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
315f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
3166e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelhoint wl1271_acx_dco_itrim_params(struct wl1271 *wl)
3176e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho{
3186e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	struct acx_dco_itrim_params *dco;
3196e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	struct conf_itrim_settings *c = &wl->conf.itrim;
3206e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	int ret;
3216e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
3226e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	wl1271_debug(DEBUG_ACX, "acx dco itrim parameters");
3236e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
3246e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	dco = kzalloc(sizeof(*dco), GFP_KERNEL);
3256e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	if (!dco) {
3266e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho		ret = -ENOMEM;
3276e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho		goto out;
3286e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	}
3296e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
3306e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	dco->enable = c->enable;
3316e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	dco->timeout = cpu_to_le32(c->timeout);
3326e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
3336e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS,
3346e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho				   dco, sizeof(*dco));
3356e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	if (ret < 0) {
3366e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho		wl1271_warning("failed to set dco itrim parameters: %d", ret);
3376e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho		goto out;
3386e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	}
3396e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
3406e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelhoout:
3416e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	kfree(dco);
3426e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho	return ret;
3436e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho}
3446e92b416b0aa6a59629cc32ee2b27129d73b98b8Luciano Coelho
3450603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif,
3460603d891c5b5153f667a79357d4652824c22b54eEliad Peller				 bool enable_filter)
347f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
34851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	struct acx_beacon_filter_option *beacon_filter = NULL;
34951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	int ret = 0;
350f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
351f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
352f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
35351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	if (enable_filter &&
35451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	    wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED)
35551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		goto out;
35651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen
357f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
358f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!beacon_filter) {
359f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
360f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
361f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
362f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
3630603d891c5b5153f667a79357d4652824c22b54eEliad Peller	beacon_filter->role_id = wlvif->role_id;
3641922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen	beacon_filter->enable = enable_filter;
36551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen
36651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	/*
36751f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	 * When set to zero, and the filter is enabled, beacons
36851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	 * without the unicast TIM bit set are dropped.
36951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	 */
370f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	beacon_filter->max_num_beacons = 0;
371f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
372f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
373f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   beacon_filter, sizeof(*beacon_filter));
374f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
375f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set beacon filter opt: %d", ret);
376f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
377f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
378f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
379f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
380f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(beacon_filter);
381f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
382f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
383f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
3840603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_beacon_filter_table(struct wl1271 *wl,
3850603d891c5b5153f667a79357d4652824c22b54eEliad Peller				   struct wl12xx_vif *wlvif)
386f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
387f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_beacon_filter_ie_table *ie_table;
38851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	int i, idx = 0;
389f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
39051f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	bool vendor_spec = false;
391f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
392f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx beacon filter table");
393f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
394f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
395f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!ie_table) {
396f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
397f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
398f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
399f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
4001922167b9de575d9d1a56be9b80f0fa3b22785f9Juuso Oikarinen	/* configure default beacon pass-through rules */
4010603d891c5b5153f667a79357d4652824c22b54eEliad Peller	ie_table->role_id = wlvif->role_id;
40251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	ie_table->num_ie = 0;
40351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) {
40451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]);
40551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		ie_table->table[idx++] = r->ie;
40651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		ie_table->table[idx++] = r->rule;
40751f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen
40851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		if (r->ie == WLAN_EID_VENDOR_SPECIFIC) {
40951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			/* only one vendor specific ie allowed */
41051f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			if (vendor_spec)
41151f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen				continue;
41251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen
41351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			/* for vendor specific rules configure the
41451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			   additional fields */
41551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			memcpy(&(ie_table->table[idx]), r->oui,
41651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			       CONF_BCN_IE_OUI_LEN);
41751f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			idx += CONF_BCN_IE_OUI_LEN;
41851f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			ie_table->table[idx++] = r->type;
41951f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			memcpy(&(ie_table->table[idx]), r->version,
42051f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			       CONF_BCN_IE_VER_LEN);
42151f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			idx += CONF_BCN_IE_VER_LEN;
42251f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen			vendor_spec = true;
42351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		}
42451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen
42551f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen		ie_table->num_ie++;
42651f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	}
427f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
428f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
429f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   ie_table, sizeof(*ie_table));
430f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
431f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set beacon filter table: %d", ret);
432f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
433f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
434f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
435f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
436f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(ie_table);
437f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
438f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
439f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
4406ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen#define ACX_CONN_MONIT_DISABLE_VALUE  0xffffffff
4416ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen
4420603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_conn_monit_params(struct wl1271 *wl, struct wl12xx_vif *wlvif,
4430603d891c5b5153f667a79357d4652824c22b54eEliad Peller				 bool enable)
444344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen{
445344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	struct acx_conn_monit_params *acx;
4466ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
4476ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
448344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	int ret;
449344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
4506ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
4516ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen		     enable ? "enabled" : "disabled");
452344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
453344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
454344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	if (!acx) {
455344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen		ret = -ENOMEM;
456344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen		goto out;
457344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	}
458344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
4596ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	if (enable) {
4606ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen		threshold = wl->conf.conn.synch_fail_thold;
4616ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen		timeout = wl->conf.conn.bss_lose_timeout;
4626ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	}
4636ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen
4640603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
4656ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	acx->synch_fail_thold = cpu_to_le32(threshold);
4666ccbb92ead9379d7de2cc25cd950d15a8d22e0c9Juuso Oikarinen	acx->bss_lose_timeout = cpu_to_le32(timeout);
467344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
468344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
469344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen				   acx, sizeof(*acx));
470344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	if (ret < 0) {
471344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen		wl1271_warning("failed to set connection monitor "
472344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen			       "parameters: %d", ret);
473344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen		goto out;
474344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	}
475344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
476344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinenout:
477344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	kfree(acx);
478344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen	return ret;
479344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen}
480344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
481344152361e6d14ade61d7f43678db7418cb445dbJuuso Oikarinen
4827fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinenint wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
483f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
484f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_bt_wlan_coex *pta;
485f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
486f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
487f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx sg enable");
488f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
489f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	pta = kzalloc(sizeof(*pta), GFP_KERNEL);
490f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!pta) {
491f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
492f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
493f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
494f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
4957fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen	if (enable)
4967fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen		pta->enable = wl->conf.sg.state;
4977fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen	else
4987fc3a8647d2eaa8bc2f7ac7e9baff55199da7be6Juuso Oikarinen		pta->enable = CONF_SG_DISABLE;
499f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
500f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
501f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
502f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set softgemini enable: %d", ret);
503f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
504f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
505f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
506f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
507f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(pta);
508f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
509f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
510f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5113be4112cb2c53fcda85fb408aea9a6f94075683bEliad Pellerint wl12xx_acx_sg_cfg(struct wl1271 *wl)
512f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
5133be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller	struct acx_bt_wlan_coex_param *param;
5142b60100bf04aba28133ccb24efd85f72fb1a5494Juuso Oikarinen	struct conf_sg_settings *c = &wl->conf.sg;
5151b00f546fc4271d94c1bccb1955ce64d9ace1000Juuso Oikarinen	int i, ret;
516f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5173be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller	wl1271_debug(DEBUG_ACX, "acx sg cfg");
518f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
519f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	param = kzalloc(sizeof(*param), GFP_KERNEL);
520f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!param) {
521f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
522f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
523f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
524f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
525f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* BT-WLAN coext parameters */
5263be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller	for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
5273be4112cb2c53fcda85fb408aea9a6f94075683bEliad Peller		param->params[i] = cpu_to_le32(c->params[i]);
5281b00f546fc4271d94c1bccb1955ce64d9ace1000Juuso Oikarinen	param->param_idx = CONF_SG_PARAMS_ALL;
529f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
530f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
531f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
532f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set sg config: %d", ret);
533f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
534f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
535f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
536f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
537f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(param);
538f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
539f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
540f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
541f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_cca_threshold(struct wl1271 *wl)
542f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
543f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_energy_detection *detection;
544f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
545f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
546f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx cca threshold");
547f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
548f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	detection = kzalloc(sizeof(*detection), GFP_KERNEL);
549f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!detection) {
550f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
551f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
552f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
553f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
554d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold);
55545b531a86f93c82d8e390e19a6258111b3627bb0Juuso Oikarinen	detection->tx_energy_detection = wl->conf.tx.tx_energy_detection;
556f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
557f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
558f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   detection, sizeof(*detection));
559f8afdf481f0fef5e170c6c928cec42879d505654Julia Lawall	if (ret < 0)
560f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set cca threshold: %d", ret);
561f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
562f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
563f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(detection);
564f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
565f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
566f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5670603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_bcn_dtim_options(struct wl1271 *wl, struct wl12xx_vif *wlvif)
568f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
569f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_beacon_broadcast *bb;
570f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
571f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
572f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
573f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
574f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
575f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!bb) {
576f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
577f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
578f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
579f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5800603d891c5b5153f667a79357d4652824c22b54eEliad Peller	bb->role_id = wlvif->role_id;
581d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout);
582d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout);
58351f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps;
58451f2be24328957f9e2acf116b1b1d2dfd10bf41fJuuso Oikarinen	bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold;
585f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
586f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
587f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
588f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set rx config: %d", ret);
589f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
590f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
591f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
592f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
593f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(bb);
594f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
595f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
596f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
5970603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_aid(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid)
598f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
599f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_aid *acx_aid;
600f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
601f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
602f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx aid");
603f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
604f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
605f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx_aid) {
606f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
607f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
608f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
609f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
6100603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx_aid->role_id = wlvif->role_id;
611d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	acx_aid->aid = cpu_to_le16(aid);
612f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
613f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
614f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
615f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set aid: %d", ret);
616f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
617f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
618f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
619f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
620f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx_aid);
621f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
622f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
623f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
624f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
625f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
626f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_event_mask *mask;
627f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
628f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
629f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx event mbox mask");
630f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
631f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	mask = kzalloc(sizeof(*mask), GFP_KERNEL);
632f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!mask) {
633f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
634f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
635f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
636f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
637f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* high event mask is unused */
638d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	mask->high_event_mask = cpu_to_le32(0xffffffff);
639d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	mask->event_mask = cpu_to_le32(event_mask);
640f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
641f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
642f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   mask, sizeof(*mask));
643f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
644f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
645f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
646f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
647f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
648f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
649f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(mask);
650f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
651f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
652f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
6530603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif,
6540603d891c5b5153f667a79357d4652824c22b54eEliad Peller			    enum acx_preamble_type preamble)
655f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
656f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_preamble *acx;
657f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
658f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
659f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx_set_preamble");
660f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
661f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
662f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
663f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
664f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
665f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
666f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
6670603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
668f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx->preamble = preamble;
669f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
670f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
671f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
672f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("Setting of preamble failed: %d", ret);
673f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
674f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
675f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
676f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
677f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
678f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
679f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
680f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
6810603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif,
682f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho			   enum acx_ctsprotect_type ctsprotect)
683f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
684f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_ctsprotect *acx;
685f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
686f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
687f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
688f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
689f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
690f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
691f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
692f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
693f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
694f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
6950603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
696f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx->ctsprotect = ctsprotect;
697f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
698f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
699f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
700f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("Setting of ctsprotect failed: %d", ret);
701f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
702f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
703f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
704f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
705f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
706f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
707f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
708f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
709f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
710f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
711f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
712f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
713f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx statistics");
714f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
715f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
716f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				     sizeof(*stats));
717f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
718f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("acx statistics failed: %d", ret);
719f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return -ENOMEM;
720f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
721f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
722f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
723f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
724f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
72530d0c8fd5b87d1c5486705d6420545a21533e115Eliad Pellerint wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
726f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
7277f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	struct acx_rate_policy *acx;
7281e05a81888318752e9a6d2158a95ddd6442ae117Arik Nemtsov	struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf;
729f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret = 0;
730f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
731f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx rate policies");
732f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
733f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
734f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
735f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
736f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
737f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
738f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
739f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
7407f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x",
741d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller		wlvif->basic_rate, wlvif->rate_set);
7427f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller
743830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen	/* configure one basic rate class */
744e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller	acx->rate_policy_idx = cpu_to_le32(wlvif->sta.basic_rate_idx);
745d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller	acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->basic_rate);
7467f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	acx->rate_policy.short_retry_limit = c->short_retry_limit;
7477f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	acx->rate_policy.long_retry_limit = c->long_retry_limit;
7487f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	acx->rate_policy.aflags = c->aflags;
7497f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller
7507f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
7517f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	if (ret < 0) {
7527f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller		wl1271_warning("Setting of rate policies failed: %d", ret);
7537f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller		goto out;
7547f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	}
755830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen
756830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen	/* configure one AP supported rate class */
757e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller	acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx);
75830d0c8fd5b87d1c5486705d6420545a21533e115Eliad Peller	acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set);
7597f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	acx->rate_policy.short_retry_limit = c->short_retry_limit;
7607f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	acx->rate_policy.long_retry_limit = c->long_retry_limit;
7617f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	acx->rate_policy.aflags = c->aflags;
762830fb67b8e37fb03cf703b4e1217fe30ce32d579Juuso Oikarinen
7634b29886feb072427df80ca6395b2b11a09245eafEliad Peller	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
7644b29886feb072427df80ca6395b2b11a09245eafEliad Peller	if (ret < 0) {
7654b29886feb072427df80ca6395b2b11a09245eafEliad Peller		wl1271_warning("Setting of rate policies failed: %d", ret);
7664b29886feb072427df80ca6395b2b11a09245eafEliad Peller		goto out;
7674b29886feb072427df80ca6395b2b11a09245eafEliad Peller	}
768f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
7694b29886feb072427df80ca6395b2b11a09245eafEliad Peller	/*
7704b29886feb072427df80ca6395b2b11a09245eafEliad Peller	 * configure one rate class for basic p2p operations.
7714b29886feb072427df80ca6395b2b11a09245eafEliad Peller	 * (p2p packets should always go out with OFDM rates, even
7724b29886feb072427df80ca6395b2b11a09245eafEliad Peller	 * if we are currently connected to 11b AP)
7734b29886feb072427df80ca6395b2b11a09245eafEliad Peller	 */
774e5a359f873f50cc123d5ca97637caa30fa095bb9Eliad Peller	acx->rate_policy_idx = cpu_to_le32(wlvif->sta.p2p_rate_idx);
7754b29886feb072427df80ca6395b2b11a09245eafEliad Peller	acx->rate_policy.enabled_rates =
7764b29886feb072427df80ca6395b2b11a09245eafEliad Peller				cpu_to_le32(CONF_TX_RATE_MASK_BASIC_P2P);
7774b29886feb072427df80ca6395b2b11a09245eafEliad Peller	acx->rate_policy.short_retry_limit = c->short_retry_limit;
7784b29886feb072427df80ca6395b2b11a09245eafEliad Peller	acx->rate_policy.long_retry_limit = c->long_retry_limit;
7794b29886feb072427df80ca6395b2b11a09245eafEliad Peller	acx->rate_policy.aflags = c->aflags;
78072c2d9e511846a4f2759389b38ed8a5553579eb3Eliad Peller
781f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
782f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
783f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("Setting of rate policies failed: %d", ret);
784f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
785f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
786f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
787f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
788f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
789f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
790f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
791f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
79279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsovint wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
79379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		      u8 idx)
79479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov{
7957f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	struct acx_rate_policy *acx;
79679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	int ret = 0;
79779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
79870f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov	wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
79970f474241b3d5fb633635a2ce39ea9da4afeea6cArik Nemtsov		     idx, c->enabled_rates);
80079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
80179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
80279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	if (!acx) {
80379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		ret = -ENOMEM;
80479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		goto out;
80579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	}
80679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
80779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	acx->rate_policy.enabled_rates = cpu_to_le32(c->enabled_rates);
80879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	acx->rate_policy.short_retry_limit = c->short_retry_limit;
80979b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	acx->rate_policy.long_retry_limit = c->long_retry_limit;
81079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	acx->rate_policy.aflags = c->aflags;
81179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
8121d4801f2689dc2618fdb5e83d4cb7743747491edEliad Peller	acx->rate_policy_idx = cpu_to_le32(idx);
81379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
81479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
81579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	if (ret < 0) {
81679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		wl1271_warning("Setting of ap rate policy failed: %d", ret);
81779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		goto out;
81879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	}
81979b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
82079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsovout:
82179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	kfree(acx);
82279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	return ret;
82379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov}
82479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
8250603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_ac_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
8260603d891c5b5153f667a79357d4652824c22b54eEliad Peller		      u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop)
827f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
828f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_ac_cfg *acx;
829243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	int ret = 0;
830f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
831243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
832243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo		     "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop);
833f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
834f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
835f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
836f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
837f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
838f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
839f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
840f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
8410603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
842243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	acx->ac = ac;
843243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	acx->cw_min = cw_min;
844243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	acx->cw_max = cpu_to_le16(cw_max);
845243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	acx->aifsn = aifsn;
846243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	acx->tx_op_limit = cpu_to_le16(txop);
847f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
848243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
849243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo	if (ret < 0) {
850243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo		wl1271_warning("acx ac cfg failed: %d", ret);
851243eeb51eaa0a33caeff3e2275b2460eea5579ecKalle Valo		goto out;
852f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
853f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
854f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
855f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
856f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
857f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
858f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
8590603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_tid_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif,
8600603d891c5b5153f667a79357d4652824c22b54eEliad Peller		       u8 queue_id, u8 channel_type,
861f2054df5170734eacd1db82138c70746ec8387deKalle Valo		       u8 tsid, u8 ps_scheme, u8 ack_policy,
862f2054df5170734eacd1db82138c70746ec8387deKalle Valo		       u32 apsd_conf0, u32 apsd_conf1)
863f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
864f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_tid_config *acx;
865f2054df5170734eacd1db82138c70746ec8387deKalle Valo	int ret = 0;
866f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
867f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx tid config");
868f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
869f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
870f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
871f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
872f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
873f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
874f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
875f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
8760603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
877f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->queue_id = queue_id;
878f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->channel_type = channel_type;
879f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->tsid = tsid;
880f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->ps_scheme = ps_scheme;
881f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->ack_policy = ack_policy;
882f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->apsd_conf[0] = cpu_to_le32(apsd_conf0);
883f2054df5170734eacd1db82138c70746ec8387deKalle Valo	acx->apsd_conf[1] = cpu_to_le32(apsd_conf1);
884f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
885f2054df5170734eacd1db82138c70746ec8387deKalle Valo	ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
886f2054df5170734eacd1db82138c70746ec8387deKalle Valo	if (ret < 0) {
887f2054df5170734eacd1db82138c70746ec8387deKalle Valo		wl1271_warning("Setting of tid config failed: %d", ret);
888f2054df5170734eacd1db82138c70746ec8387deKalle Valo		goto out;
889f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
890f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
891f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
892f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
893f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
894f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
895f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
8965f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsovint wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
897f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
898f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_frag_threshold *acx;
899f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret = 0;
900f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
9015f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	/*
9025f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	 * If the fragmentation is not configured or out of range, use the
9035f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	 * default value.
9045f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	 */
9055f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
9065f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov		frag_threshold = wl->conf.tx.frag_threshold;
9075f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov
9085f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
909f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
910f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
911f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
912f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
913f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
914f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
915f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
916f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
9175f704d180e448d05859e1cb6572822ba27dbcdc7Arik Nemtsov	acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
918f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
919f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
920f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("Setting of frag threshold failed: %d", ret);
921f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
922f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
923f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
924f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
925f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
926f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
927f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
928f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
929f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_tx_config_options(struct wl1271 *wl)
930f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
931f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct acx_tx_config_options *acx;
932f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret = 0;
933f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
934f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "acx tx config options");
935f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
936f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
937f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
938f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!acx) {
939f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
940f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
941f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
942f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
943d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout);
944d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold);
945f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
946f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
947f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("Setting of tx options failed: %d", ret);
948f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
949f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
950f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
951f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
952f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(acx);
953f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
954f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
955f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
9567f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Pellerint wl12xx_acx_mem_cfg(struct wl1271 *wl)
957f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
9587f097988f1bff42177b99cb4c8ec62e818d0b1a6Eliad Peller	struct wl12xx_acx_config_memory *mem_conf;
95913b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	struct conf_memory_settings *mem;
960f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
961f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
962c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
963c8bde243421d759844264cf11e4248e7862c2722Eliad Peller
964c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
965c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	if (!mem_conf) {
966c8bde243421d759844264cf11e4248e7862c2722Eliad Peller		ret = -ENOMEM;
967c8bde243421d759844264cf11e4248e7862c2722Eliad Peller		goto out;
968c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	}
969c8bde243421d759844264cf11e4248e7862c2722Eliad Peller
97013b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	if (wl->chip.id == CHIP_ID_1283_PG20)
97113b107dd9808343d05627f0fba7fbc764c86738eShahar Levi		mem = &wl->conf.mem_wl128x;
97213b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	else
97313b107dd9808343d05627f0fba7fbc764c86738eShahar Levi		mem = &wl->conf.mem_wl127x;
97413b107dd9808343d05627f0fba7fbc764c86738eShahar Levi
975c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	/* memory config */
97613b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->num_stations = mem->num_stations;
97713b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->rx_mem_block_num = mem->rx_block_num;
97813b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
97913b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->num_ssid_profiles = mem->ssid_profiles;
980c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
98113b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->dyn_mem_enable = mem->dynamic_memory;
98213b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->tx_free_req = mem->min_req_tx_blocks;
98313b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->rx_free_req = mem->min_req_rx_blocks;
98413b107dd9808343d05627f0fba7fbc764c86738eShahar Levi	mem_conf->tx_min = mem->tx_min;
98595dac04f881322b510c45e5ae83f0dbee4f823a2Ido Yariv	mem_conf->fwlog_blocks = wl->conf.fwlog.mem_blocks;
986c8bde243421d759844264cf11e4248e7862c2722Eliad Peller
987c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
988c8bde243421d759844264cf11e4248e7862c2722Eliad Peller				   sizeof(*mem_conf));
989c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	if (ret < 0) {
990c8bde243421d759844264cf11e4248e7862c2722Eliad Peller		wl1271_warning("wl1271 mem config failed: %d", ret);
991c8bde243421d759844264cf11e4248e7862c2722Eliad Peller		goto out;
992c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	}
993c8bde243421d759844264cf11e4248e7862c2722Eliad Peller
994c8bde243421d759844264cf11e4248e7862c2722Eliad Pellerout:
995c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	kfree(mem_conf);
996c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	return ret;
997c8bde243421d759844264cf11e4248e7862c2722Eliad Peller}
998c8bde243421d759844264cf11e4248e7862c2722Eliad Peller
99948a61477bdc04896bd96d259388a0c42a7019943Shahar Leviint wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
100048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi{
100148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	struct wl1271_acx_host_config_bitmap *bitmap_conf;
100248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	int ret;
100348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
100448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
100548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	if (!bitmap_conf) {
100648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		ret = -ENOMEM;
100748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		goto out;
100848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	}
100948a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
101048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
101148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
101248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
101348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi				   bitmap_conf, sizeof(*bitmap_conf));
101448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	if (ret < 0) {
101548a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
101648a61477bdc04896bd96d259388a0c42a7019943Shahar Levi		goto out;
101748a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	}
101848a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
101948a61477bdc04896bd96d259388a0c42a7019943Shahar Leviout:
102048a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	kfree(bitmap_conf);
102148a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
102248a61477bdc04896bd96d259388a0c42a7019943Shahar Levi	return ret;
102348a61477bdc04896bd96d259388a0c42a7019943Shahar Levi}
102448a61477bdc04896bd96d259388a0c42a7019943Shahar Levi
1025c8bde243421d759844264cf11e4248e7862c2722Eliad Pellerint wl1271_acx_init_mem_config(struct wl1271 *wl)
1026c8bde243421d759844264cf11e4248e7862c2722Eliad Peller{
1027c8bde243421d759844264cf11e4248e7862c2722Eliad Peller	int ret;
1028f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1029f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
103045b531a86f93c82d8e390e19a6258111b3627bb0Juuso Oikarinen				     GFP_KERNEL);
1031f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!wl->target_mem_map) {
1032f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_error("couldn't allocate target memory map");
1033f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return -ENOMEM;
1034f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
1035f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1036f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* we now ask for the firmware built memory map */
1037f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
1038f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				 sizeof(struct wl1271_acx_mem_map));
1039f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
1040f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_error("couldn't retrieve firmware memory map");
1041f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		kfree(wl->target_mem_map);
1042f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl->target_mem_map = NULL;
1043f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		return ret;
1044f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
1045f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1046f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	/* initialize TX block book keeping */
1047d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	wl->tx_blocks_available =
1048d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho		le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks);
1049f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_TX, "available tx blocks: %d",
1050f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		     wl->tx_blocks_available);
1051f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1052f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return 0;
1053f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
1054f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1055f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoint wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
1056f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho{
1057f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	struct wl1271_acx_rx_config_opt *rx_conf;
1058f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	int ret;
1059f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1060f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
1061f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1062f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
1063f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (!rx_conf) {
1064f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		ret = -ENOMEM;
1065f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
1066f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
1067f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1068d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold);
1069d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout);
1070d0f63b202146f3281800ee44823740c8bbf38f11Luciano Coelho	rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold);
10718793f9bb19c00b26532e37f1f516e1d9c7bc0476Juuso Oikarinen	rx_conf->queue_type = wl->conf.rx.queue_type;
1072f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1073f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
1074f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho				   sizeof(*rx_conf));
1075f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	if (ret < 0) {
1076f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		wl1271_warning("wl1271 rx config opt failed: %d", ret);
1077f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho		goto out;
1078f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	}
1079f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho
1080f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelhoout:
1081f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	kfree(rx_conf);
1082f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho	return ret;
1083f5fc0f86b02afef1119b523623b4cde41475bc8cLuciano Coelho}
10843cfd6cf960b2b030ccae1144a5c0dcd91c7c56a8Juuso Oikarinen
10850603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
10860603d891c5b5153f667a79357d4652824c22b54eEliad Peller			  bool enable)
108711f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen{
108811f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	struct wl1271_acx_bet_enable *acx = NULL;
108911f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	int ret = 0;
109011f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen
109111f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx bet enable");
109211f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen
109311f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE)
109411f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen		goto out;
109511f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen
109611f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
109711f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	if (!acx) {
109811f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen		ret = -ENOMEM;
109911f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen		goto out;
110011f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	}
110111f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen
11020603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
110311f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE;
110411f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	acx->max_consecutive = wl->conf.conn.bet_max_consecutive;
110511f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen
110611f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx));
110711f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	if (ret < 0) {
110811f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen		wl1271_warning("acx bet enable failed: %d", ret);
110911f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen		goto out;
111011f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	}
111111f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen
111211f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinenout:
111311f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	kfree(acx);
111411f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen	return ret;
111511f70f9715f0d8f99eac42d69689e8df15283feaJuuso Oikarinen}
111601c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
11170603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_arp_ip_filter(struct wl1271 *wl, struct wl12xx_vif *wlvif,
11180603d891c5b5153f667a79357d4652824c22b54eEliad Peller			     u8 enable, __be32 address)
111901c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen{
112001c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	struct wl1271_acx_arp_filter *acx;
112101c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	int ret;
112201c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
1123ca52a5ebbb7caff2995214a6ca41a36c5210b0bdJuuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
112401c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
112501c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
112601c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	if (!acx) {
112701c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen		ret = -ENOMEM;
112801c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen		goto out;
112901c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	}
113001c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
11310603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
1132eb887dfd8837bf0a2538418c02b3992fb9ff1f28Juuso Oikarinen	acx->version = ACX_IPV4_VERSION;
1133ca52a5ebbb7caff2995214a6ca41a36c5210b0bdJuuso Oikarinen	acx->enable = enable;
113401c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
1135c5312772156bb5f9b2e95e4c91526d578426a069Eliad Peller	if (enable)
1136ca52a5ebbb7caff2995214a6ca41a36c5210b0bdJuuso Oikarinen		memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
113701c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
113801c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
113901c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen				   acx, sizeof(*acx));
114001c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	if (ret < 0) {
114101c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen		wl1271_warning("failed to set arp ip filter: %d", ret);
114201c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen		goto out;
114301c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	}
114401c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen
114501c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinenout:
114601c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	kfree(acx);
114701c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen	return ret;
114801c09162cd6170f3671825d6d5f2c1ae7b27cbf3Juuso Oikarinen}
114938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
115038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinenint wl1271_acx_pm_config(struct wl1271 *wl)
115138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen{
115238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	struct wl1271_acx_pm_config *acx = NULL;
115338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	struct  conf_pm_config_settings *c = &wl->conf.pm_config;
115438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	int ret = 0;
115538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
115638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx pm config");
115738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
115838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
115938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	if (!acx) {
116038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen		ret = -ENOMEM;
116138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen		goto out;
116238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	}
116338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
116438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time);
116538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	acx->host_fast_wakeup_support = c->host_fast_wakeup_support;
116638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
116738ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx));
116838ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	if (ret < 0) {
116938ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen		wl1271_warning("acx pm config failed: %d", ret);
117038ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen		goto out;
117138ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	}
117238ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen
117338ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinenout:
117438ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	kfree(acx);
117538ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen	return ret;
117638ad2d87d42ba847c100ef132e8e363513982c8bJuuso Oikarinen}
1177c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
11780603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
11790603d891c5b5153f667a79357d4652824c22b54eEliad Peller			       bool enable)
1180c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen{
1181c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	struct wl1271_acx_keep_alive_mode *acx = NULL;
1182c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	int ret = 0;
1183c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1184c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1185c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1186c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1187c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	if (!acx) {
1188c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		ret = -ENOMEM;
1189c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		goto out;
1190c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	}
1191c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
11920603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
1193c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx->enabled = enable;
1194c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1195c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1196c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	if (ret < 0) {
1197c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		wl1271_warning("acx keep alive mode failed: %d", ret);
1198c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		goto out;
1199c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	}
1200c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1201c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinenout:
1202c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	kfree(acx);
1203c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	return ret;
1204c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen}
120500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
12060603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_keep_alive_config(struct wl1271 *wl, struct wl12xx_vif *wlvif,
12070603d891c5b5153f667a79357d4652824c22b54eEliad Peller				 u8 index, u8 tpl_valid)
1208c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen{
1209c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	struct wl1271_acx_keep_alive_config *acx = NULL;
1210c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	int ret = 0;
1211c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1212c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx keep alive config");
1213c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1214c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1215c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	if (!acx) {
1216c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		ret = -ENOMEM;
1217c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		goto out;
1218c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	}
1219c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
12200603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
1221c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1222c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx->index = index;
1223c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx->tpl_validation = tpl_valid;
1224c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1225c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1226c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1227c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen				   acx, sizeof(*acx));
1228c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	if (ret < 0) {
1229c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		wl1271_warning("acx keep alive config failed: %d", ret);
1230c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen		goto out;
1231c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	}
1232c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen
1233c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinenout:
1234c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	kfree(acx);
1235c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen	return ret;
1236c18995540cc4d2c84d130581b8b6720b22ca16b5Juuso Oikarinen}
123700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
12380603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif,
12390603d891c5b5153f667a79357d4652824c22b54eEliad Peller				bool enable, s16 thold, u8 hyst)
124000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen{
124100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	struct wl1271_acx_rssi_snr_trigger *acx = NULL;
124200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	int ret = 0;
124300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
124400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
124500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
124600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
124700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	if (!acx) {
124800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		ret = -ENOMEM;
124900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		goto out;
125000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	}
125100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
125204324d99818d16da4f64e266b45cad2e5803b961Eliad Peller	wlvif->last_rssi_event = -1;
125300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
12540603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
125500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
125600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
125700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
125800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	if (enable)
125900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		acx->enable = WL1271_ACX_TRIG_ENABLE;
126000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	else
126100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		acx->enable = WL1271_ACX_TRIG_DISABLE;
126200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
126300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->index = WL1271_ACX_TRIG_IDX_RSSI;
126400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
126500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->threshold = cpu_to_le16(thold);
126600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->hysteresis = hyst;
126700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
126800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
126900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	if (ret < 0) {
127000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
127100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		goto out;
127200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	}
127300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
127400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinenout:
127500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	kfree(acx);
127600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	return ret;
127700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen}
127800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
12790603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl,
12800603d891c5b5153f667a79357d4652824c22b54eEliad Peller				    struct wl12xx_vif *wlvif)
128100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen{
128200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
128300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
128400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	int ret = 0;
128500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
128600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
128700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
128800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
128900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	if (!acx) {
129000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		ret = -ENOMEM;
129100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		goto out;
129200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	}
129300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
12940603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
129500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->rssi_beacon = c->avg_weight_rssi_beacon;
129600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->rssi_data = c->avg_weight_rssi_data;
129700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->snr_beacon = c->avg_weight_snr_beacon;
129800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	acx->snr_data = c->avg_weight_snr_data;
129900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
130000236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
130100236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	if (ret < 0) {
130200236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
130300236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen		goto out;
130400236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	}
130500236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen
130600236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinenout:
130700236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	kfree(acx);
130800236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen	return ret;
130900236aedf1d2c49a18ae9ea00698d97705ff7289Juuso Oikarinen}
1310bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen
1311c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviint wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1312c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi				    struct ieee80211_sta_ht_cap *ht_cap,
13130b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov				    bool allow_ht_operation, u8 hlid)
1314c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi{
1315c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	struct wl1271_acx_ht_capabilities *acx;
1316c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	int ret = 0;
13176177eaea277527e48753d050723cd138494c98a8Eliad Peller	u32 ht_capabilites = 0;
1318c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
13190b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov	wl1271_debug(DEBUG_ACX, "acx ht capabilities setting "
13200b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov		     "sta supp: %d sta cap: %d", ht_cap->ht_supported,
13210b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov		     ht_cap->cap);
1322c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1323c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1324c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	if (!acx) {
1325c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		ret = -ENOMEM;
1326c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		goto out;
1327c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	}
1328c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
13290b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov	if (allow_ht_operation && ht_cap->ht_supported) {
13300f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		/* no need to translate capabilities - use the spec values */
13310f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		ht_capabilites = ht_cap->cap;
13320f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov
13330f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		/*
13340f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		 * this bit is not employed by the spec but only by FW to
13350f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		 * indicate peer HT support
13360f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		 */
13370f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		ht_capabilites |= WL12XX_HT_CAP_HT_OPERATION;
1338c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1339c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		/* get data from A-MPDU parameters field */
1340c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		acx->ampdu_max_length = ht_cap->ampdu_factor;
1341c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		acx->ampdu_min_spacing = ht_cap->ampdu_density;
1342c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	}
1343c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
13440b932ab9f156488a56577873b638ecb1e65fa8d7Arik Nemtsov	acx->hlid = hlid;
13456177eaea277527e48753d050723cd138494c98a8Eliad Peller	acx->ht_capabilites = cpu_to_le32(ht_capabilites);
13466177eaea277527e48753d050723cd138494c98a8Eliad Peller
1347c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
1348c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	if (ret < 0) {
1349c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		wl1271_warning("acx ht capabilities setting failed: %d", ret);
1350c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		goto out;
1351c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	}
1352c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1353c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviout:
1354c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	kfree(acx);
1355c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	return ret;
1356c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi}
1357c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1358c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviint wl1271_acx_set_ht_information(struct wl1271 *wl,
13590603d891c5b5153f667a79357d4652824c22b54eEliad Peller				   struct wl12xx_vif *wlvif,
1360c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi				   u16 ht_operation_mode)
1361c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi{
1362c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	struct wl1271_acx_ht_information *acx;
1363c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	int ret = 0;
1364c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1365c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	wl1271_debug(DEBUG_ACX, "acx ht information setting");
1366c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1367c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1368c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	if (!acx) {
1369c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		ret = -ENOMEM;
1370c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		goto out;
1371c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	}
1372c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
13730603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
1374c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	acx->ht_protection =
1375c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		(u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
1376c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	acx->rifs_mode = 0;
137795a776107a131823c87147dff083696d8814c1b3Helmut Schaa	acx->gf_protection =
137895a776107a131823c87147dff083696d8814c1b3Helmut Schaa		!!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1379c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	acx->ht_tx_burst_limit = 0;
1380c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	acx->dual_cts_protection = 0;
1381c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1382c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
1383c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1384c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	if (ret < 0) {
1385c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		wl1271_warning("acx ht information setting failed: %d", ret);
1386c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi		goto out;
1387c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	}
1388c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
1389c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Leviout:
1390c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	kfree(acx);
1391c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi	return ret;
1392c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi}
1393c4db1c879679e795689ef3c9dd7d3f6568ea14c5Shahar Levi
13944b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar/* Configure BA session initiator/receiver parameters setting in the FW. */
13950603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
13960603d891c5b5153f667a79357d4652824c22b54eEliad Peller				       struct wl12xx_vif *wlvif)
13974b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar{
13980f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	struct wl1271_acx_ba_initiator_policy *acx;
13994b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	int ret;
14004b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
14010f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	wl1271_debug(DEBUG_ACX, "acx ba initiator policy");
14024b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
14034b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
14044b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	if (!acx) {
14054b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar		ret = -ENOMEM;
14064b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar		goto out;
14074b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	}
14084b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
14090f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	/* set for the current role */
14100603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
14110f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	acx->tid_bitmap = wl->conf.ht.tx_ba_tid_bitmap;
14120f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	acx->win_size = wl->conf.ht.tx_ba_win_size;
14130f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
14144b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
14154b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	ret = wl1271_cmd_configure(wl,
14160f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov				   ACX_BA_SESSION_INIT_POLICY,
14174b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar				   acx,
14184b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar				   sizeof(*acx));
14194b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	if (ret < 0) {
14200f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov		wl1271_warning("acx ba initiator policy failed: %d", ret);
14214b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar		goto out;
14224b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	}
14234b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
14244b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shaharout:
14254b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	kfree(acx);
14264b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar	return ret;
14274b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar}
14284b7fac77b4c1badac84df3dcbdf07199d94cb1c3Levi, Shahar
1429bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar/* setup BA session receiver setting in the FW. */
14300f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsovint wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
14310f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov				       u16 ssn, bool enable, u8 peer_hlid)
1432bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar{
1433bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	struct wl1271_acx_ba_receiver_setup *acx;
1434bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	int ret;
1435bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar
1436bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	wl1271_debug(DEBUG_ACX, "acx ba receiver session setting");
1437bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar
1438bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1439bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	if (!acx) {
1440bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar		ret = -ENOMEM;
1441bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar		goto out;
1442bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	}
1443bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar
14440f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	acx->hlid = peer_hlid;
1445bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	acx->tid = tid_index;
1446bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	acx->enable = enable;
14470f9c8250e10a16f48f82ffda3a5a7cb9e7b4a9eeArik Nemtsov	acx->win_size = wl->conf.ht.rx_ba_win_size;
1448bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	acx->ssn = ssn;
1449bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar
1450bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx,
1451bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar				   sizeof(*acx));
1452bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	if (ret < 0) {
1453bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar		wl1271_warning("acx ba receiver session failed: %d", ret);
1454bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar		goto out;
1455bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	}
1456bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar
1457bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shaharout:
1458bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	kfree(acx);
1459bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar	return ret;
1460bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar}
1461bbba3e6832ad3e974fb593a98abe03f8b60fc7f3Levi, Shahar
1462bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinenint wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
1463bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen{
1464bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	struct wl1271_acx_fw_tsf_information *tsf_info;
1465bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	int ret;
1466bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen
1467bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
1468bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	if (!tsf_info) {
1469bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen		ret = -ENOMEM;
1470bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen		goto out;
1471bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	}
1472bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen
1473bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO,
1474bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen				     tsf_info, sizeof(*tsf_info));
1475bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	if (ret < 0) {
1476bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen		wl1271_warning("acx tsf info interrogate failed");
1477bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen		goto out;
1478bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	}
1479bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen
1480bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	*mactime = le32_to_cpu(tsf_info->current_tsf_low) |
1481bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen		((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32);
1482bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen
1483bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinenout:
1484bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	kfree(tsf_info);
1485bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen	return ret;
1486bbbb538e337a3eb2166d5a20307b93822bdacc4fJuuso Oikarinen}
148779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
14889eb599e9c62dcfd4efece1936c385381b366b684Eliad Pellerint wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
14899eb599e9c62dcfd4efece1936c385381b366b684Eliad Peller			       bool enable)
1490f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller{
1491f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	struct wl1271_acx_ps_rx_streaming *rx_streaming;
1492f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	u32 conf_queues, enable_queues;
1493f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	int i, ret = 0;
1494f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
1495f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	wl1271_debug(DEBUG_ACX, "acx ps rx streaming");
1496f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
1497f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL);
1498f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	if (!rx_streaming) {
1499f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		ret = -ENOMEM;
1500f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		goto out;
1501f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	}
1502f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
1503f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	conf_queues = wl->conf.rx_streaming.queues;
1504f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	if (enable)
1505f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		enable_queues = conf_queues;
1506f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	else
1507f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		enable_queues = 0;
1508f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
1509f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	for (i = 0; i < 8; i++) {
1510f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		/*
1511f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		 * Skip non-changed queues, to avoid redundant acxs.
1512f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		 * this check assumes conf.rx_streaming.queues can't
1513f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		 * be changed while rx_streaming is enabled.
1514f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		 */
1515f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		if (!(conf_queues & BIT(i)))
1516f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller			continue;
1517f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
15180603d891c5b5153f667a79357d4652824c22b54eEliad Peller		rx_streaming->role_id = wlvif->role_id;
1519f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		rx_streaming->tid = i;
1520f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		rx_streaming->enable = enable_queues & BIT(i);
1521f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		rx_streaming->period = wl->conf.rx_streaming.interval;
1522f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		rx_streaming->timeout = wl->conf.rx_streaming.interval;
1523f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
1524f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		ret = wl1271_cmd_configure(wl, ACX_PS_RX_STREAMING,
1525f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller					   rx_streaming,
1526f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller					   sizeof(*rx_streaming));
1527f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		if (ret < 0) {
1528f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller			wl1271_warning("acx ps rx streaming failed: %d", ret);
1529f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller			goto out;
1530f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller		}
1531f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	}
1532f84673d59773ded6efab640c5ee5f44b34116b75Eliad Pellerout:
1533f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	kfree(rx_streaming);
1534f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller	return ret;
1535f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller}
1536f84673d59773ded6efab640c5ee5f44b34116b75Eliad Peller
15370603d891c5b5153f667a79357d4652824c22b54eEliad Pellerint wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif)
153879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov{
15393618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov	struct wl1271_acx_ap_max_tx_retry *acx = NULL;
154079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	int ret;
154179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
15423618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov	wl1271_debug(DEBUG_ACX, "acx ap max tx retry");
154379b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
154479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
154579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	if (!acx)
154679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		return -ENOMEM;
154779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
15480603d891c5b5153f667a79357d4652824c22b54eEliad Peller	acx->role_id = wlvif->role_id;
15493618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov	acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries);
155079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
155179b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
155279b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	if (ret < 0) {
15533618f30f307841dba19f22d9c602a5c59cab30c7Arik Nemtsov		wl1271_warning("acx ap max tx retry failed: %d", ret);
155479b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov		goto out;
155579b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	}
155679b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov
155779b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsovout:
155879b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	kfree(acx);
155979b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov	return ret;
156079b223f4c7ce35fba145c504de12be030cc0007eArik Nemtsov}
1561ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1562d2d66c56cf6c8727662aa321991f791604c22094Eliad Pellerint wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1563ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller{
1564ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	struct wl1271_acx_config_ps *config_ps;
1565ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	int ret;
1566ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1567ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	wl1271_debug(DEBUG_ACX, "acx config ps");
1568ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1569ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL);
1570ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	if (!config_ps) {
1571ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller		ret = -ENOMEM;
1572ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller		goto out;
1573ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	}
1574ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1575ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	config_ps->exit_retries = wl->conf.conn.psm_exit_retries;
1576ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	config_ps->enter_retries = wl->conf.conn.psm_entry_retries;
1577d2d66c56cf6c8727662aa321991f791604c22094Eliad Peller	config_ps->null_data_rate = cpu_to_le32(wlvif->basic_rate);
1578ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1579ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps,
1580ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller				   sizeof(*config_ps));
1581ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1582ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	if (ret < 0) {
1583ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller		wl1271_warning("acx config ps failed: %d", ret);
1584ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller		goto out;
1585ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	}
1586ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller
1587ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Pellerout:
1588ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	kfree(config_ps);
1589ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller	return ret;
1590ee60833a4f887a09e87be52cdf1247a4963b0aefEliad Peller}
159199a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov
159299a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsovint wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
159399a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov{
159499a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	struct wl1271_acx_inconnection_sta *acx = NULL;
159599a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	int ret;
159699a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov
159799a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr);
159899a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov
159999a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
160099a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	if (!acx)
160199a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov		return -ENOMEM;
160299a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov
160399a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	memcpy(acx->addr, addr, ETH_ALEN);
160499a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov
160599a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST,
160699a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov				   acx, sizeof(*acx));
160799a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	if (ret < 0) {
160899a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov		wl1271_warning("acx set inconnaction sta failed: %d", ret);
160999a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov		goto out;
161099a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	}
161199a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov
161299a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsovout:
161399a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	kfree(acx);
161499a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov	return ret;
161599a2775d02a7accf4cc661a65c76fd7b379d1c7aArik Nemtsov}
1616ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
1617ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Leviint wl1271_acx_fm_coex(struct wl1271 *wl)
1618ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi{
1619ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	struct wl1271_acx_fm_coex *acx;
1620ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	int ret;
1621ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
1622ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	wl1271_debug(DEBUG_ACX, "acx fm coex setting");
1623ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
1624ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1625ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	if (!acx) {
1626ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		ret = -ENOMEM;
1627ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		goto out;
1628ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	}
1629ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
1630ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->enable = wl->conf.fm_coex.enable;
1631ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->swallow_period = wl->conf.fm_coex.swallow_period;
1632ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
1633ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
1634ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->m_divider_fref_set_1 =
1635ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
1636ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->m_divider_fref_set_2 =
1637ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
1638ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->coex_pll_stabilization_time =
1639ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
1640ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->ldo_stabilization_time =
1641ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
1642ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->fm_disturbed_band_margin =
1643ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		wl->conf.fm_coex.fm_disturbed_band_margin;
1644ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
1645ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
1646ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
1647ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	if (ret < 0) {
1648ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		wl1271_warning("acx fm coex setting failed: %d", ret);
1649ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi		goto out;
1650ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	}
1651ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi
1652ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Leviout:
1653ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	kfree(acx);
1654ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi	return ret;
1655ff86843dfbb368766d0aecd0147821d9a2b60edbShahar Levi}
1656fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
1657fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Pellerint wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl)
1658fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller{
1659fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	struct wl12xx_acx_set_rate_mgmt_params *acx = NULL;
1660fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	struct conf_rate_policy_settings *conf = &wl->conf.rate;
1661fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	int ret;
1662fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
1663fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	wl1271_debug(DEBUG_ACX, "acx set rate mgmt params");
1664fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
1665fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1666fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	if (!acx)
1667fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller		return -ENOMEM;
1668fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
1669fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->index = ACX_RATE_MGMT_ALL_PARAMS;
1670fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->rate_retry_score = cpu_to_le16(conf->rate_retry_score);
1671fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_add = cpu_to_le16(conf->per_add);
1672fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_th1 = cpu_to_le16(conf->per_th1);
1673fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_th2 = cpu_to_le16(conf->per_th2);
1674fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->max_per = cpu_to_le16(conf->max_per);
1675fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->inverse_curiosity_factor = conf->inverse_curiosity_factor;
1676fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->tx_fail_low_th = conf->tx_fail_low_th;
1677fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->tx_fail_high_th = conf->tx_fail_high_th;
1678fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_alpha_shift = conf->per_alpha_shift;
1679fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_add_shift = conf->per_add_shift;
1680fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_beta1_shift = conf->per_beta1_shift;
1681fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->per_beta2_shift = conf->per_beta2_shift;
1682fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->rate_check_up = conf->rate_check_up;
1683fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	acx->rate_check_down = conf->rate_check_down;
1684fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	memcpy(acx->rate_retry_policy, conf->rate_retry_policy,
1685fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	       sizeof(acx->rate_retry_policy));
1686fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
1687fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	ret = wl1271_cmd_configure(wl, ACX_SET_RATE_MGMT_PARAMS,
1688fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller				   acx, sizeof(*acx));
1689fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	if (ret < 0) {
1690fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller		wl1271_warning("acx set rate mgmt params failed: %d", ret);
1691fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller		goto out;
1692fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	}
1693fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller
1694fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Pellerout:
1695fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	kfree(acx);
1696fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller	return ret;
1697fa6ad9f0f34b0754ce7551866b33587f077a2a51Eliad Peller}
16989487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
16999487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Pellerint wl12xx_acx_config_hangover(struct wl1271 *wl)
17009487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller{
17019487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	struct wl12xx_acx_config_hangover *acx;
17029487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	struct conf_hangover_settings *conf = &wl->conf.hangover;
17039487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	int ret;
17049487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17059487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	wl1271_debug(DEBUG_ACX, "acx config hangover");
17069487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17079487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
17089487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	if (!acx) {
17099487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller		ret = -ENOMEM;
17109487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller		goto out;
17119487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	}
17129487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17139487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->recover_time = cpu_to_le32(conf->recover_time);
17149487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->hangover_period = conf->hangover_period;
17159487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->dynamic_mode = conf->dynamic_mode;
17169487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->early_termination_mode = conf->early_termination_mode;
17179487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->max_period = conf->max_period;
17189487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->min_period = conf->min_period;
17199487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->increase_delta = conf->increase_delta;
17209487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->decrease_delta = conf->decrease_delta;
17219487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->quiet_time = conf->quiet_time;
17229487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->increase_time = conf->increase_time;
17239487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	acx->window_size = acx->window_size;
17249487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17259487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx,
17269487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller				   sizeof(*acx));
17279487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17289487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	if (ret < 0) {
17299487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller		wl1271_warning("acx config hangover failed: %d", ret);
17309487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller		goto out;
17319487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	}
17329487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17339487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Pellerout:
17349487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	kfree(acx);
17359487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller	return ret;
17369487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller
17379487775c5b785d7c1e8182825c9ff9cf5e88149eEliad Peller}
1738