aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl/bmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/bmi.c')
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c245
1 files changed, 50 insertions, 195 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index a962fe4c6b7e..aef00d5a1438 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -19,165 +19,6 @@
19#include "target.h" 19#include "target.h"
20#include "debug.h" 20#include "debug.h"
21 21
22static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
23{
24 u32 addr;
25 unsigned long timeout;
26 int ret;
27
28 ar->bmi.cmd_credits = 0;
29
30 /* Read the counter register to get the command credits */
31 addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
32
33 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
34 while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
35
36 /*
37 * Hit the credit counter with a 4-byte access, the first byte
38 * read will hit the counter and cause a decrement, while the
39 * remaining 3 bytes has no effect. The rationale behind this
40 * is to make all HIF accesses 4-byte aligned.
41 */
42 ret = hif_read_write_sync(ar, addr,
43 (u8 *)&ar->bmi.cmd_credits, 4,
44 HIF_RD_SYNC_BYTE_INC);
45 if (ret) {
46 ath6kl_err("Unable to decrement the command credit count register: %d\n",
47 ret);
48 return ret;
49 }
50
51 /* The counter is only 8 bits.
52 * Ignore anything in the upper 3 bytes
53 */
54 ar->bmi.cmd_credits &= 0xFF;
55 }
56
57 if (!ar->bmi.cmd_credits) {
58 ath6kl_err("bmi communication timeout\n");
59 return -ETIMEDOUT;
60 }
61
62 return 0;
63}
64
65static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
66{
67 unsigned long timeout;
68 u32 rx_word = 0;
69 int ret = 0;
70
71 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
72 while (time_before(jiffies, timeout) && !rx_word) {
73 ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
74 (u8 *)&rx_word, sizeof(rx_word),
75 HIF_RD_SYNC_BYTE_INC);
76 if (ret) {
77 ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
78 return ret;
79 }
80
81 /* all we really want is one bit */
82 rx_word &= (1 << ENDPOINT1);
83 }
84
85 if (!rx_word) {
86 ath6kl_err("bmi_recv_buf FIFO empty\n");
87 return -EINVAL;
88 }
89
90 return ret;
91}
92
93static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
94{
95 int ret;
96 u32 addr;
97
98 ret = ath6kl_get_bmi_cmd_credits(ar);
99 if (ret)
100 return ret;
101
102 addr = ar->mbox_info.htc_addr;
103
104 ret = hif_read_write_sync(ar, addr, buf, len,
105 HIF_WR_SYNC_BYTE_INC);
106 if (ret)
107 ath6kl_err("unable to send the bmi data to the device\n");
108
109 return ret;
110}
111
112static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
113{
114 int ret;
115 u32 addr;
116
117 /*
118 * During normal bootup, small reads may be required.
119 * Rather than issue an HIF Read and then wait as the Target
120 * adds successive bytes to the FIFO, we wait here until
121 * we know that response data is available.
122 *
123 * This allows us to cleanly timeout on an unexpected
124 * Target failure rather than risk problems at the HIF level.
125 * In particular, this avoids SDIO timeouts and possibly garbage
126 * data on some host controllers. And on an interconnect
127 * such as Compact Flash (as well as some SDIO masters) which
128 * does not provide any indication on data timeout, it avoids
129 * a potential hang or garbage response.
130 *
131 * Synchronization is more difficult for reads larger than the
132 * size of the MBOX FIFO (128B), because the Target is unable
133 * to push the 129th byte of data until AFTER the Host posts an
134 * HIF Read and removes some FIFO data. So for large reads the
135 * Host proceeds to post an HIF Read BEFORE all the data is
136 * actually available to read. Fortunately, large BMI reads do
137 * not occur in practice -- they're supported for debug/development.
138 *
139 * So Host/Target BMI synchronization is divided into these cases:
140 * CASE 1: length < 4
141 * Should not happen
142 *
143 * CASE 2: 4 <= length <= 128
144 * Wait for first 4 bytes to be in FIFO
145 * If CONSERVATIVE_BMI_READ is enabled, also wait for
146 * a BMI command credit, which indicates that the ENTIRE
147 * response is available in the the FIFO
148 *
149 * CASE 3: length > 128
150 * Wait for the first 4 bytes to be in FIFO
151 *
152 * For most uses, a small timeout should be sufficient and we will
153 * usually see a response quickly; but there may be some unusual
154 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
155 * For now, we use an unbounded busy loop while waiting for
156 * BMI_EXECUTE.
157 *
158 * If BMI_EXECUTE ever needs to support longer-latency execution,
159 * especially in production, this code needs to be enhanced to sleep
160 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
161 * a function of Host processor speed.
162 */
163 if (len >= 4) { /* NB: Currently, always true */
164 ret = ath6kl_bmi_get_rx_lkahd(ar);
165 if (ret)
166 return ret;
167 }
168
169 addr = ar->mbox_info.htc_addr;
170 ret = hif_read_write_sync(ar, addr, buf, len,
171 HIF_RD_SYNC_BYTE_INC);
172 if (ret) {
173 ath6kl_err("Unable to read the bmi data from the device: %d\n",
174 ret);
175 return ret;
176 }
177
178 return 0;
179}
180
181int ath6kl_bmi_done(struct ath6kl *ar) 22int ath6kl_bmi_done(struct ath6kl *ar)
182{ 23{
183 int ret; 24 int ret;
@@ -190,7 +31,7 @@ int ath6kl_bmi_done(struct ath6kl *ar)
190 31
191 ar->bmi.done_sent = true; 32 ar->bmi.done_sent = true;
192 33
193 ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid)); 34 ret = ath6kl_hif_bmi_write(ar, (u8 *)&cid, sizeof(cid));
194 if (ret) { 35 if (ret) {
195 ath6kl_err("Unable to send bmi done: %d\n", ret); 36 ath6kl_err("Unable to send bmi done: %d\n", ret);
196 return ret; 37 return ret;
@@ -210,14 +51,20 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
210 return -EACCES; 51 return -EACCES;
211 } 52 }
212 53
213 ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid)); 54 ret = ath6kl_hif_bmi_write(ar, (u8 *)&cid, sizeof(cid));
214 if (ret) { 55 if (ret) {
215 ath6kl_err("Unable to send get target info: %d\n", ret); 56 ath6kl_err("Unable to send get target info: %d\n", ret);
216 return ret; 57 return ret;
217 } 58 }
218 59
219 ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version, 60 if (ar->hif_type == ATH6KL_HIF_TYPE_USB) {
220 sizeof(targ_info->version)); 61 ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info,
62 sizeof(*targ_info));
63 } else {
64 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
65 sizeof(targ_info->version));
66 }
67
221 if (ret) { 68 if (ret) {
222 ath6kl_err("Unable to recv target info: %d\n", ret); 69 ath6kl_err("Unable to recv target info: %d\n", ret);
223 return ret; 70 return ret;
@@ -225,7 +72,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
225 72
226 if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) { 73 if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) {
227 /* Determine how many bytes are in the Target's targ_info */ 74 /* Determine how many bytes are in the Target's targ_info */
228 ret = ath6kl_bmi_recv_buf(ar, 75 ret = ath6kl_hif_bmi_read(ar,
229 (u8 *)&targ_info->byte_count, 76 (u8 *)&targ_info->byte_count,
230 sizeof(targ_info->byte_count)); 77 sizeof(targ_info->byte_count));
231 if (ret) { 78 if (ret) {
@@ -244,7 +91,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
244 } 91 }
245 92
246 /* Read the remainder of the targ_info */ 93 /* Read the remainder of the targ_info */
247 ret = ath6kl_bmi_recv_buf(ar, 94 ret = ath6kl_hif_bmi_read(ar,
248 ((u8 *)targ_info) + 95 ((u8 *)targ_info) +
249 sizeof(targ_info->byte_count), 96 sizeof(targ_info->byte_count),
250 sizeof(*targ_info) - 97 sizeof(*targ_info) -
@@ -276,8 +123,8 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
276 return -EACCES; 123 return -EACCES;
277 } 124 }
278 125
279 size = BMI_DATASZ_MAX + sizeof(cid) + sizeof(addr) + sizeof(len); 126 size = ar->bmi.max_data_size + sizeof(cid) + sizeof(addr) + sizeof(len);
280 if (size > MAX_BMI_CMDBUF_SZ) { 127 if (size > ar->bmi.max_cmd_size) {
281 WARN_ON(1); 128 WARN_ON(1);
282 return -EINVAL; 129 return -EINVAL;
283 } 130 }
@@ -290,8 +137,8 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
290 len_remain = len; 137 len_remain = len;
291 138
292 while (len_remain) { 139 while (len_remain) {
293 rx_len = (len_remain < BMI_DATASZ_MAX) ? 140 rx_len = (len_remain < ar->bmi.max_data_size) ?
294 len_remain : BMI_DATASZ_MAX; 141 len_remain : ar->bmi.max_data_size;
295 offset = 0; 142 offset = 0;
296 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid)); 143 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
297 offset += sizeof(cid); 144 offset += sizeof(cid);
@@ -300,13 +147,13 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
300 memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len)); 147 memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len));
301 offset += sizeof(len); 148 offset += sizeof(len);
302 149
303 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 150 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
304 if (ret) { 151 if (ret) {
305 ath6kl_err("Unable to write to the device: %d\n", 152 ath6kl_err("Unable to write to the device: %d\n",
306 ret); 153 ret);
307 return ret; 154 return ret;
308 } 155 }
309 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len); 156 ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, rx_len);
310 if (ret) { 157 if (ret) {
311 ath6kl_err("Unable to read from the device: %d\n", 158 ath6kl_err("Unable to read from the device: %d\n",
312 ret); 159 ret);
@@ -326,7 +173,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
326 u32 offset; 173 u32 offset;
327 u32 len_remain, tx_len; 174 u32 len_remain, tx_len;
328 const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len); 175 const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len);
329 u8 aligned_buf[BMI_DATASZ_MAX]; 176 u8 aligned_buf[400];
330 u8 *src; 177 u8 *src;
331 178
332 if (ar->bmi.done_sent) { 179 if (ar->bmi.done_sent) {
@@ -334,12 +181,15 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
334 return -EACCES; 181 return -EACCES;
335 } 182 }
336 183
337 if ((BMI_DATASZ_MAX + header) > MAX_BMI_CMDBUF_SZ) { 184 if ((ar->bmi.max_data_size + header) > ar->bmi.max_cmd_size) {
338 WARN_ON(1); 185 WARN_ON(1);
339 return -EINVAL; 186 return -EINVAL;
340 } 187 }
341 188
342 memset(ar->bmi.cmd_buf, 0, BMI_DATASZ_MAX + header); 189 if (WARN_ON(ar->bmi.max_data_size > sizeof(aligned_buf)))
190 return -E2BIG;
191
192 memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header);
343 193
344 ath6kl_dbg(ATH6KL_DBG_BMI, 194 ath6kl_dbg(ATH6KL_DBG_BMI,
345 "bmi write memory: addr: 0x%x, len: %d\n", addr, len); 195 "bmi write memory: addr: 0x%x, len: %d\n", addr, len);
@@ -348,7 +198,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
348 while (len_remain) { 198 while (len_remain) {
349 src = &buf[len - len_remain]; 199 src = &buf[len - len_remain];
350 200
351 if (len_remain < (BMI_DATASZ_MAX - header)) { 201 if (len_remain < (ar->bmi.max_data_size - header)) {
352 if (len_remain & 3) { 202 if (len_remain & 3) {
353 /* align it with 4 bytes */ 203 /* align it with 4 bytes */
354 len_remain = len_remain + 204 len_remain = len_remain +
@@ -358,7 +208,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
358 } 208 }
359 tx_len = len_remain; 209 tx_len = len_remain;
360 } else { 210 } else {
361 tx_len = (BMI_DATASZ_MAX - header); 211 tx_len = (ar->bmi.max_data_size - header);
362 } 212 }
363 213
364 offset = 0; 214 offset = 0;
@@ -371,7 +221,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
371 memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len); 221 memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len);
372 offset += tx_len; 222 offset += tx_len;
373 223
374 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 224 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
375 if (ret) { 225 if (ret) {
376 ath6kl_err("Unable to write to the device: %d\n", 226 ath6kl_err("Unable to write to the device: %d\n",
377 ret); 227 ret);
@@ -396,7 +246,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
396 } 246 }
397 247
398 size = sizeof(cid) + sizeof(addr) + sizeof(param); 248 size = sizeof(cid) + sizeof(addr) + sizeof(param);
399 if (size > MAX_BMI_CMDBUF_SZ) { 249 if (size > ar->bmi.max_cmd_size) {
400 WARN_ON(1); 250 WARN_ON(1);
401 return -EINVAL; 251 return -EINVAL;
402 } 252 }
@@ -413,13 +263,13 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
413 memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param)); 263 memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param));
414 offset += sizeof(*param); 264 offset += sizeof(*param);
415 265
416 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 266 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
417 if (ret) { 267 if (ret) {
418 ath6kl_err("Unable to write to the device: %d\n", ret); 268 ath6kl_err("Unable to write to the device: %d\n", ret);
419 return ret; 269 return ret;
420 } 270 }
421 271
422 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param)); 272 ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param));
423 if (ret) { 273 if (ret) {
424 ath6kl_err("Unable to read from the device: %d\n", ret); 274 ath6kl_err("Unable to read from the device: %d\n", ret);
425 return ret; 275 return ret;
@@ -443,7 +293,7 @@ int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
443 } 293 }
444 294
445 size = sizeof(cid) + sizeof(addr); 295 size = sizeof(cid) + sizeof(addr);
446 if (size > MAX_BMI_CMDBUF_SZ) { 296 if (size > ar->bmi.max_cmd_size) {
447 WARN_ON(1); 297 WARN_ON(1);
448 return -EINVAL; 298 return -EINVAL;
449 } 299 }
@@ -457,7 +307,7 @@ int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
457 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); 307 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
458 offset += sizeof(addr); 308 offset += sizeof(addr);
459 309
460 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 310 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
461 if (ret) { 311 if (ret) {
462 ath6kl_err("Unable to write to the device: %d\n", ret); 312 ath6kl_err("Unable to write to the device: %d\n", ret);
463 return ret; 313 return ret;
@@ -479,7 +329,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
479 } 329 }
480 330
481 size = sizeof(cid) + sizeof(addr); 331 size = sizeof(cid) + sizeof(addr);
482 if (size > MAX_BMI_CMDBUF_SZ) { 332 if (size > ar->bmi.max_cmd_size) {
483 WARN_ON(1); 333 WARN_ON(1);
484 return -EINVAL; 334 return -EINVAL;
485 } 335 }
@@ -493,13 +343,13 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
493 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); 343 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
494 offset += sizeof(addr); 344 offset += sizeof(addr);
495 345
496 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 346 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
497 if (ret) { 347 if (ret) {
498 ath6kl_err("Unable to write to the device: %d\n", ret); 348 ath6kl_err("Unable to write to the device: %d\n", ret);
499 return ret; 349 return ret;
500 } 350 }
501 351
502 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param)); 352 ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param));
503 if (ret) { 353 if (ret) {
504 ath6kl_err("Unable to read from the device: %d\n", ret); 354 ath6kl_err("Unable to read from the device: %d\n", ret);
505 return ret; 355 return ret;
@@ -522,7 +372,7 @@ int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
522 } 372 }
523 373
524 size = sizeof(cid) + sizeof(addr) + sizeof(param); 374 size = sizeof(cid) + sizeof(addr) + sizeof(param);
525 if (size > MAX_BMI_CMDBUF_SZ) { 375 if (size > ar->bmi.max_cmd_size) {
526 WARN_ON(1); 376 WARN_ON(1);
527 return -EINVAL; 377 return -EINVAL;
528 } 378 }
@@ -540,7 +390,7 @@ int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
540 memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param)); 390 memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param));
541 offset += sizeof(param); 391 offset += sizeof(param);
542 392
543 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 393 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
544 if (ret) { 394 if (ret) {
545 ath6kl_err("Unable to write to the device: %d\n", ret); 395 ath6kl_err("Unable to write to the device: %d\n", ret);
546 return ret; 396 return ret;
@@ -563,8 +413,8 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
563 return -EACCES; 413 return -EACCES;
564 } 414 }
565 415
566 size = BMI_DATASZ_MAX + header; 416 size = ar->bmi.max_data_size + header;
567 if (size > MAX_BMI_CMDBUF_SZ) { 417 if (size > ar->bmi.max_cmd_size) {
568 WARN_ON(1); 418 WARN_ON(1);
569 return -EINVAL; 419 return -EINVAL;
570 } 420 }
@@ -575,8 +425,8 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
575 425
576 len_remain = len; 426 len_remain = len;
577 while (len_remain) { 427 while (len_remain) {
578 tx_len = (len_remain < (BMI_DATASZ_MAX - header)) ? 428 tx_len = (len_remain < (ar->bmi.max_data_size - header)) ?
579 len_remain : (BMI_DATASZ_MAX - header); 429 len_remain : (ar->bmi.max_data_size - header);
580 430
581 offset = 0; 431 offset = 0;
582 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid)); 432 memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
@@ -587,7 +437,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
587 tx_len); 437 tx_len);
588 offset += tx_len; 438 offset += tx_len;
589 439
590 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 440 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
591 if (ret) { 441 if (ret) {
592 ath6kl_err("Unable to write to the device: %d\n", 442 ath6kl_err("Unable to write to the device: %d\n",
593 ret); 443 ret);
@@ -613,7 +463,7 @@ int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
613 } 463 }
614 464
615 size = sizeof(cid) + sizeof(addr); 465 size = sizeof(cid) + sizeof(addr);
616 if (size > MAX_BMI_CMDBUF_SZ) { 466 if (size > ar->bmi.max_cmd_size) {
617 WARN_ON(1); 467 WARN_ON(1);
618 return -EINVAL; 468 return -EINVAL;
619 } 469 }
@@ -629,7 +479,7 @@ int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
629 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); 479 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
630 offset += sizeof(addr); 480 offset += sizeof(addr);
631 481
632 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 482 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
633 if (ret) { 483 if (ret) {
634 ath6kl_err("Unable to start LZ stream to the device: %d\n", 484 ath6kl_err("Unable to start LZ stream to the device: %d\n",
635 ret); 485 ret);
@@ -677,8 +527,13 @@ void ath6kl_bmi_reset(struct ath6kl *ar)
677 527
678int ath6kl_bmi_init(struct ath6kl *ar) 528int ath6kl_bmi_init(struct ath6kl *ar)
679{ 529{
680 ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC); 530 if (WARN_ON(ar->bmi.max_data_size == 0))
531 return -EINVAL;
532
533 /* cmd + addr + len + data_size */
534 ar->bmi.max_cmd_size = ar->bmi.max_data_size + (sizeof(u32) * 3);
681 535
536 ar->bmi.cmd_buf = kzalloc(ar->bmi.max_cmd_size, GFP_ATOMIC);
682 if (!ar->bmi.cmd_buf) 537 if (!ar->bmi.cmd_buf)
683 return -ENOMEM; 538 return -ENOMEM;
684 539