1 /******************************************************************************
3 * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
16 #include "halmac_common_88xx.h"
17 #include "halmac_88xx_cfg.h"
18 #include "halmac_init_88xx.h"
19 #include "halmac_cfg_wmac_88xx.h"
20 #include "halmac_efuse_88xx.h"
21 #include "halmac_bb_rf_88xx.h"
22 #if HALMAC_USB_SUPPORT
23 #include "halmac_usb_88xx.h"
25 #if HALMAC_SDIO_SUPPORT
26 #include "halmac_sdio_88xx.h"
28 #if HALMAC_PCIE_SUPPORT
29 #include "halmac_pcie_88xx.h"
31 #include "halmac_mimo_88xx.h"
33 #if HALMAC_88XX_SUPPORT
35 #define CFG_PARAM_H2C_INFO_SIZE 12
36 #define ORIGINAL_H2C_CMD_SIZE 8
38 #define WLHDR_PROT_VER 0
40 #define WLHDR_TYPE_MGMT 0
41 #define WLHDR_TYPE_CTRL 1
42 #define WLHDR_TYPE_DATA 2
45 #define WLHDR_SUB_TYPE_ASSOC_REQ 0
46 #define WLHDR_SUB_TYPE_ASSOC_RSPNS 1
47 #define WLHDR_SUB_TYPE_REASSOC_REQ 2
48 #define WLHDR_SUB_TYPE_REASSOC_RSPNS 3
49 #define WLHDR_SUB_TYPE_PROBE_REQ 4
50 #define WLHDR_SUB_TYPE_PROBE_RSPNS 5
51 #define WLHDR_SUB_TYPE_BCN 8
52 #define WLHDR_SUB_TYPE_DISASSOC 10
53 #define WLHDR_SUB_TYPE_AUTH 11
54 #define WLHDR_SUB_TYPE_DEAUTH 12
55 #define WLHDR_SUB_TYPE_ACTION 13
56 #define WLHDR_SUB_TYPE_ACTION_NOACK 14
59 #define WLHDR_SUB_TYPE_BF_RPT_POLL 4
60 #define WLHDR_SUB_TYPE_NDPA 5
63 #define WLHDR_SUB_TYPE_DATA 0
64 #define WLHDR_SUB_TYPE_NULL 4
65 #define WLHDR_SUB_TYPE_QOS_DATA 8
66 #define WLHDR_SUB_TYPE_QOS_NULL 12
68 #define LTECOEX_ACCESS_CTRL REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1
70 struct wlhdr_frame_ctrl {
84 static enum halmac_ret_status
85 parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
87 static enum halmac_ret_status
88 get_c2h_dbg_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
90 static enum halmac_ret_status
91 get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
93 static enum halmac_ret_status
94 get_scan_rpt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
96 static enum halmac_ret_status
97 get_h2c_ack_cfg_param_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
99 static enum halmac_ret_status
100 get_h2c_ack_update_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
102 static enum halmac_ret_status
103 get_h2c_ack_update_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf,
106 static enum halmac_ret_status
107 get_h2c_ack_run_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
109 static enum halmac_ret_status
110 get_h2c_ack_ch_switch_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
112 static enum halmac_ret_status
113 malloc_cfg_param_buf_88xx(struct halmac_adapter *adapter, u8 full_fifo);
115 static enum halmac_cmd_construct_state
116 cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
118 static enum halmac_ret_status
119 proc_cfg_param_88xx(struct halmac_adapter *adapter,
120 struct halmac_phy_parameter_info *param, u8 full_fifo);
122 static enum halmac_ret_status
123 send_cfg_param_h2c_88xx(struct halmac_adapter *adapter);
125 static enum halmac_ret_status
126 cnv_cfg_param_state_88xx(struct halmac_adapter *adapter,
127 enum halmac_cmd_construct_state dest_state);
129 static enum halmac_ret_status
130 add_param_buf_88xx(struct halmac_adapter *adapter,
131 struct halmac_phy_parameter_info *param, u8 *buf,
134 static enum halmac_ret_status
135 gen_cfg_param_h2c_88xx(struct halmac_adapter *adapter, u8 *buff);
137 static enum halmac_ret_status
138 send_h2c_update_packet_88xx(struct halmac_adapter *adapter,
139 enum halmac_packet_id pkt_id, u8 *pkt, u32 size);
141 static enum halmac_ret_status
142 send_bt_coex_cmd_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
145 static enum halmac_ret_status
146 read_buf_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
147 enum hal_fifo_sel sel, u8 *data);
149 static enum halmac_cmd_construct_state
150 scan_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
152 static enum halmac_ret_status
153 cnv_scan_state_88xx(struct halmac_adapter *adapter,
154 enum halmac_cmd_construct_state dest_state);
156 static enum halmac_ret_status
157 proc_ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
158 struct halmac_ch_switch_option *opt);
160 static enum halmac_ret_status
161 proc_p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info);
163 static enum halmac_ret_status
164 get_cfg_param_status_88xx(struct halmac_adapter *adapter,
165 enum halmac_cmd_process_status *proc_status);
167 static enum halmac_ret_status
168 get_ch_switch_status_88xx(struct halmac_adapter *adapter,
169 enum halmac_cmd_process_status *proc_status);
171 static enum halmac_ret_status
172 get_update_packet_status_88xx(struct halmac_adapter *adapter,
173 enum halmac_cmd_process_status *proc_status);
175 static enum halmac_ret_status
176 pwr_sub_seq_parser_88xx(struct halmac_adapter *adapter, u8 cut, u8 intf,
177 struct halmac_wlan_pwr_cfg *cmd);
180 pwr_state_88xx(struct halmac_adapter *adapter, enum halmac_mac_power *state);
182 static enum halmac_ret_status
183 pwr_cmd_polling_88xx(struct halmac_adapter *adapter,
184 struct halmac_wlan_pwr_cfg *cmd);
187 get_pq_mapping_88xx(struct halmac_adapter *adapter,
188 struct halmac_rqpn_map *mapping);
191 dump_reg_sdio_88xx(struct halmac_adapter *adapter);
193 static enum halmac_ret_status
194 wlhdr_valid_88xx(struct halmac_adapter *adapter, u8 *buf);
197 wlhdr_mgmt_valid_88xx(struct halmac_adapter *adapter,
198 struct wlhdr_frame_ctrl *wlhdr);
201 wlhdr_ctrl_valid_88xx(struct halmac_adapter *adapter,
202 struct wlhdr_frame_ctrl *wlhdr);
205 wlhdr_data_valid_88xx(struct halmac_adapter *adapter,
206 struct wlhdr_frame_ctrl *wlhdr);
209 dump_reg_88xx(struct halmac_adapter *adapter);
212 * ofld_func_cfg_88xx() - config offload function
213 * @adapter : the adapter of halmac
214 * @info : offload function information
216 * Return : enum halmac_ret_status
217 * More details of status code can be found in prototype document
219 enum halmac_ret_status
220 ofld_func_cfg_88xx(struct halmac_adapter *adapter,
221 struct halmac_ofld_func_info *info)
223 if (adapter->intf == HALMAC_INTERFACE_SDIO &&
224 info->rsvd_pg_drv_buf_max_sz > SDIO_TX_MAX_SIZE_88XX)
225 return HALMAC_RET_FAIL;
227 adapter->pltfm_info.malloc_size = info->halmac_malloc_max_sz;
228 adapter->pltfm_info.rsvd_pg_size = info->rsvd_pg_drv_buf_max_sz;
230 return HALMAC_RET_SUCCESS;
234 * dl_drv_rsvd_page_88xx() - download packet to rsvd page
235 * @adapter : the adapter of halmac
236 * @pg_offset : page offset of driver's rsvd page
237 * @halmac_buf : data to be downloaded, tx_desc is not included
238 * @halmac_size : data size to be downloaded
239 * Author : KaiYuan Chang
240 * Return : enum halmac_ret_status
241 * More details of status code can be found in prototype document
243 enum halmac_ret_status
244 dl_drv_rsvd_page_88xx(struct halmac_adapter *adapter, u8 pg_offset, u8 *buf,
247 enum halmac_ret_status status;
252 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
254 pg_size = adapter->hw_cfg_info.page_size;
255 pg_num = size / pg_size + ((size & (pg_size - 1)) ? 1 : 0);
256 if (pg_offset + pg_num > adapter->txff_alloc.rsvd_drv_pg_num) {
257 PLTFM_MSG_ERR("[ERR] pkt overflow!!\n");
258 return HALMAC_RET_DRV_DL_ERR;
261 pg_addr = adapter->txff_alloc.rsvd_drv_addr + pg_offset;
263 status = dl_rsvd_page_88xx(adapter, pg_addr, buf, size);
265 if (status != HALMAC_RET_SUCCESS) {
266 PLTFM_MSG_ERR("[ERR]dl rsvd page fail!!\n");
270 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
272 return HALMAC_RET_SUCCESS;
275 enum halmac_ret_status
276 dl_rsvd_page_88xx(struct halmac_adapter *adapter, u16 pg_addr, u8 *buf,
283 enum halmac_rsvd_pg_state *state = &adapter->halmac_state.rsvd_pg_state;
284 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
285 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
288 PLTFM_MSG_TRACE("[TRACE]pkt size = 0\n");
289 return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
292 if (*state == HALMAC_RSVD_PG_STATE_BUSY)
293 return HALMAC_RET_BUSY_STATE;
295 *state = HALMAC_RSVD_PG_STATE_BUSY;
297 pg_addr &= BIT_MASK_BCN_HEAD_1_V1;
298 HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, (u16)(pg_addr | BIT(15)));
300 value8 = HALMAC_REG_R8(REG_CR + 1);
302 value8 = (u8)(value8 | BIT(0));
303 HALMAC_REG_W8(REG_CR + 1, value8);
305 value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
307 value8 = (u8)(value8 & ~(BIT(6)));
308 HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
310 if (PLTFM_SEND_RSVD_PAGE(buf, size) == 0) {
311 PLTFM_MSG_ERR("[ERR]send rvsd pg(pltfm)!!\n");
312 status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
317 while (!(HALMAC_REG_R8(REG_FIFOPAGE_CTRL_2 + 1) & BIT(7))) {
321 PLTFM_MSG_ERR("[ERR]bcn valid!!\n");
322 status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
327 rsvd_pg_head = adapter->txff_alloc.rsvd_boundary;
328 HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, rsvd_pg_head | BIT(15));
329 HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[1]);
330 HALMAC_REG_W8(REG_CR + 1, restore[0]);
332 *state = HALMAC_RSVD_PG_STATE_IDLE;
337 enum halmac_ret_status
338 get_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
341 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
344 case HALMAC_HW_RQPN_MAPPING:
345 get_pq_mapping_88xx(adapter, (struct halmac_rqpn_map *)value);
347 case HALMAC_HW_EFUSE_SIZE:
348 *(u32 *)value = adapter->hw_cfg_info.efuse_size;
350 case HALMAC_HW_EEPROM_SIZE:
351 *(u32 *)value = adapter->hw_cfg_info.eeprom_size;
353 case HALMAC_HW_BT_BANK_EFUSE_SIZE:
354 *(u32 *)value = adapter->hw_cfg_info.bt_efuse_size;
356 case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
357 case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
360 case HALMAC_HW_TXFIFO_SIZE:
361 *(u32 *)value = adapter->hw_cfg_info.tx_fifo_size;
363 case HALMAC_HW_RXFIFO_SIZE:
364 *(u32 *)value = adapter->hw_cfg_info.rx_fifo_size;
366 case HALMAC_HW_RSVD_PG_BNDY:
367 *(u16 *)value = adapter->txff_alloc.rsvd_drv_addr;
369 case HALMAC_HW_CAM_ENTRY_NUM:
370 *(u8 *)value = adapter->hw_cfg_info.cam_entry_num;
372 case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE:
373 get_efuse_available_size_88xx(adapter, (u32 *)value);
375 case HALMAC_HW_IC_VERSION:
376 *(u8 *)value = adapter->chip_ver;
378 case HALMAC_HW_PAGE_SIZE:
379 *(u32 *)value = adapter->hw_cfg_info.page_size;
381 case HALMAC_HW_TX_AGG_ALIGN_SIZE:
382 *(u16 *)value = adapter->hw_cfg_info.tx_align_size;
384 case HALMAC_HW_RX_AGG_ALIGN_SIZE:
387 case HALMAC_HW_DRV_INFO_SIZE:
388 *(u8 *)value = adapter->drv_info_size;
390 case HALMAC_HW_TXFF_ALLOCATION:
391 PLTFM_MEMCPY(value, &adapter->txff_alloc,
392 sizeof(struct halmac_txff_allocation));
394 case HALMAC_HW_RSVD_EFUSE_SIZE:
395 *(u32 *)value = get_rsvd_efuse_size_88xx(adapter);
397 case HALMAC_HW_FW_HDR_SIZE:
398 *(u32 *)value = WLAN_FW_HDR_SIZE;
400 case HALMAC_HW_TX_DESC_SIZE:
401 *(u32 *)value = adapter->hw_cfg_info.txdesc_size;
403 case HALMAC_HW_RX_DESC_SIZE:
404 *(u32 *)value = adapter->hw_cfg_info.rxdesc_size;
406 case HALMAC_HW_ORI_H2C_SIZE:
407 *(u32 *)value = ORIGINAL_H2C_CMD_SIZE;
409 case HALMAC_HW_RSVD_DRV_PGNUM:
410 *(u16 *)value = adapter->txff_alloc.rsvd_drv_pg_num;
412 case HALMAC_HW_TX_PAGE_SIZE:
413 *(u16 *)value = TX_PAGE_SIZE_88XX;
415 case HALMAC_HW_USB_TXAGG_DESC_NUM:
416 *(u8 *)value = adapter->hw_cfg_info.usb_txagg_num;
418 case HALMAC_HW_AC_OQT_SIZE:
419 *(u8 *)value = adapter->hw_cfg_info.ac_oqt_size;
421 case HALMAC_HW_NON_AC_OQT_SIZE:
422 *(u8 *)value = adapter->hw_cfg_info.non_ac_oqt_size;
424 case HALMAC_HW_AC_QUEUE_NUM:
425 *(u8 *)value = adapter->hw_cfg_info.acq_num;
427 case HALMAC_HW_PWR_STATE:
428 pwr_state_88xx(adapter, (enum halmac_mac_power *)value);
431 return HALMAC_RET_PARA_NOT_SUPPORT;
434 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
436 return HALMAC_RET_SUCCESS;
440 get_pq_mapping_88xx(struct halmac_adapter *adapter,
441 struct halmac_rqpn_map *mapping)
443 mapping->dma_map_vo = adapter->pq_map[HALMAC_PQ_MAP_VO];
444 mapping->dma_map_vi = adapter->pq_map[HALMAC_PQ_MAP_VI];
445 mapping->dma_map_be = adapter->pq_map[HALMAC_PQ_MAP_BE];
446 mapping->dma_map_bk = adapter->pq_map[HALMAC_PQ_MAP_BK];
447 mapping->dma_map_mg = adapter->pq_map[HALMAC_PQ_MAP_MG];
448 mapping->dma_map_hi = adapter->pq_map[HALMAC_PQ_MAP_HI];
452 * set_hw_value_88xx() -set hw config value
453 * @adapter : the adapter of halmac
454 * @hw_id : hw id for driver to config
455 * @value : hw value, reference table to get data type
456 * Author : KaiYuan Chang / Ivan Lin
457 * Return : enum halmac_ret_status
458 * More details of status code can be found in prototype document
460 enum halmac_ret_status
461 set_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
464 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
465 struct halmac_tx_page_threshold_info *th_info = NULL;
466 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
468 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
471 PLTFM_MSG_ERR("[ERR]null ptr-set hw value\n");
472 return HALMAC_RET_NULL_POINTER;
476 #if HALMAC_USB_SUPPORT
477 case HALMAC_HW_USB_MODE:
478 status = set_usb_mode_88xx(adapter,
479 *(enum halmac_usb_mode *)value);
480 if (status != HALMAC_RET_SUCCESS)
484 case HALMAC_HW_BANDWIDTH:
485 cfg_bw_88xx(adapter, *(enum halmac_bw *)value);
487 case HALMAC_HW_CHANNEL:
488 cfg_ch_88xx(adapter, *(u8 *)value);
490 case HALMAC_HW_PRI_CHANNEL_IDX:
491 cfg_pri_ch_idx_88xx(adapter, *(enum halmac_pri_ch_idx *)value);
493 case HALMAC_HW_EN_BB_RF:
494 enable_bb_rf_88xx(adapter, *(u8 *)value);
496 #if HALMAC_SDIO_SUPPORT
497 case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
498 if (adapter->intf == HALMAC_INTERFACE_SDIO) {
499 th_info = (struct halmac_tx_page_threshold_info *)value;
500 cfg_sdio_tx_page_threshold_88xx(adapter, th_info);
502 return HALMAC_RET_FAIL;
506 case HALMAC_HW_RX_SHIFT:
507 rx_shift_88xx(adapter, *(u8 *)value);
509 case HALMAC_HW_TXDESC_CHECKSUM:
510 tx_desc_chksum_88xx(adapter, *(u8 *)value);
512 case HALMAC_HW_RX_CLK_GATE:
513 rx_clk_gate_88xx(adapter, *(u8 *)value);
515 case HALMAC_HW_FAST_EDCA:
516 fast_edca_cfg_88xx(adapter,
517 (struct halmac_fast_edca_cfg *)value);
519 case HALMAC_HW_RTS_FULL_BW:
520 rts_full_bw_88xx(adapter, *(u8 *)value);
522 case HALMAC_HW_FREE_CNT_EN:
523 HALMAC_REG_W8_SET(REG_MISC_CTRL, BIT_EN_FREECNT);
526 return HALMAC_RET_PARA_NOT_SUPPORT;
529 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
531 return HALMAC_RET_SUCCESS;
534 enum halmac_ret_status
535 set_h2c_pkt_hdr_88xx(struct halmac_adapter *adapter, u8 *hdr,
536 struct halmac_h2c_header_info *info, u16 *seq_num)
540 PLTFM_MSG_TRACE("[TRACE]%s!!\n", __func__);
542 total_size = H2C_PKT_HDR_SIZE_88XX + info->content_size;
543 FW_OFFLOAD_H2C_SET_TOTAL_LEN(hdr, total_size);
544 FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hdr, info->sub_cmd_id);
546 FW_OFFLOAD_H2C_SET_CATEGORY(hdr, 0x01);
547 FW_OFFLOAD_H2C_SET_CMD_ID(hdr, 0xFF);
549 PLTFM_MUTEX_LOCK(&adapter->h2c_seq_mutex);
550 FW_OFFLOAD_H2C_SET_SEQ_NUM(hdr, adapter->h2c_info.seq_num);
551 *seq_num = adapter->h2c_info.seq_num;
552 (adapter->h2c_info.seq_num)++;
553 PLTFM_MUTEX_UNLOCK(&adapter->h2c_seq_mutex);
556 FW_OFFLOAD_H2C_SET_ACK(hdr, 1);
558 return HALMAC_RET_SUCCESS;
561 enum halmac_ret_status
562 send_h2c_pkt_88xx(struct halmac_adapter *adapter, u8 *pkt)
565 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
567 while (adapter->h2c_info.buf_fs <= H2C_PKT_SIZE_88XX) {
568 get_h2c_buf_free_space_88xx(adapter);
571 PLTFM_MSG_ERR("[ERR]h2c free space!!\n");
572 return HALMAC_RET_H2C_SPACE_FULL;
578 if (PLTFM_SEND_H2C_PKT(pkt, H2C_PKT_SIZE_88XX) == 1)
582 PLTFM_MSG_ERR("[ERR]pltfm - sned h2c pkt!!\n");
583 return HALMAC_RET_SEND_H2C_FAIL;
589 adapter->h2c_info.buf_fs -= H2C_PKT_SIZE_88XX;
594 enum halmac_ret_status
595 get_h2c_buf_free_space_88xx(struct halmac_adapter *adapter)
599 struct halmac_h2c_info *info = &adapter->h2c_info;
600 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
602 hw_wptr = HALMAC_REG_R32(REG_H2C_PKT_WRITEADDR) & 0x3FFFF;
603 fw_rptr = HALMAC_REG_R32(REG_H2C_PKT_READADDR) & 0x3FFFF;
605 if (hw_wptr >= fw_rptr)
606 info->buf_fs = info->buf_size - (hw_wptr - fw_rptr);
608 info->buf_fs = fw_rptr - hw_wptr;
610 return HALMAC_RET_SUCCESS;
614 * get_c2h_info_88xx() - process halmac C2H packet
615 * @adapter : the adapter of halmac
616 * @buf : RX Packet pointer
617 * @size : RX Packet size
619 * Note : Don't use any IO or DELAY in this API
621 * Author : KaiYuan Chang/Ivan Lin
623 * Used to process c2h packet info from RX path. After receiving the packet,
624 * user need to call this api and pass the packet pointer.
626 * Return : enum halmac_ret_status
627 * More details of status code can be found in prototype document
629 enum halmac_ret_status
630 get_c2h_info_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
632 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
634 if (GET_RX_DESC_C2H(buf) == 1) {
635 PLTFM_MSG_TRACE("[TRACE]Parse c2h pkt\n");
637 status = parse_c2h_pkt_88xx(adapter, buf, size);
638 if (status != HALMAC_RET_SUCCESS) {
639 PLTFM_MSG_ERR("[ERR]Parse c2h pkt\n");
644 return HALMAC_RET_SUCCESS;
647 static enum halmac_ret_status
648 parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
652 u8 *c2h_pkt = buf + adapter->hw_cfg_info.rxdesc_size;
653 u32 c2h_size = size - adapter->hw_cfg_info.rxdesc_size;
654 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
656 cmd_id = (u8)C2H_HDR_GET_CMD_ID(c2h_pkt);
658 if (cmd_id != 0xFF) {
659 PLTFM_MSG_TRACE("[TRACE]Not 0xFF cmd!!\n");
660 return HALMAC_RET_C2H_NOT_HANDLED;
663 sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_pkt);
665 switch (sub_cmd_id) {
666 case C2H_SUB_CMD_ID_C2H_DBG:
667 status = get_c2h_dbg_88xx(adapter, c2h_pkt, c2h_size);
669 case C2H_SUB_CMD_ID_H2C_ACK_HDR:
670 status = get_h2c_ack_88xx(adapter, c2h_pkt, c2h_size);
672 case C2H_SUB_CMD_ID_BT_COEX_INFO:
673 status = HALMAC_RET_C2H_NOT_HANDLED;
675 case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
676 status = get_scan_rpt_88xx(adapter, c2h_pkt, c2h_size);
678 case C2H_SUB_CMD_ID_PSD_DATA:
679 status = get_psd_data_88xx(adapter, c2h_pkt, c2h_size);
681 case C2H_SUB_CMD_ID_EFUSE_DATA:
682 status = get_efuse_data_88xx(adapter, c2h_pkt, c2h_size);
685 PLTFM_MSG_WARN("[WARN]Sub cmd id!!\n");
686 status = HALMAC_RET_C2H_NOT_HANDLED;
693 static enum halmac_ret_status
694 get_c2h_dbg_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
700 char *c2h_buf = (char *)NULL;
704 content_len = (u8)C2H_HDR_GET_LEN((u8 *)buf);
706 if (content_len > C2H_DBG_CONTENT_MAX_LENGTH) {
707 PLTFM_MSG_ERR("[ERR]c2h size > max len!\n");
708 return HALMAC_RET_C2H_NOT_HANDLED;
711 for (i = 0; i < content_len; i++) {
712 if (*(buf + C2H_DBG_HDR_LEN + i) == '\n') {
713 if ((*(buf + C2H_DBG_HDR_LEN + i + 1) == '\0') ||
714 (*(buf + C2H_DBG_HDR_LEN + i + 1) == 0xff)) {
715 next_msg = C2H_DBG_HDR_LEN + i + 1;
722 msg_len = next_msg - C2H_DBG_HDR_LEN;
724 c2h_buf = (char *)PLTFM_MALLOC(msg_len);
726 return HALMAC_RET_MALLOC_FAIL;
728 PLTFM_MEMCPY(c2h_buf, buf + C2H_DBG_HDR_LEN, msg_len);
730 seq_num = (u8)(*(c2h_buf));
731 *(c2h_buf + msg_len - 1) = '\0';
732 PLTFM_MSG_ALWAYS("[RTKFW, SEQ=%d]: %s\n",
733 seq_num, (char *)(c2h_buf + 1));
734 PLTFM_FREE(c2h_buf, msg_len);
736 while (*(buf + next_msg) != '\0') {
739 msg_len = (u8)(*(buf + cur_msg + 3)) - 1;
740 next_msg += C2H_DBG_HDR_LEN + msg_len;
742 c2h_buf = (char *)PLTFM_MALLOC(msg_len);
744 return HALMAC_RET_MALLOC_FAIL;
746 PLTFM_MEMCPY(c2h_buf, buf + cur_msg + C2H_DBG_HDR_LEN, msg_len);
747 *(c2h_buf + msg_len - 1) = '\0';
748 seq_num = (u8)(*(c2h_buf));
749 PLTFM_MSG_ALWAYS("[RTKFW, SEQ=%d]: %s\n",
750 seq_num, (char *)(c2h_buf + 1));
751 PLTFM_FREE(c2h_buf, msg_len);
754 return HALMAC_RET_SUCCESS;
757 static enum halmac_ret_status
758 get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
763 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
765 PLTFM_MSG_TRACE("[TRACE]Ack for C2H!!\n");
767 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
768 if (HALMAC_H2C_RETURN_SUCCESS != (enum halmac_h2c_return_code)fw_rc)
769 PLTFM_MSG_TRACE("[TRACE]fw rc = %d\n", fw_rc);
771 cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(buf);
773 if (cmd_id != 0xFF) {
774 PLTFM_MSG_ERR("[ERR]h2c ack cmd id!!\n");
775 return HALMAC_RET_C2H_NOT_HANDLED;
778 sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(buf);
780 switch (sub_cmd_id) {
781 case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
782 status = get_h2c_ack_phy_efuse_88xx(adapter, buf, size);
784 case H2C_SUB_CMD_ID_CFG_PARAM_ACK:
785 status = get_h2c_ack_cfg_param_88xx(adapter, buf, size);
787 case H2C_SUB_CMD_ID_UPDATE_PKT_ACK:
788 status = get_h2c_ack_update_pkt_88xx(adapter, buf, size);
790 case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
791 status = get_h2c_ack_update_datapkt_88xx(adapter, buf, size);
793 case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
794 status = get_h2c_ack_run_datapkt_88xx(adapter, buf, size);
796 case H2C_SUB_CMD_ID_CH_SWITCH_ACK:
797 status = get_h2c_ack_ch_switch_88xx(adapter, buf, size);
799 case H2C_SUB_CMD_ID_IQK_ACK:
800 status = get_h2c_ack_iqk_88xx(adapter, buf, size);
802 case H2C_SUB_CMD_ID_PWR_TRK_ACK:
803 status = get_h2c_ack_pwr_trk_88xx(adapter, buf, size);
805 case H2C_SUB_CMD_ID_PSD_ACK:
807 case H2C_SUB_CMD_ID_FW_SNDING_ACK:
808 status = get_h2c_ack_fw_snding_88xx(adapter, buf, size);
811 status = HALMAC_RET_C2H_NOT_HANDLED;
818 static enum halmac_ret_status
819 get_scan_rpt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
822 enum halmac_cmd_process_status proc_status;
824 fw_rc = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(buf);
825 proc_status = (HALMAC_H2C_RETURN_SUCCESS ==
826 (enum halmac_h2c_return_code)fw_rc) ?
827 HALMAC_CMD_PROCESS_DONE : HALMAC_CMD_PROCESS_ERROR;
829 PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status, NULL, 0);
831 adapter->halmac_state.scan_state.proc_status = proc_status;
833 PLTFM_MSG_TRACE("[TRACE]scan : %X\n", proc_status);
835 return HALMAC_RET_SUCCESS;
838 static enum halmac_ret_status
839 get_h2c_ack_cfg_param_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
845 struct halmac_cfg_param_state *state =
846 &adapter->halmac_state.cfg_param_state;
847 enum halmac_cmd_process_status proc_status =
848 HALMAC_CMD_PROCESS_UNDEFINE;
850 seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
851 PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
852 state->seq_num, seq_num);
853 if (seq_num != state->seq_num) {
854 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
855 state->seq_num, seq_num);
856 return HALMAC_RET_SUCCESS;
859 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
860 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
861 return HALMAC_RET_SUCCESS;
864 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
865 state->fw_rc = fw_rc;
866 offset_accum = CFG_PARAM_ACK_GET_OFFSET_ACCUMULATION(buf);
867 value_accum = CFG_PARAM_ACK_GET_VALUE_ACCUMULATION(buf);
869 if (offset_accum != adapter->cfg_param_info.offset_accum ||
870 value_accum != adapter->cfg_param_info.value_accum) {
871 PLTFM_MSG_ERR("[ERR][C2H]offset_accu : %x, value_accu : %xn",
872 offset_accum, value_accum);
873 PLTFM_MSG_ERR("[ERR][Ada]offset_accu : %x, value_accu : %x\n",
874 adapter->cfg_param_info.offset_accum,
875 adapter->cfg_param_info.value_accum);
876 proc_status = HALMAC_CMD_PROCESS_ERROR;
879 if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS &&
880 proc_status != HALMAC_CMD_PROCESS_ERROR) {
881 proc_status = HALMAC_CMD_PROCESS_DONE;
882 state->proc_status = proc_status;
883 PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, proc_status, NULL, 0);
885 proc_status = HALMAC_CMD_PROCESS_ERROR;
886 state->proc_status = proc_status;
887 PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, proc_status,
891 return HALMAC_RET_SUCCESS;
894 static enum halmac_ret_status
895 get_h2c_ack_update_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
899 struct halmac_update_pkt_state *state =
900 &adapter->halmac_state.update_pkt_state;
901 enum halmac_cmd_process_status proc_status;
903 seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
904 PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
905 state->seq_num, seq_num);
906 if (seq_num != state->seq_num) {
907 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
908 state->seq_num, seq_num);
909 return HALMAC_RET_SUCCESS;
912 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
913 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
914 return HALMAC_RET_SUCCESS;
917 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
918 state->fw_rc = fw_rc;
920 if (HALMAC_H2C_RETURN_SUCCESS == (enum halmac_h2c_return_code)fw_rc) {
921 proc_status = HALMAC_CMD_PROCESS_DONE;
922 state->proc_status = proc_status;
923 PLTFM_EVENT_SIG(HALMAC_FEATURE_UPDATE_PACKET, proc_status,
926 proc_status = HALMAC_CMD_PROCESS_ERROR;
927 state->proc_status = proc_status;
928 PLTFM_EVENT_SIG(HALMAC_FEATURE_UPDATE_PACKET, proc_status,
932 return HALMAC_RET_SUCCESS;
935 static enum halmac_ret_status
936 get_h2c_ack_update_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf,
939 return HALMAC_RET_NOT_SUPPORT;
942 static enum halmac_ret_status
943 get_h2c_ack_run_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
945 return HALMAC_RET_NOT_SUPPORT;
948 static enum halmac_ret_status
949 get_h2c_ack_ch_switch_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
953 struct halmac_scan_state *state = &adapter->halmac_state.scan_state;
954 enum halmac_cmd_process_status proc_status;
956 seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
957 PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
958 state->seq_num, seq_num);
959 if (seq_num != state->seq_num) {
960 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
961 state->seq_num, seq_num);
962 return HALMAC_RET_SUCCESS;
965 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
966 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
967 return HALMAC_RET_SUCCESS;
970 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
971 state->fw_rc = fw_rc;
973 if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
974 proc_status = HALMAC_CMD_PROCESS_RCVD;
975 state->proc_status = proc_status;
976 PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status,
979 proc_status = HALMAC_CMD_PROCESS_ERROR;
980 state->proc_status = proc_status;
981 PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status,
985 return HALMAC_RET_SUCCESS;
989 * mac_debug_88xx_v1() - read some registers for debug
991 * Author : KaiYuan Chang/Ivan Lin
992 * Return : enum halmac_ret_status
994 enum halmac_ret_status
995 mac_debug_88xx(struct halmac_adapter *adapter)
997 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
999 if (adapter->intf == HALMAC_INTERFACE_SDIO)
1000 dump_reg_sdio_88xx(adapter);
1002 dump_reg_88xx(adapter);
1004 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1006 return HALMAC_RET_SUCCESS;
1010 dump_reg_sdio_88xx(struct halmac_adapter *adapter)
1015 /* Dump CCCR, it needs new platform api */
1017 /*Dump SDIO Local Register, use CMD52*/
1018 for (i = 0x10250000; i < 0x102500ff; i++) {
1019 tmp8 = PLTFM_SDIO_CMD52_R(i);
1020 PLTFM_MSG_TRACE("[TRACE]dbg-sdio[%x]=%x\n", i, tmp8);
1023 /*Dump MAC Register*/
1024 for (i = 0x0000; i < 0x17ff; i++) {
1025 tmp8 = PLTFM_SDIO_CMD52_R(i);
1026 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1029 tmp8 = PLTFM_SDIO_CMD52_R(REG_SDIO_CRC_ERR_IDX);
1031 PLTFM_MSG_ERR("[ERR]sdio crc=%x\n", tmp8);
1033 /*Check RX Fifo status*/
1034 i = REG_RXFF_PTR_V1;
1035 tmp8 = PLTFM_SDIO_CMD52_R(i);
1036 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1037 i = REG_RXFF_WTR_V1;
1038 tmp8 = PLTFM_SDIO_CMD52_R(i);
1039 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1040 i = REG_RXFF_PTR_V1;
1041 tmp8 = PLTFM_SDIO_CMD52_R(i);
1042 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1043 i = REG_RXFF_WTR_V1;
1044 tmp8 = PLTFM_SDIO_CMD52_R(i);
1045 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1049 dump_reg_88xx(struct halmac_adapter *adapter)
1053 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1055 /*Dump MAC Register*/
1056 for (i = 0x0000; i < 0x17fc; i += 4) {
1057 tmp32 = HALMAC_REG_R32(i);
1058 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1061 /*Check RX Fifo status*/
1062 i = REG_RXFF_PTR_V1;
1063 tmp32 = HALMAC_REG_R32(i);
1064 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1065 i = REG_RXFF_WTR_V1;
1066 tmp32 = HALMAC_REG_R32(i);
1067 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1068 i = REG_RXFF_PTR_V1;
1069 tmp32 = HALMAC_REG_R32(i);
1070 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1071 i = REG_RXFF_WTR_V1;
1072 tmp32 = HALMAC_REG_R32(i);
1073 PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1077 * cfg_parameter_88xx() - config parameter by FW
1078 * @adapter : the adapter of halmac
1079 * @info : cmd id, content
1080 * @full_fifo : parameter information
1082 * If msk_en = 1, the format of array is {reg_info, mask, value}.
1083 * If msk_en =_FAUSE, the format of array is {reg_info, value}
1084 * The format of reg_info is
1085 * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
1086 * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
1087 * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
1088 * ref_info[15:0]=offset
1090 * Example: msk_en = 0
1091 * {0x8100000a, 0x00001122}
1092 * =>Set RF register, path_B, offset 0xA to 0x00001122
1093 * {0x00000824, 0x11224433}
1094 * =>Set MAC_BB register, offset 0x800 to 0x11224433
1096 * Note : full fifo mode only for init flow
1098 * Author : KaiYuan Chang/Ivan Lin
1099 * Return : enum halmac_ret_status
1100 * More details of status code can be found in prototype document
1102 enum halmac_ret_status
1103 cfg_parameter_88xx(struct halmac_adapter *adapter,
1104 struct halmac_phy_parameter_info *info, u8 full_fifo)
1106 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1107 enum halmac_cmd_process_status *proc_status;
1108 enum halmac_cmd_construct_state cmd_state;
1110 proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
1112 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1113 return HALMAC_RET_NO_DLFW;
1115 if (adapter->fw_ver.h2c_version < 4)
1116 return HALMAC_RET_FW_NO_SUPPORT;
1118 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
1119 PLTFM_MSG_TRACE("[TRACE]Wait event(para)\n");
1120 return HALMAC_RET_BUSY_STATE;
1123 cmd_state = cfg_param_cmd_cnstr_state_88xx(adapter);
1124 if (cmd_state != HALMAC_CMD_CNSTR_IDLE &&
1125 cmd_state != HALMAC_CMD_CNSTR_CNSTR) {
1126 PLTFM_MSG_TRACE("[TRACE]Not idle(para)\n");
1127 return HALMAC_RET_BUSY_STATE;
1130 *proc_status = HALMAC_CMD_PROCESS_IDLE;
1132 status = proc_cfg_param_88xx(adapter, info, full_fifo);
1134 if (status != HALMAC_RET_SUCCESS && status != HALMAC_RET_PARA_SENDING) {
1135 PLTFM_MSG_ERR("[ERR]send param h2c\n");
1142 static enum halmac_cmd_construct_state
1143 cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
1145 return adapter->halmac_state.cfg_param_state.cmd_cnstr_state;
1148 static enum halmac_ret_status
1149 proc_cfg_param_88xx(struct halmac_adapter *adapter,
1150 struct halmac_phy_parameter_info *param, u8 full_fifo)
1154 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1155 struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1156 enum halmac_cmd_process_status *proc_status;
1158 proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
1160 status = malloc_cfg_param_buf_88xx(adapter, full_fifo);
1161 if (status != HALMAC_RET_SUCCESS)
1164 if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
1165 HALMAC_RET_SUCCESS) {
1166 PLTFM_FREE(info->buf, info->buf_size);
1168 info->buf_wptr = NULL;
1169 return HALMAC_RET_ERROR_STATE;
1172 add_param_buf_88xx(adapter, param, info->buf_wptr, &end_cmd);
1173 if (param->cmd_id != HALMAC_PARAMETER_CMD_END) {
1175 info->buf_wptr += CFG_PARAM_H2C_INFO_SIZE;
1176 info->avl_buf_size -= CFG_PARAM_H2C_INFO_SIZE;
1179 rsvd_size = info->avl_buf_size - adapter->hw_cfg_info.txdesc_size;
1180 if (rsvd_size > CFG_PARAM_H2C_INFO_SIZE && end_cmd == 0)
1181 return HALMAC_RET_SUCCESS;
1183 if (info->num == 0) {
1184 PLTFM_FREE(info->buf, info->buf_size);
1186 info->buf_wptr = NULL;
1187 PLTFM_MSG_TRACE("[TRACE]param num = 0!!\n");
1189 *proc_status = HALMAC_CMD_PROCESS_DONE;
1190 PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, *proc_status, NULL, 0);
1192 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CFG_PARA);
1194 return HALMAC_RET_SUCCESS;
1197 status = send_cfg_param_h2c_88xx(adapter);
1198 if (status != HALMAC_RET_SUCCESS) {
1200 PLTFM_FREE(info->buf, info->buf_size);
1202 info->buf_wptr = NULL;
1208 PLTFM_MSG_TRACE("[TRACE]send h2c-buf full\n");
1209 return HALMAC_RET_PARA_SENDING;
1215 static enum halmac_ret_status
1216 send_cfg_param_h2c_88xx(struct halmac_adapter *adapter)
1218 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1222 struct halmac_h2c_header_info hdr_info;
1223 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1224 struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1225 enum halmac_cmd_process_status *proc_status;
1227 proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
1229 if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
1231 return HALMAC_RET_ERROR_STATE;
1233 *proc_status = HALMAC_CMD_PROCESS_SENDING;
1235 if (info->full_fifo_mode == 1)
1238 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1240 info_size = info->num * CFG_PARAM_H2C_INFO_SIZE;
1242 status = dl_rsvd_page_88xx(adapter, pg_addr, info->buf, info_size);
1243 if (status != HALMAC_RET_SUCCESS) {
1244 PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
1245 goto CFG_PARAM_H2C_FAIL;
1248 gen_cfg_param_h2c_88xx(adapter, h2c_buf);
1250 hdr_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAM;
1251 hdr_info.content_size = 4;
1253 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1255 adapter->halmac_state.cfg_param_state.seq_num = seq_num;
1257 status = send_h2c_pkt_88xx(adapter, h2c_buf);
1259 if (status != HALMAC_RET_SUCCESS) {
1260 PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1261 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CFG_PARA);
1265 PLTFM_FREE(info->buf, info->buf_size);
1267 info->buf_wptr = NULL;
1269 if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
1271 return HALMAC_RET_ERROR_STATE;
1276 static enum halmac_ret_status
1277 cnv_cfg_param_state_88xx(struct halmac_adapter *adapter,
1278 enum halmac_cmd_construct_state dest_state)
1280 enum halmac_cmd_construct_state *state;
1282 state = &adapter->halmac_state.cfg_param_state.cmd_cnstr_state;
1284 if ((*state != HALMAC_CMD_CNSTR_IDLE) &&
1285 (*state != HALMAC_CMD_CNSTR_CNSTR) &&
1286 (*state != HALMAC_CMD_CNSTR_H2C_SENT))
1287 return HALMAC_RET_ERROR_STATE;
1289 if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
1290 if (*state == HALMAC_CMD_CNSTR_CNSTR)
1291 return HALMAC_RET_ERROR_STATE;
1292 } else if (dest_state == HALMAC_CMD_CNSTR_CNSTR) {
1293 if (*state == HALMAC_CMD_CNSTR_H2C_SENT)
1294 return HALMAC_RET_ERROR_STATE;
1295 } else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
1296 if ((*state == HALMAC_CMD_CNSTR_IDLE) ||
1297 (*state == HALMAC_CMD_CNSTR_H2C_SENT))
1298 return HALMAC_RET_ERROR_STATE;
1301 *state = dest_state;
1303 return HALMAC_RET_SUCCESS;
1306 static enum halmac_ret_status
1307 add_param_buf_88xx(struct halmac_adapter *adapter,
1308 struct halmac_phy_parameter_info *param, u8 *buf,
1311 struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1312 union halmac_parameter_content *content = ¶m->content;
1316 PARAM_INFO_SET_LEN(buf, CFG_PARAM_H2C_INFO_SIZE);
1317 PARAM_INFO_SET_IO_CMD(buf, param->cmd_id);
1319 switch (param->cmd_id) {
1320 case HALMAC_PARAMETER_CMD_BB_W8:
1321 case HALMAC_PARAMETER_CMD_BB_W16:
1322 case HALMAC_PARAMETER_CMD_BB_W32:
1323 case HALMAC_PARAMETER_CMD_MAC_W8:
1324 case HALMAC_PARAMETER_CMD_MAC_W16:
1325 case HALMAC_PARAMETER_CMD_MAC_W32:
1326 PARAM_INFO_SET_IO_ADDR(buf, content->MAC_REG_W.offset);
1327 PARAM_INFO_SET_DATA(buf, content->MAC_REG_W.value);
1328 PARAM_INFO_SET_MASK(buf, content->MAC_REG_W.msk);
1329 PARAM_INFO_SET_MSK_EN(buf, content->MAC_REG_W.msk_en);
1330 info->value_accum += content->MAC_REG_W.value;
1331 info->offset_accum += content->MAC_REG_W.offset;
1333 case HALMAC_PARAMETER_CMD_RF_W:
1334 /*In rf register, the address is only 1 byte*/
1335 PARAM_INFO_SET_RF_ADDR(buf, content->RF_REG_W.offset);
1336 PARAM_INFO_SET_RF_PATH(buf, content->RF_REG_W.rf_path);
1337 PARAM_INFO_SET_DATA(buf, content->RF_REG_W.value);
1338 PARAM_INFO_SET_MASK(buf, content->RF_REG_W.msk);
1339 PARAM_INFO_SET_MSK_EN(buf, content->RF_REG_W.msk_en);
1340 info->value_accum += content->RF_REG_W.value;
1341 info->offset_accum += (content->RF_REG_W.offset +
1342 (content->RF_REG_W.rf_path << 8));
1344 case HALMAC_PARAMETER_CMD_DELAY_US:
1345 case HALMAC_PARAMETER_CMD_DELAY_MS:
1346 PARAM_INFO_SET_DELAY_VAL(buf, content->DELAY_TIME.delay_time);
1348 case HALMAC_PARAMETER_CMD_END:
1352 PLTFM_MSG_ERR("[ERR]cmd id!!\n");
1356 return HALMAC_RET_SUCCESS;
1359 static enum halmac_ret_status
1360 gen_cfg_param_h2c_88xx(struct halmac_adapter *adapter, u8 *buff)
1362 struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1363 u16 h2c_info_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1364 u16 rsvd_pg_addr = adapter->txff_alloc.rsvd_boundary;
1366 CFG_PARAM_SET_NUM(buff, info->num);
1368 if (info->full_fifo_mode == 1) {
1369 CFG_PARAM_SET_INIT_CASE(buff, 0x1);
1370 CFG_PARAM_SET_LOC(buff, 0);
1372 CFG_PARAM_SET_INIT_CASE(buff, 0x0);
1373 CFG_PARAM_SET_LOC(buff, h2c_info_addr - rsvd_pg_addr);
1376 return HALMAC_RET_SUCCESS;
1379 static enum halmac_ret_status
1380 malloc_cfg_param_buf_88xx(struct halmac_adapter *adapter, u8 full_fifo)
1382 struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1383 struct halmac_pltfm_cfg_info *pltfm_info = &adapter->pltfm_info;
1386 return HALMAC_RET_SUCCESS;
1389 info->buf_size = pltfm_info->malloc_size;
1391 info->buf_size = CFG_PARAM_RSVDPG_SIZE;
1393 if (info->buf_size > pltfm_info->rsvd_pg_size)
1394 info->buf_size = pltfm_info->rsvd_pg_size;
1396 info->buf = smart_malloc_88xx(adapter, info->buf_size, &info->buf_size);
1398 PLTFM_MEMSET(info->buf, 0x00, info->buf_size);
1399 info->full_fifo_mode = full_fifo;
1400 info->buf_wptr = info->buf;
1402 info->avl_buf_size = info->buf_size;
1403 info->value_accum = 0;
1404 info->offset_accum = 0;
1406 return HALMAC_RET_MALLOC_FAIL;
1409 return HALMAC_RET_SUCCESS;
1413 * update_packet_88xx() - send specific packet to FW
1414 * @adapter : the adapter of halmac
1415 * @pkt_id : packet id, to know the purpose of this packet
1417 * @size : packet size
1419 * Note : TX_DESC is not included in the pkt
1421 * Author : KaiYuan Chang/Ivan Lin
1422 * Return : enum halmac_ret_status
1423 * More details of status code can be found in prototype document
1425 enum halmac_ret_status
1426 update_packet_88xx(struct halmac_adapter *adapter, enum halmac_packet_id pkt_id,
1429 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1430 enum halmac_cmd_process_status *proc_status =
1431 &adapter->halmac_state.update_pkt_state.proc_status;
1433 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1434 return HALMAC_RET_NO_DLFW;
1436 if (adapter->fw_ver.h2c_version < 4)
1437 return HALMAC_RET_FW_NO_SUPPORT;
1439 if (size > UPDATE_PKT_RSVDPG_SIZE)
1440 return HALMAC_RET_RSVD_PG_OVERFLOW_FAIL;
1442 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1444 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
1445 PLTFM_MSG_TRACE("[TRACE]Wait event(upd)\n");
1446 return HALMAC_RET_BUSY_STATE;
1449 *proc_status = HALMAC_CMD_PROCESS_SENDING;
1451 status = send_h2c_update_packet_88xx(adapter, pkt_id, pkt, size);
1452 if (status != HALMAC_RET_SUCCESS) {
1453 PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1454 PLTFM_MSG_ERR("[ERR]pkt id : %X!!\n", pkt_id);
1458 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1460 return HALMAC_RET_SUCCESS;
1463 static enum halmac_ret_status
1464 send_h2c_update_packet_88xx(struct halmac_adapter *adapter,
1465 enum halmac_packet_id pkt_id, u8 *pkt, u32 size)
1467 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1469 u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1471 struct halmac_h2c_header_info hdr_info;
1472 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1474 status = dl_rsvd_page_88xx(adapter, pg_addr, pkt, size);
1475 if (status != HALMAC_RET_SUCCESS) {
1476 PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
1480 pg_offset = pg_addr - adapter->txff_alloc.rsvd_boundary;
1481 UPDATE_PKT_SET_SIZE(h2c_buf, size + adapter->hw_cfg_info.txdesc_size);
1482 UPDATE_PKT_SET_ID(h2c_buf, pkt_id);
1483 UPDATE_PKT_SET_LOC(h2c_buf, pg_offset);
1485 hdr_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PKT;
1486 hdr_info.content_size = 8;
1488 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1489 adapter->halmac_state.update_pkt_state.seq_num = seq_num;
1491 status = send_h2c_pkt_88xx(adapter, h2c_buf);
1493 if (status != HALMAC_RET_SUCCESS) {
1494 PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1495 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_UPDATE_PACKET);
1502 enum halmac_ret_status
1503 bcn_ie_filter_88xx(struct halmac_adapter *adapter,
1504 struct halmac_bcn_ie_info *info)
1506 return HALMAC_RET_NOT_SUPPORT;
1509 enum halmac_ret_status
1510 update_datapack_88xx(struct halmac_adapter *adapter,
1511 enum halmac_data_type data_type,
1512 struct halmac_phy_parameter_info *info)
1514 return HALMAC_RET_NOT_SUPPORT;
1517 enum halmac_ret_status
1518 run_datapack_88xx(struct halmac_adapter *adapter,
1519 enum halmac_data_type data_type)
1521 return HALMAC_RET_NOT_SUPPORT;
1524 enum halmac_ret_status
1525 send_bt_coex_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size, u8 ack)
1527 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1529 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1530 return HALMAC_RET_NO_DLFW;
1532 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1534 status = send_bt_coex_cmd_88xx(adapter, buf, size, ack);
1536 if (status != HALMAC_RET_SUCCESS) {
1537 PLTFM_MSG_ERR("[ERR]bt coex cmd!!\n");
1541 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1543 return HALMAC_RET_SUCCESS;
1546 static enum halmac_ret_status
1547 send_bt_coex_cmd_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
1550 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1552 struct halmac_h2c_header_info hdr_info;
1553 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1555 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1557 PLTFM_MEMCPY(h2c_buf + 8, buf, size);
1559 hdr_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
1560 hdr_info.content_size = (u16)size;
1562 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1564 status = send_h2c_pkt_88xx(adapter, h2c_buf);
1566 if (status != HALMAC_RET_SUCCESS) {
1567 PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1571 return HALMAC_RET_SUCCESS;
1575 * dump_fifo_88xx() - dump fifo data
1576 * @adapter : the adapter of halmac
1577 * @sel : FIFO selection
1578 * @start_addr : start address of selected FIFO
1579 * @size : dump size of selected FIFO
1582 * Note : before dump fifo, user need to call halmac_get_fifo_size to
1583 * get fifo size. Then input this size to halmac_dump_fifo.
1585 * Author : Ivan Lin/KaiYuan Chang
1586 * Return : enum halmac_ret_status
1587 * More details of status code can be found in prototype document
1589 enum halmac_ret_status
1590 dump_fifo_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel,
1591 u32 start_addr, u32 size, u8 *data)
1593 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1596 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1598 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1600 if (sel == HAL_FIFO_SEL_TX &&
1601 (start_addr + size) > adapter->hw_cfg_info.tx_fifo_size) {
1602 PLTFM_MSG_ERR("[ERR]size overflow!!\n");
1603 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
1606 if (sel == HAL_FIFO_SEL_RX &&
1607 (start_addr + size) > adapter->hw_cfg_info.rx_fifo_size) {
1608 PLTFM_MSG_ERR("[ERR]size overflow!!\n");
1609 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
1612 if ((size & (4 - 1)) != 0) {
1613 PLTFM_MSG_ERR("[ERR]not 4byte alignment!!\n");
1614 return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
1618 return HALMAC_RET_NULL_POINTER;
1620 tmp8 = HALMAC_REG_R8(REG_RCR + 2);
1622 status = api->halmac_set_hw_value(adapter, HALMAC_HW_RX_CLK_GATE,
1624 if (status != HALMAC_RET_SUCCESS)
1626 status = read_buf_88xx(adapter, start_addr, size, sel, data);
1628 HALMAC_REG_W8(REG_RCR + 2, tmp8);
1630 if (status != HALMAC_RET_SUCCESS) {
1631 PLTFM_MSG_ERR("[ERR]read buf!!\n");
1635 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1637 return HALMAC_RET_SUCCESS;
1640 static enum halmac_ret_status
1641 read_buf_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
1642 enum hal_fifo_sel sel, u8 *data)
1649 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1651 if (sel == HAL_FIFO_SEL_RSVD_PAGE)
1652 offset += (adapter->txff_alloc.rsvd_boundary <<
1653 TX_PAGE_SIZE_SHIFT_88XX);
1655 start_pg = offset >> 12;
1656 residue = offset & (4096 - 1);
1658 if (sel == HAL_FIFO_SEL_TX || sel == HAL_FIFO_SEL_RSVD_PAGE)
1660 else if (sel == HAL_FIFO_SEL_RX)
1662 else if (sel == HAL_FIFO_SEL_REPORT)
1664 else if (sel == HAL_FIFO_SEL_LLT)
1666 else if (sel == HAL_FIFO_SEL_RXBUF_FW)
1669 return HALMAC_RET_NOT_SUPPORT;
1671 value32 = HALMAC_REG_R16(REG_PKTBUF_DBG_CTRL) & 0xF000;
1674 HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)(start_pg | value32));
1676 for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
1677 *(u32 *)(data + cnt) = HALMAC_REG_R32(i);
1678 *(u32 *)(data + cnt) =
1679 rtk_le32_to_cpu(*(u32 *)(data + cnt));
1682 goto HALMAC_BUF_READ_OK;
1690 HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)value32);
1692 return HALMAC_RET_SUCCESS;
1696 * get_fifo_size_88xx() - get fifo size
1697 * @adapter : the adapter of halmac
1698 * @sel : FIFO selection
1699 * Author : Ivan Lin/KaiYuan Chang
1701 * More details of status code can be found in prototype document
1704 get_fifo_size_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel)
1708 if (sel == HAL_FIFO_SEL_TX)
1709 size = adapter->hw_cfg_info.tx_fifo_size;
1710 else if (sel == HAL_FIFO_SEL_RX)
1711 size = adapter->hw_cfg_info.rx_fifo_size;
1712 else if (sel == HAL_FIFO_SEL_RSVD_PAGE)
1713 size = adapter->hw_cfg_info.tx_fifo_size -
1714 (adapter->txff_alloc.rsvd_boundary <<
1715 TX_PAGE_SIZE_SHIFT_88XX);
1716 else if (sel == HAL_FIFO_SEL_REPORT)
1718 else if (sel == HAL_FIFO_SEL_LLT)
1720 else if (sel == HAL_FIFO_SEL_RXBUF_FW)
1721 size = RX_BUF_FW_88XX;
1726 enum halmac_ret_status
1727 set_h2c_header_88xx(struct halmac_adapter *adapter, u8 *hdr, u16 *seq, u8 ack)
1729 PLTFM_MSG_TRACE("[TRACE]%s!!\n", __func__);
1731 H2C_CMD_HEADER_SET_CATEGORY(hdr, 0x00);
1732 H2C_CMD_HEADER_SET_TOTAL_LEN(hdr, 16);
1734 PLTFM_MUTEX_LOCK(&adapter->h2c_seq_mutex);
1735 H2C_CMD_HEADER_SET_SEQ_NUM(hdr, adapter->h2c_info.seq_num);
1736 *seq = adapter->h2c_info.seq_num;
1737 (adapter->h2c_info.seq_num)++;
1738 PLTFM_MUTEX_UNLOCK(&adapter->h2c_seq_mutex);
1741 H2C_CMD_HEADER_SET_ACK(hdr, 1);
1743 return HALMAC_RET_SUCCESS;
1747 * add_ch_info_88xx() -add channel information
1748 * @adapter : the adapter of halmac
1749 * @info : channel information
1750 * Author : KaiYuan Chang/Ivan Lin
1751 * Return : enum halmac_ret_status
1752 * More details of status code can be found in prototype document
1754 enum halmac_ret_status
1755 add_ch_info_88xx(struct halmac_adapter *adapter, struct halmac_ch_info *info)
1757 struct halmac_ch_sw_info *ch_sw_info = &adapter->ch_sw_info;
1758 enum halmac_cmd_construct_state state;
1760 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1762 if (adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
1763 PLTFM_MSG_ERR("[ERR]gen info\n");
1764 return HALMAC_RET_GEN_INFO_NOT_SENT;
1767 state = scan_cmd_cnstr_state_88xx(adapter);
1768 if (state != HALMAC_CMD_CNSTR_BUF_CLR &&
1769 state != HALMAC_CMD_CNSTR_CNSTR) {
1770 PLTFM_MSG_WARN("[WARN]cmd state (scan)\n");
1771 return HALMAC_RET_ERROR_STATE;
1774 if (!ch_sw_info->buf) {
1775 ch_sw_info->buf = (u8 *)PLTFM_MALLOC(SCAN_INFO_RSVDPG_SIZE);
1776 if (!ch_sw_info->buf)
1777 return HALMAC_RET_NULL_POINTER;
1778 ch_sw_info->buf_wptr = ch_sw_info->buf;
1779 ch_sw_info->buf_size = SCAN_INFO_RSVDPG_SIZE;
1780 ch_sw_info->avl_buf_size = SCAN_INFO_RSVDPG_SIZE;
1781 ch_sw_info->total_size = 0;
1782 ch_sw_info->extra_info_en = 0;
1783 ch_sw_info->ch_num = 0;
1786 if (ch_sw_info->extra_info_en == 1) {
1787 PLTFM_MSG_ERR("[ERR]extra info = 1!!\n");
1788 return HALMAC_RET_CH_SW_SEQ_WRONG;
1791 if (ch_sw_info->avl_buf_size < 4) {
1792 PLTFM_MSG_ERR("[ERR]buf full!!\n");
1793 return HALMAC_RET_CH_SW_NO_BUF;
1796 if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
1798 return HALMAC_RET_ERROR_STATE;
1800 CH_INFO_SET_CH(ch_sw_info->buf_wptr, info->channel);
1801 CH_INFO_SET_PRI_CH_IDX(ch_sw_info->buf_wptr, info->pri_ch_idx);
1802 CH_INFO_SET_BW(ch_sw_info->buf_wptr, info->bw);
1803 CH_INFO_SET_TIMEOUT(ch_sw_info->buf_wptr, info->timeout);
1804 CH_INFO_SET_ACTION_ID(ch_sw_info->buf_wptr, info->action_id);
1805 CH_INFO_SET_EXTRA_INFO(ch_sw_info->buf_wptr, info->extra_info);
1807 ch_sw_info->avl_buf_size = ch_sw_info->avl_buf_size - 4;
1808 ch_sw_info->total_size = ch_sw_info->total_size + 4;
1809 ch_sw_info->ch_num++;
1810 ch_sw_info->extra_info_en = info->extra_info;
1811 ch_sw_info->buf_wptr = ch_sw_info->buf_wptr + 4;
1813 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1815 return HALMAC_RET_SUCCESS;
1818 static enum halmac_cmd_construct_state
1819 scan_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
1821 return adapter->halmac_state.scan_state.cmd_cnstr_state;
1824 static enum halmac_ret_status
1825 cnv_scan_state_88xx(struct halmac_adapter *adapter,
1826 enum halmac_cmd_construct_state dest_state)
1828 enum halmac_cmd_construct_state *state;
1830 state = &adapter->halmac_state.scan_state.cmd_cnstr_state;
1832 if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
1833 if ((*state == HALMAC_CMD_CNSTR_BUF_CLR) ||
1834 (*state == HALMAC_CMD_CNSTR_CNSTR))
1835 return HALMAC_RET_ERROR_STATE;
1836 } else if (dest_state == HALMAC_CMD_CNSTR_BUF_CLR) {
1837 if (*state == HALMAC_CMD_CNSTR_H2C_SENT)
1838 return HALMAC_RET_ERROR_STATE;
1839 } else if (dest_state == HALMAC_CMD_CNSTR_CNSTR) {
1840 if ((*state == HALMAC_CMD_CNSTR_IDLE) ||
1841 (*state == HALMAC_CMD_CNSTR_H2C_SENT))
1842 return HALMAC_RET_ERROR_STATE;
1843 } else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
1844 if ((*state != HALMAC_CMD_CNSTR_CNSTR) &&
1845 (*state != HALMAC_CMD_CNSTR_BUF_CLR))
1846 return HALMAC_RET_ERROR_STATE;
1849 *state = dest_state;
1851 return HALMAC_RET_SUCCESS;
1855 * add_extra_ch_info_88xx() -add extra channel information
1856 * @adapter : the adapter of halmac
1857 * @info : extra channel information
1858 * Author : KaiYuan Chang/Ivan Lin
1859 * Return : enum halmac_ret_status
1860 * More details of status code can be found in prototype document
1862 enum halmac_ret_status
1863 add_extra_ch_info_88xx(struct halmac_adapter *adapter,
1864 struct halmac_ch_extra_info *info)
1866 struct halmac_ch_sw_info *ch_sw_info = &adapter->ch_sw_info;
1868 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1870 if (!ch_sw_info->buf) {
1871 PLTFM_MSG_ERR("[ERR]buf = null!!\n");
1872 return HALMAC_RET_CH_SW_SEQ_WRONG;
1875 if (ch_sw_info->extra_info_en == 0) {
1876 PLTFM_MSG_ERR("[ERR]extra info = 0!!\n");
1877 return HALMAC_RET_CH_SW_SEQ_WRONG;
1880 if (ch_sw_info->avl_buf_size < (u32)(info->extra_info_size + 2)) {
1881 PLTFM_MSG_ERR("[ERR]no available buffer!!\n");
1882 return HALMAC_RET_CH_SW_NO_BUF;
1885 if (scan_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_CNSTR) {
1886 PLTFM_MSG_WARN("[WARN]cmd state (ex scan)\n");
1887 return HALMAC_RET_ERROR_STATE;
1890 if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
1892 return HALMAC_RET_ERROR_STATE;
1894 CH_EXTRA_INFO_SET_ID(ch_sw_info->buf_wptr, info->extra_action_id);
1895 CH_EXTRA_INFO_SET_INFO(ch_sw_info->buf_wptr, info->extra_info);
1896 CH_EXTRA_INFO_SET_SIZE(ch_sw_info->buf_wptr, info->extra_info_size);
1897 PLTFM_MEMCPY(ch_sw_info->buf_wptr + 2, info->extra_info_data,
1898 info->extra_info_size);
1900 ch_sw_info->avl_buf_size -= (2 + info->extra_info_size);
1901 ch_sw_info->total_size += (2 + info->extra_info_size);
1902 ch_sw_info->extra_info_en = info->extra_info;
1903 ch_sw_info->buf_wptr += (2 + info->extra_info_size);
1905 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1907 return HALMAC_RET_SUCCESS;
1911 * ctrl_ch_switch_88xx() -send channel switch cmd
1912 * @adapter : the adapter of halmac
1913 * @opt : channel switch config
1914 * Author : KaiYuan Chang/Ivan Lin
1915 * Return : enum halmac_ret_status
1916 * More details of status code can be found in prototype document
1918 enum halmac_ret_status
1919 ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
1920 struct halmac_ch_switch_option *opt)
1922 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1923 enum halmac_cmd_construct_state state;
1924 enum halmac_cmd_process_status *proc_status;
1926 proc_status = &adapter->halmac_state.scan_state.proc_status;
1928 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1929 return HALMAC_RET_NO_DLFW;
1931 if (adapter->fw_ver.h2c_version < 4)
1932 return HALMAC_RET_FW_NO_SUPPORT;
1934 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1936 if (opt->switch_en == 0)
1937 *proc_status = HALMAC_CMD_PROCESS_IDLE;
1939 if ((*proc_status == HALMAC_CMD_PROCESS_SENDING) ||
1940 (*proc_status == HALMAC_CMD_PROCESS_RCVD)) {
1941 PLTFM_MSG_TRACE("[TRACE]Wait event(scan)\n");
1942 return HALMAC_RET_BUSY_STATE;
1945 state = scan_cmd_cnstr_state_88xx(adapter);
1946 if (opt->switch_en == 1) {
1947 if (state != HALMAC_CMD_CNSTR_CNSTR) {
1948 PLTFM_MSG_ERR("[ERR]state(en = 1)\n");
1949 return HALMAC_RET_ERROR_STATE;
1952 if (state != HALMAC_CMD_CNSTR_BUF_CLR) {
1953 PLTFM_MSG_ERR("[ERR]state(en = 0)\n");
1954 return HALMAC_RET_ERROR_STATE;
1958 status = proc_ctrl_ch_switch_88xx(adapter, opt);
1959 if (status != HALMAC_RET_SUCCESS) {
1960 PLTFM_MSG_ERR("[ERR]ctrl ch sw!!\n");
1964 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1966 return HALMAC_RET_SUCCESS;
1969 static enum halmac_ret_status
1970 proc_ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
1971 struct halmac_ch_switch_option *opt)
1973 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1975 u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1976 struct halmac_h2c_header_info hdr_info;
1977 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1978 enum halmac_cmd_process_status *proc_status;
1980 proc_status = &adapter->halmac_state.scan_state.proc_status;
1982 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1984 if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
1986 return HALMAC_RET_ERROR_STATE;
1988 *proc_status = HALMAC_CMD_PROCESS_SENDING;
1990 if (opt->switch_en != 0) {
1991 status = dl_rsvd_page_88xx(adapter, pg_addr,
1992 adapter->ch_sw_info.buf,
1993 adapter->ch_sw_info.total_size);
1994 if (status != HALMAC_RET_SUCCESS) {
1995 PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
2000 CH_SWITCH_SET_START(h2c_buf, opt->switch_en);
2001 CH_SWITCH_SET_CH_NUM(h2c_buf, adapter->ch_sw_info.ch_num);
2002 CH_SWITCH_SET_INFO_LOC(h2c_buf,
2003 pg_addr - adapter->txff_alloc.rsvd_boundary);
2004 CH_SWITCH_SET_DEST_CH_EN(h2c_buf, opt->dest_ch_en);
2005 CH_SWITCH_SET_DEST_CH(h2c_buf, opt->dest_ch);
2006 CH_SWITCH_SET_PRI_CH_IDX(h2c_buf, opt->dest_pri_ch_idx);
2007 CH_SWITCH_SET_ABSOLUTE_TIME(h2c_buf, opt->absolute_time_en);
2008 CH_SWITCH_SET_TSF_LOW(h2c_buf, opt->tsf_low);
2009 CH_SWITCH_SET_PERIODIC_OPT(h2c_buf, opt->periodic_option);
2010 CH_SWITCH_SET_NORMAL_CYCLE(h2c_buf, opt->normal_cycle);
2011 CH_SWITCH_SET_NORMAL_PERIOD(h2c_buf, opt->normal_period);
2012 CH_SWITCH_SET_SLOW_PERIOD(h2c_buf, opt->phase_2_period);
2013 CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_buf, opt->normal_period_sel);
2014 CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_buf, opt->phase_2_period_sel);
2015 CH_SWITCH_SET_INFO_SIZE(h2c_buf, adapter->ch_sw_info.total_size);
2017 hdr_info.sub_cmd_id = SUB_CMD_ID_CH_SWITCH;
2018 hdr_info.content_size = 20;
2020 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
2021 adapter->halmac_state.scan_state.seq_num = seq_num;
2023 status = send_h2c_pkt_88xx(adapter, h2c_buf);
2025 if (status != HALMAC_RET_SUCCESS) {
2026 PLTFM_MSG_ERR("[ERR]send h2c!!\n");
2027 reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CHANNEL_SWITCH);
2029 PLTFM_FREE(adapter->ch_sw_info.buf, adapter->ch_sw_info.buf_size);
2030 adapter->ch_sw_info.buf = NULL;
2031 adapter->ch_sw_info.buf_wptr = NULL;
2032 adapter->ch_sw_info.extra_info_en = 0;
2033 adapter->ch_sw_info.buf_size = 0;
2034 adapter->ch_sw_info.avl_buf_size = 0;
2035 adapter->ch_sw_info.total_size = 0;
2036 adapter->ch_sw_info.ch_num = 0;
2038 if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
2040 return HALMAC_RET_ERROR_STATE;
2046 * clear_ch_info_88xx() -clear channel information
2047 * @adapter : the adapter of halmac
2048 * Author : KaiYuan Chang/Ivan Lin
2049 * Return : enum halmac_ret_status
2050 * More details of status code can be found in prototype document
2052 enum halmac_ret_status
2053 clear_ch_info_88xx(struct halmac_adapter *adapter)
2055 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2057 if (scan_cmd_cnstr_state_88xx(adapter) == HALMAC_CMD_CNSTR_H2C_SENT) {
2058 PLTFM_MSG_WARN("[WARN]state(clear)\n");
2059 return HALMAC_RET_ERROR_STATE;
2062 if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_BUF_CLR) !=
2064 return HALMAC_RET_ERROR_STATE;
2066 PLTFM_FREE(adapter->ch_sw_info.buf, adapter->ch_sw_info.buf_size);
2067 adapter->ch_sw_info.buf = NULL;
2068 adapter->ch_sw_info.buf_wptr = NULL;
2069 adapter->ch_sw_info.extra_info_en = 0;
2070 adapter->ch_sw_info.buf_size = 0;
2071 adapter->ch_sw_info.avl_buf_size = 0;
2072 adapter->ch_sw_info.total_size = 0;
2073 adapter->ch_sw_info.ch_num = 0;
2075 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2077 return HALMAC_RET_SUCCESS;
2081 * chk_txdesc_88xx() -check if the tx packet format is incorrect
2082 * @adapter : the adapter of halmac
2083 * @buf : tx Packet buffer, tx desc is included
2084 * @size : tx packet size
2085 * Author : KaiYuan Chang
2086 * Return : enum halmac_ret_status
2087 * More details of status code can be found in prototype document
2089 enum halmac_ret_status
2090 chk_txdesc_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
2093 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2094 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2096 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2098 if (GET_TX_DESC_BMC(buf) == 1 && GET_TX_DESC_AGG_EN(buf) == 1)
2099 PLTFM_MSG_ERR("[ERR]txdesc - agg + bmc\n");
2101 if (size < (GET_TX_DESC_TXPKTSIZE(buf) +
2102 adapter->hw_cfg_info.txdesc_size +
2103 (GET_TX_DESC_PKT_OFFSET(buf) << 3))) {
2104 PLTFM_MSG_ERR("[ERR]txdesc - total size\n");
2105 status = HALMAC_RET_TXDESC_SET_FAIL;
2108 if (wlhdr_valid_88xx(adapter, buf) != HALMAC_RET_SUCCESS) {
2109 PLTFM_MSG_ERR("[ERR]wlhdr\n");
2110 status = HALMAC_RET_WLHDR_FAIL;
2113 if (GET_TX_DESC_AMSDU_PAD_EN(buf) != 0) {
2114 PLTFM_MSG_ERR("[ERR]txdesc - amsdu_pad\n");
2115 status = HALMAC_RET_TXDESC_SET_FAIL;
2118 switch (BIT_GET_MAC_CLK_SEL(HALMAC_REG_R32(REG_AFE_CTRL1))) {
2133 PLTFM_MSG_ALWAYS("MAC clock : 0x%XM\n", mac_clk);
2134 PLTFM_MSG_ALWAYS("mac agg en : 0x%X\n", GET_TX_DESC_AGG_EN(buf));
2135 PLTFM_MSG_ALWAYS("mac agg num : 0x%X\n", GET_TX_DESC_MAX_AGG_NUM(buf));
2137 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2142 static enum halmac_ret_status
2143 wlhdr_valid_88xx(struct halmac_adapter *adapter, u8 *buf)
2145 u32 txdesc_size = adapter->hw_cfg_info.txdesc_size +
2146 GET_TX_DESC_PKT_OFFSET(buf);
2147 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2148 struct wlhdr_frame_ctrl *wlhdr;
2150 wlhdr = (struct wlhdr_frame_ctrl *)(buf + txdesc_size);
2152 if (wlhdr->protocol != WLHDR_PROT_VER) {
2153 PLTFM_MSG_ERR("[ERR]prot ver!!\n");
2154 return HALMAC_RET_WLHDR_FAIL;
2157 switch (wlhdr->type) {
2158 case WLHDR_TYPE_MGMT:
2159 if (wlhdr_mgmt_valid_88xx(adapter, wlhdr) != 1)
2160 status = HALMAC_RET_WLHDR_FAIL;
2162 case WLHDR_TYPE_CTRL:
2163 if (wlhdr_ctrl_valid_88xx(adapter, wlhdr) != 1)
2164 status = HALMAC_RET_WLHDR_FAIL;
2166 case WLHDR_TYPE_DATA:
2167 if (wlhdr_data_valid_88xx(adapter, wlhdr) != 1)
2168 status = HALMAC_RET_WLHDR_FAIL;
2171 PLTFM_MSG_ERR("[ERR]undefined type!!\n");
2172 status = HALMAC_RET_WLHDR_FAIL;
2180 wlhdr_mgmt_valid_88xx(struct halmac_adapter *adapter,
2181 struct wlhdr_frame_ctrl *wlhdr)
2185 switch (wlhdr->sub_type) {
2186 case WLHDR_SUB_TYPE_ASSOC_REQ:
2187 case WLHDR_SUB_TYPE_ASSOC_RSPNS:
2188 case WLHDR_SUB_TYPE_REASSOC_REQ:
2189 case WLHDR_SUB_TYPE_REASSOC_RSPNS:
2190 case WLHDR_SUB_TYPE_PROBE_REQ:
2191 case WLHDR_SUB_TYPE_PROBE_RSPNS:
2192 case WLHDR_SUB_TYPE_BCN:
2193 case WLHDR_SUB_TYPE_DISASSOC:
2194 case WLHDR_SUB_TYPE_AUTH:
2195 case WLHDR_SUB_TYPE_DEAUTH:
2196 case WLHDR_SUB_TYPE_ACTION:
2197 case WLHDR_SUB_TYPE_ACTION_NOACK:
2201 PLTFM_MSG_ERR("[ERR]mgmt invalid!!\n");
2210 wlhdr_ctrl_valid_88xx(struct halmac_adapter *adapter,
2211 struct wlhdr_frame_ctrl *wlhdr)
2215 switch (wlhdr->sub_type) {
2216 case WLHDR_SUB_TYPE_BF_RPT_POLL:
2217 case WLHDR_SUB_TYPE_NDPA:
2221 PLTFM_MSG_ERR("[ERR]ctrl invalid!!\n");
2230 wlhdr_data_valid_88xx(struct halmac_adapter *adapter,
2231 struct wlhdr_frame_ctrl *wlhdr)
2235 switch (wlhdr->sub_type) {
2236 case WLHDR_SUB_TYPE_DATA:
2237 case WLHDR_SUB_TYPE_NULL:
2238 case WLHDR_SUB_TYPE_QOS_DATA:
2239 case WLHDR_SUB_TYPE_QOS_NULL:
2243 PLTFM_MSG_ERR("[ERR]data invalid!!\n");
2252 * get_version_88xx() - get HALMAC version
2253 * @ver : return version of major, prototype and minor information
2254 * Author : KaiYuan Chang / Ivan Lin
2255 * Return : enum halmac_ret_status
2256 * More details of status code can be found in prototype document
2258 enum halmac_ret_status
2259 get_version_88xx(struct halmac_adapter *adapter, struct halmac_ver *ver)
2261 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2263 ver->major_ver = (u8)HALMAC_MAJOR_VER;
2264 ver->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
2265 ver->minor_ver = (u8)HALMAC_MINOR_VER;
2267 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2269 return HALMAC_RET_SUCCESS;
2272 enum halmac_ret_status
2273 p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info)
2275 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2277 if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
2278 return HALMAC_RET_NO_DLFW;
2280 if (adapter->fw_ver.h2c_version < 6)
2281 return HALMAC_RET_FW_NO_SUPPORT;
2283 status = proc_p2pps_88xx(adapter, info);
2284 if (status != HALMAC_RET_SUCCESS) {
2285 PLTFM_MSG_ERR("[ERR]p2pps!!\n");
2289 return HALMAC_RET_SUCCESS;
2292 static enum halmac_ret_status
2293 proc_p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info)
2295 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
2297 struct halmac_h2c_header_info hdr_info;
2298 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2300 P2PPS_SET_OFFLOAD_EN(h2c_buf, info->offload_en);
2301 P2PPS_SET_ROLE(h2c_buf, info->role);
2302 P2PPS_SET_CTWINDOW_EN(h2c_buf, info->ctwindow_en);
2303 P2PPS_SET_NOA_EN(h2c_buf, info->noa_en);
2304 P2PPS_SET_NOA_SEL(h2c_buf, info->noa_sel);
2305 P2PPS_SET_ALLSTASLEEP(h2c_buf, info->all_sta_sleep);
2306 P2PPS_SET_DISCOVERY(h2c_buf, info->discovery);
2307 P2PPS_SET_DISABLE_CLOSERF(h2c_buf, info->disable_close_rf);
2308 P2PPS_SET_P2P_PORT_ID(h2c_buf, info->p2p_port_id);
2309 P2PPS_SET_P2P_GROUP(h2c_buf, info->p2p_group);
2310 P2PPS_SET_P2P_MACID(h2c_buf, info->p2p_macid);
2312 P2PPS_SET_CTWINDOW_LENGTH(h2c_buf, info->ctwindow_length);
2314 P2PPS_SET_NOA_DURATION_PARA(h2c_buf, info->noa_duration_para);
2315 P2PPS_SET_NOA_INTERVAL_PARA(h2c_buf, info->noa_interval_para);
2316 P2PPS_SET_NOA_START_TIME_PARA(h2c_buf, info->noa_start_time_para);
2317 P2PPS_SET_NOA_COUNT_PARA(h2c_buf, info->noa_count_para);
2319 hdr_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
2320 hdr_info.content_size = 24;
2322 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
2324 status = send_h2c_pkt_88xx(adapter, h2c_buf);
2326 if (status != HALMAC_RET_SUCCESS)
2327 PLTFM_MSG_ERR("[ERR]send h2c!!\n");
2333 * query_status_88xx() -query the offload feature status
2334 * @adapter : the adapter of halmac
2335 * @feature_id : feature_id
2336 * @proc_status : feature_status
2337 * @data : data buffer
2341 * If user wants to know the data size, user can allocate zero
2342 * size buffer first. If this size less than the data size, halmac
2343 * will return HALMAC_RET_BUFFER_TOO_SMALL. User need to
2344 * re-allocate data buffer with correct data size.
2346 * Author : Ivan Lin/KaiYuan Chang
2347 * Return : enum halmac_ret_status
2348 * More details of status code can be found in prototype document
2350 enum halmac_ret_status
2351 query_status_88xx(struct halmac_adapter *adapter,
2352 enum halmac_feature_id feature_id,
2353 enum halmac_cmd_process_status *proc_status, u8 *data,
2356 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2359 return HALMAC_RET_NULL_POINTER;
2361 switch (feature_id) {
2362 case HALMAC_FEATURE_CFG_PARA:
2363 status = get_cfg_param_status_88xx(adapter, proc_status);
2365 case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
2366 status = get_dump_phy_efuse_status_88xx(adapter, proc_status,
2369 case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
2370 status = get_dump_log_efuse_status_88xx(adapter, proc_status,
2373 case HALMAC_FEATURE_CHANNEL_SWITCH:
2374 status = get_ch_switch_status_88xx(adapter, proc_status);
2376 case HALMAC_FEATURE_UPDATE_PACKET:
2377 status = get_update_packet_status_88xx(adapter, proc_status);
2379 case HALMAC_FEATURE_IQK:
2380 status = get_iqk_status_88xx(adapter, proc_status);
2382 case HALMAC_FEATURE_POWER_TRACKING:
2383 status = get_pwr_trk_status_88xx(adapter, proc_status);
2385 case HALMAC_FEATURE_PSD:
2386 status = get_psd_status_88xx(adapter, proc_status, data, size);
2388 case HALMAC_FEATURE_FW_SNDING:
2389 status = get_fw_snding_status_88xx(adapter, proc_status);
2392 return HALMAC_RET_INVALID_FEATURE_ID;
2398 static enum halmac_ret_status
2399 get_cfg_param_status_88xx(struct halmac_adapter *adapter,
2400 enum halmac_cmd_process_status *proc_status)
2402 *proc_status = adapter->halmac_state.cfg_param_state.proc_status;
2404 return HALMAC_RET_SUCCESS;
2407 static enum halmac_ret_status
2408 get_ch_switch_status_88xx(struct halmac_adapter *adapter,
2409 enum halmac_cmd_process_status *proc_status)
2411 *proc_status = adapter->halmac_state.scan_state.proc_status;
2413 return HALMAC_RET_SUCCESS;
2416 static enum halmac_ret_status
2417 get_update_packet_status_88xx(struct halmac_adapter *adapter,
2418 enum halmac_cmd_process_status *proc_status)
2420 *proc_status = adapter->halmac_state.update_pkt_state.proc_status;
2422 return HALMAC_RET_SUCCESS;
2426 * cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
2427 * @adapter : the adapter of halmac
2428 * @pg_num : page number
2429 * Author : KaiYuan Chang
2430 * Return : enum halmac_ret_status
2431 * More details of status code can be found in prototype document
2433 enum halmac_ret_status
2434 cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *adapter,
2435 enum halmac_drv_rsvd_pg_num pg_num)
2437 if (adapter->api_registry.cfg_drv_rsvd_pg_en == 0)
2438 return HALMAC_RET_NOT_SUPPORT;
2440 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2441 PLTFM_MSG_TRACE("[TRACE]pg_num = %d\n", pg_num);
2444 case HALMAC_RSVD_PG_NUM8:
2445 adapter->txff_alloc.rsvd_drv_pg_num = 8;
2447 case HALMAC_RSVD_PG_NUM16:
2448 adapter->txff_alloc.rsvd_drv_pg_num = 16;
2450 case HALMAC_RSVD_PG_NUM24:
2451 adapter->txff_alloc.rsvd_drv_pg_num = 24;
2453 case HALMAC_RSVD_PG_NUM32:
2454 adapter->txff_alloc.rsvd_drv_pg_num = 32;
2456 case HALMAC_RSVD_PG_NUM64:
2457 adapter->txff_alloc.rsvd_drv_pg_num = 64;
2459 case HALMAC_RSVD_PG_NUM128:
2460 adapter->txff_alloc.rsvd_drv_pg_num = 128;
2464 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2466 return HALMAC_RET_SUCCESS;
2470 * (debug API)h2c_lb_88xx() - send h2c loopback packet
2471 * @adapter : the adapter of halmac
2472 * Author : KaiYuan Chang/Ivan Lin
2473 * Return : enum halmac_ret_status
2474 * More details of status code can be found in prototype document
2476 enum halmac_ret_status
2477 h2c_lb_88xx(struct halmac_adapter *adapter)
2479 return HALMAC_RET_SUCCESS;
2482 enum halmac_ret_status
2483 pwr_seq_parser_88xx(struct halmac_adapter *adapter,
2484 struct halmac_wlan_pwr_cfg **cmd_seq)
2489 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2490 struct halmac_wlan_pwr_cfg *cmd;
2492 switch (adapter->chip_ver) {
2493 case HALMAC_CHIP_VER_A_CUT:
2494 cut = HALMAC_PWR_CUT_A_MSK;
2496 case HALMAC_CHIP_VER_B_CUT:
2497 cut = HALMAC_PWR_CUT_B_MSK;
2499 case HALMAC_CHIP_VER_C_CUT:
2500 cut = HALMAC_PWR_CUT_C_MSK;
2502 case HALMAC_CHIP_VER_D_CUT:
2503 cut = HALMAC_PWR_CUT_D_MSK;
2505 case HALMAC_CHIP_VER_E_CUT:
2506 cut = HALMAC_PWR_CUT_E_MSK;
2508 case HALMAC_CHIP_VER_F_CUT:
2509 cut = HALMAC_PWR_CUT_F_MSK;
2511 case HALMAC_CHIP_VER_TEST:
2512 cut = HALMAC_PWR_CUT_TESTCHIP_MSK;
2515 PLTFM_MSG_ERR("[ERR]cut version!!\n");
2516 return HALMAC_RET_SWITCH_CASE_ERROR;
2519 switch (adapter->intf) {
2520 case HALMAC_INTERFACE_PCIE:
2521 case HALMAC_INTERFACE_AXI:
2522 intf = HALMAC_PWR_INTF_PCI_MSK;
2524 case HALMAC_INTERFACE_USB:
2525 intf = HALMAC_PWR_INTF_USB_MSK;
2527 case HALMAC_INTERFACE_SDIO:
2528 intf = HALMAC_PWR_INTF_SDIO_MSK;
2531 PLTFM_MSG_ERR("[ERR]interface!!\n");
2532 return HALMAC_RET_SWITCH_CASE_ERROR;
2541 status = pwr_sub_seq_parser_88xx(adapter, cut, intf, cmd);
2542 if (status != HALMAC_RET_SUCCESS) {
2543 PLTFM_MSG_ERR("[ERR]pwr sub seq!!\n");
2553 static enum halmac_ret_status
2554 pwr_sub_seq_parser_88xx(struct halmac_adapter *adapter, u8 cut, u8 intf,
2555 struct halmac_wlan_pwr_cfg *cmd)
2559 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2562 if ((cmd->interface_msk & intf) && (cmd->cut_msk & cut)) {
2564 case HALMAC_PWR_CMD_WRITE:
2565 offset = cmd->offset;
2567 if (cmd->base == HALMAC_PWR_ADDR_SDIO)
2568 offset |= SDIO_LOCAL_OFFSET;
2570 value = HALMAC_REG_R8(offset);
2571 value = (u8)(value & (u8)(~(cmd->msk)));
2572 value = (u8)(value | (cmd->value & cmd->msk));
2574 HALMAC_REG_W8(offset, value);
2576 case HALMAC_PWR_CMD_POLLING:
2577 if (pwr_cmd_polling_88xx(adapter, cmd) !=
2579 return HALMAC_RET_PWRSEQ_POLLING_FAIL;
2581 case HALMAC_PWR_CMD_DELAY:
2582 if (cmd->value == HALMAC_PWR_DELAY_US)
2583 PLTFM_DELAY_US(cmd->offset);
2585 PLTFM_DELAY_US(1000 * cmd->offset);
2587 case HALMAC_PWR_CMD_READ:
2589 case HALMAC_PWR_CMD_END:
2590 return HALMAC_RET_SUCCESS;
2592 return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
2598 return HALMAC_RET_SUCCESS;
2601 static enum halmac_ret_status
2602 pwr_cmd_polling_88xx(struct halmac_adapter *adapter,
2603 struct halmac_wlan_pwr_cfg *cmd)
2611 enum halmac_interface intf;
2612 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2615 cnt = HALMAC_PWR_POLLING_CNT;
2617 intf = adapter->intf;
2619 if (cmd->base == HALMAC_PWR_ADDR_SDIO)
2620 offset = cmd->offset | SDIO_LOCAL_OFFSET;
2622 offset = cmd->offset;
2626 value = HALMAC_REG_R8(offset);
2627 value = (u8)(value & cmd->msk);
2629 if (value == (cmd->value & cmd->msk)) {
2633 if (intf == HALMAC_INTERFACE_PCIE && flg == 0) {
2634 /* PCIE + USB package */
2635 /* power bit polling timeout issue */
2637 PLTFM_MSG_WARN("[WARN]PCIE stats:%d\n",
2639 value = HALMAC_REG_R8(REG_SYS_PW_CTRL);
2641 HALMAC_REG_W8(REG_SYS_PW_CTRL, value);
2643 HALMAC_REG_W8(REG_SYS_PW_CTRL, value);
2645 cnt = HALMAC_PWR_POLLING_CNT;
2648 PLTFM_MSG_ERR("[ERR]polling to!!\n");
2649 PLTFM_MSG_ERR("[ERR]cmd offset:%X\n",
2651 PLTFM_MSG_ERR("[ERR]cmd value:%X\n",
2653 PLTFM_MSG_ERR("[ERR]cmd msk:%X\n",
2655 PLTFM_MSG_ERR("[ERR]offset = %X\n",
2657 PLTFM_MSG_ERR("[ERR]value = %X\n",
2659 return HALMAC_RET_PWRSEQ_POLLING_FAIL;
2665 } while (!poll_bit);
2667 return HALMAC_RET_SUCCESS;
2670 enum halmac_ret_status
2671 parse_intf_phy_88xx(struct halmac_adapter *adapter,
2672 struct halmac_intf_phy_para *param,
2673 enum halmac_intf_phy_platform pltfm,
2674 enum hal_intf_phy intf_phy)
2680 struct halmac_intf_phy_para *cur_param;
2681 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2682 u8 result = HALMAC_RET_SUCCESS;
2684 switch (adapter->chip_ver) {
2685 case HALMAC_CHIP_VER_A_CUT:
2686 cur_cut = (u16)HALMAC_INTF_PHY_CUT_A;
2688 case HALMAC_CHIP_VER_B_CUT:
2689 cur_cut = (u16)HALMAC_INTF_PHY_CUT_B;
2691 case HALMAC_CHIP_VER_C_CUT:
2692 cur_cut = (u16)HALMAC_INTF_PHY_CUT_C;
2694 case HALMAC_CHIP_VER_D_CUT:
2695 cur_cut = (u16)HALMAC_INTF_PHY_CUT_D;
2697 case HALMAC_CHIP_VER_E_CUT:
2698 cur_cut = (u16)HALMAC_INTF_PHY_CUT_E;
2700 case HALMAC_CHIP_VER_F_CUT:
2701 cur_cut = (u16)HALMAC_INTF_PHY_CUT_F;
2703 case HALMAC_CHIP_VER_TEST:
2704 cur_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
2707 return HALMAC_RET_FAIL;
2713 if ((cur_param->cut & cur_cut) &&
2714 (cur_param->plaform & (u16)pltfm)) {
2715 offset = cur_param->offset;
2716 value = cur_param->value;
2717 ip_sel = cur_param->ip_sel;
2719 if (offset == 0xFFFF)
2722 if (ip_sel == HALMAC_IP_SEL_MAC) {
2723 HALMAC_REG_W8((u32)offset, (u8)value);
2724 } else if (intf_phy == HAL_INTF_PHY_USB2 ||
2725 intf_phy == HAL_INTF_PHY_USB3) {
2726 #if HALMAC_USB_SUPPORT
2727 result = usbphy_write_88xx(adapter, (u8)offset,
2729 if (result != HALMAC_RET_SUCCESS)
2730 PLTFM_MSG_ERR("[ERR]usb phy!!\n");
2732 } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1 ||
2733 intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
2734 #if HALMAC_PCIE_SUPPORT
2735 if (ip_sel == HALMAC_IP_INTF_PHY)
2736 result = mdio_write_88xx(adapter,
2741 result = dbi_w8_88xx(adapter, offset,
2743 if (result != HALMAC_RET_SUCCESS)
2744 PLTFM_MSG_ERR("[ERR]mdio/dbi!!\n");
2747 PLTFM_MSG_ERR("[ERR]intf phy sel!!\n");
2753 return HALMAC_RET_SUCCESS;
2757 * txfifo_is_empty_88xx() -check if txfifo is empty
2758 * @adapter : the adapter of halmac
2759 * @chk_num : check number
2761 * Return : enum halmac_ret_status
2762 * More details of status code can be found in prototype document
2764 enum halmac_ret_status
2765 txfifo_is_empty_88xx(struct halmac_adapter *adapter, u32 chk_num)
2768 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2770 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2772 cnt = (chk_num <= 10) ? 10 : chk_num;
2774 if (HALMAC_REG_R8(REG_TXPKT_EMPTY) != 0xFF)
2775 return HALMAC_RET_TXFIFO_NO_EMPTY;
2777 if ((HALMAC_REG_R8(REG_TXPKT_EMPTY + 1) & 0x06) != 0x06)
2778 return HALMAC_RET_TXFIFO_NO_EMPTY;
2783 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2785 return HALMAC_RET_SUCCESS;
2790 * smart_malloc_88xx() - adapt malloc size
2791 * @adapter : the adapter of halmac
2792 * @size : expected malloc size
2793 * @pNew_size : real malloc size
2795 * Return : address pointer
2798 smart_malloc_88xx(struct halmac_adapter *adapter, u32 size, u32 *new_size)
2801 u8 *malloc_buf = NULL;
2803 for (retry_num = 0; retry_num < 5; retry_num++) {
2804 malloc_buf = (u8 *)PLTFM_MALLOC(size);
2817 PLTFM_MSG_ERR("[ERR]adptive malloc!!\n");
2824 * ltecoex_reg_read_88xx() - read ltecoex register
2825 * @adapter : the adapter of halmac
2829 * Return : enum halmac_ret_status
2831 enum halmac_ret_status
2832 ltecoex_reg_read_88xx(struct halmac_adapter *adapter, u16 offset, u32 *value)
2835 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2838 while ((HALMAC_REG_R8(LTECOEX_ACCESS_CTRL + 3) & BIT(5)) == 0) {
2840 PLTFM_MSG_ERR("[ERR]lte ready(R)\n");
2841 return HALMAC_RET_LTECOEX_READY_FAIL;
2847 HALMAC_REG_W32(LTECOEX_ACCESS_CTRL, 0x800F0000 | offset);
2848 *value = HALMAC_REG_R32(REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1);
2850 return HALMAC_RET_SUCCESS;
2855 * ltecoex_reg_write_88xx() - write ltecoex register
2856 * @adapter : the adapter of halmac
2860 * Return : enum halmac_ret_status
2862 enum halmac_ret_status
2863 ltecoex_reg_write_88xx(struct halmac_adapter *adapter, u16 offset, u32 value)
2866 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2869 while ((HALMAC_REG_R8(LTECOEX_ACCESS_CTRL + 3) & BIT(5)) == 0) {
2871 PLTFM_MSG_ERR("[ERR]lte ready(W)\n");
2872 return HALMAC_RET_LTECOEX_READY_FAIL;
2878 HALMAC_REG_W32(REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1, value);
2879 HALMAC_REG_W32(LTECOEX_ACCESS_CTRL, 0xC00F0000 | offset);
2881 return HALMAC_RET_SUCCESS;
2885 pwr_state_88xx(struct halmac_adapter *adapter, enum halmac_mac_power *state)
2887 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2889 if ((HALMAC_REG_R8(REG_SYS_FUNC_EN + 1) & BIT(3)) == 0)
2890 *state = HALMAC_MAC_POWER_OFF;
2892 *state = HALMAC_MAC_POWER_ON;
2895 #endif /* HALMAC_88XX_SUPPORT */