Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
csr_wifi_hip_card_sdio_intr.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  (c) Cambridge Silicon Radio Limited 2012
4  All rights reserved and confidential information of CSR
5 
6  Refer to LICENSE.txt included with this source for details
7  on the license terms.
8 
9 *****************************************************************************/
10 
11 /*
12  * ---------------------------------------------------------------------------
13  * FILE: csr_wifi_hip_card_sdio_intr.c
14  *
15  * PURPOSE:
16  * Interrupt processing for the UniFi SDIO driver.
17  *
18  * We may need another signal queue of responses to UniFi to hold
19  * bulk data commands generated by read_to_host_signals().
20  *
21  * ---------------------------------------------------------------------------
22  */
23 #undef CSR_WIFI_HIP_NOISY
24 
25 #include "csr_wifi_hip_unifi.h"
27 #include "csr_wifi_hip_card.h"
28 #include "csr_wifi_hip_xbv.h"
29 
30 
31 /*
32  * If the SDIO link is idle for this time (in milliseconds),
33  * signal UniFi to go into Deep Sleep.
34  * Valid return value of unifi_bh().
35  */
36 #define UNIFI_DEFAULT_HOST_IDLE_TIMEOUT 5
37 /*
38  * If the UniFi has not woken up for this time (in milliseconds),
39  * signal the bottom half to take action.
40  * Valid return value of unifi_bh().
41  */
42 #define UNIFI_DEFAULT_WAKE_TIMEOUT 1000
43 
44 
45 static CsrResult process_bh(card_t *card);
46 static CsrResult handle_host_protocol(card_t *card, u8 *processed_something);
47 
48 static CsrResult flush_fh_buffer(card_t *card);
49 
50 static CsrResult check_fh_sig_slots(card_t *card, u16 needed, s32 *space);
51 
52 static CsrResult read_to_host_signals(card_t *card, s32 *processed);
53 static CsrResult process_to_host_signals(card_t *card, s32 *processed);
54 
55 static CsrResult process_bulk_data_command(card_t *card,
56  const u8 *cmdptr,
57  s16 cmd, u16 len);
58 static CsrResult process_clear_slot_command(card_t *card,
59  const u8 *cmdptr);
60 static CsrResult process_fh_cmd_queue(card_t *card, s32 *processed);
61 static CsrResult process_fh_traffic_queue(card_t *card, s32 *processed);
62 static void restart_packet_flow(card_t *card);
63 static CsrResult process_clock_request(card_t *card);
64 
65 #ifdef CSR_WIFI_HIP_NOISY
66 s16 dump_fh_buf = 0;
67 #endif /* CSR_WIFI_HIP_NOISY */
68 
69 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
70 
71 /*
72  * The unifi_debug_output buffer can be used to debug the HIP behaviour offline
73  * i.e. without using the tracing functions that change the timing.
74  *
75  * Call unifi_debug_log_to_buf() with printf arguments to store a string into
76  * unifi_debug_output. When unifi_debug_buf_dump() is called, the contents of the
77  * buffer are dumped with dump_str() which has to be implemented in the
78  * OS layer, during the porting exercise. The offset printed, holds the
79  * offset where the last character is (always a zero).
80  *
81  */
82 
83 #define UNIFI_DEBUG_GBUFFER_SIZE 8192
84 static char unifi_debug_output[UNIFI_DEBUG_GBUFFER_SIZE];
85 static char *unifi_dbgbuf_ptr = unifi_debug_output;
86 static char *unifi_dbgbuf_start = unifi_debug_output;
87 
88 static void append_char(char c)
89 {
90  /* write char and advance pointer */
91  *unifi_dbgbuf_ptr++ = c;
92  /* wrap pointer at end of buffer */
93  if ((unifi_dbgbuf_ptr - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE)
94  {
95  unifi_dbgbuf_ptr = unifi_debug_output;
96  }
97 } /* append_char() */
98 
99 
100 void unifi_debug_string_to_buf(const char *str)
101 {
102  const char *p = str;
103  while (*p)
104  {
105  append_char(*p);
106  p++;
107  }
108  /* Update start-of-buffer pointer */
109  unifi_dbgbuf_start = unifi_dbgbuf_ptr + 1;
110  if ((unifi_dbgbuf_start - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE)
111  {
112  unifi_dbgbuf_start = unifi_debug_output;
113  }
114 }
115 
116 
117 void unifi_debug_log_to_buf(const char *fmt, ...)
118 {
119 #define DEBUG_BUFFER_SIZE 80
120  static char s[DEBUG_BUFFER_SIZE];
121  va_list args;
122 
123  va_start(args, fmt);
124  vsnprintf(s, DEBUG_BUFFER_SIZE, fmt, args);
125  va_end(args);
126 
127  unifi_debug_string_to_buf(s);
128 } /* unifi_debug_log_to_buf() */
129 
130 
131 /* Convert signed 32 bit (or less) integer to string */
132 static void CsrUInt16ToHex(u16 number, char *str)
133 {
134  u16 index;
135  u16 currentValue;
136 
137  for (index = 0; index < 4; index++)
138  {
139  currentValue = (u16) (number & 0x000F);
140  number >>= 4;
141  str[3 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0');
142  }
143  str[4] = '\0';
144 }
145 
146 
147 /*
148  * ---------------------------------------------------------------------------
149  * unifi_debug_hex_to_buf
150  *
151  * puts the contents of the passed buffer into the debug buffer as a hex string
152  *
153  * Arguments:
154  * buff buffer to print as hex
155  * length number of chars to print
156  *
157  * Returns:
158  * None.
159  *
160  * ---------------------------------------------------------------------------
161  */
162 void unifi_debug_hex_to_buf(const char *buff, u16 length)
163 {
164  char s[5];
165  u16 i;
166 
167  for (i = 0; i < length; i = i + 2)
168  {
169  CsrUInt16ToHex(*((u16 *)(buff + i)), s);
170  unifi_debug_string_to_buf(s);
171  }
172 }
173 
174 
175 void unifi_debug_buf_dump(void)
176 {
177  s32 offset = unifi_dbgbuf_ptr - unifi_debug_output;
178 
179  unifi_error(NULL, "HIP debug buffer offset=%d\n", offset);
180  dump_str(unifi_debug_output + offset, UNIFI_DEBUG_GBUFFER_SIZE - offset);
181  dump_str(unifi_debug_output, offset);
182 } /* unifi_debug_buf_dump() */
183 
184 
185 #endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
186 
187 #ifdef CSR_PRE_ALLOC_NET_DATA
188 #define NETDATA_PRE_ALLOC_BUF_SIZE 8000
189 
190 void prealloc_netdata_free(card_t *card)
191 {
192  unifi_warning(card->ospriv, "prealloc_netdata_free: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
193 
194  while (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length != 0)
195  {
196  unifi_warning(card->ospriv, "prealloc_netdata_free: r=%d\n", card->prealloc_netdata_r);
197 
198  unifi_net_data_free(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_r]);
199  card->prealloc_netdata_r++;
200  card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM;
201  }
202  card->prealloc_netdata_r = card->prealloc_netdata_w = 0;
203 
204  unifi_warning(card->ospriv, "prealloc_netdata_free: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
205 }
206 
207 
208 CsrResult prealloc_netdata_alloc(card_t *card)
209 {
210  CsrResult r;
211 
212  unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
213 
214  while (card->bulk_data_desc_list[card->prealloc_netdata_w].data_length == 0)
215  {
216  r = unifi_net_data_malloc(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_w], NETDATA_PRE_ALLOC_BUF_SIZE);
217  if (r != CSR_RESULT_SUCCESS)
218  {
219  unifi_error(card->ospriv, "prealloc_netdata_alloc: Failed to allocate t-h bulk data\n");
220  return CSR_RESULT_FAILURE;
221  }
222  card->prealloc_netdata_w++;
223  card->prealloc_netdata_w %= BULK_DATA_PRE_ALLOC_NUM;
224  }
225  unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
226 
227  return CSR_RESULT_SUCCESS;
228 }
229 
230 
231 static CsrResult prealloc_netdata_get(card_t *card, bulk_data_desc_t *bulk_data_slot, u32 size)
232 {
233  CsrResult r;
234 
235  unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
236 
237  if (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0)
238  {
239  unifi_error(card->ospriv, "prealloc_netdata_get: data_length = 0\n");
240  }
241 
242  if ((size > NETDATA_PRE_ALLOC_BUF_SIZE) || (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0))
243  {
244  unifi_warning(card->ospriv, "prealloc_netdata_get: Calling net_data_malloc\n");
245 
246  r = unifi_net_data_malloc(card->ospriv, bulk_data_slot, size);
247  if (r != CSR_RESULT_SUCCESS)
248  {
249  unifi_error(card->ospriv, "prealloc_netdata_get: Failed to allocate t-h bulk data\n");
250  return CSR_RESULT_FAILURE;
251  }
252  return CSR_RESULT_SUCCESS;
253  }
254 
255  *bulk_data_slot = card->bulk_data_desc_list[card->prealloc_netdata_r];
256  card->bulk_data_desc_list[card->prealloc_netdata_r].os_data_ptr = NULL;
257  card->bulk_data_desc_list[card->prealloc_netdata_r].os_net_buf_ptr = NULL;
258  card->bulk_data_desc_list[card->prealloc_netdata_r].net_buf_length = 0;
259  card->bulk_data_desc_list[card->prealloc_netdata_r].data_length = 0;
260 
261  card->prealloc_netdata_r++;
262  card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM;
263 
264  unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
265 
266  return CSR_RESULT_SUCCESS;
267 }
268 
269 
270 #endif
271 
272 /*
273  * ---------------------------------------------------------------------------
274  * unifi_sdio_interrupt_handler
275  *
276  * This function should be called by the OS-dependent code to handle
277  * an SDIO interrupt from the UniFi.
278  *
279  * Arguments:
280  * card Pointer to card context structure.
281  *
282  * Returns:
283  * None.
284  *
285  * Notes: This function may be called in DRS context. In this case,
286  * tracing with the unifi_trace(), etc, is not allowed.
287  * ---------------------------------------------------------------------------
288  */
290 {
291  /*
292  * Set the flag to say reason for waking was SDIO interrupt.
293  * Then ask the OS layer to run the unifi_bh to give attention to the UniFi.
294  */
295  card->bh_reason_unifi = 1;
296  (void)unifi_run_bh(card->ospriv);
297 } /* sdio_interrupt_handler() */
298 
299 
300 /*
301  * ---------------------------------------------------------------------------
302  * unifi_configure_low_power_mode
303  *
304  * This function should be called by the OS-dependent when
305  * the deep sleep signaling needs to be enabled or disabled.
306  *
307  * Arguments:
308  * card Pointer to card context structure.
309  * low_power_mode Disable/Enable the deep sleep signaling
310  * periodic_wake_mode UniFi wakes host periodically.
311  *
312  * Returns:
313  * CSR_RESULT_SUCCESS on success or a CSR error code.
314  * ---------------------------------------------------------------------------
315  */
317  enum unifi_low_power_mode low_power_mode,
318  enum unifi_periodic_wake_mode periodic_wake_mode)
319 {
320  card->low_power_mode = low_power_mode;
321  card->periodic_wake_mode = periodic_wake_mode;
322 
323  unifi_trace(card->ospriv, UDBG1,
324  "unifi_configure_low_power_mode: new mode = %s, wake_host = %s\n",
325  (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled",
326  (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE");
327 
328  (void)unifi_run_bh(card->ospriv);
329  return CSR_RESULT_SUCCESS;
330 } /* unifi_configure_low_power_mode() */
331 
332 
333 /*
334  * ---------------------------------------------------------------------------
335  * unifi_force_low_power_mode
336  *
337  * This function should be called by the OS-dependent when
338  * UniFi needs to be set to the low power mode (e.g. on suspend)
339  *
340  * Arguments:
341  * card Pointer to card context structure.
342  *
343  * Returns:
344  * CSR_RESULT_SUCCESS on success or a CSR error code.
345  * ---------------------------------------------------------------------------
346  */
348 {
349  if (card->low_power_mode == UNIFI_LOW_POWER_DISABLED)
350  {
351  unifi_error(card->ospriv, "Attempt to set mode to TORPID when lower power mode is disabled\n");
353  }
354 
356 } /* unifi_force_low_power_mode() */
357 
358 
359 /*
360  * ---------------------------------------------------------------------------
361  * unifi_bh
362  *
363  * This function should be called by the OS-dependent code when
364  * host and/or UniFi has requested an exchange of messages.
365  *
366  * Arguments:
367  * card Pointer to card context structure.
368  *
369  * Returns:
370  * CSR_RESULT_SUCCESS on success or a CSR error code.
371  * ---------------------------------------------------------------------------
372  */
373 CsrResult unifi_bh(card_t *card, u32 *remaining)
374 {
375  CsrResult r;
376  CsrResult csrResult;
377  u8 pending;
378  s32 iostate, j;
379  const enum unifi_low_power_mode low_power_mode = card->low_power_mode;
380  u16 data_slots_used = 0;
381 
382 
383  /* Process request to raise the maximum SDIO clock */
384  r = process_clock_request(card);
385  if (r != CSR_RESULT_SUCCESS)
386  {
387  unifi_error(card->ospriv, "Error setting maximum SDIO clock\n");
388  goto exit;
389  }
390 
391  /*
392  * Why was the BH thread woken?
393  * If it was an SDIO interrupt, UniFi is awake and we need to process it.
394  * If it was a host process queueing data, then we need to awaken UniFi.
395  *
396  * Priority of flags is top down.
397  *
398  * ----------------------------------------------------------+
399  * \state| AWAKE | DROWSY | TORPID |
400  * flag\ | | | |
401  * ---------+--------------+----------------+----------------|
402  * | do the host | go to AWAKE and| go to AWAKE and|
403  * unifi | protocol | do the host | do the host |
404  * | | protocol | protocol |
405  * ---------+--------------+----------------+----------------|
406  * | do the host | | |
407  * host | protocol | do nothing | go to DROWSY |
408  * | | | |
409  * ---------+--------------+----------------+----------------|
410  * | | | should not |
411  * timeout | go to TORPID | error, unifi | occur |
412  * | | didn't wake up | do nothing |
413  * ----------------------------------------------------------+
414  *
415  * Note that if we end up in the AWAKE state we always do the host protocol.
416  */
417 
418  do
419  {
420  /*
421  * When the host state is set to DROWSY, then we can not disable the
422  * interrupts as UniFi can generate an interrupt even when the INT_ENABLE
423  * register has the interrupts disabled. This interrupt will be lost.
424  */
425  if (card->host_state == UNIFI_HOST_STATE_DROWSY || card->host_state == UNIFI_HOST_STATE_TORPID)
426  {
427  u8 reason_unifi;
428 
429  /*
430  * An interrupt may occur while or after we cache the reason.
431  * This interrupt will cause the unifi_bh() to be scheduled again.
432  * Any interrupt that has happened before the register is read
433  * and is considered spurious has to acknowledged.
434  */
435  reason_unifi = card->bh_reason_unifi;
436 
437  /*
438  * If an interrupt is received, check if it was a real one,
439  * set the host state to AWAKE and run the BH.
440  */
441  r = CardPendingInt(card, &pending);
442  if (r != CSR_RESULT_SUCCESS)
443  {
444  goto exit;
445  }
446 
447  if (pending)
448  {
449  unifi_trace(card->ospriv, UDBG5,
450  "UNIFI_HOST_STATE_%s: Set state to AWAKE.\n",
451  (card->host_state == UNIFI_HOST_STATE_TORPID)?"TORPID" : "DROWSY");
452 
454  if (r == CSR_RESULT_SUCCESS)
455  {
456  (*remaining) = 0;
457  break;
458  }
459  }
460  else if (reason_unifi)
461  {
462  CsrSdioInterruptAcknowledge(card->sdio_if);
463  }
464 
465  /*
466  * If an chip is in TORPID, and the host wants to wake it up,
467  * set the host state to DROWSY and wait for the wake-up interrupt.
468  */
469  if ((card->host_state == UNIFI_HOST_STATE_TORPID) && card->bh_reason_host)
470  {
472  if (r == CSR_RESULT_SUCCESS)
473  {
474  /*
475  * set the timeout value to UNIFI_DEFAULT_WAKE_TIMEOUT
476  * to capture a wake error.
477  */
478  card->bh_reason_host = 0;
479  (*remaining) = UNIFI_DEFAULT_WAKE_TIMEOUT;
480  return CSR_RESULT_SUCCESS;
481  }
482 
483  goto exit;
484  }
485 
486  /*
487  * If the chip is in DROWSY, and the timeout expires,
488  * we need to reset the chip. This should never occur.
489  * (If it does, check that the calling thread set "remaining"
490  * according to the time remaining when unifi_bh() was called).
491  */
492  if ((card->host_state == UNIFI_HOST_STATE_DROWSY) && ((*remaining) == 0))
493  {
494  unifi_error(card->ospriv, "UniFi did not wake up on time...\n");
495 
496  /*
497  * Check if Function1 has gone away or
498  * if we missed an SDIO interrupt.
499  */
500  r = unifi_check_io_status(card, &iostate);
502  {
503  goto exit;
504  }
505  /* Need to reset and reboot */
506  return CSR_RESULT_FAILURE;
507  }
508  }
509  else
510  {
511  if (card->bh_reason_unifi || card->bh_reason_host)
512  {
513  break;
514  }
515 
516  if (((*remaining) == 0) && (low_power_mode == UNIFI_LOW_POWER_ENABLED))
517  {
519  if (r == CSR_RESULT_SUCCESS)
520  {
521  (*remaining) = 0;
522  return CSR_RESULT_SUCCESS;
523  }
524 
525  goto exit;
526  }
527  }
528 
529  /* No need to run the host protocol */
530  return CSR_RESULT_SUCCESS;
531  } while (0);
532 
533 
534  /* Disable the SDIO interrupts while doing SDIO ops */
535  csrResult = CsrSdioInterruptDisable(card->sdio_if);
536  if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
537  {
539  goto exit;
540  }
541  if (csrResult != CSR_RESULT_SUCCESS)
542  {
543  r = ConvertCsrSdioToCsrHipResult(card, csrResult);
544  unifi_error(card->ospriv, "Failed to disable SDIO interrupts. unifi_bh queues error.\n");
545  goto exit;
546  }
547 
548  /* Now that the interrupts are disabled, ack the interrupt */
549  CsrSdioInterruptAcknowledge(card->sdio_if);
550 
551  /* Run the HIP */
552  r = process_bh(card);
553  if (r != CSR_RESULT_SUCCESS)
554  {
555  goto exit;
556  }
557 
558  /*
559  * If host is now idle, schedule a timer for the delay before we
560  * let UniFi go into deep sleep.
561  * If the timer goes off, we will move to TORPID state.
562  * If UniFi raises an interrupt in the meantime, we will cancel
563  * the timer and start a new one when we become idle.
564  */
565  for (j = 0; j < UNIFI_NO_OF_TX_QS; j++)
566  {
567  data_slots_used += CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[j]);
568  }
569 
570  if ((low_power_mode == UNIFI_LOW_POWER_ENABLED) && (data_slots_used == 0))
571  {
572 #ifndef CSR_WIFI_HIP_TA_DISABLE
573  if (card->ta_sampling.traffic_type != CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC)
574  {
575 #endif
576  /* return the UNIFI_DEFAULT_HOST_IDLE_TIMEOUT, so we can go to sleep. */
577  unifi_trace(card->ospriv, UDBG5,
578  "Traffic is not periodic, set timer for TORPID.\n");
579  (*remaining) = UNIFI_DEFAULT_HOST_IDLE_TIMEOUT;
580 #ifndef CSR_WIFI_HIP_TA_DISABLE
581  }
582  else
583  {
584  unifi_trace(card->ospriv, UDBG5,
585  "Traffic is periodic, set unifi to TORPID immediately.\n");
586  if (CardAreAllFromHostDataSlotsEmpty(card) == 1)
587  {
589  if (r != CSR_RESULT_SUCCESS)
590  {
591  goto exit;
592  }
593  }
594  }
595 #endif
596  }
597 
598  csrResult = CsrSdioInterruptEnable(card->sdio_if);
599  if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
600  {
602  }
603  if (csrResult != CSR_RESULT_SUCCESS)
604  {
605  r = ConvertCsrSdioToCsrHipResult(card, csrResult);
606  unifi_error(card->ospriv, "Failed to enable SDIO interrupt\n");
607  }
608 
609 exit:
610 
611  unifi_trace(card->ospriv, UDBG4, "New state=%d\n", card->host_state);
612 
613  if (r != CSR_RESULT_SUCCESS)
614  {
615 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
616  unifi_debug_buf_dump();
617 #endif
618  /* If an interrupt has been raised, ack it here */
619  if (card->bh_reason_unifi)
620  {
621  CsrSdioInterruptAcknowledge(card->sdio_if);
622  }
623 
624  unifi_error(card->ospriv,
625  "unifi_bh: state=%d %c, clock=%dkHz, interrupt=%d host=%d, power_save=%s\n",
626  card->host_state,
627  (card->host_state == UNIFI_HOST_STATE_AWAKE)?'A' : (card->host_state == UNIFI_HOST_STATE_DROWSY)?'D' : 'T',
628  card->sdio_clock_speed / 1000,
629  card->bh_reason_unifi, card->bh_reason_host,
630  (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled");
631 
632  /* Try to capture firmware panic codes */
633  (void)unifi_capture_panic(card);
634 
635  /* Ask for a mini-coredump when the driver has reset UniFi */
637  }
638 
639  return r;
640 } /* unifi_bh() */
641 
642 
643 /*
644  * ---------------------------------------------------------------------------
645  * process_clock_request
646  *
647  * Handle request from the OS layer to increase the SDIO clock speed.
648  * The fast clock is limited until the firmware has indicated that it has
649  * completed initialisation to the OS layer.
650  *
651  * Arguments:
652  * card Pointer to card context structure.
653  *
654  * Returns:
655  * CSR_RESULT_SUCCESS on success or CSR error code.
656  * ---------------------------------------------------------------------------
657  */
658 static CsrResult process_clock_request(card_t *card)
659 {
661  CsrResult csrResult;
662 
663  if (!card->request_max_clock)
664  {
665  return CSR_RESULT_SUCCESS; /* No pending request */
666  }
667 
668  /*
669  * The SDIO clock speed request from the OS layer is only acted upon if
670  * the UniFi is awake. If it was in any other state, the clock speed will
671  * transition through SAFE to MAX while the host wakes it up, and the
672  * final speed reached will be UNIFI_SDIO_CLOCK_MAX_HZ.
673  * This assumes that the SME never requests low power mode while the f/w
674  * initialisation takes place.
675  */
676  if (card->host_state == UNIFI_HOST_STATE_AWAKE)
677  {
678  unifi_trace(card->ospriv, UDBG1, "Set SDIO max clock\n");
679  csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_MAX_HZ);
680  if (csrResult != CSR_RESULT_SUCCESS)
681  {
682  r = ConvertCsrSdioToCsrHipResult(card, csrResult);
683  }
684  else
685  {
686  card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ; /* log the new freq */
687  }
688  }
689  else
690  {
691  unifi_trace(card->ospriv, UDBG1, "Will set SDIO max clock after wakeup\n");
692  }
693 
694  /* Cancel the request now that it has been acted upon, or is about to be
695  * by the wakeup mechanism
696  */
697  card->request_max_clock = 0;
698 
699  return r;
700 }
701 
702 
703 /*
704  * ---------------------------------------------------------------------------
705  * process_bh
706  *
707  * Exchange messages with UniFi
708  *
709  * Arguments:
710  * card Pointer to card context structure.
711  *
712  * Returns:
713  * CSR_RESULT_SUCCESS on success or CSR error code.
714  * ---------------------------------------------------------------------------
715  */
716 static CsrResult process_bh(card_t *card)
717 {
718  CsrResult r;
719  u8 more;
720  more = FALSE;
721 
722  /* Process the reasons (interrupt, signals) */
723  do
724  {
725  /*
726  * Run in a while loop, to save clearing the interrupts
727  * every time around the outside loop.
728  */
729  do
730  {
731  /* If configured to run the HIP just once, skip first loop */
732  if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE)
733  {
734  break;
735  }
736 
737  r = handle_host_protocol(card, &more);
738  if (r != CSR_RESULT_SUCCESS)
739  {
740  return r;
741  }
742 
743 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
744  unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n",
745  card->cmd_prof.cmd52_count,
746  card->cmd_prof.cmd53_count,
747  card->cmd_prof.tx_count,
748  card->cmd_prof.tx_cfm_count,
749  card->cmd_prof.rx_count,
750  card->cmd_prof.sdio_cmd_signal,
751  card->cmd_prof.sdio_cmd_to_host,
752  card->cmd_prof.sdio_cmd_from_host_and_clear
753  );
754 
755  card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0;
756  card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0;
757 
758  card->cmd_prof.cmd52_f0_r_count = 0;
759  card->cmd_prof.cmd52_f0_w_count = 0;
760  card->cmd_prof.cmd52_r8or16_count = 0;
761  card->cmd_prof.cmd52_w8or16_count = 0;
762  card->cmd_prof.cmd52_r16_count = 0;
763  card->cmd_prof.cmd52_w16_count = 0;
764  card->cmd_prof.cmd52_r32_count = 0;
765 
766  card->cmd_prof.sdio_cmd_signal = 0;
767  card->cmd_prof.sdio_cmd_clear_slot = 0;
768  card->cmd_prof.sdio_cmd_to_host = 0;
769  card->cmd_prof.sdio_cmd_from_host = 0;
770  card->cmd_prof.sdio_cmd_from_host_and_clear = 0;
771 #endif
772 
773 
774  } while (more || card->bh_reason_unifi || card->bh_reason_host);
775 
776  /* Acknowledge the h/w interrupt */
777  r = CardClearInt(card);
778  if (r != CSR_RESULT_SUCCESS)
779  {
780  unifi_error(card->ospriv, "Failed to acknowledge interrupt.\n");
781  return r;
782  }
783 
784  /*
785  * UniFi may have tried to generate an interrupt during the
786  * CardClearInt() was running. So, we need to run the host
787  * protocol again, to check if there are any pending requests.
788  */
789  r = handle_host_protocol(card, &more);
790  if (r != CSR_RESULT_SUCCESS)
791  {
792  return r;
793  }
794 
795 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
796  unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n",
797  card->cmd_prof.cmd52_count,
798  card->cmd_prof.cmd53_count,
799  card->cmd_prof.tx_count,
800  card->cmd_prof.tx_cfm_count,
801  card->cmd_prof.rx_count,
802  card->cmd_prof.sdio_cmd_signal,
803  card->cmd_prof.sdio_cmd_to_host,
804  card->cmd_prof.sdio_cmd_from_host_and_clear
805  );
806 
807  card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0;
808  card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0;
809 
810  card->cmd_prof.cmd52_f0_r_count = 0;
811  card->cmd_prof.cmd52_f0_w_count = 0;
812  card->cmd_prof.cmd52_r8or16_count = 0;
813  card->cmd_prof.cmd52_w8or16_count = 0;
814  card->cmd_prof.cmd52_r16_count = 0;
815  card->cmd_prof.cmd52_w16_count = 0;
816  card->cmd_prof.cmd52_r32_count = 0;
817 
818  card->cmd_prof.sdio_cmd_signal = 0;
819  card->cmd_prof.sdio_cmd_clear_slot = 0;
820  card->cmd_prof.sdio_cmd_to_host = 0;
821  card->cmd_prof.sdio_cmd_from_host = 0;
822  card->cmd_prof.sdio_cmd_from_host_and_clear = 0;
823 #endif
824  /* If configured to run the HIP just once, work is now done */
825  if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE)
826  {
827  break;
828  }
829 
830  } while (more || card->bh_reason_unifi || card->bh_reason_host);
831 
832 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
833  if ((card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE) == 0)
834  {
835  unifi_debug_log_to_buf("proc=%d\n",
836  card->cmd_prof.process_count);
837  }
838 #endif
839 
840  return CSR_RESULT_SUCCESS;
841 } /* process_bh() */
842 
843 
844 /*
845  * ---------------------------------------------------------------------------
846  * handle_host_protocol
847  *
848  * This function implements the Host Interface Protocol (HIP) as
849  * described in the Host Interface Protocol Specification.
850  *
851  * Arguments:
852  * card Pointer to card context structure.
853  * processed_something Pointer to location to update processing status:
854  * TRUE when data was transferred
855  * FALSE when no data was transferred (queues empty)
856  *
857  * Returns:
858  * CSR_RESULT_SUCCESS on success or CSR error code.
859  * ---------------------------------------------------------------------------
860  */
861 static CsrResult handle_host_protocol(card_t *card, u8 *processed_something)
862 {
863  CsrResult r;
864  s32 done;
865 
866  *processed_something = FALSE;
867 
868 #ifdef CSR_WIFI_HIP_NOISY
869  unifi_error(card->ospriv, " ======================== \n");
870 #endif /* CSR_WIFI_HIP_NOISY */
871 
872 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
873  card->cmd_prof.process_count++;
874 #endif
875 
876  card->bh_reason_unifi = card->bh_reason_host = 0;
877  card->generate_interrupt = 0;
878 
879 
880  /*
881  * (Re)fill the T-H signal buffer
882  */
883  r = read_to_host_signals(card, &done);
884  if (r != CSR_RESULT_SUCCESS)
885  {
886  unifi_error(card->ospriv, "Error occured reading to-host signals\n");
887  return r;
888  }
889  if (done > 0)
890  {
891  *processed_something = TRUE;
892  }
893 
894  /*
895  * Process any to-host signals.
896  * Perform any requested CMD53 transfers here, but just queue any
897  * bulk data command responses.
898  */
899  r = process_to_host_signals(card, &done);
900  if (r != CSR_RESULT_SUCCESS)
901  {
902  unifi_error(card->ospriv, "Error occured processing to-host signals\n");
903  return r;
904  }
905 
906  /* Now send any signals in the F-H queues */
907  /* Give precedence to the command queue */
908  r = process_fh_cmd_queue(card, &done);
909  if (r != CSR_RESULT_SUCCESS)
910  {
911  unifi_error(card->ospriv, "Error occured processing from-host signals\n");
912  return r;
913  }
914  if (done > 0)
915  {
916  *processed_something = TRUE;
917  }
918 
919  r = process_fh_traffic_queue(card, &done);
920  if (r != CSR_RESULT_SUCCESS)
921  {
922  unifi_error(card->ospriv, "Error occured processing from-host data signals\n");
923  return r;
924  }
925  if (done > 0)
926  {
927  *processed_something = TRUE;
928  }
929 
930  /* Flush out the batch of signals to the UniFi. */
931  r = flush_fh_buffer(card);
932  if (r != CSR_RESULT_SUCCESS)
933  {
934  unifi_error(card->ospriv, "Failed to copy from-host signals to UniFi\n");
935  return r;
936  }
937 
938 
939  /*
940  * Send the host interrupt to say the queues have been modified.
941  */
942  if (card->generate_interrupt)
943  {
944  r = CardGenInt(card);
945  if (r != CSR_RESULT_SUCCESS)
946  {
947  unifi_error(card->ospriv, "Failed to notify UniFi that queues have been modified.\n");
948  return r;
949  }
950  }
951 
952 #ifdef CSR_WIFI_RX_PATH_SPLIT
953 #ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
954  unifi_rx_queue_flush(card->ospriv);
955 #endif
956 #endif
957 
958  /* See if we can re-enable transmission now */
959  restart_packet_flow(card);
960 
961 #ifdef CSR_PRE_ALLOC_NET_DATA
962  r = prealloc_netdata_alloc(card);
963  if (r != CSR_RESULT_SUCCESS)
964  {
965  unifi_error(card->ospriv, "prealloc_netdata failed\n");
966  return r;
967  }
968 #endif
969 
970  /*
971  * Don't put the thread sleep if we just interacted with the chip,
972  * there might be more to do if we look again.
973  */
974  return r;
975 } /* handle_host_protocol() */
976 
977 
978 /*
979  * Rounds the given signal length in bytes to a whole number
980  * of sig_frag_size.
981  */
982 #define GET_CHUNKS_FOR(SIG_FRAG_SIZE, LENGTH) (((LENGTH) + ((SIG_FRAG_SIZE)-1)) / (SIG_FRAG_SIZE))
983 
984 
985 /*
986  * ---------------------------------------------------------------------------
987  * read_to_host_signals
988  *
989  * Read everything pending in the UniFi TH signal buffer.
990  * Only do it if the local buffer is empty.
991  *
992  * Arguments:
993  * card Pointer to card context struct
994  * processed Number of signals read:
995  * 0 if there were no signals pending,
996  * 1 if we read at least one signal
997  * Returns:
998  * CSR error code if an error occurred.
999  * ---------------------------------------------------------------------------
1000  */
1001 static CsrResult read_to_host_signals(card_t *card, s32 *processed)
1002 {
1003  s32 count_thw, count_thr;
1004  s32 unread_chunks, unread_bytes;
1005  CsrResult r;
1006 
1007  *processed = 0;
1008 
1009  /* Read any pending signals or bulk data commands */
1010  count_thw = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
1011  if (count_thw < 0)
1012  {
1013  unifi_error(card->ospriv, "Failed to read to-host sig written count\n");
1014  return CSR_RESULT_FAILURE;
1015  }
1016  card->to_host_signals_w = count_thw; /* diag */
1017 
1018  count_thr = card->to_host_signals_r;
1019 
1020  if (count_thw == count_thr)
1021  {
1022  return CSR_RESULT_SUCCESS;
1023  }
1024 
1025  unread_chunks =
1026  (((count_thw - count_thr) + 128) % 128) - card->th_buffer.count;
1027 
1028  if (unread_chunks == 0)
1029  {
1030  return CSR_RESULT_SUCCESS;
1031  }
1032 
1033  unread_bytes = card->config_data.sig_frag_size * unread_chunks;
1034 
1035 
1036  r = unifi_bulk_rw(card,
1037  card->config_data.tohost_sigbuf_handle,
1038  card->th_buffer.ptr,
1039  unread_bytes,
1040  UNIFI_SDIO_READ);
1041  if (r != CSR_RESULT_SUCCESS)
1042  {
1043  unifi_error(card->ospriv, "Failed to read ToHost signal\n");
1044  return r;
1045  }
1046 
1047  card->th_buffer.ptr += unread_bytes;
1048  card->th_buffer.count += (u16)unread_chunks;
1049 
1050  *processed = 1;
1051 
1052  return CSR_RESULT_SUCCESS;
1053 } /* read_to_host_signals() */
1054 
1055 
1056 /*
1057  * ---------------------------------------------------------------------------
1058  * update_to_host_signals_r
1059  *
1060  * Advance the shared-memory count of chunks read from the to-host
1061  * signal buffer.
1062  * Raise a UniFi internal interrupt to tell the firmware that the
1063  * count has changed.
1064  *
1065  * Arguments:
1066  * card Pointer to card context struct
1067  * pending Number of chunks remaining
1068  *
1069  * Returns:
1070  * CSR_RESULT_SUCCESS on success or CSR error code
1071  * ---------------------------------------------------------------------------
1072  */
1073 static CsrResult update_to_host_signals_r(card_t *card, s16 pending)
1074 {
1075  CsrResult r;
1076 
1077  card->to_host_signals_r =
1078  (card->to_host_signals_r + (card->th_buffer.count - pending)) % 128;
1079  card->th_buffer.count = pending;
1080 
1081  /* Update the count of signals read */
1082  r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 6,
1083  (u8)card->to_host_signals_r);
1084  if (r != CSR_RESULT_SUCCESS)
1085  {
1086  unifi_error(card->ospriv, "Failed to update to-host signals read\n");
1087  return r;
1088  }
1089 
1090  r = CardGenInt(card);
1091  if (r != CSR_RESULT_SUCCESS)
1092  {
1093  unifi_error(card->ospriv, "Failed to notify UniFi that we processed to-host signals.\n");
1094  return r;
1095  }
1096 
1097  card->generate_interrupt = 0;
1098 
1099  return CSR_RESULT_SUCCESS;
1100 } /* update_to_host_signals_r() */
1101 
1102 
1103 /*
1104  * ---------------------------------------------------------------------------
1105  * read_unpack_cmd
1106  *
1107  * Converts a wire-formatted command to the host bulk_data_cmd_t structure.
1108  *
1109  * Arguments:
1110  * ptr Pointer to the command
1111  * bulk_data_cmd Pointer to the host structure
1112  *
1113  * Returns:
1114  * None.
1115  * ---------------------------------------------------------------------------
1116  */
1117 static void read_unpack_cmd(const u8 *ptr, bulk_data_cmd_t *bulk_data_cmd)
1118 {
1119  s16 index = 0;
1120  bulk_data_cmd->cmd_and_len = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
1121  index += SIZEOF_UINT16;
1122  bulk_data_cmd->data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
1123  index += SIZEOF_UINT16;
1124  bulk_data_cmd->offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
1125  index += SIZEOF_UINT16;
1126  bulk_data_cmd->buffer_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
1127  index += SIZEOF_UINT16;
1128 } /* read_unpack_cmd */
1129 
1130 
1131 /*
1132  * ---------------------------------------------------------------------------
1133  * process_to_host_signals
1134  *
1135  * Read and dispatch signals from the UniFi
1136  *
1137  * Arguments:
1138  * card Pointer to card context struct
1139  * processed Pointer to location to write processing result:
1140  * 0 if there were no signals pending,
1141  * 1 if we read at least one signal
1142  *
1143  * Returns:
1144  * CSR error code if there was an error
1145  *
1146  * Notes:
1147  * Since bulk data transfers can take a long time, if we wait until
1148  * all are done before we acknowledge the signals, the UniFi runs out
1149  * of buffer space. Therefore we keep a count of the bytes transferred
1150  * in bulk data commands, and update the to-host-signals-read count
1151  * if we've done a large transfer.
1152  *
1153  * All data in the f/w is stored in a little endian format, without any
1154  * padding bytes. Every read from the memory has to be transformed in
1155  * host (cpu specific) format, before we can process it. Therefore we
1156  * use read_unpack_cmd() and read_unpack_signal() to convert the raw data
1157  * contained in the card->th_buffer.buf to host structures.
1158  * Important: UDI clients use wire-formatted structures, so we need to
1159  * indicate all data, as we have read it from the device.
1160  * ---------------------------------------------------------------------------
1161  */
1162 static CsrResult process_to_host_signals(card_t *card, s32 *processed)
1163 {
1164  s16 pending;
1165  s16 remaining;
1166  u8 *bufptr;
1167  bulk_data_param_t data_ptrs;
1168  s16 cmd;
1169  u16 sig_len;
1170  s16 i;
1171  u16 chunks_in_buf;
1172  u16 bytes_transferred = 0;
1174 
1175  *processed = 0;
1176 
1177  pending = card->th_buffer.count;
1178 
1179  /* Are there new to-host signals? */
1180  unifi_trace(card->ospriv, UDBG4, "handling %d to-host chunks\n", pending);
1181 
1182  if (!pending)
1183  {
1184  return CSR_RESULT_SUCCESS;
1185  }
1186 
1187  /*
1188  * This is a pointer to the raw data we have read from the f/w.
1189  * Can be a signal or a command. Note that we need to convert
1190  * it to a host structure before we process it.
1191  */
1192  bufptr = card->th_buffer.buf;
1193 
1194  while (pending > 0)
1195  {
1196  s16 f_flush_count = 0;
1197 
1198  /*
1199  * Command and length are common to signal and bulk data msgs.
1200  * If command == 0 (i.e. a signal), len is number of bytes
1201  * *following* the 2-byte header.
1202  */
1203  cmd = bufptr[1] >> 4;
1204  sig_len = bufptr[0] + ((bufptr[1] & 0x0F) << 8);
1205 
1206 #ifdef CSR_WIFI_HIP_NOISY
1207  unifi_error(card->ospriv, "Received UniFi msg cmd=%d, len=%d\n",
1208  cmd, sig_len);
1209 #endif /* CSR_WIFI_HIP_NOISY */
1210 
1211  if ((sig_len == 0) &&
1212  ((cmd != SDIO_CMD_CLEAR_SLOT) && (cmd != SDIO_CMD_PADDING)))
1213  {
1214  unifi_error(card->ospriv, "incomplete signal or command: has size zero\n");
1215  return CSR_RESULT_FAILURE;
1216  }
1217  /*
1218  * Make sure the buffer contains a complete message.
1219  * Signals may occupy multiple chunks, bulk-data commands occupy
1220  * one chunk.
1221  */
1222  if (cmd == SDIO_CMD_SIGNAL)
1223  {
1224  chunks_in_buf = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(sig_len + 2));
1225  }
1226  else
1227  {
1228  chunks_in_buf = 1;
1229  }
1230 
1231  if (chunks_in_buf > (u16)pending)
1232  {
1233  unifi_error(card->ospriv, "incomplete signal (0x%x?): need %d chunks, got %d\n",
1234  GET_SIGNAL_ID(bufptr + 2),
1235  chunks_in_buf, pending);
1236  unifi_error(card->ospriv, " thsw=%d, thsr=%d\n",
1237  card->to_host_signals_w,
1238  card->to_host_signals_r);
1239  return CSR_RESULT_FAILURE;
1240  }
1241 
1242 
1243  switch (cmd)
1244  {
1245  case SDIO_CMD_SIGNAL:
1246  /* This is a signal. Read the rest of it and then handle it. */
1247 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1248  card->cmd_prof.sdio_cmd_signal++;
1249 #endif
1250 
1251  for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
1252  {
1253  /* Retrieve dataRefs[i].DataLength */
1254  u16 data_len = GET_PACKED_DATAREF_LEN(bufptr + 2, i);
1255 
1256  /*
1257  * The bulk data length in the signal can not be greater than
1258  * the maximun length allowed by the SDIO config structure.
1259  */
1260  if (data_len > card->config_data.data_slot_size)
1261  {
1262  unifi_error(card->ospriv,
1263  "Bulk Data length (%d) exceeds Maximum Bulk Data length (%d)\n",
1264  data_len, card->config_data.data_slot_size);
1265  return CSR_RESULT_FAILURE;
1266  }
1267 
1268  /*
1269  * Len here might not be the same as the length in the
1270  * bulk data slot. The slot length will always be even,
1271  * but len could be odd.
1272  */
1273  if (data_len != 0)
1274  {
1275  /* Retrieve dataRefs[i].SlotNumber */
1276  s16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i);
1277 
1278  if (slot >= card->config_data.num_tohost_data_slots)
1279  {
1280  unifi_error(card->ospriv, "!!!bad slot number in to-host signal: %d, sig 0x%X\n",
1281  slot, cmd);
1282  return CSR_RESULT_FAILURE;
1283  }
1284 
1285  data_ptrs.d[i].os_data_ptr = card->to_host_data[slot].os_data_ptr;
1286  data_ptrs.d[i].os_net_buf_ptr = card->to_host_data[slot].os_net_buf_ptr;
1287  data_ptrs.d[i].net_buf_length = card->to_host_data[slot].net_buf_length;
1288  data_ptrs.d[i].data_length = data_len;
1289  }
1290  else
1291  {
1292  UNIFI_INIT_BULK_DATA(&data_ptrs.d[i]);
1293  }
1294  }
1295 
1296  /*
1297  * Log the signal to the UDI, before call unifi_receive_event() as
1298  * it can modify the bulk data.
1299  */
1300  if (card->udi_hook)
1301  {
1302  (*card->udi_hook)(card->ospriv, bufptr + 2, sig_len,
1303  &data_ptrs, UDI_LOG_TO_HOST);
1304  }
1305 
1306 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
1307  if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID)
1308  {
1309  card->cmd_prof.tx_cfm_count++;
1310  }
1311  else if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_INDICATION_ID)
1312  {
1313  if (data_ptrs.d[0].os_data_ptr)
1314  {
1315  if ((*data_ptrs.d[0].os_data_ptr) & 0x08)
1316  {
1317  card->cmd_prof.rx_count++;
1318  }
1319  }
1320  }
1321 #endif
1322  /*
1323  * Check if the signal is MA-PACKET.cfm and if so check the status.
1324  * If the status is failure, search through the slot records to find
1325  * if any slots are occupied for this host tag. This can happen if
1326  * f/w has not downloaded the bulkdata and before that itself it has
1327  * signalled the confirm with failure. If it finds a slot with that
1328  * host tag then, it clears the corresponding slot
1329  */
1330 
1331  if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID)
1332  {
1333  /* Get host tag and transmission status */
1334  u32 host_tag = GET_PACKED_MA_PACKET_CONFIRM_HOST_TAG(bufptr + 2);
1336 
1337  unifi_trace(card->ospriv, UDBG4, "process_to_host_signals signal ID=%x host Tag=%x status=%x\n",
1338  GET_SIGNAL_ID(bufptr + 2), host_tag, status);
1339 
1340  /* If transmission status is failure then search through the slot records
1341  * and if for any slot records the clear slot is not done then do it now
1342  */
1343 
1344  if (status && (card->fh_slot_host_tag_record))
1345  {
1346  u16 num_fh_slots = card->config_data.num_fromhost_data_slots;
1347 
1348  /* search through the list of slot records and match with host tag
1349  * If a slot is not yet cleared then clear the slot from here
1350  */
1351  for (i = 0; i < num_fh_slots; i++)
1352  {
1353  if (card->fh_slot_host_tag_record[i] == host_tag)
1354  {
1355 #ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
1356  /* Invoke the HAL module function to requeue it back to HAL Queues */
1357  r = unifi_reque_ma_packet_request(card->ospriv, host_tag, status, &card->from_host_data[i].bd);
1358  card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
1359  if (CSR_RESULT_SUCCESS != r)
1360  {
1361  unifi_trace(card->ospriv, UDBG5, "process_to_host_signals: Failed to requeue Packet(hTag:%x) back to HAL \n", host_tag);
1362  CardClearFromHostDataSlot(card, i);
1363  }
1364  else
1365  {
1366  CardClearFromHostDataSlotWithoutFreeingBulkData(card, i);
1367  }
1368 
1369 #else
1370  unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag);
1371  card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
1372 
1373  /* Set length field in from_host_data array to 0 */
1374  CardClearFromHostDataSlot(card, i);
1375 #endif
1376  break;
1377  }
1378  }
1379  }
1380  }
1381 
1382  /* Pass event to OS layer */
1383  unifi_receive_event(card->ospriv, bufptr + 2, sig_len, &data_ptrs);
1384 
1385  /* Initialise the to_host data, so it can be re-used. */
1386  for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
1387  {
1388  /* The slot is only valid if the length is non-zero. */
1389  if (GET_PACKED_DATAREF_LEN(bufptr + 2, i) != 0)
1390  {
1391  s16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i);
1392  if (slot < card->config_data.num_tohost_data_slots)
1393  {
1394  UNIFI_INIT_BULK_DATA(&card->to_host_data[slot]);
1395  }
1396  }
1397  }
1398 
1399 #ifndef CSR_WIFI_DEFER_TH_FLUSH
1400  /*
1401  * If we have previously transferred a lot of data, ack
1402  * the signals read so far, so f/w can reclaim the buffer
1403  * memory sooner.
1404  */
1405  if (bytes_transferred >= TO_HOST_FLUSH_THRESHOLD)
1406  {
1407  f_flush_count = 1;
1408  }
1409 #endif
1410  break;
1411 
1412 
1413  case SDIO_CMD_CLEAR_SLOT:
1414 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1415  card->cmd_prof.sdio_cmd_clear_slot++;
1416 #endif
1417  /* This is a clear slot command. */
1418  if (sig_len != 0)
1419  {
1420  unifi_error(card->ospriv, "process_to_host_signals: clear slot, bad data len: 0x%X at offset %d\n",
1421  sig_len, bufptr - card->th_buffer.buf);
1422  return CSR_RESULT_FAILURE;
1423  }
1424 
1425  r = process_clear_slot_command(card, bufptr);
1426  if (r != CSR_RESULT_SUCCESS)
1427  {
1428  unifi_error(card->ospriv, "Failed to process clear slot\n");
1429  return r;
1430  }
1431  break;
1432 
1437  /* This is a bulk data command. */
1438  if (sig_len & 1)
1439  {
1440  unifi_error(card->ospriv, "process_to_host_signals: bulk data, bad data len: 0x%X at offset %d\n",
1441  sig_len, bufptr - card->th_buffer.buf);
1442  return CSR_RESULT_FAILURE;
1443  }
1444 
1445  r = process_bulk_data_command(card, bufptr, cmd, sig_len);
1446  if (r != CSR_RESULT_SUCCESS)
1447  {
1448  unifi_error(card->ospriv, "Failed to process bulk cmd\n");
1449  return r;
1450  }
1451  /* Count the bytes transferred */
1452  bytes_transferred += sig_len;
1453 
1454  if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR)
1455  {
1456 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1457  card->cmd_prof.sdio_cmd_from_host_and_clear++;
1458 #endif
1459 #ifndef CSR_WIFI_DEFER_TH_FLUSH
1460  f_flush_count = 1;
1461 #endif
1462  }
1463 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1464  else if (cmd == SDIO_CMD_FROM_HOST_TRANSFER)
1465  {
1466  card->cmd_prof.sdio_cmd_from_host++;
1467  }
1468  else if (cmd == SDIO_CMD_TO_HOST_TRANSFER)
1469  {
1470  card->cmd_prof.sdio_cmd_to_host++;
1471  }
1472 #endif
1473  break;
1474 
1475  case SDIO_CMD_PADDING:
1476  break;
1477 
1478  default:
1479  unifi_error(card->ospriv, "Unrecognised to-host command: %d\n", cmd);
1480  break;
1481  }
1482 
1483  bufptr += chunks_in_buf * card->config_data.sig_frag_size;
1484  pending -= chunks_in_buf;
1485 
1486  /*
1487  * Write out the host signal count when a significant
1488  * number of bytes of bulk data have been transferred or
1489  * when we have performed a CopyFromHostAndClear.
1490  */
1491  if (f_flush_count)
1492  {
1493  r = update_to_host_signals_r(card, pending);
1494  if (r != CSR_RESULT_SUCCESS)
1495  {
1496  return r;
1497  }
1498  bytes_transferred = 0;
1499  }
1500  }
1501 
1502  if (pending)
1503  {
1504  unifi_warning(card->ospriv, "proc_th_sigs: %d unprocessed\n", pending);
1505  }
1506 
1507  /* If we processed any signals, write the updated count to UniFi */
1508  if (card->th_buffer.count != pending)
1509  {
1510  r = update_to_host_signals_r(card, pending);
1511  if (r != CSR_RESULT_SUCCESS)
1512  {
1513  return r;
1514  }
1515  }
1516 
1517  /*
1518  * Reset the buffer pointer, copying down any un-processed signals.
1519  * This can happen if we enable the optimisation in read_to_host_signals()
1520  * that limits the length to whole blocks.
1521  */
1522  remaining = card->th_buffer.ptr - bufptr;
1523  if (remaining < 0)
1524  {
1525  unifi_error(card->ospriv, "Processing TH signals overran the buffer\n");
1526  return CSR_RESULT_FAILURE;
1527  }
1528  if (remaining > 0)
1529  {
1530  /* Use a safe copy because source and destination may overlap */
1531  u8 *d = card->th_buffer.buf;
1532  u8 *s = bufptr;
1533  s32 n = remaining;
1534  while (n--)
1535  {
1536  *d++ = *s++;
1537  }
1538  }
1539  card->th_buffer.ptr = card->th_buffer.buf + remaining;
1540 
1541 
1542  /* If we reach here then we processed something */
1543  *processed = 1;
1544  return CSR_RESULT_SUCCESS;
1545 } /* process_to_host_signals() */
1546 
1547 
1548 /*
1549  * ---------------------------------------------------------------------------
1550  * process_clear_slot_command
1551  *
1552  * Process a clear slot command fom the UniFi.
1553  *
1554  * Arguments:
1555  * card Pointer to card context struct
1556  * bdcmd Pointer to bulk-data command msg from UniFi
1557  *
1558  * Returns:
1559  * 0 on success, CSR error code on error
1560  * ---------------------------------------------------------------------------
1561  */
1562 static CsrResult process_clear_slot_command(card_t *card, const u8 *cmdptr)
1563 {
1564  u16 data_slot;
1565  s16 slot;
1566 
1567  data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cmdptr + SIZEOF_UINT16);
1568 
1569  unifi_trace(card->ospriv, UDBG4, "Processing clear slot cmd, slot=0x%X\n",
1570  data_slot);
1571 
1572  slot = data_slot & 0x7FFF;
1573 
1574 #ifdef CSR_WIFI_HIP_NOISY
1575  unifi_error(card->ospriv, "CMD clear data slot 0x%04x\n", data_slot);
1576 #endif /* CSR_WIFI_HIP_NOISY */
1577 
1578  if (data_slot & SLOT_DIR_TO_HOST)
1579  {
1580  if (slot >= card->config_data.num_tohost_data_slots)
1581  {
1582  unifi_error(card->ospriv,
1583  "Invalid to-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
1584  slot);
1585  return CSR_RESULT_FAILURE;
1586  }
1587  /* clear to-host data slot */
1588  unifi_warning(card->ospriv, "Unexpected clear to-host data slot cmd: 0x%04x\n",
1589  data_slot);
1590  }
1591  else
1592  {
1593  if (slot >= card->config_data.num_fromhost_data_slots)
1594  {
1595  unifi_error(card->ospriv,
1596  "Invalid from-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
1597  slot);
1598  return CSR_RESULT_FAILURE;
1599  }
1600 
1601  /*
1602  * The driver is the owner to clear all slots now
1603  * Ref - comment in process_fh_traffic_queue
1604  * so it will just ignore the clear slot command from firmware
1605  * and return success
1606  */
1607  return CSR_RESULT_SUCCESS;
1608 
1609  /* Set length field in from_host_data array to 0 */
1610  /* CardClearFromHostDataSlot(card, slot); */
1611  }
1612 
1613  return CSR_RESULT_SUCCESS;
1614 } /* process_clear_slot_command() */
1615 
1616 
1617 /*
1618  * ---------------------------------------------------------------------------
1619  * process_bulk_data_command
1620  *
1621  * Process a bulk data request from the UniFi.
1622  *
1623  * Arguments:
1624  * card Pointer to card context struct
1625  * bdcmd Pointer to bulk-data command msg from UniFi
1626  * cmd, len Decoded values of command and length from the msg header
1627  * Cmd will only be one of:
1628  * SDIO_CMD_TO_HOST_TRANSFER
1629  * SDIO_CMD_FROM_HOST_TRANSFER
1630  * SDIO_CMD_FROM_HOST_AND_CLEAR
1631  * SDIO_CMD_OVERLAY_TRANSFER
1632  *
1633  * Returns:
1634  * CSR_RESULT_SUCCESS on success, CSR error code on error
1635  * ---------------------------------------------------------------------------
1636  */
1637 static CsrResult process_bulk_data_command(card_t *card, const u8 *cmdptr,
1638  s16 cmd, u16 len)
1639 {
1640  bulk_data_desc_t *bdslot;
1641 #ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
1642  u8 *host_bulk_data_slot;
1643 #endif
1644  bulk_data_cmd_t bdcmd;
1645  s16 offset;
1646  s16 slot;
1647  s16 dir;
1648  CsrResult r;
1649 
1650  read_unpack_cmd(cmdptr, &bdcmd);
1651 
1652  unifi_trace(card->ospriv, UDBG4, "Processing bulk data cmd %d %s, len=%d, slot=0x%X\n",
1653  cmd, lookup_bulkcmd_name(cmd), len, bdcmd.data_slot);
1654 
1655  /*
1656  * Round up the transfer length if required.
1657  * This is useful to force all transfers to be a multiple of the SDIO block
1658  * size, so the SDIO driver won't try to use a byte-mode CMD53. These are
1659  * broken on some hardware platforms.
1660  */
1661  if (card->sdio_io_block_pad)
1662  {
1663  len = (len + card->sdio_io_block_size - 1) & ~(card->sdio_io_block_size - 1);
1664  unifi_trace(card->ospriv, UDBG4, "Rounded bulk data length up to %d\n", len);
1665  }
1666 
1667  slot = bdcmd.data_slot & 0x7FFF;
1668 
1669  if (cmd == SDIO_CMD_OVERLAY_TRANSFER)
1670  {
1671  return CSR_WIFI_HIP_RESULT_INVALID_VALUE; /* Not used on CSR6xxx */
1672  }
1673  else
1674  {
1675  if (bdcmd.data_slot & SLOT_DIR_TO_HOST)
1676  {
1677  /* Request is for to-host bulk data */
1678 
1679  /* Check sanity of slot number */
1680  if (slot >= card->config_data.num_tohost_data_slots)
1681  {
1682  unifi_error(card->ospriv,
1683  "Invalid to-host data slot in SDIO bulk xfr req: %d\n",
1684  slot);
1685  return CSR_RESULT_FAILURE;
1686  }
1687 
1688  /* Allocate memory for card->to_host_data[slot] bulk data here. */
1689 #ifdef CSR_PRE_ALLOC_NET_DATA
1690  r = prealloc_netdata_get(card, &card->to_host_data[slot], len);
1691 #else
1692  r = unifi_net_data_malloc(card->ospriv, &card->to_host_data[slot], len);
1693 #endif
1694  if (r != CSR_RESULT_SUCCESS)
1695  {
1696  unifi_error(card->ospriv, "Failed to allocate t-h bulk data\n");
1697  return CSR_RESULT_FAILURE;
1698  }
1699 
1700  bdslot = &card->to_host_data[slot];
1701 
1702  /* Make sure that the buffer is 4-bytes aligned */
1703  r = unifi_net_dma_align(card->ospriv, bdslot);
1704  if (r != CSR_RESULT_SUCCESS)
1705  {
1706  unifi_error(card->ospriv, "Failed to align t-h bulk data buffer for DMA\n");
1707  return CSR_RESULT_FAILURE;
1708  }
1709  }
1710  else
1711  {
1712  /* Request is for from-host bulk data */
1713 
1714  if (slot >= card->config_data.num_fromhost_data_slots)
1715  {
1716  unifi_error(card->ospriv,
1717  "Invalid from-host data slot in SDIO bulk xfr req: %d\n",
1718  slot);
1719  return CSR_RESULT_FAILURE;
1720  }
1721  bdslot = &card->from_host_data[slot].bd;
1722  }
1723  offset = bdcmd.offset;
1724  }
1725  /* Do the transfer */
1726  dir = (cmd == SDIO_CMD_TO_HOST_TRANSFER)?
1728 
1729  unifi_trace(card->ospriv, UDBG4,
1730  "Bulk %c %s len=%d, handle %d - slot=%d %p+(%d)\n",
1731  (dir == UNIFI_SDIO_READ)?'R' : 'W',
1732  lookup_bulkcmd_name(cmd),
1733  len,
1734  bdcmd.buffer_handle,
1735  slot, bdslot->os_data_ptr, offset);
1736 #ifdef CSR_WIFI_HIP_NOISY
1737  unifi_error(card->ospriv, "Bulk %s len=%d, handle %d - slot=%d %p+(%d)\n",
1738  lookup_bulkcmd_name(cmd),
1739  len,
1740  bdcmd.buffer_handle,
1741  slot, bdslot->os_data_ptr, offset);
1742 #endif /* CSR_WIFI_HIP_NOISY */
1743 
1744 
1745  if (bdslot->os_data_ptr == NULL)
1746  {
1747  unifi_error(card->ospriv, "Null os_data_ptr - Bulk %s handle %d - slot=%d o=(%d)\n",
1748  lookup_bulkcmd_name(cmd),
1749  bdcmd.buffer_handle,
1750  slot,
1751  offset);
1753  }
1754 
1755 #ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
1756  /* if os_data_ptr is not 4-byte aligned, then allocate a new buffer and copy data
1757  to new buffer to ensure the address passed to unifi_bulk_rw is 4-byte aligned */
1758 
1759  if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((ptrdiff_t)bdslot->os_data_ptr + offset) & 3))
1760  {
1761  host_bulk_data_slot = kmalloc(len, GFP_KERNEL);
1762 
1763  if (!host_bulk_data_slot)
1764  {
1765  unifi_error(card->ospriv, " failed to allocate request_data before unifi_bulk_rw\n");
1766  return -1;
1767  }
1768 
1769  memcpy((void *)host_bulk_data_slot,
1770  (void *)(bdslot->os_data_ptr + offset), len);
1771 
1772  r = unifi_bulk_rw(card,
1773  bdcmd.buffer_handle,
1774  (void *)host_bulk_data_slot,
1775  len,
1776  dir);
1777  }
1778  else
1779 #endif
1780  {
1781  r = unifi_bulk_rw(card,
1782  bdcmd.buffer_handle,
1783  (void *)(bdslot->os_data_ptr + offset),
1784  len,
1785  dir);
1786  }
1787 
1789  {
1790  return r;
1791  }
1792  if (r != CSR_RESULT_SUCCESS)
1793  {
1794  unifi_error(card->ospriv,
1795  "Failed: %s hlen=%d, slen=%d, handle %d - slot=%d %p+0x%X\n",
1796  lookup_bulkcmd_name(cmd),
1797  len, /* Header length */
1798  bdslot->data_length, /* Length stored in slot */
1799  bdcmd.buffer_handle,
1800  slot, bdslot->os_data_ptr, offset);
1801  return r;
1802  }
1803 
1804  bdslot->data_length = len;
1805 
1806  if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR)
1807  {
1808  if (slot >= card->config_data.num_fromhost_data_slots)
1809  {
1810  unifi_error(card->ospriv,
1811  "Invalid from-host data slot in SDIO_CMD_FROM_HOST_AND_CLEAR: %d\n",
1812  slot);
1813  return CSR_RESULT_FAILURE;
1814  }
1815 
1816 #ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
1817  /* moving this check before we clear host data slot */
1818  if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((ptrdiff_t)bdslot->os_data_ptr + offset) & 3))
1819  {
1820  kfree(host_bulk_data_slot);
1821  }
1822 #endif
1823 
1824  if (card->fh_slot_host_tag_record)
1825  {
1826  unifi_trace(card->ospriv, UDBG5, "CopyFromHostAndClearSlot Reset entry for slot=%d\n", slot);
1827 
1828  /* reset the host tag entry for the corresponding slot */
1829  card->fh_slot_host_tag_record[slot] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
1830  }
1831 
1832 
1833  /* Set length field in from_host_data array to 0 */
1834  CardClearFromHostDataSlot(card, slot);
1835  }
1836 
1837  return CSR_RESULT_SUCCESS;
1838 } /* process_bulk_data_command() */
1839 
1840 
1841 /*
1842  * ---------------------------------------------------------------------------
1843  * check_fh_sig_slots
1844  *
1845  * Check whether there are <n> free signal slots available on UniFi.
1846  * This takes into account the signals already batched since the
1847  * from_host_signal counts were last read.
1848  * If the from_host_signal counts indicate not enough space, we read
1849  * the latest count from UniFi to see if some more have been freed.
1850  *
1851  * Arguments:
1852  * None.
1853  *
1854  * Returns:
1855  * CSR_RESULT_SUCCESS, otherwise CSR error code on error.
1856  * ---------------------------------------------------------------------------
1857  */
1858 static CsrResult check_fh_sig_slots(card_t *card, u16 needed, s32 *space_fh)
1859 {
1860  u32 count_fhw;
1861  u32 occupied_fh, slots_fh;
1862  s32 count_fhr;
1863 
1864  count_fhw = card->from_host_signals_w;
1865  count_fhr = card->from_host_signals_r;
1866  slots_fh = card->config_data.num_fromhost_sig_frags;
1867 
1868  /* Only read the space in from-host queue if necessary */
1869  occupied_fh = (count_fhw - count_fhr) % 128;
1870 
1871  if (slots_fh < occupied_fh)
1872  {
1873  *space_fh = 0;
1874  }
1875  else
1876  {
1877  *space_fh = slots_fh - occupied_fh;
1878  }
1879 
1880  if ((occupied_fh != 0) && (*space_fh < needed))
1881  {
1882  count_fhr = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2);
1883  if (count_fhr < 0)
1884  {
1885  unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
1886  return CSR_RESULT_FAILURE;
1887  }
1888  card->from_host_signals_r = count_fhr; /* diag */
1889 
1890  occupied_fh = (count_fhw - count_fhr) % 128;
1891  *space_fh = slots_fh - occupied_fh;
1892  }
1893 
1894  return CSR_RESULT_SUCCESS;
1895 } /* check_fh_sig_slots() */
1896 
1897 
1898 /*
1899 * If we are padding the From-Host signals to the SDIO block size,
1900 * we need to round up the needed_chunks to the SDIO block size.
1901 */
1902 #define ROUND_UP_NEEDED_CHUNKS(_card, _needed_chunks) \
1903  { \
1904  u16 _chunks_per_block; \
1905  u16 _chunks_in_last_block; \
1906  \
1907  if (_card->sdio_io_block_pad) \
1908  { \
1909  _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \
1910  _chunks_in_last_block = _needed_chunks % _chunks_per_block; \
1911  if (_chunks_in_last_block != 0) \
1912  { \
1913  _needed_chunks = _needed_chunks + (_chunks_per_block - _chunks_in_last_block); \
1914  } \
1915  } \
1916  }
1917 
1918 
1919 #define ROUND_UP_SPACE_CHUNKS(_card, _space_chunks) \
1920  { \
1921  u16 _chunks_per_block; \
1922  \
1923  if (_card->sdio_io_block_pad) \
1924  { \
1925  _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \
1926  _space_chunks = ((_space_chunks / _chunks_per_block) * _chunks_per_block); \
1927  } \
1928  }
1929 
1930 
1931 
1932 
1933 
1934 /*
1935  * ---------------------------------------------------------------------------
1936  * process_fh_cmd_queue
1937  *
1938  * Take one signal off the from-host queue and copy it to the UniFi.
1939  * Does nothing if the UniFi has no slots free.
1940  *
1941  * Arguments:
1942  * card Pointer to card context struct
1943  * processed Location to write:
1944  * 0 if there is nothing on the queue to process
1945  * 1 if a signal was successfully processed
1946  *
1947  * Returns:
1948  * CSR error code if an error occurred.
1949  *
1950  * Notes:
1951  * The from-host queue contains signal requests from the network driver
1952  * and any UDI clients interspersed. UDI clients' requests have been stored
1953  * in the from-host queue using the wire-format structures, as they arrive.
1954  * All other requests are stored in the from-host queue using the host
1955  * (cpu specific) structures. We use the is_packed member of the card_signal_t
1956  * structure that describes the queue to make the distiction.
1957  * ---------------------------------------------------------------------------
1958  */
1959 static CsrResult process_fh_cmd_queue(card_t *card, s32 *processed)
1960 {
1961  q_t *sigq = &card->fh_command_queue;
1962 
1963  CsrResult r;
1964  u16 pending_sigs;
1965  u16 pending_chunks;
1966  u16 needed_chunks;
1967  s32 space_chunks;
1968  u16 q_index;
1969 
1970  *processed = 0;
1971 
1972  /* Get the number of pending signals. */
1973  pending_sigs = CSR_WIFI_HIP_Q_SLOTS_USED(sigq);
1974  unifi_trace(card->ospriv, UDBG5, "proc_fh: %d pending\n", pending_sigs);
1975  if (pending_sigs == 0)
1976  {
1977  /* Nothing to do */
1978  return CSR_RESULT_SUCCESS;
1979  }
1980 
1981  /* Work out how many chunks we have waiting to send */
1982  for (pending_chunks = 0, q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq);
1983  q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(sigq);
1984  q_index = CSR_WIFI_HIP_Q_WRAP(sigq, q_index + 1))
1985  {
1986  card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index);
1987 
1988  /*
1989  * Note that GET_CHUNKS_FOR() needs the size of the packed
1990  * (wire-formatted) structure
1991  */
1992  pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(csptr->signal_length + 2));
1993  }
1994 
1995  /*
1996  * Check whether UniFi has space for all the buffered bulk-data
1997  * commands and signals as well.
1998  */
1999  needed_chunks = pending_chunks + card->fh_buffer.count;
2000 
2001  /* Round up to the block size if necessary */
2002  ROUND_UP_NEEDED_CHUNKS(card, needed_chunks);
2003 
2004  r = check_fh_sig_slots(card, needed_chunks, &space_chunks);
2005  if (r != CSR_RESULT_SUCCESS)
2006  {
2007  /* Error */
2008  unifi_error(card->ospriv, "Failed to read fh sig count\n");
2009  return r;
2010  }
2011 
2012 #ifdef CSR_WIFI_HIP_NOISY
2013  unifi_error(card->ospriv, "proc_fh: %d chunks free, need %d\n",
2014  space_chunks, needed_chunks);
2015 #endif /* CSR_WIFI_HIP_NOISY */
2016 
2017 
2018  /*
2019  * Coalesce as many from-host signals as possible
2020  * into a single block and write using a single CMD53
2021  */
2022  if (needed_chunks > (u16)space_chunks)
2023  {
2024  /* Round up to the block size if necessary */
2025  ROUND_UP_SPACE_CHUNKS(card, space_chunks);
2026 
2027  /*
2028  * If the f/w has less free chunks than those already pending
2029  * return immediately.
2030  */
2031  if ((u16)space_chunks <= card->fh_buffer.count)
2032  {
2033  /*
2034  * No room in UniFi for any signals after the buffered bulk
2035  * data commands have been sent.
2036  */
2037  unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
2038  card->fh_buffer.count, space_chunks);
2039  card->generate_interrupt = 1;
2040  return CSR_RESULT_SUCCESS;
2041  }
2042  pending_chunks = (u16)(space_chunks - card->fh_buffer.count);
2043  }
2044 
2045  while (pending_sigs-- && pending_chunks > 0)
2046  {
2047  card_signal_t *csptr;
2048  s16 i;
2049  u16 sig_chunks, total_length, free_chunks_in_fh_buffer;
2050  bulk_data_param_t bulkdata;
2051  u8 *packed_sigptr;
2052  u16 signal_length = 0;
2053 
2054  /* Retrieve the entry at the head of the queue */
2055  q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq);
2056 
2057  /* Get a pointer to the containing card_signal_t struct */
2058  csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index);
2059 
2060  /* Get the new length of the packed signal */
2061  signal_length = csptr->signal_length;
2062 
2063  if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE))
2064  {
2065  unifi_error(card->ospriv, "process_fh_queue: Bad len: %d\n", signal_length);
2066  return CSR_RESULT_FAILURE;
2067  }
2068 
2069  /* Need space for 2-byte SDIO protocol header + signal */
2070  sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(signal_length + 2));
2071 
2072  free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size,
2073  (u16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr));
2074  if (free_chunks_in_fh_buffer < sig_chunks)
2075  {
2076  /* No more room */
2077  unifi_notice(card->ospriv, "proc_fh_cmd_q: no room in fh buffer for 0x%.4X, deferring\n",
2078  (u16)(GET_SIGNAL_ID(csptr->sigbuf)));
2079  break;
2080  }
2081 
2082  packed_sigptr = csptr->sigbuf;
2083 
2084  /* Claim and set up a from-host data slot */
2086  {
2087  unifi_notice(card->ospriv, "proc_fh_cmd_q: no fh data slots for 0x%.4X, deferring\n",
2088  (u16)(GET_SIGNAL_ID(csptr->sigbuf)));
2089  break;
2090  }
2091 
2092  for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
2093  {
2094  if (csptr->bulkdata[i].data_length == 0)
2095  {
2096  UNIFI_INIT_BULK_DATA(&bulkdata.d[i]);
2097  }
2098  else
2099  {
2100  bulkdata.d[i].os_data_ptr = csptr->bulkdata[i].os_data_ptr;
2101  bulkdata.d[i].data_length = csptr->bulkdata[i].data_length;
2102  }
2103 
2104  /* Pass the free responsibility to the lower layer. */
2105  UNIFI_INIT_BULK_DATA(&csptr->bulkdata[i]);
2106  }
2107 
2108  unifi_trace(card->ospriv, UDBG2, "Sending signal 0x%.4X\n",
2109  GET_SIGNAL_ID(packed_sigptr));
2110 #ifdef CSR_WIFI_HIP_NOISY
2111  unifi_error(card->ospriv, "Sending signal 0x%.4X\n",
2112  GET_SIGNAL_ID(packed_sigptr));
2113 #endif /* CSR_WIFI_HIP_NOISY */
2114 
2115 
2116  /* Append packed signal to F-H buffer */
2117  total_length = sig_chunks * card->config_data.sig_frag_size;
2118 
2119  card->fh_buffer.ptr[0] = (u8)(signal_length & 0xff);
2120  card->fh_buffer.ptr[1] =
2121  (u8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4));
2122 
2123  memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
2124  memset(card->fh_buffer.ptr + 2 + signal_length, 0,
2125  total_length - (2 + signal_length));
2126 
2127 #ifdef CSR_WIFI_HIP_NOISY
2128  unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n",
2129  signal_length + 2);
2130  dump(card->fh_buffer.ptr, signal_length + 2);
2131  unifi_trace(card->ospriv, UDBG1, " \n");
2132 #endif /* CSR_WIFI_HIP_NOISY */
2133 
2134  card->fh_buffer.ptr += total_length;
2135  card->fh_buffer.count += sig_chunks;
2136 
2137 #ifdef CSR_WIFI_HIP_NOISY
2138  unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n",
2139  signal_length,
2140  card->fh_buffer.ptr - card->fh_buffer.buf,
2141  card->fh_buffer.count);
2142 #endif /* CSR_WIFI_HIP_NOISY */
2143 
2144  (*processed)++;
2145  pending_chunks -= sig_chunks;
2146 
2147  /* Log the signal to the UDI. */
2148  /* UDI will get the packed structure */
2149  /* Can not log the unpacked signal, unless we reconstruct it! */
2150  if (card->udi_hook)
2151  {
2152  (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
2153  &bulkdata, UDI_LOG_FROM_HOST);
2154  }
2155 
2156  /* Remove entry from q */
2157  csptr->signal_length = 0;
2158  CSR_WIFI_HIP_Q_INC_R(sigq);
2159  }
2160 
2161  return CSR_RESULT_SUCCESS;
2162 } /* process_fh_cmd_queue() */
2163 
2164 
2165 /*
2166  * ---------------------------------------------------------------------------
2167  * process_fh_traffic_queue
2168  *
2169  * Take signals off the from-host queue and copy them to the UniFi.
2170  * Does nothing if the UniFi has no slots free.
2171  *
2172  * Arguments:
2173  * card Pointer to card context struct
2174  * sigq Pointer to the traffic queue
2175  * processed Pointer to location to write:
2176  * 0 if there is nothing on the queue to process
2177  * 1 if a signal was successfully processed
2178  *
2179  * Returns:
2180  * CSR error code if an error occurred.
2181  *
2182  * Notes:
2183  * The from-host queue contains signal requests from the network driver
2184  * and any UDI clients interspersed.
2185  * ---------------------------------------------------------------------------
2186  */
2187 static CsrResult process_fh_traffic_queue(card_t *card, s32 *processed)
2188 {
2189  q_t *sigq = card->fh_traffic_queue;
2190 
2191  CsrResult r;
2192  s16 n = 0;
2193  s32 q_no;
2194  u16 pending_sigs = 0;
2195  u16 pending_chunks = 0;
2196  u16 needed_chunks;
2197  s32 space_chunks;
2198  u16 q_index;
2199  u32 host_tag = 0;
2200  u16 slot_num = 0;
2201 
2202  *processed = 0;
2203 
2204  /* calculate how many signals are in queues and how many chunks are needed. */
2205  for (n = UNIFI_NO_OF_TX_QS - 1; n >= 0; n--)
2206  {
2207  /* Get the number of pending signals. */
2208  pending_sigs += CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[n]);
2209  unifi_trace(card->ospriv, UDBG5, "proc_fh%d: %d pending\n", n, pending_sigs);
2210 
2211  /* Work out how many chunks we have waiting to send */
2212  for (q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[n]);
2213  q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(&sigq[n]);
2214  q_index = CSR_WIFI_HIP_Q_WRAP(&sigq[n], q_index + 1))
2215  {
2216  card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[n], q_index);
2217 
2218  /*
2219  * Note that GET_CHUNKS_FOR() needs the size of the packed
2220  * (wire-formatted) structure
2221  */
2222  pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(csptr->signal_length + 2));
2223  }
2224  }
2225 
2226  /* If there are no pending signals, just return */
2227  if (pending_sigs == 0)
2228  {
2229  /* Nothing to do */
2230  return CSR_RESULT_SUCCESS;
2231  }
2232 
2233  /*
2234  * Check whether UniFi has space for all the buffered bulk-data
2235  * commands and signals as well.
2236  */
2237  needed_chunks = pending_chunks + card->fh_buffer.count;
2238 
2239  /* Round up to the block size if necessary */
2240  ROUND_UP_NEEDED_CHUNKS(card, needed_chunks);
2241 
2242  r = check_fh_sig_slots(card, needed_chunks, &space_chunks);
2243  if (r != CSR_RESULT_SUCCESS)
2244  {
2245  /* Error */
2246  unifi_error(card->ospriv, "Failed to read fh sig count\n");
2247  return r;
2248  }
2249 
2250 #ifdef CSR_WIFI_HIP_NOISY
2251  unifi_error(card->ospriv,
2252  "process_fh_traffic_queue: %d chunks free, need %d\n",
2253  space_chunks, needed_chunks);
2254  read_fhsr(card); /* debugging only */
2255 #endif /* CSR_WIFI_HIP_NOISY */
2256 
2257  /* Coalesce as many from-host signals as possible
2258  into a single block and write using a single CMD53 */
2259  if (needed_chunks > (u16)space_chunks)
2260  {
2261  /* Round up to the block size if necessary */
2262  ROUND_UP_SPACE_CHUNKS(card, space_chunks);
2263 
2264  if ((u16)space_chunks <= card->fh_buffer.count)
2265  {
2266  /*
2267  * No room in UniFi for any signals after the buffered bulk
2268  * data commands have been sent.
2269  */
2270  unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
2271  card->fh_buffer.count, space_chunks);
2272  card->generate_interrupt = 1;
2273  return 0;
2274  }
2275 
2276  pending_chunks = (u16)space_chunks - card->fh_buffer.count;
2277  }
2278 
2279  q_no = UNIFI_NO_OF_TX_QS - 1;
2280 
2281  /*
2282  * pending_sigs will be exhausted if there are is no restriction to the pending
2283  * signals per queue. pending_chunks may be exhausted if there is a restriction.
2284  * q_no check will be exhausted if there is a restriction and our round-robin
2285  * algorith fails to fill all chunks.
2286  */
2287  do
2288  {
2289  card_signal_t *csptr;
2290  u16 sig_chunks, total_length, free_chunks_in_fh_buffer;
2291  bulk_data_param_t bulkdata;
2292  u8 *packed_sigptr;
2293  u16 signal_length = 0;
2294 
2295  /* if this queue is empty go to next one. */
2296  if (CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[q_no]) == 0)
2297  {
2298  q_no--;
2299  continue;
2300  }
2301 
2302  /* Retrieve the entry at the head of the queue */
2303  q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[q_no]);
2304 
2305  /* Get a pointer to the containing card_signal_t struct */
2306  csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[q_no], q_index);
2307 
2308  /* Get the new length of the packed signal */
2309  signal_length = csptr->signal_length;
2310 
2311  if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE))
2312  {
2313  unifi_error(card->ospriv, "process_fh_traffic_queue: Bad len: %d\n", signal_length);
2314  return CSR_RESULT_FAILURE;
2315  }
2316 
2317  /* Need space for 2-byte SDIO protocol header + signal */
2318  sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(signal_length + 2));
2319  free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size,
2320  (u16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr));
2321  if (free_chunks_in_fh_buffer < sig_chunks)
2322  {
2323  /* No more room */
2324  unifi_notice(card->ospriv, "process_fh_traffic_queue: no more chunks.\n");
2325  break;
2326  }
2327 
2328  packed_sigptr = csptr->sigbuf;
2329  /* Claim and set up a from-host data slot */
2330  if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, (unifi_TrafficQueue)q_no))
2331  {
2332  q_no--;
2333  continue;
2334  }
2335 
2336  /* Sanity check: MA-PACKET.req must have a valid bulk data */
2337  if ((csptr->bulkdata[0].data_length == 0) || (csptr->bulkdata[0].os_data_ptr == NULL))
2338  {
2339  unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n",
2340  csptr->bulkdata[0].data_length, csptr->bulkdata[0].os_data_ptr);
2341  dump(packed_sigptr, signal_length);
2342  return CSR_RESULT_FAILURE;
2343  }
2344 
2345  bulkdata.d[0].os_data_ptr = csptr->bulkdata[0].os_data_ptr;
2346  bulkdata.d[0].data_length = csptr->bulkdata[0].data_length;
2347  bulkdata.d[0].os_net_buf_ptr = csptr->bulkdata[0].os_net_buf_ptr;
2348  bulkdata.d[0].net_buf_length = csptr->bulkdata[0].net_buf_length;
2349 
2350  /* The driver owns clearing of HIP slots for following scenario
2351  * - driver has requested a MA-PACKET.req signal
2352  * - The f/w after receiving the signal decides it can't send it out due to various reasons
2353  * - So the f/w without downloading the bulk data decides to just send a confirmation with fail
2354  * - and then sends a clear slot signal to HIP
2355  *
2356  * But in some cases the clear slot signal never comes and the slot remains --NOT-- freed for ever
2357  *
2358  * To handle this, HIP will keep the record of host tag for each occupied slot
2359  * and then based on status of that Host tag and slot the driver will decide if the slot is
2360  * cleared by f/w signal or the slot has to be freed by driver
2361  */
2362 
2363  if (card->fh_slot_host_tag_record)
2364  {
2365  /* Update the f-h slot record for the corresponding host tag */
2366  host_tag = GET_PACKED_MA_PACKET_REQUEST_HOST_TAG(packed_sigptr);
2367  slot_num = GET_PACKED_DATAREF_SLOT(packed_sigptr, 0) & 0x00FF;
2368 
2369  unifi_trace(card->ospriv, UDBG5,
2370  "process_fh_traffic_queue signal ID =%x fh slot=%x Host tag =%x\n",
2371  GET_SIGNAL_ID(packed_sigptr), slot_num, host_tag);
2372  card->fh_slot_host_tag_record[slot_num] = host_tag;
2373  }
2374  UNIFI_INIT_BULK_DATA(&bulkdata.d[1]);
2375  UNIFI_INIT_BULK_DATA(&csptr->bulkdata[0]);
2376  UNIFI_INIT_BULK_DATA(&csptr->bulkdata[1]);
2377 
2378 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
2379  if (bulkdata.d[0].os_data_ptr)
2380  {
2381  if ((*bulkdata.d[0].os_data_ptr) & 0x08)
2382  {
2383  card->cmd_prof.tx_count++;
2384  }
2385  }
2386 #endif
2387  unifi_trace(card->ospriv, UDBG3, "Sending signal 0x%.4X\n",
2388  GET_SIGNAL_ID(packed_sigptr));
2389 #ifdef CSR_WIFI_HIP_NOISY
2390  unifi_error(card->ospriv, "Sending signal 0x%.4X\n",
2391  GET_SIGNAL_ID(packed_sigptr));
2392 #endif /* CSR_WIFI_HIP_NOISY */
2393 
2394  /* Append packed signal to F-H buffer */
2395  total_length = sig_chunks * card->config_data.sig_frag_size;
2396 
2397  card->fh_buffer.ptr[0] = (u8)(signal_length & 0xff);
2398  card->fh_buffer.ptr[1] =
2399  (u8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4));
2400 
2401  memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
2402  memset(card->fh_buffer.ptr + 2 + signal_length, 0,
2403  total_length - (2 + signal_length));
2404 
2405 #ifdef CSR_WIFI_HIP_NOISY
2406  unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n",
2407  signal_length + 2);
2408  dump(card->fh_buffer.ptr, signal_length + 2);
2409  unifi_trace(card->ospriv, UDBG1, " \n");
2410 #endif /* CSR_WIFI_HIP_NOISY */
2411 
2412  card->fh_buffer.ptr += total_length;
2413  card->fh_buffer.count += sig_chunks;
2414 
2415 #ifdef CSR_WIFI_HIP_NOISY
2416  unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n",
2417  signal_length,
2418  card->fh_buffer.ptr - card->fh_buffer.buf,
2419  card->fh_buffer.count);
2420 #endif /* CSR_WIFI_HIP_NOISY */
2421 
2422  (*processed)++;
2423  pending_sigs--;
2424  pending_chunks -= sig_chunks;
2425 
2426  /* Log the signal to the UDI. */
2427  /* UDI will get the packed structure */
2428  /* Can not log the unpacked signal, unless we reconstruct it! */
2429  if (card->udi_hook)
2430  {
2431  (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
2432  &bulkdata, UDI_LOG_FROM_HOST);
2433  }
2434 
2435  /* Remove entry from q */
2436  csptr->signal_length = 0;
2437  /* Note that the traffic queue has only one valid bulk data buffer. */
2438  csptr->bulkdata[0].data_length = 0;
2439 
2440  CSR_WIFI_HIP_Q_INC_R(&sigq[q_no]);
2441  } while ((pending_sigs > 0) && (pending_chunks > 0) && (q_no >= 0));
2442 
2443  return CSR_RESULT_SUCCESS;
2444 } /* process_fh_traffic_queue() */
2445 
2446 
2447 /*
2448  * ---------------------------------------------------------------------------
2449  * flush_fh_buffer
2450  *
2451  * Write out the cache from-hosts signals to the UniFi.
2452  *
2453  * Arguments:
2454  * card Pointer to card context struct
2455  *
2456  * Returns:
2457  * CSR error code if an SDIO error occurred.
2458  * ---------------------------------------------------------------------------
2459  */
2460 static CsrResult flush_fh_buffer(card_t *card)
2461 {
2462  CsrResult r;
2463  u16 len;
2464  u16 sig_units;
2465  u16 data_round;
2466  u16 chunks_in_last_block;
2467  u16 padding_chunks;
2468  u16 i;
2469 
2470  len = card->fh_buffer.ptr - card->fh_buffer.buf;
2471 
2472 #ifdef CSR_WIFI_HIP_NOISY
2473  unifi_error(card->ospriv, "fh_buffer is at %p, ptr= %p\n",
2474  card->fh_buffer.buf, card->fh_buffer.ptr);
2475 #endif /* CSR_WIFI_HIP_NOISY */
2476 
2477  if (len == 0)
2478  {
2479  return CSR_RESULT_SUCCESS;
2480  }
2481 
2482 #ifdef CSR_WIFI_HIP_NOISY
2483  if (dump_fh_buf)
2484  {
2485  dump(card->fh_buffer.buf, len);
2486  dump_fh_buf = 0;
2487  }
2488 #endif /* CSR_WIFI_HIP_NOISY */
2489 
2490  if (card->sdio_io_block_pad)
2491  {
2492  /* Both of these are powers of 2 */
2493  sig_units = card->config_data.sig_frag_size;
2494  data_round = card->sdio_io_block_size;
2495 
2496  if (data_round > sig_units)
2497  {
2498  chunks_in_last_block = (len % data_round) / sig_units;
2499 
2500  if (chunks_in_last_block != 0)
2501  {
2502  padding_chunks = (data_round / sig_units) - chunks_in_last_block;
2503 
2504  memset(card->fh_buffer.ptr, 0, padding_chunks * sig_units);
2505  for (i = 0; i < padding_chunks; i++)
2506  {
2507  card->fh_buffer.ptr[1] = SDIO_CMD_PADDING << 4;
2508  card->fh_buffer.ptr += sig_units;
2509  }
2510 
2511  card->fh_buffer.count += padding_chunks;
2512  len += padding_chunks * sig_units;
2513  }
2514  }
2515  }
2516 
2517  r = unifi_bulk_rw(card,
2518  card->config_data.fromhost_sigbuf_handle,
2519  card->fh_buffer.buf,
2520  len, UNIFI_SDIO_WRITE);
2522  {
2523  return r;
2524  }
2525  if (r != CSR_RESULT_SUCCESS)
2526  {
2527  unifi_error(card->ospriv, "Failed to write fh signals: %u bytes, error %d\n", len, r);
2528  return r;
2529  }
2530 
2531  /* Update from-host-signals-written signal count */
2532  card->from_host_signals_w =
2533  (card->from_host_signals_w + card->fh_buffer.count) % 128u;
2534  r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 0,
2535  (u8)card->from_host_signals_w);
2536  if (r != CSR_RESULT_SUCCESS)
2537  {
2538  unifi_error(card->ospriv, "Failed to write fh signal count %u with error %d\n",
2539  card->from_host_signals_w, r);
2540  return r;
2541  }
2542  card->generate_interrupt = 1;
2543 
2544  /* Reset the fh buffer pointer */
2545  card->fh_buffer.ptr = card->fh_buffer.buf;
2546  card->fh_buffer.count = 0;
2547 
2548 #ifdef CSR_WIFI_HIP_NOISY
2549  unifi_error(card->ospriv, "END flush: fh len %d, count %d\n",
2550  card->fh_buffer.ptr - card->fh_buffer.buf,
2551  card->fh_buffer.count);
2552 #endif /* CSR_WIFI_HIP_NOISY */
2553 
2554  return CSR_RESULT_SUCCESS;
2555 } /* flush_fh_buffer() */
2556 
2557 
2558 /*
2559  * ---------------------------------------------------------------------------
2560  * restart_packet_flow
2561  *
2562  * This function is called before the bottom-half thread sleeps.
2563  * It checks whether both data and signal resources are available and
2564  * then calls the OS-layer function to re-enable packet transmission.
2565  *
2566  * Arguments:
2567  * card Pointer to card context struct
2568  *
2569  * Returns:
2570  * None.
2571  * ---------------------------------------------------------------------------
2572  */
2573 static void restart_packet_flow(card_t *card)
2574 {
2575  u8 q;
2576 
2577  /*
2578  * We only look at the fh_traffic_queue, because that is where packets from
2579  * the network stack are placed.
2580  */
2581  for (q = 0; q <= UNIFI_TRAFFIC_Q_VO; q++)
2582  {
2583  if (card_is_tx_q_paused(card, q) &&
2584  CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[q]) >= RESUME_XMIT_THRESHOLD)
2585  {
2586 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
2587  unifi_debug_log_to_buf("U");
2588 #endif
2589  card_tx_q_unpause(card, q);
2590  unifi_restart_xmit(card->ospriv, (unifi_TrafficQueue)q);
2591  }
2592  }
2593 } /* restart_packet_flow() */
2594 
2595