aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/acx.c
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2009-06-12 07:14:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 14:57:41 -0400
commitff25839bf0c99e828c26864a24417a36a6b6a31e (patch)
treee5891ed357f4285f788056e270df7664b4d5aa13 /drivers/net/wireless/wl12xx/acx.c
parentc4f9f16b309b65f9f578ec4ba78b3efa106cf65d (diff)
wl12xx: cmd and acx interface rework
Rework cmd and acx interfaces, it was just too confusing earlier. Now all commands need to contain all the needed headers, either just cmd headers or both cmd and acx headers. This accomplish to remove the extra copy done for each command. The interfaces are now properly documented as well. Also try to make all commands safe for DMA transfers. I might have missed some, but most of them should be fixed now. And this is not all! As a free bonus you will also get some cosmetic cleanups and code reorganisation. Order today! Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/acx.c')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c690
1 files changed, 420 insertions, 270 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 1cfd458ad5ab..d0daf69558f0 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -13,126 +13,160 @@
13int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod, 13int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
14 u8 mgt_rate, u8 mgt_mod) 14 u8 mgt_rate, u8 mgt_mod)
15{ 15{
16 struct acx_fw_gen_frame_rates *rates;
16 int ret; 17 int ret;
17 struct acx_fw_gen_frame_rates rates;
18 18
19 wl12xx_debug(DEBUG_ACX, "acx frame rates"); 19 wl12xx_debug(DEBUG_ACX, "acx frame rates");
20 20
21 rates.header.id = ACX_FW_GEN_FRAME_RATES; 21 rates = kzalloc(sizeof(*rates), GFP_KERNEL);
22 rates.header.len = sizeof(struct acx_fw_gen_frame_rates) - 22 if (!rates) {
23 sizeof(struct acx_header); 23 ret = -ENOMEM;
24 goto out;
25 }
24 26
25 rates.tx_ctrl_frame_rate = ctrl_rate; 27 rates->tx_ctrl_frame_rate = ctrl_rate;
26 rates.tx_ctrl_frame_mod = ctrl_mod; 28 rates->tx_ctrl_frame_mod = ctrl_mod;
27 rates.tx_mgt_frame_rate = mgt_rate; 29 rates->tx_mgt_frame_rate = mgt_rate;
28 rates.tx_mgt_frame_mod = mgt_mod; 30 rates->tx_mgt_frame_mod = mgt_mod;
29 31
30 ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates)); 32 ret = wl12xx_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
33 rates, sizeof(*rates));
31 if (ret < 0) { 34 if (ret < 0) {
32 wl12xx_error("Failed to set FW rates and modulation"); 35 wl12xx_error("Failed to set FW rates and modulation");
33 return ret; 36 goto out;
34 } 37 }
35 38
36 return 0; 39out:
40 kfree(rates);
41 return ret;
37} 42}
38 43
39 44
40int wl12xx_acx_station_id(struct wl12xx *wl) 45int wl12xx_acx_station_id(struct wl12xx *wl)
41{ 46{
47 struct acx_dot11_station_id *mac;
42 int ret, i; 48 int ret, i;
43 struct dot11_station_id mac;
44 49
45 wl12xx_debug(DEBUG_ACX, "acx dot11_station_id"); 50 wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
46 51
47 mac.header.id = DOT11_STATION_ID; 52 mac = kzalloc(sizeof(*mac), GFP_KERNEL);
48 mac.header.len = sizeof(mac) - sizeof(struct acx_header); 53 if (!mac) {
54 ret = -ENOMEM;
55 goto out;
56 }
49 57
50 for (i = 0; i < ETH_ALEN; i++) 58 for (i = 0; i < ETH_ALEN; i++)
51 mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; 59 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
52 60
53 ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac)); 61 ret = wl12xx_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
54 if (ret < 0) 62 if (ret < 0)
55 return ret; 63 goto out;
56 64
57 return 0; 65out:
66 kfree(mac);
67 return ret;
58} 68}
59 69
60int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id) 70int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
61{ 71{
62 struct acx_dot11_default_key default_key; 72 struct acx_dot11_default_key *default_key;
63 int ret; 73 int ret;
64 74
65 wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); 75 wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
66 76
67 default_key.header.id = DOT11_DEFAULT_KEY; 77 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
68 default_key.header.len = sizeof(default_key) - 78 if (!default_key) {
69 sizeof(struct acx_header); 79 ret = -ENOMEM;
80 goto out;
81 }
70 82
71 default_key.id = key_id; 83 default_key->id = key_id;
72 84
73 ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key)); 85 ret = wl12xx_cmd_configure(wl, DOT11_DEFAULT_KEY,
86 default_key, sizeof(*default_key));
74 if (ret < 0) { 87 if (ret < 0) {
75 wl12xx_error("Couldnt set default key"); 88 wl12xx_error("Couldnt set default key");
76 return ret; 89 goto out;
77 } 90 }
78 91
79 wl->default_key = key_id; 92 wl->default_key = key_id;
80 93
81 return 0; 94out:
95 kfree(default_key);
96 return ret;
82} 97}
83 98
84int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval) 99int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
85{ 100{
86 struct acx_wake_up_condition wake_up; 101 struct acx_wake_up_condition *wake_up;
102 int ret;
87 103
88 wl12xx_debug(DEBUG_ACX, "acx wake up conditions"); 104 wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
89 105
90 wake_up.header.id = ACX_WAKE_UP_CONDITIONS; 106 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
91 wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header); 107 if (!wake_up) {
108 ret = -ENOMEM;
109 goto out;
110 }
92 111
93 wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP; 112 wake_up->wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
94 wake_up.listen_interval = listen_interval; 113 wake_up->listen_interval = listen_interval;
95 114
96 return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up)); 115 ret = wl12xx_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
116 wake_up, sizeof(*wake_up));
117 if (ret < 0) {
118 wl12xx_warning("could not set wake up conditions: %d", ret);
119 goto out;
120 }
121
122out:
123 kfree(wake_up);
124 return ret;
97} 125}
98 126
99int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth) 127int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
100{ 128{
129 struct acx_sleep_auth *auth;
101 int ret; 130 int ret;
102 struct acx_sleep_auth auth;
103 131
104 wl12xx_debug(DEBUG_ACX, "acx sleep auth"); 132 wl12xx_debug(DEBUG_ACX, "acx sleep auth");
105 133
106 auth.header.id = ACX_SLEEP_AUTH; 134 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
107 auth.header.len = sizeof(auth) - sizeof(struct acx_header); 135 if (!auth) {
136 ret = -ENOMEM;
137 goto out;
138 }
108 139
109 auth.sleep_auth = sleep_auth; 140 auth->sleep_auth = sleep_auth;
110 141
111 ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth)); 142 ret = wl12xx_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
112 if (ret < 0) 143 if (ret < 0)
113 return ret; 144 return ret;
114 145
115 return 0; 146out:
147 kfree(auth);
148 return ret;
116} 149}
117 150
118int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len) 151int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
119{ 152{
120 struct wl12xx_command cmd;
121 struct acx_revision *rev; 153 struct acx_revision *rev;
122 int ret; 154 int ret;
123 155
124 wl12xx_debug(DEBUG_ACX, "acx fw rev"); 156 wl12xx_debug(DEBUG_ACX, "acx fw rev");
125 157
126 memset(&cmd, 0, sizeof(cmd)); 158 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
159 if (!rev) {
160 ret = -ENOMEM;
161 goto out;
162 }
127 163
128 ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd); 164 ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
129 if (ret < 0) { 165 if (ret < 0) {
130 wl12xx_warning("ACX_FW_REV interrogate failed"); 166 wl12xx_warning("ACX_FW_REV interrogate failed");
131 return ret; 167 goto out;
132 } 168 }
133 169
134 rev = (struct acx_revision *) &cmd.parameters;
135
136 /* be careful with the buffer sizes */ 170 /* be careful with the buffer sizes */
137 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version))); 171 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
138 172
@@ -143,12 +177,14 @@ int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
143 */ 177 */
144 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0'; 178 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
145 179
146 return 0; 180out:
181 kfree(rev);
182 return ret;
147} 183}
148 184
149int wl12xx_acx_tx_power(struct wl12xx *wl, int power) 185int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
150{ 186{
151 struct acx_current_tx_power ie; 187 struct acx_current_tx_power *acx;
152 int ret; 188 int ret;
153 189
154 wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); 190 wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
@@ -156,534 +192,648 @@ int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
156 if (power < 0 || power > 25) 192 if (power < 0 || power > 25)
157 return -EINVAL; 193 return -EINVAL;
158 194
159 memset(&ie, 0, sizeof(ie)); 195 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
196 if (!acx) {
197 ret = -ENOMEM;
198 goto out;
199 }
160 200
161 ie.header.id = DOT11_CUR_TX_PWR; 201 acx->current_tx_power = power * 10;
162 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
163 ie.current_tx_power = power * 10;
164 202
165 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie)); 203 ret = wl12xx_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
166 if (ret < 0) { 204 if (ret < 0) {
167 wl12xx_warning("configure of tx power failed: %d", ret); 205 wl12xx_warning("configure of tx power failed: %d", ret);
168 return ret; 206 goto out;
169 } 207 }
170 208
171 return 0; 209out:
210 kfree(acx);
211 return ret;
172} 212}
173 213
174int wl12xx_acx_feature_cfg(struct wl12xx *wl) 214int wl12xx_acx_feature_cfg(struct wl12xx *wl)
175{ 215{
176 struct acx_feature_config feature; 216 struct acx_feature_config *feature;
177 int ret; 217 int ret;
178 218
179 wl12xx_debug(DEBUG_ACX, "acx feature cfg"); 219 wl12xx_debug(DEBUG_ACX, "acx feature cfg");
180 220
181 memset(&feature, 0, sizeof(feature)); 221 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
182 222 if (!feature) {
183 feature.header.id = ACX_FEATURE_CFG; 223 ret = -ENOMEM;
184 feature.header.len = sizeof(feature) - sizeof(struct acx_header); 224 goto out;
225 }
185 226
186 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ 227 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
187 feature.data_flow_options = 0; 228 feature->data_flow_options = 0;
188 feature.options = 0; 229 feature->options = 0;
189 230
190 ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature)); 231 ret = wl12xx_cmd_configure(wl, ACX_FEATURE_CFG,
191 if (ret < 0) 232 feature, sizeof(*feature));
233 if (ret < 0) {
192 wl12xx_error("Couldnt set HW encryption"); 234 wl12xx_error("Couldnt set HW encryption");
235 goto out;
236 }
193 237
238out:
239 kfree(feature);
194 return ret; 240 return ret;
195} 241}
196 242
197int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len) 243int wl12xx_acx_mem_map(struct wl12xx *wl, struct acx_header *mem_map,
244 size_t len)
198{ 245{
199 struct wl12xx_command cmd;
200 int ret; 246 int ret;
201 247
202 wl12xx_debug(DEBUG_ACX, "acx mem map"); 248 wl12xx_debug(DEBUG_ACX, "acx mem map");
203 249
204 ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd); 250 ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
205 if (ret < 0) 251 if (ret < 0)
206 return ret; 252 return ret;
207 else if (cmd.status != CMD_STATUS_SUCCESS)
208 return -EIO;
209
210 memcpy(mem_map, &cmd.parameters, len);
211 253
212 return 0; 254 return 0;
213} 255}
214 256
215int wl12xx_acx_data_path_params(struct wl12xx *wl, 257int wl12xx_acx_data_path_params(struct wl12xx *wl,
216 struct acx_data_path_params_resp *data_path) 258 struct acx_data_path_params_resp *resp)
217{ 259{
218 struct acx_data_path_params params; 260 struct acx_data_path_params *params;
219 struct wl12xx_command cmd;
220 int ret; 261 int ret;
221 262
222 wl12xx_debug(DEBUG_ACX, "acx data path params"); 263 wl12xx_debug(DEBUG_ACX, "acx data path params");
223 264
224 params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; 265 params = kzalloc(sizeof(*params), GFP_KERNEL);
225 params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; 266 if (!params) {
267 ret = -ENOMEM;
268 goto out;
269 }
226 270
227 params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM; 271 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
228 params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM; 272 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
229 273
230 params.tx_complete_threshold = 1; 274 params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
275 params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
231 276
232 params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE; 277 params->tx_complete_threshold = 1;
233 278
234 params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT; 279 params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
235 280
236 params.header.id = ACX_DATA_PATH_PARAMS; 281 params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
237 params.header.len = sizeof(params) - sizeof(struct acx_header);
238 282
239 ret = wl12xx_cmd_configure(wl, &params, sizeof(params)); 283 ret = wl12xx_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
284 params, sizeof(*params));
240 if (ret < 0) 285 if (ret < 0)
241 return ret; 286 goto out;
242
243 287
288 /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
244 ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS, 289 ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
245 sizeof(struct acx_data_path_params_resp), 290 resp, sizeof(*resp));
246 &cmd);
247 291
248 if (ret < 0) { 292 if (ret < 0) {
249 wl12xx_warning("failed to read data path parameters: %d", ret); 293 wl12xx_warning("failed to read data path parameters: %d", ret);
250 return ret; 294 goto out;
251 } else if (cmd.status != CMD_STATUS_SUCCESS) { 295 } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
252 wl12xx_warning("data path parameter acx status failed"); 296 wl12xx_warning("data path parameter acx status failed");
253 return -EIO; 297 ret = -EIO;
298 goto out;
254 } 299 }
255 300
256 memcpy(data_path, &cmd.parameters, sizeof(*data_path)); 301out:
257 302 kfree(params);
258 return 0; 303 return ret;
259} 304}
260 305
261int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time) 306int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
262{ 307{
263 struct rx_msdu_lifetime msdu_lifetime; 308 struct acx_rx_msdu_lifetime *acx;
264 int ret; 309 int ret;
265 310
266 wl12xx_debug(DEBUG_ACX, "acx rx msdu life time"); 311 wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
267 312
268 msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME; 313 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
269 msdu_lifetime.header.len = sizeof(msdu_lifetime) - 314 if (!acx) {
270 sizeof(struct acx_header); 315 ret = -ENOMEM;
271 msdu_lifetime.lifetime = life_time; 316 goto out;
317 }
272 318
273 ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime)); 319 ret = wl12xx_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
320 acx, sizeof(*acx));
274 if (ret < 0) { 321 if (ret < 0) {
275 wl12xx_warning("failed to set rx msdu life time: %d", ret); 322 wl12xx_warning("failed to set rx msdu life time: %d", ret);
276 return ret; 323 goto out;
277 } 324 }
278 325
279 return 0; 326out:
327 kfree(acx);
328 return ret;
280} 329}
281 330
282int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter) 331int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
283{ 332{
284 struct acx_rx_config rx_config; 333 struct acx_rx_config *rx_config;
285 int ret; 334 int ret;
286 335
287 wl12xx_debug(DEBUG_ACX, "acx rx config"); 336 wl12xx_debug(DEBUG_ACX, "acx rx config");
288 337
289 rx_config.header.id = ACX_RX_CFG; 338 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
290 rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header); 339 if (!rx_config) {
291 rx_config.config_options = config; 340 ret = -ENOMEM;
292 rx_config.filter_options = filter; 341 goto out;
342 }
343
344 rx_config->config_options = config;
345 rx_config->filter_options = filter;
293 346
294 ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config)); 347 ret = wl12xx_cmd_configure(wl, ACX_RX_CFG,
348 rx_config, sizeof(*rx_config));
295 if (ret < 0) { 349 if (ret < 0) {
296 wl12xx_warning("failed to set rx config: %d", ret); 350 wl12xx_warning("failed to set rx config: %d", ret);
297 return ret; 351 goto out;
298 } 352 }
299 353
300 return 0; 354out:
355 kfree(rx_config);
356 return ret;
301} 357}
302 358
303int wl12xx_acx_pd_threshold(struct wl12xx *wl) 359int wl12xx_acx_pd_threshold(struct wl12xx *wl)
304{ 360{
305 struct acx_packet_detection packet_detection; 361 struct acx_packet_detection *pd;
306 int ret; 362 int ret;
307 363
308 wl12xx_debug(DEBUG_ACX, "acx data pd threshold"); 364 wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
309 365
366 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
367 if (!pd) {
368 ret = -ENOMEM;
369 goto out;
370 }
371
310 /* FIXME: threshold value not set */ 372 /* FIXME: threshold value not set */
311 packet_detection.header.id = ACX_PD_THRESHOLD;
312 packet_detection.header.len = sizeof(packet_detection) -
313 sizeof(struct acx_header);
314 373
315 ret = wl12xx_cmd_configure(wl, &packet_detection, 374 ret = wl12xx_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
316 sizeof(packet_detection));
317 if (ret < 0) { 375 if (ret < 0) {
318 wl12xx_warning("failed to set pd threshold: %d", ret); 376 wl12xx_warning("failed to set pd threshold: %d", ret);
319 return ret; 377 goto out;
320 } 378 }
321 379
380out:
381 kfree(pd);
322 return 0; 382 return 0;
323} 383}
324 384
325int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time) 385int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
326{ 386{
327 struct acx_slot slot; 387 struct acx_slot *slot;
328 int ret; 388 int ret;
329 389
330 wl12xx_debug(DEBUG_ACX, "acx slot"); 390 wl12xx_debug(DEBUG_ACX, "acx slot");
331 391
332 slot.header.id = ACX_SLOT; 392 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
333 slot.header.len = sizeof(slot) - sizeof(struct acx_header); 393 if (!slot) {
394 ret = -ENOMEM;
395 goto out;
396 }
334 397
335 slot.wone_index = STATION_WONE_INDEX; 398 slot->wone_index = STATION_WONE_INDEX;
336 slot.slot_time = slot_time; 399 slot->slot_time = slot_time;
337 400
338 ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot)); 401 ret = wl12xx_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
339 if (ret < 0) { 402 if (ret < 0) {
340 wl12xx_warning("failed to set slot time: %d", ret); 403 wl12xx_warning("failed to set slot time: %d", ret);
341 return ret; 404 goto out;
342 } 405 }
343 406
344 return 0; 407out:
408 kfree(slot);
409 return ret;
345} 410}
346 411
347int wl12xx_acx_group_address_tbl(struct wl12xx *wl) 412int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
348{ 413{
349 struct multicast_grp_addr_start multicast; 414 struct acx_dot11_grp_addr_tbl *acx;
350 int ret; 415 int ret;
351 416
352 wl12xx_debug(DEBUG_ACX, "acx group address tbl"); 417 wl12xx_debug(DEBUG_ACX, "acx group address tbl");
353 418
354 /* MAC filtering */ 419 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
355 multicast.header.id = DOT11_GROUP_ADDRESS_TBL; 420 if (!acx) {
356 multicast.header.len = sizeof(multicast) - sizeof(struct acx_header); 421 ret = -ENOMEM;
422 goto out;
423 }
357 424
358 multicast.enabled = 0; 425 /* MAC filtering */
359 multicast.num_groups = 0; 426 acx->enabled = 0;
360 memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN); 427 acx->num_groups = 0;
428 memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
361 429
362 ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast)); 430 ret = wl12xx_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
431 acx, sizeof(*acx));
363 if (ret < 0) { 432 if (ret < 0) {
364 wl12xx_warning("failed to set group addr table: %d", ret); 433 wl12xx_warning("failed to set group addr table: %d", ret);
365 return ret; 434 goto out;
366 } 435 }
367 436
368 return 0; 437out:
438 kfree(acx);
439 return ret;
369} 440}
370 441
371int wl12xx_acx_service_period_timeout(struct wl12xx *wl) 442int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
372{ 443{
373 struct acx_rx_timeout rx_timeout; 444 struct acx_rx_timeout *rx_timeout;
374 int ret; 445 int ret;
375 446
376 wl12xx_debug(DEBUG_ACX, "acx service period timeout"); 447 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
448 if (!rx_timeout) {
449 ret = -ENOMEM;
450 goto out;
451 }
377 452
378 /* RX timeout */ 453 wl12xx_debug(DEBUG_ACX, "acx service period timeout");
379 rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
380 rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
381 454
382 rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF; 455 rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
383 rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF; 456 rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
384 457
385 ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout)); 458 ret = wl12xx_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
459 rx_timeout, sizeof(*rx_timeout));
386 if (ret < 0) { 460 if (ret < 0) {
387 wl12xx_warning("failed to set service period timeout: %d", 461 wl12xx_warning("failed to set service period timeout: %d",
388 ret); 462 ret);
389 return ret; 463 goto out;
390 } 464 }
391 465
392 return 0; 466out:
467 kfree(rx_timeout);
468 return ret;
393} 469}
394 470
395int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold) 471int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
396{ 472{
397 struct acx_rts_threshold rts; 473 struct acx_rts_threshold *rts;
398 int ret; 474 int ret;
399 475
400 wl12xx_debug(DEBUG_ACX, "acx rts threshold"); 476 wl12xx_debug(DEBUG_ACX, "acx rts threshold");
401 477
402 rts.header.id = DOT11_RTS_THRESHOLD; 478 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
403 rts.header.len = sizeof(rts) - sizeof(struct acx_header); 479 if (!rts) {
480 ret = -ENOMEM;
481 goto out;
482 }
404 483
405 rts.threshold = rts_threshold; 484 rts->threshold = rts_threshold;
406 485
407 ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts)); 486 ret = wl12xx_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
408 if (ret < 0) { 487 if (ret < 0) {
409 wl12xx_warning("failed to set rts threshold: %d", ret); 488 wl12xx_warning("failed to set rts threshold: %d", ret);
410 return ret; 489 goto out;
411 } 490 }
412 491
413 return 0; 492out:
493 kfree(rts);
494 return ret;
414} 495}
415 496
416int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl) 497int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
417{ 498{
418 struct acx_beacon_filter_option beacon_filter; 499 struct acx_beacon_filter_option *beacon_filter;
419 int ret; 500 int ret;
420 501
421 wl12xx_debug(DEBUG_ACX, "acx beacon filter opt"); 502 wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
422 503
423 beacon_filter.header.id = ACX_BEACON_FILTER_OPT; 504 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
424 beacon_filter.header.len = sizeof(beacon_filter) - 505 if (!beacon_filter) {
425 sizeof(struct acx_header); 506 ret = -ENOMEM;
507 goto out;
508 }
426 509
427 beacon_filter.enable = 0; 510 beacon_filter->enable = 0;
428 beacon_filter.max_num_beacons = 0; 511 beacon_filter->max_num_beacons = 0;
429 512
430 ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter)); 513 ret = wl12xx_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
514 beacon_filter, sizeof(*beacon_filter));
431 if (ret < 0) { 515 if (ret < 0) {
432 wl12xx_warning("failed to set beacon filter opt: %d", ret); 516 wl12xx_warning("failed to set beacon filter opt: %d", ret);
433 return ret; 517 goto out;
434 } 518 }
435 519
436 return 0; 520out:
521 kfree(beacon_filter);
522 return ret;
437} 523}
438 524
439int wl12xx_acx_beacon_filter_table(struct wl12xx *wl) 525int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
440{ 526{
441 struct acx_beacon_filter_ie_table ie_table; 527 struct acx_beacon_filter_ie_table *ie_table;
442 int ret; 528 int ret;
443 529
444 wl12xx_debug(DEBUG_ACX, "acx beacon filter table"); 530 wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
445 531
446 ie_table.header.id = ACX_BEACON_FILTER_TABLE; 532 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
447 ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header); 533 if (!ie_table) {
534 ret = -ENOMEM;
535 goto out;
536 }
448 537
449 ie_table.num_ie = 0; 538 ie_table->num_ie = 0;
450 memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE); 539 memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
451 540
452 ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table)); 541 ret = wl12xx_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
542 ie_table, sizeof(*ie_table));
453 if (ret < 0) { 543 if (ret < 0) {
454 wl12xx_warning("failed to set beacon filter table: %d", ret); 544 wl12xx_warning("failed to set beacon filter table: %d", ret);
455 return ret; 545 goto out;
456 } 546 }
457 547
458 return 0; 548out:
549 kfree(ie_table);
550 return ret;
459} 551}
460 552
461int wl12xx_acx_sg_enable(struct wl12xx *wl) 553int wl12xx_acx_sg_enable(struct wl12xx *wl)
462{ 554{
463 struct acx_bt_wlan_coex pta; 555 struct acx_bt_wlan_coex *pta;
464 int ret; 556 int ret;
465 557
466 wl12xx_debug(DEBUG_ACX, "acx sg enable"); 558 wl12xx_debug(DEBUG_ACX, "acx sg enable");
467 559
468 pta.header.id = ACX_SG_ENABLE; 560 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
469 pta.header.len = sizeof(pta) - sizeof(struct acx_header); 561 if (!pta) {
562 ret = -ENOMEM;
563 goto out;
564 }
470 565
471 pta.enable = SG_ENABLE; 566 pta->enable = SG_ENABLE;
472 567
473 ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta)); 568 ret = wl12xx_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
474 if (ret < 0) { 569 if (ret < 0) {
475 wl12xx_warning("failed to set softgemini enable: %d", ret); 570 wl12xx_warning("failed to set softgemini enable: %d", ret);
476 return ret; 571 goto out;
477 } 572 }
478 573
479 return 0; 574out:
575 kfree(pta);
576 return ret;
480} 577}
481 578
482int wl12xx_acx_sg_cfg(struct wl12xx *wl) 579int wl12xx_acx_sg_cfg(struct wl12xx *wl)
483{ 580{
484 struct acx_bt_wlan_coex_param param; 581 struct acx_bt_wlan_coex_param *param;
485 int ret; 582 int ret;
486 583
487 wl12xx_debug(DEBUG_ACX, "acx sg cfg"); 584 wl12xx_debug(DEBUG_ACX, "acx sg cfg");
488 585
586 param = kzalloc(sizeof(*param), GFP_KERNEL);
587 if (!param) {
588 ret = -ENOMEM;
589 goto out;
590 }
591
489 /* BT-WLAN coext parameters */ 592 /* BT-WLAN coext parameters */
490 param.header.id = ACX_SG_CFG; 593 param->min_rate = RATE_INDEX_24MBPS;
491 param.header.len = sizeof(param) - sizeof(struct acx_header); 594 param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
492 595 param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
493 param.min_rate = RATE_INDEX_24MBPS; 596 param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
494 param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF; 597 param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
495 param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF; 598 param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
496 param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF; 599 param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
497 param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF; 600 param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
498 param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF; 601 param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
499 param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF; 602 param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
500 param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF; 603 param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
501 param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF; 604 param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
502 param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF; 605 param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
503 param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF; 606 param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
504 param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF; 607 param->antenna_type = PTA_ANTENNA_TYPE_DEF;
505 param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF; 608 param->signal_type = PTA_SIGNALING_TYPE_DEF;
506 param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF; 609 param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
507 param.antenna_type = PTA_ANTENNA_TYPE_DEF; 610 param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
508 param.signal_type = PTA_SIGNALING_TYPE_DEF; 611 param->max_cts = PTA_MAX_NUM_CTS_DEF;
509 param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF; 612 param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
510 param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF; 613 param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
511 param.max_cts = PTA_MAX_NUM_CTS_DEF; 614 param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
512 param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF; 615 param->wlan_elp_hp = PTA_ELP_HP_DEF;
513 param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF; 616 param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
514 param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF; 617 param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
515 param.wlan_elp_hp = PTA_ELP_HP_DEF; 618 param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
516 param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF; 619 param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
517 param.ack_mode_dual_ant = PTA_ACK_MODE_DEF; 620 param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
518 param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF; 621
519 param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF; 622 ret = wl12xx_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
520 param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
521
522 ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
523 if (ret < 0) { 623 if (ret < 0) {
524 wl12xx_warning("failed to set sg config: %d", ret); 624 wl12xx_warning("failed to set sg config: %d", ret);
525 return ret; 625 goto out;
526 } 626 }
527 627
528 return 0; 628out:
629 kfree(param);
630 return ret;
529} 631}
530 632
531int wl12xx_acx_cca_threshold(struct wl12xx *wl) 633int wl12xx_acx_cca_threshold(struct wl12xx *wl)
532{ 634{
533 struct acx_energy_detection detection; 635 struct acx_energy_detection *detection;
534 int ret; 636 int ret;
535 637
536 wl12xx_debug(DEBUG_ACX, "acx cca threshold"); 638 wl12xx_debug(DEBUG_ACX, "acx cca threshold");
537 639
538 detection.header.id = ACX_CCA_THRESHOLD; 640 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
539 detection.header.len = sizeof(detection) - sizeof(struct acx_header); 641 if (!detection) {
642 ret = -ENOMEM;
643 goto out;
644 }
540 645
541 detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; 646 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
542 detection.tx_energy_detection = 0; 647 detection->tx_energy_detection = 0;
543 648
544 ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection)); 649 ret = wl12xx_cmd_configure(wl, ACX_CCA_THRESHOLD,
650 detection, sizeof(*detection));
545 if (ret < 0) { 651 if (ret < 0) {
546 wl12xx_warning("failed to set cca threshold: %d", ret); 652 wl12xx_warning("failed to set cca threshold: %d", ret);
547 return ret; 653 return ret;
548 } 654 }
549 655
550 return 0; 656out:
657 kfree(detection);
658 return ret;
551} 659}
552 660
553int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl) 661int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
554{ 662{
555 struct acx_beacon_broadcast bb; 663 struct acx_beacon_broadcast *bb;
556 int ret; 664 int ret;
557 665
558 wl12xx_debug(DEBUG_ACX, "acx bcn dtim options"); 666 wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
559 667
560 bb.header.id = ACX_BCN_DTIM_OPTIONS; 668 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
561 bb.header.len = sizeof(bb) - sizeof(struct acx_header); 669 if (!bb) {
670 ret = -ENOMEM;
671 goto out;
672 }
562 673
563 bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; 674 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
564 bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; 675 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
565 bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE; 676 bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
566 bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF; 677 bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
567 678
568 ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb)); 679 ret = wl12xx_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
569 if (ret < 0) { 680 if (ret < 0) {
570 wl12xx_warning("failed to set rx config: %d", ret); 681 wl12xx_warning("failed to set rx config: %d", ret);
571 return ret; 682 goto out;
572 } 683 }
573 684
574 return 0; 685out:
686 kfree(bb);
687 return ret;
575} 688}
576 689
577int wl12xx_acx_aid(struct wl12xx *wl, u16 aid) 690int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
578{ 691{
579 struct acx_aid acx_aid; 692 struct acx_aid *acx_aid;
580 int ret; 693 int ret;
581 694
582 wl12xx_debug(DEBUG_ACX, "acx aid"); 695 wl12xx_debug(DEBUG_ACX, "acx aid");
583 696
584 acx_aid.header.id = ACX_AID; 697 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
585 acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header); 698 if (!acx_aid) {
699 ret = -ENOMEM;
700 goto out;
701 }
586 702
587 acx_aid.aid = aid; 703 acx_aid->aid = aid;
588 704
589 ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid)); 705 ret = wl12xx_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
590 if (ret < 0) { 706 if (ret < 0) {
591 wl12xx_warning("failed to set aid: %d", ret); 707 wl12xx_warning("failed to set aid: %d", ret);
592 return ret; 708 goto out;
593 } 709 }
594 710
595 return 0; 711out:
712 kfree(acx_aid);
713 return ret;
596} 714}
597 715
598int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask) 716int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
599{ 717{
600 struct acx_event_mask mask; 718 struct acx_event_mask *mask;
601 int ret; 719 int ret;
602 720
603 wl12xx_debug(DEBUG_ACX, "acx event mbox mask"); 721 wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
604 722
605 mask.header.id = ACX_EVENT_MBOX_MASK; 723 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
606 mask.header.len = sizeof(mask) - sizeof(struct acx_header); 724 if (!mask) {
725 ret = -ENOMEM;
726 goto out;
727 }
607 728
608 /* high event mask is unused */ 729 /* high event mask is unused */
609 mask.high_event_mask = 0xffffffff; 730 mask->high_event_mask = 0xffffffff;
610 731
611 mask.event_mask = event_mask; 732 mask->event_mask = event_mask;
612 733
613 ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask)); 734 ret = wl12xx_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
735 mask, sizeof(*mask));
614 if (ret < 0) { 736 if (ret < 0) {
615 wl12xx_warning("failed to set aid: %d", ret); 737 wl12xx_warning("failed to set aid: %d", ret);
616 return ret; 738 goto out;
617 } 739 }
618 740
619 return 0; 741out:
742 kfree(mask);
743 return ret;
620} 744}
621 745
622int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble) 746int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
623{ 747{
624 struct acx_preamble ie; 748 struct acx_preamble *acx;
625 int ret; 749 int ret;
626 750
627 wl12xx_debug(DEBUG_ACX, "acx_set_preamble"); 751 wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
628 752
629 memset(&ie, 0, sizeof(ie)); 753 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
754 if (!acx) {
755 ret = -ENOMEM;
756 goto out;
757 }
630 758
631 ie.header.id = ACX_PREAMBLE_TYPE; 759 acx->preamble = preamble;
632 ie.header.len = sizeof(ie) - sizeof(struct acx_header); 760
633 ie.preamble = preamble; 761 ret = wl12xx_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
634 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
635 if (ret < 0) { 762 if (ret < 0) {
636 wl12xx_warning("Setting of preamble failed: %d", ret); 763 wl12xx_warning("Setting of preamble failed: %d", ret);
637 return ret; 764 goto out;
638 } 765 }
639 return 0; 766
767out:
768 kfree(acx);
769 return ret;
640} 770}
641 771
642int wl12xx_acx_cts_protect(struct wl12xx *wl, 772int wl12xx_acx_cts_protect(struct wl12xx *wl,
643 enum acx_ctsprotect_type ctsprotect) 773 enum acx_ctsprotect_type ctsprotect)
644{ 774{
645 struct acx_ctsprotect ie; 775 struct acx_ctsprotect *acx;
646 int ret; 776 int ret;
647 777
648 wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect"); 778 wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
649 779
650 memset(&ie, 0, sizeof(ie)); 780 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
781 if (!acx) {
782 ret = -ENOMEM;
783 goto out;
784 }
785
786 acx->ctsprotect = ctsprotect;
651 787
652 ie.header.id = ACX_CTS_PROTECTION; 788 ret = wl12xx_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
653 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
654 ie.ctsprotect = ctsprotect;
655 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
656 if (ret < 0) { 789 if (ret < 0) {
657 wl12xx_warning("Setting of ctsprotect failed: %d", ret); 790 wl12xx_warning("Setting of ctsprotect failed: %d", ret);
658 return ret; 791 goto out;
659 } 792 }
660 return 0; 793
794out:
795 kfree(acx);
796 return ret;
661} 797}
662 798
663int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats) 799int wl12xx_acx_tsf_info(struct wl12xx *wl, u64 *mactime)
664{ 800{
665 struct wl12xx_command *answer; 801 struct acx_tsf_info *tsf_info;
666 int ret; 802 int ret;
667 803
668 wl12xx_debug(DEBUG_ACX, "acx statistics"); 804 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
669 805 if (!tsf_info) {
670 answer = kmalloc(sizeof(*answer), GFP_KERNEL);
671 if (!answer) {
672 wl12xx_warning("could not allocate memory for acx statistics");
673 ret = -ENOMEM; 806 ret = -ENOMEM;
674 goto out; 807 goto out;
675 } 808 }
676 809
677 ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer), 810 ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
678 answer); 811 tsf_info, sizeof(*tsf_info));
679 if (ret < 0) { 812 if (ret < 0) {
680 wl12xx_warning("acx statistics failed: %d", ret); 813 wl12xx_warning("ACX_FW_REV interrogate failed");
681 goto out; 814 goto out;
682 } 815 }
683 816
684 memcpy(stats, answer->parameters, sizeof(*stats)); 817 *mactime = tsf_info->current_tsf_lsb |
818 (tsf_info->current_tsf_msb << 31);
685 819
686out: 820out:
687 kfree(answer); 821 kfree(tsf_info);
688 return ret; 822 return ret;
689} 823}
824
825int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
826{
827 int ret;
828
829 wl12xx_debug(DEBUG_ACX, "acx statistics");
830
831 ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, stats,
832 sizeof(*stats));
833 if (ret < 0) {
834 wl12xx_warning("acx statistics failed: %d", ret);
835 return -ENOMEM;
836 }
837
838 return 0;
839}