1 /******************************************************************************
2 *
3 * Copyright(c) 2019 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _HAL_FW_C_
16 #include "hal_headers.h"
17
_hal_send_fwdl_hub_msg(struct rtw_phl_com_t * phl_com,u8 dl_ok)18 static void _hal_send_fwdl_hub_msg(struct rtw_phl_com_t *phl_com, u8 dl_ok)
19 {
20 struct phl_msg msg = {0};
21 u16 evt_id = (dl_ok) ? MSG_EVT_FWDL_OK : MSG_EVT_FWDL_FAIL;
22
23 msg.inbuf = NULL;
24 msg.inlen = 0;
25 SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_PHY_MGNT);
26 SET_MSG_EVT_ID_FIELD(msg.msg_id, evt_id);
27 msg.band_idx = HW_BAND_0;
28 rtw_phl_msg_hub_hal_send(phl_com, NULL, &msg);
29 }
30
_hal_fw_log_set(struct rtw_hal_fw_log_cfg * fl_cfg,u8 type,u32 value)31 static void _hal_fw_log_set(struct rtw_hal_fw_log_cfg *fl_cfg, u8 type, u32 value)
32 {
33 switch(type) {
34 case FL_CFG_TYPE_LEVEL:
35 fl_cfg->level = value;
36 break;
37
38 case FL_CFG_TYPE_OUTPUT:
39 fl_cfg->output |= value;
40 break;
41
42 case FL_CFG_TYPE_COMP:
43 fl_cfg->comp |= value;
44 break;
45
46 case FL_CFG_TYPE_COMP_EXT:
47 fl_cfg->comp_ext |= value;
48 break;
49
50 default:
51 break;
52 }
53 }
54
_hal_fw_log_clr(struct rtw_hal_fw_log_cfg * fl_cfg,u8 type,u32 value)55 static void _hal_fw_log_clr(struct rtw_hal_fw_log_cfg *fl_cfg, u8 type, u32 value)
56 {
57 switch(type) {
58 case FL_CFG_TYPE_LEVEL:
59 break;
60
61 case FL_CFG_TYPE_OUTPUT:
62 fl_cfg->output &= (~value);
63 break;
64
65 case FL_CFG_TYPE_COMP:
66 fl_cfg->comp &= (~value);
67 break;
68
69 case FL_CFG_TYPE_COMP_EXT:
70 fl_cfg->comp_ext &= (~value);
71 break;
72
73 default:
74 break;
75 }
76 }
77
_hal_fw_log_info(struct rtw_hal_fw_log_cfg * fl_cfg)78 static void _hal_fw_log_info(struct rtw_hal_fw_log_cfg *fl_cfg)
79 {
80 PHL_PRINT("%s: level %d, output 0x%08x, comp 0x%08x, comp ext 0x%08x.\n",
81 __func__,
82 fl_cfg->level,
83 fl_cfg->output,
84 fl_cfg->comp,
85 fl_cfg->comp_ext);
86 }
87
rtw_hal_fw_log_cfg(void * hal,u8 op,u8 type,u32 value)88 enum rtw_hal_status rtw_hal_fw_log_cfg(void *hal, u8 op, u8 type, u32 value)
89 {
90 struct rtw_hal_com_t *hal_com = (struct rtw_hal_com_t *)hal;
91 static struct rtw_hal_fw_log_cfg fl_cfg = {0};
92
93 switch(op) {
94 case FL_CFG_OP_SET:
95 _hal_fw_log_set(&fl_cfg, type, value);
96 break;
97 case FL_CFG_OP_CLR:
98 _hal_fw_log_clr(&fl_cfg, type, value);
99 break;
100 case FL_CFG_OP_INFO:
101 _hal_fw_log_info(&fl_cfg);
102 break;
103 default:
104 break;
105 }
106
107 return rtw_hal_mac_fw_log_cfg(hal_com, &fl_cfg);
108 }
109
hal_fw_en_basic_log(struct rtw_hal_com_t * hal_com)110 void hal_fw_en_basic_log(struct rtw_hal_com_t *hal_com)
111 {
112 rtw_hal_fw_log_cfg(hal_com, FL_CFG_OP_SET, FL_CFG_TYPE_LEVEL,
113 FL_LV_LOUD);
114 rtw_hal_fw_log_cfg(hal_com, FL_CFG_OP_SET, FL_CFG_TYPE_OUTPUT,
115 FL_OP_C2H);
116 rtw_hal_fw_log_cfg(hal_com, FL_CFG_OP_SET, FL_CFG_TYPE_COMP,
117 FL_COMP_TASK);
118 }
119
rtw_hal_cfg_fw_ps_log(void * hal,u8 en)120 enum rtw_hal_status rtw_hal_cfg_fw_ps_log(void *hal, u8 en)
121 {
122 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
123
124 if(en)
125 return rtw_hal_fw_log_cfg(hal_info->hal_com, FL_CFG_OP_SET,
126 FL_CFG_TYPE_COMP, FL_COMP_PS);
127 else
128 return rtw_hal_fw_log_cfg(hal_info->hal_com, FL_CFG_OP_CLR,
129 FL_CFG_TYPE_COMP, FL_COMP_PS);
130 }
131
rtw_hal_cfg_fw_mcc_log(void * hal,u8 en)132 enum rtw_hal_status rtw_hal_cfg_fw_mcc_log(void *hal, u8 en)
133 {
134 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
135 enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
136
137 if(en)
138 status = rtw_hal_fw_log_cfg(hal_info->hal_com, FL_CFG_OP_SET,
139 FL_CFG_TYPE_COMP, MAC_AX_FL_COMP_MCC);
140 else
141 status = rtw_hal_fw_log_cfg(hal_info->hal_com, FL_CFG_OP_CLR,
142 FL_CFG_TYPE_COMP, MAC_AX_FL_COMP_MCC);
143
144 PHL_INFO("rtw_hal_cfg_fw_mcc_log(): status(%d), en(%d)\n", status, en);
145 return status;
146 }
147
148 enum rtw_hal_status
rtw_hal_download_fw(struct rtw_phl_com_t * phl_com,void * hal)149 rtw_hal_download_fw(struct rtw_phl_com_t *phl_com, void *hal)
150 {
151 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
152 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
153 struct rtw_fw_info_t *fw_info = &phl_com->fw_info;
154
155 FUNCIN_WSTS(hal_status);
156
157 if (!fw_info->fw_en)
158 return hal_status;
159
160 if (fw_info->dlrom_en) {
161 hal_status = rtw_hal_mac_romdl(hal_info, fw_info->rom_buff,
162 fw_info->rom_size);
163
164 if (hal_status != RTW_HAL_STATUS_SUCCESS)
165 return hal_status;
166 }
167
168 hal_status = rtw_hal_mac_disable_cpu(hal_info);
169 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
170 PHL_ERR("disable cpu fail!\n");
171 return hal_status;
172 }
173
174 hal_status = rtw_hal_mac_enable_cpu(hal_info, 0, true);
175 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
176 PHL_ERR("enable cpu fail!\n");
177 return hal_status;
178 }
179
180 if (fw_info->dlram_en) {
181 hal_status = rtw_hal_mac_fwdl(hal_info, fw_info->ram_buff,
182 fw_info->ram_size);
183 }
184
185 _hal_send_fwdl_hub_msg(phl_com, (!hal_status) ? true : false);
186
187 FUNCOUT_WSTS(hal_status);
188
189 return hal_status;
190 }
191
192 enum rtw_hal_status
rtw_hal_redownload_fw(struct rtw_phl_com_t * phl_com,void * hal)193 rtw_hal_redownload_fw(struct rtw_phl_com_t *phl_com, void *hal)
194 {
195 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
196 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
197 struct rtw_fw_info_t *fw_info = &phl_com->fw_info;
198
199 FUNCIN_WSTS(hal_status);
200
201 /* Disable/Enable CPU is necessary first when FWDL from files */
202 if(fw_info->dlram_en && fw_info->fw_src == RTW_FW_SRC_EXTNAL) {
203
204 hal_status = rtw_hal_mac_disable_cpu(hal_info);
205 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
206 PHL_ERR("disable cpu fail!\n");
207 return hal_status;
208 }
209
210 hal_status = rtw_hal_mac_enable_cpu(hal_info, 0, true);
211 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
212 PHL_ERR("enable cpu fail!\n");
213 return hal_status;
214 }
215 }
216
217 if (fw_info->dlram_en) {
218 if(fw_info->fw_src == RTW_FW_SRC_EXTNAL) {
219 hal_status = rtw_hal_mac_fwdl(hal_info, fw_info->ram_buff,
220 fw_info->ram_size);
221 } else {
222 hal_status = rtw_hal_mac_enable_fw(hal_info, fw_info->fw_type);
223 }
224 }
225
226 rtw_phl_pkt_ofld_reset_all_entry(phl_com);
227 rtw_hal_rf_config_radio_to_fw(hal_info);
228
229 _hal_send_fwdl_hub_msg(phl_com, (!hal_status) ? true : false);
230
231 FUNCOUT_WSTS(hal_status);
232
233 return hal_status;
234 }
235
rtw_hal_fw_dbg_dump(void * hal)236 void rtw_hal_fw_dbg_dump(void *hal)
237 {
238 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
239
240 rtw_hal_mac_fw_dbg_dump(hal_info);
241 }
242
rtw_hal_get_fw_status(void * h)243 enum rtw_fw_status rtw_hal_get_fw_status(void *h)
244 {
245 struct hal_info_t *hal = (struct hal_info_t *)h;
246 struct mac_ax_adapter *mac = hal_to_mac(hal);
247 struct mac_ax_ops *hal_mac_ops = mac->ops;
248 u32 mac_fw_sts;
249
250 mac_fw_sts = hal_mac_ops->get_fw_status(mac);
251
252 switch (mac_fw_sts) {
253 case MACSUCCESS:
254 return RTW_FW_STATUS_OK;
255 case MACNOFW:
256 return RTW_FW_STATUS_NOFW;
257 case MACFWASSERT:
258 return RTW_FW_STATUS_ASSERT;
259 case MACFWEXCEP:
260 return RTW_FW_STATUS_EXCEP;
261 case MACFWRXI300:
262 return RTW_FW_STATUS_RXI300;
263 case MACFWPCHANG:
264 return RTW_FW_STATUS_HANG;
265 default:
266 return RTW_FW_STATUS_OK;
267 }
268 }