xref: /wlan-dirver/qca-wifi-host-cmn/target_if/init_deinit/src/service_ready_util.c (revision a175314c51a4ce5cec2835cc8a8c7dc0c1810915)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 /**
19  * DOC: service_ready_util.c
20  *
21  * Public APIs implementation source file for accessing (ext)service ready
22  * data from psoc object
23  */
24 #include "service_ready_util.h"
25 #include <wlan_reg_ucfg_api.h>
26 #include <target_type.h>
27 #include <qdf_module.h>
28 
29 QDF_STATUS init_deinit_chainmask_table_alloc(
30 		struct wlan_psoc_host_service_ext_param *ser_ext_par)
31 {
32 	int i;
33 	uint32_t alloc_size;
34 	QDF_STATUS status;
35 
36 	if (ser_ext_par->num_chainmask_tables > 0) {
37 		status = QDF_STATUS_SUCCESS;
38 		for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) {
39 			alloc_size =
40 			(sizeof(struct wlan_psoc_host_chainmask_capabilities) *
41 			ser_ext_par->chainmask_table[i].num_valid_chainmasks);
42 
43 			ser_ext_par->chainmask_table[i].cap_list =
44 				qdf_mem_alloc_outline(NULL, alloc_size);
45 			if (!ser_ext_par->chainmask_table[i].cap_list) {
46 				init_deinit_chainmask_table_free(ser_ext_par);
47 				status = QDF_STATUS_E_NOMEM;
48 				break;
49 			}
50 		}
51 	} else {
52 		status = QDF_STATUS_E_NOSUPPORT;
53 	}
54 
55 	return status;
56 }
57 
58 qdf_export_symbol(init_deinit_chainmask_table_alloc);
59 
60 QDF_STATUS init_deinit_chainmask_table_free(
61 		struct wlan_psoc_host_service_ext_param *ser_ext_par)
62 {
63 	struct wlan_psoc_host_chainmask_table *table;
64 	int i;
65 
66 	for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) {
67 		table =  &(ser_ext_par->chainmask_table[i]);
68 		if (table->cap_list) {
69 			qdf_mem_free(table->cap_list);
70 			table->cap_list = NULL;
71 		}
72 	}
73 
74 	return QDF_STATUS_SUCCESS;
75 }
76 
77 qdf_export_symbol(init_deinit_chainmask_table_free);
78 
79 int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event,
80 				      uint32_t *service_bitmap)
81 {
82 	QDF_STATUS status;
83 
84 	status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap);
85 	if (QDF_IS_STATUS_ERROR(status)) {
86 		target_if_err("failed to parse service bitmap");
87 		return qdf_status_to_os_return(status);
88 	}
89 
90 	return 0;
91 }
92 
93 int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event)
94 {
95 	QDF_STATUS status;
96 
97 	status = wmi_unified_save_fw_version_cmd(wmi_handle, event);
98 	if (QDF_IS_STATUS_ERROR(status))
99 		target_if_err("failed to save fw version");
100 
101 	return 0;
102 }
103 
104 int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event,
105 			       struct wlan_psoc_target_capability_info *cap)
106 {
107 	QDF_STATUS status;
108 
109 	status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap);
110 	if (QDF_IS_STATUS_ERROR(status)) {
111 		target_if_err("failed to parse target cap");
112 		return qdf_status_to_os_return(status);
113 	}
114 
115 	return 0;
116 }
117 
118 int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt,
119 			struct wlan_psoc_host_service_ext_param *param)
120 {
121 	QDF_STATUS status;
122 
123 	status = wmi_extract_service_ready_ext(handle, evt, param);
124 	if (QDF_IS_STATUS_ERROR(status)) {
125 		target_if_err("failed to parse wmi service ready ext param");
126 		return qdf_status_to_os_return(status);
127 	}
128 
129 	return 0;
130 }
131 
132 int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt,
133 		struct wlan_psoc_host_chainmask_table *param)
134 {
135 	QDF_STATUS status;
136 
137 	status = wmi_extract_chainmask_tables(handle, evt, param);
138 	if (QDF_IS_STATUS_ERROR(status)) {
139 		target_if_err("failed to parse wmi service ready ext param");
140 		return qdf_status_to_os_return(status);
141 	}
142 
143 	return 0;
144 }
145 
146 int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt,
147 	struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info)
148 {
149 	QDF_STATUS status;
150 	uint32_t hw_mode_id;
151 	uint32_t phy_bit_map;
152 	uint8_t mac_phy_id;
153 
154 	hw_mode_id = hw_cap->hw_mode_id;
155 	phy_bit_map = hw_cap->phy_id_map;
156 	target_if_info("hw_mode_id %d phy_bit_map 0x%x",
157 		       hw_mode_id, phy_bit_map);
158 
159 	mac_phy_id = 0;
160 	while (phy_bit_map) {
161 		if (info->total_mac_phy_cnt >= PSOC_MAX_MAC_PHY_CAP) {
162 			target_if_err("total mac phy exceeds max limit %d",
163 				      info->total_mac_phy_cnt);
164 			return -EINVAL;
165 		}
166 
167 		status = wmi_extract_mac_phy_cap_service_ready_ext(handle,
168 				evt, hw_mode_id, mac_phy_id,
169 				&(info->mac_phy_cap[info->total_mac_phy_cnt]));
170 		if (QDF_IS_STATUS_ERROR(status)) {
171 			target_if_err("failed to parse mac phy capability");
172 			return qdf_status_to_os_return(status);
173 		}
174 		info->mac_phy_cap[info->total_mac_phy_cnt].hw_mode_config_type
175 					= hw_cap->hw_mode_config_type;
176 		info->total_mac_phy_cnt++;
177 		phy_bit_map &= (phy_bit_map - 1);
178 		mac_phy_id++;
179 	}
180 	target_if_info("total_mac_phy_cnt %d", info->total_mac_phy_cnt);
181 
182 	return 0;
183 }
184 
185 static int get_hw_mode(void *handle, uint8_t *evt, uint8_t hw_idx,
186 			struct wlan_psoc_host_hw_mode_caps *cap)
187 {
188 	QDF_STATUS status;
189 
190 	status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt,
191 					hw_idx, cap);
192 	if (QDF_IS_STATUS_ERROR(status)) {
193 		target_if_err("failed to parse hw mode capability");
194 		return qdf_status_to_os_return(status);
195 	}
196 
197 	return 0;
198 }
199 
200 static int get_sar_version(void *handle, uint8_t *evt,
201 			   struct wlan_psoc_host_service_ext_param *ext_param)
202 {
203 	QDF_STATUS status;
204 
205 	status = wmi_extract_sar_cap_service_ready_ext(handle, evt, ext_param);
206 	if (QDF_IS_STATUS_ERROR(status)) {
207 		target_if_err("failed to parse sar capability");
208 		return qdf_status_to_os_return(status);
209 	}
210 
211 	return 0;
212 }
213 
214 int init_deinit_populate_hw_mode_capability(void *wmi_handle,
215 		uint8_t *event, struct target_psoc_info *tgt_hdl)
216 {
217 	QDF_STATUS status = QDF_STATUS_SUCCESS;
218 	uint8_t hw_idx;
219 	uint32_t num_hw_modes;
220 	struct wlan_psoc_host_hw_mode_caps hw_mode_caps[PSOC_MAX_HW_MODE];
221 	uint32_t preferred_mode;
222 	struct tgt_info *info;
223 
224 	info = &tgt_hdl->info;
225 	num_hw_modes = info->service_ext_param.num_hw_modes;
226 	if (num_hw_modes > PSOC_MAX_HW_MODE) {
227 		target_if_err("invalid num_hw_modes %d", num_hw_modes);
228 		return -EINVAL;
229 	}
230 	target_if_info("num_hw_modes %d", num_hw_modes);
231 
232 	qdf_mem_zero(&hw_mode_caps, sizeof(hw_mode_caps));
233 
234 	preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl);
235 	for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) {
236 		status = get_hw_mode(wmi_handle, event, hw_idx,
237 						&hw_mode_caps[hw_idx]);
238 		if (status)
239 			goto return_exit;
240 
241 		if ((preferred_mode != WMI_HOST_HW_MODE_MAX) &&
242 		    (hw_mode_caps[hw_idx].hw_mode_id != preferred_mode))
243 			continue;
244 
245 		status = init_deinit_populate_mac_phy_capability(wmi_handle,
246 				event, &hw_mode_caps[hw_idx], info);
247 		if (status)
248 			goto return_exit;
249 
250 		if ((preferred_mode != WMI_HOST_HW_MODE_MAX) &&
251 		    (hw_mode_caps[hw_idx].hw_mode_id == preferred_mode)) {
252 			info->num_radios = info->total_mac_phy_cnt;
253 			target_if_info("num radios is %d\n", info->num_radios);
254 		}
255 	}
256 	status = get_sar_version(wmi_handle, event, &info->service_ext_param);
257 	target_if_info("sar version %d",
258 		       info->service_ext_param.sar_version);
259 
260 return_exit:
261 	return qdf_status_to_os_return(status);
262 }
263 
264 int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc,
265 			void *handle, uint8_t *event, struct tgt_info *info)
266 
267 {
268 	uint8_t cap_idx;
269 	uint32_t num_dbr_ring_caps;
270 	QDF_STATUS status = QDF_STATUS_SUCCESS;
271 
272 	num_dbr_ring_caps = info->service_ext_param.num_dbr_ring_caps;
273 
274 	target_if_info("Num DMA Capabilities = %d", num_dbr_ring_caps);
275 
276 	if (!num_dbr_ring_caps)
277 		return 0;
278 
279 	info->dbr_ring_cap = qdf_mem_malloc(
280 				sizeof(struct wlan_psoc_host_dbr_ring_caps) *
281 				num_dbr_ring_caps);
282 
283 	if (!info->dbr_ring_cap) {
284 		target_if_err("Mem alloc for DMA cap failed");
285 		return -EINVAL;
286 	}
287 
288 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
289 		status = wmi_extract_dbr_ring_cap_service_ready_ext(handle,
290 				event, cap_idx,
291 				&(info->dbr_ring_cap[cap_idx]));
292 		if (QDF_IS_STATUS_ERROR(status)) {
293 			target_if_err("Extraction of DMA cap failed");
294 			goto free_and_return;
295 		}
296 	}
297 
298 	return 0;
299 
300 free_and_return:
301 	qdf_mem_free(info->dbr_ring_cap);
302 	info->dbr_ring_cap = NULL;
303 
304 	return qdf_status_to_os_return(status);
305 }
306 
307 QDF_STATUS init_deinit_dbr_ring_cap_free(
308 		struct target_psoc_info *tgt_psoc_info)
309 {
310 	QDF_STATUS status = QDF_STATUS_SUCCESS;
311 
312 	if (tgt_psoc_info->info.dbr_ring_cap) {
313 		qdf_mem_free(tgt_psoc_info->info.dbr_ring_cap);
314 		tgt_psoc_info->info.dbr_ring_cap = NULL;
315 	}
316 
317 	return status;
318 }
319 qdf_export_symbol(init_deinit_dbr_ring_cap_free);
320 
321 int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc,
322 				void *handle, uint8_t *event,
323 				struct tgt_info *info, bool service_ready)
324 {
325 	uint8_t reg_idx;
326 	uint32_t num_phy_reg_cap;
327 	QDF_STATUS status = QDF_STATUS_SUCCESS;
328 	struct wlan_psoc_hal_reg_capability cap;
329 	struct wlan_psoc_host_hal_reg_capabilities_ext
330 				reg_cap[PSOC_MAX_PHY_REG_CAP] = {{0} };
331 
332 	if (service_ready) {
333 		status = wmi_extract_hal_reg_cap(handle, event, &cap);
334 		if (QDF_IS_STATUS_ERROR(status)) {
335 			target_if_err("failed to parse hal reg cap");
336 			return qdf_status_to_os_return(status);
337 		}
338 		info->service_ext_param.num_phy = 1;
339 		num_phy_reg_cap = 1;
340 		reg_cap[0].phy_id = 0;
341 		qdf_mem_copy(&(reg_cap[0].eeprom_reg_domain), &cap,
342 			     sizeof(struct wlan_psoc_hal_reg_capability));
343 		target_if_info("FW wireless modes 0x%x",
344 			       reg_cap[0].wireless_modes);
345 	} else {
346 		num_phy_reg_cap = info->service_ext_param.num_phy;
347 		if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) {
348 			target_if_err("Invalid num_phy_reg_cap %d",
349 				      num_phy_reg_cap);
350 			return -EINVAL;
351 		}
352 		target_if_info("num_phy_reg_cap %d", num_phy_reg_cap);
353 
354 		for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) {
355 			status = wmi_extract_reg_cap_service_ready_ext(handle,
356 					event, reg_idx, &(reg_cap[reg_idx]));
357 			if (QDF_IS_STATUS_ERROR(status)) {
358 				target_if_err("failed to parse reg cap");
359 				return qdf_status_to_os_return(status);
360 			}
361 		}
362 	}
363 
364 	status = ucfg_reg_set_hal_reg_cap(psoc, reg_cap, num_phy_reg_cap);
365 
366 	return qdf_status_to_os_return(status);
367 }
368 
369 static bool init_deinit_regdmn_160mhz_support(
370 		struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
371 {
372 	return ((hal_cap->wireless_modes &
373 		WMI_HOST_REGDMN_MODE_11AC_VHT160) != 0);
374 }
375 
376 static bool init_deinit_regdmn_80p80mhz_support(
377 		struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
378 {
379 	return ((hal_cap->wireless_modes &
380 			WMI_HOST_REGDMN_MODE_11AC_VHT80_80) != 0);
381 }
382 
383 static bool init_deinit_vht_160mhz_is_supported(uint32_t vhtcap)
384 {
385 	return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_160) != 0);
386 }
387 
388 static bool init_deinit_vht_80p80mhz_is_supported(uint32_t vhtcap)
389 {
390 	return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160) != 0);
391 }
392 
393 static bool init_deinit_vht_160mhz_shortgi_is_supported(uint32_t vhtcap)
394 {
395 	return ((vhtcap & WLAN_VHTCAP_SHORTGI_160) != 0);
396 }
397 
398 QDF_STATUS init_deinit_validate_160_80p80_fw_caps(
399 		 struct wlan_objmgr_psoc *psoc,
400 		 struct target_psoc_info *tgt_hdl)
401 {
402 	bool wireless_mode_160mhz = false;
403 	bool wireless_mode_80p80mhz = false;
404 	bool vhtcap_160mhz = false;
405 	bool vhtcap_80p80_160mhz = false;
406 	bool vhtcap_160mhz_sgi = false;
407 	bool valid = false;
408 	struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
409 	struct common_wmi_handle *wmi_handle;
410 
411 	if (!tgt_hdl) {
412 		target_if_err(
413 		"target_psoc_info is null in validate 160n80p80 cap check");
414 		return QDF_STATUS_E_INVAL;
415 	}
416 
417 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
418 
419 	if ((tgt_hdl->info.target_type == TARGET_TYPE_QCA8074) ||
420 	    (tgt_hdl->info.target_type == TARGET_TYPE_QCA6290)) {
421 		/**
422 		 * Return true for now. This is not available in
423 		 * qca8074 fw yet
424 		 */
425 		return QDF_STATUS_SUCCESS;
426 	}
427 
428 	reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
429 	if (reg_cap == NULL) {
430 		target_if_err("reg cap is NULL");
431 		return QDF_STATUS_E_FAILURE;
432 	}
433 
434 	/* NOTE: Host driver gets vht capability and supported channel
435 	 * width / channel frequency range from FW/HALPHY and obeys it.
436 	 * Host driver is unaware of any physical filters or any other
437 	 * hardware factors that can impact these capabilities.
438 	 * These need to be correctly determined by firmware.
439 	 */
440 
441 	/*This table lists all valid and invalid combinations
442 	 * WMODE160 WMODE80_80  VHTCAP_160 VHTCAP_80+80_160  IsCombinationvalid?
443 	 *      0         0           0              0                 YES
444 	 *      0         0           0              1                 NO
445 	 *      0         0           1              0                 NO
446 	 *      0         0           1              1                 NO
447 	 *      0         1           0              0                 NO
448 	 *      0         1           0              1                 NO
449 	 *      0         1           1              0                 NO
450 	 *      0         1           1              1                 NO
451 	 *      1         0           0              0                 NO
452 	 *      1         0           0              1                 NO
453 	 *      1         0           1              0                 YES
454 	 *      1         0           1              1                 NO
455 	 *      1         1           0              0                 NO
456 	 *      1         1           0              1                 YES
457 	 *      1         1           1              0                 NO
458 	 *      1         1           1              1                 NO
459 	 */
460 
461 	/* NOTE: Last row in above table is invalid because value corresponding
462 	 * to both VHTCAP_160 and VHTCAP_80+80_160 being set is reserved as per
463 	 * 802.11ac. Only one of them can be set at a time.
464 	 */
465 
466 	wireless_mode_160mhz = init_deinit_regdmn_160mhz_support(reg_cap);
467 	wireless_mode_80p80mhz = init_deinit_regdmn_80p80mhz_support(reg_cap);
468 	vhtcap_160mhz = init_deinit_vht_160mhz_is_supported(
469 				tgt_hdl->info.target_caps.vht_cap_info);
470 	vhtcap_80p80_160mhz = init_deinit_vht_80p80mhz_is_supported(
471 				tgt_hdl->info.target_caps.vht_cap_info);
472 	vhtcap_160mhz_sgi = init_deinit_vht_160mhz_shortgi_is_supported(
473 				tgt_hdl->info.target_caps.vht_cap_info);
474 
475 	if (!(wireless_mode_160mhz || wireless_mode_80p80mhz ||
476 	      vhtcap_160mhz || vhtcap_80p80_160mhz)) {
477 		valid = QDF_STATUS_SUCCESS;
478 	} else if (wireless_mode_160mhz && !wireless_mode_80p80mhz &&
479 		   vhtcap_160mhz && !vhtcap_80p80_160mhz) {
480 		valid = QDF_STATUS_SUCCESS;
481 	} else if (wireless_mode_160mhz && wireless_mode_80p80mhz &&
482 		   !vhtcap_160mhz && vhtcap_160mhz_sgi) {
483 		valid = QDF_STATUS_SUCCESS;
484 	}
485 
486 	if (valid == QDF_STATUS_SUCCESS) {
487 		/*
488 		 * Ensure short GI for 160 MHz is enabled
489 		 * only if 160/80+80 is supported.
490 		 */
491 		if (vhtcap_160mhz_sgi &&
492 		    !(vhtcap_160mhz || vhtcap_80p80_160mhz)) {
493 			valid = QDF_STATUS_E_FAILURE;
494 		}
495 	}
496 
497 	/* Invalid config specified by FW */
498 	if (valid != QDF_STATUS_SUCCESS) {
499 		target_if_err("Invalid 160/80+80 MHz config specified by FW. Take care of it first");
500 		target_if_err("wireless_mode_160mhz: %d, wireless_mode_80p80mhz: %d",
501 			      wireless_mode_160mhz, wireless_mode_80p80mhz);
502 		target_if_err("vhtcap_160mhz: %d, vhtcap_80p80_160mhz: %d,vhtcap_160mhz_sgi: %d",
503 			      vhtcap_160mhz, vhtcap_80p80_160mhz,
504 			      vhtcap_160mhz_sgi);
505 	}
506 	return valid;
507 }
508 
509 void init_deinit_chainmask_config(
510 		 struct wlan_objmgr_psoc *psoc,
511 		 struct target_psoc_info *tgt_hdl)
512 {
513 	tgt_hdl->info.wlan_res_cfg.tx_chain_mask =
514 		((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1);
515 	tgt_hdl->info.wlan_res_cfg.rx_chain_mask =
516 		((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1);
517 }
518 
519 QDF_STATUS init_deinit_is_service_ext_msg(
520 		 struct wlan_objmgr_psoc *psoc,
521 		 struct target_psoc_info *tgt_hdl)
522 {
523 	struct common_wmi_handle *wmi_handle;
524 
525 	if (!tgt_hdl) {
526 		target_if_err(
527 			"psoc target_psoc_info is null in service ext msg");
528 		return QDF_STATUS_E_INVAL;
529 	}
530 
531 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
532 
533 	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg))
534 		return QDF_STATUS_SUCCESS;
535 	else
536 		return QDF_STATUS_E_FAILURE;
537 }
538 
539 bool init_deinit_is_preferred_hw_mode_supported(
540 		 struct wlan_objmgr_psoc *psoc,
541 		 struct target_psoc_info *tgt_hdl)
542 {
543 	uint16_t i;
544 	struct tgt_info *info;
545 
546 	if (!tgt_hdl) {
547 		target_if_err(
548 			"psoc target_psoc_info is null in service ext msg");
549 		return FALSE;
550 	}
551 
552 	info = &tgt_hdl->info;
553 
554 	if (info->preferred_hw_mode == WMI_HOST_HW_MODE_MAX)
555 		return TRUE;
556 
557 	for (i = 0; i < target_psoc_get_total_mac_phy_cnt(tgt_hdl); i++) {
558 		if (info->mac_phy_cap[i].hw_mode_id == info->preferred_hw_mode)
559 			return TRUE;
560 	}
561 
562 	return FALSE;
563 }
564 
565 void init_deinit_wakeup_host_wait(
566 		 struct wlan_objmgr_psoc *psoc,
567 		 struct target_psoc_info *tgt_hdl)
568 {
569 	if (!tgt_hdl) {
570 		target_if_err("psoc target_psoc_info is null in target ready");
571 		return;
572 	}
573 	qdf_wake_up(&tgt_hdl->info.event_queue);
574 }
575