1 /*
2 * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company)
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <stdlib.h>
19 #include "bus_protocols/whd_chip_reg.h"
20 #include "bus_protocols/whd_sdio.h"
21 #include "bus_protocols/whd_bus_common.h"
22 #include "bus_protocols/whd_bus_protocol_interface.h"
23 #include "whd_chip_constants.h"
24 #include "whd_cdc_bdc.h"
25 #include "whd_thread_internal.h"
26 #include "whd_buffer_api.h"
27 #include "whd_debug.h"
28 #include "whd_utils.h"
29 #include "whd_wifi_api.h"
30 #include "whd_chip.h"
31 #include "whd.h"
32 #include "whd_wlioctl.h"
33
34 /******************************************************
35 * Macros
36 ******************************************************/
37 #define SPINWAIT_POLL_PERIOD 10
38
39 #define SPINWAIT(exp, us) { \
40 uint countdown = (us) + (SPINWAIT_POLL_PERIOD - 1); \
41 while ( (exp) && (countdown >= SPINWAIT_POLL_PERIOD) ){ \
42 cy_rtos_delay_milliseconds(SPINWAIT_POLL_PERIOD); \
43 countdown -= SPINWAIT_POLL_PERIOD; \
44 } \
45 }
46 /******************************************************
47 * Constants
48 ******************************************************/
49
50 #define PLATFORM_WLAN_RAM_BASE (0x0)
51 #define WLAN_BUS_UP_ATTEMPTS (1000)
52 #define HT_AVAIL_WAIT_MS (1)
53 #define KSO_WAIT_MS (1)
54 #define KSO_WAKE_MS (3)
55 #define MAX_KSO_ATTEMPTS (64)
56 #define MAX_CAPS_BUFFER_SIZE (768)
57
58 #define AI_IOCTRL_OFFSET (0x408)
59 #define SICF_FGC (0x0002)
60 #define SICF_CLOCK_EN (0x0001)
61 #define AI_RESETCTRL_OFFSET (0x800)
62 #define AI_RESETSTATUS_OFFSET (0x804)
63 #define AIRC_RESET (1)
64 #define WRAPPER_REGISTER_OFFSET (0x100000)
65
66 #define WLAN_SHARED_VERSION_MASK (0x00ff)
67 #define WLAN_SHARED_VERSION (0x0001)
68 #define WPRINT_WHD_DEBUG_DS(args) WPRINT_WHD_DEBUG(args)
69
70 /******************************************************
71 * Structures
72 ******************************************************/
73
74 /******************************************************
75 * Variables
76 ******************************************************/
77 static const whd_fwcap_t whd_fwcap_map[] =
78 {
79 {WHD_FWCAP_SAE, "sae "},
80 {WHD_FWCAP_SAE_EXT, "sae_ext "},
81 };
82
83 /******************************************************
84 * Static Function Declarations
85 ******************************************************/
86 static whd_bool_t whd_is_fw_sr_capable(whd_driver_t whd_driver);
87 static whd_result_t whd_kso_enable(whd_driver_t whd_driver, whd_bool_t enable);
88 static uint32_t whd_get_core_address(whd_driver_t whd_driver, device_core_t core_id);
89
90 static whd_result_t whd_enable_save_restore(whd_driver_t whd_driver);
91
92 /******************************************************
93 * Function definitions
94 ******************************************************/
whd_internal_info_init(whd_driver_t whd_driver)95 whd_result_t whd_internal_info_init(whd_driver_t whd_driver)
96 {
97 whd_internal_info_t *internal_info = &whd_driver->internal_info;
98
99 internal_info->whd_wlan_status.state = WLAN_OFF;
100 internal_info->whd_wlan_status.country_code = WHD_COUNTRY_AUSTRALIA;
101 internal_info->whd_wlan_status.aggregate_code = WHD_COUNTRY_AGGREGATE_XV_0;
102 internal_info->whd_wlan_status.keep_wlan_awake = 0;
103 internal_info->console_addr = 0;
104 internal_info->scan_result_callback = NULL;
105 internal_info->whd_scan_result_ptr = NULL;
106 internal_info->active_join_mutex_initted = WHD_FALSE;
107 internal_info->active_join_semaphore = NULL;
108 internal_info->con_lastpos = 0;
109 internal_info->whd_wifi_p2p_go_is_up = WHD_FALSE;
110
111 /* Create the mutex protecting whd_log structure */
112 if (cy_rtos_init_semaphore(&whd_driver->whd_log_mutex, 1, 0) != WHD_SUCCESS)
113 {
114 return WHD_SEMAPHORE_ERROR;
115 }
116 if (cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) != WHD_SUCCESS)
117 {
118 WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) );
119 return WHD_SEMAPHORE_ERROR;
120 }
121 return WHD_SUCCESS;
122 }
123
whd_internal_info_deinit(whd_driver_t whd_driver)124 whd_result_t whd_internal_info_deinit(whd_driver_t whd_driver)
125 {
126 /* Delete the whd_log mutex */
127 (void)cy_rtos_deinit_semaphore(&whd_driver->whd_log_mutex);
128 return WHD_SUCCESS;
129 }
130
131 /*
132 * Returns the base address of the core identified by the provided coreId
133 */
whd_get_core_address(whd_driver_t whd_driver,device_core_t core_id)134 uint32_t whd_get_core_address(whd_driver_t whd_driver, device_core_t core_id)
135 {
136 if (core_id == WLAN_ARM_CORE)
137 {
138 return GET_C_VAR(whd_driver, ARM_CORE_BASE_ADDRESS);
139 }
140 else if (core_id == SOCRAM_CORE)
141 {
142 return GET_C_VAR(whd_driver, SOCSRAM_WRAPPER_BASE_ADDRESS);
143 }
144 else if (core_id == SDIOD_CORE)
145 {
146 return GET_C_VAR(whd_driver, SDIOD_CORE_BASE_ADDRESS);
147 }
148 else
149 {
150 WPRINT_WHD_ERROR( ("%s:%d Invalid core ID(%d)\n", __FUNCTION__, __LINE__, core_id) );
151 }
152
153 return WHD_BADARG;
154
155 }
156
157 /*
158 * Returns WHD_SUCCESS is the core identified by the provided coreId is up, otherwise WHD result code
159 */
whd_device_core_is_up(whd_driver_t whd_driver,device_core_t core_id)160 whd_result_t whd_device_core_is_up(whd_driver_t whd_driver, device_core_t core_id)
161 {
162 uint8_t regdata;
163 uint32_t base;
164 whd_result_t result;
165
166 base = whd_get_core_address(whd_driver, core_id);
167
168 /* Read the IO control register */
169 result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, ®data);
170 if (result != WHD_SUCCESS)
171 {
172 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
173 return result;
174 }
175
176 /* Verify that the clock is enabled and something else is not on */
177 if ( (regdata & (SICF_FGC | SICF_CLOCK_EN) ) != ( uint8_t )SICF_CLOCK_EN )
178 {
179 return WHD_CORE_CLOCK_NOT_ENABLED;
180 }
181
182 /* Read the reset control and verify it is not in reset */
183 result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ®data);
184 if (result != WHD_SUCCESS)
185 {
186 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
187 return result;
188 }
189 if ( (regdata & AIRC_RESET) != 0 )
190 {
191 return WHD_CORE_IN_RESET;
192 }
193
194 return WHD_SUCCESS;
195 }
196
197 /*
198 * Resets the core identified by the provided coreId
199 */
whd_reset_core(whd_driver_t whd_driver,device_core_t core_id,uint32_t bits,uint32_t resetbits)200 whd_result_t whd_reset_core(whd_driver_t whd_driver, device_core_t core_id, uint32_t bits, uint32_t resetbits)
201 {
202 uint32_t base = whd_get_core_address(whd_driver, core_id);
203 whd_result_t result;
204 uint8_t regdata;
205 uint32_t loop_counter = 10;
206 /* ensure there are no pending backplane operations */
207 SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1,
208 ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 );
209
210 /* put core into reset state */
211 result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ( uint32_t )AIRC_RESET);
212 (void)cy_rtos_delay_milliseconds( (uint32_t)10 ); /* Ignore return - nothing can be done if it fails */
213
214 /* ensure there are no pending backplane operations */
215 SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1,
216 ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 );
217
218 result = whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1,
219 (bits | resetbits | SICF_FGC | SICF_CLOCK_EN) );
220
221 /* ensure there are no pending backplane operations */
222 SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1,
223 ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 );
224
225 while ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1,
226 ®data) ) == WHD_SUCCESS ) && regdata != 0 &&
227 --loop_counter != 0 )
228 {
229 /* ensure there are no pending backplane operations */
230 SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1,
231 ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 );
232 /* take core out of reset */
233 result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, (uint32_t)0);
234 if (result != WHD_SUCCESS)
235 {
236 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
237 return result;
238 }
239
240 /* ensure there are no pending backplane operations */
241 SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1,
242 ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 );
243 }
244
245 result = whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, (bits | SICF_CLOCK_EN) );
246
247 (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */
248
249 if (result != WHD_SUCCESS)
250 {
251 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
252 return result;
253 }
254 return WHD_SUCCESS;
255 }
256
257 /*
258 * Disables the core identified by the provided coreId
259 */
whd_disable_device_core(whd_driver_t whd_driver,device_core_t core_id,wlan_core_flag_t core_flag)260 whd_result_t whd_disable_device_core(whd_driver_t whd_driver, device_core_t core_id, wlan_core_flag_t core_flag)
261 {
262 uint32_t base = whd_get_core_address(whd_driver, core_id);
263 whd_result_t result;
264 uint8_t junk;
265 uint8_t regdata;
266
267 /* Read the reset control */
268 result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, &junk);
269 if (result != WHD_SUCCESS)
270 {
271 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
272 return result;
273 }
274
275 /* Read the reset control and check if it is already in reset */
276 result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ®data);
277 if (result != WHD_SUCCESS)
278 {
279 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
280 return result;
281 }
282 if ( (regdata & AIRC_RESET) != 0 )
283 {
284 /* Core already in reset */
285 return WHD_SUCCESS;
286 }
287
288 /* Write 0 to the IO control and read it back */
289 result =
290 whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1,
291 (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0);
292 if (result != WHD_SUCCESS)
293 {
294 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
295 return result;
296 }
297
298 result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk);
299 if (result != WHD_SUCCESS)
300 {
301 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
302 return result;
303 }
304
305 (void)cy_rtos_delay_milliseconds( (uint32_t)1 );
306
307 result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ( uint32_t )AIRC_RESET);
308 if (result != WHD_SUCCESS)
309 {
310 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
311 return result;
312 }
313
314 (void)cy_rtos_delay_milliseconds( (uint32_t)1 );
315
316 return result;
317 }
318
319 /*
320 * Resets the core identified by the provided coreId
321 */
whd_reset_device_core(whd_driver_t whd_driver,device_core_t core_id,wlan_core_flag_t core_flag)322 whd_result_t whd_reset_device_core(whd_driver_t whd_driver, device_core_t core_id, wlan_core_flag_t core_flag)
323 {
324 uint32_t base = whd_get_core_address(whd_driver, core_id);
325 whd_result_t result;
326 uint8_t junk;
327
328 result = whd_disable_device_core(whd_driver, core_id, core_flag);
329 if (result != WHD_SUCCESS)
330 {
331 return result;
332 }
333
334 result =
335 whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1,
336 ( uint32_t )(SICF_FGC | SICF_CLOCK_EN |
337 ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) );
338 if (result != WHD_SUCCESS)
339 {
340 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
341 return result;
342 }
343
344 result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk);
345 if (result != WHD_SUCCESS)
346 {
347 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
348 return result;
349 }
350
351 result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, 0);
352 if (result != WHD_SUCCESS)
353 {
354 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
355 return result;
356 }
357
358 (void)cy_rtos_delay_milliseconds( (uint32_t)1 );
359
360 result =
361 whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1,
362 ( uint32_t )(SICF_CLOCK_EN |
363 ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) );
364 if (result != WHD_SUCCESS)
365 {
366 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
367 return result;
368 }
369
370 result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk);
371 if (result != WHD_SUCCESS)
372 {
373 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) )
374 return result;
375 }
376
377 (void)cy_rtos_delay_milliseconds( (uint32_t)1 );
378
379 return result;
380 }
381
382 /*
383 * Release ARM core to run instructions
384 */
whd_wlan_armcore_run(whd_driver_t whd_driver,device_core_t core_id,wlan_core_flag_t core_flag)385 whd_result_t whd_wlan_armcore_run(whd_driver_t whd_driver, device_core_t core_id, wlan_core_flag_t core_flag)
386 {
387 uint32_t base = whd_get_core_address(whd_driver, core_id);
388 whd_result_t result;
389 uint8_t junk;
390
391 /* Only work for WLAN arm core! */
392 if (WLAN_ARM_CORE != core_id)
393 {
394 return WHD_UNSUPPORTED;
395 }
396
397 result =
398 whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1,
399 ( uint32_t )(SICF_FGC | SICF_CLOCK_EN |
400 ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) );
401 if (result != WHD_SUCCESS)
402 {
403 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) )
404 return result;
405 }
406
407 result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk);
408 if (result != WHD_SUCCESS)
409 {
410 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) )
411 return result;
412 }
413
414 result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, 0);
415 if (result != WHD_SUCCESS)
416 {
417 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) )
418 return result;
419 }
420
421 (void)cy_rtos_delay_milliseconds( (uint32_t)1 );
422
423 result =
424 whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1,
425 ( uint32_t )(SICF_CLOCK_EN |
426 ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) );
427 if (result != WHD_SUCCESS)
428 {
429 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
430 return result;
431 }
432
433 result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk);
434 if (result != WHD_SUCCESS)
435 {
436 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
437 return result;
438 }
439
440 (void)cy_rtos_delay_milliseconds( (uint32_t)1 );
441
442 return result;
443 }
444
whd_wifi_read_wlan_log_unsafe(whd_driver_t whd_driver,uint32_t wlan_shared_address,char * buffer,uint32_t buffer_size)445 whd_result_t whd_wifi_read_wlan_log_unsafe(whd_driver_t whd_driver, uint32_t wlan_shared_address, char *buffer,
446 uint32_t buffer_size)
447 {
448 char ch;
449 uint32_t n;
450 uint32_t index;
451 uint32_t address;
452 whd_result_t result = WHD_WLAN_ERROR;
453 whd_internal_info_t *internal_info = &whd_driver->internal_info;
454 wifi_console_t *c = internal_info->c;
455
456 c = &internal_info->console;
457
458 if (internal_info->console_addr == 0)
459 {
460 uint shared_addr;
461
462 address = wlan_shared_address;
463 result = whd_bus_read_backplane_value(whd_driver, address, 4, (uint8_t *)&shared_addr);
464 if (result != WHD_SUCCESS)
465 {
466 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
467 goto done;
468 }
469
470 result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, shared_addr, sizeof(wlan_shared_t),
471 (uint8_t *)&internal_info->sh);
472 if (result != WHD_SUCCESS)
473 {
474 WPRINT_WHD_ERROR( ("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__) );
475 goto done;
476 }
477
478 internal_info->sh.flags = dtoh32(internal_info->sh.flags);
479 internal_info->sh.trap_addr = dtoh32(internal_info->sh.trap_addr);
480 internal_info->sh.assert_exp_addr = dtoh32(internal_info->sh.assert_exp_addr);
481 internal_info->sh.assert_file_addr = dtoh32(internal_info->sh.assert_file_addr);
482 internal_info->sh.assert_line = dtoh32(internal_info->sh.assert_line);
483 internal_info->sh.console_addr = dtoh32(internal_info->sh.console_addr);
484 internal_info->sh.msgtrace_addr = dtoh32(internal_info->sh.msgtrace_addr);
485
486 if ( (internal_info->sh.flags & WLAN_SHARED_VERSION_MASK) != WLAN_SHARED_VERSION )
487 {
488 WPRINT_WHD_ERROR( ("Readconsole: WLAN shared version is not valid sh.flags %x\n\r",
489 internal_info->sh.flags) );
490 result = WHD_WLAN_INVALID;
491 goto done;
492 }
493 internal_info->console_addr = internal_info->sh.console_addr;
494 }
495
496 /* Read console log struct */
497 address = internal_info->console_addr + offsetof(hnd_cons_t, log);
498 result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, sizeof(c->log), (uint8_t *)&c->log);
499 if (result != WHD_SUCCESS)
500 {
501 WPRINT_WHD_ERROR( ("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__) );
502 goto done;
503 }
504
505 /* Allocate console buffer (one time only) */
506 if (c->buf == NULL)
507 {
508 c->bufsize = dtoh32(c->log.buf_size);
509 c->buf = whd_mem_malloc(c->bufsize);
510 if (c->buf == NULL)
511 {
512 WPRINT_WHD_ERROR( ("%s:%d c->buf IS null \n", __FUNCTION__, __LINE__) );
513 result = WHD_WLAN_NOMEM;
514 goto done;
515 }
516 }
517
518 /* Retrieve last read position */
519 c->last = whd_driver->internal_info.con_lastpos;
520
521 index = dtoh32(c->log.idx);
522
523 /* Protect against corrupt value */
524 if (index > c->bufsize)
525 {
526 WPRINT_WHD_ERROR( ("%s:%d index > c->bufsize \n", __FUNCTION__, __LINE__) );
527 result = WHD_WLAN_BUFTOOSHORT;
528 goto done;
529 }
530
531 /* Skip reading the console buffer if the index pointer has not moved */
532 if (index == c->last)
533 {
534 result = WHD_SUCCESS;
535 goto done;
536 }
537
538 /* Read the console buffer */
539 /* xxx this could optimize and read only the portion of the buffer needed, but
540 * it would also have to handle wrap-around.
541 */
542 address = dtoh32(c->log.buf);
543 result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, c->bufsize, (uint8_t *)c->buf);
544 if (result != WHD_SUCCESS)
545 {
546 WPRINT_WHD_ERROR( ("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__) );
547 goto done;
548 }
549
550 while (c->last != index)
551 {
552 for (n = 0; n < buffer_size - 2; n++)
553 {
554 if (c->last == index)
555 {
556 /* This would output a partial line. Instead, back up
557 * the buffer pointer and output this line next time around.
558 */
559 if (c->last >= n)
560 {
561 c->last -= n;
562 }
563 else
564 {
565 c->last = c->bufsize - n;
566 }
567 /* Save last read position */
568 whd_driver->internal_info.con_lastpos = c->last;
569
570 result = WHD_SUCCESS;
571 goto done;
572 }
573 ch = c->buf[c->last];
574 c->last = (c->last + 1) % c->bufsize;
575 if (ch == '\n')
576 {
577 break;
578 }
579 buffer[n] = ch;
580 }
581 if (n > 0)
582 {
583 if (buffer[n - 1] == '\r')
584 n--;
585 buffer[n] = 0;
586 WPRINT_MACRO( ("CONSOLE: %s\n", buffer) );
587 }
588 }
589 /* Save last read position */
590 whd_driver->internal_info.con_lastpos = c->last;
591 result = WHD_SUCCESS;
592
593 done: return result;
594 }
595
whd_wifi_peek(whd_driver_t whd_driver,uint32_t address,uint8_t register_length,uint8_t * value)596 void whd_wifi_peek(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, uint8_t *value)
597 {
598 uint8_t status;
599
600 WHD_WLAN_KEEP_AWAKE(whd_driver);
601
602 status = whd_bus_read_backplane_value(whd_driver, address, register_length, value);
603
604 if (status != WHD_SUCCESS)
605 {
606 WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) );
607 }
608
609 WHD_WLAN_LET_SLEEP(whd_driver);
610 }
611
whd_wifi_poke(whd_driver_t whd_driver,uint32_t address,uint8_t register_length,uint32_t value)612 void whd_wifi_poke(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, uint32_t value)
613 {
614 uint8_t status;
615
616 WHD_WLAN_KEEP_AWAKE(whd_driver);
617
618 status = whd_bus_write_backplane_value(whd_driver, address, register_length, value);
619
620 if (status != WHD_SUCCESS)
621 {
622 WPRINT_WHD_ERROR( ("%s: Error clearing the interrupt status\n", __FUNCTION__) );
623 }
624
625 WHD_WLAN_LET_SLEEP(whd_driver);
626 }
627
whd_ioctl_log_add(whd_driver_t whd_driver,uint32_t cmd,whd_buffer_t buffer)628 whd_result_t whd_ioctl_log_add(whd_driver_t whd_driver, uint32_t cmd, whd_buffer_t buffer)
629 {
630 uint8_t *data = NULL;
631 size_t data_size = whd_buffer_get_current_piece_size(whd_driver, buffer);
632
633 data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer);
634 CHECK_IOCTL_BUFFER(data);
635 CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->whd_log_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) );
636 data = data + IOCTL_OFFSET;
637 data_size = data_size - IOCTL_OFFSET;
638 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].ioct_log = cmd;
639 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].is_this_event = 0;
640 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data_size = MIN_OF(
641 WHD_MAX_DATA_SIZE, data_size);
642 memset(whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data, 0,
643 WHD_MAX_DATA_SIZE);
644 memcpy(whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data, data,
645 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data_size);
646
647 whd_driver->whd_ioctl_log_index++;
648 CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) );
649 return WHD_SUCCESS;
650 }
651
whd_ioctl_log_add_event(whd_driver_t whd_driver,uint32_t cmd,uint16_t flag,uint32_t reason)652 whd_result_t whd_ioctl_log_add_event(whd_driver_t whd_driver, uint32_t cmd, uint16_t flag, uint32_t reason)
653 {
654 CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->whd_log_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) );
655 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].is_this_event = 1;
656 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].ioct_log = cmd;
657 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].flag = flag;
658 whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].reason = reason;
659
660 whd_driver->whd_ioctl_log_index++;
661 CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) );
662 return WHD_SUCCESS;
663 }
664
whd_ioctl_print(whd_driver_t whd_driver)665 whd_result_t whd_ioctl_print(whd_driver_t whd_driver)
666 {
667 int i;
668 uint8_t *data = NULL;
669 size_t iovar_string_size = 0;
670
671 CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->whd_log_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) );
672 for (i = 0; i < WHD_IOCTL_LOG_SIZE; i++)
673 {
674 char iovar[WHD_IOVAR_STRING_SIZE] = {0};
675 data = whd_driver->whd_ioctl_log[i].data;
676
677 if ( (whd_driver->whd_ioctl_log[i].ioct_log == WLC_SET_VAR) ||
678 (whd_driver->whd_ioctl_log[i].ioct_log == WLC_GET_VAR) )
679 {
680 /* refer to whd_cdc_get_iovar_buffer() */
681 while (!*data)
682 {
683 whd_driver->whd_ioctl_log[i].data_size--;
684 data++;
685 }
686
687 if (strlen( (char *)data ) <= WHD_IOVAR_STRING_SIZE)
688 strncpy(iovar, (char *)data, strlen( (char *)data ) );
689
690 iovar_string_size = strlen( (const char *)data );
691 iovar[iovar_string_size] = '\0';
692 data += (iovar_string_size + 1);
693 whd_driver->whd_ioctl_log[i].data_size -= (iovar_string_size + 1);
694 }
695 if (whd_driver->whd_ioctl_log[i].is_this_event == 1)
696 {
697 whd_event_info_to_string(whd_driver->whd_ioctl_log[i].ioct_log, whd_driver->whd_ioctl_log[i].flag,
698 whd_driver->whd_ioctl_log[i].reason, iovar, sizeof(iovar) - 1);
699 WPRINT_MACRO( ("\n<- E:%" PRIu32 "\t\t\tS:%d\t\t\t\tR:%" PRIu32 "\n%s\n",
700 whd_driver->whd_ioctl_log[i].ioct_log,
701 whd_driver->whd_ioctl_log[i].flag, whd_driver->whd_ioctl_log[i].reason, iovar) );
702 }
703 else if (whd_driver->whd_ioctl_log[i].ioct_log == WLC_SET_VAR)
704 {
705 WPRINT_MACRO( ("\n-> %s\n", iovar) );
706 whd_hexdump(data, whd_driver->whd_ioctl_log[i].data_size);
707 }
708 else if (whd_driver->whd_ioctl_log[i].ioct_log == WLC_GET_VAR)
709 {
710 WPRINT_MACRO( ("\n<- %s\n", iovar) );
711 whd_hexdump(data, whd_driver->whd_ioctl_log[i].data_size);
712 }
713 else if (whd_driver->whd_ioctl_log[i].ioct_log != 0)
714 {
715 whd_ioctl_info_to_string(whd_driver->whd_ioctl_log[i].ioct_log, iovar, sizeof(iovar) - 1);
716 WPRINT_MACRO( ("\n%s:%" PRIu32 "\n", iovar, whd_driver->whd_ioctl_log[i].ioct_log) );
717 whd_hexdump(data, whd_driver->whd_ioctl_log[i].data_size);
718 }
719 }
720
721 memset(whd_driver->whd_ioctl_log, 0, sizeof(whd_driver->whd_ioctl_log) );
722 whd_driver->whd_ioctl_log_index = 0;
723 CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) );
724 return WHD_SUCCESS;
725 }
726
whd_wifi_chip_info_init(whd_driver_t whd_driver)727 void whd_wifi_chip_info_init(whd_driver_t whd_driver)
728 {
729 whd_driver->chip_info.save_restore_enable = WHD_FALSE;
730 }
731
whd_wifi_set_custom_country_code(whd_interface_t ifp,const whd_country_info_t * country_code)732 whd_result_t whd_wifi_set_custom_country_code(whd_interface_t ifp, const whd_country_info_t *country_code)
733 {
734 whd_driver_t whd_driver = ifp->whd_driver;
735
736 /* Get chip number */
737 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
738 if (wlan_chip_id == 43362)
739 {
740 whd_buffer_t buffer;
741 whd_result_t result;
742 whd_country_info_t *data;
743 data = (whd_country_info_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer,
744 (uint16_t)sizeof(whd_country_info_t) + 10);
745 if (data == NULL)
746 {
747 whd_assert("Could not get buffer for IOCTL", 0 != 0);
748 return WHD_BUFFER_ALLOC_FAIL;
749 }
750 memcpy(data, country_code, sizeof(whd_country_info_t) );
751 result = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_CUSTOM_COUNTRY, buffer, NULL);
752 return result;
753 }
754 else
755 {
756 UNUSED_PARAMETER(country_code);
757 return WHD_UNSUPPORTED;
758 }
759 }
760
whd_chip_specific_socsram_init(whd_driver_t whd_driver)761 whd_result_t whd_chip_specific_socsram_init(whd_driver_t whd_driver)
762 {
763 /* Get chip number */
764 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
765 if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) )
766 {
767 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SOCSRAM_BANKX_INDEX(whd_driver), 4, 0x3) );
768 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SOCSRAM_BANKX_PDA(whd_driver), 4, 0) );
769 return WHD_SUCCESS;
770 }
771 else
772 {
773 return WHD_SUCCESS;
774 }
775 }
776
whd_chip_specific_init(whd_driver_t whd_driver)777 whd_result_t whd_chip_specific_init(whd_driver_t whd_driver)
778 {
779 /* Get chip number */
780 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
781 if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43362) )
782 {
783 return WHD_SUCCESS;
784 }
785 else
786 {
787 return whd_enable_save_restore(whd_driver);
788 }
789 }
790
whd_allow_wlan_bus_to_sleep(whd_driver_t whd_driver)791 whd_result_t whd_allow_wlan_bus_to_sleep(whd_driver_t whd_driver)
792 {
793 /* Get chip number */
794 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
795 whd_bt_dev_t btdev = whd_driver->bt_dev;
796 if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43362) )
797 {
798 /* Clear HT clock request */
799 if (whd_bus_is_up(whd_driver) == WHD_TRUE)
800 {
801 whd_bus_set_state(whd_driver, WHD_FALSE);
802 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
803 (uint8_t)1, 0) );
804 /* Bus specific sleep routine */
805 return whd_bus_sleep(whd_driver);
806 }
807 else
808 {
809 return WHD_SUCCESS;
810 }
811 }
812 else
813 {
814 /* Clear HT clock request */
815 if (whd_bus_is_up(whd_driver) == WHD_TRUE)
816 {
817 whd_bus_set_state(whd_driver, WHD_FALSE);
818 if (whd_driver->chip_info.save_restore_enable == WHD_FALSE)
819 {
820 return whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
821 (uint8_t)1, 0);
822 }
823 else
824 {
825 if (btdev && btdev->bt_int_cb)
826 {
827 return WHD_SUCCESS;
828 }
829 return whd_kso_enable(whd_driver, WHD_FALSE);
830 }
831 }
832 else
833 {
834 return WHD_SUCCESS;
835 }
836 }
837 }
838
whd_wifi_read_wlan_log(whd_driver_t whd_driver,char * buffer,uint32_t buffer_size)839 whd_result_t whd_wifi_read_wlan_log(whd_driver_t whd_driver, char *buffer, uint32_t buffer_size)
840 {
841 whd_result_t result;
842 uint32_t wlan_shared_address;
843 uint16_t wlan_chip_id = 0;
844
845 CHECK_DRIVER_NULL(whd_driver);
846
847 WHD_IOCTL_PRINT(whd_driver);
848
849 wlan_chip_id = whd_chip_get_chip_id(whd_driver);
850 if (wlan_chip_id == 43362)
851 {
852 return whd_wifi_read_wlan_log_unsafe(whd_driver, ( (GET_C_VAR(whd_driver, CHIP_RAM_SIZE) +
853 PLATFORM_WLAN_RAM_BASE) - 4 ), buffer, buffer_size);
854 }
855 else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) )
856 {
857 result = whd_ensure_wlan_bus_is_up(whd_driver);
858 if (result != WHD_SUCCESS)
859 {
860 return result;
861 }
862 result = whd_wifi_read_wlan_log_unsafe(whd_driver, ( (GET_C_VAR(whd_driver, CHIP_RAM_SIZE) +
863 GET_C_VAR(whd_driver,
864 ATCM_RAM_BASE_ADDRESS) ) - 4 ), buffer,
865 buffer_size);
866 whd_thread_notify(whd_driver);
867 return result;
868 }
869 else if ( (wlan_chip_id == 4334) || (wlan_chip_id == 4390) )
870 {
871 return WHD_UNSUPPORTED;
872 }
873 else
874 {
875 /* Backplane access needs HT clock. So, disabling bus sleep */
876 WHD_WLAN_KEEP_AWAKE(whd_driver);
877 /* FW populates the last word of RAM with wlan_shared_t struct address */
878 wlan_shared_address = PLATFORM_WLAN_RAM_BASE + GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) +
879 GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4;
880 if (!GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) && (whd_is_fw_sr_capable(whd_driver) == WHD_TRUE) )
881 {
882 wlan_shared_address -= GET_C_VAR(whd_driver, SOCRAM_SRMEM_SIZE);
883 }
884 result = whd_wifi_read_wlan_log_unsafe(whd_driver, wlan_shared_address, buffer, buffer_size);
885 WHD_WLAN_LET_SLEEP(whd_driver);
886 return result;
887 }
888
889 }
890
whd_wifi_print_whd_log(whd_driver_t whd_driver)891 uint32_t whd_wifi_print_whd_log(whd_driver_t whd_driver)
892 {
893 whd_result_t result;
894 char *buffer = NULL;
895
896 CHECK_DRIVER_NULL(whd_driver);
897
898 WHD_IOCTL_PRINT(whd_driver);
899
900 if ( (buffer = whd_mem_malloc(WLAN_LOG_BUF_LEN) ) == NULL )
901 {
902 WPRINT_WHD_ERROR( ("Memory allocation failed for log buffer in %s \n", __FUNCTION__) );
903 return WHD_MALLOC_FAILURE;
904 }
905
906 result = whd_wifi_read_wlan_log(whd_driver, buffer, WLAN_LOG_BUF_LEN);
907 if (result == WHD_SUCCESS)
908 {
909 whd_print_logbuffer(); // This is not supported yet.
910 }
911 whd_mem_free(buffer);
912 CHECK_RETURN(result);
913 return result;
914 }
915
whd_wifi_read_fw_capabilities(whd_interface_t ifp)916 whd_result_t whd_wifi_read_fw_capabilities(whd_interface_t ifp)
917 {
918 whd_result_t result;
919 char caps[MAX_CAPS_BUFFER_SIZE];
920 whd_fwcap_id_t id;
921
922 CHECK_IFP_NULL(ifp);
923 whd_driver_t whd_driver = ifp->whd_driver;
924
925 result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_CAP, (uint8_t *)caps, sizeof(caps) );
926 CHECK_RETURN(result);
927
928 for (uint32_t i = 0; i < ARRAY_SIZE(whd_fwcap_map); i++)
929 {
930 if (strstr(caps, whd_fwcap_map[i].fwcap_name) )
931 {
932 id = whd_fwcap_map[i].feature;
933 WPRINT_WHD_DEBUG( ("Enabling FW Capabilities: %s\n", whd_fwcap_map[i].fwcap_name) );
934 whd_driver->chip_info.fwcap_flags |= (1 << id);
935 }
936 }
937 return WHD_SUCCESS;
938 }
939
whd_ensure_wlan_bus_is_up(whd_driver_t whd_driver)940 whd_result_t whd_ensure_wlan_bus_is_up(whd_driver_t whd_driver)
941 {
942 uint8_t csr = 0;
943 uint32_t attempts = ( uint32_t )WLAN_BUS_UP_ATTEMPTS;
944 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
945
946 /* Ensure HT clock is up */
947 if (whd_bus_is_up(whd_driver) == WHD_TRUE)
948 {
949 return WHD_SUCCESS;
950 }
951
952 if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) )
953 {
954 /* Bus specific wakeup routine */
955 CHECK_RETURN(whd_bus_wakeup(whd_driver) );
956 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
957 (uint8_t)1, (uint32_t)SBSDIO_HT_AVAIL_REQ) );
958 do
959 {
960 CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
961 (uint8_t)1, &csr) );
962 --attempts;
963 } while ( ( (csr & SBSDIO_HT_AVAIL) == 0 ) && (attempts != 0) &&
964 (cy_rtos_delay_milliseconds( (uint32_t)1 ), 1 == 1) );
965
966 if (attempts == 0)
967 {
968 WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) );
969 return WHD_SDIO_BUS_UP_FAIL;
970 }
971 else
972 {
973 whd_bus_set_state(whd_driver, WHD_TRUE);
974 return WHD_SUCCESS;
975 }
976 }
977 else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) )
978 {
979 //To-Do
980 /* M2M power save mode */
981 //M2M_POWERSAVE_COMM_TX_BEGIN
982 return WHD_SUCCESS;
983 }
984 else
985 {
986 if (whd_driver->chip_info.save_restore_enable == WHD_FALSE)
987 {
988 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
989 (uint8_t)1, (uint32_t)SBSDIO_HT_AVAIL_REQ) );
990 do
991 {
992 CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
993 (uint8_t)sizeof(csr), &csr) );
994 --attempts;
995 } while ( ( (csr & SBSDIO_HT_AVAIL) == 0 ) && (attempts != 0) &&
996 (cy_rtos_delay_milliseconds( ( uint32_t )HT_AVAIL_WAIT_MS ), 1 == 1) );
997
998 if (attempts == 0)
999 {
1000 WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) );
1001 return WHD_SDIO_BUS_UP_FAIL;
1002 }
1003 else
1004 {
1005 whd_bus_set_state(whd_driver, WHD_TRUE);
1006 return WHD_SUCCESS;
1007 }
1008 }
1009 else
1010 {
1011 if (whd_kso_enable(whd_driver, WHD_TRUE) == WHD_SUCCESS)
1012 {
1013 whd_bus_set_state(whd_driver, WHD_TRUE);
1014 return WHD_SUCCESS;
1015 }
1016 else
1017 {
1018 WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) );
1019 return WHD_SDIO_BUS_UP_FAIL;
1020 }
1021 }
1022 }
1023 }
1024
whd_is_fw_sr_capable(whd_driver_t whd_driver)1025 static whd_bool_t whd_is_fw_sr_capable(whd_driver_t whd_driver)
1026 {
1027 uint32_t core_capext;
1028 uint32_t retention_ctl = 0;
1029 uint32_t srctrl = 0;
1030 whd_bool_t save_restore_capable = WHD_FALSE;
1031 whd_result_t result = WHD_SUCCESS;
1032
1033 /* Get chip number */
1034 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
1035
1036 if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) )
1037 {
1038 /* check if fw initialized sr engine */
1039 if (whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_SR_CONTROL1, (uint8_t)4,
1040 (uint8_t *)&srctrl) != WHD_SUCCESS)
1041 {
1042 return WHD_FALSE;
1043 }
1044 if (srctrl != 0)
1045 {
1046 return WHD_TRUE;
1047 }
1048 else
1049 {
1050 return WHD_FALSE;
1051 }
1052 }
1053 else if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) )
1054 {
1055 /* check if fw initialized sr engine */
1056 result = whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_CORE_CAPEXT_ADDR, (uint8_t)4,
1057 (uint8_t *)&core_capext);
1058 if (result != WHD_SUCCESS)
1059 {
1060 return WHD_FALSE;
1061 }
1062
1063 if ( (core_capext & CHIPCOMMON_CORE_CAPEXT_SR_SUPPORTED) != 0 )
1064 {
1065 result = whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_CORE_RETENTION_CTL, (uint8_t)4,
1066 (uint8_t *)&retention_ctl);
1067 if (result != WHD_SUCCESS)
1068 {
1069 return WHD_FALSE;
1070 }
1071 if ( (retention_ctl & (CHIPCOMMON_CORE_RCTL_MACPHY_DISABLE | CHIPCOMMON_CORE_RCTL_LOGIC_DISABLE) ) == 0 )
1072 {
1073 save_restore_capable = WHD_TRUE;
1074 }
1075 }
1076 return save_restore_capable;
1077 }
1078 else
1079 {
1080 /* check if fw initialized sr engine */
1081 result =
1082 whd_bus_read_backplane_value(whd_driver, (uint32_t)RETENTION_CTL(
1083 whd_driver), (uint8_t)sizeof(retention_ctl),
1084 (uint8_t *)&retention_ctl);
1085 if (result != WHD_SUCCESS)
1086 {
1087 return WHD_FALSE;
1088 }
1089 if ( (retention_ctl & (RCTL_MACPHY_DISABLE | RCTL_LOGIC_DISABLE) ) == 0 )
1090 {
1091 save_restore_capable = WHD_TRUE;
1092 }
1093 return save_restore_capable;
1094 }
1095 }
1096
whd_enable_save_restore(whd_driver_t whd_driver)1097 static whd_result_t whd_enable_save_restore(whd_driver_t whd_driver)
1098 {
1099 uint8_t data;
1100 /* Get chip number */
1101 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
1102
1103 if (whd_is_fw_sr_capable(whd_driver) == WHD_TRUE)
1104 {
1105 if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) )
1106 {
1107 /* Configure WakeupCtrl register to set AlpAvail request bit in chipClockCSR register
1108 * after the sdiod core is powered on.
1109 */
1110 CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL,
1111 (uint8_t)sizeof(data), &data) );
1112 data |= SBSDIO_WCTRL_WAKE_TILL_ALP_AVAIL;
1113 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL,
1114 (uint8_t)sizeof(data), data) );
1115 }
1116 else
1117 {
1118 /* Configure WakeupCtrl register to set HtAvail request bit in chipClockCSR register
1119 * after the sdiod core is powered on.
1120 */
1121 CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL,
1122 (uint8_t)1, &data) );
1123 data |= SBSDIO_WCTRL_WAKE_TILL_HT_AVAIL;
1124 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL,
1125 (uint8_t)1, data) );
1126 }
1127
1128 /* Set brcmCardCapability to noCmdDecode mode.
1129 * It makes sdiod_aos to wakeup host for any activity of cmd line, even though
1130 * module won't decode cmd or respond
1131 */
1132 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, (uint32_t)SDIOD_CCCR_BRCM_CARDCAP,
1133 (uint8_t)1, SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC) );
1134 if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) )
1135 {
1136 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
1137 (uint8_t)1, SBSDIO_HT_AVAIL_REQ) );
1138 }
1139 else
1140 {
1141 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR,
1142 (uint8_t)1, (uint32_t)SBSDIO_FORCE_HT) );
1143 }
1144
1145 /* Enable KeepSdioOn (KSO) bit for normal operation */
1146 if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) )
1147 {
1148 CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1149 (uint8_t)sizeof(data), &data) );
1150 }
1151 else
1152 {
1153 CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1154 (uint8_t)1, &data) );
1155 }
1156 if ( (data & SBSDIO_SLPCSR_KEEP_SDIO_ON) == 0 )
1157 {
1158 data |= SBSDIO_SLPCSR_KEEP_SDIO_ON;
1159 if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) )
1160 {
1161 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1162 (uint8_t)sizeof(data), data) );
1163 }
1164 else
1165 {
1166 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1167 (uint8_t)1, data) );
1168 }
1169 }
1170
1171 /* SPI bus can be configured for sleep by default.
1172 * KSO bit solely controls the wlan chip sleep
1173 */
1174 CHECK_RETURN(whd_bus_sleep(whd_driver) );
1175
1176 /* Put SPI interface block to sleep */
1177 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0xf) );
1178
1179 whd_driver->chip_info.save_restore_enable = WHD_TRUE;
1180 }
1181 else
1182 {
1183 whd_driver->chip_info.save_restore_enable = WHD_FALSE;
1184 }
1185
1186 return WHD_SUCCESS;
1187 }
1188
whd_kso_enable(whd_driver_t whd_driver,whd_bool_t enable)1189 static whd_result_t whd_kso_enable(whd_driver_t whd_driver, whd_bool_t enable)
1190 {
1191 uint8_t write_value = 0;
1192 uint8_t read_value = 0;
1193 uint8_t compare_value;
1194 uint8_t bmask;
1195 uint32_t attempts = ( uint32_t )MAX_KSO_ATTEMPTS;
1196 whd_result_t result;
1197 /* Get chip number */
1198
1199 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
1200 if (enable == WHD_TRUE)
1201 {
1202 write_value |= SBSDIO_SLPCSR_KEEP_SDIO_ON;
1203 }
1204
1205 /* 1st KSO write goes to AOS wake up core if device is asleep */
1206 /* Possibly device might not respond to this cmd. So, don't check return value here */
1207 if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) )
1208 {
1209 /* 2 Sequential writes to KSO bit are required for SR module to wakeup, both write can fail */
1210 CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1211 (uint8_t)1,
1212 write_value) );
1213 CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1214 (uint8_t)1,
1215 write_value) );
1216 if (enable == WHD_TRUE)
1217 {
1218 /* device WAKEUP through KSO:
1219 * write bit 0 & read back until
1220 * both bits 0(kso bit) & 1 (dev on status) are set
1221 */
1222 compare_value = SBSDIO_SLPCSR_KEEP_SDIO_ON | SBSDIO_SLPCSR_DEVICE_ON;
1223 bmask = compare_value;
1224 }
1225 else
1226 {
1227 /* Put device to sleep, turn off KSO */
1228 compare_value = 0;
1229 /* Check for bit0 only, bit1(devon status) may not get cleared right away */
1230 bmask = SBSDIO_SLPCSR_KEEP_SDIO_ON;
1231 }
1232 }
1233 else
1234 {
1235 CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1236 (uint8_t)1, write_value) );
1237
1238 /* In case of 43012 chip, the chip could go down immediately after KSO bit is cleared.
1239 * So the further reads of KSO register could fail. Thereby just bailing out immediately
1240 * after clearing KSO bit, to avoid polling of KSO bit.
1241 */
1242 if (enable == WHD_FALSE)
1243 {
1244 return WHD_SUCCESS;
1245 }
1246
1247 /* 2 Sequential writes to KSO bit are required for SR module to wakeup */
1248 CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1249 (uint8_t)1, write_value) );
1250
1251 /* device WAKEUP through KSO:
1252 * write bit 0 & read back until
1253 * both bits 0(kso bit) & 1 (dev on status) are set
1254 */
1255 compare_value = SBSDIO_SLPCSR_KEEP_SDIO_ON | SBSDIO_SLPCSR_DEVICE_ON;
1256 bmask = compare_value;
1257 }
1258
1259 while (attempts != 0)
1260 {
1261 /* Reliable KSO bit set/clr:
1262 * Sdiod sleep write access appears to be in sync with PMU 32khz clk
1263 * just one write attempt may fail,(same is with read ?)
1264 * in any case, read it back until it matches written value
1265 */
1266 result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, (uint8_t)1,
1267 &read_value);
1268 if ( ( (read_value & bmask) == compare_value ) && (result == WHD_SUCCESS) && (read_value != 0xFF) )
1269 {
1270 break;
1271 }
1272
1273 cy_rtos_delay_milliseconds( ( uint32_t )KSO_WAIT_MS );
1274
1275 CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR,
1276 (uint8_t)1, write_value) );
1277 attempts--;
1278 }
1279
1280 if (attempts == 0)
1281 {
1282 WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) );
1283 return WHD_SDIO_BUS_UP_FAIL;
1284 }
1285 else
1286 {
1287 return WHD_SUCCESS;
1288 }
1289 }
1290
1291 void whd_wlan_wake_from_host(whd_driver_t whd_driver);
1292
whd_wlan_wake_from_host(whd_driver_t whd_driver)1293 void whd_wlan_wake_from_host(whd_driver_t whd_driver)
1294 {
1295 uint32_t val32 = 0;
1296 whd_result_t result;
1297
1298 result = whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, (uint8_t *)&val32);
1299 if (result != WHD_SUCCESS)
1300 {
1301 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) );
1302 }
1303 WPRINT_WHD_DEBUG( ("%s: %d:before: maccontrol: 0x%08x\n", __FUNCTION__, __LINE__, (unsigned int)val32) );
1304
1305 val32 = val32 | D11_MACCONTROL_REG_WAKE;
1306 result = whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, val32);
1307 if (result != WHD_SUCCESS)
1308 {
1309 WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) );
1310 }
1311 result = whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, (uint8_t *)&val32);
1312 if (result != WHD_SUCCESS)
1313 {
1314 WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) )
1315 }
1316 WPRINT_WHD_DEBUG( ("%s: %d:after: maccontrol: 0x%08x\n", __FUNCTION__, __LINE__, (unsigned int)val32) );
1317 }
1318
whd_wlan_bus_complete_ds_wake(whd_driver_t whd_driver,whd_bool_t wake_from_firmware,uint32_t wake_event_indication_addr,uint32_t wake_indication_addr,uint32_t sdio_control_addr)1319 whd_result_t whd_wlan_bus_complete_ds_wake(whd_driver_t whd_driver, whd_bool_t wake_from_firmware,
1320 uint32_t wake_event_indication_addr, uint32_t wake_indication_addr,
1321 uint32_t sdio_control_addr)
1322 {
1323 uint32_t val = 0;
1324 uint32_t val1 = 0;
1325 uint32_t count = 0;
1326 int32_t timeout = 0;
1327 /* Get chip number */
1328
1329 uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver);
1330
1331 if (wlan_chip_id == 43012)
1332 {
1333 WPRINT_WHD_DEBUG_DS( ("%s: enter: wake_fr_fw=%d\n", __func__, (int )wake_from_firmware) );
1334
1335 /* Need to do for all wake causes */
1336 while (WHD_SUCCESS !=
1337 whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, SDIO_FUNC_ENABLE_1) )
1338 {
1339 WPRINT_WHD_DEBUG( ("Retry IOEN write\n") );
1340 cy_rtos_delay_milliseconds(10);
1341 }
1342
1343 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(wake_event_indication_addr), 2,
1344 (uint8_t *)&val) );
1345 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(wake_indication_addr), 2, (uint8_t *)&val) );
1346
1347 if (WHD_TRUE == wake_from_firmware)
1348 {
1349 WPRINT_WHD_DEBUG_DS( ("%s: CCCR written\n", __func__) );
1350
1351 /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX
1352 * For RX Cases , Value will be DS1_SLEEP
1353 * For TX Cases, Value will be MAC ON or RADIO_PHY_ON
1354 */
1355 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2,
1356 (uint8_t *)&val) );
1357 if (val == DS1_SLEEP)
1358 {
1359 /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases
1360 * Simply update PMU Resource Mask and Re-download firmware for this case
1361 */
1362 WPRINT_WHD_DEBUG_DS( ("%s: D11 wake detected\n", __func__) );
1363
1364 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1,
1365 DEFAULT_43012_MIN_RES_MASK) );
1366
1367 return WHD_SUCCESS;
1368 }
1369
1370 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2,
1371 C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) );
1372 WPRINT_WHD_DEBUG_DS( ("%s: SDIO ctl written\n", __func__) );
1373
1374 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2,
1375 (uint8_t *)&val) );
1376 WPRINT_WHD_DEBUG_DS( ("%s: M_DS1_CTRL_SDIO = [%x]\n", __func__, (int )val) );
1377
1378 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) );
1379 WPRINT_WHD_DEBUG_DS( ("%s: before setting wake = [%x]\n", __func__, (int )val1) );
1380
1381 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2,
1382 val1 | D11_MACCONTROL_REG_WAKE) );
1383 WPRINT_WHD_DEBUG_DS( ("%s: After setting wake= [%x]\n", __func__, (int )val1) );
1384
1385 while (!(val & C_DS1_CTRL_PROC_DONE) )
1386 {
1387 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2,
1388 (uint8_t *)&val) );
1389 count++;
1390 if (count == 1000)
1391 {
1392 WPRINT_WHD_ERROR( ("%s: sdio timed out! Aborting\n", __func__) );
1393 return WHD_TIMEOUT;
1394 }
1395 }
1396
1397 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2,
1398 (uint8_t *)&val) );
1399 WPRINT_WHD_DEBUG_DS( ("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __func__, (int )val) );
1400
1401 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) );
1402 WPRINT_WHD_DEBUG_DS( ("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __func__, (int )val1) );
1403
1404 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2,
1405 val1 & D11_MACCONTROL_CLEAR_WAKE) );
1406 WPRINT_WHD_DEBUG_DS( ("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __func__, (int )val1) );
1407
1408 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK) );
1409 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)1, (uint8_t *)&val1) );
1410
1411 WPRINT_WHD_DEBUG_DS( ("%s: PMU_MINRESMASK = [%x]\n", __func__, (int )val1) );
1412 }
1413 else
1414 {
1415 while (WHD_SUCCESS != whd_ensure_wlan_bus_is_up(whd_driver) )
1416 {
1417 WPRINT_WHD_DEBUG_DS( ("Retrying bus is up\n") );
1418 }
1419
1420 WPRINT_WHD_DEBUG_DS( ("write backplane\n") );
1421
1422 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, (uint8_t *)&val) );
1423
1424 while (WHD_SUCCESS !=
1425 whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2,
1426 val | C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) )
1427 {
1428 WPRINT_WHD_DEBUG_DS( ("Retrying backplane write; addr=%x\n",
1429 (unsigned int )D11SHM_ADDR(sdio_control_addr) ) );
1430 cy_rtos_delay_milliseconds(100);
1431 }
1432
1433 WPRINT_WHD_DEBUG_DS( ("wake host\n") );
1434 whd_wlan_wake_from_host(whd_driver);
1435
1436 WPRINT_WHD_DEBUG_DS( ("poll for timeout\n") );
1437 /* Poll for PROC_DONE to be set by ucode; timeout after a good amount of time */
1438 for (timeout = WHD_WLAN_WAKE_TIMEOUT * 10, val = 0; timeout >= 0;
1439 timeout -= WHD_SHARED_MEMORY_POLLING_DELAY)
1440 {
1441 whd_result_t read_result =
1442 whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, (uint8_t *)&val);
1443
1444 if ( (WHD_SUCCESS != read_result) || !( (val) & C_DS1_CTRL_PROC_DONE ) )
1445 {
1446 cy_rtos_delay_milliseconds (WHD_SHARED_MEMORY_POLLING_DELAY);
1447 }
1448 else
1449 {
1450 /* success! */
1451 WPRINT_WHD_DEBUG_DS( ("Ucode has posted DONE\n") );
1452 break;
1453 }
1454 }
1455
1456 WPRINT_WHD_DEBUG_DS( ("%s: %d: 0x%08x\n", __func__, __LINE__, (unsigned int)val) );
1457
1458 if ( (timeout < 0) && !(val & C_DS1_CTRL_PROC_DONE) )
1459 {
1460 WPRINT_WHD_ERROR( ("%s: Failed to enter DS1 Exit state!\n", __func__) );
1461 return WHD_TIMEOUT;
1462 }
1463 }
1464 WPRINT_WHD_DEBUG_DS( ("successfully completed DS wake sequence\n") );
1465 return WHD_SUCCESS;
1466 }
1467 else
1468 {
1469 UNUSED_PARAMETER(wake_from_firmware);
1470 UNUSED_PARAMETER(wake_event_indication_addr);
1471 UNUSED_PARAMETER(wake_indication_addr);
1472 UNUSED_PARAMETER(sdio_control_addr);
1473
1474 WPRINT_WHD_DEBUG( ("%s: enter\n", __FUNCTION__) );
1475
1476 CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1,
1477 SDIO_FUNC_ENABLE_1) );
1478 WPRINT_WHD_DEBUG( ("%s: CCCR written\n", __FUNCTION__) );
1479
1480 /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX
1481 * For RX Cases , Value will be DS1_SLEEP
1482 * For TX Cases, Value will be MAC ON or RADIO_PHY_ON
1483 */
1484 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2,
1485 (uint8_t *)&val) );
1486 if (val == DS1_SLEEP)
1487 {
1488 /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases
1489 * Simply update PMU Resource Mask and Re-download firmware for this case
1490 */
1491 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK) );
1492 return WHD_SUCCESS;
1493 }
1494 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2,
1495 C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) );
1496 WPRINT_WHD_DEBUG( ("%s: SDIO ctl written\n", __FUNCTION__) );
1497
1498 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(
1499 M_DS1_CTRL_SDIO), (uint8_t)2, (uint8_t *)&val) );
1500 WPRINT_WHD_DEBUG( ("%s: M_DS1_CTRL_SDIO = [%x]\n", __FUNCTION__, (int)val) );
1501
1502 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) );
1503 WPRINT_WHD_DEBUG( ("%s: before setting wake = [%x]\n", __FUNCTION__, (int)val1) );
1504 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2,
1505 val1 | D11_MACCONTROL_REG_WAKE) );
1506 WPRINT_WHD_DEBUG( ("%s: After setting wake= [%x]\n", __FUNCTION__, (int)val1) );
1507
1508 while (!(val & C_DS1_CTRL_PROC_DONE) )
1509 {
1510 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2,
1511 (uint8_t *)&val) );
1512 count++;
1513 if (count == 1000)
1514 {
1515 WPRINT_WHD_ERROR( ("%s: sdio timed out! Aborting\n", __FUNCTION__) );
1516 return WHD_TIMEOUT;
1517 }
1518 }
1519
1520 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(
1521 M_DS1_CTRL_SDIO), (uint8_t)2, (uint8_t *)&val) );
1522 WPRINT_WHD_DEBUG( ("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __FUNCTION__, (int)val) );
1523
1524 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) );
1525 WPRINT_WHD_DEBUG( ("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __FUNCTION__, (int)val1) );
1526
1527 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2,
1528 val1 & D11_MACCONTROL_CLEAR_WAKE) );
1529 WPRINT_WHD_DEBUG( ("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __FUNCTION__, (int)val1) );
1530
1531 CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK) );
1532 CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)1, (uint8_t *)&val1) );
1533 WPRINT_WHD_DEBUG( ("%s: PMU_MINRESMASK = [%x]\n", __FUNCTION__, (int)val1) );
1534 return WHD_SUCCESS;
1535 }
1536 }
1537
1538