diff options
Diffstat (limited to 'drivers/net/wireless/rsi/rsi_91x_sdio_ops.c')
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 566 |
1 files changed, 566 insertions, 0 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c new file mode 100644 index 000000000000..f1cb99cafed8 --- /dev/null +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | |||
@@ -0,0 +1,566 @@ | |||
1 | /** | ||
2 | * Copyright (c) 2014 Redpine Signals Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/firmware.h> | ||
19 | #include "rsi_sdio.h" | ||
20 | #include "rsi_common.h" | ||
21 | |||
22 | /** | ||
23 | * rsi_sdio_master_access_msword() - This function sets the AHB master access | ||
24 | * MS word in the SDIO slave registers. | ||
25 | * @adapter: Pointer to the adapter structure. | ||
26 | * @ms_word: ms word need to be initialized. | ||
27 | * | ||
28 | * Return: status: 0 on success, -1 on failure. | ||
29 | */ | ||
30 | static int rsi_sdio_master_access_msword(struct rsi_hw *adapter, | ||
31 | u16 ms_word) | ||
32 | { | ||
33 | u8 byte; | ||
34 | u8 function = 0; | ||
35 | int status = 0; | ||
36 | |||
37 | byte = (u8)(ms_word & 0x00FF); | ||
38 | |||
39 | rsi_dbg(INIT_ZONE, | ||
40 | "%s: MASTER_ACCESS_MSBYTE:0x%x\n", __func__, byte); | ||
41 | |||
42 | status = rsi_sdio_write_register(adapter, | ||
43 | function, | ||
44 | SDIO_MASTER_ACCESS_MSBYTE, | ||
45 | &byte); | ||
46 | if (status) { | ||
47 | rsi_dbg(ERR_ZONE, | ||
48 | "%s: fail to access MASTER_ACCESS_MSBYTE\n", | ||
49 | __func__); | ||
50 | return -1; | ||
51 | } | ||
52 | |||
53 | byte = (u8)(ms_word >> 8); | ||
54 | |||
55 | rsi_dbg(INIT_ZONE, "%s:MASTER_ACCESS_LSBYTE:0x%x\n", __func__, byte); | ||
56 | status = rsi_sdio_write_register(adapter, | ||
57 | function, | ||
58 | SDIO_MASTER_ACCESS_LSBYTE, | ||
59 | &byte); | ||
60 | return status; | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * rsi_copy_to_card() - This function includes the actual funtionality of | ||
65 | * copying the TA firmware to the card.Basically this | ||
66 | * function includes opening the TA file,reading the | ||
67 | * TA file and writing their values in blocks of data. | ||
68 | * @common: Pointer to the driver private structure. | ||
69 | * @fw: Pointer to the firmware value to be written. | ||
70 | * @len: length of firmware file. | ||
71 | * @num_blocks: Number of blocks to be written to the card. | ||
72 | * | ||
73 | * Return: 0 on success and -1 on failure. | ||
74 | */ | ||
75 | static int rsi_copy_to_card(struct rsi_common *common, | ||
76 | const u8 *fw, | ||
77 | u32 len, | ||
78 | u32 num_blocks) | ||
79 | { | ||
80 | struct rsi_hw *adapter = common->priv; | ||
81 | struct rsi_91x_sdiodev *dev = | ||
82 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; | ||
83 | u32 indx, ii; | ||
84 | u32 block_size = dev->tx_blk_size; | ||
85 | u32 lsb_address; | ||
86 | __le32 data[] = { TA_HOLD_THREAD_VALUE, TA_SOFT_RST_CLR, | ||
87 | TA_PC_ZERO, TA_RELEASE_THREAD_VALUE }; | ||
88 | u32 address[] = { TA_HOLD_THREAD_REG, TA_SOFT_RESET_REG, | ||
89 | TA_TH0_PC_REG, TA_RELEASE_THREAD_REG }; | ||
90 | u32 base_address; | ||
91 | u16 msb_address; | ||
92 | |||
93 | base_address = TA_LOAD_ADDRESS; | ||
94 | msb_address = base_address >> 16; | ||
95 | |||
96 | for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) { | ||
97 | lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER); | ||
98 | if (rsi_sdio_write_register_multiple(adapter, | ||
99 | lsb_address, | ||
100 | (u8 *)(fw + indx), | ||
101 | block_size)) { | ||
102 | rsi_dbg(ERR_ZONE, | ||
103 | "%s: Unable to load %s blk\n", __func__, | ||
104 | FIRMWARE_RSI9113); | ||
105 | return -1; | ||
106 | } | ||
107 | rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii); | ||
108 | base_address += block_size; | ||
109 | if ((base_address >> 16) != msb_address) { | ||
110 | msb_address += 1; | ||
111 | if (rsi_sdio_master_access_msword(adapter, | ||
112 | msb_address)) { | ||
113 | rsi_dbg(ERR_ZONE, | ||
114 | "%s: Unable to set ms word reg\n", | ||
115 | __func__); | ||
116 | return -1; | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | if (len % block_size) { | ||
122 | lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER); | ||
123 | if (rsi_sdio_write_register_multiple(adapter, | ||
124 | lsb_address, | ||
125 | (u8 *)(fw + indx), | ||
126 | len % block_size)) { | ||
127 | rsi_dbg(ERR_ZONE, | ||
128 | "%s: Unable to load f/w\n", __func__); | ||
129 | return -1; | ||
130 | } | ||
131 | } | ||
132 | rsi_dbg(INIT_ZONE, | ||
133 | "%s: Succesfully loaded TA instructions\n", __func__); | ||
134 | |||
135 | if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) { | ||
136 | rsi_dbg(ERR_ZONE, | ||
137 | "%s: Unable to set ms word to common reg\n", | ||
138 | __func__); | ||
139 | return -1; | ||
140 | } | ||
141 | |||
142 | for (ii = 0; ii < ARRAY_SIZE(data); ii++) { | ||
143 | /* Bringing TA out of reset */ | ||
144 | if (rsi_sdio_write_register_multiple(adapter, | ||
145 | (address[ii] | | ||
146 | RSI_SD_REQUEST_MASTER), | ||
147 | (u8 *)&data[ii], | ||
148 | 4)) { | ||
149 | rsi_dbg(ERR_ZONE, | ||
150 | "%s: Unable to hold TA threads\n", __func__); | ||
151 | return -1; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * rsi_load_ta_instructions() - This function includes the actual funtionality | ||
161 | * of loading the TA firmware.This function also | ||
162 | * includes opening the TA file,reading the TA | ||
163 | * file and writing their value in blocks of data. | ||
164 | * @common: Pointer to the driver private structure. | ||
165 | * | ||
166 | * Return: status: 0 on success, -1 on failure. | ||
167 | */ | ||
168 | static int rsi_load_ta_instructions(struct rsi_common *common) | ||
169 | { | ||
170 | struct rsi_hw *adapter = common->priv; | ||
171 | struct rsi_91x_sdiodev *dev = | ||
172 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; | ||
173 | u32 len; | ||
174 | u32 num_blocks; | ||
175 | const u8 *fw; | ||
176 | const struct firmware *fw_entry = NULL; | ||
177 | u32 block_size = dev->tx_blk_size; | ||
178 | int status = 0; | ||
179 | u32 base_address; | ||
180 | u16 msb_address; | ||
181 | |||
182 | if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) { | ||
183 | rsi_dbg(ERR_ZONE, | ||
184 | "%s: Unable to set ms word to common reg\n", | ||
185 | __func__); | ||
186 | return -1; | ||
187 | } | ||
188 | base_address = TA_LOAD_ADDRESS; | ||
189 | msb_address = (base_address >> 16); | ||
190 | |||
191 | if (rsi_sdio_master_access_msword(adapter, msb_address)) { | ||
192 | rsi_dbg(ERR_ZONE, | ||
193 | "%s: Unable to set ms word reg\n", __func__); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device); | ||
198 | if (status < 0) { | ||
199 | rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n", | ||
200 | __func__, FIRMWARE_RSI9113); | ||
201 | return status; | ||
202 | } | ||
203 | |||
204 | fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); | ||
205 | len = fw_entry->size; | ||
206 | |||
207 | if (len % 4) | ||
208 | len += (4 - (len % 4)); | ||
209 | |||
210 | num_blocks = (len / block_size); | ||
211 | |||
212 | rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len); | ||
213 | rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); | ||
214 | |||
215 | status = rsi_copy_to_card(common, fw, len, num_blocks); | ||
216 | release_firmware(fw_entry); | ||
217 | return status; | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * rsi_process_pkt() - This Function reads rx_blocks register and figures out | ||
222 | * the size of the rx pkt. | ||
223 | * @common: Pointer to the driver private structure. | ||
224 | * | ||
225 | * Return: 0 on success, -1 on failure. | ||
226 | */ | ||
227 | static int rsi_process_pkt(struct rsi_common *common) | ||
228 | { | ||
229 | struct rsi_hw *adapter = common->priv; | ||
230 | u8 num_blks = 0; | ||
231 | u32 rcv_pkt_len = 0; | ||
232 | int status = 0; | ||
233 | |||
234 | status = rsi_sdio_read_register(adapter, | ||
235 | SDIO_RX_NUM_BLOCKS_REG, | ||
236 | &num_blks); | ||
237 | |||
238 | if (status) { | ||
239 | rsi_dbg(ERR_ZONE, | ||
240 | "%s: Failed to read pkt length from the card:\n", | ||
241 | __func__); | ||
242 | return status; | ||
243 | } | ||
244 | rcv_pkt_len = (num_blks * 256); | ||
245 | |||
246 | common->rx_data_pkt = kmalloc(rcv_pkt_len, GFP_KERNEL); | ||
247 | if (!common->rx_data_pkt) { | ||
248 | rsi_dbg(ERR_ZONE, "%s: Failed in memory allocation\n", | ||
249 | __func__); | ||
250 | return -1; | ||
251 | } | ||
252 | |||
253 | status = rsi_sdio_host_intf_read_pkt(adapter, | ||
254 | common->rx_data_pkt, | ||
255 | rcv_pkt_len); | ||
256 | if (status) { | ||
257 | rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n", | ||
258 | __func__); | ||
259 | goto fail; | ||
260 | } | ||
261 | |||
262 | status = rsi_read_pkt(common, rcv_pkt_len); | ||
263 | kfree(common->rx_data_pkt); | ||
264 | return status; | ||
265 | |||
266 | fail: | ||
267 | kfree(common->rx_data_pkt); | ||
268 | return -1; | ||
269 | } | ||
270 | |||
271 | /** | ||
272 | * rsi_init_sdio_slave_regs() - This function does the actual initialization | ||
273 | * of SDBUS slave registers. | ||
274 | * @adapter: Pointer to the adapter structure. | ||
275 | * | ||
276 | * Return: status: 0 on success, -1 on failure. | ||
277 | */ | ||
278 | int rsi_init_sdio_slave_regs(struct rsi_hw *adapter) | ||
279 | { | ||
280 | struct rsi_91x_sdiodev *dev = | ||
281 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; | ||
282 | u8 function = 0; | ||
283 | u8 byte; | ||
284 | int status = 0; | ||
285 | |||
286 | if (dev->next_read_delay) { | ||
287 | byte = dev->next_read_delay; | ||
288 | status = rsi_sdio_write_register(adapter, | ||
289 | function, | ||
290 | SDIO_NXT_RD_DELAY2, | ||
291 | &byte); | ||
292 | if (status) { | ||
293 | rsi_dbg(ERR_ZONE, | ||
294 | "%s: Failed to write SDIO_NXT_RD_DELAY2\n", | ||
295 | __func__); | ||
296 | return -1; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | if (dev->sdio_high_speed_enable) { | ||
301 | rsi_dbg(INIT_ZONE, "%s: Enabling SDIO High speed\n", __func__); | ||
302 | byte = 0x3; | ||
303 | |||
304 | status = rsi_sdio_write_register(adapter, | ||
305 | function, | ||
306 | SDIO_REG_HIGH_SPEED, | ||
307 | &byte); | ||
308 | if (status) { | ||
309 | rsi_dbg(ERR_ZONE, | ||
310 | "%s: Failed to enable SDIO high speed\n", | ||
311 | __func__); | ||
312 | return -1; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* This tells SDIO FIFO when to start read to host */ | ||
317 | rsi_dbg(INIT_ZONE, "%s: Initialzing SDIO read start level\n", __func__); | ||
318 | byte = 0x24; | ||
319 | |||
320 | status = rsi_sdio_write_register(adapter, | ||
321 | function, | ||
322 | SDIO_READ_START_LVL, | ||
323 | &byte); | ||
324 | if (status) { | ||
325 | rsi_dbg(ERR_ZONE, | ||
326 | "%s: Failed to write SDIO_READ_START_LVL\n", __func__); | ||
327 | return -1; | ||
328 | } | ||
329 | |||
330 | rsi_dbg(INIT_ZONE, "%s: Initialzing FIFO ctrl registers\n", __func__); | ||
331 | byte = (128 - 32); | ||
332 | |||
333 | status = rsi_sdio_write_register(adapter, | ||
334 | function, | ||
335 | SDIO_READ_FIFO_CTL, | ||
336 | &byte); | ||
337 | if (status) { | ||
338 | rsi_dbg(ERR_ZONE, | ||
339 | "%s: Failed to write SDIO_READ_FIFO_CTL\n", __func__); | ||
340 | return -1; | ||
341 | } | ||
342 | |||
343 | byte = 32; | ||
344 | status = rsi_sdio_write_register(adapter, | ||
345 | function, | ||
346 | SDIO_WRITE_FIFO_CTL, | ||
347 | &byte); | ||
348 | if (status) { | ||
349 | rsi_dbg(ERR_ZONE, | ||
350 | "%s: Failed to write SDIO_WRITE_FIFO_CTL\n", __func__); | ||
351 | return -1; | ||
352 | } | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * rsi_interrupt_handler() - This function read and process SDIO interrupts. | ||
359 | * @adapter: Pointer to the adapter structure. | ||
360 | * | ||
361 | * Return: None. | ||
362 | */ | ||
363 | void rsi_interrupt_handler(struct rsi_hw *adapter) | ||
364 | { | ||
365 | struct rsi_common *common = adapter->priv; | ||
366 | struct rsi_91x_sdiodev *dev = | ||
367 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; | ||
368 | int status; | ||
369 | enum sdio_interrupt_type isr_type; | ||
370 | u8 isr_status = 0; | ||
371 | u8 fw_status = 0; | ||
372 | |||
373 | dev->rx_info.sdio_int_counter++; | ||
374 | |||
375 | do { | ||
376 | mutex_lock(&common->tx_rxlock); | ||
377 | status = rsi_sdio_read_register(common->priv, | ||
378 | RSI_FN1_INT_REGISTER, | ||
379 | &isr_status); | ||
380 | if (status) { | ||
381 | rsi_dbg(ERR_ZONE, | ||
382 | "%s: Failed to Read Intr Status Register\n", | ||
383 | __func__); | ||
384 | mutex_unlock(&common->tx_rxlock); | ||
385 | return; | ||
386 | } | ||
387 | |||
388 | if (isr_status == 0) { | ||
389 | rsi_set_event(&common->tx_thread.event); | ||
390 | dev->rx_info.sdio_intr_status_zero++; | ||
391 | mutex_unlock(&common->tx_rxlock); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | rsi_dbg(ISR_ZONE, "%s: Intr_status = %x %d %d\n", | ||
396 | __func__, isr_status, (1 << MSDU_PKT_PENDING), | ||
397 | (1 << FW_ASSERT_IND)); | ||
398 | |||
399 | do { | ||
400 | RSI_GET_SDIO_INTERRUPT_TYPE(isr_status, isr_type); | ||
401 | |||
402 | switch (isr_type) { | ||
403 | case BUFFER_AVAILABLE: | ||
404 | dev->rx_info.watch_bufferfull_count = 0; | ||
405 | dev->rx_info.buffer_full = false; | ||
406 | dev->rx_info.mgmt_buffer_full = false; | ||
407 | rsi_sdio_ack_intr(common->priv, | ||
408 | (1 << PKT_BUFF_AVAILABLE)); | ||
409 | rsi_set_event((&common->tx_thread.event)); | ||
410 | rsi_dbg(ISR_ZONE, | ||
411 | "%s: ==> BUFFER_AVILABLE <==\n", | ||
412 | __func__); | ||
413 | dev->rx_info.buf_avilable_counter++; | ||
414 | break; | ||
415 | |||
416 | case FIRMWARE_ASSERT_IND: | ||
417 | rsi_dbg(ERR_ZONE, | ||
418 | "%s: ==> FIRMWARE Assert <==\n", | ||
419 | __func__); | ||
420 | status = rsi_sdio_read_register(common->priv, | ||
421 | SDIO_FW_STATUS_REG, | ||
422 | &fw_status); | ||
423 | if (status) { | ||
424 | rsi_dbg(ERR_ZONE, | ||
425 | "%s: Failed to read f/w reg\n", | ||
426 | __func__); | ||
427 | } else { | ||
428 | rsi_dbg(ERR_ZONE, | ||
429 | "%s: Firmware Status is 0x%x\n", | ||
430 | __func__ , fw_status); | ||
431 | rsi_sdio_ack_intr(common->priv, | ||
432 | (1 << FW_ASSERT_IND)); | ||
433 | } | ||
434 | |||
435 | common->fsm_state = FSM_CARD_NOT_READY; | ||
436 | break; | ||
437 | |||
438 | case MSDU_PACKET_PENDING: | ||
439 | rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n"); | ||
440 | dev->rx_info.total_sdio_msdu_pending_intr++; | ||
441 | |||
442 | status = rsi_process_pkt(common); | ||
443 | if (status) { | ||
444 | rsi_dbg(ERR_ZONE, | ||
445 | "%s: Failed to read pkt\n", | ||
446 | __func__); | ||
447 | mutex_unlock(&common->tx_rxlock); | ||
448 | return; | ||
449 | } | ||
450 | break; | ||
451 | default: | ||
452 | rsi_sdio_ack_intr(common->priv, isr_status); | ||
453 | dev->rx_info.total_sdio_unknown_intr++; | ||
454 | isr_status = 0; | ||
455 | rsi_dbg(ISR_ZONE, | ||
456 | "Unknown Interrupt %x\n", | ||
457 | isr_status); | ||
458 | break; | ||
459 | } | ||
460 | isr_status ^= BIT(isr_type - 1); | ||
461 | } while (isr_status); | ||
462 | mutex_unlock(&common->tx_rxlock); | ||
463 | } while (1); | ||
464 | } | ||
465 | |||
466 | /** | ||
467 | * rsi_device_init() - This Function Initializes The HAL. | ||
468 | * @common: Pointer to the driver private structure. | ||
469 | * | ||
470 | * Return: 0 on success, -1 on failure. | ||
471 | */ | ||
472 | int rsi_sdio_device_init(struct rsi_common *common) | ||
473 | { | ||
474 | if (rsi_load_ta_instructions(common)) | ||
475 | return -1; | ||
476 | |||
477 | if (rsi_sdio_master_access_msword(common->priv, MISC_CFG_BASE_ADDR)) { | ||
478 | rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", | ||
479 | __func__); | ||
480 | return -1; | ||
481 | } | ||
482 | rsi_dbg(INIT_ZONE, | ||
483 | "%s: Setting ms word to 0x41050000\n", __func__); | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * rsi_sdio_read_buffer_status_register() - This function is used to the read | ||
490 | * buffer status register and set | ||
491 | * relevant fields in | ||
492 | * rsi_91x_sdiodev struct. | ||
493 | * @adapter: Pointer to the driver hw structure. | ||
494 | * @q_num: The Q number whose status is to be found. | ||
495 | * | ||
496 | * Return: status: -1 on failure or else queue full/stop is indicated. | ||
497 | */ | ||
498 | int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num) | ||
499 | { | ||
500 | struct rsi_common *common = adapter->priv; | ||
501 | struct rsi_91x_sdiodev *dev = | ||
502 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; | ||
503 | u8 buf_status = 0; | ||
504 | int status = 0; | ||
505 | |||
506 | status = rsi_sdio_read_register(common->priv, | ||
507 | RSI_DEVICE_BUFFER_STATUS_REGISTER, | ||
508 | &buf_status); | ||
509 | |||
510 | if (status) { | ||
511 | rsi_dbg(ERR_ZONE, | ||
512 | "%s: Failed to read status register\n", __func__); | ||
513 | return -1; | ||
514 | } | ||
515 | |||
516 | if (buf_status & (BIT(PKT_MGMT_BUFF_FULL))) { | ||
517 | if (!dev->rx_info.mgmt_buffer_full) | ||
518 | dev->rx_info.mgmt_buf_full_counter++; | ||
519 | dev->rx_info.mgmt_buffer_full = true; | ||
520 | } else { | ||
521 | dev->rx_info.mgmt_buffer_full = false; | ||
522 | } | ||
523 | |||
524 | if (buf_status & (BIT(PKT_BUFF_FULL))) { | ||
525 | if (!dev->rx_info.buffer_full) | ||
526 | dev->rx_info.buf_full_counter++; | ||
527 | dev->rx_info.buffer_full = true; | ||
528 | } else { | ||
529 | dev->rx_info.buffer_full = false; | ||
530 | } | ||
531 | |||
532 | if (buf_status & (BIT(PKT_BUFF_SEMI_FULL))) { | ||
533 | if (!dev->rx_info.semi_buffer_full) | ||
534 | dev->rx_info.buf_semi_full_counter++; | ||
535 | dev->rx_info.semi_buffer_full = true; | ||
536 | } else { | ||
537 | dev->rx_info.semi_buffer_full = false; | ||
538 | } | ||
539 | |||
540 | if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full)) | ||
541 | return QUEUE_FULL; | ||
542 | |||
543 | if (dev->rx_info.buffer_full) | ||
544 | return QUEUE_FULL; | ||
545 | |||
546 | return QUEUE_NOT_FULL; | ||
547 | } | ||
548 | |||
549 | /** | ||
550 | * rsi_sdio_determine_event_timeout() - This Function determines the event | ||
551 | * timeout duration. | ||
552 | * @adapter: Pointer to the adapter structure. | ||
553 | * | ||
554 | * Return: timeout duration is returned. | ||
555 | */ | ||
556 | int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter) | ||
557 | { | ||
558 | struct rsi_91x_sdiodev *dev = | ||
559 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; | ||
560 | |||
561 | /* Once buffer full is seen, event timeout to occur every 2 msecs */ | ||
562 | if (dev->rx_info.buffer_full) | ||
563 | return 2; | ||
564 | |||
565 | return EVENT_WAIT_FOREVER; | ||
566 | } | ||