aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl/bmi.c
diff options
context:
space:
mode:
authorKalle Valo <kvalo@qca.qualcomm.com>2011-09-07 03:55:16 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2011-09-16 11:48:34 -0400
commitcfc301edfb4f762309b5704ae316ea98d7ba1106 (patch)
tree5a95860d6fd632877722ca46a90aae85578faec9 /drivers/net/wireless/ath/ath6kl/bmi.c
parent772c31ee438e4d2d7a5e049b8d73c2ee8902f656 (diff)
ath6kl: fix busy loop in ath6kl_bmi_get_rx_lkahd()
Brent reported that ath6kl busy loops if firmware doesn't boot for some reason (in this case he was using an older firmware which wasn't supported by ath6kl). Investigation revealed that this was even on purpose, ath6kl_bmi_get_rx_lkahd() had a parameter to disable the timeout check, which is extremely evil. I didn't find any reason why the timeout needs to be disabled so I just removed the feature. The function already busyloops a maximum of one second if it doesn't get an answer, even that's too long. If something takes longer than that a more friendly approach is needed. Reported-by: Brent Taylor <btaylor1@motorolasolutions.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/bmi.c')
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index 84676697d7eb..c5d11cc536e0 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -62,14 +62,14 @@ static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
62 return 0; 62 return 0;
63} 63}
64 64
65static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout) 65static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
66{ 66{
67 unsigned long timeout; 67 unsigned long timeout;
68 u32 rx_word = 0; 68 u32 rx_word = 0;
69 int ret = 0; 69 int ret = 0;
70 70
71 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); 71 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
72 while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) { 72 while (time_before(jiffies, timeout) && !rx_word) {
73 ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS, 73 ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
74 (u8 *)&rx_word, sizeof(rx_word), 74 (u8 *)&rx_word, sizeof(rx_word),
75 HIF_RD_SYNC_BYTE_INC); 75 HIF_RD_SYNC_BYTE_INC);
@@ -109,8 +109,7 @@ static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
109 return ret; 109 return ret;
110} 110}
111 111
112static int ath6kl_bmi_recv_buf(struct ath6kl *ar, 112static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len)
113 u8 *buf, u32 len, bool want_timeout)
114{ 113{
115 int ret; 114 int ret;
116 u32 addr; 115 u32 addr;
@@ -162,7 +161,7 @@ static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
162 * a function of Host processor speed. 161 * a function of Host processor speed.
163 */ 162 */
164 if (len >= 4) { /* NB: Currently, always true */ 163 if (len >= 4) { /* NB: Currently, always true */
165 ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout); 164 ret = ath6kl_bmi_get_rx_lkahd(ar);
166 if (ret) 165 if (ret)
167 return ret; 166 return ret;
168 } 167 }
@@ -220,7 +219,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
220 } 219 }
221 220
222 ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version, 221 ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
223 sizeof(targ_info->version), true); 222 sizeof(targ_info->version));
224 if (ret) { 223 if (ret) {
225 ath6kl_err("Unable to recv target info: %d\n", ret); 224 ath6kl_err("Unable to recv target info: %d\n", ret);
226 return ret; 225 return ret;
@@ -230,8 +229,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
230 /* Determine how many bytes are in the Target's targ_info */ 229 /* Determine how many bytes are in the Target's targ_info */
231 ret = ath6kl_bmi_recv_buf(ar, 230 ret = ath6kl_bmi_recv_buf(ar,
232 (u8 *)&targ_info->byte_count, 231 (u8 *)&targ_info->byte_count,
233 sizeof(targ_info->byte_count), 232 sizeof(targ_info->byte_count));
234 true);
235 if (ret) { 233 if (ret) {
236 ath6kl_err("unable to read target info byte count: %d\n", 234 ath6kl_err("unable to read target info byte count: %d\n",
237 ret); 235 ret);
@@ -252,8 +250,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
252 ((u8 *)targ_info) + 250 ((u8 *)targ_info) +
253 sizeof(targ_info->byte_count), 251 sizeof(targ_info->byte_count),
254 sizeof(*targ_info) - 252 sizeof(*targ_info) -
255 sizeof(targ_info->byte_count), 253 sizeof(targ_info->byte_count));
256 true);
257 254
258 if (ret) { 255 if (ret) {
259 ath6kl_err("Unable to read target info (%d bytes): %d\n", 256 ath6kl_err("Unable to read target info (%d bytes): %d\n",
@@ -311,7 +308,7 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
311 ret); 308 ret);
312 return ret; 309 return ret;
313 } 310 }
314 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true); 311 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len);
315 if (ret) { 312 if (ret) {
316 ath6kl_err("Unable to read from the device: %d\n", 313 ath6kl_err("Unable to read from the device: %d\n",
317 ret); 314 ret);
@@ -424,7 +421,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
424 return ret; 421 return ret;
425 } 422 }
426 423
427 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false); 424 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
428 if (ret) { 425 if (ret) {
429 ath6kl_err("Unable to read from the device: %d\n", ret); 426 ath6kl_err("Unable to read from the device: %d\n", ret);
430 return ret; 427 return ret;
@@ -504,7 +501,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
504 return ret; 501 return ret;
505 } 502 }
506 503
507 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true); 504 ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param));
508 if (ret) { 505 if (ret) {
509 ath6kl_err("Unable to read from the device: %d\n", ret); 506 ath6kl_err("Unable to read from the device: %d\n", ret);
510 return ret; 507 return ret;