xref: /dpdk/drivers/common/mlx5/windows/mlx5_glue.c (revision 25245d5dc9ecfa8bc9964c69a756beca6ee1ca72)
17525ebd8STal Shnaiderman /* SPDX-License-Identifier: BSD-3-Clause
27525ebd8STal Shnaiderman  * Copyright 2020 Mellanox Technologies, Ltd
37525ebd8STal Shnaiderman  */
47525ebd8STal Shnaiderman 
57525ebd8STal Shnaiderman #include <errno.h>
67525ebd8STal Shnaiderman #include <stdalign.h>
77525ebd8STal Shnaiderman #include <stddef.h>
87525ebd8STal Shnaiderman #include <stdint.h>
97525ebd8STal Shnaiderman #include <stdlib.h>
107525ebd8STal Shnaiderman #include <unistd.h>
117525ebd8STal Shnaiderman 
127525ebd8STal Shnaiderman #include <rte_malloc.h>
137525ebd8STal Shnaiderman 
147525ebd8STal Shnaiderman #include "mlx5_glue.h"
15*25245d5dSShiri Kuzin #include "../mlx5_common_log.h"
167525ebd8STal Shnaiderman #include "mlx5_win_ext.h"
177525ebd8STal Shnaiderman 
187525ebd8STal Shnaiderman /*
197525ebd8STal Shnaiderman  * The returned value of this API is an array of pointers to mlx5
207525ebd8STal Shnaiderman  * devices under Windows. The interesting parameters of a device:
217525ebd8STal Shnaiderman  * Device PCI parameters: domain, bus, device id, function.
227525ebd8STal Shnaiderman  * Device name.
237525ebd8STal Shnaiderman  */
247525ebd8STal Shnaiderman static void *
257525ebd8STal Shnaiderman mlx5_glue_devx_get_device_list(int *num_devices)
267525ebd8STal Shnaiderman {
277525ebd8STal Shnaiderman 	struct devx_device_bdf *devx_bdf_devs = NULL;
287525ebd8STal Shnaiderman 	size_t n_devx_devx = 0;
297525ebd8STal Shnaiderman 	int32_t ret = devx_get_device_list(&n_devx_devx, &devx_bdf_devs);
307525ebd8STal Shnaiderman 
317525ebd8STal Shnaiderman 	if (ret) {
327525ebd8STal Shnaiderman 		errno = ret;
337525ebd8STal Shnaiderman 		*num_devices = 0;
347525ebd8STal Shnaiderman 		return NULL;
357525ebd8STal Shnaiderman 	}
367525ebd8STal Shnaiderman 	*num_devices = (int)n_devx_devx;
377525ebd8STal Shnaiderman 	return devx_bdf_devs;
387525ebd8STal Shnaiderman }
397525ebd8STal Shnaiderman 
407525ebd8STal Shnaiderman static void
417525ebd8STal Shnaiderman mlx5_glue_devx_free_device_list(void *list)
427525ebd8STal Shnaiderman {
437525ebd8STal Shnaiderman 	if (!list) {
447525ebd8STal Shnaiderman 		errno = EINVAL;
457525ebd8STal Shnaiderman 		return;
467525ebd8STal Shnaiderman 	}
477525ebd8STal Shnaiderman 	devx_free_device_list(list);
487525ebd8STal Shnaiderman }
497525ebd8STal Shnaiderman 
507525ebd8STal Shnaiderman static int
517525ebd8STal Shnaiderman mlx5_glue_devx_close_device(void *ctx)
527525ebd8STal Shnaiderman {
537525ebd8STal Shnaiderman 	mlx5_context_st *mlx5_ctx;
547525ebd8STal Shnaiderman 	int rc;
557525ebd8STal Shnaiderman 
567525ebd8STal Shnaiderman 	if (!ctx)
577525ebd8STal Shnaiderman 		return -EINVAL;
587525ebd8STal Shnaiderman 	mlx5_ctx = (mlx5_context_st *)ctx;
597525ebd8STal Shnaiderman 	rc = devx_close_device(mlx5_ctx->devx_ctx);
607525ebd8STal Shnaiderman 	free(mlx5_ctx);
617525ebd8STal Shnaiderman 	return rc;
627525ebd8STal Shnaiderman }
637525ebd8STal Shnaiderman 
647525ebd8STal Shnaiderman static void *
657525ebd8STal Shnaiderman mlx5_glue_devx_open_device(void *device)
667525ebd8STal Shnaiderman {
677525ebd8STal Shnaiderman 	struct mlx5_context *mlx5_ctx;
687525ebd8STal Shnaiderman 
697525ebd8STal Shnaiderman 	if (!device) {
707525ebd8STal Shnaiderman 		errno = EINVAL;
717525ebd8STal Shnaiderman 		return NULL;
727525ebd8STal Shnaiderman 	}
737525ebd8STal Shnaiderman 	mlx5_ctx = malloc((sizeof(struct mlx5_context)));
747525ebd8STal Shnaiderman 	if (!mlx5_ctx) {
757525ebd8STal Shnaiderman 		errno = ENOMEM;
767525ebd8STal Shnaiderman 		return NULL;
777525ebd8STal Shnaiderman 	}
787525ebd8STal Shnaiderman 	memset(mlx5_ctx, 0, sizeof(*mlx5_ctx));
797525ebd8STal Shnaiderman 	mlx5_ctx->devx_ctx = devx_open_device(device);
807525ebd8STal Shnaiderman 	if (DEVX_IS_ERR(mlx5_ctx->devx_ctx)) {
817525ebd8STal Shnaiderman 		errno = -DEVX_PTR_ERR(mlx5_ctx->devx_ctx);
827525ebd8STal Shnaiderman 		free(mlx5_ctx);
837525ebd8STal Shnaiderman 		return NULL;
847525ebd8STal Shnaiderman 	}
857525ebd8STal Shnaiderman 	return mlx5_ctx;
867525ebd8STal Shnaiderman }
877525ebd8STal Shnaiderman 
887525ebd8STal Shnaiderman static int
897525ebd8STal Shnaiderman mlx5_glue_devx_query_device(void *device_bdf, void *dev_inf)
907525ebd8STal Shnaiderman {
917525ebd8STal Shnaiderman 	struct devx_device_bdf *dev_bdf;
927525ebd8STal Shnaiderman 	struct devx_device *mlx5_dev;
937525ebd8STal Shnaiderman 
947525ebd8STal Shnaiderman 	if (!device_bdf)
957525ebd8STal Shnaiderman 		return -EINVAL;
967525ebd8STal Shnaiderman 	dev_bdf = (struct devx_device_bdf *)device_bdf;
977525ebd8STal Shnaiderman 	mlx5_dev = (struct devx_device *)dev_inf;
987525ebd8STal Shnaiderman 	int err = devx_query_device(dev_bdf, mlx5_dev);
997525ebd8STal Shnaiderman 	if (err)
1007525ebd8STal Shnaiderman 		return -E_FAIL;
1017525ebd8STal Shnaiderman 	return 0;
1027525ebd8STal Shnaiderman }
1037525ebd8STal Shnaiderman 
1047525ebd8STal Shnaiderman static void *
1057525ebd8STal Shnaiderman mlx5_glue_devx_query_hca_iseg_mapping(void *ctx, uint32_t *cb_iseg)
1067525ebd8STal Shnaiderman {
1077525ebd8STal Shnaiderman 	struct mlx5_context *mlx5_ctx;
1087525ebd8STal Shnaiderman 	void *pv_iseg;
1097525ebd8STal Shnaiderman 	int err;
1107525ebd8STal Shnaiderman 
1117525ebd8STal Shnaiderman 	if (!ctx) {
1127525ebd8STal Shnaiderman 		errno = EINVAL;
1137525ebd8STal Shnaiderman 		return NULL;
1147525ebd8STal Shnaiderman 	}
1157525ebd8STal Shnaiderman 	mlx5_ctx = (struct mlx5_context *)ctx;
1167525ebd8STal Shnaiderman 	err = devx_query_hca_iseg_mapping(mlx5_ctx->devx_ctx,
1177525ebd8STal Shnaiderman 						cb_iseg, &pv_iseg);
1187525ebd8STal Shnaiderman 	if (err) {
1197525ebd8STal Shnaiderman 		errno = err;
1207525ebd8STal Shnaiderman 		return NULL;
1217525ebd8STal Shnaiderman 	}
1227525ebd8STal Shnaiderman 	return pv_iseg;
1237525ebd8STal Shnaiderman }
1247525ebd8STal Shnaiderman 
1257525ebd8STal Shnaiderman static void *
1267525ebd8STal Shnaiderman mlx5_glue_devx_obj_create(void *ctx,
1277525ebd8STal Shnaiderman 			      void *in, size_t inlen,
1287525ebd8STal Shnaiderman 			      void *out, size_t outlen)
1297525ebd8STal Shnaiderman {
1307525ebd8STal Shnaiderman 	mlx5_devx_obj_st *devx_obj;
1317525ebd8STal Shnaiderman 
1327525ebd8STal Shnaiderman 	if (!ctx) {
1337525ebd8STal Shnaiderman 		errno = EINVAL;
1347525ebd8STal Shnaiderman 		return NULL;
1357525ebd8STal Shnaiderman 	}
1367525ebd8STal Shnaiderman 	devx_obj = malloc((sizeof(*devx_obj)));
1377525ebd8STal Shnaiderman 	if (!devx_obj) {
1387525ebd8STal Shnaiderman 		errno = ENOMEM;
1397525ebd8STal Shnaiderman 		return NULL;
1407525ebd8STal Shnaiderman 	}
1417525ebd8STal Shnaiderman 	memset(devx_obj, 0, sizeof(*devx_obj));
1427525ebd8STal Shnaiderman 	devx_obj->devx_ctx = GET_DEVX_CTX(ctx);
1437525ebd8STal Shnaiderman 	devx_obj->obj = devx_obj_create(devx_obj->devx_ctx,
1447525ebd8STal Shnaiderman 					in, inlen, out, outlen);
1457525ebd8STal Shnaiderman 	if (DEVX_IS_ERR(devx_obj->obj)) {
1467525ebd8STal Shnaiderman 		errno = -DEVX_PTR_ERR(devx_obj->obj);
1477525ebd8STal Shnaiderman 		free(devx_obj);
1487525ebd8STal Shnaiderman 		return NULL;
1497525ebd8STal Shnaiderman 	}
1507525ebd8STal Shnaiderman 	return devx_obj;
1517525ebd8STal Shnaiderman }
1527525ebd8STal Shnaiderman 
1537525ebd8STal Shnaiderman static int
1547525ebd8STal Shnaiderman mlx5_glue_devx_obj_destroy(void *obj)
1557525ebd8STal Shnaiderman {
1567525ebd8STal Shnaiderman 	mlx5_devx_obj_st *devx_obj;
1577525ebd8STal Shnaiderman 
1587525ebd8STal Shnaiderman 	if (!obj)
1597525ebd8STal Shnaiderman 		return -EINVAL;
1607525ebd8STal Shnaiderman 	devx_obj = obj;
1617525ebd8STal Shnaiderman 	int rc = devx_obj_destroy(devx_obj->obj);
1627525ebd8STal Shnaiderman 	free(devx_obj);
1637525ebd8STal Shnaiderman 	return rc;
1647525ebd8STal Shnaiderman }
1657525ebd8STal Shnaiderman 
1667525ebd8STal Shnaiderman static int
1677525ebd8STal Shnaiderman mlx5_glue_devx_general_cmd(void *ctx,
1687525ebd8STal Shnaiderman 			   void *in, size_t inlen,
1697525ebd8STal Shnaiderman 			   void *out, size_t outlen)
1707525ebd8STal Shnaiderman {
1717525ebd8STal Shnaiderman 	if (!ctx)
1727525ebd8STal Shnaiderman 		return -EINVAL;
1737525ebd8STal Shnaiderman 	return devx_cmd(GET_DEVX_CTX(ctx), in, inlen, out, outlen);
1747525ebd8STal Shnaiderman }
1757525ebd8STal Shnaiderman 
1767525ebd8STal Shnaiderman static int
1777525ebd8STal Shnaiderman mlx5_glue_devx_obj_query(void *obj,
1787525ebd8STal Shnaiderman 			    void *in, size_t inlen,
1797525ebd8STal Shnaiderman 			    void *out, size_t outlen)
1807525ebd8STal Shnaiderman {
1817525ebd8STal Shnaiderman 	return devx_cmd(GET_OBJ_CTX(obj), in, inlen, out, outlen);
1827525ebd8STal Shnaiderman }
1837525ebd8STal Shnaiderman 
1847525ebd8STal Shnaiderman static int
1857525ebd8STal Shnaiderman mlx5_glue_devx_obj_modify(void *obj,
1867525ebd8STal Shnaiderman 			    void *in, size_t inlen,
1877525ebd8STal Shnaiderman 			    void *out, size_t outlen)
1887525ebd8STal Shnaiderman {
1897525ebd8STal Shnaiderman 	return devx_cmd(GET_OBJ_CTX(obj), in, inlen, out, outlen);
1907525ebd8STal Shnaiderman }
1917525ebd8STal Shnaiderman 
1927525ebd8STal Shnaiderman static int
1937525ebd8STal Shnaiderman mlx5_glue_devx_umem_dereg(void *pumem)
1947525ebd8STal Shnaiderman {
1957525ebd8STal Shnaiderman 	struct devx_obj_handle *umem;
1967525ebd8STal Shnaiderman 
1977525ebd8STal Shnaiderman 	if (!pumem)
1987525ebd8STal Shnaiderman 		return -EINVAL;
1997525ebd8STal Shnaiderman 	umem = pumem;
2007525ebd8STal Shnaiderman 	return devx_umem_unreg(umem);
2017525ebd8STal Shnaiderman }
2027525ebd8STal Shnaiderman 
2037525ebd8STal Shnaiderman static void *
2047525ebd8STal Shnaiderman mlx5_glue_devx_umem_reg(void *ctx, void *addr, size_t size,
2057525ebd8STal Shnaiderman 				  uint32_t access, uint32_t *id)
2067525ebd8STal Shnaiderman {
2077525ebd8STal Shnaiderman 	struct devx_obj_handle *umem_hdl;
2087525ebd8STal Shnaiderman 	int w_access = DEVX_UMEM_ACCESS_READ;
2097525ebd8STal Shnaiderman 
2107525ebd8STal Shnaiderman 	if (!ctx) {
2117525ebd8STal Shnaiderman 		errno = EINVAL;
2127525ebd8STal Shnaiderman 		return NULL;
2137525ebd8STal Shnaiderman 	}
2147525ebd8STal Shnaiderman 	if (access)
2157525ebd8STal Shnaiderman 		w_access |= DEVX_UMEM_ACCESS_WRITE;
2167525ebd8STal Shnaiderman 
2177525ebd8STal Shnaiderman 	umem_hdl = devx_umem_reg(GET_DEVX_CTX(ctx), addr,
2187525ebd8STal Shnaiderman 					size, w_access, id);
2197525ebd8STal Shnaiderman 	if (DEVX_IS_ERR(umem_hdl)) {
2207525ebd8STal Shnaiderman 		errno = -DEVX_PTR_ERR(umem_hdl);
2217525ebd8STal Shnaiderman 		return NULL;
2227525ebd8STal Shnaiderman 	}
2237525ebd8STal Shnaiderman 	return umem_hdl;
2247525ebd8STal Shnaiderman }
2257525ebd8STal Shnaiderman 
2267525ebd8STal Shnaiderman static void *
2277525ebd8STal Shnaiderman mlx5_glue_devx_alloc_uar(void *ctx,
2287525ebd8STal Shnaiderman 		uint32_t flags)
2297525ebd8STal Shnaiderman {
2307525ebd8STal Shnaiderman 	devx_uar_handle *uar;
2317525ebd8STal Shnaiderman 
2327525ebd8STal Shnaiderman 	if (!ctx) {
2337525ebd8STal Shnaiderman 		errno = EINVAL;
2347525ebd8STal Shnaiderman 		return NULL;
2357525ebd8STal Shnaiderman 	}
2367525ebd8STal Shnaiderman 	uar = devx_alloc_uar(GET_DEVX_CTX(ctx), flags);
2377525ebd8STal Shnaiderman 	if (DEVX_IS_ERR(uar)) {
2387525ebd8STal Shnaiderman 		errno = -DEVX_PTR_ERR(uar);
2397525ebd8STal Shnaiderman 		return NULL;
2407525ebd8STal Shnaiderman 	}
2417525ebd8STal Shnaiderman 	return uar;
2427525ebd8STal Shnaiderman }
2437525ebd8STal Shnaiderman 
2447525ebd8STal Shnaiderman static int
2457525ebd8STal Shnaiderman mlx5_glue_devx_query_eqn(void *ctx,
2467525ebd8STal Shnaiderman 		uint32_t cpus, uint32_t *eqn)
2477525ebd8STal Shnaiderman {
2487525ebd8STal Shnaiderman 	if (!ctx)
2497525ebd8STal Shnaiderman 		return -EINVAL;
2507525ebd8STal Shnaiderman 	return devx_query_eqn(GET_DEVX_CTX(ctx), cpus, eqn);
2517525ebd8STal Shnaiderman }
2527525ebd8STal Shnaiderman 
2537525ebd8STal Shnaiderman static void
2547525ebd8STal Shnaiderman mlx5_glue_devx_free_uar(void *uar)
2557525ebd8STal Shnaiderman {
2567525ebd8STal Shnaiderman 	devx_free_uar((devx_uar_handle *)uar);
2577525ebd8STal Shnaiderman }
2587525ebd8STal Shnaiderman 
259e961c8e3STal Shnaiderman static_assert(MLX5_ST_SZ_BYTES(fte_match_param) == 0x200,
260e961c8e3STal Shnaiderman 	"PRM size of fte_match_param is broken! cannot compile Windows!");
261e961c8e3STal Shnaiderman 
2627525ebd8STal Shnaiderman static void*
2637525ebd8STal Shnaiderman mlx5_glue_devx_fs_rule_add(void *ctx, void *in, uint32_t inlen)
2647525ebd8STal Shnaiderman 
2657525ebd8STal Shnaiderman {
2667525ebd8STal Shnaiderman 	struct devx_obj_handle *rule_hdl = NULL;
2677525ebd8STal Shnaiderman 
2687525ebd8STal Shnaiderman 	if (!ctx) {
2697525ebd8STal Shnaiderman 		errno = EINVAL;
2707525ebd8STal Shnaiderman 		return NULL;
2717525ebd8STal Shnaiderman 	}
2727525ebd8STal Shnaiderman 	rule_hdl = devx_fs_rule_add(GET_DEVX_CTX(ctx), in, inlen);
2737525ebd8STal Shnaiderman 	if (DEVX_IS_ERR(rule_hdl)) {
2747525ebd8STal Shnaiderman 		errno = -DEVX_PTR_ERR(rule_hdl);
2757525ebd8STal Shnaiderman 		return NULL;
2767525ebd8STal Shnaiderman 	}
2777525ebd8STal Shnaiderman 	return rule_hdl;
2787525ebd8STal Shnaiderman }
2797525ebd8STal Shnaiderman 
2807525ebd8STal Shnaiderman static int
2817525ebd8STal Shnaiderman mlx5_glue_devx_fs_rule_del(void *flow)
2827525ebd8STal Shnaiderman {
2837525ebd8STal Shnaiderman 	return devx_fs_rule_del(flow);
2847525ebd8STal Shnaiderman }
2857525ebd8STal Shnaiderman 
28699d7c45cSTal Shnaiderman static int
28799d7c45cSTal Shnaiderman mlx5_glue_query_rt_values(void *ctx, void *devx_clock)
28899d7c45cSTal Shnaiderman {
28999d7c45cSTal Shnaiderman 	struct mlx5_context *mlx5_ctx;
29099d7c45cSTal Shnaiderman 	struct mlx5_devx_clock *clock;
29199d7c45cSTal Shnaiderman 	int err;
29299d7c45cSTal Shnaiderman 
29399d7c45cSTal Shnaiderman 	if (!ctx) {
29499d7c45cSTal Shnaiderman 		errno = EINVAL;
29599d7c45cSTal Shnaiderman 		return errno;
29699d7c45cSTal Shnaiderman 	}
29799d7c45cSTal Shnaiderman 	mlx5_ctx = (struct mlx5_context *)ctx;
29899d7c45cSTal Shnaiderman 	clock = (struct mlx5_devx_clock *)devx_clock;
29999d7c45cSTal Shnaiderman 	err = devx_hca_clock_query(
30099d7c45cSTal Shnaiderman 			mlx5_ctx->devx_ctx,
30199d7c45cSTal Shnaiderman 			&clock->p_iseg_internal_timer,
30299d7c45cSTal Shnaiderman 			&clock->clock_frequency_hz,
30399d7c45cSTal Shnaiderman 			&clock->is_stable_clock_frequency);
30499d7c45cSTal Shnaiderman 	if (err) {
30599d7c45cSTal Shnaiderman 		errno = err;
30699d7c45cSTal Shnaiderman 		return errno;
30799d7c45cSTal Shnaiderman 	}
30899d7c45cSTal Shnaiderman 	return 0;
30999d7c45cSTal Shnaiderman }
31099d7c45cSTal Shnaiderman 
311165e5d07STal Shnaiderman static int
312165e5d07STal Shnaiderman mlx5_glue_devx_init_showdown_event(void *ctx)
313165e5d07STal Shnaiderman {
314165e5d07STal Shnaiderman 	struct mlx5_context *mlx5_ctx;
315165e5d07STal Shnaiderman 	int err;
316165e5d07STal Shnaiderman 
317165e5d07STal Shnaiderman 	if (!ctx) {
318165e5d07STal Shnaiderman 		errno = EINVAL;
319165e5d07STal Shnaiderman 		return errno;
320165e5d07STal Shnaiderman 	}
321165e5d07STal Shnaiderman 	mlx5_ctx = (struct mlx5_context *)ctx;
322165e5d07STal Shnaiderman 	err = devx_query_shutdown_event(mlx5_ctx->devx_ctx,
323165e5d07STal Shnaiderman 			&mlx5_ctx->shutdown_event_obj);
324165e5d07STal Shnaiderman 	if (err) {
325165e5d07STal Shnaiderman 		errno = err;
326165e5d07STal Shnaiderman 		return errno;
327165e5d07STal Shnaiderman 	}
328165e5d07STal Shnaiderman 	return 0;
329165e5d07STal Shnaiderman }
330165e5d07STal Shnaiderman 
3317525ebd8STal Shnaiderman alignas(RTE_CACHE_LINE_SIZE)
3327525ebd8STal Shnaiderman const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){
3337525ebd8STal Shnaiderman 	.version = MLX5_GLUE_VERSION,
3347525ebd8STal Shnaiderman 	.get_device_list = mlx5_glue_devx_get_device_list,
3357525ebd8STal Shnaiderman 	.free_device_list = mlx5_glue_devx_free_device_list,
3367525ebd8STal Shnaiderman 	.open_device = mlx5_glue_devx_open_device,
3377525ebd8STal Shnaiderman 	.close_device = mlx5_glue_devx_close_device,
3387525ebd8STal Shnaiderman 	.query_device = mlx5_glue_devx_query_device,
3397525ebd8STal Shnaiderman 	.query_hca_iseg = mlx5_glue_devx_query_hca_iseg_mapping,
3407525ebd8STal Shnaiderman 	.devx_obj_create = mlx5_glue_devx_obj_create,
3417525ebd8STal Shnaiderman 	.devx_obj_destroy = mlx5_glue_devx_obj_destroy,
3427525ebd8STal Shnaiderman 	.devx_obj_query = mlx5_glue_devx_obj_query,
3437525ebd8STal Shnaiderman 	.devx_obj_modify = mlx5_glue_devx_obj_modify,
3447525ebd8STal Shnaiderman 	.devx_general_cmd = mlx5_glue_devx_general_cmd,
3457525ebd8STal Shnaiderman 	.devx_umem_reg = mlx5_glue_devx_umem_reg,
3467525ebd8STal Shnaiderman 	.devx_umem_dereg = mlx5_glue_devx_umem_dereg,
3477525ebd8STal Shnaiderman 	.devx_alloc_uar = mlx5_glue_devx_alloc_uar,
3487525ebd8STal Shnaiderman 	.devx_free_uar = mlx5_glue_devx_free_uar,
3497525ebd8STal Shnaiderman 	.devx_fs_rule_add = mlx5_glue_devx_fs_rule_add,
3507525ebd8STal Shnaiderman 	.devx_fs_rule_del = mlx5_glue_devx_fs_rule_del,
3517525ebd8STal Shnaiderman 	.devx_query_eqn = mlx5_glue_devx_query_eqn,
35299d7c45cSTal Shnaiderman 	.query_rt_values = mlx5_glue_query_rt_values,
353165e5d07STal Shnaiderman 	.devx_init_showdown_event = mlx5_glue_devx_init_showdown_event,
3547525ebd8STal Shnaiderman };
355