aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c191
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h10
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h2
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c162
4 files changed, 190 insertions, 175 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index a962fe4c6b7e..12f5b57d2dc2 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,13 +51,13 @@ 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 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
220 sizeof(targ_info->version)); 61 sizeof(targ_info->version));
221 if (ret) { 62 if (ret) {
222 ath6kl_err("Unable to recv target info: %d\n", ret); 63 ath6kl_err("Unable to recv target info: %d\n", ret);
@@ -225,7 +66,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
225 66
226 if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) { 67 if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) {
227 /* Determine how many bytes are in the Target's targ_info */ 68 /* Determine how many bytes are in the Target's targ_info */
228 ret = ath6kl_bmi_recv_buf(ar, 69 ret = ath6kl_hif_bmi_read(ar,
229 (u8 *)&targ_info->byte_count, 70 (u8 *)&targ_info->byte_count,
230 sizeof(targ_info->byte_count)); 71 sizeof(targ_info->byte_count));
231 if (ret) { 72 if (ret) {
@@ -244,7 +85,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
244 } 85 }
245 86
246 /* Read the remainder of the targ_info */ 87 /* Read the remainder of the targ_info */
247 ret = ath6kl_bmi_recv_buf(ar, 88 ret = ath6kl_hif_bmi_read(ar,
248 ((u8 *)targ_info) + 89 ((u8 *)targ_info) +
249 sizeof(targ_info->byte_count), 90 sizeof(targ_info->byte_count),
250 sizeof(*targ_info) - 91 sizeof(*targ_info) -
@@ -300,13 +141,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)); 141 memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len));
301 offset += sizeof(len); 142 offset += sizeof(len);
302 143
303 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 144 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
304 if (ret) { 145 if (ret) {
305 ath6kl_err("Unable to write to the device: %d\n", 146 ath6kl_err("Unable to write to the device: %d\n",
306 ret); 147 ret);
307 return ret; 148 return ret;
308 } 149 }
309 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len); 150 ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, rx_len);
310 if (ret) { 151 if (ret) {
311 ath6kl_err("Unable to read from the device: %d\n", 152 ath6kl_err("Unable to read from the device: %d\n",
312 ret); 153 ret);
@@ -371,7 +212,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
371 memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len); 212 memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len);
372 offset += tx_len; 213 offset += tx_len;
373 214
374 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 215 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
375 if (ret) { 216 if (ret) {
376 ath6kl_err("Unable to write to the device: %d\n", 217 ath6kl_err("Unable to write to the device: %d\n",
377 ret); 218 ret);
@@ -413,13 +254,13 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
413 memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param)); 254 memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param));
414 offset += sizeof(*param); 255 offset += sizeof(*param);
415 256
416 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 257 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
417 if (ret) { 258 if (ret) {
418 ath6kl_err("Unable to write to the device: %d\n", ret); 259 ath6kl_err("Unable to write to the device: %d\n", ret);
419 return ret; 260 return ret;
420 } 261 }
421 262
422 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param)); 263 ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param));
423 if (ret) { 264 if (ret) {
424 ath6kl_err("Unable to read from the device: %d\n", ret); 265 ath6kl_err("Unable to read from the device: %d\n", ret);
425 return ret; 266 return ret;
@@ -457,7 +298,7 @@ int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
457 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); 298 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
458 offset += sizeof(addr); 299 offset += sizeof(addr);
459 300
460 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 301 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
461 if (ret) { 302 if (ret) {
462 ath6kl_err("Unable to write to the device: %d\n", ret); 303 ath6kl_err("Unable to write to the device: %d\n", ret);
463 return ret; 304 return ret;
@@ -493,13 +334,13 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
493 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); 334 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
494 offset += sizeof(addr); 335 offset += sizeof(addr);
495 336
496 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 337 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
497 if (ret) { 338 if (ret) {
498 ath6kl_err("Unable to write to the device: %d\n", ret); 339 ath6kl_err("Unable to write to the device: %d\n", ret);
499 return ret; 340 return ret;
500 } 341 }
501 342
502 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param)); 343 ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param));
503 if (ret) { 344 if (ret) {
504 ath6kl_err("Unable to read from the device: %d\n", ret); 345 ath6kl_err("Unable to read from the device: %d\n", ret);
505 return ret; 346 return ret;
@@ -540,7 +381,7 @@ int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
540 memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param)); 381 memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param));
541 offset += sizeof(param); 382 offset += sizeof(param);
542 383
543 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 384 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
544 if (ret) { 385 if (ret) {
545 ath6kl_err("Unable to write to the device: %d\n", ret); 386 ath6kl_err("Unable to write to the device: %d\n", ret);
546 return ret; 387 return ret;
@@ -587,7 +428,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
587 tx_len); 428 tx_len);
588 offset += tx_len; 429 offset += tx_len;
589 430
590 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 431 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
591 if (ret) { 432 if (ret) {
592 ath6kl_err("Unable to write to the device: %d\n", 433 ath6kl_err("Unable to write to the device: %d\n",
593 ret); 434 ret);
@@ -629,7 +470,7 @@ int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
629 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); 470 memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
630 offset += sizeof(addr); 471 offset += sizeof(addr);
631 472
632 ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); 473 ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
633 if (ret) { 474 if (ret) {
634 ath6kl_err("Unable to start LZ stream to the device: %d\n", 475 ath6kl_err("Unable to start LZ stream to the device: %d\n",
635 ret); 476 ret);
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
index eed22870448b..0c4c602464b7 100644
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -91,6 +91,16 @@ static inline int ath6kl_hif_suspend(struct ath6kl *ar,
91 return ar->hif_ops->suspend(ar, wow); 91 return ar->hif_ops->suspend(ar, wow);
92} 92}
93 93
94static inline int ath6kl_hif_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
95{
96 return ar->hif_ops->bmi_read(ar, buf, len);
97}
98
99static inline int ath6kl_hif_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
100{
101 return ar->hif_ops->bmi_write(ar, buf, len);
102}
103
94static inline int ath6kl_hif_resume(struct ath6kl *ar) 104static inline int ath6kl_hif_resume(struct ath6kl *ar)
95{ 105{
96 ath6kl_dbg(ATH6KL_DBG_HIF, "hif resume\n"); 106 ath6kl_dbg(ATH6KL_DBG_HIF, "hif resume\n");
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index f2dc3bcdae4a..42004e9069b6 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -244,6 +244,8 @@ struct ath6kl_hif_ops {
244 void (*cleanup_scatter)(struct ath6kl *ar); 244 void (*cleanup_scatter)(struct ath6kl *ar);
245 int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow); 245 int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow);
246 int (*resume)(struct ath6kl *ar); 246 int (*resume)(struct ath6kl *ar);
247 int (*bmi_read)(struct ath6kl *ar, u8 *buf, u32 len);
248 int (*bmi_write)(struct ath6kl *ar, u8 *buf, u32 len);
247 int (*power_on)(struct ath6kl *ar); 249 int (*power_on)(struct ath6kl *ar);
248 int (*power_off)(struct ath6kl *ar); 250 int (*power_off)(struct ath6kl *ar);
249 void (*stop)(struct ath6kl *ar); 251 void (*stop)(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index beb5f9bf26af..080be036a27e 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -845,6 +845,166 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
845 return 0; 845 return 0;
846} 846}
847 847
848static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
849{
850 u32 addr;
851 unsigned long timeout;
852 int ret;
853
854 ar->bmi.cmd_credits = 0;
855
856 /* Read the counter register to get the command credits */
857 addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
858
859 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
860 while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
861
862 /*
863 * Hit the credit counter with a 4-byte access, the first byte
864 * read will hit the counter and cause a decrement, while the
865 * remaining 3 bytes has no effect. The rationale behind this
866 * is to make all HIF accesses 4-byte aligned.
867 */
868 ret = ath6kl_sdio_read_write_sync(ar, addr,
869 (u8 *)&ar->bmi.cmd_credits, 4,
870 HIF_RD_SYNC_BYTE_INC);
871 if (ret) {
872 ath6kl_err("Unable to decrement the command credit "
873 "count register: %d\n", ret);
874 return ret;
875 }
876
877 /* The counter is only 8 bits.
878 * Ignore anything in the upper 3 bytes
879 */
880 ar->bmi.cmd_credits &= 0xFF;
881 }
882
883 if (!ar->bmi.cmd_credits) {
884 ath6kl_err("bmi communication timeout\n");
885 return -ETIMEDOUT;
886 }
887
888 return 0;
889}
890
891static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
892{
893 unsigned long timeout;
894 u32 rx_word = 0;
895 int ret = 0;
896
897 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
898 while ((time_before(jiffies, timeout)) && !rx_word) {
899 ret = ath6kl_sdio_read_write_sync(ar,
900 RX_LOOKAHEAD_VALID_ADDRESS,
901 (u8 *)&rx_word, sizeof(rx_word),
902 HIF_RD_SYNC_BYTE_INC);
903 if (ret) {
904 ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
905 return ret;
906 }
907
908 /* all we really want is one bit */
909 rx_word &= (1 << ENDPOINT1);
910 }
911
912 if (!rx_word) {
913 ath6kl_err("bmi_recv_buf FIFO empty\n");
914 return -EINVAL;
915 }
916
917 return ret;
918}
919
920static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
921{
922 int ret;
923 u32 addr;
924
925 ret = ath6kl_sdio_bmi_credits(ar);
926 if (ret)
927 return ret;
928
929 addr = ar->mbox_info.htc_addr;
930
931 ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
932 HIF_WR_SYNC_BYTE_INC);
933 if (ret)
934 ath6kl_err("unable to send the bmi data to the device\n");
935
936 return ret;
937}
938
939static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
940{
941 int ret;
942 u32 addr;
943
944 /*
945 * During normal bootup, small reads may be required.
946 * Rather than issue an HIF Read and then wait as the Target
947 * adds successive bytes to the FIFO, we wait here until
948 * we know that response data is available.
949 *
950 * This allows us to cleanly timeout on an unexpected
951 * Target failure rather than risk problems at the HIF level.
952 * In particular, this avoids SDIO timeouts and possibly garbage
953 * data on some host controllers. And on an interconnect
954 * such as Compact Flash (as well as some SDIO masters) which
955 * does not provide any indication on data timeout, it avoids
956 * a potential hang or garbage response.
957 *
958 * Synchronization is more difficult for reads larger than the
959 * size of the MBOX FIFO (128B), because the Target is unable
960 * to push the 129th byte of data until AFTER the Host posts an
961 * HIF Read and removes some FIFO data. So for large reads the
962 * Host proceeds to post an HIF Read BEFORE all the data is
963 * actually available to read. Fortunately, large BMI reads do
964 * not occur in practice -- they're supported for debug/development.
965 *
966 * So Host/Target BMI synchronization is divided into these cases:
967 * CASE 1: length < 4
968 * Should not happen
969 *
970 * CASE 2: 4 <= length <= 128
971 * Wait for first 4 bytes to be in FIFO
972 * If CONSERVATIVE_BMI_READ is enabled, also wait for
973 * a BMI command credit, which indicates that the ENTIRE
974 * response is available in the the FIFO
975 *
976 * CASE 3: length > 128
977 * Wait for the first 4 bytes to be in FIFO
978 *
979 * For most uses, a small timeout should be sufficient and we will
980 * usually see a response quickly; but there may be some unusual
981 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
982 * For now, we use an unbounded busy loop while waiting for
983 * BMI_EXECUTE.
984 *
985 * If BMI_EXECUTE ever needs to support longer-latency execution,
986 * especially in production, this code needs to be enhanced to sleep
987 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
988 * a function of Host processor speed.
989 */
990 if (len >= 4) { /* NB: Currently, always true */
991 ret = ath6kl_bmi_get_rx_lkahd(ar);
992 if (ret)
993 return ret;
994 }
995
996 addr = ar->mbox_info.htc_addr;
997 ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
998 HIF_RD_SYNC_BYTE_INC);
999 if (ret) {
1000 ath6kl_err("Unable to read the bmi data from the device: %d\n",
1001 ret);
1002 return ret;
1003 }
1004
1005 return 0;
1006}
1007
848static void ath6kl_sdio_stop(struct ath6kl *ar) 1008static void ath6kl_sdio_stop(struct ath6kl *ar)
849{ 1009{
850 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); 1010 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
@@ -889,6 +1049,8 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
889 .cleanup_scatter = ath6kl_sdio_cleanup_scatter, 1049 .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
890 .suspend = ath6kl_sdio_suspend, 1050 .suspend = ath6kl_sdio_suspend,
891 .resume = ath6kl_sdio_resume, 1051 .resume = ath6kl_sdio_resume,
1052 .bmi_read = ath6kl_sdio_bmi_read,
1053 .bmi_write = ath6kl_sdio_bmi_write,
892 .power_on = ath6kl_sdio_power_on, 1054 .power_on = ath6kl_sdio_power_on,
893 .power_off = ath6kl_sdio_power_off, 1055 .power_off = ath6kl_sdio_power_off,
894 .stop = ath6kl_sdio_stop, 1056 .stop = ath6kl_sdio_stop,