1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
14 #include "halmac_88xx_cfg.h"
17 * halmac_init_adapter_para_88xx() - int halmac adapter
22 * Author : KaiYuan Chang/Ivan Lin
25 void halmac_init_adapter_para_88xx(struct halmac_adapter *halmac_adapter)
27 halmac_adapter->api_record.array_wptr = 0;
28 halmac_adapter->hal_adapter_backup = halmac_adapter;
29 halmac_adapter->hal_efuse_map = (u8 *)NULL;
30 halmac_adapter->hal_efuse_map_valid = false;
31 halmac_adapter->efuse_end = 0;
32 halmac_adapter->hal_mac_addr[0].address_l_h.address_low = 0;
33 halmac_adapter->hal_mac_addr[0].address_l_h.address_high = 0;
34 halmac_adapter->hal_mac_addr[1].address_l_h.address_low = 0;
35 halmac_adapter->hal_mac_addr[1].address_l_h.address_high = 0;
36 halmac_adapter->hal_bss_addr[0].address_l_h.address_low = 0;
37 halmac_adapter->hal_bss_addr[0].address_l_h.address_high = 0;
38 halmac_adapter->hal_bss_addr[1].address_l_h.address_low = 0;
39 halmac_adapter->hal_bss_addr[1].address_l_h.address_high = 0;
41 halmac_adapter->low_clk = false;
42 halmac_adapter->max_download_size = HALMAC_FW_MAX_DL_SIZE_88XX;
45 halmac_adapter->fwlps_option.mode = 0x01; /*0:Active 1:LPS 2:WMMPS*/
46 halmac_adapter->fwlps_option.awake_interval = 1;
47 halmac_adapter->fwlps_option.enter_32K = 1;
48 halmac_adapter->fwlps_option.clk_request = 0;
49 halmac_adapter->fwlps_option.rlbm = 0;
50 halmac_adapter->fwlps_option.smart_ps = 0;
51 halmac_adapter->fwlps_option.awake_interval = 1;
52 halmac_adapter->fwlps_option.all_queue_uapsd = 0;
53 halmac_adapter->fwlps_option.pwr_state = 0;
54 halmac_adapter->fwlps_option.low_pwr_rx_beacon = 0;
55 halmac_adapter->fwlps_option.ant_auto_switch = 0;
56 halmac_adapter->fwlps_option.ps_allow_bt_high_priority = 0;
57 halmac_adapter->fwlps_option.protect_bcn = 0;
58 halmac_adapter->fwlps_option.silence_period = 0;
59 halmac_adapter->fwlps_option.fast_bt_connect = 0;
60 halmac_adapter->fwlps_option.two_antenna_en = 0;
61 halmac_adapter->fwlps_option.adopt_user_setting = 1;
62 halmac_adapter->fwlps_option.drv_bcn_early_shift = 0;
64 halmac_adapter->config_para_info.cfg_para_buf = NULL;
65 halmac_adapter->config_para_info.para_buf_w = NULL;
66 halmac_adapter->config_para_info.para_num = 0;
67 halmac_adapter->config_para_info.full_fifo_mode = false;
68 halmac_adapter->config_para_info.para_buf_size = 0;
69 halmac_adapter->config_para_info.avai_para_buf_size = 0;
70 halmac_adapter->config_para_info.offset_accumulation = 0;
71 halmac_adapter->config_para_info.value_accumulation = 0;
72 halmac_adapter->config_para_info.datapack_segment = 0;
74 halmac_adapter->ch_sw_info.ch_info_buf = NULL;
75 halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
76 halmac_adapter->ch_sw_info.extra_info_en = 0;
77 halmac_adapter->ch_sw_info.buf_size = 0;
78 halmac_adapter->ch_sw_info.avai_buf_size = 0;
79 halmac_adapter->ch_sw_info.total_size = 0;
80 halmac_adapter->ch_sw_info.ch_num = 0;
82 halmac_adapter->drv_info_size = 0;
84 memset(halmac_adapter->api_record.api_array, HALMAC_API_STUFF,
85 sizeof(halmac_adapter->api_record.api_array));
87 halmac_adapter->txff_allocation.tx_fifo_pg_num = 0;
88 halmac_adapter->txff_allocation.ac_q_pg_num = 0;
89 halmac_adapter->txff_allocation.rsvd_pg_bndy = 0;
90 halmac_adapter->txff_allocation.rsvd_drv_pg_bndy = 0;
91 halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy = 0;
92 halmac_adapter->txff_allocation.rsvd_h2c_queue_pg_bndy = 0;
93 halmac_adapter->txff_allocation.rsvd_cpu_instr_pg_bndy = 0;
94 halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy = 0;
95 halmac_adapter->txff_allocation.pub_queue_pg_num = 0;
96 halmac_adapter->txff_allocation.high_queue_pg_num = 0;
97 halmac_adapter->txff_allocation.low_queue_pg_num = 0;
98 halmac_adapter->txff_allocation.normal_queue_pg_num = 0;
99 halmac_adapter->txff_allocation.extra_queue_pg_num = 0;
101 halmac_adapter->txff_allocation.la_mode = HALMAC_LA_MODE_DISABLE;
102 halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
103 HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
105 halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
106 halmac_init_state_machine_88xx(halmac_adapter);
110 * halmac_init_adapter_dynamic_para_88xx() - int halmac adapter
115 * Author : KaiYuan Chang/Ivan Lin
118 void halmac_init_adapter_dynamic_para_88xx(
119 struct halmac_adapter *halmac_adapter)
121 halmac_adapter->h2c_packet_seq = 0;
122 halmac_adapter->h2c_buf_free_space = 0;
123 halmac_adapter->gen_info_valid = false;
127 * halmac_init_state_machine_88xx() - init halmac software state machine
132 * Author : KaiYuan Chang/Ivan Lin
135 void halmac_init_state_machine_88xx(struct halmac_adapter *halmac_adapter)
137 struct halmac_state *state = &halmac_adapter->halmac_state;
139 halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
141 state->api_state = HALMAC_API_STATE_INIT;
143 state->dlfw_state = HALMAC_DLFW_NONE;
144 state->mac_power = HALMAC_MAC_POWER_OFF;
145 state->ps_state = HALMAC_PS_STATE_UNDEFINE;
149 * halmac_mount_api_88xx() - attach functions to function pointer
154 * Author : KaiYuan Chang/Ivan Lin
155 * Return : enum halmac_ret_status
157 enum halmac_ret_status
158 halmac_mount_api_88xx(struct halmac_adapter *halmac_adapter)
160 void *driver_adapter = halmac_adapter->driver_adapter;
161 struct halmac_api *halmac_api = (struct halmac_api *)NULL;
163 halmac_adapter->halmac_api =
164 kzalloc(sizeof(struct halmac_api), GFP_KERNEL);
165 if (!halmac_adapter->halmac_api)
166 return HALMAC_RET_MALLOC_FAIL;
167 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
169 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
170 HALMAC_SVN_VER_88XX "\n");
171 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
172 "HALMAC_MAJOR_VER_88XX = %x\n", HALMAC_MAJOR_VER_88XX);
173 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
174 "HALMAC_PROTOTYPE_88XX = %x\n",
175 HALMAC_PROTOTYPE_VER_88XX);
176 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
177 "HALMAC_MINOR_VER_88XX = %x\n", HALMAC_MINOR_VER_88XX);
178 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
179 "HALMAC_PATCH_VER_88XX = %x\n", HALMAC_PATCH_VER_88XX);
181 /* Mount function pointer */
182 halmac_api->halmac_download_firmware = halmac_download_firmware_88xx;
183 halmac_api->halmac_free_download_firmware =
184 halmac_free_download_firmware_88xx;
185 halmac_api->halmac_get_fw_version = halmac_get_fw_version_88xx;
186 halmac_api->halmac_cfg_mac_addr = halmac_cfg_mac_addr_88xx;
187 halmac_api->halmac_cfg_bssid = halmac_cfg_bssid_88xx;
188 halmac_api->halmac_cfg_multicast_addr = halmac_cfg_multicast_addr_88xx;
189 halmac_api->halmac_pre_init_system_cfg =
190 halmac_pre_init_system_cfg_88xx;
191 halmac_api->halmac_init_system_cfg = halmac_init_system_cfg_88xx;
192 halmac_api->halmac_init_edca_cfg = halmac_init_edca_cfg_88xx;
193 halmac_api->halmac_cfg_operation_mode = halmac_cfg_operation_mode_88xx;
194 halmac_api->halmac_cfg_ch_bw = halmac_cfg_ch_bw_88xx;
195 halmac_api->halmac_cfg_bw = halmac_cfg_bw_88xx;
196 halmac_api->halmac_init_wmac_cfg = halmac_init_wmac_cfg_88xx;
197 halmac_api->halmac_init_mac_cfg = halmac_init_mac_cfg_88xx;
198 halmac_api->halmac_init_sdio_cfg = halmac_init_sdio_cfg_88xx;
199 halmac_api->halmac_init_usb_cfg = halmac_init_usb_cfg_88xx;
200 halmac_api->halmac_init_pcie_cfg = halmac_init_pcie_cfg_88xx;
201 halmac_api->halmac_deinit_sdio_cfg = halmac_deinit_sdio_cfg_88xx;
202 halmac_api->halmac_deinit_usb_cfg = halmac_deinit_usb_cfg_88xx;
203 halmac_api->halmac_deinit_pcie_cfg = halmac_deinit_pcie_cfg_88xx;
204 halmac_api->halmac_dump_efuse_map = halmac_dump_efuse_map_88xx;
205 halmac_api->halmac_dump_efuse_map_bt = halmac_dump_efuse_map_bt_88xx;
206 halmac_api->halmac_write_efuse_bt = halmac_write_efuse_bt_88xx;
207 halmac_api->halmac_dump_logical_efuse_map =
208 halmac_dump_logical_efuse_map_88xx;
209 halmac_api->halmac_pg_efuse_by_map = halmac_pg_efuse_by_map_88xx;
210 halmac_api->halmac_get_efuse_size = halmac_get_efuse_size_88xx;
211 halmac_api->halmac_get_efuse_available_size =
212 halmac_get_efuse_available_size_88xx;
213 halmac_api->halmac_get_c2h_info = halmac_get_c2h_info_88xx;
215 halmac_api->halmac_get_logical_efuse_size =
216 halmac_get_logical_efuse_size_88xx;
218 halmac_api->halmac_write_logical_efuse =
219 halmac_write_logical_efuse_88xx;
220 halmac_api->halmac_read_logical_efuse = halmac_read_logical_efuse_88xx;
222 halmac_api->halmac_cfg_fwlps_option = halmac_cfg_fwlps_option_88xx;
223 halmac_api->halmac_cfg_fwips_option = halmac_cfg_fwips_option_88xx;
224 halmac_api->halmac_enter_wowlan = halmac_enter_wowlan_88xx;
225 halmac_api->halmac_leave_wowlan = halmac_leave_wowlan_88xx;
226 halmac_api->halmac_enter_ps = halmac_enter_ps_88xx;
227 halmac_api->halmac_leave_ps = halmac_leave_ps_88xx;
228 halmac_api->halmac_h2c_lb = halmac_h2c_lb_88xx;
229 halmac_api->halmac_debug = halmac_debug_88xx;
230 halmac_api->halmac_cfg_parameter = halmac_cfg_parameter_88xx;
231 halmac_api->halmac_update_datapack = halmac_update_datapack_88xx;
232 halmac_api->halmac_run_datapack = halmac_run_datapack_88xx;
233 halmac_api->halmac_cfg_drv_info = halmac_cfg_drv_info_88xx;
234 halmac_api->halmac_send_bt_coex = halmac_send_bt_coex_88xx;
235 halmac_api->halmac_verify_platform_api =
236 halmac_verify_platform_api_88xx;
237 halmac_api->halmac_update_packet = halmac_update_packet_88xx;
238 halmac_api->halmac_bcn_ie_filter = halmac_bcn_ie_filter_88xx;
239 halmac_api->halmac_cfg_txbf = halmac_cfg_txbf_88xx;
240 halmac_api->halmac_cfg_mumimo = halmac_cfg_mumimo_88xx;
241 halmac_api->halmac_cfg_sounding = halmac_cfg_sounding_88xx;
242 halmac_api->halmac_del_sounding = halmac_del_sounding_88xx;
243 halmac_api->halmac_su_bfer_entry_init = halmac_su_bfer_entry_init_88xx;
244 halmac_api->halmac_su_bfee_entry_init = halmac_su_bfee_entry_init_88xx;
245 halmac_api->halmac_mu_bfer_entry_init = halmac_mu_bfer_entry_init_88xx;
246 halmac_api->halmac_mu_bfee_entry_init = halmac_mu_bfee_entry_init_88xx;
247 halmac_api->halmac_su_bfer_entry_del = halmac_su_bfer_entry_del_88xx;
248 halmac_api->halmac_su_bfee_entry_del = halmac_su_bfee_entry_del_88xx;
249 halmac_api->halmac_mu_bfer_entry_del = halmac_mu_bfer_entry_del_88xx;
250 halmac_api->halmac_mu_bfee_entry_del = halmac_mu_bfee_entry_del_88xx;
252 halmac_api->halmac_add_ch_info = halmac_add_ch_info_88xx;
253 halmac_api->halmac_add_extra_ch_info = halmac_add_extra_ch_info_88xx;
254 halmac_api->halmac_ctrl_ch_switch = halmac_ctrl_ch_switch_88xx;
255 halmac_api->halmac_p2pps = halmac_p2pps_88xx;
256 halmac_api->halmac_clear_ch_info = halmac_clear_ch_info_88xx;
257 halmac_api->halmac_send_general_info = halmac_send_general_info_88xx;
259 halmac_api->halmac_start_iqk = halmac_start_iqk_88xx;
260 halmac_api->halmac_ctrl_pwr_tracking = halmac_ctrl_pwr_tracking_88xx;
261 halmac_api->halmac_psd = halmac_psd_88xx;
262 halmac_api->halmac_cfg_la_mode = halmac_cfg_la_mode_88xx;
263 halmac_api->halmac_cfg_rx_fifo_expanding_mode =
264 halmac_cfg_rx_fifo_expanding_mode_88xx;
266 halmac_api->halmac_config_security = halmac_config_security_88xx;
267 halmac_api->halmac_get_used_cam_entry_num =
268 halmac_get_used_cam_entry_num_88xx;
269 halmac_api->halmac_read_cam_entry = halmac_read_cam_entry_88xx;
270 halmac_api->halmac_write_cam = halmac_write_cam_88xx;
271 halmac_api->halmac_clear_cam_entry = halmac_clear_cam_entry_88xx;
273 halmac_api->halmac_get_hw_value = halmac_get_hw_value_88xx;
274 halmac_api->halmac_set_hw_value = halmac_set_hw_value_88xx;
276 halmac_api->halmac_cfg_drv_rsvd_pg_num =
277 halmac_cfg_drv_rsvd_pg_num_88xx;
278 halmac_api->halmac_get_chip_version = halmac_get_chip_version_88xx;
280 halmac_api->halmac_query_status = halmac_query_status_88xx;
281 halmac_api->halmac_reset_feature = halmac_reset_feature_88xx;
282 halmac_api->halmac_check_fw_status = halmac_check_fw_status_88xx;
283 halmac_api->halmac_dump_fw_dmem = halmac_dump_fw_dmem_88xx;
284 halmac_api->halmac_cfg_max_dl_size = halmac_cfg_max_dl_size_88xx;
286 halmac_api->halmac_dump_fifo = halmac_dump_fifo_88xx;
287 halmac_api->halmac_get_fifo_size = halmac_get_fifo_size_88xx;
289 halmac_api->halmac_chk_txdesc = halmac_chk_txdesc_88xx;
290 halmac_api->halmac_dl_drv_rsvd_page = halmac_dl_drv_rsvd_page_88xx;
291 halmac_api->halmac_cfg_csi_rate = halmac_cfg_csi_rate_88xx;
293 halmac_api->halmac_sdio_cmd53_4byte = halmac_sdio_cmd53_4byte_88xx;
294 halmac_api->halmac_txfifo_is_empty = halmac_txfifo_is_empty_88xx;
296 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
297 halmac_api->halmac_cfg_rx_aggregation =
298 halmac_cfg_rx_aggregation_88xx_sdio;
299 halmac_api->halmac_init_interface_cfg =
300 halmac_init_sdio_cfg_88xx;
301 halmac_api->halmac_deinit_interface_cfg =
302 halmac_deinit_sdio_cfg_88xx;
303 halmac_api->halmac_reg_read_8 = halmac_reg_read_8_sdio_88xx;
304 halmac_api->halmac_reg_write_8 = halmac_reg_write_8_sdio_88xx;
305 halmac_api->halmac_reg_read_16 = halmac_reg_read_16_sdio_88xx;
306 halmac_api->halmac_reg_write_16 = halmac_reg_write_16_sdio_88xx;
307 halmac_api->halmac_reg_read_32 = halmac_reg_read_32_sdio_88xx;
308 halmac_api->halmac_reg_write_32 = halmac_reg_write_32_sdio_88xx;
309 halmac_api->halmac_reg_read_indirect_32 =
310 halmac_reg_read_indirect_32_sdio_88xx;
311 halmac_api->halmac_reg_sdio_cmd53_read_n =
312 halmac_reg_read_nbyte_sdio_88xx;
313 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
314 halmac_api->halmac_cfg_rx_aggregation =
315 halmac_cfg_rx_aggregation_88xx_usb;
316 halmac_api->halmac_init_interface_cfg =
317 halmac_init_usb_cfg_88xx;
318 halmac_api->halmac_deinit_interface_cfg =
319 halmac_deinit_usb_cfg_88xx;
320 halmac_api->halmac_reg_read_8 = halmac_reg_read_8_usb_88xx;
321 halmac_api->halmac_reg_write_8 = halmac_reg_write_8_usb_88xx;
322 halmac_api->halmac_reg_read_16 = halmac_reg_read_16_usb_88xx;
323 halmac_api->halmac_reg_write_16 = halmac_reg_write_16_usb_88xx;
324 halmac_api->halmac_reg_read_32 = halmac_reg_read_32_usb_88xx;
325 halmac_api->halmac_reg_write_32 = halmac_reg_write_32_usb_88xx;
326 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_PCIE) {
327 halmac_api->halmac_cfg_rx_aggregation =
328 halmac_cfg_rx_aggregation_88xx_pcie;
329 halmac_api->halmac_init_interface_cfg =
330 halmac_init_pcie_cfg_88xx;
331 halmac_api->halmac_deinit_interface_cfg =
332 halmac_deinit_pcie_cfg_88xx;
333 halmac_api->halmac_reg_read_8 = halmac_reg_read_8_pcie_88xx;
334 halmac_api->halmac_reg_write_8 = halmac_reg_write_8_pcie_88xx;
335 halmac_api->halmac_reg_read_16 = halmac_reg_read_16_pcie_88xx;
336 halmac_api->halmac_reg_write_16 = halmac_reg_write_16_pcie_88xx;
337 halmac_api->halmac_reg_read_32 = halmac_reg_read_32_pcie_88xx;
338 halmac_api->halmac_reg_write_32 = halmac_reg_write_32_pcie_88xx;
340 pr_err("Set halmac io function Error!!\n");
343 halmac_api->halmac_set_bulkout_num = halmac_set_bulkout_num_88xx;
344 halmac_api->halmac_get_sdio_tx_addr = halmac_get_sdio_tx_addr_88xx;
345 halmac_api->halmac_get_usb_bulkout_id = halmac_get_usb_bulkout_id_88xx;
346 halmac_api->halmac_timer_2s = halmac_timer_2s_88xx;
347 halmac_api->halmac_fill_txdesc_checksum =
348 halmac_fill_txdesc_check_sum_88xx;
350 if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B) {
351 /*mount 8822b function and data*/
352 halmac_mount_api_8822b(halmac_adapter);
354 } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8821C) {
355 } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8814B) {
356 } else if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8197F) {
358 pr_err("Chip ID undefine!!\n");
359 return HALMAC_RET_CHIP_NOT_SUPPORT;
361 return HALMAC_RET_SUCCESS;
365 * halmac_download_firmware_88xx() - download Firmware
366 * @halmac_adapter : the adapter of halmac
367 * @hamacl_fw : firmware bin
368 * @halmac_fw_size : firmware size
369 * Author : KaiYuan Chang/Ivan Lin
370 * Return : enum halmac_ret_status
371 * More details of status code can be found in prototype document
373 enum halmac_ret_status
374 halmac_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
375 u8 *hamacl_fw, u32 halmac_fw_size)
381 u32 restore_index = 0;
382 u32 halmac_h2c_ver = 0, fw_h2c_ver = 0;
383 u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
384 void *driver_adapter = NULL;
385 struct halmac_api *halmac_api;
386 struct halmac_restore_info restore_info[DLFW_RESTORE_REG_NUM_88XX];
389 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
390 return HALMAC_RET_ADAPTER_INVALID;
392 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
393 return HALMAC_RET_API_INVALID;
395 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DOWNLOAD_FIRMWARE);
397 driver_adapter = halmac_adapter->driver_adapter;
398 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
400 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
401 "%s ==========>\n", __func__);
402 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
403 "%s start!!\n", __func__);
405 if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
406 halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
407 pr_err("FW size error!\n");
408 return HALMAC_RET_FW_SIZE_ERR;
411 fw_h2c_ver = le32_to_cpu(
413 (hamacl_fw + HALMAC_FWHDR_OFFSET_H2C_FORMAT_VER_88XX)));
414 halmac_h2c_ver = H2C_FORMAT_VERSION;
416 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
417 "halmac h2c/c2h format = %x, fw h2c/c2h format = %x!!\n",
418 halmac_h2c_ver, fw_h2c_ver);
419 if (fw_h2c_ver != halmac_h2c_ver)
421 driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
422 "[WARN]H2C/C2H version between HALMAC and FW is compatible!!\n");
424 halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
426 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
427 value8 = (u8)(value8 & ~(BIT(2)));
428 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
429 value8); /* Disable CPU reset */
431 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
432 value8 = (u8)(value8 & ~(BIT(0)));
433 HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
435 restore_info[restore_index].length = 1;
436 restore_info[restore_index].mac_register = REG_TXDMA_PQ_MAP + 1;
437 restore_info[restore_index].value =
438 HALMAC_REG_READ_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1);
440 value8 = HALMAC_DMA_MAPPING_HIGH << 6;
441 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXDMA_PQ_MAP + 1,
442 value8); /* set HIQ to hi priority */
444 /* DLFW only use HIQ, map HIQ to hi priority */
445 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
446 HALMAC_DMA_MAPPING_HIGH;
447 restore_info[restore_index].length = 1;
448 restore_info[restore_index].mac_register = REG_CR;
449 restore_info[restore_index].value =
450 HALMAC_REG_READ_8(halmac_adapter, REG_CR);
452 restore_info[restore_index].length = 4;
453 restore_info[restore_index].mac_register = REG_H2CQ_CSR;
454 restore_info[restore_index].value = BIT(31);
456 value8 = BIT_HCI_TXDMA_EN | BIT_TXDMA_EN;
457 HALMAC_REG_WRITE_8(halmac_adapter, REG_CR, value8);
458 HALMAC_REG_WRITE_32(halmac_adapter, REG_H2CQ_CSR, BIT(31));
460 /* Config hi priority queue and public priority queue page number
463 restore_info[restore_index].length = 2;
464 restore_info[restore_index].mac_register = REG_FIFOPAGE_INFO_1;
465 restore_info[restore_index].value =
466 HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_INFO_1);
468 restore_info[restore_index].length = 4;
469 restore_info[restore_index].mac_register = REG_RQPN_CTRL_2;
470 restore_info[restore_index].value =
471 HALMAC_REG_READ_32(halmac_adapter, REG_RQPN_CTRL_2) | BIT(31);
473 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_INFO_1, 0x200);
474 HALMAC_REG_WRITE_32(halmac_adapter, REG_RQPN_CTRL_2,
475 restore_info[restore_index - 1].value);
477 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
478 HALMAC_REG_READ_32(halmac_adapter, REG_SDIO_FREE_TXPG);
479 HALMAC_REG_WRITE_32(halmac_adapter, REG_SDIO_TX_CTRL,
483 halmac_adapter->fw_version.version = le16_to_cpu(
484 *((__le16 *)(hamacl_fw + HALMAC_FWHDR_OFFSET_VERSION_88XX)));
485 halmac_adapter->fw_version.sub_version =
486 *(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBVERSION_88XX);
487 halmac_adapter->fw_version.sub_index =
488 *(hamacl_fw + HALMAC_FWHDR_OFFSET_SUBINDEX_88XX);
489 halmac_adapter->fw_version.h2c_version = (u16)fw_h2c_ver;
491 dmem_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
492 HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX)));
493 iram_pkt_size = le32_to_cpu(*((__le32 *)(hamacl_fw +
494 HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX)));
495 if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
497 le32_to_cpu(*((__le32 *)(hamacl_fw +
498 HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX)));
500 dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
501 iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
502 if (eram_pkt_size != 0)
503 eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
505 if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
506 iram_pkt_size + eram_pkt_size)) {
507 pr_err("FW size mismatch the real fw size!\n");
511 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
512 restore_info[restore_index].length = 1;
513 restore_info[restore_index].mac_register = REG_CR + 1;
514 restore_info[restore_index].value = value8;
516 value8 = (u8)(value8 | BIT(0));
517 HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1,
518 value8); /* Enable SW TX beacon */
520 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
521 restore_info[restore_index].length = 1;
522 restore_info[restore_index].mac_register = REG_BCN_CTRL;
523 restore_info[restore_index].value = value8;
525 value8 = (u8)((value8 & (~BIT(3))) | BIT(4));
526 HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL,
527 value8); /* Disable beacon related functions */
529 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
530 restore_info[restore_index].length = 1;
531 restore_info[restore_index].mac_register = REG_FWHW_TXQ_CTRL + 2;
532 restore_info[restore_index].value = value8;
534 value8 = (u8)(value8 & ~(BIT(6)));
535 HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2,
536 value8); /* Disable ptcl tx bcnq */
538 restore_info[restore_index].length = 2;
539 restore_info[restore_index].mac_register = REG_FIFOPAGE_CTRL_2;
540 restore_info[restore_index].value =
541 HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
545 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
546 value16); /* Set beacon header to 0 */
548 value16 = (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) &
551 HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
552 value16); /* MCU/FW setting */
554 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CPU_DMEM_CON + 2);
556 HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
558 HALMAC_REG_WRITE_8(halmac_adapter, REG_CPU_DMEM_CON + 2, value8);
560 /* Download to DMEM */
561 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX;
562 temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
563 HALMAC_FWHDR_OFFSET_DMEM_ADDR_88XX))) &
565 if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
566 dmem_pkt_size) != HALMAC_RET_SUCCESS)
569 /* Download to IMEM */
570 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size;
571 temp = le32_to_cpu(*((__le32 *)(hamacl_fw +
572 HALMAC_FWHDR_OFFSET_IRAM_ADDR_88XX))) &
574 if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, temp,
575 iram_pkt_size) != HALMAC_RET_SUCCESS)
578 /* Download to EMEM */
579 if (eram_pkt_size != 0) {
580 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
582 dest = le32_to_cpu((*((__le32 *)(hamacl_fw +
583 HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX)))) &
585 if (halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
591 halmac_init_offload_feature_state_machine_88xx(halmac_adapter);
594 halmac_restore_mac_register_88xx(halmac_adapter, restore_info,
595 DLFW_RESTORE_REG_NUM_88XX);
597 if (halmac_dlfw_end_flow_88xx(halmac_adapter) != HALMAC_RET_SUCCESS)
600 halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_DONE;
602 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
603 "%s <==========\n", __func__);
605 return HALMAC_RET_SUCCESS;
609 /* Disable FWDL_EN */
611 halmac_adapter, REG_MCUFW_CTRL,
612 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
615 return HALMAC_RET_DLFW_FAIL;
619 * halmac_free_download_firmware_88xx() - download specific memory firmware
621 * @dlfw_mem : memory selection
622 * @hamacl_fw : firmware bin
623 * @halmac_fw_size : firmware size
624 * Author : KaiYuan Chang/Ivan Lin
625 * Return : enum halmac_ret_status
627 enum halmac_ret_status
628 halmac_free_download_firmware_88xx(struct halmac_adapter *halmac_adapter,
629 enum halmac_dlfw_mem dlfw_mem, u8 *hamacl_fw,
636 u32 iram_pkt_size, dmem_pkt_size, eram_pkt_size = 0;
637 void *driver_adapter = NULL;
638 enum halmac_ret_status status = HALMAC_RET_DLFW_FAIL;
639 struct halmac_api *halmac_api;
641 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
642 return HALMAC_RET_ADAPTER_INVALID;
644 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
645 return HALMAC_RET_API_INVALID;
647 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
648 return HALMAC_RET_NO_DLFW;
650 driver_adapter = halmac_adapter->driver_adapter;
651 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
653 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
654 "[TRACE]%s ==========>\n", __func__);
656 if (halmac_fw_size > HALMAC_FW_SIZE_MAX_88XX ||
657 halmac_fw_size < HALMAC_FWHDR_SIZE_88XX) {
658 pr_err("[ERR]FW size error!\n");
659 return HALMAC_RET_FW_SIZE_ERR;
663 le32_to_cpu(*(__le32 *)(hamacl_fw +
664 HALMAC_FWHDR_OFFSET_DMEM_SIZE_88XX));
666 le32_to_cpu(*(__le32 *)(hamacl_fw +
667 HALMAC_FWHDR_OFFSET_IRAM_SIZE_88XX));
668 if (((*(hamacl_fw + HALMAC_FWHDR_OFFSET_MEM_USAGE_88XX)) & BIT(4)) != 0)
670 le32_to_cpu(*(__le32 *)(hamacl_fw +
671 HALMAC_FWHDR_OFFSET_ERAM_SIZE_88XX));
673 dmem_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
674 iram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
675 if (eram_pkt_size != 0)
676 eram_pkt_size += HALMAC_FW_CHKSUM_DUMMY_SIZE_88XX;
678 if (halmac_fw_size != (HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
679 iram_pkt_size + eram_pkt_size)) {
680 pr_err("[ERR]FW size mismatch the real fw size!\n");
681 return HALMAC_RET_DLFW_FAIL;
684 tx_pause_backup = HALMAC_REG_READ_8(halmac_adapter, REG_TXPAUSE);
685 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE,
686 tx_pause_backup | BIT(7));
689 HALMAC_REG_READ_16(halmac_adapter, REG_FIFOPAGE_CTRL_2) |
691 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0x8000);
693 if (eram_pkt_size != 0) {
694 file_ptr = hamacl_fw + HALMAC_FWHDR_SIZE_88XX + dmem_pkt_size +
696 dest = le32_to_cpu(*((__le32 *)(hamacl_fw +
697 HALMAC_FWHDR_OFFSET_EMEM_ADDR_88XX))) &
699 status = halmac_dlfw_to_mem_88xx(halmac_adapter, file_ptr, dest,
701 if (status != HALMAC_RET_SUCCESS)
705 status = halmac_free_dl_fw_end_flow_88xx(halmac_adapter);
708 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXPAUSE, tx_pause_backup);
709 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
712 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
713 "[TRACE]%s <==========\n", __func__);
719 * halmac_get_fw_version_88xx() - get FW version
720 * @halmac_adapter : the adapter of halmac
721 * @fw_version : fw version info
723 * Return : enum halmac_ret_status
724 * More details of status code can be found in prototype document
726 enum halmac_ret_status
727 halmac_get_fw_version_88xx(struct halmac_adapter *halmac_adapter,
728 struct halmac_fw_version *fw_version)
730 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
731 return HALMAC_RET_ADAPTER_INVALID;
733 if (halmac_adapter->halmac_state.dlfw_state == 0)
734 return HALMAC_RET_DLFW_FAIL;
736 fw_version->version = halmac_adapter->fw_version.version;
737 fw_version->sub_version = halmac_adapter->fw_version.sub_version;
738 fw_version->sub_index = halmac_adapter->fw_version.sub_index;
740 return HALMAC_RET_SUCCESS;
744 * halmac_cfg_mac_addr_88xx() - config mac address
745 * @halmac_adapter : the adapter of halmac
746 * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
747 * @hal_address : mac address
748 * Author : KaiYuan Chang/Ivan Lin
749 * Return : enum halmac_ret_status
750 * More details of status code can be found in prototype document
752 enum halmac_ret_status
753 halmac_cfg_mac_addr_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
754 union halmac_wlan_addr *hal_address)
758 void *driver_adapter = NULL;
759 struct halmac_api *halmac_api;
761 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
762 return HALMAC_RET_ADAPTER_INVALID;
764 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
765 return HALMAC_RET_API_INVALID;
767 driver_adapter = halmac_adapter->driver_adapter;
768 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
770 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
771 "[TRACE]%s ==========>\n", __func__);
773 if (halmac_port >= HALMAC_PORTIDMAX) {
774 pr_err("[ERR]port index > 5\n");
775 return HALMAC_RET_PORT_NOT_SUPPORT;
778 mac_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
779 mac_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
781 halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_low =
783 halmac_adapter->hal_mac_addr[halmac_port].address_l_h.address_high =
786 switch (halmac_port) {
788 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID, mac_address_L);
789 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID + 4,
794 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID1, mac_address_L);
795 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID1 + 4,
800 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID2, mac_address_L);
801 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID2 + 4,
806 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID3, mac_address_L);
807 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID3 + 4,
812 HALMAC_REG_WRITE_32(halmac_adapter, REG_MACID4, mac_address_L);
813 HALMAC_REG_WRITE_16(halmac_adapter, REG_MACID4 + 4,
822 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
823 "[TRACE]%s <==========\n", __func__);
825 return HALMAC_RET_SUCCESS;
829 * halmac_cfg_bssid_88xx() - config BSSID
830 * @halmac_adapter : the adapter of halmac
831 * @halmac_port :0 for port0, 1 for port1, 2 for port2, 3 for port3, 4 for port4
832 * @hal_address : bssid
833 * Author : KaiYuan Chang/Ivan Lin
834 * Return : enum halmac_ret_status
835 * More details of status code can be found in prototype document
837 enum halmac_ret_status
838 halmac_cfg_bssid_88xx(struct halmac_adapter *halmac_adapter, u8 halmac_port,
839 union halmac_wlan_addr *hal_address)
843 void *driver_adapter = NULL;
844 struct halmac_api *halmac_api;
846 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
847 return HALMAC_RET_ADAPTER_INVALID;
849 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
850 return HALMAC_RET_API_INVALID;
852 driver_adapter = halmac_adapter->driver_adapter;
853 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
855 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
856 "[TRACE]%s ==========>\n", __func__);
858 if (halmac_port >= HALMAC_PORTIDMAX) {
859 pr_err("[ERR]port index > 5\n");
860 return HALMAC_RET_PORT_NOT_SUPPORT;
863 bssid_address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
864 bssid_address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
866 halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_low =
868 halmac_adapter->hal_bss_addr[halmac_port].address_l_h.address_high =
871 switch (halmac_port) {
873 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID, bssid_address_L);
874 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID + 4,
879 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID1,
881 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID1 + 4,
886 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID2,
888 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID2 + 4,
893 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID3,
895 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID3 + 4,
900 HALMAC_REG_WRITE_32(halmac_adapter, REG_BSSID4,
902 HALMAC_REG_WRITE_16(halmac_adapter, REG_BSSID4 + 4,
911 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
912 "[TRACE]%s <==========\n", __func__);
914 return HALMAC_RET_SUCCESS;
918 * halmac_cfg_multicast_addr_88xx() - config multicast address
919 * @halmac_adapter : the adapter of halmac
920 * @hal_address : multicast address
921 * Author : KaiYuan Chang/Ivan Lin
922 * Return : enum halmac_ret_status
923 * More details of status code can be found in prototype document
925 enum halmac_ret_status
926 halmac_cfg_multicast_addr_88xx(struct halmac_adapter *halmac_adapter,
927 union halmac_wlan_addr *hal_address)
931 void *driver_adapter = NULL;
932 struct halmac_api *halmac_api;
934 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
935 return HALMAC_RET_ADAPTER_INVALID;
937 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
938 return HALMAC_RET_API_INVALID;
940 halmac_api_record_id_88xx(halmac_adapter,
941 HALMAC_API_CFG_MULTICAST_ADDR);
943 driver_adapter = halmac_adapter->driver_adapter;
944 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
946 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
947 "%s ==========>\n", __func__);
949 address_L = le32_to_cpu(hal_address->address_l_h.le_address_low);
950 address_H = le16_to_cpu(hal_address->address_l_h.le_address_high);
952 HALMAC_REG_WRITE_32(halmac_adapter, REG_MAR, address_L);
953 HALMAC_REG_WRITE_16(halmac_adapter, REG_MAR + 4, address_H);
955 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
956 "%s <==========\n", __func__);
958 return HALMAC_RET_SUCCESS;
962 * halmac_pre_init_system_cfg_88xx() - pre-init system config
963 * @halmac_adapter : the adapter of halmac
964 * Author : KaiYuan Chang/Ivan Lin
965 * Return : enum halmac_ret_status
966 * More details of status code can be found in prototype document
968 enum halmac_ret_status
969 halmac_pre_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
971 u32 value32, counter;
972 void *driver_adapter = NULL;
973 struct halmac_api *halmac_api;
976 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
977 return HALMAC_RET_ADAPTER_INVALID;
979 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
980 return HALMAC_RET_API_INVALID;
982 halmac_api_record_id_88xx(halmac_adapter,
983 HALMAC_API_PRE_INIT_SYSTEM_CFG);
985 driver_adapter = halmac_adapter->driver_adapter;
986 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
988 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
989 "halmac_pre_init_system_cfg ==========>\n");
991 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
993 halmac_adapter, REG_SDIO_HSUS_CTRL,
994 HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
997 while (!(HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HSUS_CTRL) &
1001 return HALMAC_RET_SDIO_LEAVE_SUSPEND_FAIL;
1003 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
1004 if (HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) ==
1007 halmac_adapter, 0xFE5B,
1008 HALMAC_REG_READ_8(halmac_adapter, 0xFE5B) |
1012 /* Config PIN Mux */
1013 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL1);
1014 value32 = value32 & (~(BIT(28) | BIT(29)));
1015 value32 = value32 | BIT(28) | BIT(29);
1016 HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL1, value32);
1018 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_LED_CFG);
1019 value32 = value32 & (~(BIT(25) | BIT(26)));
1020 HALMAC_REG_WRITE_32(halmac_adapter, REG_LED_CFG, value32);
1022 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_GPIO_MUXCFG);
1023 value32 = value32 & (~(BIT(2)));
1024 value32 = value32 | BIT(2);
1025 HALMAC_REG_WRITE_32(halmac_adapter, REG_GPIO_MUXCFG, value32);
1028 halmac_set_hw_value_88xx(halmac_adapter, HALMAC_HW_EN_BB_RF,
1031 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1032 "halmac_pre_init_system_cfg <==========\n");
1034 return HALMAC_RET_SUCCESS;
1038 * halmac_init_system_cfg_88xx() - init system config
1039 * @halmac_adapter : the adapter of halmac
1040 * Author : KaiYuan Chang/Ivan Lin
1041 * Return : enum halmac_ret_status
1042 * More details of status code can be found in prototype document
1044 enum halmac_ret_status
1045 halmac_init_system_cfg_88xx(struct halmac_adapter *halmac_adapter)
1047 void *driver_adapter = NULL;
1048 struct halmac_api *halmac_api;
1050 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1051 return HALMAC_RET_ADAPTER_INVALID;
1053 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1054 return HALMAC_RET_API_INVALID;
1056 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_SYSTEM_CFG);
1058 driver_adapter = halmac_adapter->driver_adapter;
1059 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1061 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1062 "halmac_init_system_cfg ==========>\n");
1064 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
1065 HALMAC_FUNCTION_ENABLE_88XX);
1066 HALMAC_REG_WRITE_32(
1067 halmac_adapter, REG_SYS_SDIO_CTRL,
1068 (u32)(HALMAC_REG_READ_32(halmac_adapter, REG_SYS_SDIO_CTRL) |
1069 BIT_LTE_MUX_CTRL_PATH));
1070 HALMAC_REG_WRITE_32(
1071 halmac_adapter, REG_CPU_DMEM_CON,
1072 (u32)(HALMAC_REG_READ_32(halmac_adapter, REG_CPU_DMEM_CON) |
1073 BIT_WL_PLATFORM_RST));
1075 /* halmac_api->halmac_init_h2c(halmac_adapter); */
1077 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1078 "halmac_init_system_cfg <==========\n");
1080 return HALMAC_RET_SUCCESS;
1084 * halmac_init_edca_cfg_88xx() - init EDCA config
1085 * @halmac_adapter : the adapter of halmac
1086 * Author : KaiYuan Chang/Ivan Lin
1087 * Return : enum halmac_ret_status
1088 * More details of status code can be found in prototype document
1090 enum halmac_ret_status
1091 halmac_init_edca_cfg_88xx(struct halmac_adapter *halmac_adapter)
1095 void *driver_adapter = NULL;
1096 struct halmac_api *halmac_api;
1098 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1099 return HALMAC_RET_ADAPTER_INVALID;
1101 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1102 return HALMAC_RET_API_INVALID;
1104 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_EDCA_CFG);
1106 driver_adapter = halmac_adapter->driver_adapter;
1107 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1109 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1110 "%s ==========>\n", __func__);
1112 /* Clear TX pause */
1113 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXPAUSE, 0x0000);
1115 HALMAC_REG_WRITE_8(halmac_adapter, REG_SLOT, HALMAC_SLOT_TIME_88XX);
1116 HALMAC_REG_WRITE_8(halmac_adapter, REG_PIFS, HALMAC_PIFS_TIME_88XX);
1117 value32 = HALMAC_SIFS_CCK_CTX_88XX |
1118 (HALMAC_SIFS_OFDM_CTX_88XX << BIT_SHIFT_SIFS_OFDM_CTX) |
1119 (HALMAC_SIFS_CCK_TRX_88XX << BIT_SHIFT_SIFS_CCK_TRX) |
1120 (HALMAC_SIFS_OFDM_TRX_88XX << BIT_SHIFT_SIFS_OFDM_TRX);
1121 HALMAC_REG_WRITE_32(halmac_adapter, REG_SIFS, value32);
1123 HALMAC_REG_WRITE_32(
1124 halmac_adapter, REG_EDCA_VO_PARAM,
1125 HALMAC_REG_READ_32(halmac_adapter, REG_EDCA_VO_PARAM) & 0xFFFF);
1126 HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VO_PARAM + 2,
1127 HALMAC_VO_TXOP_LIMIT_88XX);
1128 HALMAC_REG_WRITE_16(halmac_adapter, REG_EDCA_VI_PARAM + 2,
1129 HALMAC_VI_TXOP_LIMIT_88XX);
1131 HALMAC_REG_WRITE_32(halmac_adapter, REG_RD_NAV_NXT,
1132 HALMAC_RDG_NAV_88XX | (HALMAC_TXOP_NAV_88XX << 16));
1133 HALMAC_REG_WRITE_16(halmac_adapter, REG_RXTSF_OFFSET_CCK,
1134 HALMAC_CCK_RX_TSF_88XX |
1135 (HALMAC_OFDM_RX_TSF_88XX) << 8);
1137 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RD_CTRL + 1);
1139 (BIT_VOQ_RD_INIT_EN | BIT_VIQ_RD_INIT_EN | BIT_BEQ_RD_INIT_EN);
1140 HALMAC_REG_WRITE_8(halmac_adapter, REG_RD_CTRL + 1, value8);
1142 /* Set beacon cotnrol - enable TSF and other related functions */
1144 halmac_adapter, REG_BCN_CTRL,
1145 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL) |
1146 BIT_EN_BCN_FUNCTION));
1148 /* Set send beacon related registers */
1149 HALMAC_REG_WRITE_32(halmac_adapter, REG_TBTT_PROHIBIT,
1150 HALMAC_TBTT_PROHIBIT_88XX |
1151 (HALMAC_TBTT_HOLD_TIME_88XX
1152 << BIT_SHIFT_TBTT_HOLD_TIME_AP));
1153 HALMAC_REG_WRITE_8(halmac_adapter, REG_DRVERLYINT,
1154 HALMAC_DRIVER_EARLY_INT_88XX);
1155 HALMAC_REG_WRITE_8(halmac_adapter, REG_BCNDMATIM,
1156 HALMAC_BEACON_DMA_TIM_88XX);
1158 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1159 "%s <==========\n", __func__);
1161 return HALMAC_RET_SUCCESS;
1165 * halmac_init_wmac_cfg_88xx() - init wmac config
1166 * @halmac_adapter : the adapter of halmac
1167 * Author : KaiYuan Chang/Ivan Lin
1168 * Return : enum halmac_ret_status
1169 * More details of status code can be found in prototype document
1171 enum halmac_ret_status
1172 halmac_init_wmac_cfg_88xx(struct halmac_adapter *halmac_adapter)
1174 void *driver_adapter = NULL;
1175 struct halmac_api *halmac_api;
1177 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1178 return HALMAC_RET_ADAPTER_INVALID;
1180 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1181 return HALMAC_RET_API_INVALID;
1183 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_WMAC_CFG);
1185 driver_adapter = halmac_adapter->driver_adapter;
1186 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1188 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1189 "%s ==========>\n", __func__);
1191 HALMAC_REG_WRITE_32(halmac_adapter, REG_RXFLTMAP0,
1192 HALMAC_RX_FILTER0_88XX);
1193 HALMAC_REG_WRITE_16(halmac_adapter, REG_RXFLTMAP,
1194 HALMAC_RX_FILTER_88XX);
1196 HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, HALMAC_RCR_CONFIG_88XX);
1199 halmac_adapter, REG_TCR + 1,
1200 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_TCR + 1) | 0x30));
1201 HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 2, 0x30);
1202 HALMAC_REG_WRITE_8(halmac_adapter, REG_TCR + 1, 0x00);
1204 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 8,
1206 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
1209 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1210 "%s <==========\n", __func__);
1212 return HALMAC_RET_SUCCESS;
1216 * halmac_init_mac_cfg_88xx() - config page1~page7 register
1217 * @halmac_adapter : the adapter of halmac
1219 * Author : KaiYuan Chang/Ivan Lin
1220 * Return : enum halmac_ret_status
1221 * More details of status code can be found in prototype document
1223 enum halmac_ret_status
1224 halmac_init_mac_cfg_88xx(struct halmac_adapter *halmac_adapter,
1225 enum halmac_trx_mode mode)
1227 void *driver_adapter = NULL;
1228 struct halmac_api *halmac_api;
1229 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1231 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1232 return HALMAC_RET_ADAPTER_INVALID;
1234 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1235 return HALMAC_RET_API_INVALID;
1237 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_INIT_MAC_CFG);
1239 driver_adapter = halmac_adapter->driver_adapter;
1240 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1242 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1243 "%s ==========>mode = %d\n", __func__,
1246 status = halmac_api->halmac_init_trx_cfg(halmac_adapter, mode);
1247 if (status != HALMAC_RET_SUCCESS) {
1248 pr_err("halmac_init_trx_cfg error = %x\n", status);
1251 status = halmac_api->halmac_init_protocol_cfg(halmac_adapter);
1252 if (status != HALMAC_RET_SUCCESS) {
1253 pr_err("halmac_init_protocol_cfg_88xx error = %x\n", status);
1257 status = halmac_init_edca_cfg_88xx(halmac_adapter);
1258 if (status != HALMAC_RET_SUCCESS) {
1259 pr_err("halmac_init_edca_cfg_88xx error = %x\n", status);
1263 status = halmac_init_wmac_cfg_88xx(halmac_adapter);
1264 if (status != HALMAC_RET_SUCCESS) {
1265 pr_err("halmac_init_wmac_cfg_88xx error = %x\n", status);
1268 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1269 "%s <==========\n", __func__);
1275 * halmac_cfg_operation_mode_88xx() - config operation mode
1276 * @halmac_adapter : the adapter of halmac
1277 * @wireless_mode : 802.11 standard(b/g/n/ac)
1278 * Author : KaiYuan Chang/Ivan Lin
1279 * Return : enum halmac_ret_status
1280 * More details of status code can be found in prototype document
1282 enum halmac_ret_status
1283 halmac_cfg_operation_mode_88xx(struct halmac_adapter *halmac_adapter,
1284 enum halmac_wireless_mode wireless_mode)
1286 void *driver_adapter = NULL;
1287 enum halmac_wireless_mode wireless_mode_local =
1288 HALMAC_WIRELESS_MODE_UNDEFINE;
1290 wireless_mode_local = wireless_mode;
1292 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1293 return HALMAC_RET_ADAPTER_INVALID;
1295 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1296 return HALMAC_RET_API_INVALID;
1298 halmac_api_record_id_88xx(halmac_adapter,
1299 HALMAC_API_CFG_OPERATION_MODE);
1301 driver_adapter = halmac_adapter->driver_adapter;
1304 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1305 "%s ==========>wireless_mode = %d\n", __func__,
1308 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1309 "%s <==========\n", __func__);
1311 return HALMAC_RET_SUCCESS;
1315 * halmac_cfg_ch_bw_88xx() - config channel & bandwidth
1316 * @halmac_adapter : the adapter of halmac
1317 * @channel : WLAN channel, support 2.4G & 5G
1318 * @pri_ch_idx : primary channel index, idx1, idx2, idx3, idx4
1319 * @bw : band width, 20, 40, 80, 160, 5 ,10
1320 * Author : KaiYuan Chang
1321 * Return : enum halmac_ret_status
1322 * More details of status code can be found in prototype document
1324 enum halmac_ret_status
1325 halmac_cfg_ch_bw_88xx(struct halmac_adapter *halmac_adapter, u8 channel,
1326 enum halmac_pri_ch_idx pri_ch_idx, enum halmac_bw bw)
1328 void *driver_adapter = NULL;
1329 struct halmac_api *halmac_api;
1331 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1332 return HALMAC_RET_ADAPTER_INVALID;
1334 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1335 return HALMAC_RET_API_INVALID;
1337 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1339 driver_adapter = halmac_adapter->driver_adapter;
1340 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1342 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1343 "%s ==========>ch = %d, idx=%d, bw=%d\n", __func__,
1344 channel, pri_ch_idx, bw);
1346 halmac_cfg_pri_ch_idx_88xx(halmac_adapter, pri_ch_idx);
1348 halmac_cfg_bw_88xx(halmac_adapter, bw);
1350 halmac_cfg_ch_88xx(halmac_adapter, channel);
1352 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1353 "%s <==========\n", __func__);
1355 return HALMAC_RET_SUCCESS;
1358 enum halmac_ret_status halmac_cfg_ch_88xx(struct halmac_adapter *halmac_adapter,
1362 void *driver_adapter = NULL;
1363 struct halmac_api *halmac_api;
1365 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1366 return HALMAC_RET_ADAPTER_INVALID;
1368 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1369 return HALMAC_RET_API_INVALID;
1371 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1373 driver_adapter = halmac_adapter->driver_adapter;
1374 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1376 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1377 "%s ==========>ch = %d\n", __func__, channel);
1379 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CCK_CHECK);
1380 value8 = value8 & (~(BIT(7)));
1383 value8 = value8 | BIT(7);
1385 HALMAC_REG_WRITE_8(halmac_adapter, REG_CCK_CHECK, value8);
1387 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1388 "%s <==========\n", __func__);
1390 return HALMAC_RET_SUCCESS;
1393 enum halmac_ret_status
1394 halmac_cfg_pri_ch_idx_88xx(struct halmac_adapter *halmac_adapter,
1395 enum halmac_pri_ch_idx pri_ch_idx)
1397 u8 txsc_40 = 0, txsc_20 = 0;
1398 void *driver_adapter = NULL;
1399 struct halmac_api *halmac_api;
1401 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1402 return HALMAC_RET_ADAPTER_INVALID;
1404 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1405 return HALMAC_RET_API_INVALID;
1407 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CH_BW);
1409 driver_adapter = halmac_adapter->driver_adapter;
1410 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1412 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1413 "%s ==========> idx=%d\n", __func__,
1416 txsc_20 = pri_ch_idx;
1417 if (txsc_20 == HALMAC_CH_IDX_1 || txsc_20 == HALMAC_CH_IDX_3)
1422 HALMAC_REG_WRITE_8(halmac_adapter, REG_DATA_SC,
1423 BIT_TXSC_20M(txsc_20) | BIT_TXSC_40M(txsc_40));
1425 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1426 "%s <==========\n", __func__);
1428 return HALMAC_RET_SUCCESS;
1432 * halmac_cfg_bw_88xx() - config bandwidth
1433 * @halmac_adapter : the adapter of halmac
1434 * @bw : band width, 20, 40, 80, 160, 5 ,10
1435 * Author : KaiYuan Chang
1436 * Return : enum halmac_ret_status
1437 * More details of status code can be found in prototype document
1439 enum halmac_ret_status halmac_cfg_bw_88xx(struct halmac_adapter *halmac_adapter,
1443 void *driver_adapter = NULL;
1444 struct halmac_api *halmac_api;
1446 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1447 return HALMAC_RET_ADAPTER_INVALID;
1449 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1450 return HALMAC_RET_API_INVALID;
1452 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_BW);
1454 driver_adapter = halmac_adapter->driver_adapter;
1455 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1457 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1458 "%s ==========>bw=%d\n", __func__, bw);
1461 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL);
1462 value32 = value32 & (~(BIT(7) | BIT(8)));
1466 value32 = value32 | BIT(7);
1469 value32 = value32 | BIT(8);
1476 pr_err("%s switch case not support\n", __func__);
1479 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_TRXPTCL_CTL, value32);
1482 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_AFE_CTRL1);
1483 value32 = (value32 & (~(BIT(20) | BIT(21)))) |
1484 (HALMAC_MAC_CLOCK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL);
1485 HALMAC_REG_WRITE_32(halmac_adapter, REG_AFE_CTRL1, value32);
1487 HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_TSF,
1488 HALMAC_MAC_CLOCK_88XX);
1489 HALMAC_REG_WRITE_8(halmac_adapter, REG_USTIME_EDCA,
1490 HALMAC_MAC_CLOCK_88XX);
1492 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1493 "%s <==========\n", __func__);
1495 return HALMAC_RET_SUCCESS;
1499 * halmac_dump_efuse_map_88xx() - dump "physical" efuse map
1500 * @halmac_adapter : the adapter of halmac
1501 * @cfg : dump efuse method
1502 * Author : Ivan Lin/KaiYuan Chang
1503 * Return : enum halmac_ret_status
1504 * More details of status code can be found in prototype document
1506 enum halmac_ret_status
1507 halmac_dump_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
1508 enum halmac_efuse_read_cfg cfg)
1510 void *driver_adapter = NULL;
1511 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1512 enum halmac_cmd_process_status *process_status =
1513 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1515 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1516 return HALMAC_RET_ADAPTER_INVALID;
1518 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1519 return HALMAC_RET_API_INVALID;
1521 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP);
1523 driver_adapter = halmac_adapter->driver_adapter;
1525 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1526 "%s ==========>cfg=%d\n", __func__, cfg);
1528 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1529 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1530 "Wait event(dump efuse)...\n");
1531 return HALMAC_RET_BUSY_STATE;
1534 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1535 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1536 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1537 "Not idle state(dump efuse)...\n");
1538 return HALMAC_RET_ERROR_STATE;
1541 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
1542 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
1543 "[WARN]Dump efuse in suspend mode\n");
1545 *process_status = HALMAC_CMD_PROCESS_IDLE;
1546 halmac_adapter->event_trigger.physical_efuse_map = 1;
1548 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1549 HALMAC_EFUSE_BANK_WIFI);
1550 if (status != HALMAC_RET_SUCCESS) {
1551 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1555 status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
1557 if (status != HALMAC_RET_SUCCESS) {
1558 pr_err("halmac_read_efuse error = %x\n", status);
1562 if (halmac_adapter->hal_efuse_map_valid) {
1563 *process_status = HALMAC_CMD_PROCESS_DONE;
1565 PLATFORM_EVENT_INDICATION(
1566 driver_adapter, HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
1567 *process_status, halmac_adapter->hal_efuse_map,
1568 halmac_adapter->hw_config_info.efuse_size);
1569 halmac_adapter->event_trigger.physical_efuse_map = 0;
1572 if (halmac_transition_efuse_state_88xx(
1573 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1575 return HALMAC_RET_ERROR_STATE;
1577 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1578 "%s <==========\n", __func__);
1580 return HALMAC_RET_SUCCESS;
1584 * halmac_dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
1585 * @halmac_adapter : the adapter of halmac
1586 * @halmac_efuse_bank : bt efuse bank
1587 * @bt_efuse_map_size : bt efuse map size. get from halmac_get_efuse_size API
1588 * @bt_efuse_map : bt efuse map
1589 * Author : Soar / Ivan Lin
1590 * Return : enum halmac_ret_status
1591 * More details of status code can be found in prototype document
1593 enum halmac_ret_status
1594 halmac_dump_efuse_map_bt_88xx(struct halmac_adapter *halmac_adapter,
1595 enum halmac_efuse_bank halmac_efuse_bank,
1596 u32 bt_efuse_map_size, u8 *bt_efuse_map)
1598 void *driver_adapter = NULL;
1599 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1600 enum halmac_cmd_process_status *process_status =
1601 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1603 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1604 return HALMAC_RET_ADAPTER_INVALID;
1606 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1607 return HALMAC_RET_API_INVALID;
1609 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_EFUSE_MAP_BT);
1611 driver_adapter = halmac_adapter->driver_adapter;
1613 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1614 "%s ==========>\n", __func__);
1616 if (halmac_adapter->hw_config_info.bt_efuse_size != bt_efuse_map_size)
1617 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
1619 if ((halmac_efuse_bank >= HALMAC_EFUSE_BANK_MAX) ||
1620 halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
1621 pr_err("Undefined BT bank\n");
1622 return HALMAC_RET_EFUSE_BANK_INCORRECT;
1625 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1626 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1627 "Wait event(dump efuse)...\n");
1628 return HALMAC_RET_BUSY_STATE;
1631 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1632 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1633 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1634 "Not idle state(dump efuse)...\n");
1635 return HALMAC_RET_ERROR_STATE;
1638 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1640 if (status != HALMAC_RET_SUCCESS) {
1641 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1645 status = halmac_read_hw_efuse_88xx(halmac_adapter, 0, bt_efuse_map_size,
1648 if (status != HALMAC_RET_SUCCESS) {
1649 pr_err("halmac_read_hw_efuse_88xx error = %x\n", status);
1653 if (halmac_transition_efuse_state_88xx(
1654 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1656 return HALMAC_RET_ERROR_STATE;
1658 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1659 "%s <==========\n", __func__);
1661 return HALMAC_RET_SUCCESS;
1665 * halmac_write_efuse_bt_88xx() - write "BT physical" efuse offset
1666 * @halmac_adapter : the adapter of halmac
1667 * @halmac_offset : offset
1668 * @halmac_value : Write value
1669 * @bt_efuse_map : bt efuse map
1671 * Return : enum halmac_ret_status
1672 * More details of status code can be found in prototype document
1674 enum halmac_ret_status
1675 halmac_write_efuse_bt_88xx(struct halmac_adapter *halmac_adapter,
1676 u32 halmac_offset, u8 halmac_value,
1677 enum halmac_efuse_bank halmac_efuse_bank)
1679 void *driver_adapter = NULL;
1680 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1682 enum halmac_cmd_process_status *process_status =
1683 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1685 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1686 return HALMAC_RET_ADAPTER_INVALID;
1688 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1689 return HALMAC_RET_API_INVALID;
1691 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_WRITE_EFUSE_BT);
1693 driver_adapter = halmac_adapter->driver_adapter;
1695 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1696 "%s ==========>\n", __func__);
1697 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1698 "offset : %X value : %X Bank : %X\n", halmac_offset,
1699 halmac_value, halmac_efuse_bank);
1701 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1702 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1703 "Wait/Rcvd event(dump efuse)...\n");
1704 return HALMAC_RET_BUSY_STATE;
1707 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1708 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1709 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1710 "Not idle state(dump efuse)...\n");
1711 return HALMAC_RET_ERROR_STATE;
1714 if (halmac_offset >= halmac_adapter->hw_config_info.efuse_size) {
1715 pr_err("Offset is too large\n");
1716 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
1719 if (halmac_efuse_bank > HALMAC_EFUSE_BANK_MAX ||
1720 halmac_efuse_bank == HALMAC_EFUSE_BANK_WIFI) {
1721 pr_err("Undefined BT bank\n");
1722 return HALMAC_RET_EFUSE_BANK_INCORRECT;
1725 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1727 if (status != HALMAC_RET_SUCCESS) {
1728 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1732 status = halmac_func_write_efuse_88xx(halmac_adapter, halmac_offset,
1734 if (status != HALMAC_RET_SUCCESS) {
1735 pr_err("halmac_func_write_efuse error = %x\n", status);
1739 if (halmac_transition_efuse_state_88xx(
1740 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1742 return HALMAC_RET_ERROR_STATE;
1744 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1745 "%s <==========\n", __func__);
1747 return HALMAC_RET_SUCCESS;
1751 * halmac_get_efuse_available_size_88xx() - get efuse available size
1752 * @halmac_adapter : the adapter of halmac
1753 * @halmac_size : physical efuse available size
1755 * Return : enum halmac_ret_status
1756 * More details of status code can be found in prototype document
1758 enum halmac_ret_status
1759 halmac_get_efuse_available_size_88xx(struct halmac_adapter *halmac_adapter,
1762 enum halmac_ret_status status;
1763 void *driver_adapter = NULL;
1765 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1766 return HALMAC_RET_ADAPTER_INVALID;
1768 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1769 return HALMAC_RET_API_INVALID;
1771 driver_adapter = halmac_adapter->driver_adapter;
1773 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1774 "%s ==========>\n", __func__);
1776 status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
1777 HALMAC_EFUSE_R_DRV);
1779 if (status != HALMAC_RET_SUCCESS)
1782 *halmac_size = halmac_adapter->hw_config_info.efuse_size -
1783 HALMAC_PROTECTED_EFUSE_SIZE_88XX -
1784 halmac_adapter->efuse_end;
1786 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1787 "%s <==========\n", __func__);
1789 return HALMAC_RET_SUCCESS;
1793 * halmac_get_efuse_size_88xx() - get "physical" efuse size
1794 * @halmac_adapter : the adapter of halmac
1795 * @halmac_size : physical efuse size
1796 * Author : Ivan Lin/KaiYuan Chang
1797 * Return : enum halmac_ret_status
1798 * More details of status code can be found in prototype document
1800 enum halmac_ret_status
1801 halmac_get_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
1804 void *driver_adapter = NULL;
1806 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1807 return HALMAC_RET_ADAPTER_INVALID;
1809 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1810 return HALMAC_RET_API_INVALID;
1812 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_EFUSE_SIZE);
1814 driver_adapter = halmac_adapter->driver_adapter;
1816 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1817 "%s ==========>\n", __func__);
1819 *halmac_size = halmac_adapter->hw_config_info.efuse_size;
1821 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1822 "%s <==========\n", __func__);
1824 return HALMAC_RET_SUCCESS;
1828 * halmac_get_logical_efuse_size_88xx() - get "logical" efuse size
1829 * @halmac_adapter : the adapter of halmac
1830 * @halmac_size : logical efuse size
1831 * Author : Ivan Lin/KaiYuan Chang
1832 * Return : enum halmac_ret_status
1833 * More details of status code can be found in prototype document
1835 enum halmac_ret_status
1836 halmac_get_logical_efuse_size_88xx(struct halmac_adapter *halmac_adapter,
1839 void *driver_adapter = NULL;
1841 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1842 return HALMAC_RET_ADAPTER_INVALID;
1844 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1845 return HALMAC_RET_API_INVALID;
1847 halmac_api_record_id_88xx(halmac_adapter,
1848 HALMAC_API_GET_LOGICAL_EFUSE_SIZE);
1850 driver_adapter = halmac_adapter->driver_adapter;
1852 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1853 "%s ==========>\n", __func__);
1855 *halmac_size = halmac_adapter->hw_config_info.eeprom_size;
1857 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1858 "%s <==========\n", __func__);
1860 return HALMAC_RET_SUCCESS;
1864 * halmac_dump_logical_efuse_map_88xx() - dump "logical" efuse map
1865 * @halmac_adapter : the adapter of halmac
1866 * @cfg : dump efuse method
1868 * Return : enum halmac_ret_status
1869 * More details of status code can be found in prototype document
1871 enum halmac_ret_status
1872 halmac_dump_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
1873 enum halmac_efuse_read_cfg cfg)
1875 u8 *eeprom_map = NULL;
1876 u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
1877 void *driver_adapter = NULL;
1878 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1879 enum halmac_cmd_process_status *process_status =
1880 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1882 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1883 return HALMAC_RET_ADAPTER_INVALID;
1885 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1886 return HALMAC_RET_API_INVALID;
1888 halmac_api_record_id_88xx(halmac_adapter,
1889 HALMAC_API_DUMP_LOGICAL_EFUSE_MAP);
1891 driver_adapter = halmac_adapter->driver_adapter;
1893 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1894 "%s ==========>cfg = %d\n", __func__, cfg);
1896 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
1897 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1898 "Wait/Rcvd event(dump efuse)...\n");
1899 return HALMAC_RET_BUSY_STATE;
1902 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
1903 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
1904 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1905 "Not idle state(dump efuse)...\n");
1906 return HALMAC_RET_ERROR_STATE;
1909 if (halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_OFF)
1910 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_WARNING,
1911 "[WARN]Dump logical efuse in suspend mode\n");
1913 *process_status = HALMAC_CMD_PROCESS_IDLE;
1914 halmac_adapter->event_trigger.logical_efuse_map = 1;
1916 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
1917 HALMAC_EFUSE_BANK_WIFI);
1918 if (status != HALMAC_RET_SUCCESS) {
1919 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
1923 status = halmac_dump_efuse_88xx(halmac_adapter, cfg);
1925 if (status != HALMAC_RET_SUCCESS) {
1926 pr_err("halmac_eeprom_parser_88xx error = %x\n", status);
1930 if (halmac_adapter->hal_efuse_map_valid) {
1931 *process_status = HALMAC_CMD_PROCESS_DONE;
1933 eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
1936 return HALMAC_RET_MALLOC_FAIL;
1938 memset(eeprom_map, 0xFF, eeprom_size);
1940 if (halmac_eeprom_parser_88xx(halmac_adapter,
1941 halmac_adapter->hal_efuse_map,
1942 eeprom_map) != HALMAC_RET_SUCCESS) {
1944 return HALMAC_RET_EEPROM_PARSING_FAIL;
1947 PLATFORM_EVENT_INDICATION(
1948 driver_adapter, HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
1949 *process_status, eeprom_map, eeprom_size);
1950 halmac_adapter->event_trigger.logical_efuse_map = 0;
1955 if (halmac_transition_efuse_state_88xx(
1956 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
1958 return HALMAC_RET_ERROR_STATE;
1960 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1961 "%s <==========\n", __func__);
1963 return HALMAC_RET_SUCCESS;
1967 * halmac_read_logical_efuse_88xx() - read logical efuse map 1 byte
1968 * @halmac_adapter : the adapter of halmac
1969 * @halmac_offset : offset
1970 * @value : 1 byte efuse value
1972 * Return : enum halmac_ret_status
1973 * More details of status code can be found in prototype document
1975 enum halmac_ret_status
1976 halmac_read_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
1977 u32 halmac_offset, u8 *value)
1979 u8 *eeprom_map = NULL;
1980 u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
1981 void *driver_adapter = NULL;
1982 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1984 enum halmac_cmd_process_status *process_status =
1985 &halmac_adapter->halmac_state.efuse_state_set.process_status;
1987 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1988 return HALMAC_RET_ADAPTER_INVALID;
1990 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
1991 return HALMAC_RET_API_INVALID;
1993 halmac_api_record_id_88xx(halmac_adapter,
1994 HALMAC_API_READ_LOGICAL_EFUSE);
1996 driver_adapter = halmac_adapter->driver_adapter;
1998 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
1999 "%s ==========>\n", __func__);
2001 if (halmac_offset >= eeprom_size) {
2002 pr_err("Offset is too large\n");
2003 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2006 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2007 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2008 "Wait/Rcvd event(dump efuse)...\n");
2009 return HALMAC_RET_BUSY_STATE;
2011 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2012 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2013 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2014 "Not idle state(dump efuse)...\n");
2015 return HALMAC_RET_ERROR_STATE;
2018 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2019 HALMAC_EFUSE_BANK_WIFI);
2020 if (status != HALMAC_RET_SUCCESS) {
2021 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2025 eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2028 return HALMAC_RET_MALLOC_FAIL;
2030 memset(eeprom_map, 0xFF, eeprom_size);
2032 status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
2033 if (status != HALMAC_RET_SUCCESS) {
2034 pr_err("halmac_read_logical_efuse_map error = %x\n", status);
2039 *value = *(eeprom_map + halmac_offset);
2041 if (halmac_transition_efuse_state_88xx(
2042 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2043 HALMAC_RET_SUCCESS) {
2045 return HALMAC_RET_ERROR_STATE;
2048 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2049 "%s <==========\n", __func__);
2053 return HALMAC_RET_SUCCESS;
2057 * halmac_write_logical_efuse_88xx() - write "logical" efuse offset
2058 * @halmac_adapter : the adapter of halmac
2059 * @halmac_offset : offset
2060 * @halmac_value : value
2062 * Return : enum halmac_ret_status
2063 * More details of status code can be found in prototype document
2065 enum halmac_ret_status
2066 halmac_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
2067 u32 halmac_offset, u8 halmac_value)
2069 void *driver_adapter = NULL;
2070 struct halmac_api *halmac_api;
2071 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2073 enum halmac_cmd_process_status *process_status =
2074 &halmac_adapter->halmac_state.efuse_state_set.process_status;
2076 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2077 return HALMAC_RET_ADAPTER_INVALID;
2079 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2080 return HALMAC_RET_API_INVALID;
2082 halmac_api_record_id_88xx(halmac_adapter,
2083 HALMAC_API_WRITE_LOGICAL_EFUSE);
2085 driver_adapter = halmac_adapter->driver_adapter;
2086 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2088 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2089 "%s ==========>\n", __func__);
2091 if (halmac_offset >= halmac_adapter->hw_config_info.eeprom_size) {
2092 pr_err("Offset is too large\n");
2093 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2096 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2097 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2098 "Wait/Rcvd event(dump efuse)...\n");
2099 return HALMAC_RET_BUSY_STATE;
2102 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2103 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2104 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2105 "Not idle state(dump efuse)...\n");
2106 return HALMAC_RET_ERROR_STATE;
2109 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2110 HALMAC_EFUSE_BANK_WIFI);
2111 if (status != HALMAC_RET_SUCCESS) {
2112 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2116 status = halmac_func_write_logical_efuse_88xx(
2117 halmac_adapter, halmac_offset, halmac_value);
2118 if (status != HALMAC_RET_SUCCESS) {
2119 pr_err("halmac_write_logical_efuse error = %x\n", status);
2123 if (halmac_transition_efuse_state_88xx(
2124 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2126 return HALMAC_RET_ERROR_STATE;
2128 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2129 "%s <==========\n", __func__);
2131 return HALMAC_RET_SUCCESS;
2135 * halmac_pg_efuse_by_map_88xx() - pg logical efuse by map
2136 * @halmac_adapter : the adapter of halmac
2137 * @pg_efuse_info : efuse map information
2138 * @cfg : dump efuse method
2140 * Return : enum halmac_ret_status
2141 * More details of status code can be found in prototype document
2143 enum halmac_ret_status
2144 halmac_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
2145 struct halmac_pg_efuse_info *pg_efuse_info,
2146 enum halmac_efuse_read_cfg cfg)
2148 void *driver_adapter = NULL;
2149 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2151 enum halmac_cmd_process_status *process_status =
2152 &halmac_adapter->halmac_state.efuse_state_set.process_status;
2154 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2155 return HALMAC_RET_ADAPTER_INVALID;
2157 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2158 return HALMAC_RET_API_INVALID;
2160 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PG_EFUSE_BY_MAP);
2162 driver_adapter = halmac_adapter->driver_adapter;
2164 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2165 "%s ==========>\n", __func__);
2167 if (pg_efuse_info->efuse_map_size !=
2168 halmac_adapter->hw_config_info.eeprom_size) {
2169 pr_err("efuse_map_size is incorrect, should be %d bytes\n",
2170 halmac_adapter->hw_config_info.eeprom_size);
2171 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2174 if ((pg_efuse_info->efuse_map_size & 0xF) > 0) {
2175 pr_err("efuse_map_size should be multiple of 16\n");
2176 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2179 if (pg_efuse_info->efuse_mask_size !=
2180 pg_efuse_info->efuse_map_size >> 4) {
2181 pr_err("efuse_mask_size is incorrect, should be %d bytes\n",
2182 pg_efuse_info->efuse_map_size >> 4);
2183 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2186 if (!pg_efuse_info->efuse_map) {
2187 pr_err("efuse_map is NULL\n");
2188 return HALMAC_RET_NULL_POINTER;
2191 if (!pg_efuse_info->efuse_mask) {
2192 pr_err("efuse_mask is NULL\n");
2193 return HALMAC_RET_NULL_POINTER;
2196 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2197 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2198 "Wait/Rcvd event(dump efuse)...\n");
2199 return HALMAC_RET_BUSY_STATE;
2202 if (halmac_query_efuse_curr_state_88xx(halmac_adapter) !=
2203 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) {
2204 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2205 "Not idle state(dump efuse)...\n");
2206 return HALMAC_RET_ERROR_STATE;
2209 status = halmac_func_switch_efuse_bank_88xx(halmac_adapter,
2210 HALMAC_EFUSE_BANK_WIFI);
2211 if (status != HALMAC_RET_SUCCESS) {
2212 pr_err("halmac_func_switch_efuse_bank error = %x\n", status);
2216 status = halmac_func_pg_efuse_by_map_88xx(halmac_adapter, pg_efuse_info,
2219 if (status != HALMAC_RET_SUCCESS) {
2220 pr_err("halmac_pg_efuse_by_map error = %x\n", status);
2224 if (halmac_transition_efuse_state_88xx(
2225 halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_IDLE) !=
2227 return HALMAC_RET_ERROR_STATE;
2229 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_EFUSE, DBG_DMESG,
2230 "%s <==========\n", __func__);
2232 return HALMAC_RET_SUCCESS;
2236 * halmac_get_c2h_info_88xx() - process halmac C2H packet
2237 * @halmac_adapter : the adapter of halmac
2238 * @halmac_buf : RX Packet pointer
2239 * @halmac_size : RX Packet size
2240 * Author : KaiYuan Chang/Ivan Lin
2242 * Used to process c2h packet info from RX path. After receiving the packet,
2243 * user need to call this api and pass the packet pointer.
2245 * Return : enum halmac_ret_status
2246 * More details of status code can be found in prototype document
2248 enum halmac_ret_status
2249 halmac_get_c2h_info_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
2252 void *driver_adapter = NULL;
2253 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2255 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2256 return HALMAC_RET_ADAPTER_INVALID;
2258 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2259 return HALMAC_RET_API_INVALID;
2261 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_C2H_INFO);
2263 driver_adapter = halmac_adapter->driver_adapter;
2265 /* Check if it is C2H packet */
2266 if (GET_RX_DESC_C2H(halmac_buf)) {
2267 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2268 "C2H packet, start parsing!\n");
2270 status = halmac_parse_c2h_packet_88xx(halmac_adapter,
2271 halmac_buf, halmac_size);
2273 if (status != HALMAC_RET_SUCCESS) {
2274 pr_err("halmac_parse_c2h_packet_88xx error = %x\n",
2280 return HALMAC_RET_SUCCESS;
2283 enum halmac_ret_status
2284 halmac_cfg_fwlps_option_88xx(struct halmac_adapter *halmac_adapter,
2285 struct halmac_fwlps_option *lps_option)
2287 void *driver_adapter = NULL;
2288 struct halmac_fwlps_option *hal_fwlps_option;
2290 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2291 return HALMAC_RET_ADAPTER_INVALID;
2293 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2294 return HALMAC_RET_API_INVALID;
2296 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWLPS_OPTION);
2298 driver_adapter = halmac_adapter->driver_adapter;
2299 hal_fwlps_option = &halmac_adapter->fwlps_option;
2301 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2302 "%s ==========>\n", __func__);
2304 hal_fwlps_option->mode = lps_option->mode;
2305 hal_fwlps_option->clk_request = lps_option->clk_request;
2306 hal_fwlps_option->rlbm = lps_option->rlbm;
2307 hal_fwlps_option->smart_ps = lps_option->smart_ps;
2308 hal_fwlps_option->awake_interval = lps_option->awake_interval;
2309 hal_fwlps_option->all_queue_uapsd = lps_option->all_queue_uapsd;
2310 hal_fwlps_option->pwr_state = lps_option->pwr_state;
2311 hal_fwlps_option->low_pwr_rx_beacon = lps_option->low_pwr_rx_beacon;
2312 hal_fwlps_option->ant_auto_switch = lps_option->ant_auto_switch;
2313 hal_fwlps_option->ps_allow_bt_high_priority =
2314 lps_option->ps_allow_bt_high_priority;
2315 hal_fwlps_option->protect_bcn = lps_option->protect_bcn;
2316 hal_fwlps_option->silence_period = lps_option->silence_period;
2317 hal_fwlps_option->fast_bt_connect = lps_option->fast_bt_connect;
2318 hal_fwlps_option->two_antenna_en = lps_option->two_antenna_en;
2319 hal_fwlps_option->adopt_user_setting = lps_option->adopt_user_setting;
2320 hal_fwlps_option->drv_bcn_early_shift = lps_option->drv_bcn_early_shift;
2321 hal_fwlps_option->enter_32K = lps_option->enter_32K;
2323 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2324 "%s <==========\n", __func__);
2326 return HALMAC_RET_SUCCESS;
2329 enum halmac_ret_status
2330 halmac_cfg_fwips_option_88xx(struct halmac_adapter *halmac_adapter,
2331 struct halmac_fwips_option *ips_option)
2333 void *driver_adapter = NULL;
2334 struct halmac_fwips_option *ips_option_local;
2336 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2337 return HALMAC_RET_ADAPTER_INVALID;
2339 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2340 return HALMAC_RET_API_INVALID;
2342 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_FWIPS_OPTION);
2344 driver_adapter = halmac_adapter->driver_adapter;
2346 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2347 "%s ==========>\n", __func__);
2349 ips_option_local = ips_option;
2351 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2352 "%s <==========\n", __func__);
2354 return HALMAC_RET_SUCCESS;
2357 enum halmac_ret_status
2358 halmac_enter_wowlan_88xx(struct halmac_adapter *halmac_adapter,
2359 struct halmac_wowlan_option *wowlan_option)
2361 void *driver_adapter = NULL;
2362 struct halmac_wowlan_option *wowlan_option_local;
2364 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2365 return HALMAC_RET_ADAPTER_INVALID;
2367 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2368 return HALMAC_RET_API_INVALID;
2370 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_WOWLAN);
2372 driver_adapter = halmac_adapter->driver_adapter;
2374 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2375 "%s ==========>\n", __func__);
2377 wowlan_option_local = wowlan_option;
2379 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2380 "%s <==========\n", __func__);
2382 return HALMAC_RET_SUCCESS;
2385 enum halmac_ret_status
2386 halmac_leave_wowlan_88xx(struct halmac_adapter *halmac_adapter)
2388 void *driver_adapter = NULL;
2390 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2391 return HALMAC_RET_ADAPTER_INVALID;
2393 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2394 return HALMAC_RET_API_INVALID;
2396 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_WOWLAN);
2398 driver_adapter = halmac_adapter->driver_adapter;
2400 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2401 "%s ==========>\n", __func__);
2403 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2404 "%s <==========\n", __func__);
2406 return HALMAC_RET_SUCCESS;
2409 enum halmac_ret_status
2410 halmac_enter_ps_88xx(struct halmac_adapter *halmac_adapter,
2411 enum halmac_ps_state ps_state)
2414 void *driver_adapter = NULL;
2415 struct halmac_api *halmac_api;
2416 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2418 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2419 return HALMAC_RET_ADAPTER_INVALID;
2421 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2422 return HALMAC_RET_API_INVALID;
2424 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2425 return HALMAC_RET_NO_DLFW;
2427 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ENTER_PS);
2429 driver_adapter = halmac_adapter->driver_adapter;
2430 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2432 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2433 "%s ==========>\n", __func__);
2435 if (ps_state == halmac_adapter->halmac_state.ps_state) {
2436 pr_err("power state is already in PS State!!\n");
2437 return HALMAC_RET_SUCCESS;
2440 if (ps_state == HALMAC_PS_STATE_LPS) {
2441 status = halmac_send_h2c_set_pwr_mode_88xx(
2442 halmac_adapter, &halmac_adapter->fwlps_option);
2443 if (status != HALMAC_RET_SUCCESS) {
2444 pr_err("halmac_send_h2c_set_pwr_mode_88xx error = %x!!\n",
2448 } else if (ps_state == HALMAC_PS_STATE_IPS) {
2451 halmac_adapter->halmac_state.ps_state = ps_state;
2454 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
2455 if (halmac_adapter->fwlps_option.enter_32K) {
2456 rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
2459 HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1,
2461 halmac_adapter->low_clk = true;
2463 } else if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_USB) {
2464 if (halmac_adapter->fwlps_option.enter_32K) {
2465 rpwm = (u8)(((halmac_adapter->rpwm_record ^ (BIT(7))) |
2468 HALMAC_REG_WRITE_8(halmac_adapter, 0xFE58, rpwm);
2469 halmac_adapter->low_clk = true;
2473 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2474 "%s <==========\n", __func__);
2476 return HALMAC_RET_SUCCESS;
2479 enum halmac_ret_status
2480 halmac_leave_ps_88xx(struct halmac_adapter *halmac_adapter)
2484 void *driver_adapter = NULL;
2485 struct halmac_api *halmac_api;
2486 struct halmac_fwlps_option fw_lps_option;
2487 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2489 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2490 return HALMAC_RET_ADAPTER_INVALID;
2492 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2493 return HALMAC_RET_API_INVALID;
2495 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2496 return HALMAC_RET_NO_DLFW;
2498 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_LEAVE_PS);
2500 driver_adapter = halmac_adapter->driver_adapter;
2501 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2503 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2504 "%s ==========>\n", __func__);
2506 if (halmac_adapter->halmac_state.ps_state == HALMAC_PS_STATE_ACT) {
2507 pr_err("power state is already in active!!\n");
2508 return HALMAC_RET_SUCCESS;
2511 if (halmac_adapter->low_clk) {
2512 cpwm = HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1);
2514 ((halmac_adapter->rpwm_record ^ (BIT(7))) | (BIT(6))) &
2516 HALMAC_REG_WRITE_8(halmac_adapter, REG_SDIO_HRPWM1, rpwm);
2518 cpwm = (u8)((cpwm ^ BIT(7)) & BIT(7));
2521 (HALMAC_REG_READ_8(halmac_adapter, REG_SDIO_HRPWM1) &
2523 usleep_range(50, 60);
2526 return HALMAC_RET_CHANGE_PS_FAIL;
2528 halmac_adapter->low_clk = false;
2531 memcpy(&fw_lps_option, &halmac_adapter->fwlps_option,
2532 sizeof(struct halmac_fwlps_option));
2533 fw_lps_option.mode = 0;
2535 status = halmac_send_h2c_set_pwr_mode_88xx(halmac_adapter,
2537 if (status != HALMAC_RET_SUCCESS) {
2538 pr_err("halmac_send_h2c_set_pwr_mode_88xx error!!=%x\n",
2543 halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
2545 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
2546 "%s <==========\n", __func__);
2548 return HALMAC_RET_SUCCESS;
2552 * (debug API)halmac_h2c_lb_88xx() - send h2c loopback packet
2553 * @halmac_adapter : the adapter of halmac
2554 * Author : KaiYuan Chang/Ivan Lin
2555 * Return : enum halmac_ret_status
2556 * More details of status code can be found in prototype document
2558 enum halmac_ret_status halmac_h2c_lb_88xx(struct halmac_adapter *halmac_adapter)
2560 void *driver_adapter = NULL;
2562 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2563 return HALMAC_RET_ADAPTER_INVALID;
2565 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2566 return HALMAC_RET_API_INVALID;
2568 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_H2C_LB);
2570 driver_adapter = halmac_adapter->driver_adapter;
2572 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2573 "%s ==========>\n", __func__);
2575 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2576 "%s <==========\n", __func__);
2578 return HALMAC_RET_SUCCESS;
2582 * halmac_debug_88xx() - dump information for debugging
2583 * @halmac_adapter : the adapter of halmac
2584 * Author : KaiYuan Chang/Ivan Lin
2585 * Return : enum halmac_ret_status
2586 * More details of status code can be found in prototype document
2588 enum halmac_ret_status halmac_debug_88xx(struct halmac_adapter *halmac_adapter)
2591 u32 i = 0, temp32 = 0;
2592 void *driver_adapter = NULL;
2593 struct halmac_api *halmac_api;
2595 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2596 return HALMAC_RET_ADAPTER_INVALID;
2598 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2599 return HALMAC_RET_API_INVALID;
2601 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEBUG);
2603 driver_adapter = halmac_adapter->driver_adapter;
2604 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2606 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2607 "%s ==========>\n", __func__);
2609 if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
2610 /* Dump CCCR, it needs new platform api */
2612 /*Dump SDIO Local Register, use CMD52*/
2613 for (i = 0x10250000; i < 0x102500ff; i++) {
2614 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2616 driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2617 "halmac_debug: sdio[%x]=%x\n", i, temp8);
2620 /*Dump MAC Register*/
2621 for (i = 0x0000; i < 0x17ff; i++) {
2622 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2623 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
2624 DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
2628 /*Check RX Fifo status*/
2629 i = REG_RXFF_PTR_V1;
2630 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2631 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2632 "halmac_debug: mac[%x]=%x\n", i, temp8);
2633 i = REG_RXFF_WTR_V1;
2634 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2635 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2636 "halmac_debug: mac[%x]=%x\n", i, temp8);
2637 i = REG_RXFF_PTR_V1;
2638 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2639 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2640 "halmac_debug: mac[%x]=%x\n", i, temp8);
2641 i = REG_RXFF_WTR_V1;
2642 temp8 = PLATFORM_SDIO_CMD52_READ(halmac_adapter, i);
2643 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2644 "halmac_debug: mac[%x]=%x\n", i, temp8);
2646 /*Dump MAC Register*/
2647 for (i = 0x0000; i < 0x17fc; i += 4) {
2648 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2649 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
2650 DBG_DMESG, "halmac_debug: mac[%x]=%x\n",
2654 /*Check RX Fifo status*/
2655 i = REG_RXFF_PTR_V1;
2656 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2657 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2658 "halmac_debug: mac[%x]=%x\n", i, temp32);
2659 i = REG_RXFF_WTR_V1;
2660 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2661 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2662 "halmac_debug: mac[%x]=%x\n", i, temp32);
2663 i = REG_RXFF_PTR_V1;
2664 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2665 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2666 "halmac_debug: mac[%x]=%x\n", i, temp32);
2667 i = REG_RXFF_WTR_V1;
2668 temp32 = HALMAC_REG_READ_32(halmac_adapter, i);
2669 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2670 "halmac_debug: mac[%x]=%x\n", i, temp32);
2673 /* TODO: Add check register code, including MAC CLK, CPU CLK */
2675 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2676 "%s <==========\n", __func__);
2678 return HALMAC_RET_SUCCESS;
2682 * halmac_cfg_parameter_88xx() - config parameter by FW
2683 * @halmac_adapter : the adapter of halmac
2684 * @para_info : cmd id, content
2685 * @full_fifo : parameter information
2687 * If msk_en = true, the format of array is {reg_info, mask, value}.
2688 * If msk_en =_FAUSE, the format of array is {reg_info, value}
2689 * The format of reg_info is
2690 * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
2691 * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
2692 * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
2693 * ref_info[15:0]=offset
2695 * Example: msk_en = false
2696 * {0x8100000a, 0x00001122}
2697 * =>Set RF register, path_B, offset 0xA to 0x00001122
2698 * {0x00000824, 0x11224433}
2699 * =>Set MAC_BB register, offset 0x800 to 0x11224433
2701 * Note : full fifo mode only for init flow
2703 * Author : KaiYuan Chang/Ivan Lin
2704 * Return : enum halmac_ret_status
2705 * More details of status code can be found in prototype document
2707 enum halmac_ret_status
2708 halmac_cfg_parameter_88xx(struct halmac_adapter *halmac_adapter,
2709 struct halmac_phy_parameter_info *para_info,
2712 void *driver_adapter = NULL;
2713 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
2714 enum halmac_cmd_process_status *process_status =
2715 &halmac_adapter->halmac_state.cfg_para_state_set.process_status;
2717 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2718 return HALMAC_RET_ADAPTER_INVALID;
2720 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2721 return HALMAC_RET_API_INVALID;
2723 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2724 return HALMAC_RET_NO_DLFW;
2726 if (halmac_adapter->fw_version.h2c_version < 4)
2727 return HALMAC_RET_FW_NO_SUPPORT;
2729 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_PARAMETER);
2731 driver_adapter = halmac_adapter->driver_adapter;
2733 if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
2734 pr_err("%s Fail due to DLFW NONE!!\n", __func__);
2735 return HALMAC_RET_DLFW_FAIL;
2738 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2739 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2740 "Wait event(cfg para)...\n");
2741 return HALMAC_RET_BUSY_STATE;
2744 if (halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
2745 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
2746 halmac_query_cfg_para_curr_state_88xx(halmac_adapter) !=
2747 HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
2748 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2749 "Not idle state(cfg para)...\n");
2750 return HALMAC_RET_BUSY_STATE;
2753 *process_status = HALMAC_CMD_PROCESS_IDLE;
2755 ret_status = halmac_send_h2c_phy_parameter_88xx(halmac_adapter,
2756 para_info, full_fifo);
2758 if (ret_status != HALMAC_RET_SUCCESS) {
2759 pr_err("halmac_send_h2c_phy_parameter_88xx Fail!! = %x\n",
2768 * halmac_update_packet_88xx() - send specific packet to FW
2769 * @halmac_adapter : the adapter of halmac
2770 * @pkt_id : packet id, to know the purpose of this packet
2772 * @pkt_size : packet size
2774 * Note : TX_DESC is not included in the pkt
2776 * Author : KaiYuan Chang/Ivan Lin
2777 * Return : enum halmac_ret_status
2778 * More details of status code can be found in prototype document
2780 enum halmac_ret_status
2781 halmac_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2782 enum halmac_packet_id pkt_id, u8 *pkt, u32 pkt_size)
2784 void *driver_adapter = NULL;
2785 struct halmac_api *halmac_api;
2786 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2787 enum halmac_cmd_process_status *process_status =
2788 &halmac_adapter->halmac_state.update_packet_set.process_status;
2790 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2791 return HALMAC_RET_ADAPTER_INVALID;
2793 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2794 return HALMAC_RET_API_INVALID;
2796 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2797 return HALMAC_RET_NO_DLFW;
2799 if (halmac_adapter->fw_version.h2c_version < 4)
2800 return HALMAC_RET_FW_NO_SUPPORT;
2802 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_UPDATE_PACKET);
2804 driver_adapter = halmac_adapter->driver_adapter;
2805 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2807 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2808 "%s ==========>\n", __func__);
2810 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
2811 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
2812 "Wait event(update_packet)...\n");
2813 return HALMAC_RET_BUSY_STATE;
2816 *process_status = HALMAC_CMD_PROCESS_SENDING;
2818 status = halmac_send_h2c_update_packet_88xx(halmac_adapter, pkt_id, pkt,
2821 if (status != HALMAC_RET_SUCCESS) {
2822 pr_err("halmac_send_h2c_update_packet_88xx packet = %x, fail = %x!!\n",
2827 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2828 "%s <==========\n", __func__);
2830 return HALMAC_RET_SUCCESS;
2833 enum halmac_ret_status
2834 halmac_bcn_ie_filter_88xx(struct halmac_adapter *halmac_adapter,
2835 struct halmac_bcn_ie_info *bcn_ie_info)
2837 void *driver_adapter = NULL;
2838 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2840 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2841 return HALMAC_RET_ADAPTER_INVALID;
2843 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2844 return HALMAC_RET_API_INVALID;
2846 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2847 return HALMAC_RET_NO_DLFW;
2849 if (halmac_adapter->fw_version.h2c_version < 4)
2850 return HALMAC_RET_FW_NO_SUPPORT;
2852 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_BCN_IE_FILTER);
2854 driver_adapter = halmac_adapter->driver_adapter;
2856 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2857 "%s ==========>\n", __func__);
2859 status = halmac_send_h2c_update_bcn_parse_info_88xx(halmac_adapter,
2862 if (status != HALMAC_RET_SUCCESS) {
2863 pr_err("halmac_send_h2c_update_bcn_parse_info_88xx fail = %x\n",
2868 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2869 "%s <==========\n", __func__);
2871 return HALMAC_RET_SUCCESS;
2874 enum halmac_ret_status
2875 halmac_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2876 enum halmac_data_type halmac_data_type,
2877 struct halmac_phy_parameter_info *para_info)
2879 void *driver_adapter = NULL;
2881 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2882 return HALMAC_RET_ADAPTER_INVALID;
2884 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2885 return HALMAC_RET_API_INVALID;
2887 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2888 return HALMAC_RET_NO_DLFW;
2890 if (halmac_adapter->fw_version.h2c_version < 4)
2891 return HALMAC_RET_FW_NO_SUPPORT;
2893 driver_adapter = halmac_adapter->driver_adapter;
2895 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2896 "[TRACE]%s ==========>\n", __func__);
2898 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2899 "[TRACE]%s <==========\n", __func__);
2901 return HALMAC_RET_SUCCESS;
2904 enum halmac_ret_status
2905 halmac_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2906 enum halmac_data_type halmac_data_type)
2908 void *driver_adapter = NULL;
2909 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
2911 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2912 return HALMAC_RET_ADAPTER_INVALID;
2914 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2915 return HALMAC_RET_API_INVALID;
2917 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2918 return HALMAC_RET_NO_DLFW;
2920 if (halmac_adapter->fw_version.h2c_version < 4)
2921 return HALMAC_RET_FW_NO_SUPPORT;
2923 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RUN_DATAPACK);
2925 driver_adapter = halmac_adapter->driver_adapter;
2927 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2928 "%s ==========>\n", __func__);
2930 ret_status = halmac_send_h2c_run_datapack_88xx(halmac_adapter,
2933 if (ret_status != HALMAC_RET_SUCCESS) {
2934 pr_err("halmac_send_h2c_run_datapack_88xx Fail, datatype = %x, status = %x!!\n",
2935 halmac_data_type, ret_status);
2939 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2940 "halmac_update_datapack_88xx <==========\n");
2942 return HALMAC_RET_SUCCESS;
2946 * halmac_cfg_drv_info_88xx() - config driver info
2947 * @halmac_adapter : the adapter of halmac
2948 * @halmac_drv_info : driver information selection
2949 * Author : KaiYuan Chang/Ivan Lin
2950 * Return : enum halmac_ret_status
2951 * More details of status code can be found in prototype document
2953 enum halmac_ret_status
2954 halmac_cfg_drv_info_88xx(struct halmac_adapter *halmac_adapter,
2955 enum halmac_drv_info halmac_drv_info)
2957 u8 drv_info_size = 0;
2958 u8 phy_status_en = 0;
2962 void *driver_adapter = NULL;
2963 struct halmac_api *halmac_api;
2964 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2966 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2967 return HALMAC_RET_ADAPTER_INVALID;
2969 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
2970 return HALMAC_RET_API_INVALID;
2972 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_DRV_INFO);
2974 driver_adapter = halmac_adapter->driver_adapter;
2975 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2977 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2978 "%s ==========>\n", __func__);
2980 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2981 "halmac_cfg_drv_info = %d\n", halmac_drv_info);
2983 switch (halmac_drv_info) {
2984 case HALMAC_DRV_INFO_NONE:
2990 case HALMAC_DRV_INFO_PHY_STATUS:
2996 case HALMAC_DRV_INFO_PHY_SNIFFER:
2997 drv_info_size = 5; /* phy status 4byte, sniffer info 1byte */
3002 case HALMAC_DRV_INFO_PHY_PLCP:
3003 drv_info_size = 6; /* phy status 4byte, plcp header 2byte */
3009 status = HALMAC_RET_SW_CASE_NOT_SUPPORT;
3010 pr_err("%s error = %x\n", __func__, status);
3014 if (halmac_adapter->txff_allocation.rx_fifo_expanding_mode !=
3015 HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE)
3016 drv_info_size = 0xF;
3018 HALMAC_REG_WRITE_8(halmac_adapter, REG_RX_DRVINFO_SZ, drv_info_size);
3020 halmac_adapter->drv_info_size = drv_info_size;
3022 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_RCR);
3023 value32 = (value32 & (~BIT_APP_PHYSTS));
3024 if (phy_status_en == 1)
3025 value32 = value32 | BIT_APP_PHYSTS;
3026 HALMAC_REG_WRITE_32(halmac_adapter, REG_RCR, value32);
3028 value32 = HALMAC_REG_READ_32(halmac_adapter,
3029 REG_WMAC_OPTION_FUNCTION + 4);
3030 value32 = (value32 & (~(BIT(8) | BIT(9))));
3031 if (sniffer_en == 1)
3032 value32 = value32 | BIT(9);
3033 if (plcp_hdr_en == 1)
3034 value32 = value32 | BIT(8);
3035 HALMAC_REG_WRITE_32(halmac_adapter, REG_WMAC_OPTION_FUNCTION + 4,
3038 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3039 "%s <==========\n", __func__);
3041 return HALMAC_RET_SUCCESS;
3044 enum halmac_ret_status
3045 halmac_send_bt_coex_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
3046 u32 bt_size, u8 ack)
3048 void *driver_adapter = NULL;
3049 struct halmac_api *halmac_api;
3050 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3052 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3053 return HALMAC_RET_ADAPTER_INVALID;
3055 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3056 return HALMAC_RET_API_INVALID;
3058 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3059 return HALMAC_RET_NO_DLFW;
3061 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_BT_COEX);
3063 driver_adapter = halmac_adapter->driver_adapter;
3064 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3066 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3067 "%s ==========>\n", __func__);
3069 ret_status = halmac_send_bt_coex_cmd_88xx(halmac_adapter, bt_buf,
3072 if (ret_status != HALMAC_RET_SUCCESS) {
3073 pr_err("halmac_send_bt_coex_cmd_88xx Fail = %x!!\n",
3078 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3079 "%s <==========\n", __func__);
3081 return HALMAC_RET_SUCCESS;
3085 * (debug API)halmac_verify_platform_api_88xx() - verify platform api
3086 * @halmac_adapter : the adapter of halmac
3087 * Author : KaiYuan Chang/Ivan Lin
3088 * Return : enum halmac_ret_status
3089 * More details of status code can be found in prototype document
3091 enum halmac_ret_status
3092 halmac_verify_platform_api_88xx(struct halmac_adapter *halmac_adapter)
3094 void *driver_adapter = NULL;
3095 enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3097 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3098 return HALMAC_RET_ADAPTER_INVALID;
3100 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3101 return HALMAC_RET_API_INVALID;
3103 halmac_api_record_id_88xx(halmac_adapter,
3104 HALMAC_API_VERIFY_PLATFORM_API);
3106 driver_adapter = halmac_adapter->driver_adapter;
3108 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3109 "%s ==========>\n", __func__);
3111 ret_status = halmac_verify_io_88xx(halmac_adapter);
3113 if (ret_status != HALMAC_RET_SUCCESS)
3116 if (halmac_adapter->txff_allocation.la_mode != HALMAC_LA_MODE_FULL)
3117 ret_status = halmac_verify_send_rsvd_page_88xx(halmac_adapter);
3119 if (ret_status != HALMAC_RET_SUCCESS)
3122 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3123 "%s <==========\n", __func__);
3128 enum halmac_ret_status
3129 halmac_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
3130 u8 *original_h2c, u16 *seq, u8 ack)
3132 void *driver_adapter = NULL;
3133 struct halmac_api *halmac_api;
3134 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3136 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3137 return HALMAC_RET_ADAPTER_INVALID;
3139 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3140 return HALMAC_RET_API_INVALID;
3142 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3143 return HALMAC_RET_NO_DLFW;
3145 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_ORIGINAL_H2C);
3147 driver_adapter = halmac_adapter->driver_adapter;
3148 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3150 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3151 "%s ==========>\n", __func__);
3153 status = halmac_func_send_original_h2c_88xx(halmac_adapter,
3154 original_h2c, seq, ack);
3156 if (status != HALMAC_RET_SUCCESS) {
3157 pr_err("halmac_send_original_h2c FAIL = %x!!\n", status);
3161 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3162 "%s <==========\n", __func__);
3164 return HALMAC_RET_SUCCESS;
3167 enum halmac_ret_status
3168 halmac_timer_2s_88xx(struct halmac_adapter *halmac_adapter)
3170 void *driver_adapter = NULL;
3172 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3173 return HALMAC_RET_ADAPTER_INVALID;
3175 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3176 return HALMAC_RET_API_INVALID;
3178 driver_adapter = halmac_adapter->driver_adapter;
3180 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3181 "%s ==========>\n", __func__);
3183 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3184 "%s <==========\n", __func__);
3186 return HALMAC_RET_SUCCESS;
3190 * halmac_fill_txdesc_check_sum_88xx() - fill in tx desc check sum
3191 * @halmac_adapter : the adapter of halmac
3192 * @cur_desc : tx desc packet
3193 * Author : KaiYuan Chang/Ivan Lin
3194 * Return : enum halmac_ret_status
3195 * More details of status code can be found in prototype document
3197 enum halmac_ret_status
3198 halmac_fill_txdesc_check_sum_88xx(struct halmac_adapter *halmac_adapter,
3202 u16 *data = (u16 *)NULL;
3204 void *driver_adapter = NULL;
3205 struct halmac_api *halmac_api;
3207 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3208 return HALMAC_RET_ADAPTER_INVALID;
3210 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3211 return HALMAC_RET_API_INVALID;
3213 halmac_api_record_id_88xx(halmac_adapter,
3214 HALMAC_API_FILL_TXDESC_CHECKSUM);
3216 driver_adapter = halmac_adapter->driver_adapter;
3217 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3220 pr_err("%s NULL PTR", __func__);
3221 return HALMAC_RET_NULL_POINTER;
3224 SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, 0x0000);
3226 data = (u16 *)(cur_desc);
3228 /* HW clculates only 32byte */
3229 for (i = 0; i < 8; i++)
3230 chk_result ^= (*(data + 2 * i) ^ *(data + (2 * i + 1)));
3232 SET_TX_DESC_TXDESC_CHECKSUM(cur_desc, chk_result);
3234 return HALMAC_RET_SUCCESS;
3238 * halmac_dump_fifo_88xx() - dump fifo data
3239 * @halmac_adapter : the adapter of halmac
3240 * @halmac_fifo_sel : FIFO selection
3241 * @halmac_start_addr : start address of selected FIFO
3242 * @halmac_fifo_dump_size : dump size of selected FIFO
3243 * @fifo_map : FIFO data
3245 * Note : before dump fifo, user need to call halmac_get_fifo_size to
3246 * get fifo size. Then input this size to halmac_dump_fifo.
3248 * Author : Ivan Lin/KaiYuan Chang
3249 * Return : enum halmac_ret_status
3250 * More details of status code can be found in prototype document
3252 enum halmac_ret_status
3253 halmac_dump_fifo_88xx(struct halmac_adapter *halmac_adapter,
3254 enum hal_fifo_sel halmac_fifo_sel, u32 halmac_start_addr,
3255 u32 halmac_fifo_dump_size, u8 *fifo_map)
3257 void *driver_adapter = NULL;
3258 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3260 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3261 return HALMAC_RET_ADAPTER_INVALID;
3263 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3264 return HALMAC_RET_API_INVALID;
3266 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FIFO);
3268 driver_adapter = halmac_adapter->driver_adapter;
3270 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3271 "%s ==========>\n", __func__);
3273 if (halmac_fifo_sel == HAL_FIFO_SEL_TX &&
3274 (halmac_start_addr + halmac_fifo_dump_size) >
3275 halmac_adapter->hw_config_info.tx_fifo_size) {
3276 pr_err("TX fifo dump size is too large\n");
3277 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3280 if (halmac_fifo_sel == HAL_FIFO_SEL_RX &&
3281 (halmac_start_addr + halmac_fifo_dump_size) >
3282 halmac_adapter->hw_config_info.rx_fifo_size) {
3283 pr_err("RX fifo dump size is too large\n");
3284 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3287 if ((halmac_fifo_dump_size & (4 - 1)) != 0) {
3288 pr_err("halmac_fifo_dump_size shall 4byte align\n");
3289 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
3293 pr_err("fifo_map address is NULL\n");
3294 return HALMAC_RET_NULL_POINTER;
3297 status = halmac_buffer_read_88xx(halmac_adapter, halmac_start_addr,
3298 halmac_fifo_dump_size, halmac_fifo_sel,
3301 if (status != HALMAC_RET_SUCCESS) {
3302 pr_err("halmac_buffer_read_88xx error = %x\n", status);
3306 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3307 "%s <==========\n", __func__);
3309 return HALMAC_RET_SUCCESS;
3313 * halmac_get_fifo_size_88xx() - get fifo size
3314 * @halmac_adapter : the adapter of halmac
3315 * @halmac_fifo_sel : FIFO selection
3316 * Author : Ivan Lin/KaiYuan Chang
3318 * More details of status code can be found in prototype document
3320 u32 halmac_get_fifo_size_88xx(struct halmac_adapter *halmac_adapter,
3321 enum hal_fifo_sel halmac_fifo_sel)
3325 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3326 return HALMAC_RET_ADAPTER_INVALID;
3328 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3329 return HALMAC_RET_API_INVALID;
3331 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_FIFO_SIZE);
3333 if (halmac_fifo_sel == HAL_FIFO_SEL_TX)
3334 fifo_size = halmac_adapter->hw_config_info.tx_fifo_size;
3335 else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3336 fifo_size = halmac_adapter->hw_config_info.rx_fifo_size;
3337 else if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3339 ((halmac_adapter->hw_config_info.tx_fifo_size >> 7) -
3340 halmac_adapter->txff_allocation.rsvd_pg_bndy)
3342 else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3344 else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3351 * halmac_cfg_txbf_88xx() - enable/disable specific user's txbf
3352 * @halmac_adapter : the adapter of halmac
3353 * @userid : su bfee userid = 0 or 1 to apply TXBF
3354 * @bw : the sounding bandwidth
3355 * @txbf_en : 0: disable TXBF, 1: enable TXBF
3357 * Return : enum halmac_ret_status
3358 * More details of status code can be found in prototype document
3360 enum halmac_ret_status
3361 halmac_cfg_txbf_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
3362 enum halmac_bw bw, u8 txbf_en)
3365 void *driver_adapter = NULL;
3366 struct halmac_api *halmac_api;
3368 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3369 return HALMAC_RET_ADAPTER_INVALID;
3371 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3372 return HALMAC_RET_API_INVALID;
3374 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_TXBF);
3376 driver_adapter = halmac_adapter->driver_adapter;
3377 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3382 temp42C |= BIT_R_TXBF0_80M;
3385 temp42C |= BIT_R_TXBF0_40M;
3388 temp42C |= BIT_R_TXBF0_20M;
3391 pr_err("%s invalid TXBF BW setting 0x%x of userid %d\n",
3392 __func__, bw, userid);
3393 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3400 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3401 ~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3402 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL, temp42C);
3406 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3407 ~(BIT_R_TXBF0_20M | BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3408 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2, temp42C);
3411 pr_err("%s invalid userid %d\n", __func__, userid);
3412 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3415 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3416 "%s, txbf_en = %x <==========\n", __func__,
3419 return HALMAC_RET_SUCCESS;
3423 * halmac_cfg_mumimo_88xx() -config mumimo
3424 * @halmac_adapter : the adapter of halmac
3425 * @cfgmu : parameters to configure MU PPDU Tx/Rx
3427 * Return : enum halmac_ret_status
3428 * More details of status code can be found in prototype document
3430 enum halmac_ret_status
3431 halmac_cfg_mumimo_88xx(struct halmac_adapter *halmac_adapter,
3432 struct halmac_cfg_mumimo_para *cfgmu)
3434 void *driver_adapter = NULL;
3435 struct halmac_api *halmac_api;
3436 u8 i, idx, id0, id1, gid, mu_tab_sel;
3437 u8 mu_tab_valid = 0;
3438 u32 gid_valid[6] = {0};
3441 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3442 return HALMAC_RET_ADAPTER_INVALID;
3444 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3445 return HALMAC_RET_API_INVALID;
3447 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MUMIMO);
3449 driver_adapter = halmac_adapter->driver_adapter;
3450 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3452 if (cfgmu->role == HAL_BFEE) {
3454 temp14C0 = HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
3455 ~BIT_MASK_R_MU_TABLE_VALID;
3456 /*enable MU table 0 and 1, disable MU TX*/
3457 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3458 (temp14C0 | BIT(0) | BIT(1)) & ~(BIT(7)));
3460 /*config GID valid table and user position table*/
3462 HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
3463 ~(BIT(0) | BIT(1) | BIT(2));
3464 for (i = 0; i < 2; i++) {
3465 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
3467 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
3468 cfgmu->given_gid_tab[i]);
3469 HALMAC_REG_WRITE_32(halmac_adapter,
3470 REG_MU_STA_USER_POS_INFO,
3471 cfgmu->given_user_pos[i * 2]);
3472 HALMAC_REG_WRITE_32(halmac_adapter,
3473 REG_MU_STA_USER_POS_INFO + 4,
3474 cfgmu->given_user_pos[i * 2 + 1]);
3478 if (!cfgmu->mu_tx_en) {
3479 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3480 HALMAC_REG_READ_8(halmac_adapter,
3484 driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3485 "%s disable mu tx <==========\n", __func__);
3486 return HALMAC_RET_SUCCESS;
3489 /*Transform BB grouping bitmap[14:0] to MAC GID_valid table*/
3490 for (idx = 0; idx < 15; idx++) {
3492 /*group_bitmap bit0~4, MU_STA0 with MUSTA1~5*/
3494 id1 = (u8)(idx + 1);
3495 } else if (idx < 9) {
3496 /*group_bitmap bit5~8, MU_STA1 with MUSTA2~5*/
3498 id1 = (u8)(idx - 3);
3499 } else if (idx < 12) {
3500 /*group_bitmap bit9~11, MU_STA2 with MUSTA3~5*/
3502 id1 = (u8)(idx - 6);
3503 } else if (idx < 14) {
3504 /*group_bitmap bit12~13, MU_STA3 with MUSTA4~5*/
3506 id1 = (u8)(idx - 8);
3508 /*group_bitmap bit14, MU_STA4 with MUSTA5*/
3510 id1 = (u8)(idx - 9);
3512 if (cfgmu->grouping_bitmap & BIT(idx)) {
3514 gid = (idx << 1) + 1;
3515 gid_valid[id0] |= (BIT(gid));
3516 gid_valid[id1] |= (BIT(gid));
3519 gid_valid[id0] |= (BIT(gid));
3520 gid_valid[id1] |= (BIT(gid));
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));
3533 /*set MU STA GID valid TABLE*/
3535 HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL + 1) &
3536 ~(BIT(0) | BIT(1) | BIT(2));
3537 for (idx = 0; idx < 6; idx++) {
3538 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL + 1,
3540 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD,
3544 /*To validate the sounding successful MU STA and enable MU TX*/
3545 for (i = 0; i < 6; i++) {
3546 if (cfgmu->sounding_sts[i])
3547 mu_tab_valid |= BIT(i);
3549 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
3550 mu_tab_valid | BIT(7));
3552 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3553 "%s <==========\n", __func__);
3554 return HALMAC_RET_SUCCESS;
3558 * halmac_cfg_sounding_88xx() - configure general sounding
3559 * @halmac_adapter : the adapter of halmac
3560 * @role : driver's role, BFer or BFee
3561 * @datarate : set ndpa tx rate if driver is BFer, or set csi response rate
3564 * Return : enum halmac_ret_status
3565 * More details of status code can be found in prototype document
3567 enum halmac_ret_status
3568 halmac_cfg_sounding_88xx(struct halmac_adapter *halmac_adapter,
3569 enum halmac_snd_role role,
3570 enum halmac_data_rate datarate)
3572 void *driver_adapter = NULL;
3573 struct halmac_api *halmac_api;
3575 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3576 return HALMAC_RET_ADAPTER_INVALID;
3578 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3579 return HALMAC_RET_API_INVALID;
3581 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_SOUNDING);
3583 driver_adapter = halmac_adapter->driver_adapter;
3584 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3588 HALMAC_REG_WRITE_32(
3589 halmac_adapter, REG_TXBF_CTRL,
3590 HALMAC_REG_READ_32(halmac_adapter, REG_TXBF_CTRL) |
3591 BIT_R_ENABLE_NDPA | BIT_USE_NDPA_PARAMETER |
3592 BIT_R_EN_NDPA_INT | BIT_DIS_NDP_BFEN);
3593 HALMAC_REG_WRITE_8(halmac_adapter, REG_NDPA_RATE, datarate);
3595 halmac_adapter, REG_NDPA_OPT_CTRL,
3596 HALMAC_REG_READ_8(halmac_adapter, REG_NDPA_OPT_CTRL) &
3597 (~(BIT(0) | BIT(1))));
3598 /*service file length 2 bytes; fix non-STA1 csi start offset */
3599 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 1,
3601 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 2, 0x2);
3604 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0xDB);
3605 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL + 3, 0x50);
3606 /*use ndpa rx rate to decide csi rate*/
3607 HALMAC_REG_WRITE_8(halmac_adapter, REG_BBPSF_CTRL + 3,
3608 HALMAC_OFDM54 | BIT(6));
3609 HALMAC_REG_WRITE_16(
3610 halmac_adapter, REG_RRSR,
3611 HALMAC_REG_READ_16(halmac_adapter, REG_RRSR) |
3613 /*RXFF do not accept BF Rpt Poll, avoid CSI crc error*/
3615 halmac_adapter, REG_RXFLTMAP1,
3616 HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP1) &
3618 /*FWFF do not accept BF Rpt Poll, avoid CSI crc error*/
3620 halmac_adapter, REG_RXFLTMAP4,
3621 HALMAC_REG_READ_8(halmac_adapter, REG_RXFLTMAP4) &
3625 pr_err("%s invalid role\n", __func__);
3626 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3629 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3630 "%s <==========\n", __func__);
3632 return HALMAC_RET_SUCCESS;
3636 * halmac_del_sounding_88xx() - reset general sounding
3637 * @halmac_adapter : the adapter of halmac
3638 * @role : driver's role, BFer or BFee
3640 * Return : enum halmac_ret_status
3641 * More details of status code can be found in prototype document
3643 enum halmac_ret_status
3644 halmac_del_sounding_88xx(struct halmac_adapter *halmac_adapter,
3645 enum halmac_snd_role role)
3647 void *driver_adapter = NULL;
3648 struct halmac_api *halmac_api;
3650 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3651 return HALMAC_RET_ADAPTER_INVALID;
3653 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3654 return HALMAC_RET_API_INVALID;
3656 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DEL_SOUNDING);
3658 driver_adapter = halmac_adapter->driver_adapter;
3659 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3663 HALMAC_REG_WRITE_8(halmac_adapter, REG_TXBF_CTRL + 3, 0);
3666 HALMAC_REG_WRITE_8(halmac_adapter, REG_SND_PTCL_CTRL, 0);
3669 pr_err("%s invalid role\n", __func__);
3670 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3673 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3674 "%s <==========\n", __func__);
3676 return HALMAC_RET_SUCCESS;
3680 * halmac_su_bfee_entry_init_88xx() - config SU beamformee's registers
3681 * @halmac_adapter : the adapter of halmac
3682 * @userid : SU bfee userid = 0 or 1 to be added
3683 * @paid : partial AID of this bfee
3685 * Return : enum halmac_ret_status
3686 * More details of status code can be found in prototype document
3688 enum halmac_ret_status
3689 halmac_su_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter, u8 userid,
3693 void *driver_adapter = NULL;
3694 struct halmac_api *halmac_api;
3696 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3697 return HALMAC_RET_ADAPTER_INVALID;
3699 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3700 return HALMAC_RET_API_INVALID;
3702 halmac_api_record_id_88xx(halmac_adapter,
3703 HALMAC_API_SU_BFEE_ENTRY_INIT);
3705 driver_adapter = halmac_adapter->driver_adapter;
3706 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3710 temp42C = HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3711 ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
3712 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3713 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL,
3715 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
3720 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3721 ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
3722 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M);
3723 HALMAC_REG_WRITE_16(halmac_adapter, REG_TXBF_CTRL + 2,
3725 HALMAC_REG_WRITE_16(halmac_adapter,
3726 REG_ASSOCIATED_BFMEE_SEL + 2,
3730 pr_err("%s invalid userid %d\n", __func__,
3732 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3735 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3736 "%s <==========\n", __func__);
3738 return HALMAC_RET_SUCCESS;
3742 * halmac_su_bfee_entry_init_88xx() - config SU beamformer's registers
3743 * @halmac_adapter : the adapter of halmac
3744 * @su_bfer_init : parameters to configure SU BFER entry
3746 * Return : enum halmac_ret_status
3747 * More details of status code can be found in prototype document
3749 enum halmac_ret_status
3750 halmac_su_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3751 struct halmac_su_bfer_init_para *su_bfer_init)
3755 void *driver_adapter = NULL;
3756 struct halmac_api *halmac_api;
3758 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3759 return HALMAC_RET_ADAPTER_INVALID;
3761 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3762 return HALMAC_RET_API_INVALID;
3764 halmac_api_record_id_88xx(halmac_adapter,
3765 HALMAC_API_SU_BFER_ENTRY_INIT);
3767 driver_adapter = halmac_adapter->driver_adapter;
3768 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3770 /* mac_address_L = bfer_address.address_l_h.address_low; */
3771 /* mac_address_H = bfer_address.address_l_h.address_high; */
3773 mac_address_L = le32_to_cpu(
3774 su_bfer_init->bfer_address.address_l_h.le_address_low);
3775 mac_address_H = le16_to_cpu(
3776 su_bfer_init->bfer_address.address_l_h.le_address_high);
3778 switch (su_bfer_init->userid) {
3780 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
3782 HALMAC_REG_WRITE_16(halmac_adapter,
3783 REG_ASSOCIATED_BFMER0_INFO + 4,
3785 HALMAC_REG_WRITE_16(halmac_adapter,
3786 REG_ASSOCIATED_BFMER0_INFO + 6,
3787 su_bfer_init->paid);
3788 HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
3789 su_bfer_init->csi_para);
3792 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
3794 HALMAC_REG_WRITE_16(halmac_adapter,
3795 REG_ASSOCIATED_BFMER1_INFO + 4,
3797 HALMAC_REG_WRITE_16(halmac_adapter,
3798 REG_ASSOCIATED_BFMER1_INFO + 6,
3799 su_bfer_init->paid);
3800 HALMAC_REG_WRITE_16(halmac_adapter,
3801 REG_TX_CSI_RPT_PARAM_BW20 + 2,
3802 su_bfer_init->csi_para);
3805 pr_err("%s invalid userid %d\n", __func__,
3806 su_bfer_init->userid);
3807 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3810 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3811 "%s <==========\n", __func__);
3813 return HALMAC_RET_SUCCESS;
3817 * halmac_mu_bfee_entry_init_88xx() - config MU beamformee's registers
3818 * @halmac_adapter : the adapter of halmac
3819 * @mu_bfee_init : parameters to configure MU BFEE entry
3821 * Return : enum halmac_ret_status
3822 * More details of status code can be found in prototype document
3824 enum halmac_ret_status
3825 halmac_mu_bfee_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3826 struct halmac_mu_bfee_init_para *mu_bfee_init)
3828 u16 temp168X = 0, temp14C0;
3829 void *driver_adapter = NULL;
3830 struct halmac_api *halmac_api;
3832 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3833 return HALMAC_RET_ADAPTER_INVALID;
3835 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3836 return HALMAC_RET_API_INVALID;
3838 halmac_api_record_id_88xx(halmac_adapter,
3839 HALMAC_API_MU_BFEE_ENTRY_INIT);
3841 driver_adapter = halmac_adapter->driver_adapter;
3842 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3844 temp168X |= mu_bfee_init->paid | BIT(9);
3845 HALMAC_REG_WRITE_16(halmac_adapter, (0x1680 + mu_bfee_init->userid * 2),
3848 temp14C0 = HALMAC_REG_READ_16(halmac_adapter, REG_MU_TX_CTL) &
3849 ~(BIT(8) | BIT(9) | BIT(10));
3850 HALMAC_REG_WRITE_16(halmac_adapter, REG_MU_TX_CTL,
3851 temp14C0 | ((mu_bfee_init->userid - 2) << 8));
3852 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_GID_VLD, 0);
3853 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO,
3854 mu_bfee_init->user_position_l);
3855 HALMAC_REG_WRITE_32(halmac_adapter, REG_MU_STA_USER_POS_INFO + 4,
3856 mu_bfee_init->user_position_h);
3858 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3859 "%s <==========\n", __func__);
3861 return HALMAC_RET_SUCCESS;
3865 * halmac_mu_bfer_entry_init_88xx() - config MU beamformer's registers
3866 * @halmac_adapter : the adapter of halmac
3867 * @mu_bfer_init : parameters to configure MU BFER entry
3869 * Return : enum halmac_ret_status
3870 * More details of status code can be found in prototype document
3872 enum halmac_ret_status
3873 halmac_mu_bfer_entry_init_88xx(struct halmac_adapter *halmac_adapter,
3874 struct halmac_mu_bfer_init_para *mu_bfer_init)
3879 void *driver_adapter = NULL;
3880 struct halmac_api *halmac_api;
3882 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3883 return HALMAC_RET_ADAPTER_INVALID;
3885 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3886 return HALMAC_RET_API_INVALID;
3888 halmac_api_record_id_88xx(halmac_adapter,
3889 HALMAC_API_MU_BFER_ENTRY_INIT);
3891 driver_adapter = halmac_adapter->driver_adapter;
3892 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3895 le32_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_low);
3897 le16_to_cpu(mu_bfer_init->bfer_address.address_l_h.le_address_high);
3899 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
3901 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4,
3903 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 6,
3904 mu_bfer_init->paid);
3905 HALMAC_REG_WRITE_16(halmac_adapter, REG_TX_CSI_RPT_PARAM_BW20,
3906 mu_bfer_init->csi_para);
3908 temp1680 = HALMAC_REG_READ_16(halmac_adapter, 0x1680) & 0xC000;
3909 temp1680 |= mu_bfer_init->my_aid | (mu_bfer_init->csi_length_sel << 12);
3910 HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, temp1680);
3912 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3913 "%s <==========\n", __func__);
3915 return HALMAC_RET_SUCCESS;
3919 * halmac_su_bfee_entry_del_88xx() - reset SU beamformee's registers
3920 * @halmac_adapter : the adapter of halmac
3921 * @userid : the SU BFee userid to be deleted
3923 * Return : enum halmac_ret_status
3924 * More details of status code can be found in prototype document
3926 enum halmac_ret_status
3927 halmac_su_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
3929 void *driver_adapter = NULL;
3930 struct halmac_api *halmac_api;
3932 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3933 return HALMAC_RET_ADAPTER_INVALID;
3935 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3936 return HALMAC_RET_API_INVALID;
3938 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFEE_ENTRY_DEL);
3940 driver_adapter = halmac_adapter->driver_adapter;
3941 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3945 HALMAC_REG_WRITE_16(
3946 halmac_adapter, REG_TXBF_CTRL,
3947 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL) &
3948 ~(BIT_MASK_R_TXBF0_AID | BIT_R_TXBF0_20M |
3949 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
3950 HALMAC_REG_WRITE_16(halmac_adapter, REG_ASSOCIATED_BFMEE_SEL,
3954 HALMAC_REG_WRITE_16(
3955 halmac_adapter, REG_TXBF_CTRL + 2,
3956 HALMAC_REG_READ_16(halmac_adapter, REG_TXBF_CTRL + 2) &
3957 ~(BIT_MASK_R_TXBF1_AID | BIT_R_TXBF0_20M |
3958 BIT_R_TXBF0_40M | BIT_R_TXBF0_80M));
3959 HALMAC_REG_WRITE_16(halmac_adapter,
3960 REG_ASSOCIATED_BFMEE_SEL + 2, 0);
3963 pr_err("%s invalid userid %d\n", __func__,
3965 return HALMAC_RET_INVALID_SOUNDING_SETTING;
3968 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
3969 "%s <==========\n", __func__);
3971 return HALMAC_RET_SUCCESS;
3975 * halmac_su_bfee_entry_del_88xx() - reset SU beamformer's registers
3976 * @halmac_adapter : the adapter of halmac
3977 * @userid : the SU BFer userid to be deleted
3979 * Return : enum halmac_ret_status
3980 * More details of status code can be found in prototype document
3982 enum halmac_ret_status
3983 halmac_su_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
3985 void *driver_adapter = NULL;
3986 struct halmac_api *halmac_api;
3988 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3989 return HALMAC_RET_ADAPTER_INVALID;
3991 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
3992 return HALMAC_RET_API_INVALID;
3994 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SU_BFER_ENTRY_DEL);
3996 driver_adapter = halmac_adapter->driver_adapter;
3997 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4001 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO,
4003 HALMAC_REG_WRITE_32(halmac_adapter,
4004 REG_ASSOCIATED_BFMER0_INFO + 4, 0);
4007 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER1_INFO,
4009 HALMAC_REG_WRITE_32(halmac_adapter,
4010 REG_ASSOCIATED_BFMER1_INFO + 4, 0);
4013 pr_err("%s invalid userid %d\n", __func__,
4015 return HALMAC_RET_INVALID_SOUNDING_SETTING;
4018 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4019 "%s <==========\n", __func__);
4021 return HALMAC_RET_SUCCESS;
4025 * halmac_mu_bfee_entry_del_88xx() - reset MU beamformee's registers
4026 * @halmac_adapter : the adapter of halmac
4027 * @userid : the MU STA userid to be deleted
4029 * Return : enum halmac_ret_status
4030 * More details of status code can be found in prototype document
4032 enum halmac_ret_status
4033 halmac_mu_bfee_entry_del_88xx(struct halmac_adapter *halmac_adapter, u8 userid)
4035 void *driver_adapter = NULL;
4036 struct halmac_api *halmac_api;
4038 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4039 return HALMAC_RET_ADAPTER_INVALID;
4041 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4042 return HALMAC_RET_API_INVALID;
4044 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFEE_ENTRY_DEL);
4046 driver_adapter = halmac_adapter->driver_adapter;
4047 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4049 HALMAC_REG_WRITE_16(halmac_adapter, 0x1680 + userid * 2, 0);
4050 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL,
4051 HALMAC_REG_READ_8(halmac_adapter, REG_MU_TX_CTL) &
4052 ~(BIT(userid - 2)));
4054 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4055 "%s <==========\n", __func__);
4057 return HALMAC_RET_SUCCESS;
4061 * halmac_mu_bfer_entry_del_88xx() -reset MU beamformer's registers
4062 * @halmac_adapter : the adapter of halmac
4064 * Return : enum halmac_ret_status
4065 * More details of status code can be found in prototype document
4067 enum halmac_ret_status
4068 halmac_mu_bfer_entry_del_88xx(struct halmac_adapter *halmac_adapter)
4070 void *driver_adapter = NULL;
4071 struct halmac_api *halmac_api;
4073 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4074 return HALMAC_RET_ADAPTER_INVALID;
4076 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4077 return HALMAC_RET_API_INVALID;
4079 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MU_BFER_ENTRY_DEL);
4081 driver_adapter = halmac_adapter->driver_adapter;
4082 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4084 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO, 0);
4085 HALMAC_REG_WRITE_32(halmac_adapter, REG_ASSOCIATED_BFMER0_INFO + 4, 0);
4086 HALMAC_REG_WRITE_16(halmac_adapter, 0x1680, 0);
4087 HALMAC_REG_WRITE_8(halmac_adapter, REG_MU_TX_CTL, 0);
4089 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
4090 "%s <==========\n", __func__);
4092 return HALMAC_RET_SUCCESS;
4096 * halmac_add_ch_info_88xx() -add channel information
4097 * @halmac_adapter : the adapter of halmac
4098 * @ch_info : channel information
4099 * Author : KaiYuan Chang/Ivan Lin
4100 * Return : enum halmac_ret_status
4101 * More details of status code can be found in prototype document
4103 enum halmac_ret_status
4104 halmac_add_ch_info_88xx(struct halmac_adapter *halmac_adapter,
4105 struct halmac_ch_info *ch_info)
4107 void *driver_adapter = NULL;
4108 struct halmac_cs_info *ch_sw_info;
4109 enum halmac_scan_cmd_construct_state state_scan;
4111 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4112 return HALMAC_RET_ADAPTER_INVALID;
4114 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4115 return HALMAC_RET_API_INVALID;
4117 driver_adapter = halmac_adapter->driver_adapter;
4118 ch_sw_info = &halmac_adapter->ch_sw_info;
4120 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4121 "[TRACE]%s ==========>\n", __func__);
4123 if (halmac_adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
4124 pr_err("[ERR]%s: gen_info is not send to FW!!!!\n", __func__);
4125 return HALMAC_RET_GEN_INFO_NOT_SENT;
4128 state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
4129 if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED &&
4130 state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4131 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_WARNING,
4132 "[WARN]Scan machine fail(add ch info)...\n");
4133 return HALMAC_RET_ERROR_STATE;
4136 if (!ch_sw_info->ch_info_buf) {
4137 ch_sw_info->ch_info_buf =
4138 kzalloc(HALMAC_EXTRA_INFO_BUFF_SIZE_88XX, GFP_KERNEL);
4139 if (!ch_sw_info->ch_info_buf)
4140 return HALMAC_RET_NULL_POINTER;
4141 ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf;
4142 ch_sw_info->buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
4143 ch_sw_info->avai_buf_size = HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
4144 ch_sw_info->total_size = 0;
4145 ch_sw_info->extra_info_en = 0;
4146 ch_sw_info->ch_num = 0;
4149 if (ch_sw_info->extra_info_en == 1) {
4150 pr_err("[ERR]%s: construct sequence wrong!!\n", __func__);
4151 return HALMAC_RET_CH_SW_SEQ_WRONG;
4154 if (ch_sw_info->avai_buf_size < 4) {
4155 pr_err("[ERR]%s: no available buffer!!\n", __func__);
4156 return HALMAC_RET_CH_SW_NO_BUF;
4159 if (halmac_transition_scan_state_88xx(
4160 halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
4162 return HALMAC_RET_ERROR_STATE;
4164 CHANNEL_INFO_SET_CHANNEL(ch_sw_info->ch_info_buf_w, ch_info->channel);
4165 CHANNEL_INFO_SET_PRI_CH_IDX(ch_sw_info->ch_info_buf_w,
4166 ch_info->pri_ch_idx);
4167 CHANNEL_INFO_SET_BANDWIDTH(ch_sw_info->ch_info_buf_w, ch_info->bw);
4168 CHANNEL_INFO_SET_TIMEOUT(ch_sw_info->ch_info_buf_w, ch_info->timeout);
4169 CHANNEL_INFO_SET_ACTION_ID(ch_sw_info->ch_info_buf_w,
4170 ch_info->action_id);
4171 CHANNEL_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
4172 ch_info->extra_info);
4174 ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size - 4;
4175 ch_sw_info->total_size = ch_sw_info->total_size + 4;
4176 ch_sw_info->ch_num++;
4177 ch_sw_info->extra_info_en = ch_info->extra_info;
4178 ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w + 4;
4180 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4181 "[TRACE]%s <==========\n", __func__);
4183 return HALMAC_RET_SUCCESS;
4187 * halmac_add_extra_ch_info_88xx() -add extra channel information
4188 * @halmac_adapter : the adapter of halmac
4189 * @ch_extra_info : extra channel information
4190 * Author : KaiYuan Chang/Ivan Lin
4191 * Return : enum halmac_ret_status
4192 * More details of status code can be found in prototype document
4194 enum halmac_ret_status
4195 halmac_add_extra_ch_info_88xx(struct halmac_adapter *halmac_adapter,
4196 struct halmac_ch_extra_info *ch_extra_info)
4198 void *driver_adapter = NULL;
4199 struct halmac_cs_info *ch_sw_info;
4201 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4202 return HALMAC_RET_ADAPTER_INVALID;
4204 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4205 return HALMAC_RET_API_INVALID;
4207 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_ADD_EXTRA_CH_INFO);
4209 driver_adapter = halmac_adapter->driver_adapter;
4210 ch_sw_info = &halmac_adapter->ch_sw_info;
4212 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4213 "%s ==========>\n", __func__);
4215 if (!ch_sw_info->ch_info_buf) {
4216 pr_err("%s: NULL==ch_sw_info->ch_info_buf!!\n", __func__);
4217 return HALMAC_RET_CH_SW_SEQ_WRONG;
4220 if (ch_sw_info->extra_info_en == 0) {
4221 pr_err("%s: construct sequence wrong!!\n", __func__);
4222 return HALMAC_RET_CH_SW_SEQ_WRONG;
4225 if (ch_sw_info->avai_buf_size <
4226 (u32)(ch_extra_info->extra_info_size + 2)) {
4227 /* +2: ch_extra_info_id, ch_extra_info, ch_extra_info_size
4230 pr_err("%s: no available buffer!!\n", __func__);
4231 return HALMAC_RET_CH_SW_NO_BUF;
4234 if (halmac_query_scan_curr_state_88xx(halmac_adapter) !=
4235 HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4236 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4237 "Scan machine fail(add extra ch info)...\n");
4238 return HALMAC_RET_ERROR_STATE;
4241 if (halmac_transition_scan_state_88xx(
4242 halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) !=
4244 return HALMAC_RET_ERROR_STATE;
4246 CH_EXTRA_INFO_SET_CH_EXTRA_INFO_ID(ch_sw_info->ch_info_buf_w,
4247 ch_extra_info->extra_action_id);
4248 CH_EXTRA_INFO_SET_CH_EXTRA_INFO(ch_sw_info->ch_info_buf_w,
4249 ch_extra_info->extra_info);
4250 CH_EXTRA_INFO_SET_CH_EXTRA_INFO_SIZE(ch_sw_info->ch_info_buf_w,
4251 ch_extra_info->extra_info_size);
4252 memcpy(ch_sw_info->ch_info_buf_w + 2, ch_extra_info->extra_info_data,
4253 ch_extra_info->extra_info_size);
4255 ch_sw_info->avai_buf_size = ch_sw_info->avai_buf_size -
4256 (2 + ch_extra_info->extra_info_size);
4257 ch_sw_info->total_size =
4258 ch_sw_info->total_size + (2 + ch_extra_info->extra_info_size);
4259 ch_sw_info->extra_info_en = ch_extra_info->extra_info;
4260 ch_sw_info->ch_info_buf_w = ch_sw_info->ch_info_buf_w +
4261 (2 + ch_extra_info->extra_info_size);
4263 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4264 "%s <==========\n", __func__);
4266 return HALMAC_RET_SUCCESS;
4270 * halmac_ctrl_ch_switch_88xx() -send channel switch cmd
4271 * @halmac_adapter : the adapter of halmac
4272 * @cs_option : channel switch config
4273 * Author : KaiYuan Chang/Ivan Lin
4274 * Return : enum halmac_ret_status
4275 * More details of status code can be found in prototype document
4277 enum halmac_ret_status
4278 halmac_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
4279 struct halmac_ch_switch_option *cs_option)
4281 void *driver_adapter = NULL;
4282 struct halmac_api *halmac_api;
4283 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4284 enum halmac_scan_cmd_construct_state state_scan;
4285 enum halmac_cmd_process_status *process_status =
4286 &halmac_adapter->halmac_state.scan_state_set.process_status;
4288 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4289 return HALMAC_RET_ADAPTER_INVALID;
4291 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4292 return HALMAC_RET_API_INVALID;
4294 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4295 return HALMAC_RET_NO_DLFW;
4297 if (halmac_adapter->fw_version.h2c_version < 4)
4298 return HALMAC_RET_FW_NO_SUPPORT;
4300 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_CH_SWITCH);
4302 driver_adapter = halmac_adapter->driver_adapter;
4303 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4305 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4306 "%s cs_option->switch_en = %d==========>\n", __func__,
4307 cs_option->switch_en);
4309 if (!cs_option->switch_en)
4310 *process_status = HALMAC_CMD_PROCESS_IDLE;
4312 if (*process_status == HALMAC_CMD_PROCESS_SENDING ||
4313 *process_status == HALMAC_CMD_PROCESS_RCVD) {
4314 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4315 "Wait event(ctrl ch switch)...\n");
4316 return HALMAC_RET_BUSY_STATE;
4319 state_scan = halmac_query_scan_curr_state_88xx(halmac_adapter);
4320 if (cs_option->switch_en) {
4321 if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
4322 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
4324 "%s(on) invalid in state %x\n",
4325 __func__, state_scan);
4326 return HALMAC_RET_ERROR_STATE;
4329 if (state_scan != HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
4331 driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4332 "%s(off) invalid in state %x\n", __func__,
4334 return HALMAC_RET_ERROR_STATE;
4338 status = halmac_func_ctrl_ch_switch_88xx(halmac_adapter, cs_option);
4340 if (status != HALMAC_RET_SUCCESS) {
4341 pr_err("halmac_ctrl_ch_switch FAIL = %x!!\n", status);
4345 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4346 "%s <==========\n", __func__);
4348 return HALMAC_RET_SUCCESS;
4352 * halmac_clear_ch_info_88xx() -clear channel information
4353 * @halmac_adapter : the adapter of halmac
4354 * Author : KaiYuan Chang/Ivan Lin
4355 * Return : enum halmac_ret_status
4356 * More details of status code can be found in prototype document
4358 enum halmac_ret_status
4359 halmac_clear_ch_info_88xx(struct halmac_adapter *halmac_adapter)
4361 void *driver_adapter = NULL;
4362 struct halmac_api *halmac_api;
4364 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4365 return HALMAC_RET_ADAPTER_INVALID;
4367 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4368 return HALMAC_RET_API_INVALID;
4370 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CLEAR_CH_INFO);
4372 driver_adapter = halmac_adapter->driver_adapter;
4373 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4375 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4376 "%s ==========>\n", __func__);
4378 if (halmac_query_scan_curr_state_88xx(halmac_adapter) ==
4379 HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
4380 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4381 "Scan machine fail(clear ch info)...\n");
4382 return HALMAC_RET_ERROR_STATE;
4385 if (halmac_transition_scan_state_88xx(
4386 halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) !=
4388 return HALMAC_RET_ERROR_STATE;
4390 kfree(halmac_adapter->ch_sw_info.ch_info_buf);
4391 halmac_adapter->ch_sw_info.ch_info_buf = NULL;
4392 halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
4393 halmac_adapter->ch_sw_info.extra_info_en = 0;
4394 halmac_adapter->ch_sw_info.buf_size = 0;
4395 halmac_adapter->ch_sw_info.avai_buf_size = 0;
4396 halmac_adapter->ch_sw_info.total_size = 0;
4397 halmac_adapter->ch_sw_info.ch_num = 0;
4399 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4400 "%s <==========\n", __func__);
4402 return HALMAC_RET_SUCCESS;
4405 enum halmac_ret_status halmac_p2pps_88xx(struct halmac_adapter *halmac_adapter,
4406 struct halmac_p2pps *p2p_ps)
4408 void *driver_adapter = NULL;
4409 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4411 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4412 return HALMAC_RET_ADAPTER_INVALID;
4414 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4415 return HALMAC_RET_API_INVALID;
4417 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4418 return HALMAC_RET_NO_DLFW;
4420 if (halmac_adapter->fw_version.h2c_version < 6)
4421 return HALMAC_RET_FW_NO_SUPPORT;
4423 driver_adapter = halmac_adapter->driver_adapter;
4425 status = halmac_func_p2pps_88xx(halmac_adapter, p2p_ps);
4427 if (status != HALMAC_RET_SUCCESS) {
4428 pr_err("[ERR]halmac_p2pps FAIL = %x!!\n", status);
4432 return HALMAC_RET_SUCCESS;
4435 enum halmac_ret_status
4436 halmac_func_p2pps_88xx(struct halmac_adapter *halmac_adapter,
4437 struct halmac_p2pps *p2p_ps)
4439 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4440 u16 h2c_seq_mum = 0;
4441 void *driver_adapter = halmac_adapter->driver_adapter;
4442 struct halmac_api *halmac_api;
4443 struct halmac_h2c_header_info h2c_header_info;
4444 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4446 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4447 "[TRACE]halmac_p2pps !!\n");
4449 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4451 P2PPS_SET_OFFLOAD_EN(h2c_buff, p2p_ps->offload_en);
4452 P2PPS_SET_ROLE(h2c_buff, p2p_ps->role);
4453 P2PPS_SET_CTWINDOW_EN(h2c_buff, p2p_ps->ctwindow_en);
4454 P2PPS_SET_NOA_EN(h2c_buff, p2p_ps->noa_en);
4455 P2PPS_SET_NOA_SEL(h2c_buff, p2p_ps->noa_sel);
4456 P2PPS_SET_ALLSTASLEEP(h2c_buff, p2p_ps->all_sta_sleep);
4457 P2PPS_SET_DISCOVERY(h2c_buff, p2p_ps->discovery);
4458 P2PPS_SET_P2P_PORT_ID(h2c_buff, p2p_ps->p2p_port_id);
4459 P2PPS_SET_P2P_GROUP(h2c_buff, p2p_ps->p2p_group);
4460 P2PPS_SET_P2P_MACID(h2c_buff, p2p_ps->p2p_macid);
4462 P2PPS_SET_CTWINDOW_LENGTH(h2c_buff, p2p_ps->ctwindow_length);
4464 P2PPS_SET_NOA_DURATION_PARA(h2c_buff, p2p_ps->noa_duration_para);
4465 P2PPS_SET_NOA_INTERVAL_PARA(h2c_buff, p2p_ps->noa_interval_para);
4466 P2PPS_SET_NOA_START_TIME_PARA(h2c_buff, p2p_ps->noa_start_time_para);
4467 P2PPS_SET_NOA_COUNT_PARA(h2c_buff, p2p_ps->noa_count_para);
4469 h2c_header_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
4470 h2c_header_info.content_size = 24;
4471 h2c_header_info.ack = false;
4472 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4473 &h2c_header_info, &h2c_seq_mum);
4475 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4476 HALMAC_H2C_CMD_SIZE_88XX, false);
4478 if (status != HALMAC_RET_SUCCESS)
4479 pr_err("[ERR]halmac_send_h2c_p2pps_88xx Fail = %x!!\n", status);
4485 * halmac_send_general_info_88xx() -send general information to FW
4486 * @halmac_adapter : the adapter of halmac
4487 * @general_info : general information
4488 * Author : KaiYuan Chang/Ivan Lin
4489 * Return : enum halmac_ret_status
4490 * More details of status code can be found in prototype document
4492 enum halmac_ret_status
4493 halmac_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
4494 struct halmac_general_info *general_info)
4496 void *driver_adapter = NULL;
4497 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4499 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4500 return HALMAC_RET_ADAPTER_INVALID;
4502 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4503 return HALMAC_RET_API_INVALID;
4505 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4506 return HALMAC_RET_NO_DLFW;
4508 if (halmac_adapter->fw_version.h2c_version < 4)
4509 return HALMAC_RET_FW_NO_SUPPORT;
4511 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_SEND_GENERAL_INFO);
4513 driver_adapter = halmac_adapter->driver_adapter;
4515 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4516 "%s ==========>\n", __func__);
4518 if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE) {
4519 pr_err("%s Fail due to DLFW NONE!!\n", __func__);
4520 return HALMAC_RET_DLFW_FAIL;
4523 status = halmac_func_send_general_info_88xx(halmac_adapter,
4526 if (status != HALMAC_RET_SUCCESS) {
4527 pr_err("halmac_send_general_info error = %x\n", status);
4531 if (halmac_adapter->halmac_state.dlfw_state == HALMAC_DLFW_DONE)
4532 halmac_adapter->halmac_state.dlfw_state = HALMAC_GEN_INFO_SENT;
4534 halmac_adapter->gen_info_valid = true;
4535 memcpy(&halmac_adapter->general_info, general_info,
4536 sizeof(struct halmac_general_info));
4538 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4539 "%s <==========\n", __func__);
4541 return HALMAC_RET_SUCCESS;
4545 * halmac_start_iqk_88xx() -trigger FW IQK
4546 * @halmac_adapter : the adapter of halmac
4547 * @iqk_para : IQK parameter
4548 * Author : KaiYuan Chang/Ivan Lin
4549 * Return : enum halmac_ret_status
4550 * More details of status code can be found in prototype document
4552 enum halmac_ret_status
4553 halmac_start_iqk_88xx(struct halmac_adapter *halmac_adapter,
4554 struct halmac_iqk_para_ *iqk_para)
4556 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4557 u16 h2c_seq_num = 0;
4558 void *driver_adapter = NULL;
4559 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4560 struct halmac_h2c_header_info h2c_header_info;
4561 enum halmac_cmd_process_status *process_status =
4562 &halmac_adapter->halmac_state.iqk_set.process_status;
4564 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4565 return HALMAC_RET_ADAPTER_INVALID;
4567 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4568 return HALMAC_RET_API_INVALID;
4570 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4571 return HALMAC_RET_NO_DLFW;
4573 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_START_IQK);
4575 driver_adapter = halmac_adapter->driver_adapter;
4577 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4578 "%s ==========>\n", __func__);
4580 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
4581 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4582 "Wait event(iqk)...\n");
4583 return HALMAC_RET_BUSY_STATE;
4586 *process_status = HALMAC_CMD_PROCESS_SENDING;
4588 IQK_SET_CLEAR(h2c_buff, iqk_para->clear);
4589 IQK_SET_SEGMENT_IQK(h2c_buff, iqk_para->segment_iqk);
4591 h2c_header_info.sub_cmd_id = SUB_CMD_ID_IQK;
4592 h2c_header_info.content_size = 1;
4593 h2c_header_info.ack = true;
4594 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4595 &h2c_header_info, &h2c_seq_num);
4597 halmac_adapter->halmac_state.iqk_set.seq_num = h2c_seq_num;
4599 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4600 HALMAC_H2C_CMD_SIZE_88XX, true);
4602 if (status != HALMAC_RET_SUCCESS) {
4603 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
4607 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4608 "%s <==========\n", __func__);
4610 return HALMAC_RET_SUCCESS;
4614 * halmac_ctrl_pwr_tracking_88xx() -trigger FW power tracking
4615 * @halmac_adapter : the adapter of halmac
4616 * @pwr_tracking_opt : power tracking option
4617 * Author : KaiYuan Chang/Ivan Lin
4618 * Return : enum halmac_ret_status
4619 * More details of status code can be found in prototype document
4621 enum halmac_ret_status halmac_ctrl_pwr_tracking_88xx(
4622 struct halmac_adapter *halmac_adapter,
4623 struct halmac_pwr_tracking_option *pwr_tracking_opt)
4625 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
4626 u16 h2c_seq_mum = 0;
4627 void *driver_adapter = NULL;
4628 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4629 struct halmac_h2c_header_info h2c_header_info;
4630 enum halmac_cmd_process_status *process_status =
4631 &halmac_adapter->halmac_state.power_tracking_set.process_status;
4633 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4634 return HALMAC_RET_ADAPTER_INVALID;
4636 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4637 return HALMAC_RET_API_INVALID;
4639 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4640 return HALMAC_RET_NO_DLFW;
4642 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CTRL_PWR_TRACKING);
4644 driver_adapter = halmac_adapter->driver_adapter;
4646 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4647 "halmac_start_iqk_88xx ==========>\n");
4649 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
4650 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
4651 "Wait event(pwr tracking)...\n");
4652 return HALMAC_RET_BUSY_STATE;
4655 *process_status = HALMAC_CMD_PROCESS_SENDING;
4657 POWER_TRACKING_SET_TYPE(h2c_buff, pwr_tracking_opt->type);
4658 POWER_TRACKING_SET_BBSWING_INDEX(h2c_buff,
4659 pwr_tracking_opt->bbswing_index);
4660 POWER_TRACKING_SET_ENABLE_A(
4662 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A].enable);
4663 POWER_TRACKING_SET_TX_PWR_INDEX_A(
4664 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4666 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_A(
4667 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4668 .pwr_tracking_offset_value);
4669 POWER_TRACKING_SET_TSSI_VALUE_A(
4670 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_A]
4672 POWER_TRACKING_SET_ENABLE_B(
4674 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B].enable);
4675 POWER_TRACKING_SET_TX_PWR_INDEX_B(
4676 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4678 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_B(
4679 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4680 .pwr_tracking_offset_value);
4681 POWER_TRACKING_SET_TSSI_VALUE_B(
4682 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_B]
4684 POWER_TRACKING_SET_ENABLE_C(
4686 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C].enable);
4687 POWER_TRACKING_SET_TX_PWR_INDEX_C(
4688 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4690 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_C(
4691 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4692 .pwr_tracking_offset_value);
4693 POWER_TRACKING_SET_TSSI_VALUE_C(
4694 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_C]
4696 POWER_TRACKING_SET_ENABLE_D(
4698 pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D].enable);
4699 POWER_TRACKING_SET_TX_PWR_INDEX_D(
4700 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4702 POWER_TRACKING_SET_PWR_TRACKING_OFFSET_VALUE_D(
4703 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4704 .pwr_tracking_offset_value);
4705 POWER_TRACKING_SET_TSSI_VALUE_D(
4706 h2c_buff, pwr_tracking_opt->pwr_tracking_para[HALMAC_RF_PATH_D]
4709 h2c_header_info.sub_cmd_id = SUB_CMD_ID_POWER_TRACKING;
4710 h2c_header_info.content_size = 20;
4711 h2c_header_info.ack = true;
4712 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
4713 &h2c_header_info, &h2c_seq_mum);
4715 halmac_adapter->halmac_state.power_tracking_set.seq_num = h2c_seq_mum;
4717 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
4718 HALMAC_H2C_CMD_SIZE_88XX, true);
4720 if (status != HALMAC_RET_SUCCESS) {
4721 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
4725 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4726 "halmac_start_iqk_88xx <==========\n");
4728 return HALMAC_RET_SUCCESS;
4732 * halmac_query_status_88xx() -query the offload feature status
4733 * @halmac_adapter : the adapter of halmac
4734 * @feature_id : feature_id
4735 * @process_status : feature_status
4736 * @data : data buffer
4740 * If user wants to know the data size, use can allocate zero
4741 * size buffer first. If this size less than the data size, halmac
4742 * will return HALMAC_RET_BUFFER_TOO_SMALL. User need to
4743 * re-allocate data buffer with correct data size.
4745 * Author : Ivan Lin/KaiYuan Chang
4746 * Return : enum halmac_ret_status
4747 * More details of status code can be found in prototype document
4749 enum halmac_ret_status
4750 halmac_query_status_88xx(struct halmac_adapter *halmac_adapter,
4751 enum halmac_feature_id feature_id,
4752 enum halmac_cmd_process_status *process_status,
4753 u8 *data, u32 *size)
4755 void *driver_adapter = NULL;
4756 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4758 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4759 return HALMAC_RET_ADAPTER_INVALID;
4761 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4762 return HALMAC_RET_API_INVALID;
4764 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_QUERY_STATE);
4766 driver_adapter = halmac_adapter->driver_adapter;
4768 if (!process_status) {
4769 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4770 "null pointer!!\n");
4771 return HALMAC_RET_NULL_POINTER;
4774 switch (feature_id) {
4775 case HALMAC_FEATURE_CFG_PARA:
4776 status = halmac_query_cfg_para_status_88xx(
4777 halmac_adapter, process_status, data, size);
4779 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
4780 status = halmac_query_dump_physical_efuse_status_88xx(
4781 halmac_adapter, process_status, data, size);
4783 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
4784 status = halmac_query_dump_logical_efuse_status_88xx(
4785 halmac_adapter, process_status, data, size);
4787 case HALMAC_FEATURE_CHANNEL_SWITCH:
4788 status = halmac_query_channel_switch_status_88xx(
4789 halmac_adapter, process_status, data, size);
4791 case HALMAC_FEATURE_UPDATE_PACKET:
4792 status = halmac_query_update_packet_status_88xx(
4793 halmac_adapter, process_status, data, size);
4795 case HALMAC_FEATURE_IQK:
4796 status = halmac_query_iqk_status_88xx(
4797 halmac_adapter, process_status, data, size);
4799 case HALMAC_FEATURE_POWER_TRACKING:
4800 status = halmac_query_power_tracking_status_88xx(
4801 halmac_adapter, process_status, data, size);
4803 case HALMAC_FEATURE_PSD:
4804 status = halmac_query_psd_status_88xx(
4805 halmac_adapter, process_status, data, size);
4808 pr_err("%s invalid feature id %d\n", __func__,
4810 return HALMAC_RET_INVALID_FEATURE_ID;
4817 * halmac_reset_feature_88xx() -reset async api cmd status
4818 * @halmac_adapter : the adapter of halmac
4819 * @feature_id : feature_id
4820 * Author : Ivan Lin/KaiYuan Chang
4821 * Return : enum halmac_ret_status.
4822 * More details of status code can be found in prototype document
4824 enum halmac_ret_status
4825 halmac_reset_feature_88xx(struct halmac_adapter *halmac_adapter,
4826 enum halmac_feature_id feature_id)
4828 void *driver_adapter = NULL;
4829 struct halmac_state *state = &halmac_adapter->halmac_state;
4831 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4832 return HALMAC_RET_ADAPTER_INVALID;
4834 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4835 return HALMAC_RET_API_INVALID;
4837 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_RESET_FEATURE);
4839 driver_adapter = halmac_adapter->driver_adapter;
4841 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4842 "%s ==========>\n", __func__);
4844 switch (feature_id) {
4845 case HALMAC_FEATURE_CFG_PARA:
4846 state->cfg_para_state_set.process_status =
4847 HALMAC_CMD_PROCESS_IDLE;
4848 state->cfg_para_state_set.cfg_para_cmd_construct_state =
4849 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
4851 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
4852 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
4853 state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4854 state->efuse_state_set.efuse_cmd_construct_state =
4855 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
4857 case HALMAC_FEATURE_CHANNEL_SWITCH:
4858 state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4859 state->scan_state_set.scan_cmd_construct_state =
4860 HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
4862 case HALMAC_FEATURE_UPDATE_PACKET:
4863 state->update_packet_set.process_status =
4864 HALMAC_CMD_PROCESS_IDLE;
4866 case HALMAC_FEATURE_ALL:
4867 state->cfg_para_state_set.process_status =
4868 HALMAC_CMD_PROCESS_IDLE;
4869 state->cfg_para_state_set.cfg_para_cmd_construct_state =
4870 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
4871 state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4872 state->efuse_state_set.efuse_cmd_construct_state =
4873 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
4874 state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
4875 state->scan_state_set.scan_cmd_construct_state =
4876 HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
4877 state->update_packet_set.process_status =
4878 HALMAC_CMD_PROCESS_IDLE;
4881 pr_err("%s invalid feature id %d\n", __func__,
4883 return HALMAC_RET_INVALID_FEATURE_ID;
4886 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4887 "%s <==========\n", __func__);
4889 return HALMAC_RET_SUCCESS;
4893 * halmac_check_fw_status_88xx() -check fw status
4894 * @halmac_adapter : the adapter of halmac
4895 * @fw_status : fw status
4896 * Author : KaiYuan Chang/Ivan Lin
4897 * Return : enum halmac_ret_status
4898 * More details of status code can be found in prototype document
4900 enum halmac_ret_status
4901 halmac_check_fw_status_88xx(struct halmac_adapter *halmac_adapter,
4904 u32 value32 = 0, value32_backup = 0, i = 0;
4905 void *driver_adapter = NULL;
4906 struct halmac_api *halmac_api;
4907 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4909 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4910 return HALMAC_RET_ADAPTER_INVALID;
4912 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4913 return HALMAC_RET_API_INVALID;
4915 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CHECK_FW_STATUS);
4917 driver_adapter = halmac_adapter->driver_adapter;
4918 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4920 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4921 "%s ==========>\n", __func__);
4923 value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG6);
4926 pr_err("halmac_check_fw_status REG_FW_DBG6 !=0\n");
4931 value32_backup = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
4933 for (i = 0; i <= 10; i++) {
4934 value32 = PLATFORM_REG_READ_32(driver_adapter, REG_FW_DBG7);
4935 if (value32_backup != value32)
4939 pr_err("halmac_check_fw_status Polling FW PC fail\n");
4945 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4946 "%s <==========\n", __func__);
4951 enum halmac_ret_status
4952 halmac_dump_fw_dmem_88xx(struct halmac_adapter *halmac_adapter, u8 *dmem,
4955 void *driver_adapter = NULL;
4956 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4958 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4959 return HALMAC_RET_ADAPTER_INVALID;
4961 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4962 return HALMAC_RET_API_INVALID;
4964 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DUMP_FW_DMEM);
4966 driver_adapter = halmac_adapter->driver_adapter;
4968 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4969 "%s ==========>\n", __func__);
4971 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
4972 "%s <==========\n", __func__);
4978 * halmac_cfg_max_dl_size_88xx() - config max download FW size
4979 * @halmac_adapter : the adapter of halmac
4980 * @size : max download fw size
4982 * Halmac uses this setting to set max packet size for
4984 * If user has not called this API, halmac use default
4985 * setting for download FW
4986 * Note1 : size need multiple of 2
4987 * Note2 : max size is 31K
4989 * Author : Ivan Lin/KaiYuan Chang
4990 * Return : enum halmac_ret_status
4991 * More details of status code can be found in prototype document
4993 enum halmac_ret_status
4994 halmac_cfg_max_dl_size_88xx(struct halmac_adapter *halmac_adapter, u32 size)
4996 void *driver_adapter = NULL;
4998 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
4999 return HALMAC_RET_ADAPTER_INVALID;
5001 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5002 return HALMAC_RET_API_INVALID;
5004 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_MAX_DL_SIZE);
5006 driver_adapter = halmac_adapter->driver_adapter;
5008 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5009 "%s ==========>\n", __func__);
5011 if (size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX_88XX) {
5012 pr_err("size > HALMAC_FW_CFG_MAX_DL_SIZE_MAX!\n");
5013 return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
5016 if ((size & (2 - 1)) != 0) {
5017 pr_err("size is not power of 2!\n");
5018 return HALMAC_RET_CFG_DLFW_SIZE_FAIL;
5021 halmac_adapter->max_download_size = size;
5023 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5024 "Cfg max size is : %X\n", size);
5026 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_FW, DBG_DMESG,
5027 "%s <==========\n", __func__);
5029 return HALMAC_RET_SUCCESS;
5033 * halmac_psd_88xx() - trigger fw psd
5034 * @halmac_adapter : the adapter of halmac
5035 * @start_psd : start PSD
5036 * @end_psd : end PSD
5037 * Author : KaiYuan Chang/Ivan Lin
5038 * Return : enum halmac_ret_status
5039 * More details of status code can be found in prototype document
5041 enum halmac_ret_status halmac_psd_88xx(struct halmac_adapter *halmac_adapter,
5042 u16 start_psd, u16 end_psd)
5044 u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
5045 u16 h2c_seq_mum = 0;
5046 void *driver_adapter = NULL;
5047 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
5048 struct halmac_h2c_header_info h2c_header_info;
5049 enum halmac_cmd_process_status *process_status =
5050 &halmac_adapter->halmac_state.psd_set.process_status;
5052 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5053 return HALMAC_RET_ADAPTER_INVALID;
5055 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5056 return HALMAC_RET_API_INVALID;
5058 if (halmac_fw_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5059 return HALMAC_RET_NO_DLFW;
5061 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PSD);
5063 driver_adapter = halmac_adapter->driver_adapter;
5065 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5066 "%s ==========>\n", __func__);
5068 if (*process_status == HALMAC_CMD_PROCESS_SENDING) {
5069 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5070 "Wait event(psd)...\n");
5071 return HALMAC_RET_BUSY_STATE;
5074 kfree(halmac_adapter->halmac_state.psd_set.data);
5075 halmac_adapter->halmac_state.psd_set.data = (u8 *)NULL;
5077 halmac_adapter->halmac_state.psd_set.data_size = 0;
5078 halmac_adapter->halmac_state.psd_set.segment_size = 0;
5080 *process_status = HALMAC_CMD_PROCESS_SENDING;
5082 PSD_SET_START_PSD(h2c_buff, start_psd);
5083 PSD_SET_END_PSD(h2c_buff, end_psd);
5085 h2c_header_info.sub_cmd_id = SUB_CMD_ID_PSD;
5086 h2c_header_info.content_size = 4;
5087 h2c_header_info.ack = true;
5088 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
5089 &h2c_header_info, &h2c_seq_mum);
5091 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
5092 HALMAC_H2C_CMD_SIZE_88XX, true);
5094 if (status != HALMAC_RET_SUCCESS) {
5095 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
5099 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5100 "%s <==========\n", __func__);
5102 return HALMAC_RET_SUCCESS;
5106 * halmac_cfg_la_mode_88xx() - config la mode
5107 * @halmac_adapter : the adapter of halmac
5109 * disable : no TXFF space reserved for LA debug
5110 * partial : partial TXFF space is reserved for LA debug
5111 * full : all TXFF space is reserved for LA debug
5112 * Author : KaiYuan Chang
5113 * Return : enum halmac_ret_status
5114 * More details of status code can be found in prototype document
5116 enum halmac_ret_status
5117 halmac_cfg_la_mode_88xx(struct halmac_adapter *halmac_adapter,
5118 enum halmac_la_mode la_mode)
5120 void *driver_adapter = NULL;
5122 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5123 return HALMAC_RET_ADAPTER_INVALID;
5125 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5126 return HALMAC_RET_API_INVALID;
5128 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_LA_MODE);
5130 driver_adapter = halmac_adapter->driver_adapter;
5132 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5133 "%s ==========>la_mode = %d\n", __func__,
5136 halmac_adapter->txff_allocation.la_mode = la_mode;
5138 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5139 "%s <==========\n", __func__);
5141 return HALMAC_RET_SUCCESS;
5145 * halmac_cfg_rx_fifo_expanding_mode_88xx() - rx fifo expanding
5146 * @halmac_adapter : the adapter of halmac
5148 * disable : normal mode
5149 * 1 block : Rx FIFO + 1 FIFO block; Tx fifo - 1 FIFO block
5150 * 2 block : Rx FIFO + 2 FIFO block; Tx fifo - 2 FIFO block
5151 * 3 block : Rx FIFO + 3 FIFO block; Tx fifo - 3 FIFO block
5153 * Return : enum halmac_ret_status
5154 * More details of status code can be found in prototype document
5156 enum halmac_ret_status halmac_cfg_rx_fifo_expanding_mode_88xx(
5157 struct halmac_adapter *halmac_adapter,
5158 enum halmac_rx_fifo_expanding_mode rx_fifo_expanding_mode)
5160 void *driver_adapter = NULL;
5162 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5163 return HALMAC_RET_ADAPTER_INVALID;
5165 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5166 return HALMAC_RET_API_INVALID;
5168 halmac_api_record_id_88xx(halmac_adapter,
5169 HALMAC_API_CFG_RX_FIFO_EXPANDING_MODE);
5171 driver_adapter = halmac_adapter->driver_adapter;
5174 driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5175 "%s ==========>rx_fifo_expanding_mode = %d\n", __func__,
5176 rx_fifo_expanding_mode);
5178 halmac_adapter->txff_allocation.rx_fifo_expanding_mode =
5179 rx_fifo_expanding_mode;
5181 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5182 "%s <==========\n", __func__);
5184 return HALMAC_RET_SUCCESS;
5187 enum halmac_ret_status
5188 halmac_config_security_88xx(struct halmac_adapter *halmac_adapter,
5189 struct halmac_security_setting *sec_setting)
5191 struct halmac_api *halmac_api;
5192 void *driver_adapter = NULL;
5194 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5195 return HALMAC_RET_ADAPTER_INVALID;
5197 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5198 return HALMAC_RET_API_INVALID;
5200 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5201 driver_adapter = halmac_adapter->driver_adapter;
5203 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5204 "%s ==========>\n", __func__);
5206 HALMAC_REG_WRITE_16(halmac_adapter, REG_CR,
5207 (u16)(HALMAC_REG_READ_16(halmac_adapter, REG_CR) |
5210 if (sec_setting->tx_encryption == 1)
5212 halmac_adapter, REG_SECCFG,
5213 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(2));
5216 halmac_adapter, REG_SECCFG,
5217 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
5220 if (sec_setting->rx_decryption == 1)
5222 halmac_adapter, REG_SECCFG,
5223 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) | BIT(3));
5226 halmac_adapter, REG_SECCFG,
5227 HALMAC_REG_READ_8(halmac_adapter, REG_SECCFG) &
5230 if (sec_setting->bip_enable == 1) {
5231 if (halmac_adapter->chip_id == HALMAC_CHIP_ID_8822B)
5232 return HALMAC_RET_BIP_NO_SUPPORT;
5235 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5236 "%s <==========\n", __func__);
5238 return HALMAC_RET_SUCCESS;
5241 u8 halmac_get_used_cam_entry_num_88xx(struct halmac_adapter *halmac_adapter,
5242 enum hal_security_type sec_type)
5245 void *driver_adapter = NULL;
5247 driver_adapter = halmac_adapter->driver_adapter;
5249 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5250 "%s ==========>\n", __func__);
5253 case HAL_SECURITY_TYPE_WEP40:
5254 case HAL_SECURITY_TYPE_WEP104:
5255 case HAL_SECURITY_TYPE_TKIP:
5256 case HAL_SECURITY_TYPE_AES128:
5257 case HAL_SECURITY_TYPE_GCMP128:
5258 case HAL_SECURITY_TYPE_GCMSMS4:
5259 case HAL_SECURITY_TYPE_BIP:
5262 case HAL_SECURITY_TYPE_WAPI:
5263 case HAL_SECURITY_TYPE_AES256:
5264 case HAL_SECURITY_TYPE_GCMP256:
5272 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5273 "%s <==========\n", __func__);
5278 enum halmac_ret_status
5279 halmac_write_cam_88xx(struct halmac_adapter *halmac_adapter, u32 entry_index,
5280 struct halmac_cam_entry_info *cam_entry_info)
5283 u32 command = 0x80010000;
5284 struct halmac_api *halmac_api;
5285 void *driver_adapter = NULL;
5286 struct halmac_cam_entry_format *cam_entry_format = NULL;
5288 driver_adapter = halmac_adapter->driver_adapter;
5289 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5291 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5292 "[TRACE]%s ==========>\n", __func__);
5294 if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5295 return HALMAC_RET_ENTRY_INDEX_ERROR;
5297 if (cam_entry_info->key_id > 3)
5298 return HALMAC_RET_FAIL;
5300 cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
5301 if (!cam_entry_format)
5302 return HALMAC_RET_NULL_POINTER;
5304 cam_entry_format->key_id = cam_entry_info->key_id;
5305 cam_entry_format->valid = cam_entry_info->valid;
5306 memcpy(cam_entry_format->mac_address, cam_entry_info->mac_address, 6);
5307 memcpy(cam_entry_format->key, cam_entry_info->key, 16);
5309 switch (cam_entry_info->security_type) {
5310 case HAL_SECURITY_TYPE_NONE:
5311 cam_entry_format->type = 0;
5313 case HAL_SECURITY_TYPE_WEP40:
5314 cam_entry_format->type = 1;
5316 case HAL_SECURITY_TYPE_WEP104:
5317 cam_entry_format->type = 5;
5319 case HAL_SECURITY_TYPE_TKIP:
5320 cam_entry_format->type = 2;
5322 case HAL_SECURITY_TYPE_AES128:
5323 cam_entry_format->type = 4;
5325 case HAL_SECURITY_TYPE_WAPI:
5326 cam_entry_format->type = 6;
5328 case HAL_SECURITY_TYPE_AES256:
5329 cam_entry_format->type = 4;
5330 cam_entry_format->ext_sectype = 1;
5332 case HAL_SECURITY_TYPE_GCMP128:
5333 cam_entry_format->type = 7;
5335 case HAL_SECURITY_TYPE_GCMP256:
5336 case HAL_SECURITY_TYPE_GCMSMS4:
5337 cam_entry_format->type = 7;
5338 cam_entry_format->ext_sectype = 1;
5340 case HAL_SECURITY_TYPE_BIP:
5341 cam_entry_format->type = cam_entry_info->unicast == 1 ? 4 : 0;
5342 cam_entry_format->mgnt = 1;
5343 cam_entry_format->grp = cam_entry_info->unicast == 1 ? 0 : 1;
5346 kfree(cam_entry_format);
5347 return HALMAC_RET_FAIL;
5350 for (i = 0; i < 8; i++) {
5351 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5352 *((u32 *)cam_entry_format + i));
5353 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5354 command | ((entry_index << 3) + i));
5355 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5356 "[TRACE]1 - CAM entry format : %X\n",
5357 *((u32 *)cam_entry_format + i));
5358 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5359 "[TRACE]1 - REG_CAMCMD : %X\n",
5360 command | ((entry_index << 3) + i));
5363 if (cam_entry_info->security_type == HAL_SECURITY_TYPE_WAPI ||
5364 cam_entry_info->security_type == HAL_SECURITY_TYPE_AES256 ||
5365 cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMP256 ||
5366 cam_entry_info->security_type == HAL_SECURITY_TYPE_GCMSMS4) {
5367 cam_entry_format->mic = 1;
5368 memcpy(cam_entry_format->key, cam_entry_info->key_ext, 16);
5370 for (i = 0; i < 8; i++) {
5371 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5372 *((u32 *)cam_entry_format + i));
5373 HALMAC_REG_WRITE_32(
5374 halmac_adapter, REG_CAMCMD,
5375 command | (((entry_index + 1) << 3) + i));
5376 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON,
5378 "[TRACE]2 - CAM entry format : %X\n",
5379 *((u32 *)cam_entry_format + i));
5381 driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5382 "[TRACE]2 - REG_CAMCMD : %X\n",
5383 command | (((entry_index + 1) << 3) + i));
5387 kfree(cam_entry_format);
5389 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5390 "[TRACE]%s <==========\n", __func__);
5392 return HALMAC_RET_SUCCESS;
5395 enum halmac_ret_status
5396 halmac_read_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
5398 struct halmac_cam_entry_format *content)
5401 u32 command = 0x80000000;
5402 struct halmac_api *halmac_api;
5403 void *driver_adapter = NULL;
5405 driver_adapter = halmac_adapter->driver_adapter;
5406 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5408 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5409 "%s ==========>\n", __func__);
5411 if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5412 return HALMAC_RET_ENTRY_INDEX_ERROR;
5414 for (i = 0; i < 8; i++) {
5415 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5416 command | ((entry_index << 3) + i));
5417 *((u32 *)content + i) =
5418 HALMAC_REG_READ_32(halmac_adapter, REG_CAMREAD);
5421 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5422 "%s <==========\n", __func__);
5424 return HALMAC_RET_SUCCESS;
5427 enum halmac_ret_status
5428 halmac_clear_cam_entry_88xx(struct halmac_adapter *halmac_adapter,
5432 u32 command = 0x80010000;
5433 void *driver_adapter = NULL;
5434 struct halmac_api *halmac_api;
5435 struct halmac_cam_entry_format *cam_entry_format;
5437 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5438 return HALMAC_RET_ADAPTER_INVALID;
5440 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5441 return HALMAC_RET_API_INVALID;
5443 driver_adapter = halmac_adapter->driver_adapter;
5444 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5446 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5447 "[TRACE]halmac_clear_security_cam_88xx ==========>\n");
5449 if (entry_index >= halmac_adapter->hw_config_info.cam_entry_num)
5450 return HALMAC_RET_ENTRY_INDEX_ERROR;
5452 cam_entry_format = kzalloc(sizeof(*cam_entry_format), GFP_KERNEL);
5453 if (!cam_entry_format)
5454 return HALMAC_RET_NULL_POINTER;
5456 for (i = 0; i < 8; i++) {
5457 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMWRITE,
5458 *((u32 *)cam_entry_format + i));
5459 HALMAC_REG_WRITE_32(halmac_adapter, REG_CAMCMD,
5460 command | ((entry_index << 3) + i));
5463 kfree(cam_entry_format);
5465 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5466 "[TRACE]halmac_clear_security_cam_88xx <==========\n");
5468 return HALMAC_RET_SUCCESS;
5472 * halmac_get_hw_value_88xx() -get hw config value
5473 * @halmac_adapter : the adapter of halmac
5474 * @hw_id : hw id for driver to query
5475 * @pvalue : hw value, reference table to get data type
5476 * Author : KaiYuan Chang / Ivan Lin
5477 * Return : enum halmac_ret_status
5478 * More details of status code can be found in prototype document
5480 enum halmac_ret_status
5481 halmac_get_hw_value_88xx(struct halmac_adapter *halmac_adapter,
5482 enum halmac_hw_id hw_id, void *pvalue)
5484 void *driver_adapter = NULL;
5485 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
5487 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5488 return HALMAC_RET_ADAPTER_INVALID;
5490 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5491 return HALMAC_RET_API_INVALID;
5493 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
5495 driver_adapter = halmac_adapter->driver_adapter;
5497 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5498 "%s ==========>\n", __func__);
5501 pr_err("%s (!pvalue)==========>\n", __func__);
5502 return HALMAC_RET_NULL_POINTER;
5506 case HALMAC_HW_RQPN_MAPPING:
5507 ((struct halmac_rqpn_map *)pvalue)->dma_map_vo =
5508 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO];
5509 ((struct halmac_rqpn_map *)pvalue)->dma_map_vi =
5510 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI];
5511 ((struct halmac_rqpn_map *)pvalue)->dma_map_be =
5512 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE];
5513 ((struct halmac_rqpn_map *)pvalue)->dma_map_bk =
5514 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK];
5515 ((struct halmac_rqpn_map *)pvalue)->dma_map_mg =
5516 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG];
5517 ((struct halmac_rqpn_map *)pvalue)->dma_map_hi =
5518 halmac_adapter->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI];
5520 case HALMAC_HW_EFUSE_SIZE:
5521 *(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size;
5523 case HALMAC_HW_EEPROM_SIZE:
5524 *(u32 *)pvalue = halmac_adapter->hw_config_info.eeprom_size;
5526 case HALMAC_HW_BT_BANK_EFUSE_SIZE:
5527 *(u32 *)pvalue = halmac_adapter->hw_config_info.bt_efuse_size;
5529 case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
5530 case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
5533 case HALMAC_HW_TXFIFO_SIZE:
5534 *(u32 *)pvalue = halmac_adapter->hw_config_info.tx_fifo_size;
5536 case HALMAC_HW_RSVD_PG_BNDY:
5538 halmac_adapter->txff_allocation.rsvd_drv_pg_bndy;
5540 case HALMAC_HW_CAM_ENTRY_NUM:
5541 *(u8 *)pvalue = halmac_adapter->hw_config_info.cam_entry_num;
5543 case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE: /*Remove later*/
5544 status = halmac_dump_logical_efuse_map_88xx(halmac_adapter,
5545 HALMAC_EFUSE_R_DRV);
5546 if (status != HALMAC_RET_SUCCESS)
5548 *(u32 *)pvalue = halmac_adapter->hw_config_info.efuse_size -
5549 HALMAC_PROTECTED_EFUSE_SIZE_88XX -
5550 halmac_adapter->efuse_end;
5552 case HALMAC_HW_IC_VERSION:
5553 *(u8 *)pvalue = halmac_adapter->chip_version;
5555 case HALMAC_HW_PAGE_SIZE:
5556 *(u32 *)pvalue = halmac_adapter->hw_config_info.page_size;
5558 case HALMAC_HW_TX_AGG_ALIGN_SIZE:
5559 *(u16 *)pvalue = halmac_adapter->hw_config_info.tx_align_size;
5561 case HALMAC_HW_RX_AGG_ALIGN_SIZE:
5564 case HALMAC_HW_DRV_INFO_SIZE:
5565 *(u8 *)pvalue = halmac_adapter->drv_info_size;
5567 case HALMAC_HW_TXFF_ALLOCATION:
5568 memcpy(pvalue, &halmac_adapter->txff_allocation,
5569 sizeof(struct halmac_txff_allocation));
5571 case HALMAC_HW_TX_DESC_SIZE:
5572 *(u32 *)pvalue = halmac_adapter->hw_config_info.txdesc_size;
5574 case HALMAC_HW_RX_DESC_SIZE:
5575 *(u32 *)pvalue = halmac_adapter->hw_config_info.rxdesc_size;
5578 return HALMAC_RET_PARA_NOT_SUPPORT;
5581 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5582 "%s <==========\n", __func__);
5584 return HALMAC_RET_SUCCESS;
5588 * halmac_set_hw_value_88xx() -set hw config value
5589 * @halmac_adapter : the adapter of halmac
5590 * @hw_id : hw id for driver to config
5591 * @pvalue : hw value, reference table to get data type
5592 * Author : KaiYuan Chang / Ivan Lin
5593 * Return : enum halmac_ret_status
5594 * More details of status code can be found in prototype document
5596 enum halmac_ret_status
5597 halmac_set_hw_value_88xx(struct halmac_adapter *halmac_adapter,
5598 enum halmac_hw_id hw_id, void *pvalue)
5600 void *driver_adapter = NULL;
5601 enum halmac_ret_status status;
5603 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5604 return HALMAC_RET_ADAPTER_INVALID;
5606 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5607 return HALMAC_RET_API_INVALID;
5609 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_GET_HW_VALUE);
5611 driver_adapter = halmac_adapter->driver_adapter;
5613 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5614 "%s ==========>\n", __func__);
5617 pr_err("%s (!pvalue)==========>\n", __func__);
5618 return HALMAC_RET_NULL_POINTER;
5622 case HALMAC_HW_USB_MODE:
5623 status = halmac_set_usb_mode_88xx(
5624 halmac_adapter, *(enum halmac_usb_mode *)pvalue);
5625 if (status != HALMAC_RET_SUCCESS)
5628 case HALMAC_HW_SEQ_EN:
5630 case HALMAC_HW_BANDWIDTH:
5631 halmac_cfg_bw_88xx(halmac_adapter, *(enum halmac_bw *)pvalue);
5633 case HALMAC_HW_CHANNEL:
5634 halmac_cfg_ch_88xx(halmac_adapter, *(u8 *)pvalue);
5636 case HALMAC_HW_PRI_CHANNEL_IDX:
5637 halmac_cfg_pri_ch_idx_88xx(halmac_adapter,
5638 *(enum halmac_pri_ch_idx *)pvalue);
5640 case HALMAC_HW_EN_BB_RF:
5641 halmac_enable_bb_rf_88xx(halmac_adapter, *(u8 *)pvalue);
5643 case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
5644 halmac_config_sdio_tx_page_threshold_88xx(
5646 (struct halmac_tx_page_threshold_info *)pvalue);
5648 case HALMAC_HW_AMPDU_CONFIG:
5649 halmac_config_ampdu_88xx(halmac_adapter,
5650 (struct halmac_ampdu_config *)pvalue);
5653 return HALMAC_RET_PARA_NOT_SUPPORT;
5656 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5657 "%s <==========\n", __func__);
5659 return HALMAC_RET_SUCCESS;
5663 * halmac_cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
5664 * @halmac_adapter : the adapter of halmac
5665 * @pg_num : page number
5666 * Author : KaiYuan Chang
5667 * Return : enum halmac_ret_status
5668 * More details of status code can be found in prototype document
5670 enum halmac_ret_status
5671 halmac_cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *halmac_adapter,
5672 enum halmac_drv_rsvd_pg_num pg_num)
5674 void *driver_adapter = NULL;
5676 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5677 return HALMAC_RET_ADAPTER_INVALID;
5679 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5680 return HALMAC_RET_API_INVALID;
5682 halmac_api_record_id_88xx(halmac_adapter,
5683 HALMAC_API_CFG_DRV_RSVD_PG_NUM);
5685 driver_adapter = halmac_adapter->driver_adapter;
5687 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5688 "%s ==========>pg_num = %d\n", __func__,
5692 case HALMAC_RSVD_PG_NUM16:
5693 halmac_adapter->txff_allocation.rsvd_drv_pg_num = 16;
5695 case HALMAC_RSVD_PG_NUM24:
5696 halmac_adapter->txff_allocation.rsvd_drv_pg_num = 24;
5698 case HALMAC_RSVD_PG_NUM32:
5699 halmac_adapter->txff_allocation.rsvd_drv_pg_num = 32;
5703 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5704 "%s <==========\n", __func__);
5706 return HALMAC_RET_SUCCESS;
5709 enum halmac_ret_status
5710 halmac_get_chip_version_88xx(struct halmac_adapter *halmac_adapter,
5711 struct halmac_ver *version)
5713 void *driver_adapter = NULL;
5714 struct halmac_api *halmac_api;
5716 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5717 return HALMAC_RET_ADAPTER_INVALID;
5719 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5720 return HALMAC_RET_API_INVALID;
5722 driver_adapter = halmac_adapter->driver_adapter;
5723 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5725 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5726 "%s ==========>\n", __func__);
5727 version->major_ver = (u8)HALMAC_MAJOR_VER_88XX;
5728 version->prototype_ver = (u8)HALMAC_PROTOTYPE_VER_88XX;
5729 version->minor_ver = (u8)HALMAC_MINOR_VER_88XX;
5730 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
5731 "%s <==========\n", __func__);
5733 return HALMAC_RET_SUCCESS;
5737 * halmac_chk_txdesc_88xx() -check if the tx packet format is incorrect
5738 * @halmac_adapter : the adapter of halmac
5739 * @halmac_buf : tx Packet buffer, tx desc is included
5740 * @halmac_size : tx packet size
5741 * Author : KaiYuan Chang
5742 * Return : enum halmac_ret_status
5743 * More details of status code can be found in prototype document
5745 enum halmac_ret_status
5746 halmac_chk_txdesc_88xx(struct halmac_adapter *halmac_adapter, u8 *halmac_buf,
5749 void *driver_adapter = NULL;
5750 struct halmac_api *halmac_api;
5752 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5753 return HALMAC_RET_ADAPTER_INVALID;
5755 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5756 return HALMAC_RET_API_INVALID;
5758 driver_adapter = halmac_adapter->driver_adapter;
5759 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5761 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5762 "%s ==========>\n", __func__);
5764 if (GET_TX_DESC_BMC(halmac_buf))
5765 if (GET_TX_DESC_AGG_EN(halmac_buf))
5766 pr_err("TxDesc: Agg should not be set when BMC\n");
5768 if (halmac_size < (GET_TX_DESC_TXPKTSIZE(halmac_buf) +
5769 GET_TX_DESC_OFFSET(halmac_buf)))
5770 pr_err("TxDesc: PktSize too small\n");
5772 return HALMAC_RET_SUCCESS;
5776 * halmac_dl_drv_rsvd_page_88xx() - download packet to rsvd page
5777 * @halmac_adapter : the adapter of halmac
5778 * @pg_offset : page offset of driver's rsvd page
5779 * @halmac_buf : data to be downloaded, tx_desc is not included
5780 * @halmac_size : data size to be downloaded
5781 * Author : KaiYuan Chang
5782 * Return : enum halmac_ret_status
5783 * More details of status code can be found in prototype document
5785 enum halmac_ret_status
5786 halmac_dl_drv_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
5787 u8 pg_offset, u8 *halmac_buf, u32 halmac_size)
5789 void *driver_adapter = NULL;
5790 struct halmac_api *halmac_api;
5791 enum halmac_ret_status ret_status;
5792 u16 drv_pg_bndy = 0;
5795 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5796 return HALMAC_RET_ADAPTER_INVALID;
5798 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5799 return HALMAC_RET_API_INVALID;
5801 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_DL_DRV_RSVD_PG);
5803 driver_adapter = halmac_adapter->driver_adapter;
5804 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5806 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5807 "%s ==========>\n", __func__);
5809 /*check boundary and size valid*/
5810 dl_pg_num = halmac_size / halmac_adapter->hw_config_info.page_size +
5812 (halmac_adapter->hw_config_info.page_size - 1)) ?
5815 if (pg_offset + dl_pg_num >
5816 halmac_adapter->txff_allocation.rsvd_drv_pg_num) {
5817 pr_err("[ERROR] driver download offset or size error ==========>\n");
5818 return HALMAC_RET_DRV_DL_ERR;
5821 /*update to target download boundary*/
5823 halmac_adapter->txff_allocation.rsvd_drv_pg_bndy + pg_offset;
5824 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
5825 (u16)(drv_pg_bndy & BIT_MASK_BCN_HEAD_1_V1));
5827 ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, halmac_buf,
5830 /*restore to original bundary*/
5831 if (ret_status != HALMAC_RET_SUCCESS) {
5832 pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
5834 HALMAC_REG_WRITE_16(
5835 halmac_adapter, REG_FIFOPAGE_CTRL_2,
5836 (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
5837 BIT_MASK_BCN_HEAD_1_V1));
5841 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
5842 (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
5843 BIT_MASK_BCN_HEAD_1_V1));
5845 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
5846 "%s < ==========\n", __func__);
5847 return HALMAC_RET_SUCCESS;
5851 * halmac_cfg_csi_rate_88xx() - config CSI frame Tx rate
5852 * @halmac_adapter : the adapter of halmac
5853 * @rssi : rssi in decimal value
5854 * @current_rate : current CSI frame rate
5855 * @fixrate_en : enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate
5856 * @new_rate : API returns the final CSI frame rate
5858 * Return : enum halmac_ret_status
5859 * More details of status code can be found in prototype document
5861 enum halmac_ret_status
5862 halmac_cfg_csi_rate_88xx(struct halmac_adapter *halmac_adapter, u8 rssi,
5863 u8 current_rate, u8 fixrate_en, u8 *new_rate)
5865 void *driver_adapter = NULL;
5866 struct halmac_api *halmac_api;
5867 u32 temp_csi_setting;
5869 enum halmac_ret_status ret_status;
5871 if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5872 return HALMAC_RET_ADAPTER_INVALID;
5874 if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
5875 return HALMAC_RET_API_INVALID;
5877 halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_CFG_CSI_RATE);
5879 driver_adapter = halmac_adapter->driver_adapter;
5880 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5881 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_SND, DBG_DMESG,
5882 "<%s ==========>\n", __func__);
5884 temp_csi_setting = HALMAC_REG_READ_32(halmac_adapter, REG_BBPSF_CTRL) &
5885 ~(BIT_MASK_WMAC_CSI_RATE << BIT_SHIFT_WMAC_CSI_RATE);
5887 current_rrsr = HALMAC_REG_READ_16(halmac_adapter, REG_RRSR);
5890 if (current_rate != HALMAC_OFDM54) {
5891 HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
5892 current_rrsr | BIT(HALMAC_OFDM54));
5893 HALMAC_REG_WRITE_32(
5894 halmac_adapter, REG_BBPSF_CTRL,
5896 BIT_WMAC_CSI_RATE(HALMAC_OFDM54));
5898 *new_rate = HALMAC_OFDM54;
5899 ret_status = HALMAC_RET_SUCCESS;
5901 if (current_rate != HALMAC_OFDM24) {
5902 HALMAC_REG_WRITE_16(halmac_adapter, REG_RRSR,
5904 ~(BIT(HALMAC_OFDM54)));
5905 HALMAC_REG_WRITE_32(
5906 halmac_adapter, REG_BBPSF_CTRL,
5908 BIT_WMAC_CSI_RATE(HALMAC_OFDM24));
5910 *new_rate = HALMAC_OFDM24;
5911 ret_status = HALMAC_RET_SUCCESS;
5918 * halmac_sdio_cmd53_4byte_88xx() - cmd53 only for 4byte len register IO
5919 * @halmac_adapter : the adapter of halmac
5920 * @enable : 1->CMD53 only use in 4byte reg, 0 : No limitation
5921 * Author : Ivan Lin/KaiYuan Chang
5922 * Return : enum halmac_ret_status
5923 * More details of status code can be found in prototype document
5925 enum halmac_ret_status
5926 halmac_sdio_cmd53_4byte_88xx(struct halmac_adapter *halmac_adapter,
5927 enum halmac_sdio_cmd53_4byte_mode cmd53_4byte_mode)
5929 halmac_adapter->sdio_cmd53_4byte = cmd53_4byte_mode;
5931 return HALMAC_RET_SUCCESS;
5935 * halmac_txfifo_is_empty_88xx() -check if txfifo is empty
5936 * @halmac_adapter : the adapter of halmac
5938 * Return : enum halmac_ret_status
5939 * More details of status code can be found in prototype document
5941 enum halmac_ret_status
5942 halmac_txfifo_is_empty_88xx(struct halmac_adapter *halmac_adapter, u32 chk_num)
5945 void *driver_adapter = NULL;
5946 struct halmac_api *halmac_api;
5948 driver_adapter = halmac_adapter->driver_adapter;
5949 halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
5951 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5952 "%s ==========>\n", __func__);
5954 counter = (chk_num <= 10) ? 10 : chk_num;
5956 if (HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY) != 0xFF)
5957 return HALMAC_RET_TXFIFO_NO_EMPTY;
5959 if ((HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY + 1) &
5961 return HALMAC_RET_TXFIFO_NO_EMPTY;
5964 } while (counter != 0);
5966 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_COMMON, DBG_DMESG,
5967 "%s <==========\n", __func__);
5969 return HALMAC_RET_SUCCESS;