1 /******************************************************************************
3 * Copyright(c) 2016 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
25 #include "halmac_88xx_cfg.h"
28 * halmac_init_adapter_para_88xx() - int halmac adapter
33 * Author : KaiYuan Chang/Ivan Lin
36 void halmac_init_adapter_para_88xx(struct halmac_adapter *halmac_adapter)
38 halmac_adapter->api_record.array_wptr = 0;
39 halmac_adapter->hal_adapter_backup = halmac_adapter;
40 halmac_adapter->hal_efuse_map = (u8 *)NULL;
41 halmac_adapter->hal_efuse_map_valid = false;
42 halmac_adapter->efuse_end = 0;
43 halmac_adapter->hal_mac_addr[0].address_l_h.address_low = 0;
44 halmac_adapter->hal_mac_addr[0].address_l_h.address_high = 0;
45 halmac_adapter->hal_mac_addr[1].address_l_h.address_low = 0;
46 halmac_adapter->hal_mac_addr[1].address_l_h.address_high = 0;
47 halmac_adapter->hal_bss_addr[0].address_l_h.address_low = 0;
48 halmac_adapter->hal_bss_addr[0].address_l_h.address_high = 0;
49 halmac_adapter->hal_bss_addr[1].address_l_h.address_low = 0;
50 halmac_adapter->hal_bss_addr[1].address_l_h.address_high = 0;
52 halmac_adapter->low_clk = false;
53 halmac_adapter->max_download_size = HALMAC_FW_MAX_DL_SIZE_88XX;
56 halmac_adapter->fwlps_option.mode = 0x01; /*0:Active 1:LPS 2:WMMPS*/
57 halmac_adapter->fwlps_option.awake_interval = 1;
58 halmac_adapter->fwlps_option.enter_32K = 1;
59 halmac_adapter->fwlps_option.clk_request = 0;
60 halmac_adapter->fwlps_option.rlbm = 0;
61 halmac_adapter->fwlps_option.smart_ps = 0;
62 halmac_adapter->fwlps_option.awake_interval = 1;
63 halmac_adapter->fwlps_option.all_queue_uapsd = 0;
64 halmac_adapter->fwlps_option.pwr_state = 0;
65 halmac_adapter->fwlps_option.low_pwr_rx_beacon = 0;
66 halmac_adapter->fwlps_option.ant_auto_switch = 0;
67 halmac_adapter->fwlps_option.ps_allow_bt_high_priority = 0;
68 halmac_adapter->fwlps_option.protect_bcn = 0;
69 halmac_adapter->fwlps_option.silence_period = 0;
70 halmac_adapter->fwlps_option.fast_bt_connect = 0;
71 halmac_adapter->fwlps_option.two_antenna_en = 0;
72 halmac_adapter->fwlps_option.adopt_user_setting = 1;
73 halmac_adapter->fwlps_option.drv_bcn_early_shift = 0;
75 halmac_adapter->config_para_info.cfg_para_buf = NULL;
76 halmac_adapter->config_para_info.para_buf_w = NULL;
77 halmac_adapter->config_para_info.para_num = 0;
78 halmac_adapter->config_para_info.full_fifo_mode = false;
79 halmac_adapter->config_para_info.para_buf_size = 0;
80 halmac_adapter->config_para_info.avai_para_buf_size = 0;
81 halmac_adapter->config_para_info.offset_accumulation = 0;
82 halmac_adapter->config_para_info.value_accumulation = 0;
83 halmac_adapter->config_para_info.datapack_segment = 0;
85 halmac_adapter->ch_sw_info.ch_info_buf = NULL;
86 halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
87 halmac_adapter->ch_sw_info.extra_info_en = 0;
88 halmac_adapter->ch_sw_info.buf_size = 0;
89 halmac_adapter->ch_sw_info.avai_buf_size = 0;
90 halmac_adapter->ch_sw_info.total_size = 0;
91 halmac_adapter->ch_sw_info.ch_num = 0;
93 halmac_adapter->drv_info_size = 0;
95 memset(halmac_adapter->api_record.api_array, HALMAC_API_STUFF,
96 sizeof(halmac_adapter->api_record.api_array));
98 halmac_adapter->txff_allocation.tx_fifo_pg_num = 0;
99 halmac_adapter->txff_allocation.ac_q_pg_num = 0;
100 halmac_adapter->txff_allocation.rsvd_pg_bndy = 0;
101 halmac_adapter->txff_allocation.rsvd_drv_pg_bndy = 0;
102 halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy = 0;
103 halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy = 0;
104 halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy = 0;
105 halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy = 0;
106 halmac_adapter->txff_allocation.pub_queue_pg_num = 0;
107 halmac_adapter->txff_allocation.high_queue_pg_num = 0;
108 halmac_adapter->txff_allocation.low_queue_pg_num = 0;
109 halmac_adapter->txff_allocation.normal_queue_pg_num = 0;
110 halmac_adapter->txff_allocation.extra_queue_pg_num = 0;
112 halmac_adapter->txff_allocation.la_mode = HALMAC_LA_MODE_DISABLE;
113 halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
114 HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
116 halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
117 halmac_init_state_machine_88xx(halmac_adapter);
121 * halmac_init_adapter_dynamic_para_88xx() - int halmac adapter
126 * Author : KaiYuan Chang/Ivan Lin
129 void halmac_init_adapter_dynamic_para_88xx(
130 struct halmac_adapter *halmac_adapter)
132 halmac_adapter->h2c_packet_seq = 0;
133 halmac_adapter->h2c_buf_free_space = 0;
134 halmac_adapter->gen_info_valid = false;
138 * halmac_init_state_machine_88xx() - init halmac software state machine
143 * Author : KaiYuan Chang/Ivan Lin
146 void halmac_init_state_machine_88xx(struct halmac_adapter *halmac_adapter)
148 struct halmac_state *state = &halmac_adapter->halmac_state;
150 halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
152 state->api_state = HALMAC_API_STATE_INIT;
154 state->dlfw_state = HALMAC_DLFW_NONE;
155 state->mac_power = HALMAC_MAC_POWER_OFF;
156 state->ps_state = HALMAC_PS_STATE_UNDEFINE;
160 * halmac_mount_api_88xx() - attach functions to function pointer
165 * Author : KaiYuan Chang/Ivan Lin
166 * Return : enum halmac_ret_status
168 enum halmac_ret_status
169 halmac_mount_api_88xx(struct halmac_adapter *halmac_adapter)
171 void *driver_adapter = halmac_adapter->driver_adapter;
172 struct halmac_api *halmac_api = (struct halmac_api *)NULL;
174 halmac_adapter->halmac_api =
175 kzalloc(sizeof(struct halmac_api), GFP_KERNEL);
176 if (!halmac_adapter->halmac_api)
177 return HALMAC_RET_MALLOC_FAIL;
178 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
180 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
181 HALMAC_SVN_VER_88XX "\n");
182 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
183 "HALMAC_MAJOR_VER_88XX = %x\n", HALMAC_MAJOR_VER_88XX);
184 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
185 "HALMAC_PROTOTYPE_88XX = %x\n",
186 HALMAC_PROTOTYPE_VER_88XX);
187 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
188 "HALMAC_MINOR_VER_88XX = %x\n", HALMAC_MINOR_VER_88XX);
189 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
190 "HALMAC_PATCH_VER_88XX = %x\n", HALMAC_PATCH_VER_88XX);
192 /* Mount function pointer */
193 halmac_api->halmac_download_firmware = halmac_download_firmware_88xx;
194 halmac_api->halmac_free_download_firmware =
195 halmac_free_download_firmware_88xx;
196 halmac_api->halmac_get_fw_version = halmac_get_fw_version_88xx;
197 halmac_api->halmac_cfg_mac_addr = halmac_cfg_mac_addr_88xx;
198 halmac_api->halmac_cfg_bssid = halmac_cfg_bssid_88xx;
199 halmac_api->halmac_cfg_multicast_addr = halmac_cfg_multicast_addr_88xx;
200 halmac_api->halmac_pre_init_system_cfg =
201 halmac_pre_init_system_cfg_88xx;
202 halmac_api->halmac_init_system_cfg = halmac_init_system_cfg_88xx;
203 halmac_api->halmac_init_edca_cfg = halmac_init_edca_cfg_88xx;
204 halmac_api->halmac_cfg_operation_mode = halmac_cfg_operation_mode_88xx;
205 halmac_api->halmac_cfg_ch_bw = halmac_cfg_ch_bw_88xx;
206 halmac_api->halmac_cfg_bw = halmac_cfg_bw_88xx;
207 halmac_api->halmac_init_wmac_cfg = halmac_init_wmac_cfg_88xx;
208 halmac_api->halmac_init_mac_cfg = halmac_init_mac_cfg_88xx;
209 halmac_api->halmac_init_sdio_cfg = halmac_init_sdio_cfg_88xx;
210 halmac_api->halmac_init_usb_cfg = halmac_init_usb_cfg_88xx;
211 halmac_api->halmac_init_pcie_cfg = halmac_init_pcie_cfg_88xx;
212 halmac_api->halmac_deinit_sdio_cfg = halmac_deinit_sdio_cfg_88xx;
213 halmac_api->halmac_deinit_usb_cfg = halmac_deinit_usb_cfg_88xx;
214 halmac_api->halmac_deinit_pcie_cfg = halmac_deinit_pcie_cfg_88xx;
215 halmac_api->halmac_dump_efuse_map = halmac_dump_efuse_map_88xx;
216 halmac_api->halmac_dump_efuse_map_bt = halmac_dump_efuse_map_bt_88xx;
217 halmac_api->halmac_write_efuse_bt = halmac_write_efuse_bt_88xx;
218 halmac_api->halmac_dump_logical_efuse_map =
219 halmac_dump_logical_efuse_map_88xx;
220 halmac_api->halmac_pg_efuse_by_map = halmac_pg_efuse_by_map_88xx;
221 halmac_api->halmac_get_efuse_size = halmac_get_efuse_size_88xx;
222 halmac_api->halmac_get_efuse_available_size =
223 halmac_get_efuse_available_size_88xx;
224 halmac_api->halmac_get_c2h_info = halmac_get_c2h_info_88xx;
226 halmac_api->halmac_get_logical_efuse_size =
227 halmac_get_logical_efuse_size_88xx;
229 halmac_api->halmac_write_logical_efuse =
230 halmac_write_logical_efuse_88xx;
231 halmac_api->halmac_read_logical_efuse = halmac_read_logical_efuse_88xx;
233 halmac_api->halmac_cfg_fwlps_option = halmac_cfg_fwlps_option_88xx;
234 halmac_api->halmac_cfg_fwips_option = halmac_cfg_fwips_option_88xx;
235 halmac_api->halmac_enter_wowlan = halmac_enter_wowlan_88xx;
236 halmac_api->halmac_leave_wowlan = halmac_leave_wowlan_88xx;
237 halmac_api->halmac_enter_ps = halmac_enter_ps_88xx;
238 halmac_api->halmac_leave_ps = halmac_leave_ps_88xx;
239 halmac_api->halmac_h2c_lb = halmac_h2c_lb_88xx;
240 halmac_api->halmac_debug = halmac_debug_88xx;
241 halmac_api->halmac_cfg_parameter = halmac_cfg_parameter_88xx;
242 halmac_api->halmac_update_datapack = halmac_update_datapack_88xx;
243 halmac_api->halmac_run_datapack = halmac_run_datapack_88xx;
244 halmac_api->halmac_cfg_drv_info = halmac_cfg_drv_info_88xx;
245 halmac_api->halmac_send_bt_coex = halmac_send_bt_coex_88xx;
246 halmac_api->halmac_verify_platform_api =
247 halmac_verify_platform_api_88xx;
248 halmac_api->halmac_update_packet = halmac_update_packet_88xx;
249 halmac_api->halmac_bcn_ie_filter = halmac_bcn_ie_filter_88xx;
250 halmac_api->halmac_cfg_txbf = halmac_cfg_txbf_88xx;
251 halmac_api->halmac_cfg_mumimo = halmac_cfg_mumimo_88xx;
252 halmac_api->halmac_cfg_sounding = halmac_cfg_sounding_88xx;
253 halmac_api->halmac_del_sounding = halmac_del_sounding_88xx;
254 halmac_api->halmac_su_bfer_entry_init = halmac_su_bfer_entry_init_88xx;
255 halmac_api->halmac_su_bfee_entry_init = halmac_su_bfee_entry_init_88xx;
256 halmac_api->halmac_mu_bfer_entry_init = halmac_mu_bfer_entry_init_88xx;
257 halmac_api->halmac_mu_bfee_entry_init = halmac_mu_bfee_entry_init_88xx;
258 halmac_api->halmac_su_bfer_entry_del = halmac_su_bfer_entry_del_88xx;
259 halmac_api->halmac_su_bfee_entry_del = halmac_su_bfee_entry_del_88xx;
260 halmac_api->halmac_mu_bfer_entry_del = halmac_mu_bfer_entry_del_88xx;
261 halmac_api->halmac_mu_bfee_entry_del = halmac_mu_bfee_entry_del_88xx;
263 halmac_api->halmac_add_ch_info = halmac_add_ch_info_88xx;
264 halmac_api->halmac_add_extra_ch_info = halmac_add_extra_ch_info_88xx;
265 halmac_api->halmac_ctrl_ch_switch = halmac_ctrl_ch_switch_88xx;
266 halmac_api->halmac_p2pps = halmac_p2pps_88xx;
267 halmac_api->halmac_clear_ch_info = halmac_clear_ch_info_88xx;
268 halmac_api->halmac_send_general_info = halmac_send_general_info_88xx;
270 halmac_api->halmac_start_iqk = halmac_start_iqk_88xx;
271 halmac_api->halmac_ctrl_pwr_tracking = halmac_ctrl_pwr_tracking_88xx;
272 halmac_api->halmac_psd = halmac_psd_88xx;
273 halmac_api->halmac_cfg_la_mode = halmac_cfg_la_mode_88xx;
274 halmac_api->halmac_cfg_rx_fifo_expanding_mode =
275 halmac_cfg_rx_fifo_expanding_mode_88xx;
277 halmac_api->halmac_config_security = halmac_config_security_88xx;
278 halmac_api->halmac_get_used_cam_entry_num =
279 halmac_get_used_cam_entry_num_88xx;
280 halmac_api->halmac_read_cam_entry = halmac_read_cam_entry_88xx;
281 halmac_api->halmac_write_cam = halmac_write_cam_88xx;
282 halmac_api->halmac_clear_cam_entry = halmac_clear_cam_entry_88xx;
284 halmac_api->halmac_get_hw_value = halmac_get_hw_value_88xx;
285 halmac_api->halmac_set_hw_value = halmac_set_hw_value_88xx;
287 halmac_api->halmac_cfg_drv_rsvd_pg_num =
288 halmac_cfg_drv_rsvd_pg_num_88xx;
289 halmac_api->halmac_get_chip_version = halmac_get_chip_version_88xx;
291 halmac_api->halmac_query_status = halmac_query_status_88xx;
292 halmac_api->halmac_reset_feature = halmac_reset_feature_88xx;
293 halmac_api->halmac_check_fw_status = halmac_check_fw_status_88xx;
294 halmac_api->halmac_dump_fw_dmem = halmac_dump_fw_dmem_88xx;
295 halmac_api->halmac_cfg_max_dl_size = halmac_cfg_max_dl_size_88xx;
297 halmac_api->halmac_dump_fifo = halmac_dump_fifo_88xx;
298 halmac_api->halmac_get_fifo_size = halmac_get_fifo_size_88xx;
300 halmac_api->halmac_chk_txdesc = halmac_chk_txdesc_88xx;
301 halmac_api->halmac_dl_drv_rsvd_page = halmac_dl_drv_rsvd_page_88xx;
302 halmac_api->halmac_cfg_csi_rate = halmac_cfg_csi_rate_88xx;
304 halmac_api->halmac_sdio_cmd53_4byte = halmac_sdio_cmd53_4byte_88xx;
305 halmac_api->halmac_txfifo_is_empty = halmac_txfifo_is_empty_88xx;
307 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
308 halmac_api->halmac_cfg_rx_aggregation =
309 halmac_cfg_rx_aggregation_88xx_sdio;
310 halmac_api->halmac_init_interface_cfg =
311 halmac_init_sdio_cfg_88xx;
312 halmac_api->halmac_deinit_interface_cfg =
313 halmac_deinit_sdio_cfg_88xx;
314 halmac_api->halmac_reg_read_8 = halmac_reg_read_8_sdio_88xx;
315 halmac_api->halmac_reg_write_8 = halmac_reg_write_8_sdio_88xx;
316 halmac_api->halmac_reg_read_16 = halmac_reg_read_16_sdio_88xx;
317 halmac_api->halmac_reg_write_16 = halmac_reg_write_16_sdio_88xx;
318 halmac_api->halmac_reg_read_32 = halmac_reg_read_32_sdio_88xx;
319 halmac_api->halmac_reg_write_32 = halmac_reg_write_32_sdio_88xx;
320 halmac_api->halmac_reg_read_indirect_32 =
321 halmac_reg_read_indirect_32_sdio_88xx;
322 halmac_api->halmac_reg_sdio_cmd53_read_n =
323 halmac_reg_read_nbyte_sdio_88xx;
324 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
325 halmac_api->halmac_cfg_rx_aggregation =
326 halmac_cfg_rx_aggregation_88xx_usb;
327 halmac_api->halmac_init_interface_cfg =
328 halmac_init_usb_cfg_88xx;
329 halmac_api->halmac_deinit_interface_cfg =
330 halmac_deinit_usb_cfg_88xx;
331 halmac_api->halmac_reg_read_8 = halmac_reg_read_8_usb_88xx;
332 halmac_api->halmac_reg_write_8 = halmac_reg_write_8_usb_88xx;
333 halmac_api->halmac_reg_read_16 = halmac_reg_read_16_usb_88xx;
334 halmac_api->halmac_reg_write_16 = halmac_reg_write_16_usb_88xx;
335 halmac_api->halmac_reg_read_32 = halmac_reg_read_32_usb_88xx;
336 halmac_api->halmac_reg_write_32 = halmac_reg_write_32_usb_88xx;
337 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
338 halmac_api->halmac_cfg_rx_aggregation =
339 halmac_cfg_rx_aggregation_88xx_pcie;
340 halmac_api->halmac_init_interface_cfg =
341 halmac_init_pcie_cfg_88xx;
342 halmac_api->halmac_deinit_interface_cfg =
343 halmac_deinit_pcie_cfg_88xx;
344 halmac_api->halmac_reg_read_8 = halmac_reg_read_8_pcie_88xx;
345 halmac_api->halmac_reg_write_8 = halmac_reg_write_8_pcie_88xx;
346 halmac_api->halmac_reg_read_16 = halmac_reg_read_16_pcie_88xx;
347 halmac_api->halmac_reg_write_16 = halmac_reg_write_16_pcie_88xx;
348 halmac_api->halmac_reg_read_32 = halmac_reg_read_32_pcie_88xx;
349 halmac_api->halmac_reg_write_32 = halmac_reg_write_32_pcie_88xx;
351 pr_err("Set halmac io function Error!!\n");
354 halmac_api->halmac_set_bulkout_num = halmac_set_bulkout_num_88xx;
355 halmac_api->halmac_get_sdio_tx_addr = halmac_get_sdio_tx_addr_88xx;
356 halmac_api->halmac_get_usb_bulkout_id = halmac_get_usb_bulkout_id_88xx;
357 halmac_api->halmac_timer_2s = halmac_timer_2s_88xx;
358 halmac_api->halmac_fill_txdesc_checksum =
359 halmac_fill_txdesc_check_sum_88xx;
361 if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B) {
362 /*mount 8822b function and data*/
363 halmac_mount_api_8822b(halmac_adapter);
365 } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8821C) {
366 } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8814B) {
367 } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8197F) {
369 pr_err("Chip ID undefine!!\n");
370 return HALMAC_RET_CHIP_NOT_SUPPORT;
372 return HALMAC_RET_SUCCESS;
376 * halmac_download_firmware_88xx() - download Firmware
377 * @halmac_adapter : the adapter of halmac
378 * @hamacl_fw : firmware bin
379 * @halmac_fw_size : firmware size
380 * Author : KaiYuan Chang/Ivan Lin
381 * Return : enum halmac_ret_status
382 * More details of status code can be found in prototype document
384 enum halmac_ret_status
385 halmac_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
386 u8 *hamacl_fw, u32 halmac_fw_size)
392 u32 restore_index = 0;
393 u32 halmac_h2c_ver = 0, fw_h2c_ver = 0;
394 u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
395 void *driver_adapter = NULL;
396 struct halmac_api *halmac_api;
397 struct halmac_restore_info restore_info[DLFW_RESTORE_REG_NUM_88XX];
400 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
401 return HALMAC_RET_ADAPTER_INVALID;
403 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
404 return HALMAC_RET_API_INVALID;
406 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DOWNLOAD_FIRMWARE);
408 driver_adapter = halmac_adapter->driver_adapter;
409 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
411 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
412 "%s ==========>\n", __func__);
413 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
414 "%s start!!\n", __func__);
416 if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
417 halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
418 pr_err("FW size error!\n");
419 return HALMAC_RET_FW_SIZE_ERR;
422 fw_h2c_ver = le32_to_cpu(
424 (hamacl_fw + HALMAC_FWHDR_OFFSET_H2C_FORMAT_VER_88XX)));
425 halmac_h2c_ver = H2C_FORMAT_VERSION;
427 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
428 "halmac h2c/c2h format = %x, fw h2c/c2h format = %x!!\n",
429 halmac_h2c_ver, fw_h2c_ver);
430 if (fw_h2c_ver != halmac_h2c_ver)
432 driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
433 "[WARN]H2C/C2H version between HALMAC and FW is compatible!!\n");
435 halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
437 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
438 value8 = (u8)(value8 & ~(BIT(2)));
439 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
440 value8); /* Disable CPU reset */
442 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
443 value8 = (u8)(value8 & ~(BIT(0)));
444 HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
446 restore_info[restore_index].length = 1;
447 restore_info[restore_index].mac_register = REG_TXDMA_PQ_MAP + 1;
448 restore_info[restore_index].value =
449 HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1);
451 value8 = HALMAC_DMA_MAPPING_HIGH << 6;
452 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1,
453 value8); /* set HIQ to hi priority */
455 /* DLFW only use HIQ, map HIQ to hi priority */
456 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
457 HALMAC_DMA_MAPPING_HIGH;
458 restore_info[restore_index].length = 1;
459 restore_info[restore_index].mac_register = REG_CR;
460 restore_info[restore_index].value =
461 HALMAC_REG_READ_8(halmac_adapter, REG_CR);
463 restore_info[restore_index].length = 4;
464 restore_info[restore_index].mac_register = REG_H2CQ_CSR;
465 restore_info[restore_index].value = BIT(31);
467 value8 = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN;
468 HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
469 HALMAC_REG_WRITE_32(halmac_adapter, REG_H2CQ_CSR, BIT(31));
471 /* Config hi priority queue and public priority queue page number
474 restore_info[restore_index].length = 2;
475 restore_info[restore_index].mac_register = REG_FIFOPAGE_INFO_1;
476 restore_info[restore_index].value =
477 HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_INFO_1);
479 restore_info[restore_index].length = 4;
480 restore_info[restore_index].mac_register = REG_RQPN_CTRL_2;
481 restore_info[restore_index].value =
482 HALMAC_REG_READ_32(halmac_adapter, REG_RQPN_CTRL_2) | BIT(31);
484 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_1, 0x200);
485 HALMAC_REG_WRITE_32(halmac_adapter, REG_RQPN_CTRL_2,
486 restore_info[restore_index - 1].value);
488 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
489 HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
490 HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL,
494 halmac_adapter->fw_version.version = le16_to_cpu(
495 *((__le16 *)(hamacl_fw + HALMAC_FWHDR_OFFSET_VERSION_88XX)));
496 halmac_adapter->fw_version.sub_version =
497 *(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBVERSION_88XX);
498 halmac_adapter->fw_version.sub_index =
499 *(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBINDEX_88XX);
500 halmac_adapter->fw_version.h2c_version = (u16)fw_h2c_ver;
502 dmem_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
503 HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX)));
504 iram_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
505 HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX)));
506 if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
508 le32_to_cpu(*((__le32 *)(hamacl_fw +
509 HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX)));
511 dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
512 iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
513 if (eram_pkt_size != 0)
514 eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
516 if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
517 iram_pkt_size + eram_pkt_size)) {
518 pr_err("FW size mismatch the real fw size!\n");
522 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
523 restore_info[restore_index].length = 1;
524 restore_info[restore_index].mac_register = REG_CR + 1;
525 restore_info[restore_index].value = value8;
527 value8 = (u8)(value8 | BIT(0));
528 HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1,
529 value8); /* Enable SW TX beacon */
531 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
532 restore_info[restore_index].length = 1;
533 restore_info[restore_index].mac_register = REG_BCN_CTRL;
534 restore_info[restore_index].value = value8;
536 value8 = (u8)((value8 & (~BIT(3))) | BIT(4));
537 HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL,
538 value8); /* Disable beacon related functions */
540 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
541 restore_info[restore_index].length = 1;
542 restore_info[restore_index].mac_register = REG_FWHW_TXQ_CTRL + 2;
543 restore_info[restore_index].value = value8;
545 value8 = (u8)(value8 & ~(BIT(6)));
546 HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2,
547 value8); /* Disable ptcl tx bcnq */
549 restore_info[restore_index].length = 2;
550 restore_info[restore_index].mac_register = REG_FIFOPAGE_CTRL_2;
551 restore_info[restore_index].value =
552 HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
556 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
557 value16); /* Set beacon header to 0 */
559 value16 = (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) &
562 HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
563 value16); /* MCU/FW setting */
565 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CPU_DMEM_CON + 2);
567 HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
569 HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
571 /* Download to DMEM */
572 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX;
573 temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
574 HALMAC_FWHDR_OFFSET_DMEM_ADDR_88XX))) &
576 if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
577 dmem_pkt_size) != HALMAC_RET_SUCCESS)
580 /* Download to IMEM */
581 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size;
582 temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
583 HALMAC_FWHDR_OFFSET_IRAM_ADDR_88XX))) &
585 if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
586 iram_pkt_size) != HALMAC_RET_SUCCESS)
589 /* Download to EMEM */
590 if (eram_pkt_size != 0) {
591 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
593 dest = le32_to_cpu((*((__le32 *)(hamacl_fw +
594 HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX)))) &
596 if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
602 halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
605 halmac_restore_mac_register_88xx(halmac_adapter, restore_info,
606 DLFW_RESTORE_REG_NUM_88XX);
608 if (halmac_dlfw_end_flow_88xx(halmac_adapter) != HALMAC_RET_SUCCESS)
611 halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_DONE;
613 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
614 "%s <==========\n", __func__);
616 return HALMAC_RET_SUCCESS;
620 /* Disable FWDL_EN */
622 halmac_adapter, REG_MCUFW_CTRL,
623 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
626 return HALMAC_RET_DLFW_FAIL;
630 * halmac_free_download_firmware_88xx() - download specific memory firmware
632 * @dlfw_mem : memory selection
633 * @hamacl_fw : firmware bin
634 * @halmac_fw_size : firmware size
635 * Author : KaiYuan Chang/Ivan Lin
636 * Return : enum halmac_ret_status
638 enum halmac_ret_status
639 halmac_free_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
640 enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
647 u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
648 void *driver_adapter = NULL;
649 enum halmac_ret_status status = HALMAC_RET_DLFW_FAIL;
650 struct halmac_api *halmac_api;
652 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
653 return HALMAC_RET_ADAPTER_INVALID;
655 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
656 return HALMAC_RET_API_INVALID;
658 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
659 return HALMAC_RET_NO_DLFW;
661 driver_adapter = halmac_adapter->driver_adapter;
662 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
664 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
665 "[TRACE]%s ==========>\n", __func__);
667 if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
668 halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
669 pr_err("[ERR]FW size error!\n");
670 return HALMAC_RET_FW_SIZE_ERR;
674 le32_to_cpu(*(__le32 *)(hamacl_fw +
675 HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX));
677 le32_to_cpu(*(__le32 *)(hamacl_fw +
678 HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX));
679 if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
681 le32_to_cpu(*(__le32 *)(hamacl_fw +
682 HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX));
684 dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
685 iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
686 if (eram_pkt_size != 0)
687 eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
689 if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
690 iram_pkt_size + eram_pkt_size)) {
691 pr_err("[ERR]FW size mismatch the real fw size!\n");
692 return HALMAC_RET_DLFW_FAIL;
695 tx_pause_backup = HALMAC_REG_READ_8(halmac_adapter, REG_TXPAUSE);
696 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE,
697 tx_pause_backup | BIT(7));
700 HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
702 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0x8000);
704 if (eram_pkt_size != 0) {
705 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
707 dest = le32_to_cpu(*((__le32 *)(hamacl_fw +
708 HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX))) &
710 status = halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
712 if (status != HALMAC_RET_SUCCESS)
716 status = halmac_free_dl_fw_end_flow_88xx(halmac_adapter);
719 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE, tx_pause_backup);
720 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
723 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
724 "[TRACE]%s <==========\n", __func__);
730 * halmac_get_fw_version_88xx() - get FW version
731 * @halmac_adapter : the adapter of halmac
732 * @fw_version : fw version info
734 * Return : enum halmac_ret_status
735 * More details of status code can be found in prototype document
737 enum halmac_ret_status
738 halmac_get_fw_version_88xx(struct halmac_adapter *halmac_adapter,
739 struct halmac_fw_version *fw_version)
741 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
742 return HALMAC_RET_ADAPTER_INVALID;
744 if (halmac_adapter->halmac_state.dlfw_state == 0)
745 return HALMAC_RET_DLFW_FAIL;
747 fw_version->version = halmac_adapter->fw_version.version;
748 fw_version->sub_version = halmac_adapter->fw_version.sub_version;
749 fw_version->sub_index = halmac_adapter->fw_version.sub_index;
751 return HALMAC_RET_SUCCESS;
755 * halmac_cfg_mac_addr_88xx() - config mac address
756 * @halmac_adapter : the adapter of halmac
757 * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
758 * @hal_address : mac address
759 * Author : KaiYuan Chang/Ivan Lin
760 * Return : enum halmac_ret_status
761 * More details of status code can be found in prototype document
763 enum halmac_ret_status
764 halmac_cfg_mac_addr_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
765 union halmac_wlan_addr *hal_address)
769 void *driver_adapter = NULL;
770 struct halmac_api *halmac_api;
772 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
773 return HALMAC_RET_ADAPTER_INVALID;
775 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
776 return HALMAC_RET_API_INVALID;
778 driver_adapter = halmac_adapter->driver_adapter;
779 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
781 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
782 "[TRACE]%s ==========>\n", __func__);
784 if (halmac_port >= HALMAC_PORTIDMAX) {
785 pr_err("[ERR]port index > 5\n");
786 return HALMAC_RET_PORT_NOT_SUPPORT;
789 mac_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
790 mac_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
792 halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_low =
794 halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_high =
797 switch (halmac_port) {
799 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID, mac_address_L);
800 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID + 4,
805 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID1, mac_address_L);
806 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID1 + 4,
811 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID2, mac_address_L);
812 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID2 + 4,
817 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID3, mac_address_L);
818 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID3 + 4,
823 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID4, mac_address_L);
824 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID4 + 4,
833 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
834 "[TRACE]%s <==========\n", __func__);
836 return HALMAC_RET_SUCCESS;
840 * halmac_cfg_bssid_88xx() - config BSSID
841 * @halmac_adapter : the adapter of halmac
842 * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
843 * @hal_address : bssid
844 * Author : KaiYuan Chang/Ivan Lin
845 * Return : enum halmac_ret_status
846 * More details of status code can be found in prototype document
848 enum halmac_ret_status
849 halmac_cfg_bssid_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
850 union halmac_wlan_addr *hal_address)
854 void *driver_adapter = NULL;
855 struct halmac_api *halmac_api;
857 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
858 return HALMAC_RET_ADAPTER_INVALID;
860 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
861 return HALMAC_RET_API_INVALID;
863 driver_adapter = halmac_adapter->driver_adapter;
864 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
866 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
867 "[TRACE]%s ==========>\n", __func__);
869 if (halmac_port >= HALMAC_PORTIDMAX) {
870 pr_err("[ERR]port index > 5\n");
871 return HALMAC_RET_PORT_NOT_SUPPORT;
874 bssid_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
875 bssid_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
877 halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_low =
879 halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_high =
882 switch (halmac_port) {
884 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID, bssid_address_L);
885 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID + 4,
890 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID1,
892 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID1 + 4,
897 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID2,
899 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID2 + 4,
904 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID3,
906 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID3 + 4,
911 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID4,
913 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID4 + 4,
922 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
923 "[TRACE]%s <==========\n", __func__);
925 return HALMAC_RET_SUCCESS;
929 * halmac_cfg_multicast_addr_88xx() - config multicast address
930 * @halmac_adapter : the adapter of halmac
931 * @hal_address : multicast address
932 * Author : KaiYuan Chang/Ivan Lin
933 * Return : enum halmac_ret_status
934 * More details of status code can be found in prototype document
936 enum halmac_ret_status
937 halmac_cfg_multicast_addr_88xx(struct halmac_adapter *halmac_adapter,
938 union halmac_wlan_addr *hal_address)
942 void *driver_adapter = NULL;
943 struct halmac_api *halmac_api;
945 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
946 return HALMAC_RET_ADAPTER_INVALID;
948 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
949 return HALMAC_RET_API_INVALID;
951 halmac_api_record_id_88xx(halmac_adapter,
952 HALMAC_API_CFG_MULTICAST_ADDR);
954 driver_adapter = halmac_adapter->driver_adapter;
955 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
957 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
958 "%s ==========>\n", __func__);
960 address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
961 address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
963 HALMAC_REG_WRITE_32(halmac_adapter, REG_MAR, address_L);
964 HALMAC_REG_WRITE_16(halmac_adapter, REG_MAR + 4, address_H);
966 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
967 "%s <==========\n", __func__);
969 return HALMAC_RET_SUCCESS;
973 * halmac_pre_init_system_cfg_88xx() - pre-init system config
974 * @halmac_adapter : the adapter of halmac
975 * Author : KaiYuan Chang/Ivan Lin
976 * Return : enum halmac_ret_status
977 * More details of status code can be found in prototype document
979 enum halmac_ret_status
980 halmac_pre_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
982 u32 value32, counter;
983 void *driver_adapter = NULL;
984 struct halmac_api *halmac_api;
987 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
988 return HALMAC_RET_ADAPTER_INVALID;
990 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
991 return HALMAC_RET_API_INVALID;
993 halmac_api_record_id_88xx(halmac_adapter,
994 HALMAC_API_PRE_INIT_SYSTEM_CFG);
996 driver_adapter = halmac_adapter->driver_adapter;
997 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
999 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1000 "halmac_pre_init_system_cfg ==========>\n");
1002 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
1004 halmac_adapter, REG_SDIO_HSUS_CTRL,
1005 HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
1008 while (!(HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
1012 return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
1014 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
1015 if (HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) ==
1018 halmac_adapter, 0xFE5B,
1019 HALMAC_REG_READ_8(halmac_adapter, 0xFE5B) |
1023 /* Config PIN Mux */
1024 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL1);
1025 value32 = value32 & (~(BIT(28) | BIT(29)));
1026 value32 = value32 | BIT(28) | BIT(29);
1027 HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL1, value32);
1029 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_LED_CFG);
1030 value32 = value32 & (~(BIT(25) | BIT(26)));
1031 HALMAC_REG_WRITE_32(halmac_adapter, REG_LED_CFG, value32);
1033 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_GPIO_MUXCFG);
1034 value32 = value32 & (~(BIT(2)));
1035 value32 = value32 | BIT(2);
1036 HALMAC_REG_WRITE_32(halmac_adapter, REG_GPIO_MUXCFG, value32);
1039 halmac_set_hw_value_88xx(halmac_adapter, HALMAC_HW_EN_BB_RF,
1042 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1043 "halmac_pre_init_system_cfg <==========\n");
1045 return HALMAC_RET_SUCCESS;
1049 * halmac_init_system_cfg_88xx() - init system config
1050 * @halmac_adapter : the adapter of halmac
1051 * Author : KaiYuan Chang/Ivan Lin
1052 * Return : enum halmac_ret_status
1053 * More details of status code can be found in prototype document
1055 enum halmac_ret_status
1056 halmac_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
1058 void *driver_adapter = NULL;
1059 struct halmac_api *halmac_api;
1061 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1062 return HALMAC_RET_ADAPTER_INVALID;
1064 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1065 return HALMAC_RET_API_INVALID;
1067 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SYSTEM_CFG);
1069 driver_adapter = halmac_adapter->driver_adapter;
1070 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1072 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1073 "halmac_init_system_cfg ==========>\n");
1075 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
1076 HALMAC_FUNCTION_ENABLE_88XX);
1077 HALMAC_REG_WRITE_32(
1078 halmac_adapter, REG_SYS_SDIO_CTRL,
1079 (u32)(HALMAC_REG_READ_32(halmac_adapter, REG_SYS_SDIO_CTRL) |
1080 BIT_LTE_MUX_CTRL_PATH));
1081 HALMAC_REG_WRITE_32(
1082 halmac_adapter, REG_CPU_DMEM_CON,
1083 (u32)(HALMAC_REG_READ_32(halmac_adapter, REG_CPU_DMEM_CON) |
1084 BIT_WL_PLATFORM_RST));
1086 /* halmac_api->halmac_init_h2c(halmac_adapter); */
1088 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1089 "halmac_init_system_cfg <==========\n");
1091 return HALMAC_RET_SUCCESS;
1095 * halmac_init_edca_cfg_88xx() - init EDCA config
1096 * @halmac_adapter : the adapter of halmac
1097 * Author : KaiYuan Chang/Ivan Lin
1098 * Return : enum halmac_ret_status
1099 * More details of status code can be found in prototype document
1101 enum halmac_ret_status
1102 halmac_init_edca_cfg_88xx(struct halmac_adapter *halmac_adapter)
1106 void *driver_adapter = NULL;
1107 struct halmac_api *halmac_api;
1109 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1110 return HALMAC_RET_ADAPTER_INVALID;
1112 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1113 return HALMAC_RET_API_INVALID;
1115 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_EDCA_CFG);
1117 driver_adapter = halmac_adapter->driver_adapter;
1118 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1120 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1121 "%s ==========>\n", __func__);
1123 /* Clear TX pause */
1124 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXPAUSE, 0x0000);
1126 HALMAC_REG_WRITE_8(halmac_adapter, REG_SLOT, HALMAC_SLOT_TIME_88XX);
1127 HALMAC_REG_WRITE_8(halmac_adapter, REG_PIFS, HALMAC_PIFS_TIME_88XX);
1128 value32 = HALMAC_SIFS_CCK_CTX_88XX |
1129 (HALMAC_SIFS_OFDM_CTX_88XX << BIT_SHIFT_SIFS_OFDM_CTX) |
1130 (HALMAC_SIFS_CCK_TRX_88XX << BIT_SHIFT_SIFS_CCK_TRX) |
1131 (HALMAC_SIFS_OFDM_TRX_88XX << BIT_SHIFT_SIFS_OFDM_TRX);
1132 HALMAC_REG_WRITE_32(halmac_adapter, REG_SIFS, value32);
1134 HALMAC_REG_WRITE_32(
1135 halmac_adapter, REG_EDCA_VO_PARAM,
1136 HALMAC_REG_READ_32(halmac_adapter, REG_EDCA_VO_PARAM) & 0xFFFF);
1137 HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VO_PARAM + 2,
1138 HALMAC_VO_TXOP_LIMIT_88XX);
1139 HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VI_PARAM + 2,
1140 HALMAC_VI_TXOP_LIMIT_88XX);
1142 HALMAC_REG_WRITE_32(halmac_adapter, REG_RD_NAV_NXT,
1143 HALMAC_RDG_NAV_88XX | (HALMAC_TXOP_NAV_88XX << 16));
1144 HALMAC_REG_WRITE_16(halmac_adapter, REG_RXTSF_OFFSET_CCK,
1145 HALMAC_CCK_RX_TSF_88XX |
1146 (HALMAC_OFDM_RX_TSF_88XX) << 8);
1148 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RD_CTRL + 1);
1150 (BIT_VOQ_RD_INIT_EN | BIT_VIQ_RD_INIT_EN | BIT_BEQ_RD_INIT_EN);
1151 HALMAC_REG_WRITE_8(halmac_adapter, REG_RD_CTRL + 1, value8);
1153 /* Set beacon cotnrol - enable TSF and other related functions */
1155 halmac_adapter, REG_BCN_CTRL,
1156 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL) |
1157 BIT_EN_BCN_FUNCTION));
1159 /* Set send beacon related registers */
1160 HALMAC_REG_WRITE_32(halmac_adapter, REG_TBTT_PROHIBIT,
1161 HALMAC_TBTT_PROHIBIT_88XX |
1162 (HALMAC_TBTT_HOLD_TIME_88XX
1163 << BIT_SHIFT_TBTT_HOLD_TIME_AP));
1164 HALMAC_REG_WRITE_8(halmac_adapter, REG_DRVERLYINT,
1165 HALMAC_DRIVER_EARLY_INT_88XX);
1166 HALMAC_REG_WRITE_8(halmac_adapter, REG_BCNDMATIM,
1167 HALMAC_BEACON_DMA_TIM_88XX);
1169 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1170 "%s <==========\n", __func__);
1172 return HALMAC_RET_SUCCESS;
1176 * halmac_init_wmac_cfg_88xx() - init wmac config
1177 * @halmac_adapter : the adapter of halmac
1178 * Author : KaiYuan Chang/Ivan Lin
1179 * Return : enum halmac_ret_status
1180 * More details of status code can be found in prototype document
1182 enum halmac_ret_status
1183 halmac_init_wmac_cfg_88xx(struct halmac_adapter *halmac_adapter)
1185 void *driver_adapter = NULL;
1186 struct halmac_api *halmac_api;
1188 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1189 return HALMAC_RET_ADAPTER_INVALID;
1191 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1192 return HALMAC_RET_API_INVALID;
1194 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_WMAC_CFG);
1196 driver_adapter = halmac_adapter->driver_adapter;
1197 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1199 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1200 "%s ==========>\n", __func__);
1202 HALMAC_REG_WRITE_32(halmac_adapter, REG_RXFLTMAP0,
1203 HALMAC_RX_FILTER0_88XX);
1204 HALMAC_REG_WRITE_16(halmac_adapter, REG_RXFLTMAP,
1205 HALMAC_RX_FILTER_88XX);
1207 HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, HALMAC_RCR_CONFIG_88XX);
1210 halmac_adapter, REG_TCR + 1,
1211 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_TCR + 1) | 0x30));
1212 HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 2, 0x30);
1213 HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 1, 0x00);
1215 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 8,
1217 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
1220 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1221 "%s <==========\n", __func__);
1223 return HALMAC_RET_SUCCESS;
1227 * halmac_init_mac_cfg_88xx() - config page1~page7 register
1228 * @halmac_adapter : the adapter of halmac
1230 * Author : KaiYuan Chang/Ivan Lin
1231 * Return : enum halmac_ret_status
1232 * More details of status code can be found in prototype document
1234 enum halmac_ret_status
1235 halmac_init_mac_cfg_88xx(struct halmac_adapter *halmac_adapter,
1236 enum halmac_trx_mode mode)
1238 void *driver_adapter = NULL;
1239 struct halmac_api *halmac_api;
1240 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1242 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1243 return HALMAC_RET_ADAPTER_INVALID;
1245 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1246 return HALMAC_RET_API_INVALID;
1248 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_MAC_CFG);
1250 driver_adapter = halmac_adapter->driver_adapter;
1251 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1253 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1254 "%s ==========>mode = %d\n", __func__,
1257 status = halmac_api->halmac_init_trx_cfg(halmac_adapter, mode);
1258 if (status != HALMAC_RET_SUCCESS) {
1259 pr_err("halmac_init_trx_cfg error = %x\n", status);
1262 status = halmac_api->halmac_init_protocol_cfg(halmac_adapter);
1263 if (status != HALMAC_RET_SUCCESS) {
1264 pr_err("halmac_init_protocol_cfg_88xx error = %x\n", status);
1268 status = halmac_init_edca_cfg_88xx(halmac_adapter);
1269 if (status != HALMAC_RET_SUCCESS) {
1270 pr_err("halmac_init_edca_cfg_88xx error = %x\n", status);
1274 status = halmac_init_wmac_cfg_88xx(halmac_adapter);
1275 if (status != HALMAC_RET_SUCCESS) {
1276 pr_err("halmac_init_wmac_cfg_88xx error = %x\n", status);
1279 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1280 "%s <==========\n", __func__);
1286 * halmac_cfg_operation_mode_88xx() - config operation mode
1287 * @halmac_adapter : the adapter of halmac
1288 * @wireless_mode : 802.11 standard(b/g/n/ac)
1289 * Author : KaiYuan Chang/Ivan Lin
1290 * Return : enum halmac_ret_status
1291 * More details of status code can be found in prototype document
1293 enum halmac_ret_status
1294 halmac_cfg_operation_mode_88xx(struct halmac_adapter *halmac_adapter,
1295 enum halmac_wireless_mode wireless_mode)
1297 void *driver_adapter = NULL;
1298 enum halmac_wireless_mode wireless_mode_local =
1299 HALMAC_WIRELESS_MODE_UNDEFINE;
1301 wireless_mode_local = wireless_mode;
1303 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1304 return HALMAC_RET_ADAPTER_INVALID;
1306 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1307 return HALMAC_RET_API_INVALID;
1309 halmac_api_record_id_88xx(halmac_adapter,
1310 HALMAC_API_CFG_OPERATION_MODE);
1312 driver_adapter = halmac_adapter->driver_adapter;
1315 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1316 "%s ==========>wireless_mode = %d\n", __func__,
1319 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1320 "%s <==========\n", __func__);
1322 return HALMAC_RET_SUCCESS;
1326 * halmac_cfg_ch_bw_88xx() - config channel & bandwidth
1327 * @halmac_adapter : the adapter of halmac
1328 * @channel : WLAN channel, support 2.4G & 5G
1329 * @pri_ch_idx : primary channel index, idx1, idx2, idx3, idx4
1330 * @bw : band width, 20, 40, 80, 160, 5 ,10
1331 * Author : KaiYuan Chang
1332 * Return : enum halmac_ret_status
1333 * More details of status code can be found in prototype document
1335 enum halmac_ret_status
1336 halmac_cfg_ch_bw_88xx(struct halmac_adapter *halmac_adapter, u8 channel,
1337 enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw)
1339 void *driver_adapter = NULL;
1340 struct halmac_api *halmac_api;
1342 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1343 return HALMAC_RET_ADAPTER_INVALID;
1345 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1346 return HALMAC_RET_API_INVALID;
1348 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1350 driver_adapter = halmac_adapter->driver_adapter;
1351 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1353 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1354 "%s ==========>ch = %d, idx=%d, bw=%d\n", __func__,
1355 channel, pri_ch_idx, bw);
1357 halmac_cfg_pri_ch_idx_88xx(halmac_adapter, pri_ch_idx);
1359 halmac_cfg_bw_88xx(halmac_adapter, bw);
1361 halmac_cfg_ch_88xx(halmac_adapter, channel);
1363 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1364 "%s <==========\n", __func__);
1366 return HALMAC_RET_SUCCESS;
1369 enum halmac_ret_status halmac_cfg_ch_88xx(struct halmac_adapter *halmac_adapter,
1373 void *driver_adapter = NULL;
1374 struct halmac_api *halmac_api;
1376 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1377 return HALMAC_RET_ADAPTER_INVALID;
1379 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1380 return HALMAC_RET_API_INVALID;
1382 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1384 driver_adapter = halmac_adapter->driver_adapter;
1385 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1387 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1388 "%s ==========>ch = %d\n", __func__, channel);
1390 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CCK_CHECK);
1391 value8 = value8 & (~(BIT(7)));
1394 value8 = value8 | BIT(7);
1396 HALMAC_REG_WRITE_8(halmac_adapter, REG_CCK_CHECK, value8);
1398 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1399 "%s <==========\n", __func__);
1401 return HALMAC_RET_SUCCESS;
1404 enum halmac_ret_status
1405 halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter *halmac_adapter,
1406 enum halmac_pri_ch_idx pri_ch_idx)
1408 u8 txsc_40 = 0, txsc_20 = 0;
1409 void *driver_adapter = NULL;
1410 struct halmac_api *halmac_api;
1412 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1413 return HALMAC_RET_ADAPTER_INVALID;
1415 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1416 return HALMAC_RET_API_INVALID;
1418 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1420 driver_adapter = halmac_adapter->driver_adapter;
1421 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1423 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1424 "%s ==========> idx=%d\n", __func__,
1427 txsc_20 = pri_ch_idx;
1428 if (txsc_20 == HALMAC_CH_IDX_1 || txsc_20 == HALMAC_CH_IDX_3)
1433 HALMAC_REG_WRITE_8(halmac_adapter, REG_DATA_SC,
1434 BIT_TXSC_20M(txsc_20) | BIT_TXSC_40M(txsc_40));
1436 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1437 "%s <==========\n", __func__);
1439 return HALMAC_RET_SUCCESS;
1443 * halmac_cfg_bw_88xx() - config bandwidth
1444 * @halmac_adapter : the adapter of halmac
1445 * @bw : band width, 20, 40, 80, 160, 5 ,10
1446 * Author : KaiYuan Chang
1447 * Return : enum halmac_ret_status
1448 * More details of status code can be found in prototype document
1450 enum halmac_ret_status halmac_cfg_bw_88xx(struct halmac_adapter *halmac_adapter,
1454 void *driver_adapter = NULL;
1455 struct halmac_api *halmac_api;
1457 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1458 return HALMAC_RET_ADAPTER_INVALID;
1460 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1461 return HALMAC_RET_API_INVALID;
1463 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_BW);
1465 driver_adapter = halmac_adapter->driver_adapter;
1466 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1468 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1469 "%s ==========>bw=%d\n", __func__, bw);
1472 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL);
1473 value32 = value32 & (~(BIT(7) | BIT(8)));
1477 value32 = value32 | BIT(7);
1480 value32 = value32 | BIT(8);
1487 pr_err("%s switch case not support\n", __func__);
1490 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL, value32);
1493 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_AFE_CTRL1);
1494 value32 = (value32 & (~(BIT(20) | BIT(21)))) |
1495 (HALMAC_MAC_CLOCK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
1496 HALMAC_REG_WRITE_32(halmac_adapter, REG_AFE_CTRL1, value32);
1498 HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_TSF,
1499 HALMAC_MAC_CLOCK_88XX);
1500 HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_EDCA,
1501 HALMAC_MAC_CLOCK_88XX);
1503 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1504 "%s <==========\n", __func__);
1506 return HALMAC_RET_SUCCESS;
1510 * halmac_dump_efuse_map_88xx() - dump "physical" efuse map
1511 * @halmac_adapter : the adapter of halmac
1512 * @cfg : dump efuse method
1513 * Author : Ivan Lin/KaiYuan Chang
1514 * Return : enum halmac_ret_status
1515 * More details of status code can be found in prototype document
1517 enum halmac_ret_status
1518 halmac_dump_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
1519 enum halmac_efuse_read_cfg cfg)
1521 void *driver_adapter = NULL;
1522 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1523 enum halmac_cmd_process_status *process_status =
1524 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1526 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1527 return HALMAC_RET_ADAPTER_INVALID;
1529 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1530 return HALMAC_RET_API_INVALID;
1532 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP);
1534 driver_adapter = halmac_adapter->driver_adapter;
1536 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1537 "%s ==========>cfg=%d\n", __func__, cfg);
1539 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1540 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1541 "Wait event(dump efuse)...\n");
1542 return HALMAC_RET_BUSY_STATE;
1545 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1546 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1547 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1548 "Not idle state(dump efuse)...\n");
1549 return HALMAC_RET_ERROR_STATE;
1552 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
1553 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
1554 "[WARN]Dump efuse in suspend mode\n");
1556 *process_status = HALMAC_CMD_PROCESS_IDLE;
1557 halmac_adapter->event_trigger.physical_efuse_map = 1;
1559 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1560 HALMAC_EFUSE_BANK_WIFI);
1561 if (status != HALMAC_RET_SUCCESS) {
1562 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1566 status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
1568 if (status != HALMAC_RET_SUCCESS) {
1569 pr_err("halmac_read_efuse error = %x\n", status);
1573 if (halmac_adapter->hal_efuse_map_valid) {
1574 *process_status = HALMAC_CMD_PROCESS_DONE;
1576 PLATFORM_EVENT_INDICATION(
1577 driver_adapter, HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
1578 *process_status, halmac_adapter->hal_efuse_map,
1579 halmac_adapter->hw_config_info.efuse_size);
1580 halmac_adapter->event_trigger.physical_efuse_map = 0;
1583 if (halmac_transition_efuse_state_88xx(
1584 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1586 return HALMAC_RET_ERROR_STATE;
1588 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1589 "%s <==========\n", __func__);
1591 return HALMAC_RET_SUCCESS;
1595 * halmac_dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
1596 * @halmac_adapter : the adapter of halmac
1597 * @halmac_efuse_bank : bt efuse bank
1598 * @bt_efuse_map_size : bt efuse map size. get from halmac_get_efuse_size API
1599 * @bt_efuse_map : bt efuse map
1600 * Author : Soar / Ivan Lin
1601 * Return : enum halmac_ret_status
1602 * More details of status code can be found in prototype document
1604 enum halmac_ret_status
1605 halmac_dump_efuse_map_bt_88xx(struct halmac_adapter *halmac_adapter,
1606 enum halmac_efuse_bank halmac_efuse_bank,
1607 u32 bt_efuse_map_size, u8 *bt_efuse_map)
1609 void *driver_adapter = NULL;
1610 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1611 enum halmac_cmd_process_status *process_status =
1612 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1614 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1615 return HALMAC_RET_ADAPTER_INVALID;
1617 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1618 return HALMAC_RET_API_INVALID;
1620 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP_BT);
1622 driver_adapter = halmac_adapter->driver_adapter;
1624 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1625 "%s ==========>\n", __func__);
1627 if (halmac_adapter->hw_config_info.bt_efuse_size != bt_efuse_map_size)
1628 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
1630 if ((halmac_efuse_bank >= HALMAC_EFUSE_BANK_MAX) ||
1631 halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
1632 pr_err("Undefined BT bank\n");
1633 return HALMAC_RET_EFUSE_BANK_INCORRECT;
1636 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1637 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1638 "Wait event(dump efuse)...\n");
1639 return HALMAC_RET_BUSY_STATE;
1642 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1643 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1644 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1645 "Not idle state(dump efuse)...\n");
1646 return HALMAC_RET_ERROR_STATE;
1649 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1651 if (status != HALMAC_RET_SUCCESS) {
1652 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1656 status = halmac_read_hw_efuse_88xx(halmac_adapter, 0, bt_efuse_map_size,
1659 if (status != HALMAC_RET_SUCCESS) {
1660 pr_err("halmac_read_hw_efuse_88xx error = %x\n", status);
1664 if (halmac_transition_efuse_state_88xx(
1665 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1667 return HALMAC_RET_ERROR_STATE;
1669 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1670 "%s <==========\n", __func__);
1672 return HALMAC_RET_SUCCESS;
1676 * halmac_write_efuse_bt_88xx() - write "BT physical" efuse offset
1677 * @halmac_adapter : the adapter of halmac
1678 * @halmac_offset : offset
1679 * @halmac_value : Write value
1680 * @bt_efuse_map : bt efuse map
1682 * Return : enum halmac_ret_status
1683 * More details of status code can be found in prototype document
1685 enum halmac_ret_status
1686 halmac_write_efuse_bt_88xx(struct halmac_adapter *halmac_adapter,
1687 u32 halmac_offset, u8 halmac_value,
1688 enum halmac_efuse_bank halmac_efuse_bank)
1690 void *driver_adapter = NULL;
1691 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1693 enum halmac_cmd_process_status *process_status =
1694 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1696 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1697 return HALMAC_RET_ADAPTER_INVALID;
1699 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1700 return HALMAC_RET_API_INVALID;
1702 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_WRITE_EFUSE_BT);
1704 driver_adapter = halmac_adapter->driver_adapter;
1706 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1707 "%s ==========>\n", __func__);
1708 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1709 "offset : %X value : %X Bank : %X\n", halmac_offset,
1710 halmac_value, halmac_efuse_bank);
1712 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1713 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1714 "Wait/Rcvd event(dump efuse)...\n");
1715 return HALMAC_RET_BUSY_STATE;
1718 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1719 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1720 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1721 "Not idle state(dump efuse)...\n");
1722 return HALMAC_RET_ERROR_STATE;
1725 if (halmac_offset >= halmac_adapter->hw_config_info.efuse_size) {
1726 pr_err("Offset is too large\n");
1727 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
1730 if (halmac_efuse_bank > HALMAC_EFUSE_BANK_MAX ||
1731 halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
1732 pr_err("Undefined BT bank\n");
1733 return HALMAC_RET_EFUSE_BANK_INCORRECT;
1736 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1738 if (status != HALMAC_RET_SUCCESS) {
1739 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1743 status = halmac_func_write_efuse_88xx(halmac_adapter, halmac_offset,
1745 if (status != HALMAC_RET_SUCCESS) {
1746 pr_err("halmac_func_write_efuse error = %x\n", status);
1750 if (halmac_transition_efuse_state_88xx(
1751 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1753 return HALMAC_RET_ERROR_STATE;
1755 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1756 "%s <==========\n", __func__);
1758 return HALMAC_RET_SUCCESS;
1762 * halmac_get_efuse_available_size_88xx() - get efuse available size
1763 * @halmac_adapter : the adapter of halmac
1764 * @halmac_size : physical efuse available size
1766 * Return : enum halmac_ret_status
1767 * More details of status code can be found in prototype document
1769 enum halmac_ret_status
1770 halmac_get_efuse_available_size_88xx(struct halmac_adapter *halmac_adapter,
1773 enum halmac_ret_status status;
1774 void *driver_adapter = NULL;
1776 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1777 return HALMAC_RET_ADAPTER_INVALID;
1779 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1780 return HALMAC_RET_API_INVALID;
1782 driver_adapter = halmac_adapter->driver_adapter;
1784 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1785 "%s ==========>\n", __func__);
1787 status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
1788 HALMAC_EFUSE_R_DRV);
1790 if (status != HALMAC_RET_SUCCESS)
1793 *halmac_size = halmac_adapter->hw_config_info.efuse_size -
1794 HALMAC_PROTECTED_EFUSE_SIZE_88XX -
1795 halmac_adapter->efuse_end;
1797 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1798 "%s <==========\n", __func__);
1800 return HALMAC_RET_SUCCESS;
1804 * halmac_get_efuse_size_88xx() - get "physical" efuse size
1805 * @halmac_adapter : the adapter of halmac
1806 * @halmac_size : physical efuse size
1807 * Author : Ivan Lin/KaiYuan Chang
1808 * Return : enum halmac_ret_status
1809 * More details of status code can be found in prototype document
1811 enum halmac_ret_status
1812 halmac_get_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
1815 void *driver_adapter = NULL;
1817 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1818 return HALMAC_RET_ADAPTER_INVALID;
1820 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1821 return HALMAC_RET_API_INVALID;
1823 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_EFUSE_SIZE);
1825 driver_adapter = halmac_adapter->driver_adapter;
1827 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1828 "%s ==========>\n", __func__);
1830 *halmac_size = halmac_adapter->hw_config_info.efuse_size;
1832 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1833 "%s <==========\n", __func__);
1835 return HALMAC_RET_SUCCESS;
1839 * halmac_get_logical_efuse_size_88xx() - get "logical" efuse size
1840 * @halmac_adapter : the adapter of halmac
1841 * @halmac_size : logical efuse size
1842 * Author : Ivan Lin/KaiYuan Chang
1843 * Return : enum halmac_ret_status
1844 * More details of status code can be found in prototype document
1846 enum halmac_ret_status
1847 halmac_get_logical_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
1850 void *driver_adapter = NULL;
1852 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1853 return HALMAC_RET_ADAPTER_INVALID;
1855 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1856 return HALMAC_RET_API_INVALID;
1858 halmac_api_record_id_88xx(halmac_adapter,
1859 HALMAC_API_GET_LOGICAL_EFUSE_SIZE);
1861 driver_adapter = halmac_adapter->driver_adapter;
1863 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1864 "%s ==========>\n", __func__);
1866 *halmac_size = halmac_adapter->hw_config_info.eeprom_size;
1868 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1869 "%s <==========\n", __func__);
1871 return HALMAC_RET_SUCCESS;
1875 * halmac_dump_logical_efuse_map_88xx() - dump "logical" efuse map
1876 * @halmac_adapter : the adapter of halmac
1877 * @cfg : dump efuse method
1879 * Return : enum halmac_ret_status
1880 * More details of status code can be found in prototype document
1882 enum halmac_ret_status
1883 halmac_dump_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
1884 enum halmac_efuse_read_cfg cfg)
1886 u8 *eeprom_map = NULL;
1887 u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
1888 void *driver_adapter = NULL;
1889 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1890 enum halmac_cmd_process_status *process_status =
1891 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1893 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1894 return HALMAC_RET_ADAPTER_INVALID;
1896 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1897 return HALMAC_RET_API_INVALID;
1899 halmac_api_record_id_88xx(halmac_adapter,
1900 HALMAC_API_DUMP_LOGICAL_EFUSE_MAP);
1902 driver_adapter = halmac_adapter->driver_adapter;
1904 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1905 "%s ==========>cfg = %d\n", __func__, cfg);
1907 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1908 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1909 "Wait/Rcvd event(dump efuse)...\n");
1910 return HALMAC_RET_BUSY_STATE;
1913 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1914 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1915 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1916 "Not idle state(dump efuse)...\n");
1917 return HALMAC_RET_ERROR_STATE;
1920 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
1921 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
1922 "[WARN]Dump logical efuse in suspend mode\n");
1924 *process_status = HALMAC_CMD_PROCESS_IDLE;
1925 halmac_adapter->event_trigger.logical_efuse_map = 1;
1927 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1928 HALMAC_EFUSE_BANK_WIFI);
1929 if (status != HALMAC_RET_SUCCESS) {
1930 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1934 status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
1936 if (status != HALMAC_RET_SUCCESS) {
1937 pr_err("halmac_eeprom_parser_88xx error = %x\n", status);
1941 if (halmac_adapter->hal_efuse_map_valid) {
1942 *process_status = HALMAC_CMD_PROCESS_DONE;
1944 eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
1947 return HALMAC_RET_MALLOC_FAIL;
1949 memset(eeprom_map, 0xFF, eeprom_size);
1951 if (halmac_eeprom_parser_88xx(halmac_adapter,
1952 halmac_adapter->hal_efuse_map,
1953 eeprom_map) != HALMAC_RET_SUCCESS) {
1955 return HALMAC_RET_EEPROM_PARSING_FAIL;
1958 PLATFORM_EVENT_INDICATION(
1959 driver_adapter, HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
1960 *process_status, eeprom_map, eeprom_size);
1961 halmac_adapter->event_trigger.logical_efuse_map = 0;
1966 if (halmac_transition_efuse_state_88xx(
1967 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1969 return HALMAC_RET_ERROR_STATE;
1971 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1972 "%s <==========\n", __func__);
1974 return HALMAC_RET_SUCCESS;
1978 * halmac_read_logical_efuse_88xx() - read logical efuse map 1 byte
1979 * @halmac_adapter : the adapter of halmac
1980 * @halmac_offset : offset
1981 * @value : 1 byte efuse value
1983 * Return : enum halmac_ret_status
1984 * More details of status code can be found in prototype document
1986 enum halmac_ret_status
1987 halmac_read_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
1988 u32 halmac_offset, u8 *value)
1990 u8 *eeprom_map = NULL;
1991 u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
1992 void *driver_adapter = NULL;
1993 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1995 enum halmac_cmd_process_status *process_status =
1996 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1998 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1999 return HALMAC_RET_ADAPTER_INVALID;
2001 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2002 return HALMAC_RET_API_INVALID;
2004 halmac_api_record_id_88xx(halmac_adapter,
2005 HALMAC_API_READ_LOGICAL_EFUSE);
2007 driver_adapter = halmac_adapter->driver_adapter;
2009 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2010 "%s ==========>\n", __func__);
2012 if (halmac_offset >= eeprom_size) {
2013 pr_err("Offset is too large\n");
2014 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2017 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2018 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2019 "Wait/Rcvd event(dump efuse)...\n");
2020 return HALMAC_RET_BUSY_STATE;
2022 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2023 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2024 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2025 "Not idle state(dump efuse)...\n");
2026 return HALMAC_RET_ERROR_STATE;
2029 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2030 HALMAC_EFUSE_BANK_WIFI);
2031 if (status != HALMAC_RET_SUCCESS) {
2032 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2036 eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2039 return HALMAC_RET_MALLOC_FAIL;
2041 memset(eeprom_map, 0xFF, eeprom_size);
2043 status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
2044 if (status != HALMAC_RET_SUCCESS) {
2045 pr_err("halmac_read_logical_efuse_map error = %x\n", status);
2050 *value = *(eeprom_map + halmac_offset);
2052 if (halmac_transition_efuse_state_88xx(
2053 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2054 HALMAC_RET_SUCCESS) {
2056 return HALMAC_RET_ERROR_STATE;
2059 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2060 "%s <==========\n", __func__);
2064 return HALMAC_RET_SUCCESS;
2068 * halmac_write_logical_efuse_88xx() - write "logical" efuse offset
2069 * @halmac_adapter : the adapter of halmac
2070 * @halmac_offset : offset
2071 * @halmac_value : value
2073 * Return : enum halmac_ret_status
2074 * More details of status code can be found in prototype document
2076 enum halmac_ret_status
2077 halmac_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
2078 u32 halmac_offset, u8 halmac_value)
2080 void *driver_adapter = NULL;
2081 struct halmac_api *halmac_api;
2082 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2084 enum halmac_cmd_process_status *process_status =
2085 &halmac_adapter->halmac_state.efuse_state_set.process_status;
2087 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2088 return HALMAC_RET_ADAPTER_INVALID;
2090 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2091 return HALMAC_RET_API_INVALID;
2093 halmac_api_record_id_88xx(halmac_adapter,
2094 HALMAC_API_WRITE_LOGICAL_EFUSE);
2096 driver_adapter = halmac_adapter->driver_adapter;
2097 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2099 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2100 "%s ==========>\n", __func__);
2102 if (halmac_offset >= halmac_adapter->hw_config_info.eeprom_size) {
2103 pr_err("Offset is too large\n");
2104 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2107 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2108 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2109 "Wait/Rcvd event(dump efuse)...\n");
2110 return HALMAC_RET_BUSY_STATE;
2113 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2114 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2115 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2116 "Not idle state(dump efuse)...\n");
2117 return HALMAC_RET_ERROR_STATE;
2120 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2121 HALMAC_EFUSE_BANK_WIFI);
2122 if (status != HALMAC_RET_SUCCESS) {
2123 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2127 status = halmac_func_write_logical_efuse_88xx(
2128 halmac_adapter, halmac_offset, halmac_value);
2129 if (status != HALMAC_RET_SUCCESS) {
2130 pr_err("halmac_write_logical_efuse error = %x\n", status);
2134 if (halmac_transition_efuse_state_88xx(
2135 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2137 return HALMAC_RET_ERROR_STATE;
2139 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2140 "%s <==========\n", __func__);
2142 return HALMAC_RET_SUCCESS;
2146 * halmac_pg_efuse_by_map_88xx() - pg logical efuse by map
2147 * @halmac_adapter : the adapter of halmac
2148 * @pg_efuse_info : efuse map information
2149 * @cfg : dump efuse method
2151 * Return : enum halmac_ret_status
2152 * More details of status code can be found in prototype document
2154 enum halmac_ret_status
2155 halmac_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
2156 struct halmac_pg_efuse_info *pg_efuse_info,
2157 enum halmac_efuse_read_cfg cfg)
2159 void *driver_adapter = NULL;
2160 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2162 enum halmac_cmd_process_status *process_status =
2163 &halmac_adapter->halmac_state.efuse_state_set.process_status;
2165 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2166 return HALMAC_RET_ADAPTER_INVALID;
2168 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2169 return HALMAC_RET_API_INVALID;
2171 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PG_EFUSE_BY_MAP);
2173 driver_adapter = halmac_adapter->driver_adapter;
2175 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2176 "%s ==========>\n", __func__);
2178 if (pg_efuse_info->efuse_map_size !=
2179 halmac_adapter->hw_config_info.eeprom_size) {
2180 pr_err("efuse_map_size is incorrect, should be %d bytes\n",
2181 halmac_adapter->hw_config_info.eeprom_size);
2182 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2185 if ((pg_efuse_info->efuse_map_size & 0xF) > 0) {
2186 pr_err("efuse_map_size should be multiple of 16\n");
2187 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2190 if (pg_efuse_info->efuse_mask_size !=
2191 pg_efuse_info->efuse_map_size >> 4) {
2192 pr_err("efuse_mask_size is incorrect, should be %d bytes\n",
2193 pg_efuse_info->efuse_map_size >> 4);
2194 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2197 if (!pg_efuse_info->efuse_map) {
2198 pr_err("efuse_map is NULL\n");
2199 return HALMAC_RET_NULL_POINTER;
2202 if (!pg_efuse_info->efuse_mask) {
2203 pr_err("efuse_mask is NULL\n");
2204 return HALMAC_RET_NULL_POINTER;
2207 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2208 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2209 "Wait/Rcvd event(dump efuse)...\n");
2210 return HALMAC_RET_BUSY_STATE;
2213 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2214 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2215 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2216 "Not idle state(dump efuse)...\n");
2217 return HALMAC_RET_ERROR_STATE;
2220 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2221 HALMAC_EFUSE_BANK_WIFI);
2222 if (status != HALMAC_RET_SUCCESS) {
2223 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2227 status = halmac_func_pg_efuse_by_map_88xx(halmac_adapter, pg_efuse_info,
2230 if (status != HALMAC_RET_SUCCESS) {
2231 pr_err("halmac_pg_efuse_by_map error = %x\n", status);
2235 if (halmac_transition_efuse_state_88xx(
2236 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2238 return HALMAC_RET_ERROR_STATE;
2240 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2241 "%s <==========\n", __func__);
2243 return HALMAC_RET_SUCCESS;
2247 * halmac_get_c2h_info_88xx() - process halmac C2H packet
2248 * @halmac_adapter : the adapter of halmac
2249 * @halmac_buf : RX Packet pointer
2250 * @halmac_size : RX Packet size
2251 * Author : KaiYuan Chang/Ivan Lin
2253 * Used to process c2h packet info from RX path. After receiving the packet,
2254 * user need to call this api and pass the packet pointer.
2256 * Return : enum halmac_ret_status
2257 * More details of status code can be found in prototype document
2259 enum halmac_ret_status
2260 halmac_get_c2h_info_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
2263 void *driver_adapter = NULL;
2264 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2266 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2267 return HALMAC_RET_ADAPTER_INVALID;
2269 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2270 return HALMAC_RET_API_INVALID;
2272 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_C2H_INFO);
2274 driver_adapter = halmac_adapter->driver_adapter;
2276 /* Check if it is C2H packet */
2277 if (GET_RX_DESC_C2H(halmac_buf)) {
2278 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2279 "C2H packet, start parsing!\n");
2281 status = halmac_parse_c2h_packet_88xx(halmac_adapter,
2282 halmac_buf, halmac_size);
2284 if (status != HALMAC_RET_SUCCESS) {
2285 pr_err("halmac_parse_c2h_packet_88xx error = %x\n",
2291 return HALMAC_RET_SUCCESS;
2294 enum halmac_ret_status
2295 halmac_cfg_fwlps_option_88xx(struct halmac_adapter *halmac_adapter,
2296 struct halmac_fwlps_option *lps_option)
2298 void *driver_adapter = NULL;
2299 struct halmac_fwlps_option *hal_fwlps_option;
2301 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2302 return HALMAC_RET_ADAPTER_INVALID;
2304 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2305 return HALMAC_RET_API_INVALID;
2307 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWLPS_OPTION);
2309 driver_adapter = halmac_adapter->driver_adapter;
2310 hal_fwlps_option = &halmac_adapter->fwlps_option;
2312 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2313 "%s ==========>\n", __func__);
2315 hal_fwlps_option->mode = lps_option->mode;
2316 hal_fwlps_option->clk_request = lps_option->clk_request;
2317 hal_fwlps_option->rlbm = lps_option->rlbm;
2318 hal_fwlps_option->smart_ps = lps_option->smart_ps;
2319 hal_fwlps_option->awake_interval = lps_option->awake_interval;
2320 hal_fwlps_option->all_queue_uapsd = lps_option->all_queue_uapsd;
2321 hal_fwlps_option->pwr_state = lps_option->pwr_state;
2322 hal_fwlps_option->low_pwr_rx_beacon = lps_option->low_pwr_rx_beacon;
2323 hal_fwlps_option->ant_auto_switch = lps_option->ant_auto_switch;
2324 hal_fwlps_option->ps_allow_bt_high_priority =
2325 lps_option->ps_allow_bt_high_priority;
2326 hal_fwlps_option->protect_bcn = lps_option->protect_bcn;
2327 hal_fwlps_option->silence_period = lps_option->silence_period;
2328 hal_fwlps_option->fast_bt_connect = lps_option->fast_bt_connect;
2329 hal_fwlps_option->two_antenna_en = lps_option->two_antenna_en;
2330 hal_fwlps_option->adopt_user_setting = lps_option->adopt_user_setting;
2331 hal_fwlps_option->drv_bcn_early_shift = lps_option->drv_bcn_early_shift;
2332 hal_fwlps_option->enter_32K = lps_option->enter_32K;
2334 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2335 "%s <==========\n", __func__);
2337 return HALMAC_RET_SUCCESS;
2340 enum halmac_ret_status
2341 halmac_cfg_fwips_option_88xx(struct halmac_adapter *halmac_adapter,
2342 struct halmac_fwips_option *ips_option)
2344 void *driver_adapter = NULL;
2345 struct halmac_fwips_option *ips_option_local;
2347 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2348 return HALMAC_RET_ADAPTER_INVALID;
2350 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2351 return HALMAC_RET_API_INVALID;
2353 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWIPS_OPTION);
2355 driver_adapter = halmac_adapter->driver_adapter;
2357 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2358 "%s ==========>\n", __func__);
2360 ips_option_local = ips_option;
2362 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2363 "%s <==========\n", __func__);
2365 return HALMAC_RET_SUCCESS;
2368 enum halmac_ret_status
2369 halmac_enter_wowlan_88xx(struct halmac_adapter *halmac_adapter,
2370 struct halmac_wowlan_option *wowlan_option)
2372 void *driver_adapter = NULL;
2373 struct halmac_wowlan_option *wowlan_option_local;
2375 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2376 return HALMAC_RET_ADAPTER_INVALID;
2378 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2379 return HALMAC_RET_API_INVALID;
2381 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_WOWLAN);
2383 driver_adapter = halmac_adapter->driver_adapter;
2385 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2386 "%s ==========>\n", __func__);
2388 wowlan_option_local = wowlan_option;
2390 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2391 "%s <==========\n", __func__);
2393 return HALMAC_RET_SUCCESS;
2396 enum halmac_ret_status
2397 halmac_leave_wowlan_88xx(struct halmac_adapter *halmac_adapter)
2399 void *driver_adapter = NULL;
2401 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2402 return HALMAC_RET_ADAPTER_INVALID;
2404 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2405 return HALMAC_RET_API_INVALID;
2407 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_WOWLAN);
2409 driver_adapter = halmac_adapter->driver_adapter;
2411 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2412 "%s ==========>\n", __func__);
2414 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2415 "%s <==========\n", __func__);
2417 return HALMAC_RET_SUCCESS;
2420 enum halmac_ret_status
2421 halmac_enter_ps_88xx(struct halmac_adapter *halmac_adapter,
2422 enum halmac_ps_state ps_state)
2425 void *driver_adapter = NULL;
2426 struct halmac_api *halmac_api;
2427 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2429 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2430 return HALMAC_RET_ADAPTER_INVALID;
2432 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2433 return HALMAC_RET_API_INVALID;
2435 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2436 return HALMAC_RET_NO_DLFW;
2438 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_PS);
2440 driver_adapter = halmac_adapter->driver_adapter;
2441 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2443 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2444 "%s ==========>\n", __func__);
2446 if (ps_state == halmac_adapter->halmac_state.ps_state) {
2447 pr_err("power state is already in PS State!!\n");
2448 return HALMAC_RET_SUCCESS;
2451 if (ps_state == HALMAC_PS_STATE_LPS) {
2452 status = halmac_send_h2c_set_pwr_mode_88xx(
2453 halmac_adapter, &halmac_adapter->fwlps_option);
2454 if (status != HALMAC_RET_SUCCESS) {
2455 pr_err("halmac_send_h2c_set_pwr_mode_88xx error = %x!!\n",
2459 } else if (ps_state == HALMAC_PS_STATE_IPS) {
2462 halmac_adapter->halmac_state.ps_state = ps_state;
2465 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
2466 if (halmac_adapter->fwlps_option.enter_32K) {
2467 rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
2470 HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1,
2472 halmac_adapter->low_clk = true;
2474 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
2475 if (halmac_adapter->fwlps_option.enter_32K) {
2476 rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
2479 HALMAC_REG_WRITE_8(halmac_adapter, 0xFE58, rpwm);
2480 halmac_adapter->low_clk = true;
2484 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2485 "%s <==========\n", __func__);
2487 return HALMAC_RET_SUCCESS;
2490 enum halmac_ret_status
2491 halmac_leave_ps_88xx(struct halmac_adapter *halmac_adapter)
2495 void *driver_adapter = NULL;
2496 struct halmac_api *halmac_api;
2497 struct halmac_fwlps_option fw_lps_option;
2498 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2500 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2501 return HALMAC_RET_ADAPTER_INVALID;
2503 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2504 return HALMAC_RET_API_INVALID;
2506 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2507 return HALMAC_RET_NO_DLFW;
2509 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_PS);
2511 driver_adapter = halmac_adapter->driver_adapter;
2512 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2514 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2515 "%s ==========>\n", __func__);
2517 if (halmac_adapter->halmac_state.ps_state == HALMAC_PS_STATE_ACT) {
2518 pr_err("power state is already in active!!\n");
2519 return HALMAC_RET_SUCCESS;
2522 if (halmac_adapter->low_clk) {
2523 cpwm = HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1);
2525 ((halmac_adapter->rpwm_record ^ (BIT(7))) | (BIT(6))) &
2527 HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1, rpwm);
2529 cpwm = (u8)((cpwm ^ BIT(7)) & BIT(7));
2532 (HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1) &
2534 usleep_range(50, 60);
2537 return HALMAC_RET_CHANGE_PS_FAIL;
2539 halmac_adapter->low_clk = false;
2542 memcpy(&fw_lps_option, &halmac_adapter->fwlps_option,
2543 sizeof(struct halmac_fwlps_option));
2544 fw_lps_option.mode = 0;
2546 status = halmac_send_h2c_set_pwr_mode_88xx(halmac_adapter,
2548 if (status != HALMAC_RET_SUCCESS) {
2549 pr_err("halmac_send_h2c_set_pwr_mode_88xx error!!=%x\n",
2554 halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
2556 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2557 "%s <==========\n", __func__);
2559 return HALMAC_RET_SUCCESS;
2563 * (debug API)halmac_h2c_lb_88xx() - send h2c loopback packet
2564 * @halmac_adapter : the adapter of halmac
2565 * Author : KaiYuan Chang/Ivan Lin
2566 * Return : enum halmac_ret_status
2567 * More details of status code can be found in prototype document
2569 enum halmac_ret_status halmac_h2c_lb_88xx(struct halmac_adapter *halmac_adapter)
2571 void *driver_adapter = NULL;
2573 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2574 return HALMAC_RET_ADAPTER_INVALID;
2576 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2577 return HALMAC_RET_API_INVALID;
2579 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_H2C_LB);
2581 driver_adapter = halmac_adapter->driver_adapter;
2583 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2584 "%s ==========>\n", __func__);
2586 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2587 "%s <==========\n", __func__);
2589 return HALMAC_RET_SUCCESS;
2593 * halmac_debug_88xx() - dump information for debugging
2594 * @halmac_adapter : the adapter of halmac
2595 * Author : KaiYuan Chang/Ivan Lin
2596 * Return : enum halmac_ret_status
2597 * More details of status code can be found in prototype document
2599 enum halmac_ret_status halmac_debug_88xx(struct halmac_adapter *halmac_adapter)
2602 u32 i = 0, temp32 = 0;
2603 void *driver_adapter = NULL;
2604 struct halmac_api *halmac_api;
2606 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2607 return HALMAC_RET_ADAPTER_INVALID;
2609 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2610 return HALMAC_RET_API_INVALID;
2612 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEBUG);
2614 driver_adapter = halmac_adapter->driver_adapter;
2615 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2617 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2618 "%s ==========>\n", __func__);
2620 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
2621 /* Dump CCCR, it needs new platform api */
2623 /*Dump SDIO Local Register, use CMD52*/
2624 for (i = 0x10250000; i < 0x102500ff; i++) {
2625 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2627 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2628 "halmac_debug: sdio[%x]=%x\n", i, temp8);
2631 /*Dump MAC Register*/
2632 for (i = 0x0000; i < 0x17ff; i++) {
2633 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2634 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
2635 DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
2639 /*Check RX Fifo status*/
2640 i = REG_RXFF_PTR_V1;
2641 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2642 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2643 "halmac_debug: mac[%x]=%x\n", i, temp8);
2644 i = REG_RXFF_WTR_V1;
2645 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2646 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2647 "halmac_debug: mac[%x]=%x\n", i, temp8);
2648 i = REG_RXFF_PTR_V1;
2649 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2650 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2651 "halmac_debug: mac[%x]=%x\n", i, temp8);
2652 i = REG_RXFF_WTR_V1;
2653 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2654 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2655 "halmac_debug: mac[%x]=%x\n", i, temp8);
2657 /*Dump MAC Register*/
2658 for (i = 0x0000; i < 0x17fc; i += 4) {
2659 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2660 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
2661 DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
2665 /*Check RX Fifo status*/
2666 i = REG_RXFF_PTR_V1;
2667 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2668 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2669 "halmac_debug: mac[%x]=%x\n", i, temp32);
2670 i = REG_RXFF_WTR_V1;
2671 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2672 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2673 "halmac_debug: mac[%x]=%x\n", i, temp32);
2674 i = REG_RXFF_PTR_V1;
2675 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2676 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2677 "halmac_debug: mac[%x]=%x\n", i, temp32);
2678 i = REG_RXFF_WTR_V1;
2679 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2680 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2681 "halmac_debug: mac[%x]=%x\n", i, temp32);
2684 /* TODO: Add check register code, including MAC CLK, CPU CLK */
2686 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2687 "%s <==========\n", __func__);
2689 return HALMAC_RET_SUCCESS;
2693 * halmac_cfg_parameter_88xx() - config parameter by FW
2694 * @halmac_adapter : the adapter of halmac
2695 * @para_info : cmd id, content
2696 * @full_fifo : parameter information
2698 * If msk_en = true, the format of array is {reg_info, mask, value}.
2699 * If msk_en =_FAUSE, the format of array is {reg_info, value}
2700 * The format of reg_info is
2701 * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
2702 * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
2703 * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
2704 * ref_info[15:0]=offset
2706 * Example: msk_en = false
2707 * {0x8100000a, 0x00001122}
2708 * =>Set RF register, path_B, offset 0xA to 0x00001122
2709 * {0x00000824, 0x11224433}
2710 * =>Set MAC_BB register, offset 0x800 to 0x11224433
2712 * Note : full fifo mode only for init flow
2714 * Author : KaiYuan Chang/Ivan Lin
2715 * Return : enum halmac_ret_status
2716 * More details of status code can be found in prototype document
2718 enum halmac_ret_status
2719 halmac_cfg_parameter_88xx(struct halmac_adapter *halmac_adapter,
2720 struct halmac_phy_parameter_info *para_info,
2723 void *driver_adapter = NULL;
2724 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
2725 enum halmac_cmd_process_status *process_status =
2726 &halmac_adapter->halmac_state.cfg_para_state_set.process_status;
2728 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2729 return HALMAC_RET_ADAPTER_INVALID;
2731 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2732 return HALMAC_RET_API_INVALID;
2734 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2735 return HALMAC_RET_NO_DLFW;
2737 if (halmac_adapter->fw_version.h2c_version < 4)
2738 return HALMAC_RET_FW_NO_SUPPORT;
2740 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_PARAMETER);
2742 driver_adapter = halmac_adapter->driver_adapter;
2744 if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
2745 pr_err("%s Fail due to DLFW NONE!!\n", __func__);
2746 return HALMAC_RET_DLFW_FAIL;
2749 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2750 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2751 "Wait event(cfg para)...\n");
2752 return HALMAC_RET_BUSY_STATE;
2755 if (halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
2756 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
2757 halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
2758 HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
2759 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2760 "Not idle state(cfg para)...\n");
2761 return HALMAC_RET_BUSY_STATE;
2764 *process_status = HALMAC_CMD_PROCESS_IDLE;
2766 ret_status = halmac_send_h2c_phy_parameter_88xx(halmac_adapter,
2767 para_info, full_fifo);
2769 if (ret_status != HALMAC_RET_SUCCESS) {
2770 pr_err("halmac_send_h2c_phy_parameter_88xx Fail!! = %x\n",
2779 * halmac_update_packet_88xx() - send specific packet to FW
2780 * @halmac_adapter : the adapter of halmac
2781 * @pkt_id : packet id, to know the purpose of this packet
2783 * @pkt_size : packet size
2785 * Note : TX_DESC is not included in the pkt
2787 * Author : KaiYuan Chang/Ivan Lin
2788 * Return : enum halmac_ret_status
2789 * More details of status code can be found in prototype document
2791 enum halmac_ret_status
2792 halmac_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2793 enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size)
2795 void *driver_adapter = NULL;
2796 struct halmac_api *halmac_api;
2797 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2798 enum halmac_cmd_process_status *process_status =
2799 &halmac_adapter->halmac_state.update_packet_set.process_status;
2801 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2802 return HALMAC_RET_ADAPTER_INVALID;
2804 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2805 return HALMAC_RET_API_INVALID;
2807 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2808 return HALMAC_RET_NO_DLFW;
2810 if (halmac_adapter->fw_version.h2c_version < 4)
2811 return HALMAC_RET_FW_NO_SUPPORT;
2813 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_UPDATE_PACKET);
2815 driver_adapter = halmac_adapter->driver_adapter;
2816 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2818 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2819 "%s ==========>\n", __func__);
2821 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2822 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2823 "Wait event(update_packet)...\n");
2824 return HALMAC_RET_BUSY_STATE;
2827 *process_status = HALMAC_CMD_PROCESS_SENDING;
2829 status = halmac_send_h2c_update_packet_88xx(halmac_adapter, pkt_id, pkt,
2832 if (status != HALMAC_RET_SUCCESS) {
2833 pr_err("halmac_send_h2c_update_packet_88xx packet = %x, fail = %x!!\n",
2838 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2839 "%s <==========\n", __func__);
2841 return HALMAC_RET_SUCCESS;
2844 enum halmac_ret_status
2845 halmac_bcn_ie_filter_88xx(struct halmac_adapter *halmac_adapter,
2846 struct halmac_bcn_ie_info *bcn_ie_info)
2848 void *driver_adapter = NULL;
2849 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2851 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2852 return HALMAC_RET_ADAPTER_INVALID;
2854 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2855 return HALMAC_RET_API_INVALID;
2857 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2858 return HALMAC_RET_NO_DLFW;
2860 if (halmac_adapter->fw_version.h2c_version < 4)
2861 return HALMAC_RET_FW_NO_SUPPORT;
2863 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_BCN_IE_FILTER);
2865 driver_adapter = halmac_adapter->driver_adapter;
2867 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2868 "%s ==========>\n", __func__);
2870 status = halmac_send_h2c_update_bcn_parse_info_88xx(halmac_adapter,
2873 if (status != HALMAC_RET_SUCCESS) {
2874 pr_err("halmac_send_h2c_update_bcn_parse_info_88xx fail = %x\n",
2879 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2880 "%s <==========\n", __func__);
2882 return HALMAC_RET_SUCCESS;
2885 enum halmac_ret_status
2886 halmac_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2887 enum halmac_data_type halmac_data_type,
2888 struct halmac_phy_parameter_info *para_info)
2890 void *driver_adapter = NULL;
2892 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2893 return HALMAC_RET_ADAPTER_INVALID;
2895 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2896 return HALMAC_RET_API_INVALID;
2898 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2899 return HALMAC_RET_NO_DLFW;
2901 if (halmac_adapter->fw_version.h2c_version < 4)
2902 return HALMAC_RET_FW_NO_SUPPORT;
2904 driver_adapter = halmac_adapter->driver_adapter;
2906 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2907 "[TRACE]%s ==========>\n", __func__);
2909 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2910 "[TRACE]%s <==========\n", __func__);
2912 return HALMAC_RET_SUCCESS;
2915 enum halmac_ret_status
2916 halmac_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2917 enum halmac_data_type halmac_data_type)
2919 void *driver_adapter = NULL;
2920 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
2922 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2923 return HALMAC_RET_ADAPTER_INVALID;
2925 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2926 return HALMAC_RET_API_INVALID;
2928 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2929 return HALMAC_RET_NO_DLFW;
2931 if (halmac_adapter->fw_version.h2c_version < 4)
2932 return HALMAC_RET_FW_NO_SUPPORT;
2934 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RUN_DATAPACK);
2936 driver_adapter = halmac_adapter->driver_adapter;
2938 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2939 "%s ==========>\n", __func__);
2941 ret_status = halmac_send_h2c_run_datapack_88xx(halmac_adapter,
2944 if (ret_status != HALMAC_RET_SUCCESS) {
2945 pr_err("halmac_send_h2c_run_datapack_88xx Fail, datatype = %x, status = %x!!\n",
2946 halmac_data_type, ret_status);
2950 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2951 "halmac_update_datapack_88xx <==========\n");
2953 return HALMAC_RET_SUCCESS;
2957 * halmac_cfg_drv_info_88xx() - config driver info
2958 * @halmac_adapter : the adapter of halmac
2959 * @halmac_drv_info : driver information selection
2960 * Author : KaiYuan Chang/Ivan Lin
2961 * Return : enum halmac_ret_status
2962 * More details of status code can be found in prototype document
2964 enum halmac_ret_status
2965 halmac_cfg_drv_info_88xx(struct halmac_adapter *halmac_adapter,
2966 enum halmac_drv_info halmac_drv_info)
2968 u8 drv_info_size = 0;
2969 u8 phy_status_en = 0;
2973 void *driver_adapter = NULL;
2974 struct halmac_api *halmac_api;
2975 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2977 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2978 return HALMAC_RET_ADAPTER_INVALID;
2980 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2981 return HALMAC_RET_API_INVALID;
2983 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_DRV_INFO);
2985 driver_adapter = halmac_adapter->driver_adapter;
2986 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2988 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2989 "%s ==========>\n", __func__);
2991 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2992 "halmac_cfg_drv_info = %d\n", halmac_drv_info);
2994 switch (halmac_drv_info) {
2995 case HALMAC_DRV_INFO_NONE:
3001 case HALMAC_DRV_INFO_PHY_STATUS:
3007 case HALMAC_DRV_INFO_PHY_SNIFFER:
3008 drv_info_size = 5; /* phy status 4byte, sniffer info 1byte */
3013 case HALMAC_DRV_INFO_PHY_PLCP:
3014 drv_info_size = 6; /* phy status 4byte, plcp header 2byte */
3020 status = HALMAC_RET_SW_CASE_NOT_SUPPORT;
3021 pr_err("%s error = %x\n", __func__, status);
3025 if (halmac_adapter->txff_allocation.rx_fifo_expanding_mode !=
3026 HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
3027 drv_info_size = 0xF;
3029 HALMAC_REG_WRITE_8(halmac_adapter, REG_RX_DRVINFO_SZ, drv_info_size);
3031 halmac_adapter->drv_info_size = drv_info_size;
3033 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_RCR);
3034 value32 = (value32 & (~BIT_APP_PHYSTS));
3035 if (phy_status_en == 1)
3036 value32 = value32 | BIT_APP_PHYSTS;
3037 HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, value32);
3039 value32 = HALMAC_REG_READ_32(halmac_adapter,
3040 REG_WMAC_OPTION_FUNCTION + 4);
3041 value32 = (value32 & (~(BIT(8) | BIT(9))));
3042 if (sniffer_en == 1)
3043 value32 = value32 | BIT(9);
3044 if (plcp_hdr_en == 1)
3045 value32 = value32 | BIT(8);
3046 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
3049 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3050 "%s <==========\n", __func__);
3052 return HALMAC_RET_SUCCESS;
3055 enum halmac_ret_status
3056 halmac_send_bt_coex_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
3057 u32 bt_size, u8 ack)
3059 void *driver_adapter = NULL;
3060 struct halmac_api *halmac_api;
3061 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3063 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3064 return HALMAC_RET_ADAPTER_INVALID;
3066 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3067 return HALMAC_RET_API_INVALID;
3069 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3070 return HALMAC_RET_NO_DLFW;
3072 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_BT_COEX);
3074 driver_adapter = halmac_adapter->driver_adapter;
3075 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3077 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3078 "%s ==========>\n", __func__);
3080 ret_status = halmac_send_bt_coex_cmd_88xx(halmac_adapter, bt_buf,
3083 if (ret_status != HALMAC_RET_SUCCESS) {
3084 pr_err("halmac_send_bt_coex_cmd_88xx Fail = %x!!\n",
3089 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3090 "%s <==========\n", __func__);
3092 return HALMAC_RET_SUCCESS;
3096 * (debug API)halmac_verify_platform_api_88xx() - verify platform api
3097 * @halmac_adapter : the adapter of halmac
3098 * Author : KaiYuan Chang/Ivan Lin
3099 * Return : enum halmac_ret_status
3100 * More details of status code can be found in prototype document
3102 enum halmac_ret_status
3103 halmac_verify_platform_api_88xx(struct halmac_adapter *halmac_adapter)
3105 void *driver_adapter = NULL;
3106 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3108 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3109 return HALMAC_RET_ADAPTER_INVALID;
3111 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3112 return HALMAC_RET_API_INVALID;
3114 halmac_api_record_id_88xx(halmac_adapter,
3115 HALMAC_API_VERIFY_PLATFORM_API);
3117 driver_adapter = halmac_adapter->driver_adapter;
3119 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3120 "%s ==========>\n", __func__);
3122 ret_status = halmac_verify_io_88xx(halmac_adapter);
3124 if (ret_status != HALMAC_RET_SUCCESS)
3127 if (halmac_adapter->txff_allocation.la_mode != HALMAC_LA_MODE_FULL)
3128 ret_status = halmac_verify_send_rsvd_page_88xx(halmac_adapter);
3130 if (ret_status != HALMAC_RET_SUCCESS)
3133 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3134 "%s <==========\n", __func__);
3139 enum halmac_ret_status
3140 halmac_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
3141 u8 *original_h2c, u16 *seq, u8 ack)
3143 void *driver_adapter = NULL;
3144 struct halmac_api *halmac_api;
3145 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3147 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3148 return HALMAC_RET_ADAPTER_INVALID;
3150 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3151 return HALMAC_RET_API_INVALID;
3153 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3154 return HALMAC_RET_NO_DLFW;
3156 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_ORIGINAL_H2C);
3158 driver_adapter = halmac_adapter->driver_adapter;
3159 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3161 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3162 "%s ==========>\n", __func__);
3164 status = halmac_func_send_original_h2c_88xx(halmac_adapter,
3165 original_h2c, seq, ack);
3167 if (status != HALMAC_RET_SUCCESS) {
3168 pr_err("halmac_send_original_h2c FAIL = %x!!\n", status);
3172 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3173 "%s <==========\n", __func__);
3175 return HALMAC_RET_SUCCESS;
3178 enum halmac_ret_status
3179 halmac_timer_2s_88xx(struct halmac_adapter *halmac_adapter)
3181 void *driver_adapter = NULL;
3183 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3184 return HALMAC_RET_ADAPTER_INVALID;
3186 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3187 return HALMAC_RET_API_INVALID;
3189 driver_adapter = halmac_adapter->driver_adapter;
3191 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3192 "%s ==========>\n", __func__);
3194 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3195 "%s <==========\n", __func__);
3197 return HALMAC_RET_SUCCESS;
3201 * halmac_fill_txdesc_check_sum_88xx() - fill in tx desc check sum
3202 * @halmac_adapter : the adapter of halmac
3203 * @cur_desc : tx desc packet
3204 * Author : KaiYuan Chang/Ivan Lin
3205 * Return : enum halmac_ret_status
3206 * More details of status code can be found in prototype document
3208 enum halmac_ret_status
3209 halmac_fill_txdesc_check_sum_88xx(struct halmac_adapter *halmac_adapter,
3213 u16 *data = (u16 *)NULL;
3215 void *driver_adapter = NULL;
3216 struct halmac_api *halmac_api;
3218 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3219 return HALMAC_RET_ADAPTER_INVALID;
3221 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3222 return HALMAC_RET_API_INVALID;
3224 halmac_api_record_id_88xx(halmac_adapter,
3225 HALMAC_API_FILL_TXDESC_CHECKSUM);
3227 driver_adapter = halmac_adapter->driver_adapter;
3228 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3231 pr_err("%s NULL PTR", __func__);
3232 return HALMAC_RET_NULL_POINTER;
3235 SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, 0x0000);
3237 data = (u16 *)(cur_desc);
3239 /* HW clculates only 32byte */
3240 for (i = 0; i < 8; i++)
3241 chk_result ^= (*(data + 2 * i) ^ *(data + (2 * i + 1)));
3243 SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, chk_result);
3245 return HALMAC_RET_SUCCESS;
3249 * halmac_dump_fifo_88xx() - dump fifo data
3250 * @halmac_adapter : the adapter of halmac
3251 * @halmac_fifo_sel : FIFO selection
3252 * @halmac_start_addr : start address of selected FIFO
3253 * @halmac_fifo_dump_size : dump size of selected FIFO
3254 * @fifo_map : FIFO data
3256 * Note : before dump fifo, user need to call halmac_get_fifo_size to
3257 * get fifo size. Then input this size to halmac_dump_fifo.
3259 * Author : Ivan Lin/KaiYuan Chang
3260 * Return : enum halmac_ret_status
3261 * More details of status code can be found in prototype document
3263 enum halmac_ret_status
3264 halmac_dump_fifo_88xx(struct halmac_adapter *halmac_adapter,
3265 enum hal_fifo_sel halmac_fifo_sel, u32 halmac_start_addr,
3266 u32 halmac_fifo_dump_size, u8 *fifo_map)
3268 void *driver_adapter = NULL;
3269 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3271 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3272 return HALMAC_RET_ADAPTER_INVALID;
3274 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3275 return HALMAC_RET_API_INVALID;
3277 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FIFO);
3279 driver_adapter = halmac_adapter->driver_adapter;
3281 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3282 "%s ==========>\n", __func__);
3284 if (halmac_fifo_sel == HAL_FIFO_SEL_TX &&
3285 (halmac_start_addr + halmac_fifo_dump_size) >
3286 halmac_adapter->hw_config_info.tx_fifo_size) {
3287 pr_err("TX fifo dump size is too large\n");
3288 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3291 if (halmac_fifo_sel == HAL_FIFO_SEL_RX &&
3292 (halmac_start_addr + halmac_fifo_dump_size) >
3293 halmac_adapter->hw_config_info.rx_fifo_size) {
3294 pr_err("RX fifo dump size is too large\n");
3295 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3298 if ((halmac_fifo_dump_size & (4 - 1)) != 0) {
3299 pr_err("halmac_fifo_dump_size shall 4byte align\n");
3300 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3304 pr_err("fifo_map address is NULL\n");
3305 return HALMAC_RET_NULL_POINTER;
3308 status = halmac_buffer_read_88xx(halmac_adapter, halmac_start_addr,
3309 halmac_fifo_dump_size, halmac_fifo_sel,
3312 if (status != HALMAC_RET_SUCCESS) {
3313 pr_err("halmac_buffer_read_88xx error = %x\n", status);
3317 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3318 "%s <==========\n", __func__);
3320 return HALMAC_RET_SUCCESS;
3324 * halmac_get_fifo_size_88xx() - get fifo size
3325 * @halmac_adapter : the adapter of halmac
3326 * @halmac_fifo_sel : FIFO selection
3327 * Author : Ivan Lin/KaiYuan Chang
3329 * More details of status code can be found in prototype document
3331 u32 halmac_get_fifo_size_88xx(struct halmac_adapter *halmac_adapter,
3332 enum hal_fifo_sel halmac_fifo_sel)
3336 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3337 return HALMAC_RET_ADAPTER_INVALID;
3339 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3340 return HALMAC_RET_API_INVALID;
3342 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_FIFO_SIZE);
3344 if (halmac_fifo_sel == HAL_FIFO_SEL_TX)
3345 fifo_size = halmac_adapter->hw_config_info.tx_fifo_size;
3346 else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3347 fifo_size = halmac_adapter->hw_config_info.rx_fifo_size;
3348 else if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3350 ((halmac_adapter->hw_config_info.tx_fifo_size >> 7) -
3351 halmac_adapter->txff_allocation.rsvd_pg_bndy)
3353 else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3355 else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3362 * halmac_cfg_txbf_88xx() - enable/disable specific user's txbf
3363 * @halmac_adapter : the adapter of halmac
3364 * @userid : su bfee userid = 0 or 1 to apply TXBF
3365 * @bw : the sounding bandwidth
3366 * @txbf_en : 0: disable TXBF, 1: enable TXBF
3368 * Return : enum halmac_ret_status
3369 * More details of status code can be found in prototype document
3371 enum halmac_ret_status
3372 halmac_cfg_txbf_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
3373 enum halmac_bw bw, u8 txbf_en)
3376 void *driver_adapter = NULL;
3377 struct halmac_api *halmac_api;
3379 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3380 return HALMAC_RET_ADAPTER_INVALID;
3382 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3383 return HALMAC_RET_API_INVALID;
3385 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TXBF);
3387 driver_adapter = halmac_adapter->driver_adapter;
3388 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3393 temp42C |= BIT_R_TXBF0_80M;
3395 temp42C |= BIT_R_TXBF0_40M;
3397 temp42C |= BIT_R_TXBF0_20M;
3400 pr_err("%s invalid TXBF BW setting 0x%x of userid %d\n",
3401 __func__, bw, userid);
3402 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3409 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3410 ~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3411 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL, temp42C);
3415 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3416 ~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3417 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2, temp42C);
3420 pr_err("%s invalid userid %d\n", __func__, userid);
3421 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3424 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3425 "%s, txbf_en = %x <==========\n", __func__,
3428 return HALMAC_RET_SUCCESS;
3432 * halmac_cfg_mumimo_88xx() -config mumimo
3433 * @halmac_adapter : the adapter of halmac
3434 * @cfgmu : parameters to configure MU PPDU Tx/Rx
3436 * Return : enum halmac_ret_status
3437 * More details of status code can be found in prototype document
3439 enum halmac_ret_status
3440 halmac_cfg_mumimo_88xx(struct halmac_adapter *halmac_adapter,
3441 struct halmac_cfg_mumimo_para *cfgmu)
3443 void *driver_adapter = NULL;
3444 struct halmac_api *halmac_api;
3445 u8 i, idx, id0, id1, gid, mu_tab_sel;
3446 u8 mu_tab_valid = 0;
3447 u32 gid_valid[6] = {0};
3450 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3451 return HALMAC_RET_ADAPTER_INVALID;
3453 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3454 return HALMAC_RET_API_INVALID;
3456 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MUMIMO);
3458 driver_adapter = halmac_adapter->driver_adapter;
3459 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3461 if (cfgmu->role == HAL_BFEE) {
3463 temp14C0 = HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
3464 ~BIT_MASK_R_MU_TABLE_VALID;
3465 /*enable MU table 0 and 1, disable MU TX*/
3466 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3467 (temp14C0 | BIT(0) | BIT(1)) & ~(BIT(7)));
3469 /*config GID valid table and user position table*/
3471 HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
3472 ~(BIT(0) | BIT(1) | BIT(2));
3473 for (i = 0; i < 2; i++) {
3474 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
3476 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
3477 cfgmu->given_gid_tab[i]);
3478 HALMAC_REG_WRITE_32(halmac_adapter,
3479 REG_MU_STA_USER_POS_INFO,
3480 cfgmu->given_user_pos[i * 2]);
3481 HALMAC_REG_WRITE_32(halmac_adapter,
3482 REG_MU_STA_USER_POS_INFO + 4,
3483 cfgmu->given_user_pos[i * 2 + 1]);
3487 if (!cfgmu->mu_tx_en) {
3488 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3489 HALMAC_REG_READ_8(halmac_adapter,
3493 driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3494 "%s disable mu tx <==========\n", __func__);
3495 return HALMAC_RET_SUCCESS;
3498 /*Transform BB grouping bitmap[14:0] to MAC GID_valid table*/
3499 for (idx = 0; idx < 15; idx++) {
3501 /*group_bitmap bit0~4, MU_STA0 with MUSTA1~5*/
3503 id1 = (u8)(idx + 1);
3504 } else if (idx < 9) {
3505 /*group_bitmap bit5~8, MU_STA1 with MUSTA2~5*/
3507 id1 = (u8)(idx - 3);
3508 } else if (idx < 12) {
3509 /*group_bitmap bit9~11, MU_STA2 with MUSTA3~5*/
3511 id1 = (u8)(idx - 6);
3512 } else if (idx < 14) {
3513 /*group_bitmap bit12~13, MU_STA3 with MUSTA4~5*/
3515 id1 = (u8)(idx - 8);
3517 /*group_bitmap bit14, MU_STA4 with MUSTA5*/
3519 id1 = (u8)(idx - 9);
3521 if (cfgmu->grouping_bitmap & BIT(idx)) {
3523 gid = (idx << 1) + 1;
3524 gid_valid[id0] |= (BIT(gid));
3525 gid_valid[id1] |= (BIT(gid));
3528 gid_valid[id0] |= (BIT(gid));
3529 gid_valid[id1] |= (BIT(gid));
3532 gid = (idx << 1) + 1;
3533 gid_valid[id0] &= ~(BIT(gid));
3534 gid_valid[id1] &= ~(BIT(gid));
3537 gid_valid[id0] &= ~(BIT(gid));
3538 gid_valid[id1] &= ~(BIT(gid));
3542 /*set MU STA GID valid TABLE*/
3544 HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
3545 ~(BIT(0) | BIT(1) | BIT(2));
3546 for (idx = 0; idx < 6; idx++) {
3547 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
3549 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
3553 /*To validate the sounding successful MU STA and enable MU TX*/
3554 for (i = 0; i < 6; i++) {
3555 if (cfgmu->sounding_sts[i])
3556 mu_tab_valid |= BIT(i);
3558 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3559 mu_tab_valid | BIT(7));
3561 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3562 "%s <==========\n", __func__);
3563 return HALMAC_RET_SUCCESS;
3567 * halmac_cfg_sounding_88xx() - configure general sounding
3568 * @halmac_adapter : the adapter of halmac
3569 * @role : driver's role, BFer or BFee
3570 * @datarate : set ndpa tx rate if driver is BFer, or set csi response rate
3573 * Return : enum halmac_ret_status
3574 * More details of status code can be found in prototype document
3576 enum halmac_ret_status
3577 halmac_cfg_sounding_88xx(struct halmac_adapter *halmac_adapter,
3578 enum halmac_snd_role role,
3579 enum halmac_data_rate datarate)
3581 void *driver_adapter = NULL;
3582 struct halmac_api *halmac_api;
3584 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3585 return HALMAC_RET_ADAPTER_INVALID;
3587 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3588 return HALMAC_RET_API_INVALID;
3590 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_SOUNDING);
3592 driver_adapter = halmac_adapter->driver_adapter;
3593 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3597 HALMAC_REG_WRITE_32(
3598 halmac_adapter, REG_TXBF_CTRL,
3599 HALMAC_REG_READ_32(halmac_adapter, REG_TXBF_CTRL) |
3600 BIT_R_ENABLE_NDPA | BIT_USE_NDPA_PARAMETER |
3601 BIT_R_EN_NDPA_INT | BIT_DIS_NDP_BFEN);
3602 HALMAC_REG_WRITE_8(halmac_adapter, REG_NDPA_RATE, datarate);
3604 halmac_adapter, REG_NDPA_OPT_CTRL,
3605 HALMAC_REG_READ_8(halmac_adapter, REG_NDPA_OPT_CTRL) &
3606 (~(BIT(0) | BIT(1))));
3607 /*service file length 2 bytes; fix non-STA1 csi start offset */
3608 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 1,
3610 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 2, 0x2);
3613 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0xDB);
3614 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 3, 0x50);
3615 /*use ndpa rx rate to decide csi rate*/
3616 HALMAC_REG_WRITE_8(halmac_adapter, REG_BBPSF_CTRL + 3,
3617 HALMAC_OFDM54 | BIT(6));
3618 HALMAC_REG_WRITE_16(
3619 halmac_adapter, REG_RRSR,
3620 HALMAC_REG_READ_16(halmac_adapter, REG_RRSR) |
3622 /*RXFF do not accept BF Rpt Poll, avoid CSI crc error*/
3624 halmac_adapter, REG_RXFLTMAP1,
3625 HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP1) &
3627 /*FWFF do not accept BF Rpt Poll, avoid CSI crc error*/
3629 halmac_adapter, REG_RXFLTMAP4,
3630 HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP4) &
3634 pr_err("%s invalid role\n", __func__);
3635 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3638 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3639 "%s <==========\n", __func__);
3641 return HALMAC_RET_SUCCESS;
3645 * halmac_del_sounding_88xx() - reset general sounding
3646 * @halmac_adapter : the adapter of halmac
3647 * @role : driver's role, BFer or BFee
3649 * Return : enum halmac_ret_status
3650 * More details of status code can be found in prototype document
3652 enum halmac_ret_status
3653 halmac_del_sounding_88xx(struct halmac_adapter *halmac_adapter,
3654 enum halmac_snd_role role)
3656 void *driver_adapter = NULL;
3657 struct halmac_api *halmac_api;
3659 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3660 return HALMAC_RET_ADAPTER_INVALID;
3662 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3663 return HALMAC_RET_API_INVALID;
3665 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEL_SOUNDING);
3667 driver_adapter = halmac_adapter->driver_adapter;
3668 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3672 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXBF_CTRL + 3, 0);
3675 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0);
3678 pr_err("%s invalid role\n", __func__);
3679 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3682 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3683 "%s <==========\n", __func__);
3685 return HALMAC_RET_SUCCESS;
3689 * halmac_su_bfee_entry_init_88xx() - config SU beamformee's registers
3690 * @halmac_adapter : the adapter of halmac
3691 * @userid : SU bfee userid = 0 or 1 to be added
3692 * @paid : partial AID of this bfee
3694 * Return : enum halmac_ret_status
3695 * More details of status code can be found in prototype document
3697 enum halmac_ret_status
3698 halmac_su_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
3702 void *driver_adapter = NULL;
3703 struct halmac_api *halmac_api;
3705 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3706 return HALMAC_RET_ADAPTER_INVALID;
3708 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3709 return HALMAC_RET_API_INVALID;
3711 halmac_api_record_id_88xx(halmac_adapter,
3712 HALMAC_API_SU_BFEE_ENTRY_INIT);
3714 driver_adapter = halmac_adapter->driver_adapter;
3715 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3719 temp42C = HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3720 ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
3721 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3722 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL,
3724 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
3729 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3730 ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
3731 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3732 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2,
3734 HALMAC_REG_WRITE_16(halmac_adapter,
3735 REG_ASSOCIATED_BFMEE_SEL + 2,
3739 pr_err("%s invalid userid %d\n", __func__,
3741 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3744 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3745 "%s <==========\n", __func__);
3747 return HALMAC_RET_SUCCESS;
3751 * halmac_su_bfee_entry_init_88xx() - config SU beamformer's registers
3752 * @halmac_adapter : the adapter of halmac
3753 * @su_bfer_init : parameters to configure SU BFER entry
3755 * Return : enum halmac_ret_status
3756 * More details of status code can be found in prototype document
3758 enum halmac_ret_status
3759 halmac_su_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3760 struct halmac_su_bfer_init_para *su_bfer_init)
3764 void *driver_adapter = NULL;
3765 struct halmac_api *halmac_api;
3767 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3768 return HALMAC_RET_ADAPTER_INVALID;
3770 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3771 return HALMAC_RET_API_INVALID;
3773 halmac_api_record_id_88xx(halmac_adapter,
3774 HALMAC_API_SU_BFER_ENTRY_INIT);
3776 driver_adapter = halmac_adapter->driver_adapter;
3777 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3779 /* mac_address_L = bfer_address.address_l_h.address_low; */
3780 /* mac_address_H = bfer_address.address_l_h.address_high; */
3782 mac_address_L = le32_to_cpu(
3783 su_bfer_init->bfer_address.address_l_h.le_address_low);
3784 mac_address_H = le16_to_cpu(
3785 su_bfer_init->bfer_address.address_l_h.le_address_high);
3787 switch (su_bfer_init->userid) {
3789 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
3791 HALMAC_REG_WRITE_16(halmac_adapter,
3792 REG_ASSOCIATED_BFMER0_INFO + 4,
3794 HALMAC_REG_WRITE_16(halmac_adapter,
3795 REG_ASSOCIATED_BFMER0_INFO + 6,
3796 su_bfer_init->paid);
3797 HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
3798 su_bfer_init->csi_para);
3801 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
3803 HALMAC_REG_WRITE_16(halmac_adapter,
3804 REG_ASSOCIATED_BFMER1_INFO + 4,
3806 HALMAC_REG_WRITE_16(halmac_adapter,
3807 REG_ASSOCIATED_BFMER1_INFO + 6,
3808 su_bfer_init->paid);
3809 HALMAC_REG_WRITE_16(halmac_adapter,
3810 REG_TX_CSI_RPT_PARAM_BW20 + 2,
3811 su_bfer_init->csi_para);
3814 pr_err("%s invalid userid %d\n", __func__,
3815 su_bfer_init->userid);
3816 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3819 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3820 "%s <==========\n", __func__);
3822 return HALMAC_RET_SUCCESS;
3826 * halmac_mu_bfee_entry_init_88xx() - config MU beamformee's registers
3827 * @halmac_adapter : the adapter of halmac
3828 * @mu_bfee_init : parameters to configure MU BFEE entry
3830 * Return : enum halmac_ret_status
3831 * More details of status code can be found in prototype document
3833 enum halmac_ret_status
3834 halmac_mu_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3835 struct halmac_mu_bfee_init_para *mu_bfee_init)
3837 u16 temp168X = 0, temp14C0;
3838 void *driver_adapter = NULL;
3839 struct halmac_api *halmac_api;
3841 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3842 return HALMAC_RET_ADAPTER_INVALID;
3844 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3845 return HALMAC_RET_API_INVALID;
3847 halmac_api_record_id_88xx(halmac_adapter,
3848 HALMAC_API_MU_BFEE_ENTRY_INIT);
3850 driver_adapter = halmac_adapter->driver_adapter;
3851 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3853 temp168X |= mu_bfee_init->paid | BIT(9);
3854 HALMAC_REG_WRITE_16(halmac_adapter, (0x1680 + mu_bfee_init->userid * 2),
3857 temp14C0 = HALMAC_REG_READ_16(halmac_adapter, REG_MU_TX_CTL) &
3858 ~(BIT(8) | BIT(9) | BIT(10));
3859 HALMAC_REG_WRITE_16(halmac_adapter, REG_MU_TX_CTL,
3860 temp14C0 | ((mu_bfee_init->userid - 2) << 8));
3861 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD, 0);
3862 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO,
3863 mu_bfee_init->user_position_l);
3864 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO + 4,
3865 mu_bfee_init->user_position_h);
3867 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3868 "%s <==========\n", __func__);
3870 return HALMAC_RET_SUCCESS;
3874 * halmac_mu_bfer_entry_init_88xx() - config MU beamformer's registers
3875 * @halmac_adapter : the adapter of halmac
3876 * @mu_bfer_init : parameters to configure MU BFER entry
3878 * Return : enum halmac_ret_status
3879 * More details of status code can be found in prototype document
3881 enum halmac_ret_status
3882 halmac_mu_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3883 struct halmac_mu_bfer_init_para *mu_bfer_init)
3888 void *driver_adapter = NULL;
3889 struct halmac_api *halmac_api;
3891 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3892 return HALMAC_RET_ADAPTER_INVALID;
3894 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3895 return HALMAC_RET_API_INVALID;
3897 halmac_api_record_id_88xx(halmac_adapter,
3898 HALMAC_API_MU_BFER_ENTRY_INIT);
3900 driver_adapter = halmac_adapter->driver_adapter;
3901 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3904 le32_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_low);
3906 le16_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_high);
3908 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
3910 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4,
3912 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 6,
3913 mu_bfer_init->paid);
3914 HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
3915 mu_bfer_init->csi_para);
3917 temp1680 = HALMAC_REG_READ_16(halmac_adapter, 0x1680) & 0xC000;
3918 temp1680 |= mu_bfer_init->my_aid | (mu_bfer_init->csi_length_sel << 12);
3919 HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, temp1680);
3921 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3922 "%s <==========\n", __func__);
3924 return HALMAC_RET_SUCCESS;
3928 * halmac_su_bfee_entry_del_88xx() - reset SU beamformee's registers
3929 * @halmac_adapter : the adapter of halmac
3930 * @userid : the SU BFee userid to be deleted
3932 * Return : enum halmac_ret_status
3933 * More details of status code can be found in prototype document
3935 enum halmac_ret_status
3936 halmac_su_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
3938 void *driver_adapter = NULL;
3939 struct halmac_api *halmac_api;
3941 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3942 return HALMAC_RET_ADAPTER_INVALID;
3944 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3945 return HALMAC_RET_API_INVALID;
3947 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFEE_ENTRY_DEL);
3949 driver_adapter = halmac_adapter->driver_adapter;
3950 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3954 HALMAC_REG_WRITE_16(
3955 halmac_adapter, REG_TXBF_CTRL,
3956 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3957 ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
3958 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
3959 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
3963 HALMAC_REG_WRITE_16(
3964 halmac_adapter, REG_TXBF_CTRL + 2,
3965 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3966 ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
3967 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
3968 HALMAC_REG_WRITE_16(halmac_adapter,
3969 REG_ASSOCIATED_BFMEE_SEL + 2, 0);
3972 pr_err("%s invalid userid %d\n", __func__,
3974 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3977 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3978 "%s <==========\n", __func__);
3980 return HALMAC_RET_SUCCESS;
3984 * halmac_su_bfee_entry_del_88xx() - reset SU beamformer's registers
3985 * @halmac_adapter : the adapter of halmac
3986 * @userid : the SU BFer userid to be deleted
3988 * Return : enum halmac_ret_status
3989 * More details of status code can be found in prototype document
3991 enum halmac_ret_status
3992 halmac_su_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
3994 void *driver_adapter = NULL;
3995 struct halmac_api *halmac_api;
3997 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3998 return HALMAC_RET_ADAPTER_INVALID;
4000 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4001 return HALMAC_RET_API_INVALID;
4003 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFER_ENTRY_DEL);
4005 driver_adapter = halmac_adapter->driver_adapter;
4006 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4010 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
4012 HALMAC_REG_WRITE_32(halmac_adapter,
4013 REG_ASSOCIATED_BFMER0_INFO + 4, 0);
4016 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
4018 HALMAC_REG_WRITE_32(halmac_adapter,
4019 REG_ASSOCIATED_BFMER1_INFO + 4, 0);
4022 pr_err("%s invalid userid %d\n", __func__,
4024 return HALMAC_RET_INVALID_SOUNDING_SETTING;
4027 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4028 "%s <==========\n", __func__);
4030 return HALMAC_RET_SUCCESS;
4034 * halmac_mu_bfee_entry_del_88xx() - reset MU beamformee's registers
4035 * @halmac_adapter : the adapter of halmac
4036 * @userid : the MU STA userid to be deleted
4038 * Return : enum halmac_ret_status
4039 * More details of status code can be found in prototype document
4041 enum halmac_ret_status
4042 halmac_mu_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
4044 void *driver_adapter = NULL;
4045 struct halmac_api *halmac_api;
4047 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4048 return HALMAC_RET_ADAPTER_INVALID;
4050 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4051 return HALMAC_RET_API_INVALID;
4053 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFEE_ENTRY_DEL);
4055 driver_adapter = halmac_adapter->driver_adapter;
4056 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4058 HALMAC_REG_WRITE_16(halmac_adapter, 0x1680 + userid * 2, 0);
4059 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
4060 HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
4061 ~(BIT(userid - 2)));
4063 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4064 "%s <==========\n", __func__);
4066 return HALMAC_RET_SUCCESS;
4070 * halmac_mu_bfer_entry_del_88xx() -reset MU beamformer's registers
4071 * @halmac_adapter : the adapter of halmac
4073 * Return : enum halmac_ret_status
4074 * More details of status code can be found in prototype document
4076 enum halmac_ret_status
4077 halmac_mu_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter)
4079 void *driver_adapter = NULL;
4080 struct halmac_api *halmac_api;
4082 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4083 return HALMAC_RET_ADAPTER_INVALID;
4085 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4086 return HALMAC_RET_API_INVALID;
4088 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFER_ENTRY_DEL);
4090 driver_adapter = halmac_adapter->driver_adapter;
4091 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4093 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO, 0);
4094 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4, 0);
4095 HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, 0);
4096 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL, 0);
4098 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4099 "%s <==========\n", __func__);
4101 return HALMAC_RET_SUCCESS;
4105 * halmac_add_ch_info_88xx() -add channel information
4106 * @halmac_adapter : the adapter of halmac
4107 * @ch_info : channel information
4108 * Author : KaiYuan Chang/Ivan Lin
4109 * Return : enum halmac_ret_status
4110 * More details of status code can be found in prototype document
4112 enum halmac_ret_status
4113 halmac_add_ch_info_88xx(struct halmac_adapter *halmac_adapter,
4114 struct halmac_ch_info *ch_info)
4116 void *driver_adapter = NULL;
4117 struct halmac_cs_info *ch_sw_info;
4118 enum halmac_scan_cmd_construct_state state_scan;
4120 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4121 return HALMAC_RET_ADAPTER_INVALID;
4123 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4124 return HALMAC_RET_API_INVALID;
4126 driver_adapter = halmac_adapter->driver_adapter;
4127 ch_sw_info = &halmac_adapter->ch_sw_info;
4129 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4130 "[TRACE]%s ==========>\n", __func__);
4132 if (halmac_adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
4133 pr_err("[ERR]%s: gen_info is not send to FW!!!!\n", __func__);
4134 return HALMAC_RET_GEN_INFO_NOT_SENT;
4137 state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
4138 if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED &&
4139 state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4140 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
4141 "[WARN]Scan machine fail(add ch info)...\n");
4142 return HALMAC_RET_ERROR_STATE;
4145 if (!ch_sw_info->ch_info_buf) {
4146 ch_sw_info->ch_info_buf =
4147 kzalloc(HALMAC_EXTRA_INFO_BUFF_SIZE_88XX, GFP_KERNEL);
4148 if (!ch_sw_info->ch_info_buf)
4149 return HALMAC_RET_NULL_POINTER;
4150 ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf;
4151 ch_sw_info->buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
4152 ch_sw_info->avai_buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
4153 ch_sw_info->total_size = 0;
4154 ch_sw_info->extra_info_en = 0;
4155 ch_sw_info->ch_num = 0;
4158 if (ch_sw_info->extra_info_en == 1) {
4159 pr_err("[ERR]%s: construct sequence wrong!!\n", __func__);
4160 return HALMAC_RET_CH_SW_SEQ_WRONG;
4163 if (ch_sw_info->avai_buf_size < 4) {
4164 pr_err("[ERR]%s: no available buffer!!\n", __func__);
4165 return HALMAC_RET_CH_SW_NO_BUF;
4168 if (halmac_transition_scan_state_88xx(
4169 halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
4171 return HALMAC_RET_ERROR_STATE;
4173 CHANNEL_INFO_SET_CHANNEL(ch_sw_info->ch_info_buf_w, ch_info->channel);
4174 CHANNEL_INFO_SET_PRI_CH_IDX(ch_sw_info->ch_info_buf_w,
4175 ch_info->pri_ch_idx);
4176 CHANNEL_INFO_SET_BANDWIDTH(ch_sw_info->ch_info_buf_w, ch_info->bw);
4177 CHANNEL_INFO_SET_TIMEOUT(ch_sw_info->ch_info_buf_w, ch_info->timeout);
4178 CHANNEL_INFO_SET_ACTION_ID(ch_sw_info->ch_info_buf_w,
4179 ch_info->action_id);
4180 CHANNEL_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
4181 ch_info->extra_info);
4183 ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size - 4;
4184 ch_sw_info->total_size = ch_sw_info->total_size + 4;
4185 ch_sw_info->ch_num++;
4186 ch_sw_info->extra_info_en = ch_info->extra_info;
4187 ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w + 4;
4189 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4190 "[TRACE]%s <==========\n", __func__);
4192 return HALMAC_RET_SUCCESS;
4196 * halmac_add_extra_ch_info_88xx() -add extra channel information
4197 * @halmac_adapter : the adapter of halmac
4198 * @ch_extra_info : extra channel information
4199 * Author : KaiYuan Chang/Ivan Lin
4200 * Return : enum halmac_ret_status
4201 * More details of status code can be found in prototype document
4203 enum halmac_ret_status
4204 halmac_add_extra_ch_info_88xx(struct halmac_adapter *halmac_adapter,
4205 struct halmac_ch_extra_info *ch_extra_info)
4207 void *driver_adapter = NULL;
4208 struct halmac_cs_info *ch_sw_info;
4210 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4211 return HALMAC_RET_ADAPTER_INVALID;
4213 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4214 return HALMAC_RET_API_INVALID;
4216 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ADD_EXTRA_CH_INFO);
4218 driver_adapter = halmac_adapter->driver_adapter;
4219 ch_sw_info = &halmac_adapter->ch_sw_info;
4221 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4222 "%s ==========>\n", __func__);
4224 if (!ch_sw_info->ch_info_buf) {
4225 pr_err("%s: NULL==ch_sw_info->ch_info_buf!!\n", __func__);
4226 return HALMAC_RET_CH_SW_SEQ_WRONG;
4229 if (ch_sw_info->extra_info_en == 0) {
4230 pr_err("%s: construct sequence wrong!!\n", __func__);
4231 return HALMAC_RET_CH_SW_SEQ_WRONG;
4234 if (ch_sw_info->avai_buf_size <
4235 (u32)(ch_extra_info->extra_info_size + 2)) {
4236 /* +2: ch_extra_info_id, ch_extra_info, ch_extra_info_size
4239 pr_err("%s: no available buffer!!\n", __func__);
4240 return HALMAC_RET_CH_SW_NO_BUF;
4243 if (halmac_query_scan_curr_state_88xx(halmac_adapter) !=
4244 HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4245 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4246 "Scan machine fail(add extra ch info)...\n");
4247 return HALMAC_RET_ERROR_STATE;
4250 if (halmac_transition_scan_state_88xx(
4251 halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
4253 return HALMAC_RET_ERROR_STATE;
4255 CH_EXTRA_INFO_SET_CH_EXTRA_INFO_ID(ch_sw_info->ch_info_buf_w,
4256 ch_extra_info->extra_action_id);
4257 CH_EXTRA_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
4258 ch_extra_info->extra_info);
4259 CH_EXTRA_INFO_SET_CH_EXTRA_INFO_SIZE(ch_sw_info->ch_info_buf_w,
4260 ch_extra_info->extra_info_size);
4261 memcpy(ch_sw_info->ch_info_buf_w + 2, ch_extra_info->extra_info_data,
4262 ch_extra_info->extra_info_size);
4264 ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size -
4265 (2 + ch_extra_info->extra_info_size);
4266 ch_sw_info->total_size =
4267 ch_sw_info->total_size + (2 + ch_extra_info->extra_info_size);
4268 ch_sw_info->extra_info_en = ch_extra_info->extra_info;
4269 ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w +
4270 (2 + ch_extra_info->extra_info_size);
4272 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4273 "%s <==========\n", __func__);
4275 return HALMAC_RET_SUCCESS;
4279 * halmac_ctrl_ch_switch_88xx() -send channel switch cmd
4280 * @halmac_adapter : the adapter of halmac
4281 * @cs_option : channel switch config
4282 * Author : KaiYuan Chang/Ivan Lin
4283 * Return : enum halmac_ret_status
4284 * More details of status code can be found in prototype document
4286 enum halmac_ret_status
4287 halmac_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
4288 struct halmac_ch_switch_option *cs_option)
4290 void *driver_adapter = NULL;
4291 struct halmac_api *halmac_api;
4292 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4293 enum halmac_scan_cmd_construct_state state_scan;
4294 enum halmac_cmd_process_status *process_status =
4295 &halmac_adapter->halmac_state.scan_state_set.process_status;
4297 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4298 return HALMAC_RET_ADAPTER_INVALID;
4300 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4301 return HALMAC_RET_API_INVALID;
4303 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4304 return HALMAC_RET_NO_DLFW;
4306 if (halmac_adapter->fw_version.h2c_version < 4)
4307 return HALMAC_RET_FW_NO_SUPPORT;
4309 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_CH_SWITCH);
4311 driver_adapter = halmac_adapter->driver_adapter;
4312 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4314 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4315 "%s cs_option->switch_en = %d==========>\n", __func__,
4316 cs_option->switch_en);
4318 if (!cs_option->switch_en)
4319 *process_status = HALMAC_CMD_PROCESS_IDLE;
4321 if (*process_status == HALMAC_CMD_PROCESS_SENDING ||
4322 *process_status == HALMAC_CMD_PROCESS_RCVD) {
4323 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4324 "Wait event(ctrl ch switch)...\n");
4325 return HALMAC_RET_BUSY_STATE;
4328 state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
4329 if (cs_option->switch_en) {
4330 if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4331 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
4333 "%s(on) invalid in state %x\n",
4334 __func__, state_scan);
4335 return HALMAC_RET_ERROR_STATE;
4338 if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
4340 driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4341 "%s(off) invalid in state %x\n", __func__,
4343 return HALMAC_RET_ERROR_STATE;
4347 status = halmac_func_ctrl_ch_switch_88xx(halmac_adapter, cs_option);
4349 if (status != HALMAC_RET_SUCCESS) {
4350 pr_err("halmac_ctrl_ch_switch FAIL = %x!!\n", status);
4354 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4355 "%s <==========\n", __func__);
4357 return HALMAC_RET_SUCCESS;
4361 * halmac_clear_ch_info_88xx() -clear channel information
4362 * @halmac_adapter : the adapter of halmac
4363 * Author : KaiYuan Chang/Ivan Lin
4364 * Return : enum halmac_ret_status
4365 * More details of status code can be found in prototype document
4367 enum halmac_ret_status
4368 halmac_clear_ch_info_88xx(struct halmac_adapter *halmac_adapter)
4370 void *driver_adapter = NULL;
4371 struct halmac_api *halmac_api;
4373 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4374 return HALMAC_RET_ADAPTER_INVALID;
4376 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4377 return HALMAC_RET_API_INVALID;
4379 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CLEAR_CH_INFO);
4381 driver_adapter = halmac_adapter->driver_adapter;
4382 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4384 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4385 "%s ==========>\n", __func__);
4387 if (halmac_query_scan_curr_state_88xx(halmac_adapter) ==
4388 HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
4389 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4390 "Scan machine fail(clear ch info)...\n");
4391 return HALMAC_RET_ERROR_STATE;
4394 if (halmac_transition_scan_state_88xx(
4395 halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) !=
4397 return HALMAC_RET_ERROR_STATE;
4399 kfree(halmac_adapter->ch_sw_info.ch_info_buf);
4400 halmac_adapter->ch_sw_info.ch_info_buf = NULL;
4401 halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
4402 halmac_adapter->ch_sw_info.extra_info_en = 0;
4403 halmac_adapter->ch_sw_info.buf_size = 0;
4404 halmac_adapter->ch_sw_info.avai_buf_size = 0;
4405 halmac_adapter->ch_sw_info.total_size = 0;
4406 halmac_adapter->ch_sw_info.ch_num = 0;
4408 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4409 "%s <==========\n", __func__);
4411 return HALMAC_RET_SUCCESS;
4414 enum halmac_ret_status halmac_p2pps_88xx(struct halmac_adapter *halmac_adapter,
4415 struct halmac_p2pps *p2p_ps)
4417 void *driver_adapter = NULL;
4418 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4420 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4421 return HALMAC_RET_ADAPTER_INVALID;
4423 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4424 return HALMAC_RET_API_INVALID;
4426 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4427 return HALMAC_RET_NO_DLFW;
4429 if (halmac_adapter->fw_version.h2c_version < 6)
4430 return HALMAC_RET_FW_NO_SUPPORT;
4432 driver_adapter = halmac_adapter->driver_adapter;
4434 status = halmac_func_p2pps_88xx(halmac_adapter, p2p_ps);
4436 if (status != HALMAC_RET_SUCCESS) {
4437 pr_err("[ERR]halmac_p2pps FAIL = %x!!\n", status);
4441 return HALMAC_RET_SUCCESS;
4444 enum halmac_ret_status
4445 halmac_func_p2pps_88xx(struct halmac_adapter *halmac_adapter,
4446 struct halmac_p2pps *p2p_ps)
4448 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4449 u16 h2c_seq_mum = 0;
4450 void *driver_adapter = halmac_adapter->driver_adapter;
4451 struct halmac_api *halmac_api;
4452 struct halmac_h2c_header_info h2c_header_info;
4453 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4455 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4456 "[TRACE]halmac_p2pps !!\n");
4458 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4460 P2PPS_SET_OFFLOAD_EN(h2c_buff, p2p_ps->offload_en);
4461 P2PPS_SET_ROLE(h2c_buff, p2p_ps->role);
4462 P2PPS_SET_CTWINDOW_EN(h2c_buff, p2p_ps->ctwindow_en);
4463 P2PPS_SET_NOA_EN(h2c_buff, p2p_ps->noa_en);
4464 P2PPS_SET_NOA_SEL(h2c_buff, p2p_ps->noa_sel);
4465 P2PPS_SET_ALLSTASLEEP(h2c_buff, p2p_ps->all_sta_sleep);
4466 P2PPS_SET_DISCOVERY(h2c_buff, p2p_ps->discovery);
4467 P2PPS_SET_P2P_PORT_ID(h2c_buff, p2p_ps->p2p_port_id);
4468 P2PPS_SET_P2P_GROUP(h2c_buff, p2p_ps->p2p_group);
4469 P2PPS_SET_P2P_MACID(h2c_buff, p2p_ps->p2p_macid);
4471 P2PPS_SET_CTWINDOW_LENGTH(h2c_buff, p2p_ps->ctwindow_length);
4473 P2PPS_SET_NOA_DURATION_PARA(h2c_buff, p2p_ps->noa_duration_para);
4474 P2PPS_SET_NOA_INTERVAL_PARA(h2c_buff, p2p_ps->noa_interval_para);
4475 P2PPS_SET_NOA_START_TIME_PARA(h2c_buff, p2p_ps->noa_start_time_para);
4476 P2PPS_SET_NOA_COUNT_PARA(h2c_buff, p2p_ps->noa_count_para);
4478 h2c_header_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
4479 h2c_header_info.content_size = 24;
4480 h2c_header_info.ack = false;
4481 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4482 &h2c_header_info, &h2c_seq_mum);
4484 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4485 HALMAC_H2C_CMD_SIZE_88XX, false);
4487 if (status != HALMAC_RET_SUCCESS)
4488 pr_err("[ERR]halmac_send_h2c_p2pps_88xx Fail = %x!!\n", status);
4494 * halmac_send_general_info_88xx() -send general information to FW
4495 * @halmac_adapter : the adapter of halmac
4496 * @general_info : general information
4497 * Author : KaiYuan Chang/Ivan Lin
4498 * Return : enum halmac_ret_status
4499 * More details of status code can be found in prototype document
4501 enum halmac_ret_status
4502 halmac_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
4503 struct halmac_general_info *general_info)
4505 void *driver_adapter = NULL;
4506 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4508 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4509 return HALMAC_RET_ADAPTER_INVALID;
4511 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4512 return HALMAC_RET_API_INVALID;
4514 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4515 return HALMAC_RET_NO_DLFW;
4517 if (halmac_adapter->fw_version.h2c_version < 4)
4518 return HALMAC_RET_FW_NO_SUPPORT;
4520 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_GENERAL_INFO);
4522 driver_adapter = halmac_adapter->driver_adapter;
4524 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4525 "%s ==========>\n", __func__);
4527 if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
4528 pr_err("%s Fail due to DLFW NONE!!\n", __func__);
4529 return HALMAC_RET_DLFW_FAIL;
4532 status = halmac_func_send_general_info_88xx(halmac_adapter,
4535 if (status != HALMAC_RET_SUCCESS) {
4536 pr_err("halmac_send_general_info error = %x\n", status);
4540 if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_DONE)
4541 halmac_adapter->halmac_state.dlfw_state = HALMAC_GEN_INFO_SENT;
4543 halmac_adapter->gen_info_valid = true;
4544 memcpy(&halmac_adapter->general_info, general_info,
4545 sizeof(struct halmac_general_info));
4547 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4548 "%s <==========\n", __func__);
4550 return HALMAC_RET_SUCCESS;
4554 * halmac_start_iqk_88xx() -trigger FW IQK
4555 * @halmac_adapter : the adapter of halmac
4556 * @iqk_para : IQK parameter
4557 * Author : KaiYuan Chang/Ivan Lin
4558 * Return : enum halmac_ret_status
4559 * More details of status code can be found in prototype document
4561 enum halmac_ret_status
4562 halmac_start_iqk_88xx(struct halmac_adapter *halmac_adapter,
4563 struct halmac_iqk_para_ *iqk_para)
4565 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4566 u16 h2c_seq_num = 0;
4567 void *driver_adapter = NULL;
4568 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4569 struct halmac_h2c_header_info h2c_header_info;
4570 enum halmac_cmd_process_status *process_status =
4571 &halmac_adapter->halmac_state.iqk_set.process_status;
4573 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4574 return HALMAC_RET_ADAPTER_INVALID;
4576 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4577 return HALMAC_RET_API_INVALID;
4579 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4580 return HALMAC_RET_NO_DLFW;
4582 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_START_IQK);
4584 driver_adapter = halmac_adapter->driver_adapter;
4586 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4587 "%s ==========>\n", __func__);
4589 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
4590 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4591 "Wait event(iqk)...\n");
4592 return HALMAC_RET_BUSY_STATE;
4595 *process_status = HALMAC_CMD_PROCESS_SENDING;
4597 IQK_SET_CLEAR(h2c_buff, iqk_para->clear);
4598 IQK_SET_SEGMENT_IQK(h2c_buff, iqk_para->segment_iqk);
4600 h2c_header_info.sub_cmd_id = SUB_CMD_ID_IQK;
4601 h2c_header_info.content_size = 1;
4602 h2c_header_info.ack = true;
4603 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4604 &h2c_header_info, &h2c_seq_num);
4606 halmac_adapter->halmac_state.iqk_set.seq_num = h2c_seq_num;
4608 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4609 HALMAC_H2C_CMD_SIZE_88XX, true);
4611 if (status != HALMAC_RET_SUCCESS) {
4612 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
4616 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4617 "%s <==========\n", __func__);
4619 return HALMAC_RET_SUCCESS;
4623 * halmac_ctrl_pwr_tracking_88xx() -trigger FW power tracking
4624 * @halmac_adapter : the adapter of halmac
4625 * @pwr_tracking_opt : power tracking option
4626 * Author : KaiYuan Chang/Ivan Lin
4627 * Return : enum halmac_ret_status
4628 * More details of status code can be found in prototype document
4630 enum halmac_ret_status halmac_ctrl_pwr_tracking_88xx(
4631 struct halmac_adapter *halmac_adapter,
4632 struct halmac_pwr_tracking_option *pwr_tracking_opt)
4634 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4635 u16 h2c_seq_mum = 0;
4636 void *driver_adapter = NULL;
4637 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4638 struct halmac_h2c_header_info h2c_header_info;
4639 enum halmac_cmd_process_status *process_status =
4640 &halmac_adapter->halmac_state.power_tracking_set.process_status;
4642 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4643 return HALMAC_RET_ADAPTER_INVALID;
4645 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4646 return HALMAC_RET_API_INVALID;
4648 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4649 return HALMAC_RET_NO_DLFW;
4651 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_PWR_TRACKING);
4653 driver_adapter = halmac_adapter->driver_adapter;
4655 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4656 "halmac_start_iqk_88xx ==========>\n");
4658 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
4659 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4660 "Wait event(pwr tracking)...\n");
4661 return HALMAC_RET_BUSY_STATE;
4664 *process_status = HALMAC_CMD_PROCESS_SENDING;
4666 POWER_TRACKING_SET_TYPE(h2c_buff, pwr_tracking_opt->type);
4667 POWER_TRACKING_SET_BBSWING_INDEX(h2c_buff,
4668 pwr_tracking_opt->bbswing_index);
4669 POWER_TRACKING_SET_ENABLE_A(
4671 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A].enable);
4672 POWER_TRACKING_SET_TX_PWR_INDEX_A(
4673 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4675 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_A(
4676 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4677 .pwr_tracking_offset_value);
4678 POWER_TRACKING_SET_TSSI_VALUE_A(
4679 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4681 POWER_TRACKING_SET_ENABLE_B(
4683 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B].enable);
4684 POWER_TRACKING_SET_TX_PWR_INDEX_B(
4685 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4687 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_B(
4688 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4689 .pwr_tracking_offset_value);
4690 POWER_TRACKING_SET_TSSI_VALUE_B(
4691 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4693 POWER_TRACKING_SET_ENABLE_C(
4695 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C].enable);
4696 POWER_TRACKING_SET_TX_PWR_INDEX_C(
4697 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4699 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_C(
4700 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4701 .pwr_tracking_offset_value);
4702 POWER_TRACKING_SET_TSSI_VALUE_C(
4703 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4705 POWER_TRACKING_SET_ENABLE_D(
4707 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D].enable);
4708 POWER_TRACKING_SET_TX_PWR_INDEX_D(
4709 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4711 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_D(
4712 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4713 .pwr_tracking_offset_value);
4714 POWER_TRACKING_SET_TSSI_VALUE_D(
4715 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4718 h2c_header_info.sub_cmd_id = SUB_CMD_ID_POWER_TRACKING;
4719 h2c_header_info.content_size = 20;
4720 h2c_header_info.ack = true;
4721 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4722 &h2c_header_info, &h2c_seq_mum);
4724 halmac_adapter->halmac_state.power_tracking_set.seq_num = h2c_seq_mum;
4726 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4727 HALMAC_H2C_CMD_SIZE_88XX, true);
4729 if (status != HALMAC_RET_SUCCESS) {
4730 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
4734 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4735 "halmac_start_iqk_88xx <==========\n");
4737 return HALMAC_RET_SUCCESS;
4741 * halmac_query_status_88xx() -query the offload feature status
4742 * @halmac_adapter : the adapter of halmac
4743 * @feature_id : feature_id
4744 * @process_status : feature_status
4745 * @data : data buffer
4749 * If user wants to know the data size, use can allocate zero
4750 * size buffer first. If this size less than the data size, halmac
4751 * will return HALMAC_RET_BUFFER_TOO_SMALL. User need to
4752 * re-allocate data buffer with correct data size.
4754 * Author : Ivan Lin/KaiYuan Chang
4755 * Return : enum halmac_ret_status
4756 * More details of status code can be found in prototype document
4758 enum halmac_ret_status
4759 halmac_query_status_88xx(struct halmac_adapter *halmac_adapter,
4760 enum halmac_feature_id feature_id,
4761 enum halmac_cmd_process_status *process_status,
4762 u8 *data, u32 *size)
4764 void *driver_adapter = NULL;
4765 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4767 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4768 return HALMAC_RET_ADAPTER_INVALID;
4770 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4771 return HALMAC_RET_API_INVALID;
4773 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_QUERY_STATE);
4775 driver_adapter = halmac_adapter->driver_adapter;
4777 if (!process_status) {
4778 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4779 "null pointer!!\n");
4780 return HALMAC_RET_NULL_POINTER;
4783 switch (feature_id) {
4784 case HALMAC_FEATURE_CFG_PARA:
4785 status = halmac_query_cfg_para_status_88xx(
4786 halmac_adapter, process_status, data, size);
4788 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
4789 status = halmac_query_dump_physical_efuse_status_88xx(
4790 halmac_adapter, process_status, data, size);
4792 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
4793 status = halmac_query_dump_logical_efuse_status_88xx(
4794 halmac_adapter, process_status, data, size);
4796 case HALMAC_FEATURE_CHANNEL_SWITCH:
4797 status = halmac_query_channel_switch_status_88xx(
4798 halmac_adapter, process_status, data, size);
4800 case HALMAC_FEATURE_UPDATE_PACKET:
4801 status = halmac_query_update_packet_status_88xx(
4802 halmac_adapter, process_status, data, size);
4804 case HALMAC_FEATURE_IQK:
4805 status = halmac_query_iqk_status_88xx(
4806 halmac_adapter, process_status, data, size);
4808 case HALMAC_FEATURE_POWER_TRACKING:
4809 status = halmac_query_power_tracking_status_88xx(
4810 halmac_adapter, process_status, data, size);
4812 case HALMAC_FEATURE_PSD:
4813 status = halmac_query_psd_status_88xx(
4814 halmac_adapter, process_status, data, size);
4817 pr_err("%s invalid feature id %d\n", __func__,
4819 return HALMAC_RET_INVALID_FEATURE_ID;
4826 * halmac_reset_feature_88xx() -reset async api cmd status
4827 * @halmac_adapter : the adapter of halmac
4828 * @feature_id : feature_id
4829 * Author : Ivan Lin/KaiYuan Chang
4830 * Return : enum halmac_ret_status.
4831 * More details of status code can be found in prototype document
4833 enum halmac_ret_status
4834 halmac_reset_feature_88xx(struct halmac_adapter *halmac_adapter,
4835 enum halmac_feature_id feature_id)
4837 void *driver_adapter = NULL;
4838 struct halmac_state *state = &halmac_adapter->halmac_state;
4840 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4841 return HALMAC_RET_ADAPTER_INVALID;
4843 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4844 return HALMAC_RET_API_INVALID;
4846 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RESET_FEATURE);
4848 driver_adapter = halmac_adapter->driver_adapter;
4850 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4851 "%s ==========>\n", __func__);
4853 switch (feature_id) {
4854 case HALMAC_FEATURE_CFG_PARA:
4855 state->cfg_para_state_set.process_status =
4856 HALMAC_CMD_PROCESS_IDLE;
4857 state->cfg_para_state_set.cfg_para_cmd_construct_state =
4858 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
4860 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
4861 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
4862 state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4863 state->efuse_state_set.efuse_cmd_construct_state =
4864 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
4866 case HALMAC_FEATURE_CHANNEL_SWITCH:
4867 state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4868 state->scan_state_set.scan_cmd_construct_state =
4869 HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
4871 case HALMAC_FEATURE_UPDATE_PACKET:
4872 state->update_packet_set.process_status =
4873 HALMAC_CMD_PROCESS_IDLE;
4875 case HALMAC_FEATURE_ALL:
4876 state->cfg_para_state_set.process_status =
4877 HALMAC_CMD_PROCESS_IDLE;
4878 state->cfg_para_state_set.cfg_para_cmd_construct_state =
4879 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
4880 state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4881 state->efuse_state_set.efuse_cmd_construct_state =
4882 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
4883 state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4884 state->scan_state_set.scan_cmd_construct_state =
4885 HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
4886 state->update_packet_set.process_status =
4887 HALMAC_CMD_PROCESS_IDLE;
4890 pr_err("%s invalid feature id %d\n", __func__,
4892 return HALMAC_RET_INVALID_FEATURE_ID;
4895 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4896 "%s <==========\n", __func__);
4898 return HALMAC_RET_SUCCESS;
4902 * halmac_check_fw_status_88xx() -check fw status
4903 * @halmac_adapter : the adapter of halmac
4904 * @fw_status : fw status
4905 * Author : KaiYuan Chang/Ivan Lin
4906 * Return : enum halmac_ret_status
4907 * More details of status code can be found in prototype document
4909 enum halmac_ret_status
4910 halmac_check_fw_status_88xx(struct halmac_adapter *halmac_adapter,
4913 u32 value32 = 0, value32_backup = 0, i = 0;
4914 void *driver_adapter = NULL;
4915 struct halmac_api *halmac_api;
4916 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4918 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4919 return HALMAC_RET_ADAPTER_INVALID;
4921 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4922 return HALMAC_RET_API_INVALID;
4924 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CHECK_FW_STATUS);
4926 driver_adapter = halmac_adapter->driver_adapter;
4927 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4929 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4930 "%s ==========>\n", __func__);
4932 value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG6);
4935 pr_err("halmac_check_fw_status REG_FW_DBG6 !=0\n");
4940 value32_backup = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
4942 for (i = 0; i <= 10; i++) {
4943 value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
4944 if (value32_backup != value32)
4948 pr_err("halmac_check_fw_status Polling FW PC fail\n");
4954 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4955 "%s <==========\n", __func__);
4960 enum halmac_ret_status
4961 halmac_dump_fw_dmem_88xx(struct halmac_adapter *halmac_adapter, u8 *dmem,
4964 void *driver_adapter = NULL;
4965 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4967 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4968 return HALMAC_RET_ADAPTER_INVALID;
4970 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4971 return HALMAC_RET_API_INVALID;
4973 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FW_DMEM);
4975 driver_adapter = halmac_adapter->driver_adapter;
4977 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4978 "%s ==========>\n", __func__);
4980 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4981 "%s <==========\n", __func__);
4987 * halmac_cfg_max_dl_size_88xx() - config max download FW size
4988 * @halmac_adapter : the adapter of halmac
4989 * @size : max download fw size
4991 * Halmac uses this setting to set max packet size for
4993 * If user has not called this API, halmac use default
4994 * setting for download FW
4995 * Note1 : size need multiple of 2
4996 * Note2 : max size is 31K
4998 * Author : Ivan Lin/KaiYuan Chang
4999 * Return : enum halmac_ret_status
5000 * More details of status code can be found in prototype document
5002 enum halmac_ret_status
5003 halmac_cfg_max_dl_size_88xx(struct halmac_adapter *halmac_adapter, u32 size)
5005 void *driver_adapter = NULL;
5007 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5008 return HALMAC_RET_ADAPTER_INVALID;
5010 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5011 return HALMAC_RET_API_INVALID;
5013 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MAX_DL_SIZE);
5015 driver_adapter = halmac_adapter->driver_adapter;
5017 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5018 "%s ==========>\n", __func__);
5020 if (size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX_88XX) {
5021 pr_err("size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX!\n");
5022 return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
5025 if ((size & (2 - 1)) != 0) {
5026 pr_err("size is not power of 2!\n");
5027 return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
5030 halmac_adapter->max_download_size = size;
5032 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5033 "Cfg max size is : %X\n", size);
5035 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5036 "%s <==========\n", __func__);
5038 return HALMAC_RET_SUCCESS;
5042 * halmac_psd_88xx() - trigger fw psd
5043 * @halmac_adapter : the adapter of halmac
5044 * @start_psd : start PSD
5045 * @end_psd : end PSD
5046 * Author : KaiYuan Chang/Ivan Lin
5047 * Return : enum halmac_ret_status
5048 * More details of status code can be found in prototype document
5050 enum halmac_ret_status halmac_psd_88xx(struct halmac_adapter *halmac_adapter,
5051 u16 start_psd, u16 end_psd)
5053 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
5054 u16 h2c_seq_mum = 0;
5055 void *driver_adapter = NULL;
5056 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
5057 struct halmac_h2c_header_info h2c_header_info;
5058 enum halmac_cmd_process_status *process_status =
5059 &halmac_adapter->halmac_state.psd_set.process_status;
5061 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5062 return HALMAC_RET_ADAPTER_INVALID;
5064 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5065 return HALMAC_RET_API_INVALID;
5067 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5068 return HALMAC_RET_NO_DLFW;
5070 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PSD);
5072 driver_adapter = halmac_adapter->driver_adapter;
5074 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5075 "%s ==========>\n", __func__);
5077 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
5078 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5079 "Wait event(psd)...\n");
5080 return HALMAC_RET_BUSY_STATE;
5083 kfree(halmac_adapter->halmac_state.psd_set.data);
5084 halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
5086 halmac_adapter->halmac_state.psd_set.data_size = 0;
5087 halmac_adapter->halmac_state.psd_set.segment_size = 0;
5089 *process_status = HALMAC_CMD_PROCESS_SENDING;
5091 PSD_SET_START_PSD(h2c_buff, start_psd);
5092 PSD_SET_END_PSD(h2c_buff, end_psd);
5094 h2c_header_info.sub_cmd_id = SUB_CMD_ID_PSD;
5095 h2c_header_info.content_size = 4;
5096 h2c_header_info.ack = true;
5097 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
5098 &h2c_header_info, &h2c_seq_mum);
5100 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
5101 HALMAC_H2C_CMD_SIZE_88XX, true);
5103 if (status != HALMAC_RET_SUCCESS) {
5104 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
5108 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5109 "%s <==========\n", __func__);
5111 return HALMAC_RET_SUCCESS;
5115 * halmac_cfg_la_mode_88xx() - config la mode
5116 * @halmac_adapter : the adapter of halmac
5118 * disable : no TXFF space reserved for LA debug
5119 * partial : partial TXFF space is reserved for LA debug
5120 * full : all TXFF space is reserved for LA debug
5121 * Author : KaiYuan Chang
5122 * Return : enum halmac_ret_status
5123 * More details of status code can be found in prototype document
5125 enum halmac_ret_status
5126 halmac_cfg_la_mode_88xx(struct halmac_adapter *halmac_adapter,
5127 enum halmac_la_mode la_mode)
5129 void *driver_adapter = NULL;
5131 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5132 return HALMAC_RET_ADAPTER_INVALID;
5134 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5135 return HALMAC_RET_API_INVALID;
5137 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_LA_MODE);
5139 driver_adapter = halmac_adapter->driver_adapter;
5141 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5142 "%s ==========>la_mode = %d\n", __func__,
5145 halmac_adapter->txff_allocation.la_mode = la_mode;
5147 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5148 "%s <==========\n", __func__);
5150 return HALMAC_RET_SUCCESS;
5154 * halmac_cfg_rx_fifo_expanding_mode_88xx() - rx fifo expanding
5155 * @halmac_adapter : the adapter of halmac
5157 * disable : normal mode
5158 * 1 block : Rx FIFO + 1 FIFO block; Tx fifo - 1 FIFO block
5159 * 2 block : Rx FIFO + 2 FIFO block; Tx fifo - 2 FIFO block
5160 * 3 block : Rx FIFO + 3 FIFO block; Tx fifo - 3 FIFO block
5162 * Return : enum halmac_ret_status
5163 * More details of status code can be found in prototype document
5165 enum halmac_ret_status halmac_cfg_rx_fifo_expanding_mode_88xx(
5166 struct halmac_adapter *halmac_adapter,
5167 enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode)
5169 void *driver_adapter = NULL;
5171 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5172 return HALMAC_RET_ADAPTER_INVALID;
5174 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5175 return HALMAC_RET_API_INVALID;
5177 halmac_api_record_id_88xx(halmac_adapter,
5178 HALMAC_API_CFG_RX_FIFO_EXPANDING_MODE);
5180 driver_adapter = halmac_adapter->driver_adapter;
5183 driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5184 "%s ==========>rx_fifo_expanding_mode = %d\n", __func__,
5185 rx_fifo_expanding_mode);
5187 halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
5188 rx_fifo_expanding_mode;
5190 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5191 "%s <==========\n", __func__);
5193 return HALMAC_RET_SUCCESS;
5196 enum halmac_ret_status
5197 halmac_config_security_88xx(struct halmac_adapter *halmac_adapter,
5198 struct halmac_security_setting *sec_setting)
5200 struct halmac_api *halmac_api;
5201 void *driver_adapter = NULL;
5203 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5204 return HALMAC_RET_ADAPTER_INVALID;
5206 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5207 return HALMAC_RET_API_INVALID;
5209 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5210 driver_adapter = halmac_adapter->driver_adapter;
5212 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5213 "%s ==========>\n", __func__);
5215 HALMAC_REG_WRITE_16(halmac_adapter, REG_CR,
5216 (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_CR) |
5219 if (sec_setting->tx_encryption == 1)
5221 halmac_adapter, REG_SECCFG,
5222 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(2));
5225 halmac_adapter, REG_SECCFG,
5226 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
5229 if (sec_setting->rx_decryption == 1)
5231 halmac_adapter, REG_SECCFG,
5232 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(3));
5235 halmac_adapter, REG_SECCFG,
5236 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
5239 if (sec_setting->bip_enable == 1) {
5240 if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B)
5241 return HALMAC_RET_BIP_NO_SUPPORT;
5244 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5245 "%s <==========\n", __func__);
5247 return HALMAC_RET_SUCCESS;
5250 u8 halmac_get_used_cam_entry_num_88xx(struct halmac_adapter *halmac_adapter,
5251 enum hal_security_type sec_type)
5254 void *driver_adapter = NULL;
5256 driver_adapter = halmac_adapter->driver_adapter;
5258 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5259 "%s ==========>\n", __func__);
5262 case HAL_SECURITY_TYPE_WEP40:
5263 case HAL_SECURITY_TYPE_WEP104:
5264 case HAL_SECURITY_TYPE_TKIP:
5265 case HAL_SECURITY_TYPE_AES128:
5266 case HAL_SECURITY_TYPE_GCMP128:
5267 case HAL_SECURITY_TYPE_GCMSMS4:
5268 case HAL_SECURITY_TYPE_BIP:
5271 case HAL_SECURITY_TYPE_WAPI:
5272 case HAL_SECURITY_TYPE_AES256:
5273 case HAL_SECURITY_TYPE_GCMP256:
5281 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5282 "%s <==========\n", __func__);
5287 enum halmac_ret_status
5288 halmac_write_cam_88xx(struct halmac_adapter *halmac_adapter, u32 entry_index,
5289 struct halmac_cam_entry_info *cam_entry_info)
5292 u32 command = 0x80010000;
5293 struct halmac_api *halmac_api;
5294 void *driver_adapter = NULL;
5295 struct halmac_cam_entry_format *cam_entry_format = NULL;
5297 driver_adapter = halmac_adapter->driver_adapter;
5298 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5300 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5301 "[TRACE]%s ==========>\n", __func__);
5303 if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5304 return HALMAC_RET_ENTRY_INDEX_ERROR;
5306 if (cam_entry_info->key_id > 3)
5307 return HALMAC_RET_FAIL;
5309 cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
5310 if (!cam_entry_format)
5311 return HALMAC_RET_NULL_POINTER;
5313 cam_entry_format->key_id = cam_entry_info->key_id;
5314 cam_entry_format->valid = cam_entry_info->valid;
5315 memcpy(cam_entry_format->mac_address, cam_entry_info->mac_address, 6);
5316 memcpy(cam_entry_format->key, cam_entry_info->key, 16);
5318 switch (cam_entry_info->security_type) {
5319 case HAL_SECURITY_TYPE_NONE:
5320 cam_entry_format->type = 0;
5322 case HAL_SECURITY_TYPE_WEP40:
5323 cam_entry_format->type = 1;
5325 case HAL_SECURITY_TYPE_WEP104:
5326 cam_entry_format->type = 5;
5328 case HAL_SECURITY_TYPE_TKIP:
5329 cam_entry_format->type = 2;
5331 case HAL_SECURITY_TYPE_AES128:
5332 cam_entry_format->type = 4;
5334 case HAL_SECURITY_TYPE_WAPI:
5335 cam_entry_format->type = 6;
5337 case HAL_SECURITY_TYPE_AES256:
5338 cam_entry_format->type = 4;
5339 cam_entry_format->ext_sectype = 1;
5341 case HAL_SECURITY_TYPE_GCMP128:
5342 cam_entry_format->type = 7;
5344 case HAL_SECURITY_TYPE_GCMP256:
5345 case HAL_SECURITY_TYPE_GCMSMS4:
5346 cam_entry_format->type = 7;
5347 cam_entry_format->ext_sectype = 1;
5349 case HAL_SECURITY_TYPE_BIP:
5350 cam_entry_format->type = cam_entry_info->unicast == 1 ? 4 : 0;
5351 cam_entry_format->mgnt = 1;
5352 cam_entry_format->grp = cam_entry_info->unicast == 1 ? 0 : 1;
5355 kfree(cam_entry_format);
5356 return HALMAC_RET_FAIL;
5359 for (i = 0; i < 8; i++) {
5360 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5361 *((u32 *)cam_entry_format + i));
5362 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5363 command | ((entry_index << 3) + i));
5364 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5365 "[TRACE]1 - CAM entry format : %X\n",
5366 *((u32 *)cam_entry_format + i));
5367 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5368 "[TRACE]1 - REG_CAMCMD : %X\n",
5369 command | ((entry_index << 3) + i));
5372 if (cam_entry_info->security_type == HAL_SECURITY_TYPE_WAPI ||
5373 cam_entry_info->security_type == HAL_SECURITY_TYPE_AES256 ||
5374 cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMP256 ||
5375 cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMSMS4) {
5376 cam_entry_format->mic = 1;
5377 memcpy(cam_entry_format->key, cam_entry_info->key_ext, 16);
5379 for (i = 0; i < 8; i++) {
5380 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5381 *((u32 *)cam_entry_format + i));
5382 HALMAC_REG_WRITE_32(
5383 halmac_adapter, REG_CAMCMD,
5384 command | (((entry_index + 1) << 3) + i));
5385 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON,
5387 "[TRACE]2 - CAM entry format : %X\n",
5388 *((u32 *)cam_entry_format + i));
5390 driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5391 "[TRACE]2 - REG_CAMCMD : %X\n",
5392 command | (((entry_index + 1) << 3) + i));
5396 kfree(cam_entry_format);
5398 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5399 "[TRACE]%s <==========\n", __func__);
5401 return HALMAC_RET_SUCCESS;
5404 enum halmac_ret_status
5405 halmac_read_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
5407 struct halmac_cam_entry_format *content)
5410 u32 command = 0x80000000;
5411 struct halmac_api *halmac_api;
5412 void *driver_adapter = NULL;
5414 driver_adapter = halmac_adapter->driver_adapter;
5415 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5417 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5418 "%s ==========>\n", __func__);
5420 if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5421 return HALMAC_RET_ENTRY_INDEX_ERROR;
5423 for (i = 0; i < 8; i++) {
5424 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5425 command | ((entry_index << 3) + i));
5426 *((u32 *)content + i) =
5427 HALMAC_REG_READ_32(halmac_adapter, REG_CAMREAD);
5430 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5431 "%s <==========\n", __func__);
5433 return HALMAC_RET_SUCCESS;
5436 enum halmac_ret_status
5437 halmac_clear_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
5441 u32 command = 0x80010000;
5442 void *driver_adapter = NULL;
5443 struct halmac_api *halmac_api;
5444 struct halmac_cam_entry_format *cam_entry_format;
5446 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5447 return HALMAC_RET_ADAPTER_INVALID;
5449 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5450 return HALMAC_RET_API_INVALID;
5452 driver_adapter = halmac_adapter->driver_adapter;
5453 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5455 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5456 "[TRACE]halmac_clear_security_cam_88xx ==========>\n");
5458 if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5459 return HALMAC_RET_ENTRY_INDEX_ERROR;
5461 cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
5462 if (!cam_entry_format)
5463 return HALMAC_RET_NULL_POINTER;
5465 for (i = 0; i < 8; i++) {
5466 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5467 *((u32 *)cam_entry_format + i));
5468 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5469 command | ((entry_index << 3) + i));
5472 kfree(cam_entry_format);
5474 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5475 "[TRACE]halmac_clear_security_cam_88xx <==========\n");
5477 return HALMAC_RET_SUCCESS;
5481 * halmac_get_hw_value_88xx() -get hw config value
5482 * @halmac_adapter : the adapter of halmac
5483 * @hw_id : hw id for driver to query
5484 * @pvalue : hw value, reference table to get data type
5485 * Author : KaiYuan Chang / Ivan Lin
5486 * Return : enum halmac_ret_status
5487 * More details of status code can be found in prototype document
5489 enum halmac_ret_status
5490 halmac_get_hw_value_88xx(struct halmac_adapter *halmac_adapter,
5491 enum halmac_hw_id hw_id, void *pvalue)
5493 void *driver_adapter = NULL;
5494 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
5496 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5497 return HALMAC_RET_ADAPTER_INVALID;
5499 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5500 return HALMAC_RET_API_INVALID;
5502 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
5504 driver_adapter = halmac_adapter->driver_adapter;
5506 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5507 "%s ==========>\n", __func__);
5510 pr_err("%s (!pvalue)==========>\n", __func__);
5511 return HALMAC_RET_NULL_POINTER;
5515 case HALMAC_HW_RQPN_MAPPING:
5516 ((struct halmac_rqpn_map *)pvalue)->dma_map_vo =
5517 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
5518 ((struct halmac_rqpn_map *)pvalue)->dma_map_vi =
5519 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
5520 ((struct halmac_rqpn_map *)pvalue)->dma_map_be =
5521 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
5522 ((struct halmac_rqpn_map *)pvalue)->dma_map_bk =
5523 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
5524 ((struct halmac_rqpn_map *)pvalue)->dma_map_mg =
5525 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
5526 ((struct halmac_rqpn_map *)pvalue)->dma_map_hi =
5527 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
5529 case HALMAC_HW_EFUSE_SIZE:
5530 *(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size;
5532 case HALMAC_HW_EEPROM_SIZE:
5533 *(u32 *)pvalue = halmac_adapter->hw_config_info.eeprom_size;
5535 case HALMAC_HW_BT_BANK_EFUSE_SIZE:
5536 *(u32 *)pvalue = halmac_adapter->hw_config_info.bt_efuse_size;
5538 case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
5539 case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
5542 case HALMAC_HW_TXFIFO_SIZE:
5543 *(u32 *)pvalue = halmac_adapter->hw_config_info.tx_fifo_size;
5545 case HALMAC_HW_RSVD_PG_BNDY:
5547 halmac_adapter->txff_allocation.rsvd_drv_pg_bndy;
5549 case HALMAC_HW_CAM_ENTRY_NUM:
5550 *(u8 *)pvalue = halmac_adapter->hw_config_info.cam_entry_num;
5552 case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE: /*Remove later*/
5553 status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
5554 HALMAC_EFUSE_R_DRV);
5555 if (status != HALMAC_RET_SUCCESS)
5557 *(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size -
5558 HALMAC_PROTECTED_EFUSE_SIZE_88XX -
5559 halmac_adapter->efuse_end;
5561 case HALMAC_HW_IC_VERSION:
5562 *(u8 *)pvalue = halmac_adapter->chip_version;
5564 case HALMAC_HW_PAGE_SIZE:
5565 *(u32 *)pvalue = halmac_adapter->hw_config_info.page_size;
5567 case HALMAC_HW_TX_AGG_ALIGN_SIZE:
5568 *(u16 *)pvalue = halmac_adapter->hw_config_info.tx_align_size;
5570 case HALMAC_HW_RX_AGG_ALIGN_SIZE:
5573 case HALMAC_HW_DRV_INFO_SIZE:
5574 *(u8 *)pvalue = halmac_adapter->drv_info_size;
5576 case HALMAC_HW_TXFF_ALLOCATION:
5577 memcpy(pvalue, &halmac_adapter->txff_allocation,
5578 sizeof(struct halmac_txff_allocation));
5580 case HALMAC_HW_TX_DESC_SIZE:
5581 *(u32 *)pvalue = halmac_adapter->hw_config_info.txdesc_size;
5583 case HALMAC_HW_RX_DESC_SIZE:
5584 *(u32 *)pvalue = halmac_adapter->hw_config_info.rxdesc_size;
5587 return HALMAC_RET_PARA_NOT_SUPPORT;
5590 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5591 "%s <==========\n", __func__);
5593 return HALMAC_RET_SUCCESS;
5597 * halmac_set_hw_value_88xx() -set hw config value
5598 * @halmac_adapter : the adapter of halmac
5599 * @hw_id : hw id for driver to config
5600 * @pvalue : hw value, reference table to get data type
5601 * Author : KaiYuan Chang / Ivan Lin
5602 * Return : enum halmac_ret_status
5603 * More details of status code can be found in prototype document
5605 enum halmac_ret_status
5606 halmac_set_hw_value_88xx(struct halmac_adapter *halmac_adapter,
5607 enum halmac_hw_id hw_id, void *pvalue)
5609 void *driver_adapter = NULL;
5610 enum halmac_ret_status status;
5612 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5613 return HALMAC_RET_ADAPTER_INVALID;
5615 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5616 return HALMAC_RET_API_INVALID;
5618 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
5620 driver_adapter = halmac_adapter->driver_adapter;
5622 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5623 "%s ==========>\n", __func__);
5626 pr_err("%s (!pvalue)==========>\n", __func__);
5627 return HALMAC_RET_NULL_POINTER;
5631 case HALMAC_HW_USB_MODE:
5632 status = halmac_set_usb_mode_88xx(
5633 halmac_adapter, *(enum halmac_usb_mode *)pvalue);
5634 if (status != HALMAC_RET_SUCCESS)
5637 case HALMAC_HW_SEQ_EN:
5639 case HALMAC_HW_BANDWIDTH:
5640 halmac_cfg_bw_88xx(halmac_adapter, *(enum halmac_bw *)pvalue);
5642 case HALMAC_HW_CHANNEL:
5643 halmac_cfg_ch_88xx(halmac_adapter, *(u8 *)pvalue);
5645 case HALMAC_HW_PRI_CHANNEL_IDX:
5646 halmac_cfg_pri_ch_idx_88xx(halmac_adapter,
5647 *(enum halmac_pri_ch_idx *)pvalue);
5649 case HALMAC_HW_EN_BB_RF:
5650 halmac_enable_bb_rf_88xx(halmac_adapter, *(u8 *)pvalue);
5652 case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
5653 halmac_config_sdio_tx_page_threshold_88xx(
5655 (struct halmac_tx_page_threshold_info *)pvalue);
5657 case HALMAC_HW_AMPDU_CONFIG:
5658 halmac_config_ampdu_88xx(halmac_adapter,
5659 (struct halmac_ampdu_config *)pvalue);
5662 return HALMAC_RET_PARA_NOT_SUPPORT;
5665 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5666 "%s <==========\n", __func__);
5668 return HALMAC_RET_SUCCESS;
5672 * halmac_cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
5673 * @halmac_adapter : the adapter of halmac
5674 * @pg_num : page number
5675 * Author : KaiYuan Chang
5676 * Return : enum halmac_ret_status
5677 * More details of status code can be found in prototype document
5679 enum halmac_ret_status
5680 halmac_cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *halmac_adapter,
5681 enum halmac_drv_rsvd_pg_num pg_num)
5683 void *driver_adapter = NULL;
5685 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5686 return HALMAC_RET_ADAPTER_INVALID;
5688 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5689 return HALMAC_RET_API_INVALID;
5691 halmac_api_record_id_88xx(halmac_adapter,
5692 HALMAC_API_CFG_DRV_RSVD_PG_NUM);
5694 driver_adapter = halmac_adapter->driver_adapter;
5696 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5697 "%s ==========>pg_num = %d\n", __func__,
5701 case HALMAC_RSVD_PG_NUM16:
5702 halmac_adapter->txff_allocation.rsvd_drv_pg_num = 16;
5704 case HALMAC_RSVD_PG_NUM24:
5705 halmac_adapter->txff_allocation.rsvd_drv_pg_num = 24;
5707 case HALMAC_RSVD_PG_NUM32:
5708 halmac_adapter->txff_allocation.rsvd_drv_pg_num = 32;
5712 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5713 "%s <==========\n", __func__);
5715 return HALMAC_RET_SUCCESS;
5718 enum halmac_ret_status
5719 halmac_get_chip_version_88xx(struct halmac_adapter *halmac_adapter,
5720 struct halmac_ver *version)
5722 void *driver_adapter = NULL;
5723 struct halmac_api *halmac_api;
5725 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5726 return HALMAC_RET_ADAPTER_INVALID;
5728 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5729 return HALMAC_RET_API_INVALID;
5731 driver_adapter = halmac_adapter->driver_adapter;
5732 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5734 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5735 "%s ==========>\n", __func__);
5736 version->major_ver = (u8)HALMAC_MAJOR_VER_88XX;
5737 version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER_88XX;
5738 version->minor_ver = (u8)HALMAC_MINOR_VER_88XX;
5739 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5740 "%s <==========\n", __func__);
5742 return HALMAC_RET_SUCCESS;
5746 * halmac_chk_txdesc_88xx() -check if the tx packet format is incorrect
5747 * @halmac_adapter : the adapter of halmac
5748 * @halmac_buf : tx Packet buffer, tx desc is included
5749 * @halmac_size : tx packet size
5750 * Author : KaiYuan Chang
5751 * Return : enum halmac_ret_status
5752 * More details of status code can be found in prototype document
5754 enum halmac_ret_status
5755 halmac_chk_txdesc_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
5758 void *driver_adapter = NULL;
5759 struct halmac_api *halmac_api;
5761 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5762 return HALMAC_RET_ADAPTER_INVALID;
5764 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5765 return HALMAC_RET_API_INVALID;
5767 driver_adapter = halmac_adapter->driver_adapter;
5768 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5770 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5771 "%s ==========>\n", __func__);
5773 if (GET_TX_DESC_BMC(halmac_buf))
5774 if (GET_TX_DESC_AGG_EN(halmac_buf))
5775 pr_err("TxDesc: Agg should not be set when BMC\n");
5777 if (halmac_size < (GET_TX_DESC_TXPKTSIZE(halmac_buf) +
5778 GET_TX_DESC_OFFSET(halmac_buf)))
5779 pr_err("TxDesc: PktSize too small\n");
5781 return HALMAC_RET_SUCCESS;
5785 * halmac_dl_drv_rsvd_page_88xx() - download packet to rsvd page
5786 * @halmac_adapter : the adapter of halmac
5787 * @pg_offset : page offset of driver's rsvd page
5788 * @halmac_buf : data to be downloaded, tx_desc is not included
5789 * @halmac_size : data size to be downloaded
5790 * Author : KaiYuan Chang
5791 * Return : enum halmac_ret_status
5792 * More details of status code can be found in prototype document
5794 enum halmac_ret_status
5795 halmac_dl_drv_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
5796 u8 pg_offset, u8 *halmac_buf, u32 halmac_size)
5798 void *driver_adapter = NULL;
5799 struct halmac_api *halmac_api;
5800 enum halmac_ret_status ret_status;
5801 u16 drv_pg_bndy = 0;
5804 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5805 return HALMAC_RET_ADAPTER_INVALID;
5807 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5808 return HALMAC_RET_API_INVALID;
5810 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DL_DRV_RSVD_PG);
5812 driver_adapter = halmac_adapter->driver_adapter;
5813 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5815 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5816 "%s ==========>\n", __func__);
5818 /*check boundary and size valid*/
5819 dl_pg_num = halmac_size / halmac_adapter->hw_config_info.page_size +
5821 (halmac_adapter->hw_config_info.page_size - 1)) ?
5824 if (pg_offset + dl_pg_num >
5825 halmac_adapter->txff_allocation.rsvd_drv_pg_num) {
5826 pr_err("[ERROR] driver download offset or size error ==========>\n");
5827 return HALMAC_RET_DRV_DL_ERR;
5830 /*update to target download boundary*/
5832 halmac_adapter->txff_allocation.rsvd_drv_pg_bndy + pg_offset;
5833 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
5834 (u16)(drv_pg_bndy & BIT_MASK_BCN_HEAD_1_V1));
5836 ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, halmac_buf,
5839 /*restore to original bundary*/
5840 if (ret_status != HALMAC_RET_SUCCESS) {
5841 pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
5843 HALMAC_REG_WRITE_16(
5844 halmac_adapter, REG_FIFOPAGE_CTRL_2,
5845 (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
5846 BIT_MASK_BCN_HEAD_1_V1));
5850 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
5851 (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
5852 BIT_MASK_BCN_HEAD_1_V1));
5854 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5855 "%s < ==========\n", __func__);
5856 return HALMAC_RET_SUCCESS;
5860 * halmac_cfg_csi_rate_88xx() - config CSI frame Tx rate
5861 * @halmac_adapter : the adapter of halmac
5862 * @rssi : rssi in decimal value
5863 * @current_rate : current CSI frame rate
5864 * @fixrate_en : enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate
5865 * @new_rate : API returns the final CSI frame rate
5867 * Return : enum halmac_ret_status
5868 * More details of status code can be found in prototype document
5870 enum halmac_ret_status
5871 halmac_cfg_csi_rate_88xx(struct halmac_adapter *halmac_adapter, u8 rssi,
5872 u8 current_rate, u8 fixrate_en, u8 *new_rate)
5874 void *driver_adapter = NULL;
5875 struct halmac_api *halmac_api;
5876 u32 temp_csi_setting;
5878 enum halmac_ret_status ret_status;
5880 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5881 return HALMAC_RET_ADAPTER_INVALID;
5883 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5884 return HALMAC_RET_API_INVALID;
5886 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CSI_RATE);
5888 driver_adapter = halmac_adapter->driver_adapter;
5889 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5890 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
5891 "<%s ==========>\n", __func__);
5893 temp_csi_setting = HALMAC_REG_READ_32(halmac_adapter, REG_BBPSF_CTRL) &
5894 ~(BIT_MASK_WMAC_CSI_RATE << BIT_SHIFT_WMAC_CSI_RATE);
5896 current_rrsr = HALMAC_REG_READ_16(halmac_adapter, REG_RRSR);
5899 if (current_rate != HALMAC_OFDM54) {
5900 HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
5901 current_rrsr | BIT(HALMAC_OFDM54));
5902 HALMAC_REG_WRITE_32(
5903 halmac_adapter, REG_BBPSF_CTRL,
5905 BIT_WMAC_CSI_RATE(HALMAC_OFDM54));
5907 *new_rate = HALMAC_OFDM54;
5908 ret_status = HALMAC_RET_SUCCESS;
5910 if (current_rate != HALMAC_OFDM24) {
5911 HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
5913 ~(BIT(HALMAC_OFDM54)));
5914 HALMAC_REG_WRITE_32(
5915 halmac_adapter, REG_BBPSF_CTRL,
5917 BIT_WMAC_CSI_RATE(HALMAC_OFDM24));
5919 *new_rate = HALMAC_OFDM24;
5920 ret_status = HALMAC_RET_SUCCESS;
5927 * halmac_sdio_cmd53_4byte_88xx() - cmd53 only for 4byte len register IO
5928 * @halmac_adapter : the adapter of halmac
5929 * @enable : 1->CMD53 only use in 4byte reg, 0 : No limitation
5930 * Author : Ivan Lin/KaiYuan Chang
5931 * Return : enum halmac_ret_status
5932 * More details of status code can be found in prototype document
5934 enum halmac_ret_status
5935 halmac_sdio_cmd53_4byte_88xx(struct halmac_adapter *halmac_adapter,
5936 enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode)
5938 halmac_adapter->sdio_cmd53_4byte = cmd53_4byte_mode;
5940 return HALMAC_RET_SUCCESS;
5944 * halmac_txfifo_is_empty_88xx() -check if txfifo is empty
5945 * @halmac_adapter : the adapter of halmac
5947 * Return : enum halmac_ret_status
5948 * More details of status code can be found in prototype document
5950 enum halmac_ret_status
5951 halmac_txfifo_is_empty_88xx(struct halmac_adapter *halmac_adapter, u32 chk_num)
5954 void *driver_adapter = NULL;
5955 struct halmac_api *halmac_api;
5957 driver_adapter = halmac_adapter->driver_adapter;
5958 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5960 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5961 "%s ==========>\n", __func__);
5963 counter = (chk_num <= 10) ? 10 : chk_num;
5965 if (HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY) != 0xFF)
5966 return HALMAC_RET_TXFIFO_NO_EMPTY;
5968 if ((HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY + 1) &
5970 return HALMAC_RET_TXFIFO_NO_EMPTY;
5973 } while (counter != 0);
5975 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5976 "%s <==========\n", __func__);
5978 return HALMAC_RET_SUCCESS;