1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14 #include "halmac_88xx_cfg.h"
15 
16 /**
17  * halmac_init_adapter_para_88xx() - int halmac adapter
18  * @halmac_adapter
19  *
20  * SD1 internal use
21  *
22  * Author : KaiYuan Chang/Ivan Lin
23  * Return : void
24  */
halmac_init_adapter_para_88xx(struct halmac_adapter * halmac_adapter)25 void halmac_init_adapter_para_88xx(struct halmac_adapter *halmac_adapter)
26 {
27 	halmac_adapter->api_record.array_wptr = 0;
28 	halmac_adapter->hal_adapter_backup = halmac_adapter;
29 	halmac_adapter->hal_efuse_map = (u8 *)NULL;
30 	halmac_adapter->hal_efuse_map_valid = false;
31 	halmac_adapter->efuse_end = 0;
32 	halmac_adapter->hal_mac_addr[0].address_l_h.address_low = 0;
33 	halmac_adapter->hal_mac_addr[0].address_l_h.address_high = 0;
34 	halmac_adapter->hal_mac_addr[1].address_l_h.address_low = 0;
35 	halmac_adapter->hal_mac_addr[1].address_l_h.address_high = 0;
36 	halmac_adapter->hal_bss_addr[0].address_l_h.address_low = 0;
37 	halmac_adapter->hal_bss_addr[0].address_l_h.address_high = 0;
38 	halmac_adapter->hal_bss_addr[1].address_l_h.address_low = 0;
39 	halmac_adapter->hal_bss_addr[1].address_l_h.address_high = 0;
40 
41 	halmac_adapter->low_clk = false;
42 	halmac_adapter->max_download_size = HALMAC_FW_MAX_DL_SIZE_88XX;
43 
44 	/* Init LPS Option */
45 	halmac_adapter->fwlps_option.mode = 0x01; /*0:Active 1:LPS 2:WMMPS*/
46 	halmac_adapter->fwlps_option.awake_interval = 1;
47 	halmac_adapter->fwlps_option.enter_32K = 1;
48 	halmac_adapter->fwlps_option.clk_request = 0;
49 	halmac_adapter->fwlps_option.rlbm = 0;
50 	halmac_adapter->fwlps_option.smart_ps = 0;
51 	halmac_adapter->fwlps_option.awake_interval = 1;
52 	halmac_adapter->fwlps_option.all_queue_uapsd = 0;
53 	halmac_adapter->fwlps_option.pwr_state = 0;
54 	halmac_adapter->fwlps_option.low_pwr_rx_beacon = 0;
55 	halmac_adapter->fwlps_option.ant_auto_switch = 0;
56 	halmac_adapter->fwlps_option.ps_allow_bt_high_priority = 0;
57 	halmac_adapter->fwlps_option.protect_bcn = 0;
58 	halmac_adapter->fwlps_option.silence_period = 0;
59 	halmac_adapter->fwlps_option.fast_bt_connect = 0;
60 	halmac_adapter->fwlps_option.two_antenna_en = 0;
61 	halmac_adapter->fwlps_option.adopt_user_setting = 1;
62 	halmac_adapter->fwlps_option.drv_bcn_early_shift = 0;
63 
64 	halmac_adapter->config_para_info.cfg_para_buf = NULL;
65 	halmac_adapter->config_para_info.para_buf_w = NULL;
66 	halmac_adapter->config_para_info.para_num = 0;
67 	halmac_adapter->config_para_info.full_fifo_mode = false;
68 	halmac_adapter->config_para_info.para_buf_size = 0;
69 	halmac_adapter->config_para_info.avai_para_buf_size = 0;
70 	halmac_adapter->config_para_info.offset_accumulation = 0;
71 	halmac_adapter->config_para_info.value_accumulation = 0;
72 	halmac_adapter->config_para_info.datapack_segment = 0;
73 
74 	halmac_adapter->ch_sw_info.ch_info_buf = NULL;
75 	halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
76 	halmac_adapter->ch_sw_info.extra_info_en = 0;
77 	halmac_adapter->ch_sw_info.buf_size = 0;
78 	halmac_adapter->ch_sw_info.avai_buf_size = 0;
79 	halmac_adapter->ch_sw_info.total_size = 0;
80 	halmac_adapter->ch_sw_info.ch_num = 0;
81 
82 	halmac_adapter->drv_info_size = 0;
83 
84 	memset(halmac_adapter->api_record.api_array, HALMAC_API_STUFF,
85 	       sizeof(halmac_adapter->api_record.api_array));
86 
87 	halmac_adapter->txff_allocation.tx_fifo_pg_num = 0;
88 	halmac_adapter->txff_allocation.ac_q_pg_num = 0;
89 	halmac_adapter->txff_allocation.rsvd_pg_bndy = 0;
90 	halmac_adapter->txff_allocation.rsvd_drv_pg_bndy = 0;
91 	halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy = 0;
92 	halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy = 0;
93 	halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy = 0;
94 	halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy = 0;
95 	halmac_adapter->txff_allocation.pub_queue_pg_num = 0;
96 	halmac_adapter->txff_allocation.high_queue_pg_num = 0;
97 	halmac_adapter->txff_allocation.low_queue_pg_num = 0;
98 	halmac_adapter->txff_allocation.normal_queue_pg_num = 0;
99 	halmac_adapter->txff_allocation.extra_queue_pg_num = 0;
100 
101 	halmac_adapter->txff_allocation.la_mode = HALMAC_LA_MODE_DISABLE;
102 	halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
103 		HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
104 
105 	halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
106 	halmac_init_state_machine_88xx(halmac_adapter);
107 }
108 
109 /**
110  * halmac_init_adapter_dynamic_para_88xx() - int halmac adapter
111  * @halmac_adapter
112  *
113  * SD1 internal use
114  *
115  * Author : KaiYuan Chang/Ivan Lin
116  * Return : void
117  */
halmac_init_adapter_dynamic_para_88xx(struct halmac_adapter * halmac_adapter)118 void halmac_init_adapter_dynamic_para_88xx(
119 	struct halmac_adapter *halmac_adapter)
120 {
121 	halmac_adapter->h2c_packet_seq = 0;
122 	halmac_adapter->h2c_buf_free_space = 0;
123 	halmac_adapter->gen_info_valid = false;
124 }
125 
126 /**
127  * halmac_init_state_machine_88xx() - init halmac software state machine
128  * @halmac_adapter
129  *
130  * SD1 internal use.
131  *
132  * Author : KaiYuan Chang/Ivan Lin
133  * Return : void
134  */
halmac_init_state_machine_88xx(struct halmac_adapter * halmac_adapter)135 void halmac_init_state_machine_88xx(struct halmac_adapter *halmac_adapter)
136 {
137 	struct halmac_state *state = &halmac_adapter->halmac_state;
138 
139 	halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
140 
141 	state->api_state = HALMAC_API_STATE_INIT;
142 
143 	state->dlfw_state = HALMAC_DLFW_NONE;
144 	state->mac_power = HALMAC_MAC_POWER_OFF;
145 	state->ps_state = HALMAC_PS_STATE_UNDEFINE;
146 }
147 
148 /**
149  * halmac_mount_api_88xx() - attach functions to function pointer
150  * @halmac_adapter
151  *
152  * SD1 internal use
153  *
154  * Author : KaiYuan Chang/Ivan Lin
155  * Return : enum halmac_ret_status
156  */
157 enum halmac_ret_status
halmac_mount_api_88xx(struct halmac_adapter * halmac_adapter)158 halmac_mount_api_88xx(struct halmac_adapter *halmac_adapter)
159 {
160 	void *driver_adapter = halmac_adapter->driver_adapter;
161 	struct halmac_api *halmac_api = (struct halmac_api *)NULL;
162 
163 	halmac_adapter->halmac_api =
164 		kzalloc(sizeof(struct halmac_api), GFP_KERNEL);
165 	if (!halmac_adapter->halmac_api)
166 		return HALMAC_RET_MALLOC_FAIL;
167 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
168 
169 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
170 			HALMAC_SVN_VER_88XX "\n");
171 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
172 			"HALMAC_MAJOR_VER_88XX = %x\n", HALMAC_MAJOR_VER_88XX);
173 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
174 			"HALMAC_PROTOTYPE_88XX = %x\n",
175 			HALMAC_PROTOTYPE_VER_88XX);
176 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
177 			"HALMAC_MINOR_VER_88XX = %x\n", HALMAC_MINOR_VER_88XX);
178 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
179 			"HALMAC_PATCH_VER_88XX = %x\n", HALMAC_PATCH_VER_88XX);
180 
181 	/* Mount function pointer */
182 	halmac_api->halmac_download_firmware = halmac_download_firmware_88xx;
183 	halmac_api->halmac_free_download_firmware =
184 		halmac_free_download_firmware_88xx;
185 	halmac_api->halmac_get_fw_version = halmac_get_fw_version_88xx;
186 	halmac_api->halmac_cfg_mac_addr = halmac_cfg_mac_addr_88xx;
187 	halmac_api->halmac_cfg_bssid = halmac_cfg_bssid_88xx;
188 	halmac_api->halmac_cfg_multicast_addr = halmac_cfg_multicast_addr_88xx;
189 	halmac_api->halmac_pre_init_system_cfg =
190 		halmac_pre_init_system_cfg_88xx;
191 	halmac_api->halmac_init_system_cfg = halmac_init_system_cfg_88xx;
192 	halmac_api->halmac_init_edca_cfg = halmac_init_edca_cfg_88xx;
193 	halmac_api->halmac_cfg_operation_mode = halmac_cfg_operation_mode_88xx;
194 	halmac_api->halmac_cfg_ch_bw = halmac_cfg_ch_bw_88xx;
195 	halmac_api->halmac_cfg_bw = halmac_cfg_bw_88xx;
196 	halmac_api->halmac_init_wmac_cfg = halmac_init_wmac_cfg_88xx;
197 	halmac_api->halmac_init_mac_cfg = halmac_init_mac_cfg_88xx;
198 	halmac_api->halmac_init_sdio_cfg = halmac_init_sdio_cfg_88xx;
199 	halmac_api->halmac_init_usb_cfg = halmac_init_usb_cfg_88xx;
200 	halmac_api->halmac_init_pcie_cfg = halmac_init_pcie_cfg_88xx;
201 	halmac_api->halmac_deinit_sdio_cfg = halmac_deinit_sdio_cfg_88xx;
202 	halmac_api->halmac_deinit_usb_cfg = halmac_deinit_usb_cfg_88xx;
203 	halmac_api->halmac_deinit_pcie_cfg = halmac_deinit_pcie_cfg_88xx;
204 	halmac_api->halmac_dump_efuse_map = halmac_dump_efuse_map_88xx;
205 	halmac_api->halmac_dump_efuse_map_bt = halmac_dump_efuse_map_bt_88xx;
206 	halmac_api->halmac_write_efuse_bt = halmac_write_efuse_bt_88xx;
207 	halmac_api->halmac_dump_logical_efuse_map =
208 		halmac_dump_logical_efuse_map_88xx;
209 	halmac_api->halmac_pg_efuse_by_map = halmac_pg_efuse_by_map_88xx;
210 	halmac_api->halmac_get_efuse_size = halmac_get_efuse_size_88xx;
211 	halmac_api->halmac_get_efuse_available_size =
212 		halmac_get_efuse_available_size_88xx;
213 	halmac_api->halmac_get_c2h_info = halmac_get_c2h_info_88xx;
214 
215 	halmac_api->halmac_get_logical_efuse_size =
216 		halmac_get_logical_efuse_size_88xx;
217 
218 	halmac_api->halmac_write_logical_efuse =
219 		halmac_write_logical_efuse_88xx;
220 	halmac_api->halmac_read_logical_efuse = halmac_read_logical_efuse_88xx;
221 
222 	halmac_api->halmac_cfg_fwlps_option = halmac_cfg_fwlps_option_88xx;
223 	halmac_api->halmac_cfg_fwips_option = halmac_cfg_fwips_option_88xx;
224 	halmac_api->halmac_enter_wowlan = halmac_enter_wowlan_88xx;
225 	halmac_api->halmac_leave_wowlan = halmac_leave_wowlan_88xx;
226 	halmac_api->halmac_enter_ps = halmac_enter_ps_88xx;
227 	halmac_api->halmac_leave_ps = halmac_leave_ps_88xx;
228 	halmac_api->halmac_h2c_lb = halmac_h2c_lb_88xx;
229 	halmac_api->halmac_debug = halmac_debug_88xx;
230 	halmac_api->halmac_cfg_parameter = halmac_cfg_parameter_88xx;
231 	halmac_api->halmac_update_datapack = halmac_update_datapack_88xx;
232 	halmac_api->halmac_run_datapack = halmac_run_datapack_88xx;
233 	halmac_api->halmac_cfg_drv_info = halmac_cfg_drv_info_88xx;
234 	halmac_api->halmac_send_bt_coex = halmac_send_bt_coex_88xx;
235 	halmac_api->halmac_verify_platform_api =
236 		halmac_verify_platform_api_88xx;
237 	halmac_api->halmac_update_packet = halmac_update_packet_88xx;
238 	halmac_api->halmac_bcn_ie_filter = halmac_bcn_ie_filter_88xx;
239 	halmac_api->halmac_cfg_txbf = halmac_cfg_txbf_88xx;
240 	halmac_api->halmac_cfg_mumimo = halmac_cfg_mumimo_88xx;
241 	halmac_api->halmac_cfg_sounding = halmac_cfg_sounding_88xx;
242 	halmac_api->halmac_del_sounding = halmac_del_sounding_88xx;
243 	halmac_api->halmac_su_bfer_entry_init = halmac_su_bfer_entry_init_88xx;
244 	halmac_api->halmac_su_bfee_entry_init = halmac_su_bfee_entry_init_88xx;
245 	halmac_api->halmac_mu_bfer_entry_init = halmac_mu_bfer_entry_init_88xx;
246 	halmac_api->halmac_mu_bfee_entry_init = halmac_mu_bfee_entry_init_88xx;
247 	halmac_api->halmac_su_bfer_entry_del = halmac_su_bfer_entry_del_88xx;
248 	halmac_api->halmac_su_bfee_entry_del = halmac_su_bfee_entry_del_88xx;
249 	halmac_api->halmac_mu_bfer_entry_del = halmac_mu_bfer_entry_del_88xx;
250 	halmac_api->halmac_mu_bfee_entry_del = halmac_mu_bfee_entry_del_88xx;
251 
252 	halmac_api->halmac_add_ch_info = halmac_add_ch_info_88xx;
253 	halmac_api->halmac_add_extra_ch_info = halmac_add_extra_ch_info_88xx;
254 	halmac_api->halmac_ctrl_ch_switch = halmac_ctrl_ch_switch_88xx;
255 	halmac_api->halmac_p2pps = halmac_p2pps_88xx;
256 	halmac_api->halmac_clear_ch_info = halmac_clear_ch_info_88xx;
257 	halmac_api->halmac_send_general_info = halmac_send_general_info_88xx;
258 
259 	halmac_api->halmac_start_iqk = halmac_start_iqk_88xx;
260 	halmac_api->halmac_ctrl_pwr_tracking = halmac_ctrl_pwr_tracking_88xx;
261 	halmac_api->halmac_psd = halmac_psd_88xx;
262 	halmac_api->halmac_cfg_la_mode = halmac_cfg_la_mode_88xx;
263 	halmac_api->halmac_cfg_rx_fifo_expanding_mode =
264 		halmac_cfg_rx_fifo_expanding_mode_88xx;
265 
266 	halmac_api->halmac_config_security = halmac_config_security_88xx;
267 	halmac_api->halmac_get_used_cam_entry_num =
268 		halmac_get_used_cam_entry_num_88xx;
269 	halmac_api->halmac_read_cam_entry = halmac_read_cam_entry_88xx;
270 	halmac_api->halmac_write_cam = halmac_write_cam_88xx;
271 	halmac_api->halmac_clear_cam_entry = halmac_clear_cam_entry_88xx;
272 
273 	halmac_api->halmac_get_hw_value = halmac_get_hw_value_88xx;
274 	halmac_api->halmac_set_hw_value = halmac_set_hw_value_88xx;
275 
276 	halmac_api->halmac_cfg_drv_rsvd_pg_num =
277 		halmac_cfg_drv_rsvd_pg_num_88xx;
278 	halmac_api->halmac_get_chip_version = halmac_get_chip_version_88xx;
279 
280 	halmac_api->halmac_query_status = halmac_query_status_88xx;
281 	halmac_api->halmac_reset_feature = halmac_reset_feature_88xx;
282 	halmac_api->halmac_check_fw_status = halmac_check_fw_status_88xx;
283 	halmac_api->halmac_dump_fw_dmem = halmac_dump_fw_dmem_88xx;
284 	halmac_api->halmac_cfg_max_dl_size = halmac_cfg_max_dl_size_88xx;
285 
286 	halmac_api->halmac_dump_fifo = halmac_dump_fifo_88xx;
287 	halmac_api->halmac_get_fifo_size = halmac_get_fifo_size_88xx;
288 
289 	halmac_api->halmac_chk_txdesc = halmac_chk_txdesc_88xx;
290 	halmac_api->halmac_dl_drv_rsvd_page = halmac_dl_drv_rsvd_page_88xx;
291 	halmac_api->halmac_cfg_csi_rate = halmac_cfg_csi_rate_88xx;
292 
293 	halmac_api->halmac_sdio_cmd53_4byte = halmac_sdio_cmd53_4byte_88xx;
294 	halmac_api->halmac_txfifo_is_empty = halmac_txfifo_is_empty_88xx;
295 
296 	if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
297 		halmac_api->halmac_cfg_rx_aggregation =
298 			halmac_cfg_rx_aggregation_88xx_sdio;
299 		halmac_api->halmac_init_interface_cfg =
300 			halmac_init_sdio_cfg_88xx;
301 		halmac_api->halmac_deinit_interface_cfg =
302 			halmac_deinit_sdio_cfg_88xx;
303 		halmac_api->halmac_reg_read_8 = halmac_reg_read_8_sdio_88xx;
304 		halmac_api->halmac_reg_write_8 = halmac_reg_write_8_sdio_88xx;
305 		halmac_api->halmac_reg_read_16 = halmac_reg_read_16_sdio_88xx;
306 		halmac_api->halmac_reg_write_16 = halmac_reg_write_16_sdio_88xx;
307 		halmac_api->halmac_reg_read_32 = halmac_reg_read_32_sdio_88xx;
308 		halmac_api->halmac_reg_write_32 = halmac_reg_write_32_sdio_88xx;
309 		halmac_api->halmac_reg_read_indirect_32 =
310 			halmac_reg_read_indirect_32_sdio_88xx;
311 		halmac_api->halmac_reg_sdio_cmd53_read_n =
312 			halmac_reg_read_nbyte_sdio_88xx;
313 	} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
314 		halmac_api->halmac_cfg_rx_aggregation =
315 			halmac_cfg_rx_aggregation_88xx_usb;
316 		halmac_api->halmac_init_interface_cfg =
317 			halmac_init_usb_cfg_88xx;
318 		halmac_api->halmac_deinit_interface_cfg =
319 			halmac_deinit_usb_cfg_88xx;
320 		halmac_api->halmac_reg_read_8 = halmac_reg_read_8_usb_88xx;
321 		halmac_api->halmac_reg_write_8 = halmac_reg_write_8_usb_88xx;
322 		halmac_api->halmac_reg_read_16 = halmac_reg_read_16_usb_88xx;
323 		halmac_api->halmac_reg_write_16 = halmac_reg_write_16_usb_88xx;
324 		halmac_api->halmac_reg_read_32 = halmac_reg_read_32_usb_88xx;
325 		halmac_api->halmac_reg_write_32 = halmac_reg_write_32_usb_88xx;
326 	} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
327 		halmac_api->halmac_cfg_rx_aggregation =
328 			halmac_cfg_rx_aggregation_88xx_pcie;
329 		halmac_api->halmac_init_interface_cfg =
330 			halmac_init_pcie_cfg_88xx;
331 		halmac_api->halmac_deinit_interface_cfg =
332 			halmac_deinit_pcie_cfg_88xx;
333 		halmac_api->halmac_reg_read_8 = halmac_reg_read_8_pcie_88xx;
334 		halmac_api->halmac_reg_write_8 = halmac_reg_write_8_pcie_88xx;
335 		halmac_api->halmac_reg_read_16 = halmac_reg_read_16_pcie_88xx;
336 		halmac_api->halmac_reg_write_16 = halmac_reg_write_16_pcie_88xx;
337 		halmac_api->halmac_reg_read_32 = halmac_reg_read_32_pcie_88xx;
338 		halmac_api->halmac_reg_write_32 = halmac_reg_write_32_pcie_88xx;
339 	} else {
340 		pr_err("Set halmac io function Error!!\n");
341 	}
342 
343 	halmac_api->halmac_set_bulkout_num = halmac_set_bulkout_num_88xx;
344 	halmac_api->halmac_get_sdio_tx_addr = halmac_get_sdio_tx_addr_88xx;
345 	halmac_api->halmac_get_usb_bulkout_id = halmac_get_usb_bulkout_id_88xx;
346 	halmac_api->halmac_timer_2s = halmac_timer_2s_88xx;
347 	halmac_api->halmac_fill_txdesc_checksum =
348 		halmac_fill_txdesc_check_sum_88xx;
349 
350 	if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B) {
351 		/*mount 8822b function and data*/
352 		halmac_mount_api_8822b(halmac_adapter);
353 
354 	} else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8821C) {
355 	} else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8814B) {
356 	} else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8197F) {
357 	} else {
358 		pr_err("Chip ID undefine!!\n");
359 		return HALMAC_RET_CHIP_NOT_SUPPORT;
360 	}
361 	return HALMAC_RET_SUCCESS;
362 }
363 
364 /**
365  * halmac_download_firmware_88xx() - download Firmware
366  * @halmac_adapter : the adapter of halmac
367  * @hamacl_fw : firmware bin
368  * @halmac_fw_size : firmware size
369  * Author : KaiYuan Chang/Ivan Lin
370  * Return : enum halmac_ret_status
371  * More details of status code can be found in prototype document
372  */
373 enum halmac_ret_status
halmac_download_firmware_88xx(struct halmac_adapter * halmac_adapter,u8 * hamacl_fw,u32 halmac_fw_size)374 halmac_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
375 			      u8 *hamacl_fw, u32 halmac_fw_size)
376 {
377 	u8 value8;
378 	u8 *file_ptr;
379 	u32 dest;
380 	u16 value16;
381 	u32 restore_index = 0;
382 	u32 halmac_h2c_ver = 0, fw_h2c_ver = 0;
383 	u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
384 	void *driver_adapter = NULL;
385 	struct halmac_api *halmac_api;
386 	struct halmac_restore_info restore_info[DLFW_RESTORE_REG_NUM_88XX];
387 	u32 temp;
388 
389 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
390 		return HALMAC_RET_ADAPTER_INVALID;
391 
392 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
393 		return HALMAC_RET_API_INVALID;
394 
395 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DOWNLOAD_FIRMWARE);
396 
397 	driver_adapter = halmac_adapter->driver_adapter;
398 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
399 
400 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
401 			"%s ==========>\n", __func__);
402 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
403 			"%s start!!\n", __func__);
404 
405 	if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
406 	    halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
407 		pr_err("FW size error!\n");
408 		return HALMAC_RET_FW_SIZE_ERR;
409 	}
410 
411 	fw_h2c_ver = le32_to_cpu(
412 		*((__le32 *)
413 		  (hamacl_fw + HALMAC_FWHDR_OFFSET_H2C_FORMAT_VER_88XX)));
414 	halmac_h2c_ver = H2C_FORMAT_VERSION;
415 	HALMAC_RT_TRACE(
416 		driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
417 		"halmac h2c/c2h format = %x, fw h2c/c2h format = %x!!\n",
418 		halmac_h2c_ver, fw_h2c_ver);
419 	if (fw_h2c_ver != halmac_h2c_ver)
420 		HALMAC_RT_TRACE(
421 			driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
422 			"[WARN]H2C/C2H version between HALMAC and FW is compatible!!\n");
423 
424 	halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
425 
426 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
427 	value8 = (u8)(value8 & ~(BIT(2)));
428 	HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
429 			   value8); /* Disable CPU reset */
430 
431 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
432 	value8 = (u8)(value8 & ~(BIT(0)));
433 	HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
434 
435 	restore_info[restore_index].length = 1;
436 	restore_info[restore_index].mac_register = REG_TXDMA_PQ_MAP + 1;
437 	restore_info[restore_index].value =
438 		HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1);
439 	restore_index++;
440 	value8 = HALMAC_DMA_MAPPING_HIGH << 6;
441 	HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1,
442 			   value8); /* set HIQ to hi priority */
443 
444 	/* DLFW only use HIQ, map HIQ to hi priority */
445 	halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
446 		HALMAC_DMA_MAPPING_HIGH;
447 	restore_info[restore_index].length = 1;
448 	restore_info[restore_index].mac_register = REG_CR;
449 	restore_info[restore_index].value =
450 		HALMAC_REG_READ_8(halmac_adapter, REG_CR);
451 	restore_index++;
452 	restore_info[restore_index].length = 4;
453 	restore_info[restore_index].mac_register = REG_H2CQ_CSR;
454 	restore_info[restore_index].value = BIT(31);
455 	restore_index++;
456 	value8 = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN;
457 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
458 	HALMAC_REG_WRITE_32(halmac_adapter, REG_H2CQ_CSR, BIT(31));
459 
460 	/* Config hi priority queue and public priority queue page number
461 	 * (only for DLFW)
462 	 */
463 	restore_info[restore_index].length = 2;
464 	restore_info[restore_index].mac_register = REG_FIFOPAGE_INFO_1;
465 	restore_info[restore_index].value =
466 		HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_INFO_1);
467 	restore_index++;
468 	restore_info[restore_index].length = 4;
469 	restore_info[restore_index].mac_register = REG_RQPN_CTRL_2;
470 	restore_info[restore_index].value =
471 		HALMAC_REG_READ_32(halmac_adapter, REG_RQPN_CTRL_2) | BIT(31);
472 	restore_index++;
473 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_1, 0x200);
474 	HALMAC_REG_WRITE_32(halmac_adapter, REG_RQPN_CTRL_2,
475 			    restore_info[restore_index - 1].value);
476 
477 	if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
478 		HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
479 		HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL,
480 				    0x00000000);
481 	}
482 
483 	halmac_adapter->fw_version.version = le16_to_cpu(
484 		*((__le16 *)(hamacl_fw + HALMAC_FWHDR_OFFSET_VERSION_88XX)));
485 	halmac_adapter->fw_version.sub_version =
486 		*(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBVERSION_88XX);
487 	halmac_adapter->fw_version.sub_index =
488 		*(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBINDEX_88XX);
489 	halmac_adapter->fw_version.h2c_version = (u16)fw_h2c_ver;
490 
491 	dmem_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
492 				      HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX)));
493 	iram_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
494 				      HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX)));
495 	if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
496 		eram_pkt_size =
497 		     le32_to_cpu(*((__le32 *)(hamacl_fw +
498 				   HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX)));
499 
500 	dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
501 	iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
502 	if (eram_pkt_size != 0)
503 		eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
504 
505 	if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
506 			       iram_pkt_size + eram_pkt_size)) {
507 		pr_err("FW size mismatch the real fw size!\n");
508 		goto DLFW_FAIL;
509 	}
510 
511 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
512 	restore_info[restore_index].length = 1;
513 	restore_info[restore_index].mac_register = REG_CR + 1;
514 	restore_info[restore_index].value = value8;
515 	restore_index++;
516 	value8 = (u8)(value8 | BIT(0));
517 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1,
518 			   value8); /* Enable SW TX beacon */
519 
520 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
521 	restore_info[restore_index].length = 1;
522 	restore_info[restore_index].mac_register = REG_BCN_CTRL;
523 	restore_info[restore_index].value = value8;
524 	restore_index++;
525 	value8 = (u8)((value8 & (~BIT(3))) | BIT(4));
526 	HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL,
527 			   value8); /* Disable beacon related functions */
528 
529 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
530 	restore_info[restore_index].length = 1;
531 	restore_info[restore_index].mac_register = REG_FWHW_TXQ_CTRL + 2;
532 	restore_info[restore_index].value = value8;
533 	restore_index++;
534 	value8 = (u8)(value8 & ~(BIT(6)));
535 	HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2,
536 			   value8); /* Disable ptcl tx bcnq */
537 
538 	restore_info[restore_index].length = 2;
539 	restore_info[restore_index].mac_register = REG_FIFOPAGE_CTRL_2;
540 	restore_info[restore_index].value =
541 		HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
542 		BIT(15);
543 	restore_index++;
544 	value16 = 0x8000;
545 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
546 			    value16); /* Set beacon header to  0 */
547 
548 	value16 = (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) &
549 			0x3800);
550 	value16 |= BIT(0);
551 	HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
552 			    value16); /* MCU/FW setting */
553 
554 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CPU_DMEM_CON + 2);
555 	value8 &= ~(BIT(0));
556 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
557 	value8 |= BIT(0);
558 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
559 
560 	/* Download to DMEM */
561 	file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX;
562 	temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
563 			   HALMAC_FWHDR_OFFSET_DMEM_ADDR_88XX))) &
564 			   ~(BIT(31));
565 	if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
566 				    dmem_pkt_size) != HALMAC_RET_SUCCESS)
567 		goto DLFW_END;
568 
569 	/* Download to IMEM */
570 	file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size;
571 	temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
572 			   HALMAC_FWHDR_OFFSET_IRAM_ADDR_88XX))) &
573 			   ~(BIT(31));
574 	if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
575 				    iram_pkt_size) != HALMAC_RET_SUCCESS)
576 		goto DLFW_END;
577 
578 	/* Download to EMEM */
579 	if (eram_pkt_size != 0) {
580 		file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
581 			   iram_pkt_size;
582 		dest = le32_to_cpu((*((__le32 *)(hamacl_fw +
583 				    HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX)))) &
584 				   ~(BIT(31));
585 		if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
586 					    eram_pkt_size) !=
587 		    HALMAC_RET_SUCCESS)
588 			goto DLFW_END;
589 	}
590 
591 	halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
592 DLFW_END:
593 
594 	halmac_restore_mac_register_88xx(halmac_adapter, restore_info,
595 					 DLFW_RESTORE_REG_NUM_88XX);
596 
597 	if (halmac_dlfw_end_flow_88xx(halmac_adapter) != HALMAC_RET_SUCCESS)
598 		goto DLFW_FAIL;
599 
600 	halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_DONE;
601 
602 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
603 			"%s <==========\n", __func__);
604 
605 	return HALMAC_RET_SUCCESS;
606 
607 DLFW_FAIL:
608 
609 	/* Disable FWDL_EN */
610 	HALMAC_REG_WRITE_8(
611 		halmac_adapter, REG_MCUFW_CTRL,
612 		(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
613 		     ~(BIT(0))));
614 
615 	return HALMAC_RET_DLFW_FAIL;
616 }
617 
618 /**
619  * halmac_free_download_firmware_88xx() - download specific memory firmware
620  * @halmac_adapter
621  * @dlfw_mem : memory selection
622  * @hamacl_fw : firmware bin
623  * @halmac_fw_size : firmware size
624  * Author : KaiYuan Chang/Ivan Lin
625  * Return : enum halmac_ret_status
626  */
627 enum halmac_ret_status
halmac_free_download_firmware_88xx(struct halmac_adapter * halmac_adapter,enum halmac_dlfw_mem dlfw_mem,u8 * hamacl_fw,u32 halmac_fw_size)628 halmac_free_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
629 				   enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
630 				   u32 halmac_fw_size)
631 {
632 	u8 tx_pause_backup;
633 	u8 *file_ptr;
634 	u32 dest;
635 	u16 bcn_head_backup;
636 	u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
637 	void *driver_adapter = NULL;
638 	enum halmac_ret_status status = HALMAC_RET_DLFW_FAIL;
639 	struct halmac_api *halmac_api;
640 
641 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
642 		return HALMAC_RET_ADAPTER_INVALID;
643 
644 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
645 		return HALMAC_RET_API_INVALID;
646 
647 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
648 		return HALMAC_RET_NO_DLFW;
649 
650 	driver_adapter = halmac_adapter->driver_adapter;
651 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
652 
653 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
654 			"[TRACE]%s ==========>\n", __func__);
655 
656 	if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
657 	    halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
658 		pr_err("[ERR]FW size error!\n");
659 		return HALMAC_RET_FW_SIZE_ERR;
660 	}
661 
662 	dmem_pkt_size =
663 	    le32_to_cpu(*(__le32 *)(hamacl_fw +
664 				    HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX));
665 	iram_pkt_size =
666 	    le32_to_cpu(*(__le32 *)(hamacl_fw +
667 				    HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX));
668 	if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
669 		eram_pkt_size =
670 		  le32_to_cpu(*(__le32 *)(hamacl_fw +
671 					  HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX));
672 
673 	dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
674 	iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
675 	if (eram_pkt_size != 0)
676 		eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
677 
678 	if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
679 			       iram_pkt_size + eram_pkt_size)) {
680 		pr_err("[ERR]FW size mismatch the real fw size!\n");
681 		return HALMAC_RET_DLFW_FAIL;
682 	}
683 
684 	tx_pause_backup = HALMAC_REG_READ_8(halmac_adapter, REG_TXPAUSE);
685 	HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE,
686 			   tx_pause_backup | BIT(7));
687 
688 	bcn_head_backup =
689 		HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
690 		BIT(15);
691 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0x8000);
692 
693 	if (eram_pkt_size != 0) {
694 		file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
695 			   iram_pkt_size;
696 		dest = le32_to_cpu(*((__le32 *)(hamacl_fw +
697 				   HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX))) &
698 				   ~(BIT(31));
699 		status = halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
700 						 eram_pkt_size);
701 		if (status != HALMAC_RET_SUCCESS)
702 			goto DL_FREE_FW_END;
703 	}
704 
705 	status = halmac_free_dl_fw_end_flow_88xx(halmac_adapter);
706 
707 DL_FREE_FW_END:
708 	HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE, tx_pause_backup);
709 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
710 			    bcn_head_backup);
711 
712 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
713 			"[TRACE]%s <==========\n", __func__);
714 
715 	return status;
716 }
717 
718 /**
719  * halmac_get_fw_version_88xx() - get FW version
720  * @halmac_adapter : the adapter of halmac
721  * @fw_version : fw version info
722  * Author : Ivan Lin
723  * Return : enum halmac_ret_status
724  * More details of status code can be found in prototype document
725  */
726 enum halmac_ret_status
halmac_get_fw_version_88xx(struct halmac_adapter * halmac_adapter,struct halmac_fw_version * fw_version)727 halmac_get_fw_version_88xx(struct halmac_adapter *halmac_adapter,
728 			   struct halmac_fw_version *fw_version)
729 {
730 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
731 		return HALMAC_RET_ADAPTER_INVALID;
732 
733 	if (halmac_adapter->halmac_state.dlfw_state == 0)
734 		return HALMAC_RET_DLFW_FAIL;
735 
736 	fw_version->version = halmac_adapter->fw_version.version;
737 	fw_version->sub_version = halmac_adapter->fw_version.sub_version;
738 	fw_version->sub_index = halmac_adapter->fw_version.sub_index;
739 
740 	return HALMAC_RET_SUCCESS;
741 }
742 
743 /**
744  * halmac_cfg_mac_addr_88xx() - config mac address
745  * @halmac_adapter : the adapter of halmac
746  * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
747  * @hal_address : mac address
748  * Author : KaiYuan Chang/Ivan Lin
749  * Return : enum halmac_ret_status
750  * More details of status code can be found in prototype document
751  */
752 enum halmac_ret_status
halmac_cfg_mac_addr_88xx(struct halmac_adapter * halmac_adapter,u8 halmac_port,union halmac_wlan_addr * hal_address)753 halmac_cfg_mac_addr_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
754 			 union halmac_wlan_addr *hal_address)
755 {
756 	u16 mac_address_H;
757 	u32 mac_address_L;
758 	void *driver_adapter = NULL;
759 	struct halmac_api *halmac_api;
760 
761 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
762 		return HALMAC_RET_ADAPTER_INVALID;
763 
764 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
765 		return HALMAC_RET_API_INVALID;
766 
767 	driver_adapter = halmac_adapter->driver_adapter;
768 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
769 
770 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
771 			"[TRACE]%s ==========>\n", __func__);
772 
773 	if (halmac_port >= HALMAC_PORTIDMAX) {
774 		pr_err("[ERR]port index > 5\n");
775 		return HALMAC_RET_PORT_NOT_SUPPORT;
776 	}
777 
778 	mac_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
779 	mac_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
780 
781 	halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_low =
782 		mac_address_L;
783 	halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_high =
784 		mac_address_H;
785 
786 	switch (halmac_port) {
787 	case HALMAC_PORTID0:
788 		HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID, mac_address_L);
789 		HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID + 4,
790 				    mac_address_H);
791 		break;
792 
793 	case HALMAC_PORTID1:
794 		HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID1, mac_address_L);
795 		HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID1 + 4,
796 				    mac_address_H);
797 		break;
798 
799 	case HALMAC_PORTID2:
800 		HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID2, mac_address_L);
801 		HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID2 + 4,
802 				    mac_address_H);
803 		break;
804 
805 	case HALMAC_PORTID3:
806 		HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID3, mac_address_L);
807 		HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID3 + 4,
808 				    mac_address_H);
809 		break;
810 
811 	case HALMAC_PORTID4:
812 		HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID4, mac_address_L);
813 		HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID4 + 4,
814 				    mac_address_H);
815 		break;
816 
817 	default:
818 
819 		break;
820 	}
821 
822 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
823 			"[TRACE]%s <==========\n", __func__);
824 
825 	return HALMAC_RET_SUCCESS;
826 }
827 
828 /**
829  * halmac_cfg_bssid_88xx() - config BSSID
830  * @halmac_adapter : the adapter of halmac
831  * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
832  * @hal_address : bssid
833  * Author : KaiYuan Chang/Ivan Lin
834  * Return : enum halmac_ret_status
835  * More details of status code can be found in prototype document
836  */
837 enum halmac_ret_status
halmac_cfg_bssid_88xx(struct halmac_adapter * halmac_adapter,u8 halmac_port,union halmac_wlan_addr * hal_address)838 halmac_cfg_bssid_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
839 		      union halmac_wlan_addr *hal_address)
840 {
841 	u16 bssid_address_H;
842 	u32 bssid_address_L;
843 	void *driver_adapter = NULL;
844 	struct halmac_api *halmac_api;
845 
846 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
847 		return HALMAC_RET_ADAPTER_INVALID;
848 
849 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
850 		return HALMAC_RET_API_INVALID;
851 
852 	driver_adapter = halmac_adapter->driver_adapter;
853 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
854 
855 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
856 			"[TRACE]%s ==========>\n", __func__);
857 
858 	if (halmac_port >= HALMAC_PORTIDMAX) {
859 		pr_err("[ERR]port index > 5\n");
860 		return HALMAC_RET_PORT_NOT_SUPPORT;
861 	}
862 
863 	bssid_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
864 	bssid_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
865 
866 	halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_low =
867 		bssid_address_L;
868 	halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_high =
869 		bssid_address_H;
870 
871 	switch (halmac_port) {
872 	case HALMAC_PORTID0:
873 		HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID, bssid_address_L);
874 		HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID + 4,
875 				    bssid_address_H);
876 		break;
877 
878 	case HALMAC_PORTID1:
879 		HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID1,
880 				    bssid_address_L);
881 		HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID1 + 4,
882 				    bssid_address_H);
883 		break;
884 
885 	case HALMAC_PORTID2:
886 		HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID2,
887 				    bssid_address_L);
888 		HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID2 + 4,
889 				    bssid_address_H);
890 		break;
891 
892 	case HALMAC_PORTID3:
893 		HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID3,
894 				    bssid_address_L);
895 		HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID3 + 4,
896 				    bssid_address_H);
897 		break;
898 
899 	case HALMAC_PORTID4:
900 		HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID4,
901 				    bssid_address_L);
902 		HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID4 + 4,
903 				    bssid_address_H);
904 		break;
905 
906 	default:
907 
908 		break;
909 	}
910 
911 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
912 			"[TRACE]%s <==========\n", __func__);
913 
914 	return HALMAC_RET_SUCCESS;
915 }
916 
917 /**
918  * halmac_cfg_multicast_addr_88xx() - config multicast address
919  * @halmac_adapter : the adapter of halmac
920  * @hal_address : multicast address
921  * Author : KaiYuan Chang/Ivan Lin
922  * Return : enum halmac_ret_status
923  * More details of status code can be found in prototype document
924  */
925 enum halmac_ret_status
halmac_cfg_multicast_addr_88xx(struct halmac_adapter * halmac_adapter,union halmac_wlan_addr * hal_address)926 halmac_cfg_multicast_addr_88xx(struct halmac_adapter *halmac_adapter,
927 			       union halmac_wlan_addr *hal_address)
928 {
929 	u16 address_H;
930 	u32 address_L;
931 	void *driver_adapter = NULL;
932 	struct halmac_api *halmac_api;
933 
934 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
935 		return HALMAC_RET_ADAPTER_INVALID;
936 
937 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
938 		return HALMAC_RET_API_INVALID;
939 
940 	halmac_api_record_id_88xx(halmac_adapter,
941 				  HALMAC_API_CFG_MULTICAST_ADDR);
942 
943 	driver_adapter = halmac_adapter->driver_adapter;
944 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
945 
946 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
947 			"%s ==========>\n", __func__);
948 
949 	address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
950 	address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
951 
952 	HALMAC_REG_WRITE_32(halmac_adapter, REG_MAR, address_L);
953 	HALMAC_REG_WRITE_16(halmac_adapter, REG_MAR + 4, address_H);
954 
955 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
956 			"%s <==========\n", __func__);
957 
958 	return HALMAC_RET_SUCCESS;
959 }
960 
961 /**
962  * halmac_pre_init_system_cfg_88xx() - pre-init system config
963  * @halmac_adapter : the adapter of halmac
964  * Author : KaiYuan Chang/Ivan Lin
965  * Return : enum halmac_ret_status
966  * More details of status code can be found in prototype document
967  */
968 enum halmac_ret_status
halmac_pre_init_system_cfg_88xx(struct halmac_adapter * halmac_adapter)969 halmac_pre_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
970 {
971 	u32 value32, counter;
972 	void *driver_adapter = NULL;
973 	struct halmac_api *halmac_api;
974 	bool enable_bb;
975 
976 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
977 		return HALMAC_RET_ADAPTER_INVALID;
978 
979 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
980 		return HALMAC_RET_API_INVALID;
981 
982 	halmac_api_record_id_88xx(halmac_adapter,
983 				  HALMAC_API_PRE_INIT_SYSTEM_CFG);
984 
985 	driver_adapter = halmac_adapter->driver_adapter;
986 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
987 
988 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
989 			"halmac_pre_init_system_cfg ==========>\n");
990 
991 	if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
992 		HALMAC_REG_WRITE_8(
993 			halmac_adapter, REG_SDIO_HSUS_CTRL,
994 			HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
995 				~(BIT(0)));
996 		counter = 10000;
997 		while (!(HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
998 			 0x02)) {
999 			counter--;
1000 			if (counter == 0)
1001 				return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
1002 		}
1003 	} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
1004 		if (HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) ==
1005 		    0x20) /* usb3.0 */
1006 			HALMAC_REG_WRITE_8(
1007 				halmac_adapter, 0xFE5B,
1008 				HALMAC_REG_READ_8(halmac_adapter, 0xFE5B) |
1009 					BIT(4));
1010 	}
1011 
1012 	/* Config PIN Mux */
1013 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL1);
1014 	value32 = value32 & (~(BIT(28) | BIT(29)));
1015 	value32 = value32 | BIT(28) | BIT(29);
1016 	HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL1, value32);
1017 
1018 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_LED_CFG);
1019 	value32 = value32 & (~(BIT(25) | BIT(26)));
1020 	HALMAC_REG_WRITE_32(halmac_adapter, REG_LED_CFG, value32);
1021 
1022 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_GPIO_MUXCFG);
1023 	value32 = value32 & (~(BIT(2)));
1024 	value32 = value32 | BIT(2);
1025 	HALMAC_REG_WRITE_32(halmac_adapter, REG_GPIO_MUXCFG, value32);
1026 
1027 	enable_bb = false;
1028 	halmac_set_hw_value_88xx(halmac_adapter, HALMAC_HW_EN_BB_RF,
1029 				 &enable_bb);
1030 
1031 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1032 			"halmac_pre_init_system_cfg <==========\n");
1033 
1034 	return HALMAC_RET_SUCCESS;
1035 }
1036 
1037 /**
1038  * halmac_init_system_cfg_88xx() -  init system config
1039  * @halmac_adapter : the adapter of halmac
1040  * Author : KaiYuan Chang/Ivan Lin
1041  * Return : enum halmac_ret_status
1042  * More details of status code can be found in prototype document
1043  */
1044 enum halmac_ret_status
halmac_init_system_cfg_88xx(struct halmac_adapter * halmac_adapter)1045 halmac_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
1046 {
1047 	void *driver_adapter = NULL;
1048 	struct halmac_api *halmac_api;
1049 
1050 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1051 		return HALMAC_RET_ADAPTER_INVALID;
1052 
1053 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1054 		return HALMAC_RET_API_INVALID;
1055 
1056 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SYSTEM_CFG);
1057 
1058 	driver_adapter = halmac_adapter->driver_adapter;
1059 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1060 
1061 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1062 			"halmac_init_system_cfg ==========>\n");
1063 
1064 	HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
1065 			   HALMAC_FUNCTION_ENABLE_88XX);
1066 	HALMAC_REG_WRITE_32(
1067 		halmac_adapter, REG_SYS_SDIO_CTRL,
1068 		(u32)(HALMAC_REG_READ_32(halmac_adapter, REG_SYS_SDIO_CTRL) |
1069 		      BIT_LTE_MUX_CTRL_PATH));
1070 	HALMAC_REG_WRITE_32(
1071 		halmac_adapter, REG_CPU_DMEM_CON,
1072 		(u32)(HALMAC_REG_READ_32(halmac_adapter, REG_CPU_DMEM_CON) |
1073 		      BIT_WL_PLATFORM_RST));
1074 
1075 	/* halmac_api->halmac_init_h2c(halmac_adapter); */
1076 
1077 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1078 			"halmac_init_system_cfg <==========\n");
1079 
1080 	return HALMAC_RET_SUCCESS;
1081 }
1082 
1083 /**
1084  * halmac_init_edca_cfg_88xx() - init EDCA config
1085  * @halmac_adapter : the adapter of halmac
1086  * Author : KaiYuan Chang/Ivan Lin
1087  * Return : enum halmac_ret_status
1088  * More details of status code can be found in prototype document
1089  */
1090 enum halmac_ret_status
halmac_init_edca_cfg_88xx(struct halmac_adapter * halmac_adapter)1091 halmac_init_edca_cfg_88xx(struct halmac_adapter *halmac_adapter)
1092 {
1093 	u8 value8;
1094 	u32 value32;
1095 	void *driver_adapter = NULL;
1096 	struct halmac_api *halmac_api;
1097 
1098 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1099 		return HALMAC_RET_ADAPTER_INVALID;
1100 
1101 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1102 		return HALMAC_RET_API_INVALID;
1103 
1104 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_EDCA_CFG);
1105 
1106 	driver_adapter = halmac_adapter->driver_adapter;
1107 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1108 
1109 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1110 			"%s ==========>\n", __func__);
1111 
1112 	/* Clear TX pause */
1113 	HALMAC_REG_WRITE_16(halmac_adapter, REG_TXPAUSE, 0x0000);
1114 
1115 	HALMAC_REG_WRITE_8(halmac_adapter, REG_SLOT, HALMAC_SLOT_TIME_88XX);
1116 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PIFS, HALMAC_PIFS_TIME_88XX);
1117 	value32 = HALMAC_SIFS_CCK_CTX_88XX |
1118 		  (HALMAC_SIFS_OFDM_CTX_88XX << BIT_SHIFT_SIFS_OFDM_CTX) |
1119 		  (HALMAC_SIFS_CCK_TRX_88XX << BIT_SHIFT_SIFS_CCK_TRX) |
1120 		  (HALMAC_SIFS_OFDM_TRX_88XX << BIT_SHIFT_SIFS_OFDM_TRX);
1121 	HALMAC_REG_WRITE_32(halmac_adapter, REG_SIFS, value32);
1122 
1123 	HALMAC_REG_WRITE_32(
1124 		halmac_adapter, REG_EDCA_VO_PARAM,
1125 		HALMAC_REG_READ_32(halmac_adapter, REG_EDCA_VO_PARAM) & 0xFFFF);
1126 	HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VO_PARAM + 2,
1127 			    HALMAC_VO_TXOP_LIMIT_88XX);
1128 	HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VI_PARAM + 2,
1129 			    HALMAC_VI_TXOP_LIMIT_88XX);
1130 
1131 	HALMAC_REG_WRITE_32(halmac_adapter, REG_RD_NAV_NXT,
1132 			    HALMAC_RDG_NAV_88XX | (HALMAC_TXOP_NAV_88XX << 16));
1133 	HALMAC_REG_WRITE_16(halmac_adapter, REG_RXTSF_OFFSET_CCK,
1134 			    HALMAC_CCK_RX_TSF_88XX |
1135 				    (HALMAC_OFDM_RX_TSF_88XX) << 8);
1136 
1137 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RD_CTRL + 1);
1138 	value8 |=
1139 		(BIT_VOQ_RD_INIT_EN | BIT_VIQ_RD_INIT_EN | BIT_BEQ_RD_INIT_EN);
1140 	HALMAC_REG_WRITE_8(halmac_adapter, REG_RD_CTRL + 1, value8);
1141 
1142 	/* Set beacon cotnrol - enable TSF and other related functions */
1143 	HALMAC_REG_WRITE_8(
1144 		halmac_adapter, REG_BCN_CTRL,
1145 		(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL) |
1146 		     BIT_EN_BCN_FUNCTION));
1147 
1148 	/* Set send beacon related registers */
1149 	HALMAC_REG_WRITE_32(halmac_adapter, REG_TBTT_PROHIBIT,
1150 			    HALMAC_TBTT_PROHIBIT_88XX |
1151 				    (HALMAC_TBTT_HOLD_TIME_88XX
1152 				     << BIT_SHIFT_TBTT_HOLD_TIME_AP));
1153 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DRVERLYINT,
1154 			   HALMAC_DRIVER_EARLY_INT_88XX);
1155 	HALMAC_REG_WRITE_8(halmac_adapter, REG_BCNDMATIM,
1156 			   HALMAC_BEACON_DMA_TIM_88XX);
1157 
1158 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1159 			"%s <==========\n", __func__);
1160 
1161 	return HALMAC_RET_SUCCESS;
1162 }
1163 
1164 /**
1165  * halmac_init_wmac_cfg_88xx() - init wmac config
1166  * @halmac_adapter : the adapter of halmac
1167  * Author : KaiYuan Chang/Ivan Lin
1168  * Return : enum halmac_ret_status
1169  * More details of status code can be found in prototype document
1170  */
1171 enum halmac_ret_status
halmac_init_wmac_cfg_88xx(struct halmac_adapter * halmac_adapter)1172 halmac_init_wmac_cfg_88xx(struct halmac_adapter *halmac_adapter)
1173 {
1174 	void *driver_adapter = NULL;
1175 	struct halmac_api *halmac_api;
1176 
1177 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1178 		return HALMAC_RET_ADAPTER_INVALID;
1179 
1180 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1181 		return HALMAC_RET_API_INVALID;
1182 
1183 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_WMAC_CFG);
1184 
1185 	driver_adapter = halmac_adapter->driver_adapter;
1186 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1187 
1188 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1189 			"%s ==========>\n", __func__);
1190 
1191 	HALMAC_REG_WRITE_32(halmac_adapter, REG_RXFLTMAP0,
1192 			    HALMAC_RX_FILTER0_88XX);
1193 	HALMAC_REG_WRITE_16(halmac_adapter, REG_RXFLTMAP,
1194 			    HALMAC_RX_FILTER_88XX);
1195 
1196 	HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, HALMAC_RCR_CONFIG_88XX);
1197 
1198 	HALMAC_REG_WRITE_8(
1199 		halmac_adapter, REG_TCR + 1,
1200 		(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_TCR + 1) | 0x30));
1201 	HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 2, 0x30);
1202 	HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 1, 0x00);
1203 
1204 	HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 8,
1205 			    0x30810041);
1206 	HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
1207 			    0x50802080);
1208 
1209 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1210 			"%s <==========\n", __func__);
1211 
1212 	return HALMAC_RET_SUCCESS;
1213 }
1214 
1215 /**
1216  * halmac_init_mac_cfg_88xx() - config page1~page7 register
1217  * @halmac_adapter : the adapter of halmac
1218  * @mode : trx mode
1219  * Author : KaiYuan Chang/Ivan Lin
1220  * Return : enum halmac_ret_status
1221  * More details of status code can be found in prototype document
1222  */
1223 enum halmac_ret_status
halmac_init_mac_cfg_88xx(struct halmac_adapter * halmac_adapter,enum halmac_trx_mode mode)1224 halmac_init_mac_cfg_88xx(struct halmac_adapter *halmac_adapter,
1225 			 enum halmac_trx_mode mode)
1226 {
1227 	void *driver_adapter = NULL;
1228 	struct halmac_api *halmac_api;
1229 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1230 
1231 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1232 		return HALMAC_RET_ADAPTER_INVALID;
1233 
1234 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1235 		return HALMAC_RET_API_INVALID;
1236 
1237 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_MAC_CFG);
1238 
1239 	driver_adapter = halmac_adapter->driver_adapter;
1240 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1241 
1242 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1243 			"%s ==========>mode = %d\n", __func__,
1244 			mode);
1245 
1246 	status = halmac_api->halmac_init_trx_cfg(halmac_adapter, mode);
1247 	if (status != HALMAC_RET_SUCCESS) {
1248 		pr_err("halmac_init_trx_cfg error = %x\n", status);
1249 		return status;
1250 	}
1251 	status = halmac_api->halmac_init_protocol_cfg(halmac_adapter);
1252 	if (status != HALMAC_RET_SUCCESS) {
1253 		pr_err("halmac_init_protocol_cfg_88xx error = %x\n", status);
1254 		return status;
1255 	}
1256 
1257 	status = halmac_init_edca_cfg_88xx(halmac_adapter);
1258 	if (status != HALMAC_RET_SUCCESS) {
1259 		pr_err("halmac_init_edca_cfg_88xx error = %x\n", status);
1260 		return status;
1261 	}
1262 
1263 	status = halmac_init_wmac_cfg_88xx(halmac_adapter);
1264 	if (status != HALMAC_RET_SUCCESS) {
1265 		pr_err("halmac_init_wmac_cfg_88xx error = %x\n", status);
1266 		return status;
1267 	}
1268 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1269 			"%s <==========\n", __func__);
1270 
1271 	return status;
1272 }
1273 
1274 /**
1275  * halmac_cfg_operation_mode_88xx() - config operation mode
1276  * @halmac_adapter : the adapter of halmac
1277  * @wireless_mode : 802.11 standard(b/g/n/ac)
1278  * Author : KaiYuan Chang/Ivan Lin
1279  * Return : enum halmac_ret_status
1280  * More details of status code can be found in prototype document
1281  */
1282 enum halmac_ret_status
halmac_cfg_operation_mode_88xx(struct halmac_adapter * halmac_adapter,enum halmac_wireless_mode wireless_mode)1283 halmac_cfg_operation_mode_88xx(struct halmac_adapter *halmac_adapter,
1284 			       enum halmac_wireless_mode wireless_mode)
1285 {
1286 	void *driver_adapter = NULL;
1287 	enum halmac_wireless_mode wireless_mode_local =
1288 		HALMAC_WIRELESS_MODE_UNDEFINE;
1289 
1290 	wireless_mode_local = wireless_mode;
1291 
1292 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1293 		return HALMAC_RET_ADAPTER_INVALID;
1294 
1295 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1296 		return HALMAC_RET_API_INVALID;
1297 
1298 	halmac_api_record_id_88xx(halmac_adapter,
1299 				  HALMAC_API_CFG_OPERATION_MODE);
1300 
1301 	driver_adapter = halmac_adapter->driver_adapter;
1302 
1303 	HALMAC_RT_TRACE(
1304 		driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1305 		"%s ==========>wireless_mode = %d\n", __func__,
1306 		wireless_mode);
1307 
1308 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1309 			"%s <==========\n", __func__);
1310 
1311 	return HALMAC_RET_SUCCESS;
1312 }
1313 
1314 /**
1315  * halmac_cfg_ch_bw_88xx() - config channel & bandwidth
1316  * @halmac_adapter : the adapter of halmac
1317  * @channel : WLAN channel, support 2.4G & 5G
1318  * @pri_ch_idx : primary channel index, idx1, idx2, idx3, idx4
1319  * @bw : band width, 20, 40, 80, 160, 5 ,10
1320  * Author : KaiYuan Chang
1321  * Return : enum halmac_ret_status
1322  * More details of status code can be found in prototype document
1323  */
1324 enum halmac_ret_status
halmac_cfg_ch_bw_88xx(struct halmac_adapter * halmac_adapter,u8 channel,enum halmac_pri_ch_idx pri_ch_idx,enum halmac_bw bw)1325 halmac_cfg_ch_bw_88xx(struct halmac_adapter *halmac_adapter, u8 channel,
1326 		      enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw)
1327 {
1328 	void *driver_adapter = NULL;
1329 	struct halmac_api *halmac_api;
1330 
1331 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1332 		return HALMAC_RET_ADAPTER_INVALID;
1333 
1334 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1335 		return HALMAC_RET_API_INVALID;
1336 
1337 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1338 
1339 	driver_adapter = halmac_adapter->driver_adapter;
1340 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1341 
1342 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1343 			"%s ==========>ch = %d, idx=%d, bw=%d\n", __func__,
1344 			channel, pri_ch_idx, bw);
1345 
1346 	halmac_cfg_pri_ch_idx_88xx(halmac_adapter, pri_ch_idx);
1347 
1348 	halmac_cfg_bw_88xx(halmac_adapter, bw);
1349 
1350 	halmac_cfg_ch_88xx(halmac_adapter, channel);
1351 
1352 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1353 			"%s <==========\n", __func__);
1354 
1355 	return HALMAC_RET_SUCCESS;
1356 }
1357 
halmac_cfg_ch_88xx(struct halmac_adapter * halmac_adapter,u8 channel)1358 enum halmac_ret_status halmac_cfg_ch_88xx(struct halmac_adapter *halmac_adapter,
1359 					  u8 channel)
1360 {
1361 	u8 value8;
1362 	void *driver_adapter = NULL;
1363 	struct halmac_api *halmac_api;
1364 
1365 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1366 		return HALMAC_RET_ADAPTER_INVALID;
1367 
1368 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1369 		return HALMAC_RET_API_INVALID;
1370 
1371 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1372 
1373 	driver_adapter = halmac_adapter->driver_adapter;
1374 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1375 
1376 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1377 			"%s ==========>ch = %d\n", __func__, channel);
1378 
1379 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CCK_CHECK);
1380 	value8 = value8 & (~(BIT(7)));
1381 
1382 	if (channel > 35)
1383 		value8 = value8 | BIT(7);
1384 
1385 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CCK_CHECK, value8);
1386 
1387 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1388 			"%s <==========\n", __func__);
1389 
1390 	return HALMAC_RET_SUCCESS;
1391 }
1392 
1393 enum halmac_ret_status
halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter * halmac_adapter,enum halmac_pri_ch_idx pri_ch_idx)1394 halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter *halmac_adapter,
1395 			   enum halmac_pri_ch_idx pri_ch_idx)
1396 {
1397 	u8 txsc_40 = 0, txsc_20 = 0;
1398 	void *driver_adapter = NULL;
1399 	struct halmac_api *halmac_api;
1400 
1401 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1402 		return HALMAC_RET_ADAPTER_INVALID;
1403 
1404 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1405 		return HALMAC_RET_API_INVALID;
1406 
1407 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1408 
1409 	driver_adapter = halmac_adapter->driver_adapter;
1410 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1411 
1412 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1413 			"%s ==========> idx=%d\n", __func__,
1414 			pri_ch_idx);
1415 
1416 	txsc_20 = pri_ch_idx;
1417 	if (txsc_20 == HALMAC_CH_IDX_1 || txsc_20 == HALMAC_CH_IDX_3)
1418 		txsc_40 = 9;
1419 	else
1420 		txsc_40 = 10;
1421 
1422 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DATA_SC,
1423 			   BIT_TXSC_20M(txsc_20) | BIT_TXSC_40M(txsc_40));
1424 
1425 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1426 			"%s <==========\n", __func__);
1427 
1428 	return HALMAC_RET_SUCCESS;
1429 }
1430 
1431 /**
1432  * halmac_cfg_bw_88xx() - config bandwidth
1433  * @halmac_adapter : the adapter of halmac
1434  * @bw : band width, 20, 40, 80, 160, 5 ,10
1435  * Author : KaiYuan Chang
1436  * Return : enum halmac_ret_status
1437  * More details of status code can be found in prototype document
1438  */
halmac_cfg_bw_88xx(struct halmac_adapter * halmac_adapter,enum halmac_bw bw)1439 enum halmac_ret_status halmac_cfg_bw_88xx(struct halmac_adapter *halmac_adapter,
1440 					  enum halmac_bw bw)
1441 {
1442 	u32 value32;
1443 	void *driver_adapter = NULL;
1444 	struct halmac_api *halmac_api;
1445 
1446 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1447 		return HALMAC_RET_ADAPTER_INVALID;
1448 
1449 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1450 		return HALMAC_RET_API_INVALID;
1451 
1452 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_BW);
1453 
1454 	driver_adapter = halmac_adapter->driver_adapter;
1455 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1456 
1457 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1458 			"%s ==========>bw=%d\n", __func__, bw);
1459 
1460 	/* RF mode */
1461 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL);
1462 	value32 = value32 & (~(BIT(7) | BIT(8)));
1463 
1464 	switch (bw) {
1465 	case HALMAC_BW_80:
1466 		value32 = value32 | BIT(7);
1467 		break;
1468 	case HALMAC_BW_40:
1469 		value32 = value32 | BIT(8);
1470 		break;
1471 	case HALMAC_BW_20:
1472 	case HALMAC_BW_10:
1473 	case HALMAC_BW_5:
1474 		break;
1475 	default:
1476 		pr_err("%s switch case not support\n", __func__);
1477 		break;
1478 	}
1479 	HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL, value32);
1480 
1481 	/* MAC CLK */
1482 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_AFE_CTRL1);
1483 	value32 = (value32 & (~(BIT(20) | BIT(21)))) |
1484 		  (HALMAC_MAC_CLOCK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
1485 	HALMAC_REG_WRITE_32(halmac_adapter, REG_AFE_CTRL1, value32);
1486 
1487 	HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_TSF,
1488 			   HALMAC_MAC_CLOCK_88XX);
1489 	HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_EDCA,
1490 			   HALMAC_MAC_CLOCK_88XX);
1491 
1492 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1493 			"%s <==========\n", __func__);
1494 
1495 	return HALMAC_RET_SUCCESS;
1496 }
1497 
1498 /**
1499  * halmac_dump_efuse_map_88xx() - dump "physical" efuse map
1500  * @halmac_adapter : the adapter of halmac
1501  * @cfg : dump efuse method
1502  * Author : Ivan Lin/KaiYuan Chang
1503  * Return : enum halmac_ret_status
1504  * More details of status code can be found in prototype document
1505  */
1506 enum halmac_ret_status
halmac_dump_efuse_map_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_read_cfg cfg)1507 halmac_dump_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
1508 			   enum halmac_efuse_read_cfg cfg)
1509 {
1510 	void *driver_adapter = NULL;
1511 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1512 	enum halmac_cmd_process_status *process_status =
1513 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
1514 
1515 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1516 		return HALMAC_RET_ADAPTER_INVALID;
1517 
1518 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1519 		return HALMAC_RET_API_INVALID;
1520 
1521 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP);
1522 
1523 	driver_adapter = halmac_adapter->driver_adapter;
1524 
1525 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1526 			"%s ==========>cfg=%d\n", __func__, cfg);
1527 
1528 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1529 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1530 				"Wait event(dump efuse)...\n");
1531 		return HALMAC_RET_BUSY_STATE;
1532 	}
1533 
1534 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1535 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1536 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1537 				"Not idle state(dump efuse)...\n");
1538 		return HALMAC_RET_ERROR_STATE;
1539 	}
1540 
1541 	if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
1542 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
1543 				"[WARN]Dump efuse in suspend mode\n");
1544 
1545 	*process_status = HALMAC_CMD_PROCESS_IDLE;
1546 	halmac_adapter->event_trigger.physical_efuse_map = 1;
1547 
1548 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1549 						    HALMAC_EFUSE_BANK_WIFI);
1550 	if (status != HALMAC_RET_SUCCESS) {
1551 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1552 		return status;
1553 	}
1554 
1555 	status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
1556 
1557 	if (status != HALMAC_RET_SUCCESS) {
1558 		pr_err("halmac_read_efuse error = %x\n", status);
1559 		return status;
1560 	}
1561 
1562 	if (halmac_adapter->hal_efuse_map_valid) {
1563 		*process_status = HALMAC_CMD_PROCESS_DONE;
1564 
1565 		PLATFORM_EVENT_INDICATION(
1566 			driver_adapter, HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
1567 			*process_status, halmac_adapter->hal_efuse_map,
1568 			halmac_adapter->hw_config_info.efuse_size);
1569 		halmac_adapter->event_trigger.physical_efuse_map = 0;
1570 	}
1571 
1572 	if (halmac_transition_efuse_state_88xx(
1573 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1574 	    HALMAC_RET_SUCCESS)
1575 		return HALMAC_RET_ERROR_STATE;
1576 
1577 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1578 			"%s <==========\n", __func__);
1579 
1580 	return HALMAC_RET_SUCCESS;
1581 }
1582 
1583 /**
1584  * halmac_dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
1585  * @halmac_adapter : the adapter of halmac
1586  * @halmac_efuse_bank : bt efuse bank
1587  * @bt_efuse_map_size : bt efuse map size. get from halmac_get_efuse_size API
1588  * @bt_efuse_map : bt efuse map
1589  * Author : Soar / Ivan Lin
1590  * Return : enum halmac_ret_status
1591  * More details of status code can be found in prototype document
1592  */
1593 enum halmac_ret_status
halmac_dump_efuse_map_bt_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_bank halmac_efuse_bank,u32 bt_efuse_map_size,u8 * bt_efuse_map)1594 halmac_dump_efuse_map_bt_88xx(struct halmac_adapter *halmac_adapter,
1595 			      enum halmac_efuse_bank halmac_efuse_bank,
1596 			      u32 bt_efuse_map_size, u8 *bt_efuse_map)
1597 {
1598 	void *driver_adapter = NULL;
1599 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1600 	enum halmac_cmd_process_status *process_status =
1601 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
1602 
1603 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1604 		return HALMAC_RET_ADAPTER_INVALID;
1605 
1606 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1607 		return HALMAC_RET_API_INVALID;
1608 
1609 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP_BT);
1610 
1611 	driver_adapter = halmac_adapter->driver_adapter;
1612 
1613 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1614 			"%s ==========>\n", __func__);
1615 
1616 	if (halmac_adapter->hw_config_info.bt_efuse_size != bt_efuse_map_size)
1617 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
1618 
1619 	if ((halmac_efuse_bank >= HALMAC_EFUSE_BANK_MAX) ||
1620 	    halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
1621 		pr_err("Undefined BT bank\n");
1622 		return HALMAC_RET_EFUSE_BANK_INCORRECT;
1623 	}
1624 
1625 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1626 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1627 				"Wait event(dump efuse)...\n");
1628 		return HALMAC_RET_BUSY_STATE;
1629 	}
1630 
1631 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1632 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1633 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1634 				"Not idle state(dump efuse)...\n");
1635 		return HALMAC_RET_ERROR_STATE;
1636 	}
1637 
1638 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1639 						    halmac_efuse_bank);
1640 	if (status != HALMAC_RET_SUCCESS) {
1641 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1642 		return status;
1643 	}
1644 
1645 	status = halmac_read_hw_efuse_88xx(halmac_adapter, 0, bt_efuse_map_size,
1646 					   bt_efuse_map);
1647 
1648 	if (status != HALMAC_RET_SUCCESS) {
1649 		pr_err("halmac_read_hw_efuse_88xx error = %x\n", status);
1650 		return status;
1651 	}
1652 
1653 	if (halmac_transition_efuse_state_88xx(
1654 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1655 	    HALMAC_RET_SUCCESS)
1656 		return HALMAC_RET_ERROR_STATE;
1657 
1658 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1659 			"%s <==========\n", __func__);
1660 
1661 	return HALMAC_RET_SUCCESS;
1662 }
1663 
1664 /**
1665  * halmac_write_efuse_bt_88xx() - write "BT physical" efuse offset
1666  * @halmac_adapter : the adapter of halmac
1667  * @halmac_offset : offset
1668  * @halmac_value : Write value
1669  * @bt_efuse_map : bt efuse map
1670  * Author : Soar
1671  * Return : enum halmac_ret_status
1672  * More details of status code can be found in prototype document
1673  */
1674 enum halmac_ret_status
halmac_write_efuse_bt_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset,u8 halmac_value,enum halmac_efuse_bank halmac_efuse_bank)1675 halmac_write_efuse_bt_88xx(struct halmac_adapter *halmac_adapter,
1676 			   u32 halmac_offset, u8 halmac_value,
1677 			   enum halmac_efuse_bank halmac_efuse_bank)
1678 {
1679 	void *driver_adapter = NULL;
1680 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1681 
1682 	enum halmac_cmd_process_status *process_status =
1683 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
1684 
1685 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1686 		return HALMAC_RET_ADAPTER_INVALID;
1687 
1688 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1689 		return HALMAC_RET_API_INVALID;
1690 
1691 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_WRITE_EFUSE_BT);
1692 
1693 	driver_adapter = halmac_adapter->driver_adapter;
1694 
1695 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1696 			"%s ==========>\n", __func__);
1697 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1698 			"offset : %X value : %X Bank : %X\n", halmac_offset,
1699 			halmac_value, halmac_efuse_bank);
1700 
1701 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1702 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1703 				"Wait/Rcvd event(dump efuse)...\n");
1704 		return HALMAC_RET_BUSY_STATE;
1705 	}
1706 
1707 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1708 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1709 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1710 				"Not idle state(dump efuse)...\n");
1711 		return HALMAC_RET_ERROR_STATE;
1712 	}
1713 
1714 	if (halmac_offset >= halmac_adapter->hw_config_info.efuse_size) {
1715 		pr_err("Offset is too large\n");
1716 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
1717 	}
1718 
1719 	if (halmac_efuse_bank > HALMAC_EFUSE_BANK_MAX ||
1720 	    halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
1721 		pr_err("Undefined BT bank\n");
1722 		return HALMAC_RET_EFUSE_BANK_INCORRECT;
1723 	}
1724 
1725 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1726 						    halmac_efuse_bank);
1727 	if (status != HALMAC_RET_SUCCESS) {
1728 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1729 		return status;
1730 	}
1731 
1732 	status = halmac_func_write_efuse_88xx(halmac_adapter, halmac_offset,
1733 					      halmac_value);
1734 	if (status != HALMAC_RET_SUCCESS) {
1735 		pr_err("halmac_func_write_efuse error = %x\n", status);
1736 		return status;
1737 	}
1738 
1739 	if (halmac_transition_efuse_state_88xx(
1740 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1741 	    HALMAC_RET_SUCCESS)
1742 		return HALMAC_RET_ERROR_STATE;
1743 
1744 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1745 			"%s <==========\n", __func__);
1746 
1747 	return HALMAC_RET_SUCCESS;
1748 }
1749 
1750 /**
1751  * halmac_get_efuse_available_size_88xx() - get efuse available size
1752  * @halmac_adapter : the adapter of halmac
1753  * @halmac_size : physical efuse available size
1754  * Author : Soar
1755  * Return : enum halmac_ret_status
1756  * More details of status code can be found in prototype document
1757  */
1758 enum halmac_ret_status
halmac_get_efuse_available_size_88xx(struct halmac_adapter * halmac_adapter,u32 * halmac_size)1759 halmac_get_efuse_available_size_88xx(struct halmac_adapter *halmac_adapter,
1760 				     u32 *halmac_size)
1761 {
1762 	enum halmac_ret_status status;
1763 	void *driver_adapter = NULL;
1764 
1765 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1766 		return HALMAC_RET_ADAPTER_INVALID;
1767 
1768 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1769 		return HALMAC_RET_API_INVALID;
1770 
1771 	driver_adapter = halmac_adapter->driver_adapter;
1772 
1773 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1774 			"%s ==========>\n", __func__);
1775 
1776 	status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
1777 						    HALMAC_EFUSE_R_DRV);
1778 
1779 	if (status != HALMAC_RET_SUCCESS)
1780 		return status;
1781 
1782 	*halmac_size = halmac_adapter->hw_config_info.efuse_size -
1783 		       HALMAC_PROTECTED_EFUSE_SIZE_88XX -
1784 		       halmac_adapter->efuse_end;
1785 
1786 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1787 			"%s <==========\n", __func__);
1788 
1789 	return HALMAC_RET_SUCCESS;
1790 }
1791 
1792 /**
1793  * halmac_get_efuse_size_88xx() - get "physical" efuse size
1794  * @halmac_adapter : the adapter of halmac
1795  * @halmac_size : physical efuse size
1796  * Author : Ivan Lin/KaiYuan Chang
1797  * Return : enum halmac_ret_status
1798  * More details of status code can be found in prototype document
1799  */
1800 enum halmac_ret_status
halmac_get_efuse_size_88xx(struct halmac_adapter * halmac_adapter,u32 * halmac_size)1801 halmac_get_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
1802 			   u32 *halmac_size)
1803 {
1804 	void *driver_adapter = NULL;
1805 
1806 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1807 		return HALMAC_RET_ADAPTER_INVALID;
1808 
1809 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1810 		return HALMAC_RET_API_INVALID;
1811 
1812 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_EFUSE_SIZE);
1813 
1814 	driver_adapter = halmac_adapter->driver_adapter;
1815 
1816 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1817 			"%s ==========>\n", __func__);
1818 
1819 	*halmac_size = halmac_adapter->hw_config_info.efuse_size;
1820 
1821 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1822 			"%s <==========\n", __func__);
1823 
1824 	return HALMAC_RET_SUCCESS;
1825 }
1826 
1827 /**
1828  * halmac_get_logical_efuse_size_88xx() - get "logical" efuse size
1829  * @halmac_adapter : the adapter of halmac
1830  * @halmac_size : logical efuse size
1831  * Author : Ivan Lin/KaiYuan Chang
1832  * Return : enum halmac_ret_status
1833  * More details of status code can be found in prototype document
1834  */
1835 enum halmac_ret_status
halmac_get_logical_efuse_size_88xx(struct halmac_adapter * halmac_adapter,u32 * halmac_size)1836 halmac_get_logical_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
1837 				   u32 *halmac_size)
1838 {
1839 	void *driver_adapter = NULL;
1840 
1841 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1842 		return HALMAC_RET_ADAPTER_INVALID;
1843 
1844 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1845 		return HALMAC_RET_API_INVALID;
1846 
1847 	halmac_api_record_id_88xx(halmac_adapter,
1848 				  HALMAC_API_GET_LOGICAL_EFUSE_SIZE);
1849 
1850 	driver_adapter = halmac_adapter->driver_adapter;
1851 
1852 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1853 			"%s ==========>\n", __func__);
1854 
1855 	*halmac_size = halmac_adapter->hw_config_info.eeprom_size;
1856 
1857 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1858 			"%s <==========\n", __func__);
1859 
1860 	return HALMAC_RET_SUCCESS;
1861 }
1862 
1863 /**
1864  * halmac_dump_logical_efuse_map_88xx() - dump "logical" efuse map
1865  * @halmac_adapter : the adapter of halmac
1866  * @cfg : dump efuse method
1867  * Author : Soar
1868  * Return : enum halmac_ret_status
1869  * More details of status code can be found in prototype document
1870  */
1871 enum halmac_ret_status
halmac_dump_logical_efuse_map_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_read_cfg cfg)1872 halmac_dump_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
1873 				   enum halmac_efuse_read_cfg cfg)
1874 {
1875 	u8 *eeprom_map = NULL;
1876 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
1877 	void *driver_adapter = NULL;
1878 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1879 	enum halmac_cmd_process_status *process_status =
1880 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
1881 
1882 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1883 		return HALMAC_RET_ADAPTER_INVALID;
1884 
1885 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1886 		return HALMAC_RET_API_INVALID;
1887 
1888 	halmac_api_record_id_88xx(halmac_adapter,
1889 				  HALMAC_API_DUMP_LOGICAL_EFUSE_MAP);
1890 
1891 	driver_adapter = halmac_adapter->driver_adapter;
1892 
1893 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1894 			"%s ==========>cfg = %d\n", __func__, cfg);
1895 
1896 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1897 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1898 				"Wait/Rcvd event(dump efuse)...\n");
1899 		return HALMAC_RET_BUSY_STATE;
1900 	}
1901 
1902 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1903 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1904 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1905 				"Not idle state(dump efuse)...\n");
1906 		return HALMAC_RET_ERROR_STATE;
1907 	}
1908 
1909 	if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
1910 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
1911 				"[WARN]Dump logical efuse in suspend mode\n");
1912 
1913 	*process_status = HALMAC_CMD_PROCESS_IDLE;
1914 	halmac_adapter->event_trigger.logical_efuse_map = 1;
1915 
1916 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1917 						    HALMAC_EFUSE_BANK_WIFI);
1918 	if (status != HALMAC_RET_SUCCESS) {
1919 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1920 		return status;
1921 	}
1922 
1923 	status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
1924 
1925 	if (status != HALMAC_RET_SUCCESS) {
1926 		pr_err("halmac_eeprom_parser_88xx error = %x\n", status);
1927 		return status;
1928 	}
1929 
1930 	if (halmac_adapter->hal_efuse_map_valid) {
1931 		*process_status = HALMAC_CMD_PROCESS_DONE;
1932 
1933 		eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
1934 		if (!eeprom_map) {
1935 			/* out of memory */
1936 			return HALMAC_RET_MALLOC_FAIL;
1937 		}
1938 		memset(eeprom_map, 0xFF, eeprom_size);
1939 
1940 		if (halmac_eeprom_parser_88xx(halmac_adapter,
1941 					      halmac_adapter->hal_efuse_map,
1942 					      eeprom_map) != HALMAC_RET_SUCCESS) {
1943 			kfree(eeprom_map);
1944 			return HALMAC_RET_EEPROM_PARSING_FAIL;
1945 		}
1946 
1947 		PLATFORM_EVENT_INDICATION(
1948 			driver_adapter, HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
1949 			*process_status, eeprom_map, eeprom_size);
1950 		halmac_adapter->event_trigger.logical_efuse_map = 0;
1951 
1952 		kfree(eeprom_map);
1953 	}
1954 
1955 	if (halmac_transition_efuse_state_88xx(
1956 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1957 	    HALMAC_RET_SUCCESS)
1958 		return HALMAC_RET_ERROR_STATE;
1959 
1960 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1961 			"%s <==========\n", __func__);
1962 
1963 	return HALMAC_RET_SUCCESS;
1964 }
1965 
1966 /**
1967  * halmac_read_logical_efuse_88xx() - read logical efuse map 1 byte
1968  * @halmac_adapter : the adapter of halmac
1969  * @halmac_offset : offset
1970  * @value : 1 byte efuse value
1971  * Author : Soar
1972  * Return : enum halmac_ret_status
1973  * More details of status code can be found in prototype document
1974  */
1975 enum halmac_ret_status
halmac_read_logical_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset,u8 * value)1976 halmac_read_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
1977 			       u32 halmac_offset, u8 *value)
1978 {
1979 	u8 *eeprom_map = NULL;
1980 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
1981 	void *driver_adapter = NULL;
1982 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1983 
1984 	enum halmac_cmd_process_status *process_status =
1985 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
1986 
1987 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1988 		return HALMAC_RET_ADAPTER_INVALID;
1989 
1990 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1991 		return HALMAC_RET_API_INVALID;
1992 
1993 	halmac_api_record_id_88xx(halmac_adapter,
1994 				  HALMAC_API_READ_LOGICAL_EFUSE);
1995 
1996 	driver_adapter = halmac_adapter->driver_adapter;
1997 
1998 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1999 			"%s ==========>\n", __func__);
2000 
2001 	if (halmac_offset >= eeprom_size) {
2002 		pr_err("Offset is too large\n");
2003 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2004 	}
2005 
2006 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2007 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2008 				"Wait/Rcvd event(dump efuse)...\n");
2009 		return HALMAC_RET_BUSY_STATE;
2010 	}
2011 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2012 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2013 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2014 				"Not idle state(dump efuse)...\n");
2015 		return HALMAC_RET_ERROR_STATE;
2016 	}
2017 
2018 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2019 						    HALMAC_EFUSE_BANK_WIFI);
2020 	if (status != HALMAC_RET_SUCCESS) {
2021 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2022 		return status;
2023 	}
2024 
2025 	eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2026 	if (!eeprom_map) {
2027 		/* out of memory */
2028 		return HALMAC_RET_MALLOC_FAIL;
2029 	}
2030 	memset(eeprom_map, 0xFF, eeprom_size);
2031 
2032 	status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
2033 	if (status != HALMAC_RET_SUCCESS) {
2034 		pr_err("halmac_read_logical_efuse_map error = %x\n", status);
2035 		kfree(eeprom_map);
2036 		return status;
2037 	}
2038 
2039 	*value = *(eeprom_map + halmac_offset);
2040 
2041 	if (halmac_transition_efuse_state_88xx(
2042 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2043 	    HALMAC_RET_SUCCESS) {
2044 		kfree(eeprom_map);
2045 		return HALMAC_RET_ERROR_STATE;
2046 	}
2047 
2048 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2049 			"%s <==========\n", __func__);
2050 
2051 	kfree(eeprom_map);
2052 
2053 	return HALMAC_RET_SUCCESS;
2054 }
2055 
2056 /**
2057  * halmac_write_logical_efuse_88xx() - write "logical" efuse offset
2058  * @halmac_adapter : the adapter of halmac
2059  * @halmac_offset : offset
2060  * @halmac_value : value
2061  * Author : Soar
2062  * Return : enum halmac_ret_status
2063  * More details of status code can be found in prototype document
2064  */
2065 enum halmac_ret_status
halmac_write_logical_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 halmac_offset,u8 halmac_value)2066 halmac_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
2067 				u32 halmac_offset, u8 halmac_value)
2068 {
2069 	void *driver_adapter = NULL;
2070 	struct halmac_api *halmac_api;
2071 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2072 
2073 	enum halmac_cmd_process_status *process_status =
2074 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
2075 
2076 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2077 		return HALMAC_RET_ADAPTER_INVALID;
2078 
2079 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2080 		return HALMAC_RET_API_INVALID;
2081 
2082 	halmac_api_record_id_88xx(halmac_adapter,
2083 				  HALMAC_API_WRITE_LOGICAL_EFUSE);
2084 
2085 	driver_adapter = halmac_adapter->driver_adapter;
2086 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2087 
2088 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2089 			"%s ==========>\n", __func__);
2090 
2091 	if (halmac_offset >= halmac_adapter->hw_config_info.eeprom_size) {
2092 		pr_err("Offset is too large\n");
2093 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2094 	}
2095 
2096 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2097 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2098 				"Wait/Rcvd event(dump efuse)...\n");
2099 		return HALMAC_RET_BUSY_STATE;
2100 	}
2101 
2102 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2103 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2104 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2105 				"Not idle state(dump efuse)...\n");
2106 		return HALMAC_RET_ERROR_STATE;
2107 	}
2108 
2109 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2110 						    HALMAC_EFUSE_BANK_WIFI);
2111 	if (status != HALMAC_RET_SUCCESS) {
2112 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2113 		return status;
2114 	}
2115 
2116 	status = halmac_func_write_logical_efuse_88xx(
2117 		halmac_adapter, halmac_offset, halmac_value);
2118 	if (status != HALMAC_RET_SUCCESS) {
2119 		pr_err("halmac_write_logical_efuse error = %x\n", status);
2120 		return status;
2121 	}
2122 
2123 	if (halmac_transition_efuse_state_88xx(
2124 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2125 	    HALMAC_RET_SUCCESS)
2126 		return HALMAC_RET_ERROR_STATE;
2127 
2128 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2129 			"%s <==========\n", __func__);
2130 
2131 	return HALMAC_RET_SUCCESS;
2132 }
2133 
2134 /**
2135  * halmac_pg_efuse_by_map_88xx() - pg logical efuse by map
2136  * @halmac_adapter : the adapter of halmac
2137  * @pg_efuse_info : efuse map information
2138  * @cfg : dump efuse method
2139  * Author : Soar
2140  * Return : enum halmac_ret_status
2141  * More details of status code can be found in prototype document
2142  */
2143 enum halmac_ret_status
halmac_pg_efuse_by_map_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,enum halmac_efuse_read_cfg cfg)2144 halmac_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
2145 			    struct halmac_pg_efuse_info *pg_efuse_info,
2146 			    enum halmac_efuse_read_cfg cfg)
2147 {
2148 	void *driver_adapter = NULL;
2149 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2150 
2151 	enum halmac_cmd_process_status *process_status =
2152 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
2153 
2154 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2155 		return HALMAC_RET_ADAPTER_INVALID;
2156 
2157 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2158 		return HALMAC_RET_API_INVALID;
2159 
2160 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PG_EFUSE_BY_MAP);
2161 
2162 	driver_adapter = halmac_adapter->driver_adapter;
2163 
2164 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2165 			"%s ==========>\n", __func__);
2166 
2167 	if (pg_efuse_info->efuse_map_size !=
2168 	    halmac_adapter->hw_config_info.eeprom_size) {
2169 		pr_err("efuse_map_size is incorrect, should be %d bytes\n",
2170 		       halmac_adapter->hw_config_info.eeprom_size);
2171 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2172 	}
2173 
2174 	if ((pg_efuse_info->efuse_map_size & 0xF) > 0) {
2175 		pr_err("efuse_map_size should be multiple of 16\n");
2176 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2177 	}
2178 
2179 	if (pg_efuse_info->efuse_mask_size !=
2180 	    pg_efuse_info->efuse_map_size >> 4) {
2181 		pr_err("efuse_mask_size is incorrect, should be %d bytes\n",
2182 		       pg_efuse_info->efuse_map_size >> 4);
2183 		return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2184 	}
2185 
2186 	if (!pg_efuse_info->efuse_map) {
2187 		pr_err("efuse_map is NULL\n");
2188 		return HALMAC_RET_NULL_POINTER;
2189 	}
2190 
2191 	if (!pg_efuse_info->efuse_mask) {
2192 		pr_err("efuse_mask is NULL\n");
2193 		return HALMAC_RET_NULL_POINTER;
2194 	}
2195 
2196 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2197 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2198 				"Wait/Rcvd event(dump efuse)...\n");
2199 		return HALMAC_RET_BUSY_STATE;
2200 	}
2201 
2202 	if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2203 	    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2204 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2205 				"Not idle state(dump efuse)...\n");
2206 		return HALMAC_RET_ERROR_STATE;
2207 	}
2208 
2209 	status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2210 						    HALMAC_EFUSE_BANK_WIFI);
2211 	if (status != HALMAC_RET_SUCCESS) {
2212 		pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2213 		return status;
2214 	}
2215 
2216 	status = halmac_func_pg_efuse_by_map_88xx(halmac_adapter, pg_efuse_info,
2217 						  cfg);
2218 
2219 	if (status != HALMAC_RET_SUCCESS) {
2220 		pr_err("halmac_pg_efuse_by_map error = %x\n", status);
2221 		return status;
2222 	}
2223 
2224 	if (halmac_transition_efuse_state_88xx(
2225 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2226 	    HALMAC_RET_SUCCESS)
2227 		return HALMAC_RET_ERROR_STATE;
2228 
2229 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2230 			"%s <==========\n", __func__);
2231 
2232 	return HALMAC_RET_SUCCESS;
2233 }
2234 
2235 /**
2236  * halmac_get_c2h_info_88xx() - process halmac C2H packet
2237  * @halmac_adapter : the adapter of halmac
2238  * @halmac_buf : RX Packet pointer
2239  * @halmac_size : RX Packet size
2240  * Author : KaiYuan Chang/Ivan Lin
2241  *
2242  * Used to process c2h packet info from RX path. After receiving the packet,
2243  * user need to call this api and pass the packet pointer.
2244  *
2245  * Return : enum halmac_ret_status
2246  * More details of status code can be found in prototype document
2247  */
2248 enum halmac_ret_status
halmac_get_c2h_info_88xx(struct halmac_adapter * halmac_adapter,u8 * halmac_buf,u32 halmac_size)2249 halmac_get_c2h_info_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
2250 			 u32 halmac_size)
2251 {
2252 	void *driver_adapter = NULL;
2253 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2254 
2255 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2256 		return HALMAC_RET_ADAPTER_INVALID;
2257 
2258 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2259 		return HALMAC_RET_API_INVALID;
2260 
2261 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_C2H_INFO);
2262 
2263 	driver_adapter = halmac_adapter->driver_adapter;
2264 
2265 	/* Check if it is C2H packet */
2266 	if (GET_RX_DESC_C2H(halmac_buf)) {
2267 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2268 				"C2H packet, start parsing!\n");
2269 
2270 		status = halmac_parse_c2h_packet_88xx(halmac_adapter,
2271 						      halmac_buf, halmac_size);
2272 
2273 		if (status != HALMAC_RET_SUCCESS) {
2274 			pr_err("halmac_parse_c2h_packet_88xx error = %x\n",
2275 			       status);
2276 			return status;
2277 		}
2278 	}
2279 
2280 	return HALMAC_RET_SUCCESS;
2281 }
2282 
2283 enum halmac_ret_status
halmac_cfg_fwlps_option_88xx(struct halmac_adapter * halmac_adapter,struct halmac_fwlps_option * lps_option)2284 halmac_cfg_fwlps_option_88xx(struct halmac_adapter *halmac_adapter,
2285 			     struct halmac_fwlps_option *lps_option)
2286 {
2287 	void *driver_adapter = NULL;
2288 	struct halmac_fwlps_option *hal_fwlps_option;
2289 
2290 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2291 		return HALMAC_RET_ADAPTER_INVALID;
2292 
2293 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2294 		return HALMAC_RET_API_INVALID;
2295 
2296 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWLPS_OPTION);
2297 
2298 	driver_adapter = halmac_adapter->driver_adapter;
2299 	hal_fwlps_option = &halmac_adapter->fwlps_option;
2300 
2301 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2302 			"%s ==========>\n", __func__);
2303 
2304 	hal_fwlps_option->mode = lps_option->mode;
2305 	hal_fwlps_option->clk_request = lps_option->clk_request;
2306 	hal_fwlps_option->rlbm = lps_option->rlbm;
2307 	hal_fwlps_option->smart_ps = lps_option->smart_ps;
2308 	hal_fwlps_option->awake_interval = lps_option->awake_interval;
2309 	hal_fwlps_option->all_queue_uapsd = lps_option->all_queue_uapsd;
2310 	hal_fwlps_option->pwr_state = lps_option->pwr_state;
2311 	hal_fwlps_option->low_pwr_rx_beacon = lps_option->low_pwr_rx_beacon;
2312 	hal_fwlps_option->ant_auto_switch = lps_option->ant_auto_switch;
2313 	hal_fwlps_option->ps_allow_bt_high_priority =
2314 		lps_option->ps_allow_bt_high_priority;
2315 	hal_fwlps_option->protect_bcn = lps_option->protect_bcn;
2316 	hal_fwlps_option->silence_period = lps_option->silence_period;
2317 	hal_fwlps_option->fast_bt_connect = lps_option->fast_bt_connect;
2318 	hal_fwlps_option->two_antenna_en = lps_option->two_antenna_en;
2319 	hal_fwlps_option->adopt_user_setting = lps_option->adopt_user_setting;
2320 	hal_fwlps_option->drv_bcn_early_shift = lps_option->drv_bcn_early_shift;
2321 	hal_fwlps_option->enter_32K = lps_option->enter_32K;
2322 
2323 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2324 			"%s <==========\n", __func__);
2325 
2326 	return HALMAC_RET_SUCCESS;
2327 }
2328 
2329 enum halmac_ret_status
halmac_cfg_fwips_option_88xx(struct halmac_adapter * halmac_adapter,struct halmac_fwips_option * ips_option)2330 halmac_cfg_fwips_option_88xx(struct halmac_adapter *halmac_adapter,
2331 			     struct halmac_fwips_option *ips_option)
2332 {
2333 	void *driver_adapter = NULL;
2334 	struct halmac_fwips_option *ips_option_local;
2335 
2336 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2337 		return HALMAC_RET_ADAPTER_INVALID;
2338 
2339 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2340 		return HALMAC_RET_API_INVALID;
2341 
2342 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWIPS_OPTION);
2343 
2344 	driver_adapter = halmac_adapter->driver_adapter;
2345 
2346 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2347 			"%s ==========>\n", __func__);
2348 
2349 	ips_option_local = ips_option;
2350 
2351 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2352 			"%s <==========\n", __func__);
2353 
2354 	return HALMAC_RET_SUCCESS;
2355 }
2356 
2357 enum halmac_ret_status
halmac_enter_wowlan_88xx(struct halmac_adapter * halmac_adapter,struct halmac_wowlan_option * wowlan_option)2358 halmac_enter_wowlan_88xx(struct halmac_adapter *halmac_adapter,
2359 			 struct halmac_wowlan_option *wowlan_option)
2360 {
2361 	void *driver_adapter = NULL;
2362 	struct halmac_wowlan_option *wowlan_option_local;
2363 
2364 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2365 		return HALMAC_RET_ADAPTER_INVALID;
2366 
2367 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2368 		return HALMAC_RET_API_INVALID;
2369 
2370 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_WOWLAN);
2371 
2372 	driver_adapter = halmac_adapter->driver_adapter;
2373 
2374 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2375 			"%s ==========>\n", __func__);
2376 
2377 	wowlan_option_local = wowlan_option;
2378 
2379 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2380 			"%s <==========\n", __func__);
2381 
2382 	return HALMAC_RET_SUCCESS;
2383 }
2384 
2385 enum halmac_ret_status
halmac_leave_wowlan_88xx(struct halmac_adapter * halmac_adapter)2386 halmac_leave_wowlan_88xx(struct halmac_adapter *halmac_adapter)
2387 {
2388 	void *driver_adapter = NULL;
2389 
2390 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2391 		return HALMAC_RET_ADAPTER_INVALID;
2392 
2393 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2394 		return HALMAC_RET_API_INVALID;
2395 
2396 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_WOWLAN);
2397 
2398 	driver_adapter = halmac_adapter->driver_adapter;
2399 
2400 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2401 			"%s ==========>\n", __func__);
2402 
2403 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2404 			"%s <==========\n", __func__);
2405 
2406 	return HALMAC_RET_SUCCESS;
2407 }
2408 
2409 enum halmac_ret_status
halmac_enter_ps_88xx(struct halmac_adapter * halmac_adapter,enum halmac_ps_state ps_state)2410 halmac_enter_ps_88xx(struct halmac_adapter *halmac_adapter,
2411 		     enum halmac_ps_state ps_state)
2412 {
2413 	u8 rpwm;
2414 	void *driver_adapter = NULL;
2415 	struct halmac_api *halmac_api;
2416 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2417 
2418 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2419 		return HALMAC_RET_ADAPTER_INVALID;
2420 
2421 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2422 		return HALMAC_RET_API_INVALID;
2423 
2424 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2425 		return HALMAC_RET_NO_DLFW;
2426 
2427 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_PS);
2428 
2429 	driver_adapter = halmac_adapter->driver_adapter;
2430 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2431 
2432 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2433 			"%s ==========>\n", __func__);
2434 
2435 	if (ps_state == halmac_adapter->halmac_state.ps_state) {
2436 		pr_err("power state is already in PS State!!\n");
2437 		return HALMAC_RET_SUCCESS;
2438 	}
2439 
2440 	if (ps_state == HALMAC_PS_STATE_LPS) {
2441 		status = halmac_send_h2c_set_pwr_mode_88xx(
2442 			halmac_adapter, &halmac_adapter->fwlps_option);
2443 		if (status != HALMAC_RET_SUCCESS) {
2444 			pr_err("halmac_send_h2c_set_pwr_mode_88xx error = %x!!\n",
2445 			       status);
2446 			return status;
2447 		}
2448 	} else if (ps_state == HALMAC_PS_STATE_IPS) {
2449 	}
2450 
2451 	halmac_adapter->halmac_state.ps_state = ps_state;
2452 
2453 	/* Enter 32K */
2454 	if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
2455 		if (halmac_adapter->fwlps_option.enter_32K) {
2456 			rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
2457 				     (BIT(0))) &
2458 				    0x81);
2459 			HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1,
2460 					   rpwm);
2461 			halmac_adapter->low_clk = true;
2462 		}
2463 	} else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
2464 		if (halmac_adapter->fwlps_option.enter_32K) {
2465 			rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
2466 				     (BIT(0))) &
2467 				    0x81);
2468 			HALMAC_REG_WRITE_8(halmac_adapter, 0xFE58, rpwm);
2469 			halmac_adapter->low_clk = true;
2470 		}
2471 	}
2472 
2473 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2474 			"%s <==========\n", __func__);
2475 
2476 	return HALMAC_RET_SUCCESS;
2477 }
2478 
2479 enum halmac_ret_status
halmac_leave_ps_88xx(struct halmac_adapter * halmac_adapter)2480 halmac_leave_ps_88xx(struct halmac_adapter *halmac_adapter)
2481 {
2482 	u8 rpwm, cpwm;
2483 	u32 counter;
2484 	void *driver_adapter = NULL;
2485 	struct halmac_api *halmac_api;
2486 	struct halmac_fwlps_option fw_lps_option;
2487 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2488 
2489 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2490 		return HALMAC_RET_ADAPTER_INVALID;
2491 
2492 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2493 		return HALMAC_RET_API_INVALID;
2494 
2495 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2496 		return HALMAC_RET_NO_DLFW;
2497 
2498 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_PS);
2499 
2500 	driver_adapter = halmac_adapter->driver_adapter;
2501 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2502 
2503 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2504 			"%s ==========>\n", __func__);
2505 
2506 	if (halmac_adapter->halmac_state.ps_state == HALMAC_PS_STATE_ACT) {
2507 		pr_err("power state is already in active!!\n");
2508 		return HALMAC_RET_SUCCESS;
2509 	}
2510 
2511 	if (halmac_adapter->low_clk) {
2512 		cpwm = HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1);
2513 		rpwm = (u8)(
2514 			((halmac_adapter->rpwm_record ^ (BIT(7))) | (BIT(6))) &
2515 			0xC0);
2516 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1, rpwm);
2517 
2518 		cpwm = (u8)((cpwm ^ BIT(7)) & BIT(7));
2519 		counter = 100;
2520 		while (cpwm !=
2521 		       (HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1) &
2522 			BIT(7))) {
2523 			usleep_range(50, 60);
2524 			counter--;
2525 			if (counter == 0)
2526 				return HALMAC_RET_CHANGE_PS_FAIL;
2527 		}
2528 		halmac_adapter->low_clk = false;
2529 	}
2530 
2531 	memcpy(&fw_lps_option, &halmac_adapter->fwlps_option,
2532 	       sizeof(struct halmac_fwlps_option));
2533 	fw_lps_option.mode = 0;
2534 
2535 	status = halmac_send_h2c_set_pwr_mode_88xx(halmac_adapter,
2536 						   &fw_lps_option);
2537 	if (status != HALMAC_RET_SUCCESS) {
2538 		pr_err("halmac_send_h2c_set_pwr_mode_88xx error!!=%x\n",
2539 		       status);
2540 		return status;
2541 	}
2542 
2543 	halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
2544 
2545 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2546 			"%s <==========\n", __func__);
2547 
2548 	return HALMAC_RET_SUCCESS;
2549 }
2550 
2551 /**
2552  * (debug API)halmac_h2c_lb_88xx() - send h2c loopback packet
2553  * @halmac_adapter : the adapter of halmac
2554  * Author : KaiYuan Chang/Ivan Lin
2555  * Return : enum halmac_ret_status
2556  * More details of status code can be found in prototype document
2557  */
halmac_h2c_lb_88xx(struct halmac_adapter * halmac_adapter)2558 enum halmac_ret_status halmac_h2c_lb_88xx(struct halmac_adapter *halmac_adapter)
2559 {
2560 	void *driver_adapter = NULL;
2561 
2562 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2563 		return HALMAC_RET_ADAPTER_INVALID;
2564 
2565 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2566 		return HALMAC_RET_API_INVALID;
2567 
2568 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_H2C_LB);
2569 
2570 	driver_adapter = halmac_adapter->driver_adapter;
2571 
2572 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2573 			"%s ==========>\n", __func__);
2574 
2575 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2576 			"%s <==========\n", __func__);
2577 
2578 	return HALMAC_RET_SUCCESS;
2579 }
2580 
2581 /**
2582  * halmac_debug_88xx() - dump information for debugging
2583  * @halmac_adapter : the adapter of halmac
2584  * Author : KaiYuan Chang/Ivan Lin
2585  * Return : enum halmac_ret_status
2586  * More details of status code can be found in prototype document
2587  */
halmac_debug_88xx(struct halmac_adapter * halmac_adapter)2588 enum halmac_ret_status halmac_debug_88xx(struct halmac_adapter *halmac_adapter)
2589 {
2590 	u8 temp8 = 0;
2591 	u32 i = 0, temp32 = 0;
2592 	void *driver_adapter = NULL;
2593 	struct halmac_api *halmac_api;
2594 
2595 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2596 		return HALMAC_RET_ADAPTER_INVALID;
2597 
2598 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2599 		return HALMAC_RET_API_INVALID;
2600 
2601 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEBUG);
2602 
2603 	driver_adapter = halmac_adapter->driver_adapter;
2604 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2605 
2606 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2607 			"%s ==========>\n", __func__);
2608 
2609 	if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
2610 		/* Dump CCCR, it needs new platform api */
2611 
2612 		/*Dump SDIO Local Register, use CMD52*/
2613 		for (i = 0x10250000; i < 0x102500ff; i++) {
2614 			temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2615 			HALMAC_RT_TRACE(
2616 				driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2617 				"halmac_debug: sdio[%x]=%x\n", i, temp8);
2618 		}
2619 
2620 		/*Dump MAC Register*/
2621 		for (i = 0x0000; i < 0x17ff; i++) {
2622 			temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2623 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
2624 					DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
2625 					i, temp8);
2626 		}
2627 
2628 		/*Check RX Fifo status*/
2629 		i = REG_RXFF_PTR_V1;
2630 		temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2631 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2632 				"halmac_debug: mac[%x]=%x\n", i, temp8);
2633 		i = REG_RXFF_WTR_V1;
2634 		temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2635 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2636 				"halmac_debug: mac[%x]=%x\n", i, temp8);
2637 		i = REG_RXFF_PTR_V1;
2638 		temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2639 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2640 				"halmac_debug: mac[%x]=%x\n", i, temp8);
2641 		i = REG_RXFF_WTR_V1;
2642 		temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2643 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2644 				"halmac_debug: mac[%x]=%x\n", i, temp8);
2645 	} else {
2646 		/*Dump MAC Register*/
2647 		for (i = 0x0000; i < 0x17fc; i += 4) {
2648 			temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2649 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
2650 					DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
2651 					i, temp32);
2652 		}
2653 
2654 		/*Check RX Fifo status*/
2655 		i = REG_RXFF_PTR_V1;
2656 		temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2657 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2658 				"halmac_debug: mac[%x]=%x\n", i, temp32);
2659 		i = REG_RXFF_WTR_V1;
2660 		temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2661 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2662 				"halmac_debug: mac[%x]=%x\n", i, temp32);
2663 		i = REG_RXFF_PTR_V1;
2664 		temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2665 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2666 				"halmac_debug: mac[%x]=%x\n", i, temp32);
2667 		i = REG_RXFF_WTR_V1;
2668 		temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2669 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2670 				"halmac_debug: mac[%x]=%x\n", i, temp32);
2671 	}
2672 
2673 	/*	TODO: Add check register code, including MAC CLK, CPU CLK */
2674 
2675 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2676 			"%s <==========\n", __func__);
2677 
2678 	return HALMAC_RET_SUCCESS;
2679 }
2680 
2681 /**
2682  * halmac_cfg_parameter_88xx() - config parameter by FW
2683  * @halmac_adapter : the adapter of halmac
2684  * @para_info : cmd id, content
2685  * @full_fifo : parameter information
2686  *
2687  * If msk_en = true, the format of array is {reg_info, mask, value}.
2688  * If msk_en =_FAUSE, the format of array is {reg_info, value}
2689  * The format of reg_info is
2690  * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
2691  * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
2692  * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
2693  * ref_info[15:0]=offset
2694  *
2695  * Example: msk_en = false
2696  * {0x8100000a, 0x00001122}
2697  * =>Set RF register, path_B, offset 0xA to 0x00001122
2698  * {0x00000824, 0x11224433}
2699  * =>Set MAC_BB register, offset 0x800 to 0x11224433
2700  *
2701  * Note : full fifo mode only for init flow
2702  *
2703  * Author : KaiYuan Chang/Ivan Lin
2704  * Return : enum halmac_ret_status
2705  * More details of status code can be found in prototype document
2706  */
2707 enum halmac_ret_status
halmac_cfg_parameter_88xx(struct halmac_adapter * halmac_adapter,struct halmac_phy_parameter_info * para_info,u8 full_fifo)2708 halmac_cfg_parameter_88xx(struct halmac_adapter *halmac_adapter,
2709 			  struct halmac_phy_parameter_info *para_info,
2710 			  u8 full_fifo)
2711 {
2712 	void *driver_adapter = NULL;
2713 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
2714 	enum halmac_cmd_process_status *process_status =
2715 		&halmac_adapter->halmac_state.cfg_para_state_set.process_status;
2716 
2717 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2718 		return HALMAC_RET_ADAPTER_INVALID;
2719 
2720 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2721 		return HALMAC_RET_API_INVALID;
2722 
2723 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2724 		return HALMAC_RET_NO_DLFW;
2725 
2726 	if (halmac_adapter->fw_version.h2c_version < 4)
2727 		return HALMAC_RET_FW_NO_SUPPORT;
2728 
2729 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_PARAMETER);
2730 
2731 	driver_adapter = halmac_adapter->driver_adapter;
2732 
2733 	if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
2734 		pr_err("%s Fail due to DLFW NONE!!\n", __func__);
2735 		return HALMAC_RET_DLFW_FAIL;
2736 	}
2737 
2738 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2739 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2740 				"Wait event(cfg para)...\n");
2741 		return HALMAC_RET_BUSY_STATE;
2742 	}
2743 
2744 	if (halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
2745 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
2746 	    halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
2747 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
2748 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2749 				"Not idle state(cfg para)...\n");
2750 		return HALMAC_RET_BUSY_STATE;
2751 	}
2752 
2753 	*process_status = HALMAC_CMD_PROCESS_IDLE;
2754 
2755 	ret_status = halmac_send_h2c_phy_parameter_88xx(halmac_adapter,
2756 							para_info, full_fifo);
2757 
2758 	if (ret_status != HALMAC_RET_SUCCESS) {
2759 		pr_err("halmac_send_h2c_phy_parameter_88xx Fail!! = %x\n",
2760 		       ret_status);
2761 		return ret_status;
2762 	}
2763 
2764 	return ret_status;
2765 }
2766 
2767 /**
2768  * halmac_update_packet_88xx() - send specific packet to FW
2769  * @halmac_adapter : the adapter of halmac
2770  * @pkt_id : packet id, to know the purpose of this packet
2771  * @pkt : packet
2772  * @pkt_size : packet size
2773  *
2774  * Note : TX_DESC is not included in the pkt
2775  *
2776  * Author : KaiYuan Chang/Ivan Lin
2777  * Return : enum halmac_ret_status
2778  * More details of status code can be found in prototype document
2779  */
2780 enum halmac_ret_status
halmac_update_packet_88xx(struct halmac_adapter * halmac_adapter,enum halmac_packet_id pkt_id,u8 * pkt,u32 pkt_size)2781 halmac_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2782 			  enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size)
2783 {
2784 	void *driver_adapter = NULL;
2785 	struct halmac_api *halmac_api;
2786 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2787 	enum halmac_cmd_process_status *process_status =
2788 		&halmac_adapter->halmac_state.update_packet_set.process_status;
2789 
2790 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2791 		return HALMAC_RET_ADAPTER_INVALID;
2792 
2793 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2794 		return HALMAC_RET_API_INVALID;
2795 
2796 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2797 		return HALMAC_RET_NO_DLFW;
2798 
2799 	if (halmac_adapter->fw_version.h2c_version < 4)
2800 		return HALMAC_RET_FW_NO_SUPPORT;
2801 
2802 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_UPDATE_PACKET);
2803 
2804 	driver_adapter = halmac_adapter->driver_adapter;
2805 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2806 
2807 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2808 			"%s ==========>\n", __func__);
2809 
2810 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2811 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2812 				"Wait event(update_packet)...\n");
2813 		return HALMAC_RET_BUSY_STATE;
2814 	}
2815 
2816 	*process_status = HALMAC_CMD_PROCESS_SENDING;
2817 
2818 	status = halmac_send_h2c_update_packet_88xx(halmac_adapter, pkt_id, pkt,
2819 						    pkt_size);
2820 
2821 	if (status != HALMAC_RET_SUCCESS) {
2822 		pr_err("halmac_send_h2c_update_packet_88xx packet = %x,  fail = %x!!\n",
2823 		       pkt_id, status);
2824 		return status;
2825 	}
2826 
2827 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2828 			"%s <==========\n", __func__);
2829 
2830 	return HALMAC_RET_SUCCESS;
2831 }
2832 
2833 enum halmac_ret_status
halmac_bcn_ie_filter_88xx(struct halmac_adapter * halmac_adapter,struct halmac_bcn_ie_info * bcn_ie_info)2834 halmac_bcn_ie_filter_88xx(struct halmac_adapter *halmac_adapter,
2835 			  struct halmac_bcn_ie_info *bcn_ie_info)
2836 {
2837 	void *driver_adapter = NULL;
2838 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2839 
2840 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2841 		return HALMAC_RET_ADAPTER_INVALID;
2842 
2843 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2844 		return HALMAC_RET_API_INVALID;
2845 
2846 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2847 		return HALMAC_RET_NO_DLFW;
2848 
2849 	if (halmac_adapter->fw_version.h2c_version < 4)
2850 		return HALMAC_RET_FW_NO_SUPPORT;
2851 
2852 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_BCN_IE_FILTER);
2853 
2854 	driver_adapter = halmac_adapter->driver_adapter;
2855 
2856 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2857 			"%s ==========>\n", __func__);
2858 
2859 	status = halmac_send_h2c_update_bcn_parse_info_88xx(halmac_adapter,
2860 							    bcn_ie_info);
2861 
2862 	if (status != HALMAC_RET_SUCCESS) {
2863 		pr_err("halmac_send_h2c_update_bcn_parse_info_88xx fail = %x\n",
2864 		       status);
2865 		return status;
2866 	}
2867 
2868 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2869 			"%s <==========\n", __func__);
2870 
2871 	return HALMAC_RET_SUCCESS;
2872 }
2873 
2874 enum halmac_ret_status
halmac_update_datapack_88xx(struct halmac_adapter * halmac_adapter,enum halmac_data_type halmac_data_type,struct halmac_phy_parameter_info * para_info)2875 halmac_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2876 			    enum halmac_data_type halmac_data_type,
2877 			    struct halmac_phy_parameter_info *para_info)
2878 {
2879 	void *driver_adapter = NULL;
2880 
2881 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2882 		return HALMAC_RET_ADAPTER_INVALID;
2883 
2884 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2885 		return HALMAC_RET_API_INVALID;
2886 
2887 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2888 		return HALMAC_RET_NO_DLFW;
2889 
2890 	if (halmac_adapter->fw_version.h2c_version < 4)
2891 		return HALMAC_RET_FW_NO_SUPPORT;
2892 
2893 	driver_adapter = halmac_adapter->driver_adapter;
2894 
2895 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2896 			"[TRACE]%s ==========>\n", __func__);
2897 
2898 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2899 			"[TRACE]%s <==========\n", __func__);
2900 
2901 	return HALMAC_RET_SUCCESS;
2902 }
2903 
2904 enum halmac_ret_status
halmac_run_datapack_88xx(struct halmac_adapter * halmac_adapter,enum halmac_data_type halmac_data_type)2905 halmac_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2906 			 enum halmac_data_type halmac_data_type)
2907 {
2908 	void *driver_adapter = NULL;
2909 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
2910 
2911 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2912 		return HALMAC_RET_ADAPTER_INVALID;
2913 
2914 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2915 		return HALMAC_RET_API_INVALID;
2916 
2917 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2918 		return HALMAC_RET_NO_DLFW;
2919 
2920 	if (halmac_adapter->fw_version.h2c_version < 4)
2921 		return HALMAC_RET_FW_NO_SUPPORT;
2922 
2923 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RUN_DATAPACK);
2924 
2925 	driver_adapter = halmac_adapter->driver_adapter;
2926 
2927 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2928 			"%s ==========>\n", __func__);
2929 
2930 	ret_status = halmac_send_h2c_run_datapack_88xx(halmac_adapter,
2931 						       halmac_data_type);
2932 
2933 	if (ret_status != HALMAC_RET_SUCCESS) {
2934 		pr_err("halmac_send_h2c_run_datapack_88xx Fail, datatype = %x, status = %x!!\n",
2935 		       halmac_data_type, ret_status);
2936 		return ret_status;
2937 	}
2938 
2939 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2940 			"halmac_update_datapack_88xx <==========\n");
2941 
2942 	return HALMAC_RET_SUCCESS;
2943 }
2944 
2945 /**
2946  * halmac_cfg_drv_info_88xx() - config driver info
2947  * @halmac_adapter : the adapter of halmac
2948  * @halmac_drv_info : driver information selection
2949  * Author : KaiYuan Chang/Ivan Lin
2950  * Return : enum halmac_ret_status
2951  * More details of status code can be found in prototype document
2952  */
2953 enum halmac_ret_status
halmac_cfg_drv_info_88xx(struct halmac_adapter * halmac_adapter,enum halmac_drv_info halmac_drv_info)2954 halmac_cfg_drv_info_88xx(struct halmac_adapter *halmac_adapter,
2955 			 enum halmac_drv_info halmac_drv_info)
2956 {
2957 	u8 drv_info_size = 0;
2958 	u8 phy_status_en = 0;
2959 	u8 sniffer_en = 0;
2960 	u8 plcp_hdr_en = 0;
2961 	u32 value32;
2962 	void *driver_adapter = NULL;
2963 	struct halmac_api *halmac_api;
2964 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2965 
2966 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2967 		return HALMAC_RET_ADAPTER_INVALID;
2968 
2969 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2970 		return HALMAC_RET_API_INVALID;
2971 
2972 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_DRV_INFO);
2973 
2974 	driver_adapter = halmac_adapter->driver_adapter;
2975 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2976 
2977 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2978 			"%s ==========>\n", __func__);
2979 
2980 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2981 			"halmac_cfg_drv_info = %d\n", halmac_drv_info);
2982 
2983 	switch (halmac_drv_info) {
2984 	case HALMAC_DRV_INFO_NONE:
2985 		drv_info_size = 0;
2986 		phy_status_en = 0;
2987 		sniffer_en = 0;
2988 		plcp_hdr_en = 0;
2989 		break;
2990 	case HALMAC_DRV_INFO_PHY_STATUS:
2991 		drv_info_size = 4;
2992 		phy_status_en = 1;
2993 		sniffer_en = 0;
2994 		plcp_hdr_en = 0;
2995 		break;
2996 	case HALMAC_DRV_INFO_PHY_SNIFFER:
2997 		drv_info_size = 5; /* phy status 4byte, sniffer info 1byte */
2998 		phy_status_en = 1;
2999 		sniffer_en = 1;
3000 		plcp_hdr_en = 0;
3001 		break;
3002 	case HALMAC_DRV_INFO_PHY_PLCP:
3003 		drv_info_size = 6; /* phy status 4byte, plcp header 2byte */
3004 		phy_status_en = 1;
3005 		sniffer_en = 0;
3006 		plcp_hdr_en = 1;
3007 		break;
3008 	default:
3009 		status = HALMAC_RET_SW_CASE_NOT_SUPPORT;
3010 		pr_err("%s error = %x\n", __func__, status);
3011 		return status;
3012 	}
3013 
3014 	if (halmac_adapter->txff_allocation.rx_fifo_expanding_mode !=
3015 	    HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
3016 		drv_info_size = 0xF;
3017 
3018 	HALMAC_REG_WRITE_8(halmac_adapter, REG_RX_DRVINFO_SZ, drv_info_size);
3019 
3020 	halmac_adapter->drv_info_size = drv_info_size;
3021 
3022 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_RCR);
3023 	value32 = (value32 & (~BIT_APP_PHYSTS));
3024 	if (phy_status_en == 1)
3025 		value32 = value32 | BIT_APP_PHYSTS;
3026 	HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, value32);
3027 
3028 	value32 = HALMAC_REG_READ_32(halmac_adapter,
3029 				     REG_WMAC_OPTION_FUNCTION + 4);
3030 	value32 = (value32 & (~(BIT(8) | BIT(9))));
3031 	if (sniffer_en == 1)
3032 		value32 = value32 | BIT(9);
3033 	if (plcp_hdr_en == 1)
3034 		value32 = value32 | BIT(8);
3035 	HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
3036 			    value32);
3037 
3038 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3039 			"%s <==========\n", __func__);
3040 
3041 	return HALMAC_RET_SUCCESS;
3042 }
3043 
3044 enum halmac_ret_status
halmac_send_bt_coex_88xx(struct halmac_adapter * halmac_adapter,u8 * bt_buf,u32 bt_size,u8 ack)3045 halmac_send_bt_coex_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
3046 			 u32 bt_size, u8 ack)
3047 {
3048 	void *driver_adapter = NULL;
3049 	struct halmac_api *halmac_api;
3050 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3051 
3052 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3053 		return HALMAC_RET_ADAPTER_INVALID;
3054 
3055 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3056 		return HALMAC_RET_API_INVALID;
3057 
3058 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3059 		return HALMAC_RET_NO_DLFW;
3060 
3061 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_BT_COEX);
3062 
3063 	driver_adapter = halmac_adapter->driver_adapter;
3064 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3065 
3066 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3067 			"%s ==========>\n", __func__);
3068 
3069 	ret_status = halmac_send_bt_coex_cmd_88xx(halmac_adapter, bt_buf,
3070 						  bt_size, ack);
3071 
3072 	if (ret_status != HALMAC_RET_SUCCESS) {
3073 		pr_err("halmac_send_bt_coex_cmd_88xx Fail = %x!!\n",
3074 		       ret_status);
3075 		return ret_status;
3076 	}
3077 
3078 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3079 			"%s <==========\n", __func__);
3080 
3081 	return HALMAC_RET_SUCCESS;
3082 }
3083 
3084 /**
3085  * (debug API)halmac_verify_platform_api_88xx() - verify platform api
3086  * @halmac_adapter : the adapter of halmac
3087  * Author : KaiYuan Chang/Ivan Lin
3088  * Return : enum halmac_ret_status
3089  * More details of status code can be found in prototype document
3090  */
3091 enum halmac_ret_status
halmac_verify_platform_api_88xx(struct halmac_adapter * halmac_adapter)3092 halmac_verify_platform_api_88xx(struct halmac_adapter *halmac_adapter)
3093 {
3094 	void *driver_adapter = NULL;
3095 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3096 
3097 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3098 		return HALMAC_RET_ADAPTER_INVALID;
3099 
3100 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3101 		return HALMAC_RET_API_INVALID;
3102 
3103 	halmac_api_record_id_88xx(halmac_adapter,
3104 				  HALMAC_API_VERIFY_PLATFORM_API);
3105 
3106 	driver_adapter = halmac_adapter->driver_adapter;
3107 
3108 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3109 			"%s ==========>\n", __func__);
3110 
3111 	ret_status = halmac_verify_io_88xx(halmac_adapter);
3112 
3113 	if (ret_status != HALMAC_RET_SUCCESS)
3114 		return ret_status;
3115 
3116 	if (halmac_adapter->txff_allocation.la_mode != HALMAC_LA_MODE_FULL)
3117 		ret_status = halmac_verify_send_rsvd_page_88xx(halmac_adapter);
3118 
3119 	if (ret_status != HALMAC_RET_SUCCESS)
3120 		return ret_status;
3121 
3122 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3123 			"%s <==========\n", __func__);
3124 
3125 	return ret_status;
3126 }
3127 
3128 enum halmac_ret_status
halmac_send_original_h2c_88xx(struct halmac_adapter * halmac_adapter,u8 * original_h2c,u16 * seq,u8 ack)3129 halmac_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
3130 			      u8 *original_h2c, u16 *seq, u8 ack)
3131 {
3132 	void *driver_adapter = NULL;
3133 	struct halmac_api *halmac_api;
3134 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3135 
3136 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3137 		return HALMAC_RET_ADAPTER_INVALID;
3138 
3139 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3140 		return HALMAC_RET_API_INVALID;
3141 
3142 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3143 		return HALMAC_RET_NO_DLFW;
3144 
3145 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_ORIGINAL_H2C);
3146 
3147 	driver_adapter = halmac_adapter->driver_adapter;
3148 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3149 
3150 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3151 			"%s ==========>\n", __func__);
3152 
3153 	status = halmac_func_send_original_h2c_88xx(halmac_adapter,
3154 						    original_h2c, seq, ack);
3155 
3156 	if (status != HALMAC_RET_SUCCESS) {
3157 		pr_err("halmac_send_original_h2c FAIL = %x!!\n", status);
3158 		return status;
3159 	}
3160 
3161 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3162 			"%s <==========\n", __func__);
3163 
3164 	return HALMAC_RET_SUCCESS;
3165 }
3166 
3167 enum halmac_ret_status
halmac_timer_2s_88xx(struct halmac_adapter * halmac_adapter)3168 halmac_timer_2s_88xx(struct halmac_adapter *halmac_adapter)
3169 {
3170 	void *driver_adapter = NULL;
3171 
3172 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3173 		return HALMAC_RET_ADAPTER_INVALID;
3174 
3175 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3176 		return HALMAC_RET_API_INVALID;
3177 
3178 	driver_adapter = halmac_adapter->driver_adapter;
3179 
3180 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3181 			"%s ==========>\n", __func__);
3182 
3183 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3184 			"%s <==========\n", __func__);
3185 
3186 	return HALMAC_RET_SUCCESS;
3187 }
3188 
3189 /**
3190  * halmac_fill_txdesc_check_sum_88xx() -  fill in tx desc check sum
3191  * @halmac_adapter : the adapter of halmac
3192  * @cur_desc : tx desc packet
3193  * Author : KaiYuan Chang/Ivan Lin
3194  * Return : enum halmac_ret_status
3195  * More details of status code can be found in prototype document
3196  */
3197 enum halmac_ret_status
halmac_fill_txdesc_check_sum_88xx(struct halmac_adapter * halmac_adapter,u8 * cur_desc)3198 halmac_fill_txdesc_check_sum_88xx(struct halmac_adapter *halmac_adapter,
3199 				  u8 *cur_desc)
3200 {
3201 	u16 chk_result = 0;
3202 	u16 *data = (u16 *)NULL;
3203 	u32 i;
3204 	void *driver_adapter = NULL;
3205 	struct halmac_api *halmac_api;
3206 
3207 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3208 		return HALMAC_RET_ADAPTER_INVALID;
3209 
3210 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3211 		return HALMAC_RET_API_INVALID;
3212 
3213 	halmac_api_record_id_88xx(halmac_adapter,
3214 				  HALMAC_API_FILL_TXDESC_CHECKSUM);
3215 
3216 	driver_adapter = halmac_adapter->driver_adapter;
3217 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3218 
3219 	if (!cur_desc) {
3220 		pr_err("%s NULL PTR", __func__);
3221 		return HALMAC_RET_NULL_POINTER;
3222 	}
3223 
3224 	SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, 0x0000);
3225 
3226 	data = (u16 *)(cur_desc);
3227 
3228 	/* HW clculates only 32byte */
3229 	for (i = 0; i < 8; i++)
3230 		chk_result ^= (*(data + 2 * i) ^ *(data + (2 * i + 1)));
3231 
3232 	SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, chk_result);
3233 
3234 	return HALMAC_RET_SUCCESS;
3235 }
3236 
3237 /**
3238  * halmac_dump_fifo_88xx() - dump fifo data
3239  * @halmac_adapter : the adapter of halmac
3240  * @halmac_fifo_sel : FIFO selection
3241  * @halmac_start_addr : start address of selected FIFO
3242  * @halmac_fifo_dump_size : dump size of selected FIFO
3243  * @fifo_map : FIFO data
3244  *
3245  * Note : before dump fifo, user need to call halmac_get_fifo_size to
3246  * get fifo size. Then input this size to halmac_dump_fifo.
3247  *
3248  * Author : Ivan Lin/KaiYuan Chang
3249  * Return : enum halmac_ret_status
3250  * More details of status code can be found in prototype document
3251  */
3252 enum halmac_ret_status
halmac_dump_fifo_88xx(struct halmac_adapter * halmac_adapter,enum hal_fifo_sel halmac_fifo_sel,u32 halmac_start_addr,u32 halmac_fifo_dump_size,u8 * fifo_map)3253 halmac_dump_fifo_88xx(struct halmac_adapter *halmac_adapter,
3254 		      enum hal_fifo_sel halmac_fifo_sel, u32 halmac_start_addr,
3255 		      u32 halmac_fifo_dump_size, u8 *fifo_map)
3256 {
3257 	void *driver_adapter = NULL;
3258 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3259 
3260 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3261 		return HALMAC_RET_ADAPTER_INVALID;
3262 
3263 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3264 		return HALMAC_RET_API_INVALID;
3265 
3266 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FIFO);
3267 
3268 	driver_adapter = halmac_adapter->driver_adapter;
3269 
3270 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3271 			"%s ==========>\n", __func__);
3272 
3273 	if (halmac_fifo_sel == HAL_FIFO_SEL_TX &&
3274 	    (halmac_start_addr + halmac_fifo_dump_size) >
3275 		    halmac_adapter->hw_config_info.tx_fifo_size) {
3276 		pr_err("TX fifo dump size is too large\n");
3277 		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3278 	}
3279 
3280 	if (halmac_fifo_sel == HAL_FIFO_SEL_RX &&
3281 	    (halmac_start_addr + halmac_fifo_dump_size) >
3282 		    halmac_adapter->hw_config_info.rx_fifo_size) {
3283 		pr_err("RX fifo dump size is too large\n");
3284 		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3285 	}
3286 
3287 	if ((halmac_fifo_dump_size & (4 - 1)) != 0) {
3288 		pr_err("halmac_fifo_dump_size shall 4byte align\n");
3289 		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3290 	}
3291 
3292 	if (!fifo_map) {
3293 		pr_err("fifo_map address is NULL\n");
3294 		return HALMAC_RET_NULL_POINTER;
3295 	}
3296 
3297 	status = halmac_buffer_read_88xx(halmac_adapter, halmac_start_addr,
3298 					 halmac_fifo_dump_size, halmac_fifo_sel,
3299 					 fifo_map);
3300 
3301 	if (status != HALMAC_RET_SUCCESS) {
3302 		pr_err("halmac_buffer_read_88xx error = %x\n", status);
3303 		return status;
3304 	}
3305 
3306 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3307 			"%s <==========\n", __func__);
3308 
3309 	return HALMAC_RET_SUCCESS;
3310 }
3311 
3312 /**
3313  * halmac_get_fifo_size_88xx() - get fifo size
3314  * @halmac_adapter : the adapter of halmac
3315  * @halmac_fifo_sel : FIFO selection
3316  * Author : Ivan Lin/KaiYuan Chang
3317  * Return : u32
3318  * More details of status code can be found in prototype document
3319  */
halmac_get_fifo_size_88xx(struct halmac_adapter * halmac_adapter,enum hal_fifo_sel halmac_fifo_sel)3320 u32 halmac_get_fifo_size_88xx(struct halmac_adapter *halmac_adapter,
3321 			      enum hal_fifo_sel halmac_fifo_sel)
3322 {
3323 	u32 fifo_size = 0;
3324 
3325 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3326 		return HALMAC_RET_ADAPTER_INVALID;
3327 
3328 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3329 		return HALMAC_RET_API_INVALID;
3330 
3331 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_FIFO_SIZE);
3332 
3333 	if (halmac_fifo_sel == HAL_FIFO_SEL_TX)
3334 		fifo_size = halmac_adapter->hw_config_info.tx_fifo_size;
3335 	else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3336 		fifo_size = halmac_adapter->hw_config_info.rx_fifo_size;
3337 	else if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3338 		fifo_size =
3339 			((halmac_adapter->hw_config_info.tx_fifo_size >> 7) -
3340 			 halmac_adapter->txff_allocation.rsvd_pg_bndy)
3341 			<< 7;
3342 	else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3343 		fifo_size = 65536;
3344 	else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3345 		fifo_size = 65536;
3346 
3347 	return fifo_size;
3348 }
3349 
3350 /**
3351  * halmac_cfg_txbf_88xx() - enable/disable specific user's txbf
3352  * @halmac_adapter : the adapter of halmac
3353  * @userid : su bfee userid = 0 or 1 to apply TXBF
3354  * @bw : the sounding bandwidth
3355  * @txbf_en : 0: disable TXBF, 1: enable TXBF
3356  * Author : chunchu
3357  * Return : enum halmac_ret_status
3358  * More details of status code can be found in prototype document
3359  */
3360 enum halmac_ret_status
halmac_cfg_txbf_88xx(struct halmac_adapter * halmac_adapter,u8 userid,enum halmac_bw bw,u8 txbf_en)3361 halmac_cfg_txbf_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
3362 		     enum halmac_bw bw, u8 txbf_en)
3363 {
3364 	u16 temp42C = 0;
3365 	void *driver_adapter = NULL;
3366 	struct halmac_api *halmac_api;
3367 
3368 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3369 		return HALMAC_RET_ADAPTER_INVALID;
3370 
3371 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3372 		return HALMAC_RET_API_INVALID;
3373 
3374 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TXBF);
3375 
3376 	driver_adapter = halmac_adapter->driver_adapter;
3377 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3378 
3379 	if (txbf_en) {
3380 		switch (bw) {
3381 		case HALMAC_BW_80:
3382 			temp42C |= BIT_R_TXBF0_80M;
3383 			/* fall through */
3384 		case HALMAC_BW_40:
3385 			temp42C |= BIT_R_TXBF0_40M;
3386 			/* fall through */
3387 		case HALMAC_BW_20:
3388 			temp42C |= BIT_R_TXBF0_20M;
3389 			break;
3390 		default:
3391 			pr_err("%s invalid TXBF BW setting 0x%x of userid %d\n",
3392 			       __func__, bw, userid);
3393 			return HALMAC_RET_INVALID_SOUNDING_SETTING;
3394 		}
3395 	}
3396 
3397 	switch (userid) {
3398 	case 0:
3399 		temp42C |=
3400 			HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3401 			~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3402 		HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL, temp42C);
3403 		break;
3404 	case 1:
3405 		temp42C |=
3406 			HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3407 			~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3408 		HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2, temp42C);
3409 		break;
3410 	default:
3411 		pr_err("%s invalid userid %d\n", __func__, userid);
3412 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
3413 	}
3414 
3415 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3416 			"%s, txbf_en = %x <==========\n", __func__,
3417 			txbf_en);
3418 
3419 	return HALMAC_RET_SUCCESS;
3420 }
3421 
3422 /**
3423  * halmac_cfg_mumimo_88xx() -config mumimo
3424  * @halmac_adapter : the adapter of halmac
3425  * @cfgmu : parameters to configure MU PPDU Tx/Rx
3426  * Author : chunchu
3427  * Return : enum halmac_ret_status
3428  * More details of status code can be found in prototype document
3429  */
3430 enum halmac_ret_status
halmac_cfg_mumimo_88xx(struct halmac_adapter * halmac_adapter,struct halmac_cfg_mumimo_para * cfgmu)3431 halmac_cfg_mumimo_88xx(struct halmac_adapter *halmac_adapter,
3432 		       struct halmac_cfg_mumimo_para *cfgmu)
3433 {
3434 	void *driver_adapter = NULL;
3435 	struct halmac_api *halmac_api;
3436 	u8 i, idx, id0, id1, gid, mu_tab_sel;
3437 	u8 mu_tab_valid = 0;
3438 	u32 gid_valid[6] = {0};
3439 	u8 temp14C0 = 0;
3440 
3441 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3442 		return HALMAC_RET_ADAPTER_INVALID;
3443 
3444 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3445 		return HALMAC_RET_API_INVALID;
3446 
3447 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MUMIMO);
3448 
3449 	driver_adapter = halmac_adapter->driver_adapter;
3450 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3451 
3452 	if (cfgmu->role == HAL_BFEE) {
3453 		/*config MU BFEE*/
3454 		temp14C0 = HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
3455 			   ~BIT_MASK_R_MU_TABLE_VALID;
3456 		/*enable MU table 0 and 1, disable MU TX*/
3457 		HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3458 				   (temp14C0 | BIT(0) | BIT(1)) & ~(BIT(7)));
3459 
3460 		/*config GID valid table and user position table*/
3461 		mu_tab_sel =
3462 			HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
3463 			~(BIT(0) | BIT(1) | BIT(2));
3464 		for (i = 0; i < 2; i++) {
3465 			HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
3466 					   mu_tab_sel | i);
3467 			HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
3468 					    cfgmu->given_gid_tab[i]);
3469 			HALMAC_REG_WRITE_32(halmac_adapter,
3470 					    REG_MU_STA_USER_POS_INFO,
3471 					    cfgmu->given_user_pos[i * 2]);
3472 			HALMAC_REG_WRITE_32(halmac_adapter,
3473 					    REG_MU_STA_USER_POS_INFO + 4,
3474 					    cfgmu->given_user_pos[i * 2 + 1]);
3475 		}
3476 	} else {
3477 		/*config MU BFER*/
3478 		if (!cfgmu->mu_tx_en) {
3479 			HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3480 					   HALMAC_REG_READ_8(halmac_adapter,
3481 							     REG_MU_TX_CTL) &
3482 						   ~(BIT(7)));
3483 			HALMAC_RT_TRACE(
3484 				driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3485 				"%s disable mu tx <==========\n", __func__);
3486 			return HALMAC_RET_SUCCESS;
3487 		}
3488 
3489 		/*Transform BB grouping bitmap[14:0] to MAC GID_valid table*/
3490 		for (idx = 0; idx < 15; idx++) {
3491 			if (idx < 5) {
3492 				/*group_bitmap bit0~4, MU_STA0 with MUSTA1~5*/
3493 				id0 = 0;
3494 				id1 = (u8)(idx + 1);
3495 			} else if (idx < 9) {
3496 				/*group_bitmap bit5~8, MU_STA1 with MUSTA2~5*/
3497 				id0 = 1;
3498 				id1 = (u8)(idx - 3);
3499 			} else if (idx < 12) {
3500 				/*group_bitmap bit9~11, MU_STA2 with MUSTA3~5*/
3501 				id0 = 2;
3502 				id1 = (u8)(idx - 6);
3503 			} else if (idx < 14) {
3504 				/*group_bitmap bit12~13, MU_STA3 with MUSTA4~5*/
3505 				id0 = 3;
3506 				id1 = (u8)(idx - 8);
3507 			} else {
3508 				/*group_bitmap bit14, MU_STA4 with MUSTA5*/
3509 				id0 = 4;
3510 				id1 = (u8)(idx - 9);
3511 			}
3512 			if (cfgmu->grouping_bitmap & BIT(idx)) {
3513 				/*Pair 1*/
3514 				gid = (idx << 1) + 1;
3515 				gid_valid[id0] |= (BIT(gid));
3516 				gid_valid[id1] |= (BIT(gid));
3517 				/*Pair 2*/
3518 				gid += 1;
3519 				gid_valid[id0] |= (BIT(gid));
3520 				gid_valid[id1] |= (BIT(gid));
3521 			} else {
3522 				/*Pair 1*/
3523 				gid = (idx << 1) + 1;
3524 				gid_valid[id0] &= ~(BIT(gid));
3525 				gid_valid[id1] &= ~(BIT(gid));
3526 				/*Pair 2*/
3527 				gid += 1;
3528 				gid_valid[id0] &= ~(BIT(gid));
3529 				gid_valid[id1] &= ~(BIT(gid));
3530 			}
3531 		}
3532 
3533 		/*set MU STA GID valid TABLE*/
3534 		mu_tab_sel =
3535 			HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
3536 			~(BIT(0) | BIT(1) | BIT(2));
3537 		for (idx = 0; idx < 6; idx++) {
3538 			HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
3539 					   idx | mu_tab_sel);
3540 			HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
3541 					    gid_valid[idx]);
3542 		}
3543 
3544 		/*To validate the sounding successful MU STA and enable MU TX*/
3545 		for (i = 0; i < 6; i++) {
3546 			if (cfgmu->sounding_sts[i])
3547 				mu_tab_valid |= BIT(i);
3548 		}
3549 		HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3550 				   mu_tab_valid | BIT(7));
3551 	}
3552 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3553 			"%s <==========\n", __func__);
3554 	return HALMAC_RET_SUCCESS;
3555 }
3556 
3557 /**
3558  * halmac_cfg_sounding_88xx() - configure general sounding
3559  * @halmac_adapter : the adapter of halmac
3560  * @role : driver's role, BFer or BFee
3561  * @datarate : set ndpa tx rate if driver is BFer, or set csi response rate
3562  *             if driver is BFee
3563  * Author : chunchu
3564  * Return : enum halmac_ret_status
3565  * More details of status code can be found in prototype document
3566  */
3567 enum halmac_ret_status
halmac_cfg_sounding_88xx(struct halmac_adapter * halmac_adapter,enum halmac_snd_role role,enum halmac_data_rate datarate)3568 halmac_cfg_sounding_88xx(struct halmac_adapter *halmac_adapter,
3569 			 enum halmac_snd_role role,
3570 			 enum halmac_data_rate datarate)
3571 {
3572 	void *driver_adapter = NULL;
3573 	struct halmac_api *halmac_api;
3574 
3575 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3576 		return HALMAC_RET_ADAPTER_INVALID;
3577 
3578 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3579 		return HALMAC_RET_API_INVALID;
3580 
3581 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_SOUNDING);
3582 
3583 	driver_adapter = halmac_adapter->driver_adapter;
3584 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3585 
3586 	switch (role) {
3587 	case HAL_BFER:
3588 		HALMAC_REG_WRITE_32(
3589 			halmac_adapter, REG_TXBF_CTRL,
3590 			HALMAC_REG_READ_32(halmac_adapter, REG_TXBF_CTRL) |
3591 				BIT_R_ENABLE_NDPA | BIT_USE_NDPA_PARAMETER |
3592 				BIT_R_EN_NDPA_INT | BIT_DIS_NDP_BFEN);
3593 		HALMAC_REG_WRITE_8(halmac_adapter, REG_NDPA_RATE, datarate);
3594 		HALMAC_REG_WRITE_8(
3595 			halmac_adapter, REG_NDPA_OPT_CTRL,
3596 			HALMAC_REG_READ_8(halmac_adapter, REG_NDPA_OPT_CTRL) &
3597 				(~(BIT(0) | BIT(1))));
3598 		/*service file length 2 bytes; fix non-STA1 csi start offset */
3599 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 1,
3600 				   0x2 | BIT(7));
3601 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 2, 0x2);
3602 		break;
3603 	case HAL_BFEE:
3604 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0xDB);
3605 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 3, 0x50);
3606 		/*use ndpa rx rate to decide csi rate*/
3607 		HALMAC_REG_WRITE_8(halmac_adapter, REG_BBPSF_CTRL + 3,
3608 				   HALMAC_OFDM54 | BIT(6));
3609 		HALMAC_REG_WRITE_16(
3610 			halmac_adapter, REG_RRSR,
3611 			HALMAC_REG_READ_16(halmac_adapter, REG_RRSR) |
3612 				BIT(datarate));
3613 		/*RXFF do not accept BF Rpt Poll, avoid CSI crc error*/
3614 		HALMAC_REG_WRITE_8(
3615 			halmac_adapter, REG_RXFLTMAP1,
3616 			HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP1) &
3617 				(~(BIT(4))));
3618 		/*FWFF do not accept BF Rpt Poll, avoid CSI crc error*/
3619 		HALMAC_REG_WRITE_8(
3620 			halmac_adapter, REG_RXFLTMAP4,
3621 			HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP4) &
3622 				(~(BIT(4))));
3623 		break;
3624 	default:
3625 		pr_err("%s invalid role\n", __func__);
3626 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
3627 	}
3628 
3629 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3630 			"%s <==========\n", __func__);
3631 
3632 	return HALMAC_RET_SUCCESS;
3633 }
3634 
3635 /**
3636  * halmac_del_sounding_88xx() - reset general sounding
3637  * @halmac_adapter : the adapter of halmac
3638  * @role : driver's role, BFer or BFee
3639  * Author : chunchu
3640  * Return : enum halmac_ret_status
3641  * More details of status code can be found in prototype document
3642  */
3643 enum halmac_ret_status
halmac_del_sounding_88xx(struct halmac_adapter * halmac_adapter,enum halmac_snd_role role)3644 halmac_del_sounding_88xx(struct halmac_adapter *halmac_adapter,
3645 			 enum halmac_snd_role role)
3646 {
3647 	void *driver_adapter = NULL;
3648 	struct halmac_api *halmac_api;
3649 
3650 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3651 		return HALMAC_RET_ADAPTER_INVALID;
3652 
3653 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3654 		return HALMAC_RET_API_INVALID;
3655 
3656 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEL_SOUNDING);
3657 
3658 	driver_adapter = halmac_adapter->driver_adapter;
3659 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3660 
3661 	switch (role) {
3662 	case HAL_BFER:
3663 		HALMAC_REG_WRITE_8(halmac_adapter, REG_TXBF_CTRL + 3, 0);
3664 		break;
3665 	case HAL_BFEE:
3666 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0);
3667 		break;
3668 	default:
3669 		pr_err("%s invalid role\n", __func__);
3670 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
3671 	}
3672 
3673 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3674 			"%s <==========\n", __func__);
3675 
3676 	return HALMAC_RET_SUCCESS;
3677 }
3678 
3679 /**
3680  * halmac_su_bfee_entry_init_88xx() - config SU beamformee's registers
3681  * @halmac_adapter : the adapter of halmac
3682  * @userid : SU bfee userid = 0 or 1 to be added
3683  * @paid : partial AID of this bfee
3684  * Author : chunchu
3685  * Return : enum halmac_ret_status
3686  * More details of status code can be found in prototype document
3687  */
3688 enum halmac_ret_status
halmac_su_bfee_entry_init_88xx(struct halmac_adapter * halmac_adapter,u8 userid,u16 paid)3689 halmac_su_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
3690 			       u16 paid)
3691 {
3692 	u16 temp42C = 0;
3693 	void *driver_adapter = NULL;
3694 	struct halmac_api *halmac_api;
3695 
3696 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3697 		return HALMAC_RET_ADAPTER_INVALID;
3698 
3699 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3700 		return HALMAC_RET_API_INVALID;
3701 
3702 	halmac_api_record_id_88xx(halmac_adapter,
3703 				  HALMAC_API_SU_BFEE_ENTRY_INIT);
3704 
3705 	driver_adapter = halmac_adapter->driver_adapter;
3706 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3707 
3708 	switch (userid) {
3709 	case 0:
3710 		temp42C = HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3711 			  ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
3712 			    BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3713 		HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL,
3714 				    temp42C | paid);
3715 		HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
3716 				    paid);
3717 		break;
3718 	case 1:
3719 		temp42C =
3720 			HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3721 			~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
3722 			  BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3723 		HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2,
3724 				    temp42C | paid);
3725 		HALMAC_REG_WRITE_16(halmac_adapter,
3726 				    REG_ASSOCIATED_BFMEE_SEL + 2,
3727 				    paid | BIT(9));
3728 		break;
3729 	default:
3730 		pr_err("%s invalid userid %d\n", __func__,
3731 		       userid);
3732 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
3733 	}
3734 
3735 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3736 			"%s <==========\n", __func__);
3737 
3738 	return HALMAC_RET_SUCCESS;
3739 }
3740 
3741 /**
3742  * halmac_su_bfee_entry_init_88xx() - config SU beamformer's registers
3743  * @halmac_adapter : the adapter of halmac
3744  * @su_bfer_init : parameters to configure SU BFER entry
3745  * Author : chunchu
3746  * Return : enum halmac_ret_status
3747  * More details of status code can be found in prototype document
3748  */
3749 enum halmac_ret_status
halmac_su_bfer_entry_init_88xx(struct halmac_adapter * halmac_adapter,struct halmac_su_bfer_init_para * su_bfer_init)3750 halmac_su_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3751 			       struct halmac_su_bfer_init_para *su_bfer_init)
3752 {
3753 	u16 mac_address_H;
3754 	u32 mac_address_L;
3755 	void *driver_adapter = NULL;
3756 	struct halmac_api *halmac_api;
3757 
3758 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3759 		return HALMAC_RET_ADAPTER_INVALID;
3760 
3761 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3762 		return HALMAC_RET_API_INVALID;
3763 
3764 	halmac_api_record_id_88xx(halmac_adapter,
3765 				  HALMAC_API_SU_BFER_ENTRY_INIT);
3766 
3767 	driver_adapter = halmac_adapter->driver_adapter;
3768 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3769 
3770 	/* mac_address_L = bfer_address.address_l_h.address_low; */
3771 	/* mac_address_H = bfer_address.address_l_h.address_high; */
3772 
3773 	mac_address_L = le32_to_cpu(
3774 		su_bfer_init->bfer_address.address_l_h.le_address_low);
3775 	mac_address_H = le16_to_cpu(
3776 		su_bfer_init->bfer_address.address_l_h.le_address_high);
3777 
3778 	switch (su_bfer_init->userid) {
3779 	case 0:
3780 		HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
3781 				    mac_address_L);
3782 		HALMAC_REG_WRITE_16(halmac_adapter,
3783 				    REG_ASSOCIATED_BFMER0_INFO + 4,
3784 				    mac_address_H);
3785 		HALMAC_REG_WRITE_16(halmac_adapter,
3786 				    REG_ASSOCIATED_BFMER0_INFO + 6,
3787 				    su_bfer_init->paid);
3788 		HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
3789 				    su_bfer_init->csi_para);
3790 		break;
3791 	case 1:
3792 		HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
3793 				    mac_address_L);
3794 		HALMAC_REG_WRITE_16(halmac_adapter,
3795 				    REG_ASSOCIATED_BFMER1_INFO + 4,
3796 				    mac_address_H);
3797 		HALMAC_REG_WRITE_16(halmac_adapter,
3798 				    REG_ASSOCIATED_BFMER1_INFO + 6,
3799 				    su_bfer_init->paid);
3800 		HALMAC_REG_WRITE_16(halmac_adapter,
3801 				    REG_TX_CSI_RPT_PARAM_BW20 + 2,
3802 				    su_bfer_init->csi_para);
3803 		break;
3804 	default:
3805 		pr_err("%s invalid userid %d\n", __func__,
3806 		       su_bfer_init->userid);
3807 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
3808 	}
3809 
3810 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3811 			"%s <==========\n", __func__);
3812 
3813 	return HALMAC_RET_SUCCESS;
3814 }
3815 
3816 /**
3817  * halmac_mu_bfee_entry_init_88xx() - config MU beamformee's registers
3818  * @halmac_adapter : the adapter of halmac
3819  * @mu_bfee_init : parameters to configure MU BFEE entry
3820  * Author : chunchu
3821  * Return : enum halmac_ret_status
3822  * More details of status code can be found in prototype document
3823  */
3824 enum halmac_ret_status
halmac_mu_bfee_entry_init_88xx(struct halmac_adapter * halmac_adapter,struct halmac_mu_bfee_init_para * mu_bfee_init)3825 halmac_mu_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3826 			       struct halmac_mu_bfee_init_para *mu_bfee_init)
3827 {
3828 	u16 temp168X = 0, temp14C0;
3829 	void *driver_adapter = NULL;
3830 	struct halmac_api *halmac_api;
3831 
3832 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3833 		return HALMAC_RET_ADAPTER_INVALID;
3834 
3835 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3836 		return HALMAC_RET_API_INVALID;
3837 
3838 	halmac_api_record_id_88xx(halmac_adapter,
3839 				  HALMAC_API_MU_BFEE_ENTRY_INIT);
3840 
3841 	driver_adapter = halmac_adapter->driver_adapter;
3842 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3843 
3844 	temp168X |= mu_bfee_init->paid | BIT(9);
3845 	HALMAC_REG_WRITE_16(halmac_adapter, (0x1680 + mu_bfee_init->userid * 2),
3846 			    temp168X);
3847 
3848 	temp14C0 = HALMAC_REG_READ_16(halmac_adapter, REG_MU_TX_CTL) &
3849 		   ~(BIT(8) | BIT(9) | BIT(10));
3850 	HALMAC_REG_WRITE_16(halmac_adapter, REG_MU_TX_CTL,
3851 			    temp14C0 | ((mu_bfee_init->userid - 2) << 8));
3852 	HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD, 0);
3853 	HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO,
3854 			    mu_bfee_init->user_position_l);
3855 	HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO + 4,
3856 			    mu_bfee_init->user_position_h);
3857 
3858 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3859 			"%s <==========\n", __func__);
3860 
3861 	return HALMAC_RET_SUCCESS;
3862 }
3863 
3864 /**
3865  * halmac_mu_bfer_entry_init_88xx() - config MU beamformer's registers
3866  * @halmac_adapter : the adapter of halmac
3867  * @mu_bfer_init : parameters to configure MU BFER entry
3868  * Author : chunchu
3869  * Return : enum halmac_ret_status
3870  * More details of status code can be found in prototype document
3871  */
3872 enum halmac_ret_status
halmac_mu_bfer_entry_init_88xx(struct halmac_adapter * halmac_adapter,struct halmac_mu_bfer_init_para * mu_bfer_init)3873 halmac_mu_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3874 			       struct halmac_mu_bfer_init_para *mu_bfer_init)
3875 {
3876 	u16 temp1680 = 0;
3877 	u16 mac_address_H;
3878 	u32 mac_address_L;
3879 	void *driver_adapter = NULL;
3880 	struct halmac_api *halmac_api;
3881 
3882 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3883 		return HALMAC_RET_ADAPTER_INVALID;
3884 
3885 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3886 		return HALMAC_RET_API_INVALID;
3887 
3888 	halmac_api_record_id_88xx(halmac_adapter,
3889 				  HALMAC_API_MU_BFER_ENTRY_INIT);
3890 
3891 	driver_adapter = halmac_adapter->driver_adapter;
3892 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3893 
3894 	mac_address_L =
3895 	    le32_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_low);
3896 	mac_address_H =
3897 	    le16_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_high);
3898 
3899 	HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
3900 			    mac_address_L);
3901 	HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4,
3902 			    mac_address_H);
3903 	HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 6,
3904 			    mu_bfer_init->paid);
3905 	HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
3906 			    mu_bfer_init->csi_para);
3907 
3908 	temp1680 = HALMAC_REG_READ_16(halmac_adapter, 0x1680) & 0xC000;
3909 	temp1680 |= mu_bfer_init->my_aid | (mu_bfer_init->csi_length_sel << 12);
3910 	HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, temp1680);
3911 
3912 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3913 			"%s <==========\n", __func__);
3914 
3915 	return HALMAC_RET_SUCCESS;
3916 }
3917 
3918 /**
3919  * halmac_su_bfee_entry_del_88xx() - reset SU beamformee's registers
3920  * @halmac_adapter : the adapter of halmac
3921  * @userid : the SU BFee userid to be deleted
3922  * Author : chunchu
3923  * Return : enum halmac_ret_status
3924  * More details of status code can be found in prototype document
3925  */
3926 enum halmac_ret_status
halmac_su_bfee_entry_del_88xx(struct halmac_adapter * halmac_adapter,u8 userid)3927 halmac_su_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
3928 {
3929 	void *driver_adapter = NULL;
3930 	struct halmac_api *halmac_api;
3931 
3932 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3933 		return HALMAC_RET_ADAPTER_INVALID;
3934 
3935 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3936 		return HALMAC_RET_API_INVALID;
3937 
3938 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFEE_ENTRY_DEL);
3939 
3940 	driver_adapter = halmac_adapter->driver_adapter;
3941 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3942 
3943 	switch (userid) {
3944 	case 0:
3945 		HALMAC_REG_WRITE_16(
3946 			halmac_adapter, REG_TXBF_CTRL,
3947 			HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3948 				~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
3949 				  BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
3950 		HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
3951 				    0);
3952 		break;
3953 	case 1:
3954 		HALMAC_REG_WRITE_16(
3955 			halmac_adapter, REG_TXBF_CTRL + 2,
3956 			HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3957 				~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
3958 				  BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
3959 		HALMAC_REG_WRITE_16(halmac_adapter,
3960 				    REG_ASSOCIATED_BFMEE_SEL + 2, 0);
3961 		break;
3962 	default:
3963 		pr_err("%s invalid userid %d\n", __func__,
3964 		       userid);
3965 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
3966 	}
3967 
3968 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3969 			"%s <==========\n", __func__);
3970 
3971 	return HALMAC_RET_SUCCESS;
3972 }
3973 
3974 /**
3975  * halmac_su_bfee_entry_del_88xx() - reset SU beamformer's registers
3976  * @halmac_adapter : the adapter of halmac
3977  * @userid : the SU BFer userid to be deleted
3978  * Author : chunchu
3979  * Return : enum halmac_ret_status
3980  * More details of status code can be found in prototype document
3981  */
3982 enum halmac_ret_status
halmac_su_bfer_entry_del_88xx(struct halmac_adapter * halmac_adapter,u8 userid)3983 halmac_su_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
3984 {
3985 	void *driver_adapter = NULL;
3986 	struct halmac_api *halmac_api;
3987 
3988 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3989 		return HALMAC_RET_ADAPTER_INVALID;
3990 
3991 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3992 		return HALMAC_RET_API_INVALID;
3993 
3994 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFER_ENTRY_DEL);
3995 
3996 	driver_adapter = halmac_adapter->driver_adapter;
3997 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3998 
3999 	switch (userid) {
4000 	case 0:
4001 		HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
4002 				    0);
4003 		HALMAC_REG_WRITE_32(halmac_adapter,
4004 				    REG_ASSOCIATED_BFMER0_INFO + 4, 0);
4005 		break;
4006 	case 1:
4007 		HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
4008 				    0);
4009 		HALMAC_REG_WRITE_32(halmac_adapter,
4010 				    REG_ASSOCIATED_BFMER1_INFO + 4, 0);
4011 		break;
4012 	default:
4013 		pr_err("%s invalid userid %d\n", __func__,
4014 		       userid);
4015 		return HALMAC_RET_INVALID_SOUNDING_SETTING;
4016 	}
4017 
4018 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4019 			"%s <==========\n", __func__);
4020 
4021 	return HALMAC_RET_SUCCESS;
4022 }
4023 
4024 /**
4025  * halmac_mu_bfee_entry_del_88xx() - reset MU beamformee's registers
4026  * @halmac_adapter : the adapter of halmac
4027  * @userid : the MU STA userid to be deleted
4028  * Author : chunchu
4029  * Return : enum halmac_ret_status
4030  * More details of status code can be found in prototype document
4031  */
4032 enum halmac_ret_status
halmac_mu_bfee_entry_del_88xx(struct halmac_adapter * halmac_adapter,u8 userid)4033 halmac_mu_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
4034 {
4035 	void *driver_adapter = NULL;
4036 	struct halmac_api *halmac_api;
4037 
4038 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4039 		return HALMAC_RET_ADAPTER_INVALID;
4040 
4041 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4042 		return HALMAC_RET_API_INVALID;
4043 
4044 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFEE_ENTRY_DEL);
4045 
4046 	driver_adapter = halmac_adapter->driver_adapter;
4047 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4048 
4049 	HALMAC_REG_WRITE_16(halmac_adapter, 0x1680 + userid * 2, 0);
4050 	HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
4051 			   HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
4052 				   ~(BIT(userid - 2)));
4053 
4054 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4055 			"%s <==========\n", __func__);
4056 
4057 	return HALMAC_RET_SUCCESS;
4058 }
4059 
4060 /**
4061  * halmac_mu_bfer_entry_del_88xx() -reset MU beamformer's registers
4062  * @halmac_adapter : the adapter of halmac
4063  * Author : chunchu
4064  * Return : enum halmac_ret_status
4065  * More details of status code can be found in prototype document
4066  */
4067 enum halmac_ret_status
halmac_mu_bfer_entry_del_88xx(struct halmac_adapter * halmac_adapter)4068 halmac_mu_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter)
4069 {
4070 	void *driver_adapter = NULL;
4071 	struct halmac_api *halmac_api;
4072 
4073 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4074 		return HALMAC_RET_ADAPTER_INVALID;
4075 
4076 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4077 		return HALMAC_RET_API_INVALID;
4078 
4079 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFER_ENTRY_DEL);
4080 
4081 	driver_adapter = halmac_adapter->driver_adapter;
4082 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4083 
4084 	HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO, 0);
4085 	HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4, 0);
4086 	HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, 0);
4087 	HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL, 0);
4088 
4089 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4090 			"%s <==========\n", __func__);
4091 
4092 	return HALMAC_RET_SUCCESS;
4093 }
4094 
4095 /**
4096  * halmac_add_ch_info_88xx() -add channel information
4097  * @halmac_adapter : the adapter of halmac
4098  * @ch_info : channel information
4099  * Author : KaiYuan Chang/Ivan Lin
4100  * Return : enum halmac_ret_status
4101  * More details of status code can be found in prototype document
4102  */
4103 enum halmac_ret_status
halmac_add_ch_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ch_info * ch_info)4104 halmac_add_ch_info_88xx(struct halmac_adapter *halmac_adapter,
4105 			struct halmac_ch_info *ch_info)
4106 {
4107 	void *driver_adapter = NULL;
4108 	struct halmac_cs_info *ch_sw_info;
4109 	enum halmac_scan_cmd_construct_state state_scan;
4110 
4111 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4112 		return HALMAC_RET_ADAPTER_INVALID;
4113 
4114 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4115 		return HALMAC_RET_API_INVALID;
4116 
4117 	driver_adapter = halmac_adapter->driver_adapter;
4118 	ch_sw_info = &halmac_adapter->ch_sw_info;
4119 
4120 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4121 			"[TRACE]%s ==========>\n", __func__);
4122 
4123 	if (halmac_adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
4124 		pr_err("[ERR]%s: gen_info is not send to FW!!!!\n", __func__);
4125 		return HALMAC_RET_GEN_INFO_NOT_SENT;
4126 	}
4127 
4128 	state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
4129 	if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED &&
4130 	    state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4131 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
4132 				"[WARN]Scan machine fail(add ch info)...\n");
4133 		return HALMAC_RET_ERROR_STATE;
4134 	}
4135 
4136 	if (!ch_sw_info->ch_info_buf) {
4137 		ch_sw_info->ch_info_buf =
4138 			kzalloc(HALMAC_EXTRA_INFO_BUFF_SIZE_88XX, GFP_KERNEL);
4139 		if (!ch_sw_info->ch_info_buf)
4140 			return HALMAC_RET_NULL_POINTER;
4141 		ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf;
4142 		ch_sw_info->buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
4143 		ch_sw_info->avai_buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
4144 		ch_sw_info->total_size = 0;
4145 		ch_sw_info->extra_info_en = 0;
4146 		ch_sw_info->ch_num = 0;
4147 	}
4148 
4149 	if (ch_sw_info->extra_info_en == 1) {
4150 		pr_err("[ERR]%s: construct sequence wrong!!\n", __func__);
4151 		return HALMAC_RET_CH_SW_SEQ_WRONG;
4152 	}
4153 
4154 	if (ch_sw_info->avai_buf_size < 4) {
4155 		pr_err("[ERR]%s: no available buffer!!\n", __func__);
4156 		return HALMAC_RET_CH_SW_NO_BUF;
4157 	}
4158 
4159 	if (halmac_transition_scan_state_88xx(
4160 		    halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
4161 	    HALMAC_RET_SUCCESS)
4162 		return HALMAC_RET_ERROR_STATE;
4163 
4164 	CHANNEL_INFO_SET_CHANNEL(ch_sw_info->ch_info_buf_w, ch_info->channel);
4165 	CHANNEL_INFO_SET_PRI_CH_IDX(ch_sw_info->ch_info_buf_w,
4166 				    ch_info->pri_ch_idx);
4167 	CHANNEL_INFO_SET_BANDWIDTH(ch_sw_info->ch_info_buf_w, ch_info->bw);
4168 	CHANNEL_INFO_SET_TIMEOUT(ch_sw_info->ch_info_buf_w, ch_info->timeout);
4169 	CHANNEL_INFO_SET_ACTION_ID(ch_sw_info->ch_info_buf_w,
4170 				   ch_info->action_id);
4171 	CHANNEL_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
4172 				       ch_info->extra_info);
4173 
4174 	ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size - 4;
4175 	ch_sw_info->total_size = ch_sw_info->total_size + 4;
4176 	ch_sw_info->ch_num++;
4177 	ch_sw_info->extra_info_en = ch_info->extra_info;
4178 	ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w + 4;
4179 
4180 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4181 			"[TRACE]%s <==========\n", __func__);
4182 
4183 	return HALMAC_RET_SUCCESS;
4184 }
4185 
4186 /**
4187  * halmac_add_extra_ch_info_88xx() -add extra channel information
4188  * @halmac_adapter : the adapter of halmac
4189  * @ch_extra_info : extra channel information
4190  * Author : KaiYuan Chang/Ivan Lin
4191  * Return : enum halmac_ret_status
4192  * More details of status code can be found in prototype document
4193  */
4194 enum halmac_ret_status
halmac_add_extra_ch_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ch_extra_info * ch_extra_info)4195 halmac_add_extra_ch_info_88xx(struct halmac_adapter *halmac_adapter,
4196 			      struct halmac_ch_extra_info *ch_extra_info)
4197 {
4198 	void *driver_adapter = NULL;
4199 	struct halmac_cs_info *ch_sw_info;
4200 
4201 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4202 		return HALMAC_RET_ADAPTER_INVALID;
4203 
4204 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4205 		return HALMAC_RET_API_INVALID;
4206 
4207 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ADD_EXTRA_CH_INFO);
4208 
4209 	driver_adapter = halmac_adapter->driver_adapter;
4210 	ch_sw_info = &halmac_adapter->ch_sw_info;
4211 
4212 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4213 			"%s ==========>\n", __func__);
4214 
4215 	if (!ch_sw_info->ch_info_buf) {
4216 		pr_err("%s: NULL==ch_sw_info->ch_info_buf!!\n", __func__);
4217 		return HALMAC_RET_CH_SW_SEQ_WRONG;
4218 	}
4219 
4220 	if (ch_sw_info->extra_info_en == 0) {
4221 		pr_err("%s: construct sequence wrong!!\n", __func__);
4222 		return HALMAC_RET_CH_SW_SEQ_WRONG;
4223 	}
4224 
4225 	if (ch_sw_info->avai_buf_size <
4226 	    (u32)(ch_extra_info->extra_info_size + 2)) {
4227 		/* +2: ch_extra_info_id, ch_extra_info, ch_extra_info_size
4228 		 * are totally 2Byte
4229 		 */
4230 		pr_err("%s: no available buffer!!\n", __func__);
4231 		return HALMAC_RET_CH_SW_NO_BUF;
4232 	}
4233 
4234 	if (halmac_query_scan_curr_state_88xx(halmac_adapter) !=
4235 	    HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4236 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4237 				"Scan machine fail(add extra ch info)...\n");
4238 		return HALMAC_RET_ERROR_STATE;
4239 	}
4240 
4241 	if (halmac_transition_scan_state_88xx(
4242 		    halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
4243 	    HALMAC_RET_SUCCESS)
4244 		return HALMAC_RET_ERROR_STATE;
4245 
4246 	CH_EXTRA_INFO_SET_CH_EXTRA_INFO_ID(ch_sw_info->ch_info_buf_w,
4247 					   ch_extra_info->extra_action_id);
4248 	CH_EXTRA_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
4249 					ch_extra_info->extra_info);
4250 	CH_EXTRA_INFO_SET_CH_EXTRA_INFO_SIZE(ch_sw_info->ch_info_buf_w,
4251 					     ch_extra_info->extra_info_size);
4252 	memcpy(ch_sw_info->ch_info_buf_w + 2, ch_extra_info->extra_info_data,
4253 	       ch_extra_info->extra_info_size);
4254 
4255 	ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size -
4256 				    (2 + ch_extra_info->extra_info_size);
4257 	ch_sw_info->total_size =
4258 		ch_sw_info->total_size + (2 + ch_extra_info->extra_info_size);
4259 	ch_sw_info->extra_info_en = ch_extra_info->extra_info;
4260 	ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w +
4261 				    (2 + ch_extra_info->extra_info_size);
4262 
4263 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4264 			"%s <==========\n", __func__);
4265 
4266 	return HALMAC_RET_SUCCESS;
4267 }
4268 
4269 /**
4270  * halmac_ctrl_ch_switch_88xx() -send channel switch cmd
4271  * @halmac_adapter : the adapter of halmac
4272  * @cs_option : channel switch config
4273  * Author : KaiYuan Chang/Ivan Lin
4274  * Return : enum halmac_ret_status
4275  * More details of status code can be found in prototype document
4276  */
4277 enum halmac_ret_status
halmac_ctrl_ch_switch_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ch_switch_option * cs_option)4278 halmac_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
4279 			   struct halmac_ch_switch_option *cs_option)
4280 {
4281 	void *driver_adapter = NULL;
4282 	struct halmac_api *halmac_api;
4283 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4284 	enum halmac_scan_cmd_construct_state state_scan;
4285 	enum halmac_cmd_process_status *process_status =
4286 		&halmac_adapter->halmac_state.scan_state_set.process_status;
4287 
4288 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4289 		return HALMAC_RET_ADAPTER_INVALID;
4290 
4291 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4292 		return HALMAC_RET_API_INVALID;
4293 
4294 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4295 		return HALMAC_RET_NO_DLFW;
4296 
4297 	if (halmac_adapter->fw_version.h2c_version < 4)
4298 		return HALMAC_RET_FW_NO_SUPPORT;
4299 
4300 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_CH_SWITCH);
4301 
4302 	driver_adapter = halmac_adapter->driver_adapter;
4303 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4304 
4305 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4306 			"%s  cs_option->switch_en = %d==========>\n", __func__,
4307 			cs_option->switch_en);
4308 
4309 	if (!cs_option->switch_en)
4310 		*process_status = HALMAC_CMD_PROCESS_IDLE;
4311 
4312 	if (*process_status == HALMAC_CMD_PROCESS_SENDING ||
4313 	    *process_status == HALMAC_CMD_PROCESS_RCVD) {
4314 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4315 				"Wait event(ctrl ch switch)...\n");
4316 		return HALMAC_RET_BUSY_STATE;
4317 	}
4318 
4319 	state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
4320 	if (cs_option->switch_en) {
4321 		if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4322 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
4323 					DBG_DMESG,
4324 					"%s(on)  invalid in state %x\n",
4325 					__func__, state_scan);
4326 			return HALMAC_RET_ERROR_STATE;
4327 		}
4328 	} else {
4329 		if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
4330 			HALMAC_RT_TRACE(
4331 				driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4332 				"%s(off)  invalid in state %x\n", __func__,
4333 				state_scan);
4334 			return HALMAC_RET_ERROR_STATE;
4335 		}
4336 	}
4337 
4338 	status = halmac_func_ctrl_ch_switch_88xx(halmac_adapter, cs_option);
4339 
4340 	if (status != HALMAC_RET_SUCCESS) {
4341 		pr_err("halmac_ctrl_ch_switch FAIL = %x!!\n", status);
4342 		return status;
4343 	}
4344 
4345 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4346 			"%s <==========\n", __func__);
4347 
4348 	return HALMAC_RET_SUCCESS;
4349 }
4350 
4351 /**
4352  * halmac_clear_ch_info_88xx() -clear channel information
4353  * @halmac_adapter : the adapter of halmac
4354  * Author : KaiYuan Chang/Ivan Lin
4355  * Return : enum halmac_ret_status
4356  * More details of status code can be found in prototype document
4357  */
4358 enum halmac_ret_status
halmac_clear_ch_info_88xx(struct halmac_adapter * halmac_adapter)4359 halmac_clear_ch_info_88xx(struct halmac_adapter *halmac_adapter)
4360 {
4361 	void *driver_adapter = NULL;
4362 	struct halmac_api *halmac_api;
4363 
4364 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4365 		return HALMAC_RET_ADAPTER_INVALID;
4366 
4367 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4368 		return HALMAC_RET_API_INVALID;
4369 
4370 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CLEAR_CH_INFO);
4371 
4372 	driver_adapter = halmac_adapter->driver_adapter;
4373 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4374 
4375 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4376 			"%s ==========>\n", __func__);
4377 
4378 	if (halmac_query_scan_curr_state_88xx(halmac_adapter) ==
4379 	    HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
4380 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4381 				"Scan machine fail(clear ch info)...\n");
4382 		return HALMAC_RET_ERROR_STATE;
4383 	}
4384 
4385 	if (halmac_transition_scan_state_88xx(
4386 		    halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) !=
4387 	    HALMAC_RET_SUCCESS)
4388 		return HALMAC_RET_ERROR_STATE;
4389 
4390 	kfree(halmac_adapter->ch_sw_info.ch_info_buf);
4391 	halmac_adapter->ch_sw_info.ch_info_buf = NULL;
4392 	halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
4393 	halmac_adapter->ch_sw_info.extra_info_en = 0;
4394 	halmac_adapter->ch_sw_info.buf_size = 0;
4395 	halmac_adapter->ch_sw_info.avai_buf_size = 0;
4396 	halmac_adapter->ch_sw_info.total_size = 0;
4397 	halmac_adapter->ch_sw_info.ch_num = 0;
4398 
4399 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4400 			"%s <==========\n", __func__);
4401 
4402 	return HALMAC_RET_SUCCESS;
4403 }
4404 
halmac_p2pps_88xx(struct halmac_adapter * halmac_adapter,struct halmac_p2pps * p2p_ps)4405 enum halmac_ret_status halmac_p2pps_88xx(struct halmac_adapter *halmac_adapter,
4406 					 struct halmac_p2pps *p2p_ps)
4407 {
4408 	void *driver_adapter = NULL;
4409 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4410 
4411 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4412 		return HALMAC_RET_ADAPTER_INVALID;
4413 
4414 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4415 		return HALMAC_RET_API_INVALID;
4416 
4417 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4418 		return HALMAC_RET_NO_DLFW;
4419 
4420 	if (halmac_adapter->fw_version.h2c_version < 6)
4421 		return HALMAC_RET_FW_NO_SUPPORT;
4422 
4423 	driver_adapter = halmac_adapter->driver_adapter;
4424 
4425 	status = halmac_func_p2pps_88xx(halmac_adapter, p2p_ps);
4426 
4427 	if (status != HALMAC_RET_SUCCESS) {
4428 		pr_err("[ERR]halmac_p2pps FAIL = %x!!\n", status);
4429 		return status;
4430 	}
4431 
4432 	return HALMAC_RET_SUCCESS;
4433 }
4434 
4435 enum halmac_ret_status
halmac_func_p2pps_88xx(struct halmac_adapter * halmac_adapter,struct halmac_p2pps * p2p_ps)4436 halmac_func_p2pps_88xx(struct halmac_adapter *halmac_adapter,
4437 		       struct halmac_p2pps *p2p_ps)
4438 {
4439 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4440 	u16 h2c_seq_mum = 0;
4441 	void *driver_adapter = halmac_adapter->driver_adapter;
4442 	struct halmac_api *halmac_api;
4443 	struct halmac_h2c_header_info h2c_header_info;
4444 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4445 
4446 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4447 			"[TRACE]halmac_p2pps !!\n");
4448 
4449 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4450 
4451 	P2PPS_SET_OFFLOAD_EN(h2c_buff, p2p_ps->offload_en);
4452 	P2PPS_SET_ROLE(h2c_buff, p2p_ps->role);
4453 	P2PPS_SET_CTWINDOW_EN(h2c_buff, p2p_ps->ctwindow_en);
4454 	P2PPS_SET_NOA_EN(h2c_buff, p2p_ps->noa_en);
4455 	P2PPS_SET_NOA_SEL(h2c_buff, p2p_ps->noa_sel);
4456 	P2PPS_SET_ALLSTASLEEP(h2c_buff, p2p_ps->all_sta_sleep);
4457 	P2PPS_SET_DISCOVERY(h2c_buff, p2p_ps->discovery);
4458 	P2PPS_SET_P2P_PORT_ID(h2c_buff, p2p_ps->p2p_port_id);
4459 	P2PPS_SET_P2P_GROUP(h2c_buff, p2p_ps->p2p_group);
4460 	P2PPS_SET_P2P_MACID(h2c_buff, p2p_ps->p2p_macid);
4461 
4462 	P2PPS_SET_CTWINDOW_LENGTH(h2c_buff, p2p_ps->ctwindow_length);
4463 
4464 	P2PPS_SET_NOA_DURATION_PARA(h2c_buff, p2p_ps->noa_duration_para);
4465 	P2PPS_SET_NOA_INTERVAL_PARA(h2c_buff, p2p_ps->noa_interval_para);
4466 	P2PPS_SET_NOA_START_TIME_PARA(h2c_buff, p2p_ps->noa_start_time_para);
4467 	P2PPS_SET_NOA_COUNT_PARA(h2c_buff, p2p_ps->noa_count_para);
4468 
4469 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
4470 	h2c_header_info.content_size = 24;
4471 	h2c_header_info.ack = false;
4472 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4473 					      &h2c_header_info, &h2c_seq_mum);
4474 
4475 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4476 					  HALMAC_H2C_CMD_SIZE_88XX, false);
4477 
4478 	if (status != HALMAC_RET_SUCCESS)
4479 		pr_err("[ERR]halmac_send_h2c_p2pps_88xx Fail = %x!!\n", status);
4480 
4481 	return status;
4482 }
4483 
4484 /**
4485  * halmac_send_general_info_88xx() -send general information to FW
4486  * @halmac_adapter : the adapter of halmac
4487  * @general_info : general information
4488  * Author : KaiYuan Chang/Ivan Lin
4489  * Return : enum halmac_ret_status
4490  * More details of status code can be found in prototype document
4491  */
4492 enum halmac_ret_status
halmac_send_general_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_general_info * general_info)4493 halmac_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
4494 			      struct halmac_general_info *general_info)
4495 {
4496 	void *driver_adapter = NULL;
4497 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4498 
4499 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4500 		return HALMAC_RET_ADAPTER_INVALID;
4501 
4502 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4503 		return HALMAC_RET_API_INVALID;
4504 
4505 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4506 		return HALMAC_RET_NO_DLFW;
4507 
4508 	if (halmac_adapter->fw_version.h2c_version < 4)
4509 		return HALMAC_RET_FW_NO_SUPPORT;
4510 
4511 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_GENERAL_INFO);
4512 
4513 	driver_adapter = halmac_adapter->driver_adapter;
4514 
4515 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4516 			"%s ==========>\n", __func__);
4517 
4518 	if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
4519 		pr_err("%s Fail due to DLFW NONE!!\n", __func__);
4520 		return HALMAC_RET_DLFW_FAIL;
4521 	}
4522 
4523 	status = halmac_func_send_general_info_88xx(halmac_adapter,
4524 						    general_info);
4525 
4526 	if (status != HALMAC_RET_SUCCESS) {
4527 		pr_err("halmac_send_general_info error = %x\n", status);
4528 		return status;
4529 	}
4530 
4531 	if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_DONE)
4532 		halmac_adapter->halmac_state.dlfw_state = HALMAC_GEN_INFO_SENT;
4533 
4534 	halmac_adapter->gen_info_valid = true;
4535 	memcpy(&halmac_adapter->general_info, general_info,
4536 	       sizeof(struct halmac_general_info));
4537 
4538 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4539 			"%s <==========\n", __func__);
4540 
4541 	return HALMAC_RET_SUCCESS;
4542 }
4543 
4544 /**
4545  * halmac_start_iqk_88xx() -trigger FW IQK
4546  * @halmac_adapter : the adapter of halmac
4547  * @iqk_para : IQK parameter
4548  * Author : KaiYuan Chang/Ivan Lin
4549  * Return : enum halmac_ret_status
4550  * More details of status code can be found in prototype document
4551  */
4552 enum halmac_ret_status
halmac_start_iqk_88xx(struct halmac_adapter * halmac_adapter,struct halmac_iqk_para_ * iqk_para)4553 halmac_start_iqk_88xx(struct halmac_adapter *halmac_adapter,
4554 		      struct halmac_iqk_para_ *iqk_para)
4555 {
4556 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4557 	u16 h2c_seq_num = 0;
4558 	void *driver_adapter = NULL;
4559 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4560 	struct halmac_h2c_header_info h2c_header_info;
4561 	enum halmac_cmd_process_status *process_status =
4562 		&halmac_adapter->halmac_state.iqk_set.process_status;
4563 
4564 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4565 		return HALMAC_RET_ADAPTER_INVALID;
4566 
4567 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4568 		return HALMAC_RET_API_INVALID;
4569 
4570 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4571 		return HALMAC_RET_NO_DLFW;
4572 
4573 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_START_IQK);
4574 
4575 	driver_adapter = halmac_adapter->driver_adapter;
4576 
4577 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4578 			"%s ==========>\n", __func__);
4579 
4580 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
4581 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4582 				"Wait event(iqk)...\n");
4583 		return HALMAC_RET_BUSY_STATE;
4584 	}
4585 
4586 	*process_status = HALMAC_CMD_PROCESS_SENDING;
4587 
4588 	IQK_SET_CLEAR(h2c_buff, iqk_para->clear);
4589 	IQK_SET_SEGMENT_IQK(h2c_buff, iqk_para->segment_iqk);
4590 
4591 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_IQK;
4592 	h2c_header_info.content_size = 1;
4593 	h2c_header_info.ack = true;
4594 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4595 					      &h2c_header_info, &h2c_seq_num);
4596 
4597 	halmac_adapter->halmac_state.iqk_set.seq_num = h2c_seq_num;
4598 
4599 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4600 					  HALMAC_H2C_CMD_SIZE_88XX, true);
4601 
4602 	if (status != HALMAC_RET_SUCCESS) {
4603 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
4604 		return status;
4605 	}
4606 
4607 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4608 			"%s <==========\n", __func__);
4609 
4610 	return HALMAC_RET_SUCCESS;
4611 }
4612 
4613 /**
4614  * halmac_ctrl_pwr_tracking_88xx() -trigger FW power tracking
4615  * @halmac_adapter : the adapter of halmac
4616  * @pwr_tracking_opt : power tracking option
4617  * Author : KaiYuan Chang/Ivan Lin
4618  * Return : enum halmac_ret_status
4619  * More details of status code can be found in prototype document
4620  */
halmac_ctrl_pwr_tracking_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pwr_tracking_option * pwr_tracking_opt)4621 enum halmac_ret_status halmac_ctrl_pwr_tracking_88xx(
4622 	struct halmac_adapter *halmac_adapter,
4623 	struct halmac_pwr_tracking_option *pwr_tracking_opt)
4624 {
4625 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4626 	u16 h2c_seq_mum = 0;
4627 	void *driver_adapter = NULL;
4628 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4629 	struct halmac_h2c_header_info h2c_header_info;
4630 	enum halmac_cmd_process_status *process_status =
4631 		&halmac_adapter->halmac_state.power_tracking_set.process_status;
4632 
4633 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4634 		return HALMAC_RET_ADAPTER_INVALID;
4635 
4636 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4637 		return HALMAC_RET_API_INVALID;
4638 
4639 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4640 		return HALMAC_RET_NO_DLFW;
4641 
4642 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_PWR_TRACKING);
4643 
4644 	driver_adapter = halmac_adapter->driver_adapter;
4645 
4646 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4647 			"halmac_start_iqk_88xx ==========>\n");
4648 
4649 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
4650 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4651 				"Wait event(pwr tracking)...\n");
4652 		return HALMAC_RET_BUSY_STATE;
4653 	}
4654 
4655 	*process_status = HALMAC_CMD_PROCESS_SENDING;
4656 
4657 	POWER_TRACKING_SET_TYPE(h2c_buff, pwr_tracking_opt->type);
4658 	POWER_TRACKING_SET_BBSWING_INDEX(h2c_buff,
4659 					 pwr_tracking_opt->bbswing_index);
4660 	POWER_TRACKING_SET_ENABLE_A(
4661 		h2c_buff,
4662 		pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A].enable);
4663 	POWER_TRACKING_SET_TX_PWR_INDEX_A(
4664 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4665 				  .tx_pwr_index);
4666 	POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_A(
4667 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4668 				  .pwr_tracking_offset_value);
4669 	POWER_TRACKING_SET_TSSI_VALUE_A(
4670 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4671 				  .tssi_value);
4672 	POWER_TRACKING_SET_ENABLE_B(
4673 		h2c_buff,
4674 		pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B].enable);
4675 	POWER_TRACKING_SET_TX_PWR_INDEX_B(
4676 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4677 				  .tx_pwr_index);
4678 	POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_B(
4679 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4680 				  .pwr_tracking_offset_value);
4681 	POWER_TRACKING_SET_TSSI_VALUE_B(
4682 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4683 				  .tssi_value);
4684 	POWER_TRACKING_SET_ENABLE_C(
4685 		h2c_buff,
4686 		pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C].enable);
4687 	POWER_TRACKING_SET_TX_PWR_INDEX_C(
4688 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4689 				  .tx_pwr_index);
4690 	POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_C(
4691 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4692 				  .pwr_tracking_offset_value);
4693 	POWER_TRACKING_SET_TSSI_VALUE_C(
4694 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4695 				  .tssi_value);
4696 	POWER_TRACKING_SET_ENABLE_D(
4697 		h2c_buff,
4698 		pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D].enable);
4699 	POWER_TRACKING_SET_TX_PWR_INDEX_D(
4700 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4701 				  .tx_pwr_index);
4702 	POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_D(
4703 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4704 				  .pwr_tracking_offset_value);
4705 	POWER_TRACKING_SET_TSSI_VALUE_D(
4706 		h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4707 				  .tssi_value);
4708 
4709 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_POWER_TRACKING;
4710 	h2c_header_info.content_size = 20;
4711 	h2c_header_info.ack = true;
4712 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4713 					      &h2c_header_info, &h2c_seq_mum);
4714 
4715 	halmac_adapter->halmac_state.power_tracking_set.seq_num = h2c_seq_mum;
4716 
4717 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4718 					  HALMAC_H2C_CMD_SIZE_88XX, true);
4719 
4720 	if (status != HALMAC_RET_SUCCESS) {
4721 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
4722 		return status;
4723 	}
4724 
4725 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4726 			"halmac_start_iqk_88xx <==========\n");
4727 
4728 	return HALMAC_RET_SUCCESS;
4729 }
4730 
4731 /**
4732  * halmac_query_status_88xx() -query the offload feature status
4733  * @halmac_adapter : the adapter of halmac
4734  * @feature_id : feature_id
4735  * @process_status : feature_status
4736  * @data : data buffer
4737  * @size : data size
4738  *
4739  * Note :
4740  * If user wants to know the data size, use can allocate zero
4741  * size buffer first. If this size less than the data size, halmac
4742  * will return  HALMAC_RET_BUFFER_TOO_SMALL. User need to
4743  * re-allocate data buffer with correct data size.
4744  *
4745  * Author : Ivan Lin/KaiYuan Chang
4746  * Return : enum halmac_ret_status
4747  * More details of status code can be found in prototype document
4748  */
4749 enum halmac_ret_status
halmac_query_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_feature_id feature_id,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)4750 halmac_query_status_88xx(struct halmac_adapter *halmac_adapter,
4751 			 enum halmac_feature_id feature_id,
4752 			 enum halmac_cmd_process_status *process_status,
4753 			 u8 *data, u32 *size)
4754 {
4755 	void *driver_adapter = NULL;
4756 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4757 
4758 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4759 		return HALMAC_RET_ADAPTER_INVALID;
4760 
4761 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4762 		return HALMAC_RET_API_INVALID;
4763 
4764 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_QUERY_STATE);
4765 
4766 	driver_adapter = halmac_adapter->driver_adapter;
4767 
4768 	if (!process_status) {
4769 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4770 				"null pointer!!\n");
4771 		return HALMAC_RET_NULL_POINTER;
4772 	}
4773 
4774 	switch (feature_id) {
4775 	case HALMAC_FEATURE_CFG_PARA:
4776 		status = halmac_query_cfg_para_status_88xx(
4777 			halmac_adapter, process_status, data, size);
4778 		break;
4779 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
4780 		status = halmac_query_dump_physical_efuse_status_88xx(
4781 			halmac_adapter, process_status, data, size);
4782 		break;
4783 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
4784 		status = halmac_query_dump_logical_efuse_status_88xx(
4785 			halmac_adapter, process_status, data, size);
4786 		break;
4787 	case HALMAC_FEATURE_CHANNEL_SWITCH:
4788 		status = halmac_query_channel_switch_status_88xx(
4789 			halmac_adapter, process_status, data, size);
4790 		break;
4791 	case HALMAC_FEATURE_UPDATE_PACKET:
4792 		status = halmac_query_update_packet_status_88xx(
4793 			halmac_adapter, process_status, data, size);
4794 		break;
4795 	case HALMAC_FEATURE_IQK:
4796 		status = halmac_query_iqk_status_88xx(
4797 			halmac_adapter, process_status, data, size);
4798 		break;
4799 	case HALMAC_FEATURE_POWER_TRACKING:
4800 		status = halmac_query_power_tracking_status_88xx(
4801 			halmac_adapter, process_status, data, size);
4802 		break;
4803 	case HALMAC_FEATURE_PSD:
4804 		status = halmac_query_psd_status_88xx(
4805 			halmac_adapter, process_status, data, size);
4806 		break;
4807 	default:
4808 		pr_err("%s invalid feature id %d\n", __func__,
4809 		       feature_id);
4810 		return HALMAC_RET_INVALID_FEATURE_ID;
4811 	}
4812 
4813 	return status;
4814 }
4815 
4816 /**
4817  * halmac_reset_feature_88xx() -reset async api cmd status
4818  * @halmac_adapter : the adapter of halmac
4819  * @feature_id : feature_id
4820  * Author : Ivan Lin/KaiYuan Chang
4821  * Return : enum halmac_ret_status.
4822  * More details of status code can be found in prototype document
4823  */
4824 enum halmac_ret_status
halmac_reset_feature_88xx(struct halmac_adapter * halmac_adapter,enum halmac_feature_id feature_id)4825 halmac_reset_feature_88xx(struct halmac_adapter *halmac_adapter,
4826 			  enum halmac_feature_id feature_id)
4827 {
4828 	void *driver_adapter = NULL;
4829 	struct halmac_state *state = &halmac_adapter->halmac_state;
4830 
4831 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4832 		return HALMAC_RET_ADAPTER_INVALID;
4833 
4834 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4835 		return HALMAC_RET_API_INVALID;
4836 
4837 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RESET_FEATURE);
4838 
4839 	driver_adapter = halmac_adapter->driver_adapter;
4840 
4841 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4842 			"%s ==========>\n", __func__);
4843 
4844 	switch (feature_id) {
4845 	case HALMAC_FEATURE_CFG_PARA:
4846 		state->cfg_para_state_set.process_status =
4847 			HALMAC_CMD_PROCESS_IDLE;
4848 		state->cfg_para_state_set.cfg_para_cmd_construct_state =
4849 			HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
4850 		break;
4851 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
4852 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
4853 		state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4854 		state->efuse_state_set.efuse_cmd_construct_state =
4855 			HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
4856 		break;
4857 	case HALMAC_FEATURE_CHANNEL_SWITCH:
4858 		state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4859 		state->scan_state_set.scan_cmd_construct_state =
4860 			HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
4861 		break;
4862 	case HALMAC_FEATURE_UPDATE_PACKET:
4863 		state->update_packet_set.process_status =
4864 			HALMAC_CMD_PROCESS_IDLE;
4865 		break;
4866 	case HALMAC_FEATURE_ALL:
4867 		state->cfg_para_state_set.process_status =
4868 			HALMAC_CMD_PROCESS_IDLE;
4869 		state->cfg_para_state_set.cfg_para_cmd_construct_state =
4870 			HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
4871 		state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4872 		state->efuse_state_set.efuse_cmd_construct_state =
4873 			HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
4874 		state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4875 		state->scan_state_set.scan_cmd_construct_state =
4876 			HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
4877 		state->update_packet_set.process_status =
4878 			HALMAC_CMD_PROCESS_IDLE;
4879 		break;
4880 	default:
4881 		pr_err("%s invalid feature id %d\n", __func__,
4882 		       feature_id);
4883 		return HALMAC_RET_INVALID_FEATURE_ID;
4884 	}
4885 
4886 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4887 			"%s <==========\n", __func__);
4888 
4889 	return HALMAC_RET_SUCCESS;
4890 }
4891 
4892 /**
4893  * halmac_check_fw_status_88xx() -check fw status
4894  * @halmac_adapter : the adapter of halmac
4895  * @fw_status : fw status
4896  * Author : KaiYuan Chang/Ivan Lin
4897  * Return : enum halmac_ret_status
4898  * More details of status code can be found in prototype document
4899  */
4900 enum halmac_ret_status
halmac_check_fw_status_88xx(struct halmac_adapter * halmac_adapter,bool * fw_status)4901 halmac_check_fw_status_88xx(struct halmac_adapter *halmac_adapter,
4902 			    bool *fw_status)
4903 {
4904 	u32 value32 = 0, value32_backup = 0, i = 0;
4905 	void *driver_adapter = NULL;
4906 	struct halmac_api *halmac_api;
4907 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4908 
4909 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4910 		return HALMAC_RET_ADAPTER_INVALID;
4911 
4912 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4913 		return HALMAC_RET_API_INVALID;
4914 
4915 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CHECK_FW_STATUS);
4916 
4917 	driver_adapter = halmac_adapter->driver_adapter;
4918 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4919 
4920 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4921 			"%s ==========>\n", __func__);
4922 
4923 	value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG6);
4924 
4925 	if (value32 != 0) {
4926 		pr_err("halmac_check_fw_status REG_FW_DBG6 !=0\n");
4927 		*fw_status = false;
4928 		return status;
4929 	}
4930 
4931 	value32_backup = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
4932 
4933 	for (i = 0; i <= 10; i++) {
4934 		value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
4935 		if (value32_backup != value32)
4936 			break;
4937 
4938 		if (i == 10) {
4939 			pr_err("halmac_check_fw_status Polling FW PC fail\n");
4940 			*fw_status = false;
4941 			return status;
4942 		}
4943 	}
4944 
4945 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4946 			"%s <==========\n", __func__);
4947 
4948 	return status;
4949 }
4950 
4951 enum halmac_ret_status
halmac_dump_fw_dmem_88xx(struct halmac_adapter * halmac_adapter,u8 * dmem,u32 * size)4952 halmac_dump_fw_dmem_88xx(struct halmac_adapter *halmac_adapter, u8 *dmem,
4953 			 u32 *size)
4954 {
4955 	void *driver_adapter = NULL;
4956 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4957 
4958 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4959 		return HALMAC_RET_ADAPTER_INVALID;
4960 
4961 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4962 		return HALMAC_RET_API_INVALID;
4963 
4964 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FW_DMEM);
4965 
4966 	driver_adapter = halmac_adapter->driver_adapter;
4967 
4968 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4969 			"%s ==========>\n", __func__);
4970 
4971 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4972 			"%s <==========\n", __func__);
4973 
4974 	return status;
4975 }
4976 
4977 /**
4978  * halmac_cfg_max_dl_size_88xx() - config max download FW size
4979  * @halmac_adapter : the adapter of halmac
4980  * @size : max download fw size
4981  *
4982  * Halmac uses this setting to set max packet size for
4983  * download FW.
4984  * If user has not called this API, halmac use default
4985  * setting for download FW
4986  * Note1 : size need multiple of 2
4987  * Note2 : max size is 31K
4988  *
4989  * Author : Ivan Lin/KaiYuan Chang
4990  * Return : enum halmac_ret_status
4991  * More details of status code can be found in prototype document
4992  */
4993 enum halmac_ret_status
halmac_cfg_max_dl_size_88xx(struct halmac_adapter * halmac_adapter,u32 size)4994 halmac_cfg_max_dl_size_88xx(struct halmac_adapter *halmac_adapter, u32 size)
4995 {
4996 	void *driver_adapter = NULL;
4997 
4998 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4999 		return HALMAC_RET_ADAPTER_INVALID;
5000 
5001 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5002 		return HALMAC_RET_API_INVALID;
5003 
5004 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MAX_DL_SIZE);
5005 
5006 	driver_adapter = halmac_adapter->driver_adapter;
5007 
5008 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5009 			"%s ==========>\n", __func__);
5010 
5011 	if (size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX_88XX) {
5012 		pr_err("size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX!\n");
5013 		return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
5014 	}
5015 
5016 	if ((size & (2 - 1)) != 0) {
5017 		pr_err("size is not power of 2!\n");
5018 		return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
5019 	}
5020 
5021 	halmac_adapter->max_download_size = size;
5022 
5023 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5024 			"Cfg max size is : %X\n", size);
5025 
5026 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5027 			"%s <==========\n", __func__);
5028 
5029 	return HALMAC_RET_SUCCESS;
5030 }
5031 
5032 /**
5033  * halmac_psd_88xx() - trigger fw psd
5034  * @halmac_adapter : the adapter of halmac
5035  * @start_psd : start PSD
5036  * @end_psd : end PSD
5037  * Author : KaiYuan Chang/Ivan Lin
5038  * Return : enum halmac_ret_status
5039  * More details of status code can be found in prototype document
5040  */
halmac_psd_88xx(struct halmac_adapter * halmac_adapter,u16 start_psd,u16 end_psd)5041 enum halmac_ret_status halmac_psd_88xx(struct halmac_adapter *halmac_adapter,
5042 				       u16 start_psd, u16 end_psd)
5043 {
5044 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
5045 	u16 h2c_seq_mum = 0;
5046 	void *driver_adapter = NULL;
5047 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
5048 	struct halmac_h2c_header_info h2c_header_info;
5049 	enum halmac_cmd_process_status *process_status =
5050 		&halmac_adapter->halmac_state.psd_set.process_status;
5051 
5052 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5053 		return HALMAC_RET_ADAPTER_INVALID;
5054 
5055 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5056 		return HALMAC_RET_API_INVALID;
5057 
5058 	if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5059 		return HALMAC_RET_NO_DLFW;
5060 
5061 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PSD);
5062 
5063 	driver_adapter = halmac_adapter->driver_adapter;
5064 
5065 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5066 			"%s ==========>\n", __func__);
5067 
5068 	if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
5069 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5070 				"Wait event(psd)...\n");
5071 		return HALMAC_RET_BUSY_STATE;
5072 	}
5073 
5074 	kfree(halmac_adapter->halmac_state.psd_set.data);
5075 	halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
5076 
5077 	halmac_adapter->halmac_state.psd_set.data_size = 0;
5078 	halmac_adapter->halmac_state.psd_set.segment_size = 0;
5079 
5080 	*process_status = HALMAC_CMD_PROCESS_SENDING;
5081 
5082 	PSD_SET_START_PSD(h2c_buff, start_psd);
5083 	PSD_SET_END_PSD(h2c_buff, end_psd);
5084 
5085 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_PSD;
5086 	h2c_header_info.content_size = 4;
5087 	h2c_header_info.ack = true;
5088 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
5089 					      &h2c_header_info, &h2c_seq_mum);
5090 
5091 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
5092 					  HALMAC_H2C_CMD_SIZE_88XX, true);
5093 
5094 	if (status != HALMAC_RET_SUCCESS) {
5095 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
5096 		return status;
5097 	}
5098 
5099 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5100 			"%s <==========\n", __func__);
5101 
5102 	return HALMAC_RET_SUCCESS;
5103 }
5104 
5105 /**
5106  * halmac_cfg_la_mode_88xx() - config la mode
5107  * @halmac_adapter : the adapter of halmac
5108  * @la_mode :
5109  *	disable : no TXFF space reserved for LA debug
5110  *	partial : partial TXFF space is reserved for LA debug
5111  *	full : all TXFF space is reserved for LA debug
5112  * Author : KaiYuan Chang
5113  * Return : enum halmac_ret_status
5114  * More details of status code can be found in prototype document
5115  */
5116 enum halmac_ret_status
halmac_cfg_la_mode_88xx(struct halmac_adapter * halmac_adapter,enum halmac_la_mode la_mode)5117 halmac_cfg_la_mode_88xx(struct halmac_adapter *halmac_adapter,
5118 			enum halmac_la_mode la_mode)
5119 {
5120 	void *driver_adapter = NULL;
5121 
5122 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5123 		return HALMAC_RET_ADAPTER_INVALID;
5124 
5125 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5126 		return HALMAC_RET_API_INVALID;
5127 
5128 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_LA_MODE);
5129 
5130 	driver_adapter = halmac_adapter->driver_adapter;
5131 
5132 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5133 			"%s ==========>la_mode = %d\n", __func__,
5134 			la_mode);
5135 
5136 	halmac_adapter->txff_allocation.la_mode = la_mode;
5137 
5138 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5139 			"%s <==========\n", __func__);
5140 
5141 	return HALMAC_RET_SUCCESS;
5142 }
5143 
5144 /**
5145  * halmac_cfg_rx_fifo_expanding_mode_88xx() - rx fifo expanding
5146  * @halmac_adapter : the adapter of halmac
5147  * @la_mode :
5148  *	disable : normal mode
5149  *	1 block : Rx FIFO + 1 FIFO block; Tx fifo - 1 FIFO block
5150  *	2 block : Rx FIFO + 2 FIFO block; Tx fifo - 2 FIFO block
5151  *	3 block : Rx FIFO + 3 FIFO block; Tx fifo - 3 FIFO block
5152  * Author : Soar
5153  * Return : enum halmac_ret_status
5154  * More details of status code can be found in prototype document
5155  */
halmac_cfg_rx_fifo_expanding_mode_88xx(struct halmac_adapter * halmac_adapter,enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode)5156 enum halmac_ret_status halmac_cfg_rx_fifo_expanding_mode_88xx(
5157 	struct halmac_adapter *halmac_adapter,
5158 	enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode)
5159 {
5160 	void *driver_adapter = NULL;
5161 
5162 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5163 		return HALMAC_RET_ADAPTER_INVALID;
5164 
5165 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5166 		return HALMAC_RET_API_INVALID;
5167 
5168 	halmac_api_record_id_88xx(halmac_adapter,
5169 				  HALMAC_API_CFG_RX_FIFO_EXPANDING_MODE);
5170 
5171 	driver_adapter = halmac_adapter->driver_adapter;
5172 
5173 	HALMAC_RT_TRACE(
5174 		driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5175 		"%s ==========>rx_fifo_expanding_mode = %d\n", __func__,
5176 		rx_fifo_expanding_mode);
5177 
5178 	halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
5179 		rx_fifo_expanding_mode;
5180 
5181 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5182 			"%s <==========\n", __func__);
5183 
5184 	return HALMAC_RET_SUCCESS;
5185 }
5186 
5187 enum halmac_ret_status
halmac_config_security_88xx(struct halmac_adapter * halmac_adapter,struct halmac_security_setting * sec_setting)5188 halmac_config_security_88xx(struct halmac_adapter *halmac_adapter,
5189 			    struct halmac_security_setting *sec_setting)
5190 {
5191 	struct halmac_api *halmac_api;
5192 	void *driver_adapter = NULL;
5193 
5194 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5195 		return HALMAC_RET_ADAPTER_INVALID;
5196 
5197 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5198 		return HALMAC_RET_API_INVALID;
5199 
5200 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5201 	driver_adapter = halmac_adapter->driver_adapter;
5202 
5203 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5204 			"%s ==========>\n", __func__);
5205 
5206 	HALMAC_REG_WRITE_16(halmac_adapter, REG_CR,
5207 			    (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_CR) |
5208 				  BIT_MAC_SEC_EN));
5209 
5210 	if (sec_setting->tx_encryption == 1)
5211 		HALMAC_REG_WRITE_8(
5212 			halmac_adapter, REG_SECCFG,
5213 			HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(2));
5214 	else
5215 		HALMAC_REG_WRITE_8(
5216 			halmac_adapter, REG_SECCFG,
5217 			HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
5218 				~(BIT(2)));
5219 
5220 	if (sec_setting->rx_decryption == 1)
5221 		HALMAC_REG_WRITE_8(
5222 			halmac_adapter, REG_SECCFG,
5223 			HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(3));
5224 	else
5225 		HALMAC_REG_WRITE_8(
5226 			halmac_adapter, REG_SECCFG,
5227 			HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
5228 				~(BIT(3)));
5229 
5230 	if (sec_setting->bip_enable == 1) {
5231 		if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B)
5232 			return HALMAC_RET_BIP_NO_SUPPORT;
5233 	}
5234 
5235 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5236 			"%s <==========\n", __func__);
5237 
5238 	return HALMAC_RET_SUCCESS;
5239 }
5240 
halmac_get_used_cam_entry_num_88xx(struct halmac_adapter * halmac_adapter,enum hal_security_type sec_type)5241 u8 halmac_get_used_cam_entry_num_88xx(struct halmac_adapter *halmac_adapter,
5242 				      enum hal_security_type sec_type)
5243 {
5244 	u8 entry_num;
5245 	void *driver_adapter = NULL;
5246 
5247 	driver_adapter = halmac_adapter->driver_adapter;
5248 
5249 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5250 			"%s ==========>\n", __func__);
5251 
5252 	switch (sec_type) {
5253 	case HAL_SECURITY_TYPE_WEP40:
5254 	case HAL_SECURITY_TYPE_WEP104:
5255 	case HAL_SECURITY_TYPE_TKIP:
5256 	case HAL_SECURITY_TYPE_AES128:
5257 	case HAL_SECURITY_TYPE_GCMP128:
5258 	case HAL_SECURITY_TYPE_GCMSMS4:
5259 	case HAL_SECURITY_TYPE_BIP:
5260 		entry_num = 1;
5261 		break;
5262 	case HAL_SECURITY_TYPE_WAPI:
5263 	case HAL_SECURITY_TYPE_AES256:
5264 	case HAL_SECURITY_TYPE_GCMP256:
5265 		entry_num = 2;
5266 		break;
5267 	default:
5268 		entry_num = 0;
5269 		break;
5270 	}
5271 
5272 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5273 			"%s <==========\n", __func__);
5274 
5275 	return entry_num;
5276 }
5277 
5278 enum halmac_ret_status
halmac_write_cam_88xx(struct halmac_adapter * halmac_adapter,u32 entry_index,struct halmac_cam_entry_info * cam_entry_info)5279 halmac_write_cam_88xx(struct halmac_adapter *halmac_adapter, u32 entry_index,
5280 		      struct halmac_cam_entry_info *cam_entry_info)
5281 {
5282 	u32 i;
5283 	u32 command = 0x80010000;
5284 	struct halmac_api *halmac_api;
5285 	void *driver_adapter = NULL;
5286 	struct halmac_cam_entry_format *cam_entry_format = NULL;
5287 
5288 	driver_adapter = halmac_adapter->driver_adapter;
5289 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5290 
5291 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5292 			"[TRACE]%s ==========>\n", __func__);
5293 
5294 	if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5295 		return HALMAC_RET_ENTRY_INDEX_ERROR;
5296 
5297 	if (cam_entry_info->key_id > 3)
5298 		return HALMAC_RET_FAIL;
5299 
5300 	cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
5301 	if (!cam_entry_format)
5302 		return HALMAC_RET_NULL_POINTER;
5303 
5304 	cam_entry_format->key_id = cam_entry_info->key_id;
5305 	cam_entry_format->valid = cam_entry_info->valid;
5306 	memcpy(cam_entry_format->mac_address, cam_entry_info->mac_address, 6);
5307 	memcpy(cam_entry_format->key, cam_entry_info->key, 16);
5308 
5309 	switch (cam_entry_info->security_type) {
5310 	case HAL_SECURITY_TYPE_NONE:
5311 		cam_entry_format->type = 0;
5312 		break;
5313 	case HAL_SECURITY_TYPE_WEP40:
5314 		cam_entry_format->type = 1;
5315 		break;
5316 	case HAL_SECURITY_TYPE_WEP104:
5317 		cam_entry_format->type = 5;
5318 		break;
5319 	case HAL_SECURITY_TYPE_TKIP:
5320 		cam_entry_format->type = 2;
5321 		break;
5322 	case HAL_SECURITY_TYPE_AES128:
5323 		cam_entry_format->type = 4;
5324 		break;
5325 	case HAL_SECURITY_TYPE_WAPI:
5326 		cam_entry_format->type = 6;
5327 		break;
5328 	case HAL_SECURITY_TYPE_AES256:
5329 		cam_entry_format->type = 4;
5330 		cam_entry_format->ext_sectype = 1;
5331 		break;
5332 	case HAL_SECURITY_TYPE_GCMP128:
5333 		cam_entry_format->type = 7;
5334 		break;
5335 	case HAL_SECURITY_TYPE_GCMP256:
5336 	case HAL_SECURITY_TYPE_GCMSMS4:
5337 		cam_entry_format->type = 7;
5338 		cam_entry_format->ext_sectype = 1;
5339 		break;
5340 	case HAL_SECURITY_TYPE_BIP:
5341 		cam_entry_format->type = cam_entry_info->unicast == 1 ? 4 : 0;
5342 		cam_entry_format->mgnt = 1;
5343 		cam_entry_format->grp = cam_entry_info->unicast == 1 ? 0 : 1;
5344 		break;
5345 	default:
5346 		kfree(cam_entry_format);
5347 		return HALMAC_RET_FAIL;
5348 	}
5349 
5350 	for (i = 0; i < 8; i++) {
5351 		HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5352 				    *((u32 *)cam_entry_format + i));
5353 		HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5354 				    command | ((entry_index << 3) + i));
5355 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5356 				"[TRACE]1 - CAM entry format : %X\n",
5357 				*((u32 *)cam_entry_format + i));
5358 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5359 				"[TRACE]1 - REG_CAMCMD : %X\n",
5360 				command | ((entry_index << 3) + i));
5361 	}
5362 
5363 	if (cam_entry_info->security_type == HAL_SECURITY_TYPE_WAPI ||
5364 	    cam_entry_info->security_type == HAL_SECURITY_TYPE_AES256 ||
5365 	    cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMP256 ||
5366 	    cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMSMS4) {
5367 		cam_entry_format->mic = 1;
5368 		memcpy(cam_entry_format->key, cam_entry_info->key_ext, 16);
5369 
5370 		for (i = 0; i < 8; i++) {
5371 			HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5372 					    *((u32 *)cam_entry_format + i));
5373 			HALMAC_REG_WRITE_32(
5374 				halmac_adapter, REG_CAMCMD,
5375 				command | (((entry_index + 1) << 3) + i));
5376 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON,
5377 					DBG_DMESG,
5378 					"[TRACE]2 - CAM entry format : %X\n",
5379 					*((u32 *)cam_entry_format + i));
5380 			HALMAC_RT_TRACE(
5381 				driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5382 				"[TRACE]2 - REG_CAMCMD : %X\n",
5383 				command | (((entry_index + 1) << 3) + i));
5384 		}
5385 	}
5386 
5387 	kfree(cam_entry_format);
5388 
5389 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5390 			"[TRACE]%s <==========\n", __func__);
5391 
5392 	return HALMAC_RET_SUCCESS;
5393 }
5394 
5395 enum halmac_ret_status
halmac_read_cam_entry_88xx(struct halmac_adapter * halmac_adapter,u32 entry_index,struct halmac_cam_entry_format * content)5396 halmac_read_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
5397 			   u32 entry_index,
5398 			   struct halmac_cam_entry_format *content)
5399 {
5400 	u32 i;
5401 	u32 command = 0x80000000;
5402 	struct halmac_api *halmac_api;
5403 	void *driver_adapter = NULL;
5404 
5405 	driver_adapter = halmac_adapter->driver_adapter;
5406 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5407 
5408 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5409 			"%s ==========>\n", __func__);
5410 
5411 	if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5412 		return HALMAC_RET_ENTRY_INDEX_ERROR;
5413 
5414 	for (i = 0; i < 8; i++) {
5415 		HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5416 				    command | ((entry_index << 3) + i));
5417 		*((u32 *)content + i) =
5418 			HALMAC_REG_READ_32(halmac_adapter, REG_CAMREAD);
5419 	}
5420 
5421 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5422 			"%s <==========\n", __func__);
5423 
5424 	return HALMAC_RET_SUCCESS;
5425 }
5426 
5427 enum halmac_ret_status
halmac_clear_cam_entry_88xx(struct halmac_adapter * halmac_adapter,u32 entry_index)5428 halmac_clear_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
5429 			    u32 entry_index)
5430 {
5431 	u32 i;
5432 	u32 command = 0x80010000;
5433 	void *driver_adapter = NULL;
5434 	struct halmac_api *halmac_api;
5435 	struct halmac_cam_entry_format *cam_entry_format;
5436 
5437 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5438 		return HALMAC_RET_ADAPTER_INVALID;
5439 
5440 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5441 		return HALMAC_RET_API_INVALID;
5442 
5443 	driver_adapter = halmac_adapter->driver_adapter;
5444 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5445 
5446 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5447 			"[TRACE]halmac_clear_security_cam_88xx ==========>\n");
5448 
5449 	if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5450 		return HALMAC_RET_ENTRY_INDEX_ERROR;
5451 
5452 	cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
5453 	if (!cam_entry_format)
5454 		return HALMAC_RET_NULL_POINTER;
5455 
5456 	for (i = 0; i < 8; i++) {
5457 		HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5458 				    *((u32 *)cam_entry_format + i));
5459 		HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5460 				    command | ((entry_index << 3) + i));
5461 	}
5462 
5463 	kfree(cam_entry_format);
5464 
5465 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5466 			"[TRACE]halmac_clear_security_cam_88xx <==========\n");
5467 
5468 	return HALMAC_RET_SUCCESS;
5469 }
5470 
5471 /**
5472  * halmac_get_hw_value_88xx() -get hw config value
5473  * @halmac_adapter : the adapter of halmac
5474  * @hw_id : hw id for driver to query
5475  * @pvalue : hw value, reference table to get data type
5476  * Author : KaiYuan Chang / Ivan Lin
5477  * Return : enum halmac_ret_status
5478  * More details of status code can be found in prototype document
5479  */
5480 enum halmac_ret_status
halmac_get_hw_value_88xx(struct halmac_adapter * halmac_adapter,enum halmac_hw_id hw_id,void * pvalue)5481 halmac_get_hw_value_88xx(struct halmac_adapter *halmac_adapter,
5482 			 enum halmac_hw_id hw_id, void *pvalue)
5483 {
5484 	void *driver_adapter = NULL;
5485 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
5486 
5487 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5488 		return HALMAC_RET_ADAPTER_INVALID;
5489 
5490 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5491 		return HALMAC_RET_API_INVALID;
5492 
5493 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
5494 
5495 	driver_adapter = halmac_adapter->driver_adapter;
5496 
5497 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5498 			"%s ==========>\n", __func__);
5499 
5500 	if (!pvalue) {
5501 		pr_err("%s (!pvalue)==========>\n", __func__);
5502 		return HALMAC_RET_NULL_POINTER;
5503 	}
5504 
5505 	switch (hw_id) {
5506 	case HALMAC_HW_RQPN_MAPPING:
5507 		((struct halmac_rqpn_map *)pvalue)->dma_map_vo =
5508 			halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
5509 		((struct halmac_rqpn_map *)pvalue)->dma_map_vi =
5510 			halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
5511 		((struct halmac_rqpn_map *)pvalue)->dma_map_be =
5512 			halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
5513 		((struct halmac_rqpn_map *)pvalue)->dma_map_bk =
5514 			halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
5515 		((struct halmac_rqpn_map *)pvalue)->dma_map_mg =
5516 			halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
5517 		((struct halmac_rqpn_map *)pvalue)->dma_map_hi =
5518 			halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
5519 		break;
5520 	case HALMAC_HW_EFUSE_SIZE:
5521 		*(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size;
5522 		break;
5523 	case HALMAC_HW_EEPROM_SIZE:
5524 		*(u32 *)pvalue = halmac_adapter->hw_config_info.eeprom_size;
5525 		break;
5526 	case HALMAC_HW_BT_BANK_EFUSE_SIZE:
5527 		*(u32 *)pvalue = halmac_adapter->hw_config_info.bt_efuse_size;
5528 		break;
5529 	case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
5530 	case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
5531 		*(u32 *)pvalue = 0;
5532 		break;
5533 	case HALMAC_HW_TXFIFO_SIZE:
5534 		*(u32 *)pvalue = halmac_adapter->hw_config_info.tx_fifo_size;
5535 		break;
5536 	case HALMAC_HW_RSVD_PG_BNDY:
5537 		*(u16 *)pvalue =
5538 			halmac_adapter->txff_allocation.rsvd_drv_pg_bndy;
5539 		break;
5540 	case HALMAC_HW_CAM_ENTRY_NUM:
5541 		*(u8 *)pvalue = halmac_adapter->hw_config_info.cam_entry_num;
5542 		break;
5543 	case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE: /*Remove later*/
5544 		status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
5545 							    HALMAC_EFUSE_R_DRV);
5546 		if (status != HALMAC_RET_SUCCESS)
5547 			return status;
5548 		*(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size -
5549 				 HALMAC_PROTECTED_EFUSE_SIZE_88XX -
5550 				 halmac_adapter->efuse_end;
5551 		break;
5552 	case HALMAC_HW_IC_VERSION:
5553 		*(u8 *)pvalue = halmac_adapter->chip_version;
5554 		break;
5555 	case HALMAC_HW_PAGE_SIZE:
5556 		*(u32 *)pvalue = halmac_adapter->hw_config_info.page_size;
5557 		break;
5558 	case HALMAC_HW_TX_AGG_ALIGN_SIZE:
5559 		*(u16 *)pvalue = halmac_adapter->hw_config_info.tx_align_size;
5560 		break;
5561 	case HALMAC_HW_RX_AGG_ALIGN_SIZE:
5562 		*(u8 *)pvalue = 8;
5563 		break;
5564 	case HALMAC_HW_DRV_INFO_SIZE:
5565 		*(u8 *)pvalue = halmac_adapter->drv_info_size;
5566 		break;
5567 	case HALMAC_HW_TXFF_ALLOCATION:
5568 		memcpy(pvalue, &halmac_adapter->txff_allocation,
5569 		       sizeof(struct halmac_txff_allocation));
5570 		break;
5571 	case HALMAC_HW_TX_DESC_SIZE:
5572 		*(u32 *)pvalue = halmac_adapter->hw_config_info.txdesc_size;
5573 		break;
5574 	case HALMAC_HW_RX_DESC_SIZE:
5575 		*(u32 *)pvalue = halmac_adapter->hw_config_info.rxdesc_size;
5576 		break;
5577 	default:
5578 		return HALMAC_RET_PARA_NOT_SUPPORT;
5579 	}
5580 
5581 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5582 			"%s <==========\n", __func__);
5583 
5584 	return HALMAC_RET_SUCCESS;
5585 }
5586 
5587 /**
5588  * halmac_set_hw_value_88xx() -set hw config value
5589  * @halmac_adapter : the adapter of halmac
5590  * @hw_id : hw id for driver to config
5591  * @pvalue : hw value, reference table to get data type
5592  * Author : KaiYuan Chang / Ivan Lin
5593  * Return : enum halmac_ret_status
5594  * More details of status code can be found in prototype document
5595  */
5596 enum halmac_ret_status
halmac_set_hw_value_88xx(struct halmac_adapter * halmac_adapter,enum halmac_hw_id hw_id,void * pvalue)5597 halmac_set_hw_value_88xx(struct halmac_adapter *halmac_adapter,
5598 			 enum halmac_hw_id hw_id, void *pvalue)
5599 {
5600 	void *driver_adapter = NULL;
5601 	enum halmac_ret_status status;
5602 
5603 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5604 		return HALMAC_RET_ADAPTER_INVALID;
5605 
5606 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5607 		return HALMAC_RET_API_INVALID;
5608 
5609 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
5610 
5611 	driver_adapter = halmac_adapter->driver_adapter;
5612 
5613 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5614 			"%s ==========>\n", __func__);
5615 
5616 	if (!pvalue) {
5617 		pr_err("%s (!pvalue)==========>\n", __func__);
5618 		return HALMAC_RET_NULL_POINTER;
5619 	}
5620 
5621 	switch (hw_id) {
5622 	case HALMAC_HW_USB_MODE:
5623 		status = halmac_set_usb_mode_88xx(
5624 			halmac_adapter, *(enum halmac_usb_mode *)pvalue);
5625 		if (status != HALMAC_RET_SUCCESS)
5626 			return status;
5627 		break;
5628 	case HALMAC_HW_SEQ_EN:
5629 		break;
5630 	case HALMAC_HW_BANDWIDTH:
5631 		halmac_cfg_bw_88xx(halmac_adapter, *(enum halmac_bw *)pvalue);
5632 		break;
5633 	case HALMAC_HW_CHANNEL:
5634 		halmac_cfg_ch_88xx(halmac_adapter, *(u8 *)pvalue);
5635 		break;
5636 	case HALMAC_HW_PRI_CHANNEL_IDX:
5637 		halmac_cfg_pri_ch_idx_88xx(halmac_adapter,
5638 					   *(enum halmac_pri_ch_idx *)pvalue);
5639 		break;
5640 	case HALMAC_HW_EN_BB_RF:
5641 		halmac_enable_bb_rf_88xx(halmac_adapter, *(u8 *)pvalue);
5642 		break;
5643 	case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
5644 		halmac_config_sdio_tx_page_threshold_88xx(
5645 			halmac_adapter,
5646 			(struct halmac_tx_page_threshold_info *)pvalue);
5647 		break;
5648 	case HALMAC_HW_AMPDU_CONFIG:
5649 		halmac_config_ampdu_88xx(halmac_adapter,
5650 					 (struct halmac_ampdu_config *)pvalue);
5651 		break;
5652 	default:
5653 		return HALMAC_RET_PARA_NOT_SUPPORT;
5654 	}
5655 
5656 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5657 			"%s <==========\n", __func__);
5658 
5659 	return HALMAC_RET_SUCCESS;
5660 }
5661 
5662 /**
5663  * halmac_cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
5664  * @halmac_adapter : the adapter of halmac
5665  * @pg_num : page number
5666  * Author : KaiYuan Chang
5667  * Return : enum halmac_ret_status
5668  * More details of status code can be found in prototype document
5669  */
5670 enum halmac_ret_status
halmac_cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter * halmac_adapter,enum halmac_drv_rsvd_pg_num pg_num)5671 halmac_cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *halmac_adapter,
5672 				enum halmac_drv_rsvd_pg_num pg_num)
5673 {
5674 	void *driver_adapter = NULL;
5675 
5676 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5677 		return HALMAC_RET_ADAPTER_INVALID;
5678 
5679 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5680 		return HALMAC_RET_API_INVALID;
5681 
5682 	halmac_api_record_id_88xx(halmac_adapter,
5683 				  HALMAC_API_CFG_DRV_RSVD_PG_NUM);
5684 
5685 	driver_adapter = halmac_adapter->driver_adapter;
5686 
5687 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5688 			"%s ==========>pg_num = %d\n", __func__,
5689 			pg_num);
5690 
5691 	switch (pg_num) {
5692 	case HALMAC_RSVD_PG_NUM16:
5693 		halmac_adapter->txff_allocation.rsvd_drv_pg_num = 16;
5694 		break;
5695 	case HALMAC_RSVD_PG_NUM24:
5696 		halmac_adapter->txff_allocation.rsvd_drv_pg_num = 24;
5697 		break;
5698 	case HALMAC_RSVD_PG_NUM32:
5699 		halmac_adapter->txff_allocation.rsvd_drv_pg_num = 32;
5700 		break;
5701 	}
5702 
5703 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5704 			"%s <==========\n", __func__);
5705 
5706 	return HALMAC_RET_SUCCESS;
5707 }
5708 
5709 enum halmac_ret_status
halmac_get_chip_version_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ver * version)5710 halmac_get_chip_version_88xx(struct halmac_adapter *halmac_adapter,
5711 			     struct halmac_ver *version)
5712 {
5713 	void *driver_adapter = NULL;
5714 	struct halmac_api *halmac_api;
5715 
5716 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5717 		return HALMAC_RET_ADAPTER_INVALID;
5718 
5719 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5720 		return HALMAC_RET_API_INVALID;
5721 
5722 	driver_adapter = halmac_adapter->driver_adapter;
5723 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5724 
5725 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5726 			"%s ==========>\n", __func__);
5727 	version->major_ver = (u8)HALMAC_MAJOR_VER_88XX;
5728 	version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER_88XX;
5729 	version->minor_ver = (u8)HALMAC_MINOR_VER_88XX;
5730 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5731 			"%s <==========\n", __func__);
5732 
5733 	return HALMAC_RET_SUCCESS;
5734 }
5735 
5736 /**
5737  * halmac_chk_txdesc_88xx() -check if the tx packet format is incorrect
5738  * @halmac_adapter : the adapter of halmac
5739  * @halmac_buf : tx Packet buffer, tx desc is included
5740  * @halmac_size : tx packet size
5741  * Author : KaiYuan Chang
5742  * Return : enum halmac_ret_status
5743  * More details of status code can be found in prototype document
5744  */
5745 enum halmac_ret_status
halmac_chk_txdesc_88xx(struct halmac_adapter * halmac_adapter,u8 * halmac_buf,u32 halmac_size)5746 halmac_chk_txdesc_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
5747 		       u32 halmac_size)
5748 {
5749 	void *driver_adapter = NULL;
5750 	struct halmac_api *halmac_api;
5751 
5752 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5753 		return HALMAC_RET_ADAPTER_INVALID;
5754 
5755 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5756 		return HALMAC_RET_API_INVALID;
5757 
5758 	driver_adapter = halmac_adapter->driver_adapter;
5759 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5760 
5761 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5762 			"%s ==========>\n", __func__);
5763 
5764 	if (GET_TX_DESC_BMC(halmac_buf))
5765 		if (GET_TX_DESC_AGG_EN(halmac_buf))
5766 			pr_err("TxDesc: Agg should not be set when BMC\n");
5767 
5768 	if (halmac_size < (GET_TX_DESC_TXPKTSIZE(halmac_buf) +
5769 			   GET_TX_DESC_OFFSET(halmac_buf)))
5770 		pr_err("TxDesc: PktSize too small\n");
5771 
5772 	return HALMAC_RET_SUCCESS;
5773 }
5774 
5775 /**
5776  * halmac_dl_drv_rsvd_page_88xx() - download packet to rsvd page
5777  * @halmac_adapter : the adapter of halmac
5778  * @pg_offset : page offset of driver's rsvd page
5779  * @halmac_buf : data to be downloaded, tx_desc is not included
5780  * @halmac_size : data size to be downloaded
5781  * Author : KaiYuan Chang
5782  * Return : enum halmac_ret_status
5783  * More details of status code can be found in prototype document
5784  */
5785 enum halmac_ret_status
halmac_dl_drv_rsvd_page_88xx(struct halmac_adapter * halmac_adapter,u8 pg_offset,u8 * halmac_buf,u32 halmac_size)5786 halmac_dl_drv_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
5787 			     u8 pg_offset, u8 *halmac_buf, u32 halmac_size)
5788 {
5789 	void *driver_adapter = NULL;
5790 	struct halmac_api *halmac_api;
5791 	enum halmac_ret_status ret_status;
5792 	u16 drv_pg_bndy = 0;
5793 	u32 dl_pg_num = 0;
5794 
5795 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5796 		return HALMAC_RET_ADAPTER_INVALID;
5797 
5798 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5799 		return HALMAC_RET_API_INVALID;
5800 
5801 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DL_DRV_RSVD_PG);
5802 
5803 	driver_adapter = halmac_adapter->driver_adapter;
5804 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5805 
5806 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5807 			"%s ==========>\n", __func__);
5808 
5809 	/*check boundary and size valid*/
5810 	dl_pg_num = halmac_size / halmac_adapter->hw_config_info.page_size +
5811 		    ((halmac_size &
5812 		      (halmac_adapter->hw_config_info.page_size - 1)) ?
5813 			     1 :
5814 			     0);
5815 	if (pg_offset + dl_pg_num >
5816 	    halmac_adapter->txff_allocation.rsvd_drv_pg_num) {
5817 		pr_err("[ERROR] driver download offset or size error ==========>\n");
5818 		return HALMAC_RET_DRV_DL_ERR;
5819 	}
5820 
5821 	/*update to target download boundary*/
5822 	drv_pg_bndy =
5823 		halmac_adapter->txff_allocation.rsvd_drv_pg_bndy + pg_offset;
5824 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
5825 			    (u16)(drv_pg_bndy & BIT_MASK_BCN_HEAD_1_V1));
5826 
5827 	ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, halmac_buf,
5828 						    halmac_size);
5829 
5830 	/*restore to original bundary*/
5831 	if (ret_status != HALMAC_RET_SUCCESS) {
5832 		pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
5833 		       ret_status);
5834 		HALMAC_REG_WRITE_16(
5835 			halmac_adapter, REG_FIFOPAGE_CTRL_2,
5836 			(u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
5837 			      BIT_MASK_BCN_HEAD_1_V1));
5838 		return ret_status;
5839 	}
5840 
5841 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
5842 			    (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
5843 				  BIT_MASK_BCN_HEAD_1_V1));
5844 
5845 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5846 			"%s < ==========\n", __func__);
5847 	return HALMAC_RET_SUCCESS;
5848 }
5849 
5850 /**
5851  * halmac_cfg_csi_rate_88xx() - config CSI frame Tx rate
5852  * @halmac_adapter : the adapter of halmac
5853  * @rssi : rssi in decimal value
5854  * @current_rate : current CSI frame rate
5855  * @fixrate_en : enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate
5856  * @new_rate : API returns the final CSI frame rate
5857  * Author : chunchu
5858  * Return : enum halmac_ret_status
5859  * More details of status code can be found in prototype document
5860  */
5861 enum halmac_ret_status
halmac_cfg_csi_rate_88xx(struct halmac_adapter * halmac_adapter,u8 rssi,u8 current_rate,u8 fixrate_en,u8 * new_rate)5862 halmac_cfg_csi_rate_88xx(struct halmac_adapter *halmac_adapter, u8 rssi,
5863 			 u8 current_rate, u8 fixrate_en, u8 *new_rate)
5864 {
5865 	void *driver_adapter = NULL;
5866 	struct halmac_api *halmac_api;
5867 	u32 temp_csi_setting;
5868 	u16 current_rrsr;
5869 	enum halmac_ret_status ret_status;
5870 
5871 	if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5872 		return HALMAC_RET_ADAPTER_INVALID;
5873 
5874 	if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5875 		return HALMAC_RET_API_INVALID;
5876 
5877 	halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CSI_RATE);
5878 
5879 	driver_adapter = halmac_adapter->driver_adapter;
5880 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5881 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
5882 			"<%s ==========>\n", __func__);
5883 
5884 	temp_csi_setting = HALMAC_REG_READ_32(halmac_adapter, REG_BBPSF_CTRL) &
5885 			   ~(BIT_MASK_WMAC_CSI_RATE << BIT_SHIFT_WMAC_CSI_RATE);
5886 
5887 	current_rrsr = HALMAC_REG_READ_16(halmac_adapter, REG_RRSR);
5888 
5889 	if (rssi >= 40) {
5890 		if (current_rate != HALMAC_OFDM54) {
5891 			HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
5892 					    current_rrsr | BIT(HALMAC_OFDM54));
5893 			HALMAC_REG_WRITE_32(
5894 				halmac_adapter, REG_BBPSF_CTRL,
5895 				temp_csi_setting |
5896 					BIT_WMAC_CSI_RATE(HALMAC_OFDM54));
5897 		}
5898 		*new_rate = HALMAC_OFDM54;
5899 		ret_status = HALMAC_RET_SUCCESS;
5900 	} else {
5901 		if (current_rate != HALMAC_OFDM24) {
5902 			HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
5903 					    current_rrsr &
5904 						    ~(BIT(HALMAC_OFDM54)));
5905 			HALMAC_REG_WRITE_32(
5906 				halmac_adapter, REG_BBPSF_CTRL,
5907 				temp_csi_setting |
5908 					BIT_WMAC_CSI_RATE(HALMAC_OFDM24));
5909 		}
5910 		*new_rate = HALMAC_OFDM24;
5911 		ret_status = HALMAC_RET_SUCCESS;
5912 	}
5913 
5914 	return ret_status;
5915 }
5916 
5917 /**
5918  * halmac_sdio_cmd53_4byte_88xx() - cmd53 only for 4byte len register IO
5919  * @halmac_adapter : the adapter of halmac
5920  * @enable : 1->CMD53 only use in 4byte reg, 0 : No limitation
5921  * Author : Ivan Lin/KaiYuan Chang
5922  * Return : enum halmac_ret_status
5923  * More details of status code can be found in prototype document
5924  */
5925 enum halmac_ret_status
halmac_sdio_cmd53_4byte_88xx(struct halmac_adapter * halmac_adapter,enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode)5926 halmac_sdio_cmd53_4byte_88xx(struct halmac_adapter *halmac_adapter,
5927 			     enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode)
5928 {
5929 	halmac_adapter->sdio_cmd53_4byte = cmd53_4byte_mode;
5930 
5931 	return HALMAC_RET_SUCCESS;
5932 }
5933 
5934 /**
5935  * halmac_txfifo_is_empty_88xx() -check if txfifo is empty
5936  * @halmac_adapter : the adapter of halmac
5937  * Author : Ivan Lin
5938  * Return : enum halmac_ret_status
5939  * More details of status code can be found in prototype document
5940  */
5941 enum halmac_ret_status
halmac_txfifo_is_empty_88xx(struct halmac_adapter * halmac_adapter,u32 chk_num)5942 halmac_txfifo_is_empty_88xx(struct halmac_adapter *halmac_adapter, u32 chk_num)
5943 {
5944 	u32 counter;
5945 	void *driver_adapter = NULL;
5946 	struct halmac_api *halmac_api;
5947 
5948 	driver_adapter = halmac_adapter->driver_adapter;
5949 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5950 
5951 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5952 			"%s ==========>\n", __func__);
5953 
5954 	counter = (chk_num <= 10) ? 10 : chk_num;
5955 	do {
5956 		if (HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY) != 0xFF)
5957 			return HALMAC_RET_TXFIFO_NO_EMPTY;
5958 
5959 		if ((HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY + 1) &
5960 		     0x07) != 0x07)
5961 			return HALMAC_RET_TXFIFO_NO_EMPTY;
5962 		counter--;
5963 
5964 	} while (counter != 0);
5965 
5966 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5967 			"%s <==========\n", __func__);
5968 
5969 	return HALMAC_RET_SUCCESS;
5970 }
5971