1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief File containing command specific definitions for the
9  * FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "host_rpu_umac_if.h"
13 #include "common/hal_api_common.h"
14 #include "common/fmac_structs_common.h"
15 #include "common/fmac_util.h"
16 
umac_cmd_alloc(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,int type,int len)17 struct host_rpu_msg *umac_cmd_alloc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
18 				    int type,
19 				    int len)
20 {
21 	struct host_rpu_msg *umac_cmd = NULL;
22 
23 	umac_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*umac_cmd) + len);
24 
25 	if (!umac_cmd) {
26 		nrf_wifi_osal_log_err("%s: Failed to allocate UMAC cmd",
27 				      __func__);
28 		goto out;
29 	}
30 
31 	umac_cmd->type = type;
32 	umac_cmd->hdr.len = sizeof(*umac_cmd) + len;
33 
34 out:
35 	return umac_cmd;
36 }
37 
38 
umac_cmd_cfg(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * params,int len)39 enum nrf_wifi_status umac_cmd_cfg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
40 				  void *params,
41 				  int len)
42 {
43 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
44 	struct host_rpu_msg *umac_cmd = NULL;
45 
46 	if (!fmac_dev_ctx->fw_init_done) {
47 		struct nrf_wifi_umac_hdr *umac_hdr = NULL;
48 
49 		umac_hdr = (struct nrf_wifi_umac_hdr *)params;
50 		nrf_wifi_osal_log_err("%s: UMAC buff config not yet done(%d)",
51 				      __func__,
52 				      umac_hdr->cmd_evnt);
53 		goto out;
54 	}
55 
56 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
57 				  NRF_WIFI_HOST_RPU_MSG_TYPE_UMAC,
58 				  len);
59 
60 	if (!umac_cmd) {
61 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
62 				      __func__);
63 		goto out;
64 	}
65 
66 	nrf_wifi_osal_mem_cpy(umac_cmd->msg,
67 			      params,
68 			      len);
69 
70 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
71 					    umac_cmd,
72 					    (sizeof(*umac_cmd) + len));
73 
74 	nrf_wifi_osal_log_dbg("%s: Command %d sent to RPU",
75 			      __func__,
76 			      ((struct nrf_wifi_umac_hdr *)params)->cmd_evnt);
77 
78 out:
79 	return status;
80 }
81 
82 
umac_cmd_deinit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)83 enum nrf_wifi_status umac_cmd_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
84 {
85 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
86 	struct host_rpu_msg *umac_cmd = NULL;
87 	struct nrf_wifi_cmd_sys_deinit *umac_cmd_data = NULL;
88 	unsigned int len = 0;
89 
90 	len = sizeof(*umac_cmd_data);
91 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
92 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
93 				  len);
94 	if (!umac_cmd) {
95 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
96 				      __func__);
97 		goto out;
98 	}
99 	umac_cmd_data = (struct nrf_wifi_cmd_sys_deinit *)(umac_cmd->msg);
100 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_DEINIT;
101 	umac_cmd_data->sys_head.len = len;
102 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
103 					    umac_cmd,
104 					    (sizeof(*umac_cmd) + len));
105 out:
106 	return status;
107 }
108 
umac_cmd_srcoex(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * cmd,unsigned int cmd_len)109 enum nrf_wifi_status umac_cmd_srcoex(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
110 				     void *cmd,
111 				     unsigned int cmd_len)
112 {
113 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
114 	struct host_rpu_msg *umac_cmd = NULL;
115 	struct nrf_wifi_cmd_coex_config *umac_cmd_data = NULL;
116 	int len = 0;
117 
118 	len = sizeof(*umac_cmd_data)+cmd_len;
119 
120 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
121 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
122 				  len);
123 
124 	if (!umac_cmd) {
125 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
126 				      __func__);
127 		goto out;
128 	}
129 
130 	umac_cmd_data = (struct nrf_wifi_cmd_coex_config *)(umac_cmd->msg);
131 
132 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_SRCOEX;
133 	umac_cmd_data->sys_head.len = len;
134 	umac_cmd_data->coex_config_info.len = cmd_len;
135 
136 	nrf_wifi_osal_mem_cpy(umac_cmd_data->coex_config_info.coex_cmd,
137 			      cmd,
138 			      cmd_len);
139 
140 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
141 					    umac_cmd,
142 					    (sizeof(*umac_cmd) + len));
143 out:
144 	return status;
145 
146 
147 }
148 
149 
umac_cmd_prog_stats_reset(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)150 enum nrf_wifi_status umac_cmd_prog_stats_reset(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
151 {
152 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
153 	struct host_rpu_msg *umac_cmd = NULL;
154 	struct nrf_wifi_cmd_reset_stats *umac_cmd_data = NULL;
155 	int len = 0;
156 
157 	len = sizeof(*umac_cmd_data);
158 
159 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
160 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
161 				  len);
162 	if (!umac_cmd) {
163 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
164 				      __func__);
165 		goto out;
166 	}
167 
168 	umac_cmd_data = (struct nrf_wifi_cmd_reset_stats *)(umac_cmd->msg);
169 
170 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RESET_STATISTICS;
171 	umac_cmd_data->sys_head.len = len;
172 
173 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
174 					    umac_cmd,
175 					    (sizeof(*umac_cmd) + len));
176 
177 out:
178 	return status;
179 }
180