• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2016 - 2019 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 
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"
24 #endif
25 #if HALMAC_SDIO_SUPPORT
26 #include "halmac_sdio_88xx.h"
27 #endif
28 #if HALMAC_PCIE_SUPPORT
29 #include "halmac_pcie_88xx.h"
30 #endif
31 #include "halmac_mimo_88xx.h"
32 
33 #if HALMAC_88XX_SUPPORT
34 
35 #define CFG_PARAM_H2C_INFO_SIZE	12
36 #define ORIGINAL_H2C_CMD_SIZE	8
37 
38 #define WLHDR_PROT_VER	0
39 
40 #define WLHDR_TYPE_MGMT		0
41 #define WLHDR_TYPE_CTRL		1
42 #define WLHDR_TYPE_DATA		2
43 
44 /* mgmt frame */
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
57 
58 /* ctrl frame */
59 #define WLHDR_SUB_TYPE_BF_RPT_POLL	4
60 #define WLHDR_SUB_TYPE_NDPA		5
61 
62 /* data frame */
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
67 
68 #define LTECOEX_ACCESS_CTRL REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1
69 
70 struct wlhdr_frame_ctrl {
71 	u16 protocol:2;
72 	u16 type:2;
73 	u16 sub_type:4;
74 	u16 to_ds:1;
75 	u16 from_ds:1;
76 	u16 more_frag:1;
77 	u16 retry:1;
78 	u16 pwr_mgmt:1;
79 	u16 more_data:1;
80 	u16 protect_frame:1;
81 	u16 order:1;
82 };
83 
84 static enum halmac_ret_status
85 parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
86 
87 static enum halmac_ret_status
88 get_c2h_dbg_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
89 
90 static enum halmac_ret_status
91 get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
92 
93 static enum halmac_ret_status
94 get_scan_ch_notify_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
95 
96 static enum halmac_ret_status
97 get_scan_rpt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
98 
99 static enum halmac_ret_status
100 get_h2c_ack_cfg_param_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
101 
102 static enum halmac_ret_status
103 get_h2c_ack_update_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
104 
105 static enum halmac_ret_status
106 get_h2c_ack_send_scan_pkt_88xx(struct halmac_adapter *adapter, u8 *buf,
107 			       u32 size);
108 
109 static enum halmac_ret_status
110 get_h2c_ack_drop_scan_pkt_88xx(struct halmac_adapter *adapter, u8 *buf,
111 			       u32 size);
112 
113 static enum halmac_ret_status
114 get_h2c_ack_update_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf,
115 				u32 size);
116 
117 static enum halmac_ret_status
118 get_h2c_ack_run_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
119 
120 static enum halmac_ret_status
121 get_h2c_ack_ch_switch_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size);
122 
123 static enum halmac_ret_status
124 malloc_cfg_param_buf_88xx(struct halmac_adapter *adapter, u8 full_fifo);
125 
126 static enum halmac_cmd_construct_state
127 cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
128 
129 static enum halmac_ret_status
130 proc_cfg_param_88xx(struct halmac_adapter *adapter,
131 		    struct halmac_phy_parameter_info *param, u8 full_fifo);
132 
133 static enum halmac_ret_status
134 send_cfg_param_h2c_88xx(struct halmac_adapter *adapter);
135 
136 static enum halmac_ret_status
137 cnv_cfg_param_state_88xx(struct halmac_adapter *adapter,
138 			 enum halmac_cmd_construct_state dest_state);
139 
140 static enum halmac_ret_status
141 add_param_buf_88xx(struct halmac_adapter *adapter,
142 		   struct halmac_phy_parameter_info *param, u8 *buf,
143 		   u8 *end_cmd);
144 
145 static enum halmac_ret_status
146 gen_cfg_param_h2c_88xx(struct halmac_adapter *adapter, u8 *buff);
147 
148 static enum halmac_ret_status
149 send_h2c_update_packet_88xx(struct halmac_adapter *adapter,
150 			    enum halmac_packet_id pkt_id, u8 *pkt, u32 size);
151 
152 static enum halmac_ret_status
153 send_h2c_send_scan_packet_88xx(struct halmac_adapter *adapter,
154 			       u8 index, u8 *pkt, u32 size);
155 
156 static enum halmac_ret_status
157 send_h2c_drop_scan_packet_88xx(struct halmac_adapter *adapter,
158 			       struct halmac_drop_pkt_option *option);
159 
160 static enum halmac_ret_status
161 send_bt_coex_cmd_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
162 		      u8 ack);
163 
164 static enum halmac_ret_status
165 read_buf_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
166 	      enum hal_fifo_sel sel, u8 *data);
167 
168 static enum halmac_cmd_construct_state
169 scan_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
170 
171 static enum halmac_ret_status
172 cnv_scan_state_88xx(struct halmac_adapter *adapter,
173 		    enum halmac_cmd_construct_state dest_state);
174 
175 static enum halmac_ret_status
176 proc_ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
177 			 struct halmac_ch_switch_option *opt);
178 
179 static enum halmac_ret_status
180 proc_p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info);
181 
182 static enum halmac_ret_status
183 get_cfg_param_status_88xx(struct halmac_adapter *adapter,
184 			  enum halmac_cmd_process_status *proc_status);
185 
186 static enum halmac_ret_status
187 get_ch_switch_status_88xx(struct halmac_adapter *adapter,
188 			  enum halmac_cmd_process_status *proc_status);
189 
190 static enum halmac_ret_status
191 get_update_packet_status_88xx(struct halmac_adapter *adapter,
192 			      enum halmac_cmd_process_status *proc_status);
193 
194 static enum halmac_ret_status
195 get_send_scan_packet_status_88xx(struct halmac_adapter *adapter,
196 				 enum halmac_cmd_process_status *proc_status);
197 
198 static enum halmac_ret_status
199 get_drop_scan_packet_status_88xx(struct halmac_adapter *adapter,
200 				 enum halmac_cmd_process_status *proc_status);
201 
202 static enum halmac_ret_status
203 pwr_sub_seq_parser_88xx(struct halmac_adapter *adapter, u8 cut, u8 intf,
204 			struct halmac_wlan_pwr_cfg *cmd);
205 
206 static void
207 pwr_state_88xx(struct halmac_adapter *adapter, enum halmac_mac_power *state);
208 
209 static enum halmac_ret_status
210 pwr_cmd_polling_88xx(struct halmac_adapter *adapter,
211 		     struct halmac_wlan_pwr_cfg *cmd);
212 
213 static void
214 get_pq_mapping_88xx(struct halmac_adapter *adapter,
215 		    struct halmac_rqpn_map *mapping);
216 
217 static void
218 dump_reg_sdio_88xx(struct halmac_adapter *adapter);
219 
220 static enum halmac_ret_status
221 wlhdr_valid_88xx(struct halmac_adapter *adapter, u8 *buf);
222 
223 static u8
224 wlhdr_mgmt_valid_88xx(struct halmac_adapter *adapter,
225 		      struct wlhdr_frame_ctrl *wlhdr);
226 
227 static u8
228 wlhdr_ctrl_valid_88xx(struct halmac_adapter *adapter,
229 		      struct wlhdr_frame_ctrl *wlhdr);
230 
231 static u8
232 wlhdr_data_valid_88xx(struct halmac_adapter *adapter,
233 		      struct wlhdr_frame_ctrl *wlhdr);
234 
235 static void
236 dump_reg_88xx(struct halmac_adapter *adapter);
237 
238 static u8
239 packet_in_nlo_88xx(struct halmac_adapter *adapter,
240 		   enum halmac_packet_id pkt_id);
241 
242 static enum halmac_packet_id
243 get_real_pkt_id_88xx(struct halmac_adapter *adapter,
244 		     enum halmac_packet_id pkt_id);
245 
246 static u32
247 get_update_packet_page_size(struct halmac_adapter *adapter, u32 size);
248 
249 /**
250  * ofld_func_cfg_88xx() - config offload function
251  * @adapter : the adapter of halmac
252  * @info : offload function information
253  * Author : Ivan Lin
254  * Return : enum halmac_ret_status
255  * More details of status code can be found in prototype document
256  */
257 enum halmac_ret_status
ofld_func_cfg_88xx(struct halmac_adapter * adapter,struct halmac_ofld_func_info * info)258 ofld_func_cfg_88xx(struct halmac_adapter *adapter,
259 		   struct halmac_ofld_func_info *info)
260 {
261 	if (adapter->intf == HALMAC_INTERFACE_SDIO &&
262 	    info->rsvd_pg_drv_buf_max_sz > SDIO_TX_MAX_SIZE_88XX)
263 		return HALMAC_RET_FAIL;
264 
265 	adapter->pltfm_info.malloc_size = info->halmac_malloc_max_sz;
266 	adapter->pltfm_info.rsvd_pg_size = info->rsvd_pg_drv_buf_max_sz;
267 
268 	return HALMAC_RET_SUCCESS;
269 }
270 
271 /**
272  * dl_drv_rsvd_page_88xx() - download packet to rsvd page
273  * @adapter : the adapter of halmac
274  * @pg_offset : page offset of driver's rsvd page
275  * @halmac_buf : data to be downloaded, tx_desc is not included
276  * @halmac_size : data size to be downloaded
277  * Author : KaiYuan Chang
278  * Return : enum halmac_ret_status
279  * More details of status code can be found in prototype document
280  */
281 enum halmac_ret_status
dl_drv_rsvd_page_88xx(struct halmac_adapter * adapter,u8 pg_offset,u8 * buf,u32 size)282 dl_drv_rsvd_page_88xx(struct halmac_adapter *adapter, u8 pg_offset, u8 *buf,
283 		      u32 size)
284 {
285 	enum halmac_ret_status status;
286 	u32 pg_size;
287 	u32 pg_num = 0;
288 	u16 pg_addr = 0;
289 
290 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
291 
292 	pg_size = adapter->hw_cfg_info.page_size;
293 	pg_num = size / pg_size + ((size & (pg_size - 1)) ? 1 : 0);
294 	if (pg_offset + pg_num > adapter->txff_alloc.rsvd_drv_pg_num) {
295 		PLTFM_MSG_ERR("[ERR] pkt overflow!!\n");
296 		return HALMAC_RET_DRV_DL_ERR;
297 	}
298 
299 	pg_addr = adapter->txff_alloc.rsvd_drv_addr + pg_offset;
300 
301 	status = dl_rsvd_page_88xx(adapter, pg_addr, buf, size);
302 
303 	if (status != HALMAC_RET_SUCCESS) {
304 		PLTFM_MSG_ERR("[ERR]dl rsvd page fail!!\n");
305 		return status;
306 	}
307 
308 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
309 
310 	return HALMAC_RET_SUCCESS;
311 }
312 
313 enum halmac_ret_status
dl_rsvd_page_88xx(struct halmac_adapter * adapter,u16 pg_addr,u8 * buf,u32 size)314 dl_rsvd_page_88xx(struct halmac_adapter *adapter, u16 pg_addr, u8 *buf,
315 		  u32 size)
316 {
317 	u8 restore[2];
318 	u8 value8;
319 	u16 rsvd_pg_head;
320 	u32 cnt;
321 	enum halmac_rsvd_pg_state *state = &adapter->halmac_state.rsvd_pg_state;
322 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
323 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
324 
325 	if (size == 0) {
326 		PLTFM_MSG_TRACE("[TRACE]pkt size = 0\n");
327 		return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
328 	}
329 
330 	if (*state == HALMAC_RSVD_PG_STATE_BUSY)
331 		return HALMAC_RET_BUSY_STATE;
332 
333 	*state = HALMAC_RSVD_PG_STATE_BUSY;
334 
335 	pg_addr &= BIT_MASK_BCN_HEAD_1_V1;
336 	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, (u16)(pg_addr | BIT(15)));
337 
338 	value8 = HALMAC_REG_R8(REG_CR + 1);
339 	restore[0] = value8;
340 	value8 = (u8)(value8 | BIT(0));
341 	HALMAC_REG_W8(REG_CR + 1, value8);
342 
343 	value8 = HALMAC_REG_R8(REG_FWHW_TXQ_CTRL + 2);
344 	restore[1] = value8;
345 	value8 = (u8)(value8 & ~(BIT(6)));
346 	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, value8);
347 
348 	if (PLTFM_SEND_RSVD_PAGE(buf, size) == 0) {
349 		PLTFM_MSG_ERR("[ERR]send rvsd pg(pltfm)!!\n");
350 		status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
351 		goto DL_RSVD_PG_END;
352 	}
353 
354 	cnt = 1000;
355 	while (!(HALMAC_REG_R8(REG_FIFOPAGE_CTRL_2 + 1) & BIT(7))) {
356 		PLTFM_DELAY_US(10);
357 		cnt--;
358 		if (cnt == 0) {
359 			PLTFM_MSG_ERR("[ERR]bcn valid!!\n");
360 			status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
361 			break;
362 		}
363 	}
364 DL_RSVD_PG_END:
365 	rsvd_pg_head = adapter->txff_alloc.rsvd_boundary;
366 	HALMAC_REG_W16(REG_FIFOPAGE_CTRL_2, rsvd_pg_head | BIT(15));
367 	HALMAC_REG_W8(REG_FWHW_TXQ_CTRL + 2, restore[1]);
368 	HALMAC_REG_W8(REG_CR + 1, restore[0]);
369 
370 	*state = HALMAC_RSVD_PG_STATE_IDLE;
371 
372 	return status;
373 }
374 
375 enum halmac_ret_status
get_hw_value_88xx(struct halmac_adapter * adapter,enum halmac_hw_id hw_id,void * value)376 get_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
377 		  void *value)
378 {
379 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
380 
381 	switch (hw_id) {
382 	case HALMAC_HW_RQPN_MAPPING:
383 		get_pq_mapping_88xx(adapter, (struct halmac_rqpn_map *)value);
384 		break;
385 	case HALMAC_HW_EFUSE_SIZE:
386 		*(u32 *)value = adapter->hw_cfg_info.efuse_size;
387 		break;
388 	case HALMAC_HW_EEPROM_SIZE:
389 		*(u32 *)value = adapter->hw_cfg_info.eeprom_size;
390 		break;
391 	case HALMAC_HW_BT_BANK_EFUSE_SIZE:
392 		*(u32 *)value = adapter->hw_cfg_info.bt_efuse_size;
393 		break;
394 	case HALMAC_HW_BT_BANK1_EFUSE_SIZE:
395 	case HALMAC_HW_BT_BANK2_EFUSE_SIZE:
396 		*(u32 *)value = 0;
397 		break;
398 	case HALMAC_HW_TXFIFO_SIZE:
399 		*(u32 *)value = adapter->hw_cfg_info.tx_fifo_size;
400 		break;
401 	case HALMAC_HW_RXFIFO_SIZE:
402 		*(u32 *)value = adapter->hw_cfg_info.rx_fifo_size;
403 		break;
404 	case HALMAC_HW_RSVD_PG_BNDY:
405 		*(u16 *)value = adapter->txff_alloc.rsvd_drv_addr;
406 		break;
407 	case HALMAC_HW_CAM_ENTRY_NUM:
408 		*(u8 *)value = adapter->hw_cfg_info.cam_entry_num;
409 		break;
410 	case HALMAC_HW_WLAN_EFUSE_AVAILABLE_SIZE:
411 		get_efuse_available_size_88xx(adapter, (u32 *)value);
412 		break;
413 	case HALMAC_HW_IC_VERSION:
414 		*(u8 *)value = adapter->chip_ver;
415 		break;
416 	case HALMAC_HW_PAGE_SIZE:
417 		*(u32 *)value = adapter->hw_cfg_info.page_size;
418 		break;
419 	case HALMAC_HW_TX_AGG_ALIGN_SIZE:
420 		*(u16 *)value = adapter->hw_cfg_info.tx_align_size;
421 		break;
422 	case HALMAC_HW_RX_AGG_ALIGN_SIZE:
423 		*(u8 *)value = 8;
424 		break;
425 	case HALMAC_HW_DRV_INFO_SIZE:
426 		*(u8 *)value = adapter->drv_info_size;
427 		break;
428 	case HALMAC_HW_TXFF_ALLOCATION:
429 		PLTFM_MEMCPY(value, &adapter->txff_alloc,
430 			     sizeof(struct halmac_txff_allocation));
431 		break;
432 	case HALMAC_HW_RSVD_EFUSE_SIZE:
433 		*(u32 *)value = get_rsvd_efuse_size_88xx(adapter);
434 		break;
435 	case HALMAC_HW_FW_HDR_SIZE:
436 		*(u32 *)value = WLAN_FW_HDR_SIZE;
437 		break;
438 	case HALMAC_HW_TX_DESC_SIZE:
439 		*(u32 *)value = adapter->hw_cfg_info.txdesc_size;
440 		break;
441 	case HALMAC_HW_RX_DESC_SIZE:
442 		*(u32 *)value = adapter->hw_cfg_info.rxdesc_size;
443 		break;
444 	case HALMAC_HW_ORI_H2C_SIZE:
445 		*(u32 *)value = ORIGINAL_H2C_CMD_SIZE;
446 		break;
447 	case HALMAC_HW_RSVD_DRV_PGNUM:
448 		*(u16 *)value = adapter->txff_alloc.rsvd_drv_pg_num;
449 		break;
450 	case HALMAC_HW_TX_PAGE_SIZE:
451 		*(u16 *)value = TX_PAGE_SIZE_88XX;
452 		break;
453 	case HALMAC_HW_USB_TXAGG_DESC_NUM:
454 		*(u8 *)value = adapter->hw_cfg_info.usb_txagg_num;
455 		break;
456 	case HALMAC_HW_AC_OQT_SIZE:
457 		*(u8 *)value = adapter->hw_cfg_info.ac_oqt_size;
458 		break;
459 	case HALMAC_HW_NON_AC_OQT_SIZE:
460 		*(u8 *)value = adapter->hw_cfg_info.non_ac_oqt_size;
461 		break;
462 	case HALMAC_HW_AC_QUEUE_NUM:
463 		*(u8 *)value = adapter->hw_cfg_info.acq_num;
464 		break;
465 	case HALMAC_HW_PWR_STATE:
466 		pwr_state_88xx(adapter, (enum halmac_mac_power *)value);
467 		break;
468 	default:
469 		return HALMAC_RET_PARA_NOT_SUPPORT;
470 	}
471 
472 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
473 
474 	return HALMAC_RET_SUCCESS;
475 }
476 
477 static void
get_pq_mapping_88xx(struct halmac_adapter * adapter,struct halmac_rqpn_map * mapping)478 get_pq_mapping_88xx(struct halmac_adapter *adapter,
479 		    struct halmac_rqpn_map *mapping)
480 {
481 	mapping->dma_map_vo = adapter->pq_map[HALMAC_PQ_MAP_VO];
482 	mapping->dma_map_vi = adapter->pq_map[HALMAC_PQ_MAP_VI];
483 	mapping->dma_map_be = adapter->pq_map[HALMAC_PQ_MAP_BE];
484 	mapping->dma_map_bk = adapter->pq_map[HALMAC_PQ_MAP_BK];
485 	mapping->dma_map_mg = adapter->pq_map[HALMAC_PQ_MAP_MG];
486 	mapping->dma_map_hi = adapter->pq_map[HALMAC_PQ_MAP_HI];
487 }
488 
489 /**
490  * set_hw_value_88xx() -set hw config value
491  * @adapter : the adapter of halmac
492  * @hw_id : hw id for driver to config
493  * @value : hw value, reference table to get data type
494  * Author : KaiYuan Chang / Ivan Lin
495  * Return : enum halmac_ret_status
496  * More details of status code can be found in prototype document
497  */
498 enum halmac_ret_status
set_hw_value_88xx(struct halmac_adapter * adapter,enum halmac_hw_id hw_id,void * value)499 set_hw_value_88xx(struct halmac_adapter *adapter, enum halmac_hw_id hw_id,
500 		  void *value)
501 {
502 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
503 #if HALMAC_SDIO_SUPPORT
504 	struct halmac_tx_page_threshold_info *th_info;
505 #endif
506 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
507 
508 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
509 
510 	if (!value) {
511 		PLTFM_MSG_ERR("[ERR]null ptr-set hw value\n");
512 		return HALMAC_RET_NULL_POINTER;
513 	}
514 
515 	switch (hw_id) {
516 #if HALMAC_USB_SUPPORT
517 	case HALMAC_HW_USB_MODE:
518 		status = set_usb_mode_88xx(adapter,
519 					   *(enum halmac_usb_mode *)value);
520 		if (status != HALMAC_RET_SUCCESS)
521 			return status;
522 		break;
523 #endif
524 	case HALMAC_HW_BANDWIDTH:
525 		cfg_bw_88xx(adapter, *(enum halmac_bw *)value);
526 		break;
527 	case HALMAC_HW_CHANNEL:
528 		cfg_ch_88xx(adapter, *(u8 *)value);
529 		break;
530 	case HALMAC_HW_PRI_CHANNEL_IDX:
531 		cfg_pri_ch_idx_88xx(adapter, *(enum halmac_pri_ch_idx *)value);
532 		break;
533 	case HALMAC_HW_EN_BB_RF:
534 		status = enable_bb_rf_88xx(adapter, *(u8 *)value);
535 		if (status != HALMAC_RET_SUCCESS)
536 			return status;
537 		break;
538 #if HALMAC_SDIO_SUPPORT
539 	case HALMAC_HW_SDIO_TX_PAGE_THRESHOLD:
540 		if (adapter->intf == HALMAC_INTERFACE_SDIO) {
541 			th_info = (struct halmac_tx_page_threshold_info *)value;
542 			cfg_sdio_tx_page_threshold_88xx(adapter, th_info);
543 		} else {
544 			return HALMAC_RET_FAIL;
545 		}
546 		break;
547 #endif
548 	case HALMAC_HW_RX_SHIFT:
549 		rx_shift_88xx(adapter, *(u8 *)value);
550 		break;
551 	case HALMAC_HW_TXDESC_CHECKSUM:
552 		tx_desc_chksum_88xx(adapter, *(u8 *)value);
553 		break;
554 	case HALMAC_HW_RX_CLK_GATE:
555 		rx_clk_gate_88xx(adapter, *(u8 *)value);
556 		break;
557 	case HALMAC_HW_FAST_EDCA:
558 		fast_edca_cfg_88xx(adapter,
559 				   (struct halmac_fast_edca_cfg *)value);
560 		break;
561 	case HALMAC_HW_RTS_FULL_BW:
562 		rts_full_bw_88xx(adapter, *(u8 *)value);
563 		break;
564 	case HALMAC_HW_FREE_CNT_EN:
565 		HALMAC_REG_W8_SET(REG_MISC_CTRL, BIT_EN_FREECNT);
566 		break;
567 	case HALMAC_HW_TXFIFO_LIFETIME:
568 		cfg_txfifo_lt_88xx(adapter,
569 				   (struct halmac_txfifo_lifetime_cfg *)value);
570 		break;
571 	default:
572 		return HALMAC_RET_PARA_NOT_SUPPORT;
573 	}
574 
575 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
576 
577 	return HALMAC_RET_SUCCESS;
578 }
579 
580 /**
581  * get_watcher_88xx() -get watcher value
582  * @adapter : the adapter of halmac
583  * @sel : id for driver to config
584  * @value : value, reference table to get data type
585  * Author :
586  * Return : enum halmac_ret_status
587  * More details of status code can be found in prototype document
588  */
589 enum halmac_ret_status
get_watcher_88xx(struct halmac_adapter * adapter,enum halmac_watcher_sel sel,void * value)590 get_watcher_88xx(struct halmac_adapter *adapter, enum halmac_watcher_sel sel,
591 		 void *value)
592 {
593 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
594 
595 	if (!value) {
596 		PLTFM_MSG_ERR("[ERR]null ptr-set hw value\n");
597 		return HALMAC_RET_NULL_POINTER;
598 	}
599 
600 	switch (sel) {
601 	case HALMAC_WATCHER_SDIO_RN_FOOL_PROOFING:
602 		*(u32 *)value = adapter->watcher.get_watcher.sdio_rn_not_align;
603 		break;
604 	default:
605 		return HALMAC_RET_PARA_NOT_SUPPORT;
606 	}
607 
608 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
609 
610 	return HALMAC_RET_SUCCESS;
611 }
612 
613 enum halmac_ret_status
set_h2c_pkt_hdr_88xx(struct halmac_adapter * adapter,u8 * hdr,struct halmac_h2c_header_info * info,u16 * seq_num)614 set_h2c_pkt_hdr_88xx(struct halmac_adapter *adapter, u8 *hdr,
615 		     struct halmac_h2c_header_info *info, u16 *seq_num)
616 {
617 	u16 total_size;
618 
619 	PLTFM_MSG_TRACE("[TRACE]%s!!\n", __func__);
620 
621 	total_size = H2C_PKT_HDR_SIZE_88XX + info->content_size;
622 	FW_OFFLOAD_H2C_SET_TOTAL_LEN(hdr, total_size);
623 	FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hdr, info->sub_cmd_id);
624 
625 	FW_OFFLOAD_H2C_SET_CATEGORY(hdr, 0x01);
626 	FW_OFFLOAD_H2C_SET_CMD_ID(hdr, 0xFF);
627 
628 	PLTFM_MUTEX_LOCK(&adapter->h2c_seq_mutex);
629 	FW_OFFLOAD_H2C_SET_SEQ_NUM(hdr, adapter->h2c_info.seq_num);
630 	*seq_num = adapter->h2c_info.seq_num;
631 	(adapter->h2c_info.seq_num)++;
632 	PLTFM_MUTEX_UNLOCK(&adapter->h2c_seq_mutex);
633 
634 	if (info->ack == 1)
635 		FW_OFFLOAD_H2C_SET_ACK(hdr, 1);
636 
637 	return HALMAC_RET_SUCCESS;
638 }
639 
640 enum halmac_ret_status
send_h2c_pkt_88xx(struct halmac_adapter * adapter,u8 * pkt)641 send_h2c_pkt_88xx(struct halmac_adapter *adapter, u8 *pkt)
642 {
643 	u32 cnt = 100;
644 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
645 
646 	while (adapter->h2c_info.buf_fs <= H2C_PKT_SIZE_88XX) {
647 		get_h2c_buf_free_space_88xx(adapter);
648 		cnt--;
649 		if (cnt == 0) {
650 			PLTFM_MSG_ERR("[ERR]h2c free space!!\n");
651 			return HALMAC_RET_H2C_SPACE_FULL;
652 		}
653 	}
654 
655 	cnt = 100;
656 	do {
657 		if (PLTFM_SEND_H2C_PKT(pkt, H2C_PKT_SIZE_88XX) == 1)
658 			break;
659 		cnt--;
660 		if (cnt == 0) {
661 			PLTFM_MSG_ERR("[ERR]pltfm - sned h2c pkt!!\n");
662 			return HALMAC_RET_SEND_H2C_FAIL;
663 		}
664 		PLTFM_DELAY_US(5);
665 
666 	} while (1);
667 
668 	adapter->h2c_info.buf_fs -= H2C_PKT_SIZE_88XX;
669 
670 	return status;
671 }
672 
673 enum halmac_ret_status
get_h2c_buf_free_space_88xx(struct halmac_adapter * adapter)674 get_h2c_buf_free_space_88xx(struct halmac_adapter *adapter)
675 {
676 	u32 hw_wptr;
677 	u32 fw_rptr;
678 	struct halmac_h2c_info *info = &adapter->h2c_info;
679 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
680 
681 	hw_wptr = HALMAC_REG_R32(REG_H2C_PKT_WRITEADDR) & 0x3FFFF;
682 	fw_rptr = HALMAC_REG_R32(REG_H2C_PKT_READADDR) & 0x3FFFF;
683 
684 	if (hw_wptr >= fw_rptr)
685 		info->buf_fs = info->buf_size - (hw_wptr - fw_rptr);
686 	else
687 		info->buf_fs = fw_rptr - hw_wptr;
688 
689 	return HALMAC_RET_SUCCESS;
690 }
691 
692 /**
693  * get_c2h_info_88xx() - process halmac C2H packet
694  * @adapter : the adapter of halmac
695  * @buf : RX Packet pointer
696  * @size : RX Packet size
697  *
698  * Note : Don't use any IO or DELAY in this API
699  *
700  * Author : KaiYuan Chang/Ivan Lin
701  *
702  * Used to process c2h packet info from RX path. After receiving the packet,
703  * user need to call this api and pass the packet pointer.
704  *
705  * Return : enum halmac_ret_status
706  * More details of status code can be found in prototype document
707  */
708 enum halmac_ret_status
get_c2h_info_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)709 get_c2h_info_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
710 {
711 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
712 
713 	if (GET_RX_DESC_C2H(buf) == 1) {
714 		PLTFM_MSG_TRACE("[TRACE]Parse c2h pkt\n");
715 
716 		status = parse_c2h_pkt_88xx(adapter, buf, size);
717 		if (status != HALMAC_RET_SUCCESS) {
718 			PLTFM_MSG_ERR("[ERR]Parse c2h pkt\n");
719 			return status;
720 		}
721 	}
722 
723 	return HALMAC_RET_SUCCESS;
724 }
725 
726 static enum halmac_ret_status
parse_c2h_pkt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)727 parse_c2h_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
728 {
729 	u8 cmd_id;
730 	u8 sub_cmd_id;
731 	u8 *c2h_pkt = buf + adapter->hw_cfg_info.rxdesc_size;
732 	u32 c2h_size = size - adapter->hw_cfg_info.rxdesc_size;
733 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
734 
735 	cmd_id = (u8)C2H_HDR_GET_CMD_ID(c2h_pkt);
736 
737 	if (cmd_id != 0xFF) {
738 		PLTFM_MSG_TRACE("[TRACE]Not 0xFF cmd!!\n");
739 		return HALMAC_RET_C2H_NOT_HANDLED;
740 	}
741 
742 	sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_pkt);
743 
744 	switch (sub_cmd_id) {
745 	case C2H_SUB_CMD_ID_C2H_DBG:
746 		status = get_c2h_dbg_88xx(adapter, c2h_pkt, c2h_size);
747 		break;
748 	case C2H_SUB_CMD_ID_H2C_ACK_HDR:
749 		status = get_h2c_ack_88xx(adapter, c2h_pkt, c2h_size);
750 		break;
751 	case C2H_SUB_CMD_ID_BT_COEX_INFO:
752 		status = HALMAC_RET_C2H_NOT_HANDLED;
753 		break;
754 	case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
755 		status = get_scan_rpt_88xx(adapter, c2h_pkt, c2h_size);
756 		break;
757 	case C2H_SUB_CMD_ID_PSD_DATA:
758 		status = get_psd_data_88xx(adapter, c2h_pkt, c2h_size);
759 		break;
760 	case C2H_SUB_CMD_ID_EFUSE_DATA:
761 		status = get_efuse_data_88xx(adapter, c2h_pkt, c2h_size);
762 		break;
763 	case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY:
764 		status = get_scan_ch_notify_88xx(adapter, c2h_pkt, c2h_size);
765 		break;
766 	case C2H_SUB_CMD_ID_DPK_DATA:
767 		status = get_dpk_data_88xx(adapter, c2h_pkt, c2h_size);
768 		break;
769 	default:
770 		PLTFM_MSG_WARN("[WARN]Sub cmd id!!\n");
771 		status = HALMAC_RET_C2H_NOT_HANDLED;
772 		break;
773 	}
774 
775 	return status;
776 }
777 
778 static enum halmac_ret_status
get_c2h_dbg_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)779 get_c2h_dbg_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
780 {
781 	u8 i;
782 	u8 next_msg = 0;
783 	u8 cur_msg = 0;
784 	u8 msg_len = 0;
785 	char *c2h_buf = (char *)NULL;
786 	u8 content_len = 0;
787 	u8 seq_num = 0;
788 
789 	content_len = (u8)C2H_HDR_GET_LEN((u8 *)buf);
790 
791 	if (content_len > C2H_DBG_CONTENT_MAX_LENGTH) {
792 		PLTFM_MSG_ERR("[ERR]c2h size > max len!\n");
793 		return HALMAC_RET_C2H_NOT_HANDLED;
794 	}
795 
796 	for (i = 0; i < content_len; i++) {
797 		if (*(buf + C2H_DBG_HDR_LEN + i) == '\n') {
798 			if ((*(buf + C2H_DBG_HDR_LEN + i + 1) == '\0') ||
799 			    (*(buf + C2H_DBG_HDR_LEN + i + 1) == 0xff)) {
800 				next_msg = C2H_DBG_HDR_LEN + i + 1;
801 				goto _ENDFOUND;
802 			}
803 		}
804 	}
805 
806 _ENDFOUND:
807 	msg_len = next_msg - C2H_DBG_HDR_LEN;
808 
809 	c2h_buf = (char *)PLTFM_MALLOC(msg_len);
810 	if (!c2h_buf)
811 		return HALMAC_RET_MALLOC_FAIL;
812 
813 	PLTFM_MEMCPY(c2h_buf, buf + C2H_DBG_HDR_LEN, msg_len);
814 
815 	seq_num = (u8)(*(c2h_buf));
816 	*(c2h_buf + msg_len - 1) = '\0';
817 	PLTFM_MSG_ALWAYS("[RTKFW, SEQ=%d]: %s\n",
818 			 seq_num, (char *)(c2h_buf + 1));
819 	PLTFM_FREE(c2h_buf, msg_len);
820 
821 	while (*(buf + next_msg) != '\0') {
822 		cur_msg = next_msg;
823 
824 		msg_len = (u8)(*(buf + cur_msg + 3)) - 1;
825 		next_msg += C2H_DBG_HDR_LEN + msg_len;
826 
827 		c2h_buf = (char *)PLTFM_MALLOC(msg_len);
828 		if (!c2h_buf)
829 			return HALMAC_RET_MALLOC_FAIL;
830 
831 		PLTFM_MEMCPY(c2h_buf, buf + cur_msg + C2H_DBG_HDR_LEN, msg_len);
832 		*(c2h_buf + msg_len - 1) = '\0';
833 		seq_num = (u8)(*(c2h_buf));
834 		PLTFM_MSG_ALWAYS("[RTKFW, SEQ=%d]: %s\n",
835 				 seq_num, (char *)(c2h_buf + 1));
836 		PLTFM_FREE(c2h_buf, msg_len);
837 	}
838 
839 	return HALMAC_RET_SUCCESS;
840 }
841 
842 static enum halmac_ret_status
get_h2c_ack_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)843 get_h2c_ack_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
844 {
845 	u8 cmd_id;
846 	u8 sub_cmd_id;
847 	u8 fw_rc;
848 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
849 
850 	PLTFM_MSG_TRACE("[TRACE]Ack for C2H!!\n");
851 
852 	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
853 	if (HALMAC_H2C_RETURN_SUCCESS != (enum halmac_h2c_return_code)fw_rc)
854 		PLTFM_MSG_TRACE("[TRACE]fw rc = %d\n", fw_rc);
855 
856 	cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(buf);
857 
858 	if (cmd_id != 0xFF) {
859 		PLTFM_MSG_ERR("[ERR]h2c ack cmd id!!\n");
860 		return HALMAC_RET_C2H_NOT_HANDLED;
861 	}
862 
863 	sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(buf);
864 
865 	switch (sub_cmd_id) {
866 	case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
867 		status = get_h2c_ack_phy_efuse_88xx(adapter, buf, size);
868 		break;
869 	case H2C_SUB_CMD_ID_CFG_PARAM_ACK:
870 		status = get_h2c_ack_cfg_param_88xx(adapter, buf, size);
871 		break;
872 	case H2C_SUB_CMD_ID_UPDATE_PKT_ACK:
873 		status = get_h2c_ack_update_pkt_88xx(adapter, buf, size);
874 		break;
875 	case H2C_SUB_CMD_ID_SEND_SCAN_PKT_ACK:
876 		status = get_h2c_ack_send_scan_pkt_88xx(adapter, buf, size);
877 		break;
878 	case H2C_SUB_CMD_ID_DROP_SCAN_PKT_ACK:
879 		status = get_h2c_ack_drop_scan_pkt_88xx(adapter, buf, size);
880 		break;
881 	case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
882 		status = get_h2c_ack_update_datapkt_88xx(adapter, buf, size);
883 		break;
884 	case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
885 		status = get_h2c_ack_run_datapkt_88xx(adapter, buf, size);
886 		break;
887 	case H2C_SUB_CMD_ID_CH_SWITCH_ACK:
888 		status = get_h2c_ack_ch_switch_88xx(adapter, buf, size);
889 		break;
890 	case H2C_SUB_CMD_ID_IQK_ACK:
891 		status = get_h2c_ack_iqk_88xx(adapter, buf, size);
892 		break;
893 	case H2C_SUB_CMD_ID_PWR_TRK_ACK:
894 		status = get_h2c_ack_pwr_trk_88xx(adapter, buf, size);
895 		break;
896 	case H2C_SUB_CMD_ID_PSD_ACK:
897 		break;
898 	case H2C_SUB_CMD_ID_FW_SNDING_ACK:
899 		status = get_h2c_ack_fw_snding_88xx(adapter, buf, size);
900 		break;
901 	case H2C_SUB_CMD_ID_DPK_ACK:
902 		status = get_h2c_ack_dpk_88xx(adapter, buf, size);
903 		break;
904 	default:
905 		status = HALMAC_RET_C2H_NOT_HANDLED;
906 		break;
907 	}
908 
909 	return status;
910 }
911 
912 static enum halmac_ret_status
get_scan_ch_notify_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)913 get_scan_ch_notify_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
914 {
915 	struct halmac_scan_rpt_info *scan_rpt_info = &adapter->scan_rpt_info;
916 
917 	PLTFM_MSG_TRACE("[TRACE]scan mode:%d\n", adapter->ch_sw_info.scan_mode);
918 
919 	if (adapter->ch_sw_info.scan_mode == 1) {
920 		if (scan_rpt_info->avl_buf_size < 12) {
921 			PLTFM_MSG_ERR("[ERR]ch_notify buffer full!!\n");
922 			return HALMAC_RET_CH_SW_NO_BUF;
923 		}
924 
925 		SCAN_CH_NOTIFY_SET_CH_NUM(scan_rpt_info->buf_wptr,
926 					  (u8)SCAN_CH_NOTIFY_GET_CH_NUM(buf));
927 		SCAN_CH_NOTIFY_SET_NOTIFY_ID(scan_rpt_info->buf_wptr,
928 					     SCAN_CH_NOTIFY_GET_NOTIFY_ID(buf));
929 		SCAN_CH_NOTIFY_SET_STATUS(scan_rpt_info->buf_wptr,
930 					  (u8)SCAN_CH_NOTIFY_GET_STATUS(buf));
931 		SCAN_CH_NOTIFY_SET_TSF_0(scan_rpt_info->buf_wptr,
932 					 (u8)SCAN_CH_NOTIFY_GET_TSF_0(buf));
933 		SCAN_CH_NOTIFY_SET_TSF_1(scan_rpt_info->buf_wptr,
934 					 (u8)SCAN_CH_NOTIFY_GET_TSF_1(buf));
935 		SCAN_CH_NOTIFY_SET_TSF_2(scan_rpt_info->buf_wptr,
936 					 (u8)SCAN_CH_NOTIFY_GET_TSF_2(buf));
937 		SCAN_CH_NOTIFY_SET_TSF_3(scan_rpt_info->buf_wptr,
938 					 (u8)SCAN_CH_NOTIFY_GET_TSF_3(buf));
939 		SCAN_CH_NOTIFY_SET_TSF_4(scan_rpt_info->buf_wptr,
940 					 (u8)SCAN_CH_NOTIFY_GET_TSF_4(buf));
941 		SCAN_CH_NOTIFY_SET_TSF_5(scan_rpt_info->buf_wptr,
942 					 (u8)SCAN_CH_NOTIFY_GET_TSF_5(buf));
943 		SCAN_CH_NOTIFY_SET_TSF_6(scan_rpt_info->buf_wptr,
944 					 (u8)SCAN_CH_NOTIFY_GET_TSF_6(buf));
945 		SCAN_CH_NOTIFY_SET_TSF_7(scan_rpt_info->buf_wptr,
946 					 (u8)SCAN_CH_NOTIFY_GET_TSF_7(buf));
947 
948 		scan_rpt_info->avl_buf_size = scan_rpt_info->avl_buf_size - 12;
949 		scan_rpt_info->total_size = scan_rpt_info->total_size + 12;
950 		scan_rpt_info->buf_wptr = scan_rpt_info->buf_wptr + 12;
951 	}
952 
953 	return HALMAC_RET_SUCCESS;
954 }
955 
956 static enum halmac_ret_status
get_scan_rpt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)957 get_scan_rpt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
958 {
959 	u8 fw_rc;
960 	enum halmac_cmd_process_status proc_status;
961 	struct halmac_scan_rpt_info *scan_rpt_info = &adapter->scan_rpt_info;
962 
963 	fw_rc = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(buf);
964 	proc_status = (HALMAC_H2C_RETURN_SUCCESS ==
965 		(enum halmac_h2c_return_code)fw_rc) ?
966 		HALMAC_CMD_PROCESS_DONE : HALMAC_CMD_PROCESS_ERROR;
967 
968 	PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status, NULL, 0);
969 
970 	adapter->halmac_state.scan_state.proc_status = proc_status;
971 
972 	if (adapter->ch_sw_info.scan_mode == 1) {
973 		scan_rpt_info->rpt_tsf_low =
974 			((SCAN_STATUS_RPT_GET_TSF_3(buf) << 24) |
975 			(SCAN_STATUS_RPT_GET_TSF_2(buf) << 16) |
976 			(SCAN_STATUS_RPT_GET_TSF_1(buf) << 8) |
977 			(SCAN_STATUS_RPT_GET_TSF_0(buf)));
978 		scan_rpt_info->rpt_tsf_high =
979 			((SCAN_STATUS_RPT_GET_TSF_7(buf) << 24) |
980 			(SCAN_STATUS_RPT_GET_TSF_6(buf) << 16) |
981 			(SCAN_STATUS_RPT_GET_TSF_5(buf) << 8) |
982 			(SCAN_STATUS_RPT_GET_TSF_4(buf)));
983 	}
984 
985 	PLTFM_MSG_TRACE("[TRACE]scan : %X\n", proc_status);
986 
987 	return HALMAC_RET_SUCCESS;
988 }
989 
990 static enum halmac_ret_status
get_h2c_ack_cfg_param_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)991 get_h2c_ack_cfg_param_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
992 {
993 	u8 seq_num;
994 	u8 fw_rc;
995 	u32 offset_accum;
996 	u32 value_accum;
997 	struct halmac_cfg_param_state *state =
998 		&adapter->halmac_state.cfg_param_state;
999 	enum halmac_cmd_process_status proc_status =
1000 		HALMAC_CMD_PROCESS_UNDEFINE;
1001 
1002 	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
1003 	PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
1004 			state->seq_num, seq_num);
1005 	if (seq_num != state->seq_num) {
1006 		PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
1007 			      state->seq_num, seq_num);
1008 		return HALMAC_RET_SUCCESS;
1009 	}
1010 
1011 	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
1012 		PLTFM_MSG_ERR("[ERR]not cmd sending\n");
1013 		return HALMAC_RET_SUCCESS;
1014 	}
1015 
1016 	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
1017 	state->fw_rc = fw_rc;
1018 	offset_accum = CFG_PARAM_ACK_GET_OFFSET_ACCUMULATION(buf);
1019 	value_accum = CFG_PARAM_ACK_GET_VALUE_ACCUMULATION(buf);
1020 
1021 	if (offset_accum != adapter->cfg_param_info.offset_accum ||
1022 	    value_accum != adapter->cfg_param_info.value_accum) {
1023 		PLTFM_MSG_ERR("[ERR][C2H]offset_accu : %x, value_accu : %xn",
1024 			      offset_accum, value_accum);
1025 		PLTFM_MSG_ERR("[ERR][Ada]offset_accu : %x, value_accu : %x\n",
1026 			      adapter->cfg_param_info.offset_accum,
1027 			      adapter->cfg_param_info.value_accum);
1028 		proc_status = HALMAC_CMD_PROCESS_ERROR;
1029 	}
1030 
1031 	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS &&
1032 	    proc_status != HALMAC_CMD_PROCESS_ERROR) {
1033 		proc_status = HALMAC_CMD_PROCESS_DONE;
1034 		state->proc_status = proc_status;
1035 		PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, proc_status, NULL, 0);
1036 	} else {
1037 		proc_status = HALMAC_CMD_PROCESS_ERROR;
1038 		state->proc_status = proc_status;
1039 		PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, proc_status,
1040 				&fw_rc, 1);
1041 	}
1042 
1043 	return HALMAC_RET_SUCCESS;
1044 }
1045 
1046 static enum halmac_ret_status
get_h2c_ack_update_pkt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)1047 get_h2c_ack_update_pkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
1048 {
1049 	u8 seq_num;
1050 	u8 fw_rc;
1051 	struct halmac_update_pkt_state *state =
1052 		&adapter->halmac_state.update_pkt_state;
1053 	enum halmac_cmd_process_status proc_status;
1054 
1055 	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
1056 	PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
1057 			state->seq_num, seq_num);
1058 	if (seq_num != state->seq_num) {
1059 		PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
1060 			      state->seq_num, seq_num);
1061 		return HALMAC_RET_SUCCESS;
1062 	}
1063 
1064 	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
1065 		PLTFM_MSG_ERR("[ERR]not cmd sending\n");
1066 		return HALMAC_RET_SUCCESS;
1067 	}
1068 
1069 	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
1070 	state->fw_rc = fw_rc;
1071 
1072 	if (HALMAC_H2C_RETURN_SUCCESS == (enum halmac_h2c_return_code)fw_rc) {
1073 		proc_status = HALMAC_CMD_PROCESS_DONE;
1074 		state->proc_status = proc_status;
1075 		PLTFM_EVENT_SIG(HALMAC_FEATURE_UPDATE_PACKET, proc_status,
1076 				NULL, 0);
1077 	} else {
1078 		proc_status = HALMAC_CMD_PROCESS_ERROR;
1079 		state->proc_status = proc_status;
1080 		PLTFM_EVENT_SIG(HALMAC_FEATURE_UPDATE_PACKET, proc_status,
1081 				&state->fw_rc, 1);
1082 	}
1083 
1084 	return HALMAC_RET_SUCCESS;
1085 }
1086 
1087 static enum halmac_ret_status
get_h2c_ack_send_scan_pkt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)1088 get_h2c_ack_send_scan_pkt_88xx(struct halmac_adapter *adapter,
1089 			       u8 *buf, u32 size)
1090 {
1091 	u8 seq_num;
1092 	u8 fw_rc;
1093 	struct halmac_scan_pkt_state *state =
1094 		&adapter->halmac_state.scan_pkt_state;
1095 	enum halmac_cmd_process_status proc_status;
1096 
1097 	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
1098 	PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
1099 			state->seq_num, seq_num);
1100 	if (seq_num != state->seq_num) {
1101 		PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
1102 			      state->seq_num, seq_num);
1103 		return HALMAC_RET_SUCCESS;
1104 	}
1105 
1106 	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
1107 		PLTFM_MSG_ERR("[ERR]not cmd sending\n");
1108 		return HALMAC_RET_SUCCESS;
1109 	}
1110 
1111 	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
1112 	state->fw_rc = fw_rc;
1113 
1114 	if (HALMAC_H2C_RETURN_SUCCESS == (enum halmac_h2c_return_code)fw_rc) {
1115 		proc_status = HALMAC_CMD_PROCESS_DONE;
1116 		state->proc_status = proc_status;
1117 		PLTFM_EVENT_SIG(HALMAC_FEATURE_SEND_SCAN_PACKET, proc_status,
1118 				NULL, 0);
1119 	} else {
1120 		proc_status = HALMAC_CMD_PROCESS_ERROR;
1121 		state->proc_status = proc_status;
1122 		PLTFM_EVENT_SIG(HALMAC_FEATURE_SEND_SCAN_PACKET, proc_status,
1123 				&state->fw_rc, 1);
1124 	}
1125 
1126 	return HALMAC_RET_SUCCESS;
1127 }
1128 
1129 static enum halmac_ret_status
get_h2c_ack_drop_scan_pkt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)1130 get_h2c_ack_drop_scan_pkt_88xx(struct halmac_adapter *adapter,
1131 			       u8 *buf, u32 size)
1132 {
1133 	u8 seq_num;
1134 	u8 fw_rc;
1135 	struct halmac_drop_pkt_state *state =
1136 		&adapter->halmac_state.drop_pkt_state;
1137 	enum halmac_cmd_process_status proc_status;
1138 
1139 	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
1140 	PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
1141 			state->seq_num, seq_num);
1142 	if (seq_num != state->seq_num) {
1143 		PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
1144 			      state->seq_num, seq_num);
1145 		return HALMAC_RET_SUCCESS;
1146 	}
1147 
1148 	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
1149 		PLTFM_MSG_ERR("[ERR]not cmd sending\n");
1150 		return HALMAC_RET_SUCCESS;
1151 	}
1152 
1153 	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
1154 	state->fw_rc = fw_rc;
1155 
1156 	if (HALMAC_H2C_RETURN_SUCCESS == (enum halmac_h2c_return_code)fw_rc) {
1157 		proc_status = HALMAC_CMD_PROCESS_DONE;
1158 		state->proc_status = proc_status;
1159 		PLTFM_EVENT_SIG(HALMAC_FEATURE_DROP_SCAN_PACKET, proc_status,
1160 				NULL, 0);
1161 	} else {
1162 		proc_status = HALMAC_CMD_PROCESS_ERROR;
1163 		state->proc_status = proc_status;
1164 		PLTFM_EVENT_SIG(HALMAC_FEATURE_DROP_SCAN_PACKET, proc_status,
1165 				&state->fw_rc, 1);
1166 	}
1167 
1168 	return HALMAC_RET_SUCCESS;
1169 }
1170 
1171 static enum halmac_ret_status
get_h2c_ack_update_datapkt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)1172 get_h2c_ack_update_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf,
1173 				u32 size)
1174 {
1175 	return HALMAC_RET_NOT_SUPPORT;
1176 }
1177 
1178 static enum halmac_ret_status
get_h2c_ack_run_datapkt_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)1179 get_h2c_ack_run_datapkt_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
1180 {
1181 	return HALMAC_RET_NOT_SUPPORT;
1182 }
1183 
1184 static enum halmac_ret_status
get_h2c_ack_ch_switch_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)1185 get_h2c_ack_ch_switch_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
1186 {
1187 	u8 seq_num;
1188 	u8 fw_rc;
1189 	struct halmac_scan_state *state = &adapter->halmac_state.scan_state;
1190 	struct halmac_scan_rpt_info *scan_rpt_info = &adapter->scan_rpt_info;
1191 	enum halmac_cmd_process_status proc_status;
1192 
1193 	seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
1194 	PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
1195 			state->seq_num, seq_num);
1196 	if (seq_num != state->seq_num) {
1197 		PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
1198 			      state->seq_num, seq_num);
1199 		return HALMAC_RET_SUCCESS;
1200 	}
1201 
1202 	if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
1203 		PLTFM_MSG_ERR("[ERR]not cmd sending\n");
1204 		return HALMAC_RET_SUCCESS;
1205 	}
1206 
1207 	fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
1208 	state->fw_rc = fw_rc;
1209 
1210 	if (adapter->ch_sw_info.scan_mode == 1) {
1211 		scan_rpt_info->ack_tsf_low =
1212 			((CH_SWITCH_ACK_GET_TSF_3(buf) << 24) |
1213 			(CH_SWITCH_ACK_GET_TSF_2(buf) << 16) |
1214 			(CH_SWITCH_ACK_GET_TSF_1(buf) << 8) |
1215 			(CH_SWITCH_ACK_GET_TSF_0(buf)));
1216 		scan_rpt_info->ack_tsf_high =
1217 			((CH_SWITCH_ACK_GET_TSF_7(buf) << 24) |
1218 			(CH_SWITCH_ACK_GET_TSF_6(buf) << 16) |
1219 			(CH_SWITCH_ACK_GET_TSF_5(buf) << 8) |
1220 			(CH_SWITCH_ACK_GET_TSF_4(buf)));
1221 	}
1222 
1223 	if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
1224 		proc_status = HALMAC_CMD_PROCESS_RCVD;
1225 		state->proc_status = proc_status;
1226 		PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status,
1227 				NULL, 0);
1228 	} else {
1229 		proc_status = HALMAC_CMD_PROCESS_ERROR;
1230 		state->proc_status = proc_status;
1231 		PLTFM_EVENT_SIG(HALMAC_FEATURE_CHANNEL_SWITCH, proc_status,
1232 				&fw_rc, 1);
1233 	}
1234 
1235 	return HALMAC_RET_SUCCESS;
1236 }
1237 
1238 /**
1239  * mac_debug_88xx_v1() - read some registers for debug
1240  * @adapter
1241  * Author : KaiYuan Chang/Ivan Lin
1242  * Return : enum halmac_ret_status
1243  */
1244 enum halmac_ret_status
mac_debug_88xx(struct halmac_adapter * adapter)1245 mac_debug_88xx(struct halmac_adapter *adapter)
1246 {
1247 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1248 
1249 	if (adapter->intf == HALMAC_INTERFACE_SDIO)
1250 		dump_reg_sdio_88xx(adapter);
1251 	else
1252 		dump_reg_88xx(adapter);
1253 
1254 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1255 
1256 	return HALMAC_RET_SUCCESS;
1257 }
1258 
1259 static void
dump_reg_sdio_88xx(struct halmac_adapter * adapter)1260 dump_reg_sdio_88xx(struct halmac_adapter *adapter)
1261 {
1262 	u8 tmp8;
1263 	u32 i;
1264 
1265 	/* Dump CCCR, it needs new platform api */
1266 
1267 	/*Dump SDIO Local Register, use CMD52*/
1268 	for (i = 0x10250000; i < 0x102500ff; i++) {
1269 		tmp8 = PLTFM_SDIO_CMD52_R(i);
1270 		PLTFM_MSG_TRACE("[TRACE]dbg-sdio[%x]=%x\n", i, tmp8);
1271 	}
1272 
1273 	/*Dump MAC Register*/
1274 	for (i = 0x0000; i < 0x17ff; i++) {
1275 		tmp8 = PLTFM_SDIO_CMD52_R(i);
1276 		PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1277 	}
1278 
1279 	tmp8 = PLTFM_SDIO_CMD52_R(REG_SDIO_CRC_ERR_IDX);
1280 	if (tmp8)
1281 		PLTFM_MSG_ERR("[ERR]sdio crc=%x\n", tmp8);
1282 
1283 	/*Check RX Fifo status*/
1284 	i = REG_RXFF_PTR_V1;
1285 	tmp8 = PLTFM_SDIO_CMD52_R(i);
1286 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1287 	i = REG_RXFF_WTR_V1;
1288 	tmp8 = PLTFM_SDIO_CMD52_R(i);
1289 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1290 	i = REG_RXFF_PTR_V1;
1291 	tmp8 = PLTFM_SDIO_CMD52_R(i);
1292 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1293 	i = REG_RXFF_WTR_V1;
1294 	tmp8 = PLTFM_SDIO_CMD52_R(i);
1295 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp8);
1296 }
1297 
1298 static void
dump_reg_88xx(struct halmac_adapter * adapter)1299 dump_reg_88xx(struct halmac_adapter *adapter)
1300 {
1301 	u32 tmp32;
1302 	u32 i;
1303 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1304 
1305 	/*Dump MAC Register*/
1306 	for (i = 0x0000; i < 0x17fc; i += 4) {
1307 		tmp32 = HALMAC_REG_R32(i);
1308 		PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1309 	}
1310 
1311 	/*Check RX Fifo status*/
1312 	i = REG_RXFF_PTR_V1;
1313 	tmp32 = HALMAC_REG_R32(i);
1314 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1315 	i = REG_RXFF_WTR_V1;
1316 	tmp32 = HALMAC_REG_R32(i);
1317 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1318 	i = REG_RXFF_PTR_V1;
1319 	tmp32 = HALMAC_REG_R32(i);
1320 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1321 	i = REG_RXFF_WTR_V1;
1322 	tmp32 = HALMAC_REG_R32(i);
1323 	PLTFM_MSG_TRACE("[TRACE]dbg-mac[%x]=%x\n", i, tmp32);
1324 }
1325 
1326 /**
1327  * cfg_parameter_88xx() - config parameter by FW
1328  * @adapter : the adapter of halmac
1329  * @info : cmd id, content
1330  * @full_fifo : parameter information
1331  *
1332  * If msk_en = 1, the format of array is {reg_info, mask, value}.
1333  * If msk_en =_FAUSE, the format of array is {reg_info, value}
1334  * The format of reg_info is
1335  * reg_info[31]=rf_reg, 0: MAC_BB reg, 1: RF reg
1336  * reg_info[27:24]=rf_path, 0: path_A, 1: path_B
1337  * if rf_reg=0(MAC_BB reg), rf_path is meaningless.
1338  * ref_info[15:0]=offset
1339  *
1340  * Example: msk_en = 0
1341  * {0x8100000a, 0x00001122}
1342  * =>Set RF register, path_B, offset 0xA to 0x00001122
1343  * {0x00000824, 0x11224433}
1344  * =>Set MAC_BB register, offset 0x800 to 0x11224433
1345  *
1346  * Note : full fifo mode only for init flow
1347  *
1348  * Author : KaiYuan Chang/Ivan Lin
1349  * Return : enum halmac_ret_status
1350  * More details of status code can be found in prototype document
1351  */
1352 enum halmac_ret_status
cfg_parameter_88xx(struct halmac_adapter * adapter,struct halmac_phy_parameter_info * info,u8 full_fifo)1353 cfg_parameter_88xx(struct halmac_adapter *adapter,
1354 		   struct halmac_phy_parameter_info *info, u8 full_fifo)
1355 {
1356 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1357 	enum halmac_cmd_process_status *proc_status;
1358 	enum halmac_cmd_construct_state cmd_state;
1359 
1360 	proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
1361 
1362 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1363 		return HALMAC_RET_NO_DLFW;
1364 
1365 	if (adapter->fw_ver.h2c_version < 4)
1366 		return HALMAC_RET_FW_NO_SUPPORT;
1367 
1368 	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
1369 		PLTFM_MSG_TRACE("[TRACE]Wait event(para)\n");
1370 		return HALMAC_RET_BUSY_STATE;
1371 	}
1372 
1373 	cmd_state = cfg_param_cmd_cnstr_state_88xx(adapter);
1374 	if (cmd_state != HALMAC_CMD_CNSTR_IDLE &&
1375 	    cmd_state != HALMAC_CMD_CNSTR_CNSTR) {
1376 		PLTFM_MSG_TRACE("[TRACE]Not idle(para)\n");
1377 		return HALMAC_RET_BUSY_STATE;
1378 	}
1379 
1380 	*proc_status = HALMAC_CMD_PROCESS_IDLE;
1381 
1382 	status = proc_cfg_param_88xx(adapter, info, full_fifo);
1383 
1384 	if (status != HALMAC_RET_SUCCESS && status != HALMAC_RET_PARA_SENDING) {
1385 		PLTFM_MSG_ERR("[ERR]send param h2c\n");
1386 		return status;
1387 	}
1388 
1389 	return status;
1390 }
1391 
1392 static enum halmac_cmd_construct_state
cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter * adapter)1393 cfg_param_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
1394 {
1395 	return adapter->halmac_state.cfg_param_state.cmd_cnstr_state;
1396 }
1397 
1398 static enum halmac_ret_status
proc_cfg_param_88xx(struct halmac_adapter * adapter,struct halmac_phy_parameter_info * param,u8 full_fifo)1399 proc_cfg_param_88xx(struct halmac_adapter *adapter,
1400 		    struct halmac_phy_parameter_info *param, u8 full_fifo)
1401 {
1402 	u8 end_cmd = 0;
1403 	u32 rsvd_size;
1404 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1405 	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1406 	enum halmac_cmd_process_status *proc_status;
1407 
1408 	proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
1409 
1410 	status = malloc_cfg_param_buf_88xx(adapter, full_fifo);
1411 	if (status != HALMAC_RET_SUCCESS)
1412 		return status;
1413 
1414 	if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
1415 	    HALMAC_RET_SUCCESS) {
1416 		PLTFM_FREE(info->buf, info->buf_size);
1417 		info->buf = NULL;
1418 		info->buf_wptr = NULL;
1419 		return HALMAC_RET_ERROR_STATE;
1420 	}
1421 
1422 	add_param_buf_88xx(adapter, param, info->buf_wptr, &end_cmd);
1423 	if (param->cmd_id != HALMAC_PARAMETER_CMD_END) {
1424 		info->num++;
1425 		info->buf_wptr += CFG_PARAM_H2C_INFO_SIZE;
1426 		info->avl_buf_size -= CFG_PARAM_H2C_INFO_SIZE;
1427 	}
1428 
1429 	rsvd_size = info->avl_buf_size - adapter->hw_cfg_info.txdesc_size;
1430 	if (rsvd_size > CFG_PARAM_H2C_INFO_SIZE && end_cmd == 0)
1431 		return HALMAC_RET_SUCCESS;
1432 
1433 	if (info->num == 0) {
1434 		PLTFM_FREE(info->buf, info->buf_size);
1435 		info->buf = NULL;
1436 		info->buf_wptr = NULL;
1437 		PLTFM_MSG_TRACE("[TRACE]param num = 0!!\n");
1438 
1439 		*proc_status = HALMAC_CMD_PROCESS_DONE;
1440 		PLTFM_EVENT_SIG(HALMAC_FEATURE_CFG_PARA, *proc_status, NULL, 0);
1441 
1442 		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CFG_PARA);
1443 
1444 		return HALMAC_RET_SUCCESS;
1445 	}
1446 
1447 	status = send_cfg_param_h2c_88xx(adapter);
1448 	if (status != HALMAC_RET_SUCCESS) {
1449 		if (info->buf) {
1450 			PLTFM_FREE(info->buf, info->buf_size);
1451 			info->buf = NULL;
1452 			info->buf_wptr = NULL;
1453 		}
1454 		return status;
1455 	}
1456 
1457 	if (end_cmd == 0) {
1458 		PLTFM_MSG_TRACE("[TRACE]send h2c-buf full\n");
1459 		return HALMAC_RET_PARA_SENDING;
1460 	}
1461 
1462 	return status;
1463 }
1464 
1465 static enum halmac_ret_status
send_cfg_param_h2c_88xx(struct halmac_adapter * adapter)1466 send_cfg_param_h2c_88xx(struct halmac_adapter *adapter)
1467 {
1468 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1469 	u16 pg_addr;
1470 	u16 seq_num = 0;
1471 	u32 info_size;
1472 	struct halmac_h2c_header_info hdr_info;
1473 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1474 	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1475 	enum halmac_cmd_process_status *proc_status;
1476 
1477 	proc_status = &adapter->halmac_state.cfg_param_state.proc_status;
1478 
1479 	if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
1480 	    HALMAC_RET_SUCCESS)
1481 		return HALMAC_RET_ERROR_STATE;
1482 
1483 	*proc_status = HALMAC_CMD_PROCESS_SENDING;
1484 
1485 	if (info->full_fifo_mode == 1)
1486 		pg_addr = 0;
1487 	else
1488 		pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1489 
1490 	info_size = info->num * CFG_PARAM_H2C_INFO_SIZE;
1491 
1492 	status = dl_rsvd_page_88xx(adapter, pg_addr, info->buf, info_size);
1493 	if (status != HALMAC_RET_SUCCESS) {
1494 		PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
1495 		goto CFG_PARAM_H2C_FAIL;
1496 	}
1497 
1498 	gen_cfg_param_h2c_88xx(adapter, h2c_buf);
1499 
1500 	hdr_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAM;
1501 	hdr_info.content_size = 4;
1502 	hdr_info.ack = 1;
1503 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1504 
1505 	adapter->halmac_state.cfg_param_state.seq_num = seq_num;
1506 
1507 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
1508 
1509 	if (status != HALMAC_RET_SUCCESS) {
1510 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1511 		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CFG_PARA);
1512 	}
1513 
1514 CFG_PARAM_H2C_FAIL:
1515 	PLTFM_FREE(info->buf, info->buf_size);
1516 	info->buf = NULL;
1517 	info->buf_wptr = NULL;
1518 
1519 	if (cnv_cfg_param_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
1520 	    HALMAC_RET_SUCCESS)
1521 		return HALMAC_RET_ERROR_STATE;
1522 
1523 	return status;
1524 }
1525 
1526 static enum halmac_ret_status
cnv_cfg_param_state_88xx(struct halmac_adapter * adapter,enum halmac_cmd_construct_state dest_state)1527 cnv_cfg_param_state_88xx(struct halmac_adapter *adapter,
1528 			 enum halmac_cmd_construct_state dest_state)
1529 {
1530 	enum halmac_cmd_construct_state *state;
1531 
1532 	state = &adapter->halmac_state.cfg_param_state.cmd_cnstr_state;
1533 
1534 	if ((*state != HALMAC_CMD_CNSTR_IDLE) &&
1535 	    (*state != HALMAC_CMD_CNSTR_CNSTR) &&
1536 	    (*state != HALMAC_CMD_CNSTR_H2C_SENT))
1537 		return HALMAC_RET_ERROR_STATE;
1538 
1539 	if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
1540 		if (*state == HALMAC_CMD_CNSTR_CNSTR)
1541 			return HALMAC_RET_ERROR_STATE;
1542 	} else if (dest_state == HALMAC_CMD_CNSTR_CNSTR) {
1543 		if (*state == HALMAC_CMD_CNSTR_H2C_SENT)
1544 			return HALMAC_RET_ERROR_STATE;
1545 	} else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
1546 		if ((*state == HALMAC_CMD_CNSTR_IDLE) ||
1547 		    (*state == HALMAC_CMD_CNSTR_H2C_SENT))
1548 			return HALMAC_RET_ERROR_STATE;
1549 	}
1550 
1551 	*state = dest_state;
1552 
1553 	return HALMAC_RET_SUCCESS;
1554 }
1555 
1556 static enum halmac_ret_status
add_param_buf_88xx(struct halmac_adapter * adapter,struct halmac_phy_parameter_info * param,u8 * buf,u8 * end_cmd)1557 add_param_buf_88xx(struct halmac_adapter *adapter,
1558 		   struct halmac_phy_parameter_info *param, u8 *buf,
1559 		   u8 *end_cmd)
1560 {
1561 	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1562 	union halmac_parameter_content *content = &param->content;
1563 
1564 	*end_cmd = 0;
1565 
1566 	PARAM_INFO_SET_LEN(buf, CFG_PARAM_H2C_INFO_SIZE);
1567 	PARAM_INFO_SET_IO_CMD(buf, param->cmd_id);
1568 
1569 	switch (param->cmd_id) {
1570 	case HALMAC_PARAMETER_CMD_BB_W8:
1571 	case HALMAC_PARAMETER_CMD_BB_W16:
1572 	case HALMAC_PARAMETER_CMD_BB_W32:
1573 	case HALMAC_PARAMETER_CMD_MAC_W8:
1574 	case HALMAC_PARAMETER_CMD_MAC_W16:
1575 	case HALMAC_PARAMETER_CMD_MAC_W32:
1576 		PARAM_INFO_SET_IO_ADDR(buf, content->MAC_REG_W.offset);
1577 		PARAM_INFO_SET_DATA(buf, content->MAC_REG_W.value);
1578 		PARAM_INFO_SET_MASK(buf, content->MAC_REG_W.msk);
1579 		PARAM_INFO_SET_MSK_EN(buf, content->MAC_REG_W.msk_en);
1580 		info->value_accum += content->MAC_REG_W.value;
1581 		info->offset_accum += content->MAC_REG_W.offset;
1582 		break;
1583 	case HALMAC_PARAMETER_CMD_RF_W:
1584 		/*In rf register, the address is only 1 byte*/
1585 		PARAM_INFO_SET_RF_ADDR(buf, content->RF_REG_W.offset);
1586 		PARAM_INFO_SET_RF_PATH(buf, content->RF_REG_W.rf_path);
1587 		PARAM_INFO_SET_DATA(buf, content->RF_REG_W.value);
1588 		PARAM_INFO_SET_MASK(buf, content->RF_REG_W.msk);
1589 		PARAM_INFO_SET_MSK_EN(buf, content->RF_REG_W.msk_en);
1590 		info->value_accum += content->RF_REG_W.value;
1591 		info->offset_accum += (content->RF_REG_W.offset +
1592 					(content->RF_REG_W.rf_path << 8));
1593 		break;
1594 	case HALMAC_PARAMETER_CMD_DELAY_US:
1595 	case HALMAC_PARAMETER_CMD_DELAY_MS:
1596 		PARAM_INFO_SET_DELAY_VAL(buf, content->DELAY_TIME.delay_time);
1597 		break;
1598 	case HALMAC_PARAMETER_CMD_END:
1599 		*end_cmd = 1;
1600 		break;
1601 	default:
1602 		PLTFM_MSG_ERR("[ERR]cmd id!!\n");
1603 		break;
1604 	}
1605 
1606 	return HALMAC_RET_SUCCESS;
1607 }
1608 
1609 static enum halmac_ret_status
gen_cfg_param_h2c_88xx(struct halmac_adapter * adapter,u8 * buff)1610 gen_cfg_param_h2c_88xx(struct halmac_adapter *adapter, u8 *buff)
1611 {
1612 	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1613 	u16 h2c_info_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1614 	u16 rsvd_pg_addr = adapter->txff_alloc.rsvd_boundary;
1615 
1616 	CFG_PARAM_SET_NUM(buff, info->num);
1617 
1618 	if (info->full_fifo_mode == 1) {
1619 		CFG_PARAM_SET_INIT_CASE(buff, 0x1);
1620 		CFG_PARAM_SET_LOC(buff, 0);
1621 	} else {
1622 		CFG_PARAM_SET_INIT_CASE(buff, 0x0);
1623 		CFG_PARAM_SET_LOC(buff, h2c_info_addr - rsvd_pg_addr);
1624 	}
1625 
1626 	return HALMAC_RET_SUCCESS;
1627 }
1628 
1629 static enum halmac_ret_status
malloc_cfg_param_buf_88xx(struct halmac_adapter * adapter,u8 full_fifo)1630 malloc_cfg_param_buf_88xx(struct halmac_adapter *adapter, u8 full_fifo)
1631 {
1632 	struct halmac_cfg_param_info *info = &adapter->cfg_param_info;
1633 	struct halmac_pltfm_cfg_info *pltfm_info = &adapter->pltfm_info;
1634 
1635 	if (info->buf)
1636 		return HALMAC_RET_SUCCESS;
1637 
1638 	if (full_fifo == 1)
1639 		info->buf_size = pltfm_info->malloc_size;
1640 	else
1641 		info->buf_size = CFG_PARAM_RSVDPG_SIZE;
1642 
1643 	if (info->buf_size > pltfm_info->rsvd_pg_size)
1644 		info->buf_size = pltfm_info->rsvd_pg_size;
1645 
1646 	info->buf = smart_malloc_88xx(adapter, info->buf_size, &info->buf_size);
1647 	if (info->buf) {
1648 		PLTFM_MEMSET(info->buf, 0x00, info->buf_size);
1649 		info->full_fifo_mode = full_fifo;
1650 		info->buf_wptr = info->buf;
1651 		info->num = 0;
1652 		info->avl_buf_size = info->buf_size;
1653 		info->value_accum = 0;
1654 		info->offset_accum = 0;
1655 	} else {
1656 		return HALMAC_RET_MALLOC_FAIL;
1657 	}
1658 
1659 	return HALMAC_RET_SUCCESS;
1660 }
1661 
1662 /**
1663  * update_packet_88xx() - send specific packet to FW
1664  * @adapter : the adapter of halmac
1665  * @pkt_id : packet id, to know the purpose of this packet
1666  * @pkt : packet
1667  * @size : packet size
1668  *
1669  * Note : TX_DESC is not included in the pkt
1670  *
1671  * Author : KaiYuan Chang/Ivan Lin
1672  * Return : enum halmac_ret_status
1673  * More details of status code can be found in prototype document
1674  */
1675 enum halmac_ret_status
update_packet_88xx(struct halmac_adapter * adapter,enum halmac_packet_id pkt_id,u8 * pkt,u32 size)1676 update_packet_88xx(struct halmac_adapter *adapter, enum halmac_packet_id pkt_id,
1677 		   u8 *pkt, u32 size)
1678 {
1679 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1680 	enum halmac_cmd_process_status *proc_status =
1681 		&adapter->halmac_state.update_pkt_state.proc_status;
1682 	u8 *used_page = &adapter->halmac_state.update_pkt_state.used_page;
1683 
1684 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1685 		return HALMAC_RET_NO_DLFW;
1686 
1687 	if (adapter->fw_ver.h2c_version < 4)
1688 		return HALMAC_RET_FW_NO_SUPPORT;
1689 
1690 	if (size > UPDATE_PKT_RSVDPG_SIZE)
1691 		return HALMAC_RET_RSVD_PG_OVERFLOW_FAIL;
1692 
1693 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1694 
1695 	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
1696 		PLTFM_MSG_TRACE("[TRACE]Wait event(upd)\n");
1697 		return HALMAC_RET_BUSY_STATE;
1698 	}
1699 
1700 	*proc_status = HALMAC_CMD_PROCESS_SENDING;
1701 
1702 	status = send_h2c_update_packet_88xx(adapter, pkt_id, pkt, size);
1703 	if (status != HALMAC_RET_SUCCESS) {
1704 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1705 		PLTFM_MSG_ERR("[ERR]pkt id : %X!!\n", pkt_id);
1706 		return status;
1707 	}
1708 
1709 	*used_page = (u8)get_update_packet_page_size(adapter, size);
1710 
1711 	if (packet_in_nlo_88xx(adapter, pkt_id)) {
1712 		*proc_status = HALMAC_CMD_PROCESS_DONE;
1713 		adapter->nlo_flag = 1;
1714 	}
1715 
1716 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1717 
1718 	return HALMAC_RET_SUCCESS;
1719 }
1720 
1721 static enum halmac_ret_status
send_h2c_update_packet_88xx(struct halmac_adapter * adapter,enum halmac_packet_id pkt_id,u8 * pkt,u32 size)1722 send_h2c_update_packet_88xx(struct halmac_adapter *adapter,
1723 			    enum halmac_packet_id pkt_id, u8 *pkt, u32 size)
1724 {
1725 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1726 	u16 seq_num = 0;
1727 	u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1728 	u16 pg_offset;
1729 	struct halmac_h2c_header_info hdr_info;
1730 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1731 	enum halmac_packet_id real_pkt_id;
1732 
1733 	status = dl_rsvd_page_88xx(adapter, pg_addr, pkt, size);
1734 	if (status != HALMAC_RET_SUCCESS) {
1735 		PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
1736 		return status;
1737 	}
1738 
1739 	real_pkt_id = get_real_pkt_id_88xx(adapter, pkt_id);
1740 	pg_offset = pg_addr - adapter->txff_alloc.rsvd_boundary;
1741 	UPDATE_PKT_SET_SIZE(h2c_buf, size + adapter->hw_cfg_info.txdesc_size);
1742 	UPDATE_PKT_SET_ID(h2c_buf, real_pkt_id);
1743 	UPDATE_PKT_SET_LOC(h2c_buf, pg_offset);
1744 
1745 	hdr_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PKT;
1746 	hdr_info.content_size = 4;
1747 	if (packet_in_nlo_88xx(adapter, pkt_id))
1748 		hdr_info.ack = 0;
1749 	else
1750 		hdr_info.ack = 1;
1751 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1752 	adapter->halmac_state.update_pkt_state.seq_num = seq_num;
1753 
1754 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
1755 
1756 	if (status != HALMAC_RET_SUCCESS) {
1757 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1758 		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_UPDATE_PACKET);
1759 		return status;
1760 	}
1761 
1762 	return status;
1763 }
1764 
1765 enum halmac_ret_status
send_scan_packet_88xx(struct halmac_adapter * adapter,u8 index,u8 * pkt,u32 size)1766 send_scan_packet_88xx(struct halmac_adapter *adapter, u8 index,
1767 		      u8 *pkt, u32 size)
1768 {
1769 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1770 	enum halmac_cmd_process_status *proc_status =
1771 		&adapter->halmac_state.scan_pkt_state.proc_status;
1772 
1773 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1774 		return HALMAC_RET_NO_DLFW;
1775 
1776 	if (adapter->fw_ver.h2c_version < 13)
1777 		return HALMAC_RET_FW_NO_SUPPORT;
1778 
1779 	if (size > UPDATE_PKT_RSVDPG_SIZE)
1780 		return HALMAC_RET_RSVD_PG_OVERFLOW_FAIL;
1781 
1782 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1783 
1784 	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
1785 		PLTFM_MSG_TRACE("[TRACE]Wait event(send_scan)\n");
1786 		return HALMAC_RET_BUSY_STATE;
1787 	}
1788 
1789 	*proc_status = HALMAC_CMD_PROCESS_SENDING;
1790 
1791 	status = send_h2c_send_scan_packet_88xx(adapter, index, pkt, size);
1792 	if (status != HALMAC_RET_SUCCESS)
1793 		return status;
1794 
1795 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1796 
1797 	return HALMAC_RET_SUCCESS;
1798 }
1799 
1800 static enum halmac_ret_status
send_h2c_send_scan_packet_88xx(struct halmac_adapter * adapter,u8 index,u8 * pkt,u32 size)1801 send_h2c_send_scan_packet_88xx(struct halmac_adapter *adapter,
1802 			       u8 index, u8 *pkt, u32 size)
1803 {
1804 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1805 	u16 seq_num = 0;
1806 	u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
1807 	u16 pg_offset;
1808 	struct halmac_h2c_header_info hdr_info;
1809 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1810 
1811 	status = dl_rsvd_page_88xx(adapter, pg_addr, pkt, size);
1812 	if (status != HALMAC_RET_SUCCESS) {
1813 		PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
1814 		return status;
1815 	}
1816 
1817 	pg_offset = pg_addr - adapter->txff_alloc.rsvd_boundary;
1818 	SEND_SCAN_PKT_SET_SIZE(h2c_buf, size +
1819 			       adapter->hw_cfg_info.txdesc_size);
1820 	SEND_SCAN_PKT_SET_INDEX(h2c_buf, index);
1821 	SEND_SCAN_PKT_SET_LOC(h2c_buf, pg_offset);
1822 
1823 	hdr_info.sub_cmd_id = SUB_CMD_ID_SEND_SCAN_PKT;
1824 	hdr_info.content_size = 8;
1825 	hdr_info.ack = 1;
1826 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1827 	adapter->halmac_state.scan_pkt_state.seq_num = seq_num;
1828 
1829 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
1830 
1831 	if (status != HALMAC_RET_SUCCESS) {
1832 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1833 		reset_ofld_feature_88xx(adapter,
1834 					HALMAC_FEATURE_SEND_SCAN_PACKET);
1835 		return status;
1836 	}
1837 
1838 	return status;
1839 }
1840 
1841 enum halmac_ret_status
drop_scan_packet_88xx(struct halmac_adapter * adapter,struct halmac_drop_pkt_option * option)1842 drop_scan_packet_88xx(struct halmac_adapter *adapter,
1843 		      struct halmac_drop_pkt_option *option)
1844 {
1845 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1846 	enum halmac_cmd_process_status *proc_status =
1847 		&adapter->halmac_state.drop_pkt_state.proc_status;
1848 
1849 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1850 		return HALMAC_RET_NO_DLFW;
1851 
1852 	if (adapter->fw_ver.h2c_version < 13)
1853 		return HALMAC_RET_FW_NO_SUPPORT;
1854 
1855 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1856 
1857 	if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
1858 		PLTFM_MSG_TRACE("[TRACE]Wait event(drop_scan)\n");
1859 		return HALMAC_RET_BUSY_STATE;
1860 	}
1861 
1862 	*proc_status = HALMAC_CMD_PROCESS_SENDING;
1863 
1864 	status = send_h2c_drop_scan_packet_88xx(adapter, option);
1865 	if (status != HALMAC_RET_SUCCESS)
1866 		return status;
1867 
1868 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1869 
1870 	return HALMAC_RET_SUCCESS;
1871 }
1872 
1873 static enum halmac_ret_status
send_h2c_drop_scan_packet_88xx(struct halmac_adapter * adapter,struct halmac_drop_pkt_option * option)1874 send_h2c_drop_scan_packet_88xx(struct halmac_adapter *adapter,
1875 			       struct halmac_drop_pkt_option *option)
1876 {
1877 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1878 	u16 seq_num = 0;
1879 	struct halmac_h2c_header_info hdr_info;
1880 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1881 
1882 	PLTFM_MSG_TRACE("[TRACE]%s\n", __func__);
1883 
1884 	DROP_SCAN_PKT_SET_DROP_ALL(h2c_buf, option->drop_all);
1885 	DROP_SCAN_PKT_SET_DROP_SINGLE(h2c_buf, option->drop_single);
1886 	DROP_SCAN_PKT_SET_DROP_IDX(h2c_buf, option->drop_index);
1887 
1888 	hdr_info.sub_cmd_id = SUB_CMD_ID_DROP_SCAN_PKT;
1889 	hdr_info.content_size = 8;
1890 	hdr_info.ack = 1;
1891 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1892 	adapter->halmac_state.drop_pkt_state.seq_num = seq_num;
1893 
1894 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
1895 
1896 	if (status != HALMAC_RET_SUCCESS) {
1897 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1898 		reset_ofld_feature_88xx(adapter,
1899 					HALMAC_FEATURE_DROP_SCAN_PACKET);
1900 		return status;
1901 	}
1902 
1903 	return status;
1904 }
1905 
1906 enum halmac_ret_status
bcn_ie_filter_88xx(struct halmac_adapter * adapter,struct halmac_bcn_ie_info * info)1907 bcn_ie_filter_88xx(struct halmac_adapter *adapter,
1908 		   struct halmac_bcn_ie_info *info)
1909 {
1910 	return HALMAC_RET_NOT_SUPPORT;
1911 }
1912 
1913 enum halmac_ret_status
update_datapack_88xx(struct halmac_adapter * adapter,enum halmac_data_type data_type,struct halmac_phy_parameter_info * info)1914 update_datapack_88xx(struct halmac_adapter *adapter,
1915 		     enum halmac_data_type data_type,
1916 		     struct halmac_phy_parameter_info *info)
1917 {
1918 	return HALMAC_RET_NOT_SUPPORT;
1919 }
1920 
1921 enum halmac_ret_status
run_datapack_88xx(struct halmac_adapter * adapter,enum halmac_data_type data_type)1922 run_datapack_88xx(struct halmac_adapter *adapter,
1923 		  enum halmac_data_type data_type)
1924 {
1925 	return HALMAC_RET_NOT_SUPPORT;
1926 }
1927 
1928 enum halmac_ret_status
send_bt_coex_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size,u8 ack)1929 send_bt_coex_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size, u8 ack)
1930 {
1931 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1932 
1933 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
1934 		return HALMAC_RET_NO_DLFW;
1935 
1936 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1937 
1938 	status = send_bt_coex_cmd_88xx(adapter, buf, size, ack);
1939 
1940 	if (status != HALMAC_RET_SUCCESS) {
1941 		PLTFM_MSG_ERR("[ERR]bt coex cmd!!\n");
1942 		return status;
1943 	}
1944 
1945 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
1946 
1947 	return HALMAC_RET_SUCCESS;
1948 }
1949 
1950 static enum halmac_ret_status
send_bt_coex_cmd_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size,u8 ack)1951 send_bt_coex_cmd_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size,
1952 		      u8 ack)
1953 {
1954 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1955 	u16 seq_num = 0;
1956 	struct halmac_h2c_header_info hdr_info;
1957 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1958 
1959 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
1960 
1961 	PLTFM_MEMCPY(h2c_buf + 8, buf, size);
1962 
1963 	hdr_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
1964 	hdr_info.content_size = (u16)size;
1965 	hdr_info.ack = ack;
1966 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1967 
1968 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
1969 
1970 	if (status != HALMAC_RET_SUCCESS) {
1971 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
1972 		return status;
1973 	}
1974 
1975 	return HALMAC_RET_SUCCESS;
1976 }
1977 
1978 /**
1979  * dump_fifo_88xx() - dump fifo data
1980  * @adapter : the adapter of halmac
1981  * @sel : FIFO selection
1982  * @start_addr : start address of selected FIFO
1983  * @size : dump size of selected FIFO
1984  * @data : FIFO data
1985  *
1986  * Note : before dump fifo, user need to call halmac_get_fifo_size to
1987  * get fifo size. Then input this size to halmac_dump_fifo.
1988  *
1989  * Author : Ivan Lin/KaiYuan Chang
1990  * Return : enum halmac_ret_status
1991  * More details of status code can be found in prototype document
1992  */
1993 enum halmac_ret_status
dump_fifo_88xx(struct halmac_adapter * adapter,enum hal_fifo_sel sel,u32 start_addr,u32 size,u8 * data)1994 dump_fifo_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel,
1995 	       u32 start_addr, u32 size, u8 *data)
1996 {
1997 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1998 	u8 tmp8;
1999 	u8 enable;
2000 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2001 
2002 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2003 
2004 	if (sel == HAL_FIFO_SEL_TX &&
2005 	    (start_addr + size) > adapter->hw_cfg_info.tx_fifo_size) {
2006 		PLTFM_MSG_ERR("[ERR]size overflow!!\n");
2007 		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
2008 	}
2009 
2010 	if (sel == HAL_FIFO_SEL_RX &&
2011 	    (start_addr + size) > adapter->hw_cfg_info.rx_fifo_size) {
2012 		PLTFM_MSG_ERR("[ERR]size overflow!!\n");
2013 		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
2014 	}
2015 
2016 	if ((size & (4 - 1)) != 0) {
2017 		PLTFM_MSG_ERR("[ERR]not 4byte alignment!!\n");
2018 		return HALMAC_RET_DUMP_FIFOSIZE_INCORRECT;
2019 	}
2020 
2021 	if (!data)
2022 		return HALMAC_RET_NULL_POINTER;
2023 
2024 	tmp8 = HALMAC_REG_R8(REG_RCR + 2);
2025 	enable = 0;
2026 	status = api->halmac_set_hw_value(adapter, HALMAC_HW_RX_CLK_GATE,
2027 					  &enable);
2028 	if (status != HALMAC_RET_SUCCESS)
2029 		return status;
2030 	status = read_buf_88xx(adapter, start_addr, size, sel, data);
2031 
2032 	HALMAC_REG_W8(REG_RCR + 2, tmp8);
2033 
2034 	if (status != HALMAC_RET_SUCCESS) {
2035 		PLTFM_MSG_ERR("[ERR]read buf!!\n");
2036 		return status;
2037 	}
2038 
2039 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2040 
2041 	return HALMAC_RET_SUCCESS;
2042 }
2043 
2044 static enum halmac_ret_status
read_buf_88xx(struct halmac_adapter * adapter,u32 offset,u32 size,enum hal_fifo_sel sel,u8 * data)2045 read_buf_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
2046 	      enum hal_fifo_sel sel, u8 *data)
2047 {
2048 	u32 start_pg;
2049 	u32 value32;
2050 	u32 i;
2051 	u32 residue;
2052 	u32 cnt = 0;
2053 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2054 
2055 	if (sel == HAL_FIFO_SEL_RSVD_PAGE)
2056 		offset += (adapter->txff_alloc.rsvd_boundary <<
2057 			   TX_PAGE_SIZE_SHIFT_88XX);
2058 
2059 	start_pg = offset >> 12;
2060 	residue = offset & (4096 - 1);
2061 
2062 	if (sel == HAL_FIFO_SEL_TX || sel == HAL_FIFO_SEL_RSVD_PAGE)
2063 		start_pg += 0x780;
2064 	else if (sel == HAL_FIFO_SEL_RX)
2065 		start_pg += 0x700;
2066 	else if (sel == HAL_FIFO_SEL_REPORT)
2067 		start_pg += 0x660;
2068 	else if (sel == HAL_FIFO_SEL_LLT)
2069 		start_pg += 0x650;
2070 	else if (sel == HAL_FIFO_SEL_RXBUF_FW)
2071 		start_pg += 0x680;
2072 	else
2073 		return HALMAC_RET_NOT_SUPPORT;
2074 
2075 	value32 = HALMAC_REG_R16(REG_PKTBUF_DBG_CTRL) & 0xF000;
2076 
2077 	do {
2078 		HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)(start_pg | value32));
2079 
2080 		for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
2081 			*(u32 *)(data + cnt) = HALMAC_REG_R32(i);
2082 			*(u32 *)(data + cnt) =
2083 				rtk_le32_to_cpu(*(u32 *)(data + cnt));
2084 			cnt += 4;
2085 			if (size == cnt)
2086 				goto HALMAC_BUF_READ_OK;
2087 		}
2088 
2089 		residue = 0;
2090 		start_pg++;
2091 	} while (1);
2092 
2093 HALMAC_BUF_READ_OK:
2094 	HALMAC_REG_W16(REG_PKTBUF_DBG_CTRL, (u16)value32);
2095 
2096 	return HALMAC_RET_SUCCESS;
2097 }
2098 
2099 /**
2100  * get_fifo_size_88xx() - get fifo size
2101  * @adapter : the adapter of halmac
2102  * @sel : FIFO selection
2103  * Author : Ivan Lin/KaiYuan Chang
2104  * Return : u32
2105  * More details of status code can be found in prototype document
2106  */
2107 u32
get_fifo_size_88xx(struct halmac_adapter * adapter,enum hal_fifo_sel sel)2108 get_fifo_size_88xx(struct halmac_adapter *adapter, enum hal_fifo_sel sel)
2109 {
2110 	u32 size = 0;
2111 
2112 	if (sel == HAL_FIFO_SEL_TX)
2113 		size = adapter->hw_cfg_info.tx_fifo_size;
2114 	else if (sel == HAL_FIFO_SEL_RX)
2115 		size = adapter->hw_cfg_info.rx_fifo_size;
2116 	else if (sel == HAL_FIFO_SEL_RSVD_PAGE)
2117 		size = adapter->hw_cfg_info.tx_fifo_size -
2118 		       (adapter->txff_alloc.rsvd_boundary <<
2119 			TX_PAGE_SIZE_SHIFT_88XX);
2120 	else if (sel == HAL_FIFO_SEL_REPORT)
2121 		size = 65536;
2122 	else if (sel == HAL_FIFO_SEL_LLT)
2123 		size = 65536;
2124 	else if (sel == HAL_FIFO_SEL_RXBUF_FW)
2125 		size = RX_BUF_FW_88XX;
2126 
2127 	return size;
2128 }
2129 
2130 enum halmac_ret_status
set_h2c_header_88xx(struct halmac_adapter * adapter,u8 * hdr,u16 * seq,u8 ack)2131 set_h2c_header_88xx(struct halmac_adapter *adapter, u8 *hdr, u16 *seq, u8 ack)
2132 {
2133 	PLTFM_MSG_TRACE("[TRACE]%s!!\n", __func__);
2134 
2135 	H2C_CMD_HEADER_SET_CATEGORY(hdr, 0x00);
2136 	H2C_CMD_HEADER_SET_TOTAL_LEN(hdr, 16);
2137 
2138 	PLTFM_MUTEX_LOCK(&adapter->h2c_seq_mutex);
2139 	H2C_CMD_HEADER_SET_SEQ_NUM(hdr, adapter->h2c_info.seq_num);
2140 	*seq = adapter->h2c_info.seq_num;
2141 	(adapter->h2c_info.seq_num)++;
2142 	PLTFM_MUTEX_UNLOCK(&adapter->h2c_seq_mutex);
2143 
2144 	if (ack == 1)
2145 		H2C_CMD_HEADER_SET_ACK(hdr, 1);
2146 
2147 	return HALMAC_RET_SUCCESS;
2148 }
2149 
2150 /**
2151  * add_ch_info_88xx() -add channel information
2152  * @adapter : the adapter of halmac
2153  * @info : channel information
2154  * Author : KaiYuan Chang/Ivan Lin
2155  * Return : enum halmac_ret_status
2156  * More details of status code can be found in prototype document
2157  */
2158 enum halmac_ret_status
add_ch_info_88xx(struct halmac_adapter * adapter,struct halmac_ch_info * info)2159 add_ch_info_88xx(struct halmac_adapter *adapter, struct halmac_ch_info *info)
2160 {
2161 	struct halmac_ch_sw_info *ch_sw_info = &adapter->ch_sw_info;
2162 	enum halmac_cmd_construct_state state;
2163 
2164 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2165 
2166 	if (adapter->halmac_state.dlfw_state != HALMAC_GEN_INFO_SENT) {
2167 		PLTFM_MSG_ERR("[ERR]gen info\n");
2168 		return HALMAC_RET_GEN_INFO_NOT_SENT;
2169 	}
2170 
2171 	state = scan_cmd_cnstr_state_88xx(adapter);
2172 	if (state != HALMAC_CMD_CNSTR_BUF_CLR &&
2173 	    state != HALMAC_CMD_CNSTR_CNSTR) {
2174 		PLTFM_MSG_WARN("[WARN]cmd state (scan)\n");
2175 		return HALMAC_RET_ERROR_STATE;
2176 	}
2177 
2178 	if (!ch_sw_info->buf) {
2179 		ch_sw_info->buf = (u8 *)PLTFM_MALLOC(SCAN_INFO_RSVDPG_SIZE);
2180 		if (!ch_sw_info->buf)
2181 			return HALMAC_RET_NULL_POINTER;
2182 		ch_sw_info->buf_wptr = ch_sw_info->buf;
2183 		ch_sw_info->buf_size = SCAN_INFO_RSVDPG_SIZE;
2184 		ch_sw_info->avl_buf_size = SCAN_INFO_RSVDPG_SIZE;
2185 		ch_sw_info->total_size = 0;
2186 		ch_sw_info->extra_info_en = 0;
2187 		ch_sw_info->ch_num = 0;
2188 	}
2189 
2190 	if (ch_sw_info->extra_info_en == 1) {
2191 		PLTFM_MSG_ERR("[ERR]extra info = 1!!\n");
2192 		return HALMAC_RET_CH_SW_SEQ_WRONG;
2193 	}
2194 
2195 	if (ch_sw_info->avl_buf_size < 4) {
2196 		PLTFM_MSG_ERR("[ERR]buf full!!\n");
2197 		return HALMAC_RET_CH_SW_NO_BUF;
2198 	}
2199 
2200 	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
2201 	    HALMAC_RET_SUCCESS)
2202 		return HALMAC_RET_ERROR_STATE;
2203 
2204 	CH_INFO_SET_CH(ch_sw_info->buf_wptr, info->channel);
2205 	CH_INFO_SET_PRI_CH_IDX(ch_sw_info->buf_wptr, info->pri_ch_idx);
2206 	CH_INFO_SET_BW(ch_sw_info->buf_wptr, info->bw);
2207 	CH_INFO_SET_TIMEOUT(ch_sw_info->buf_wptr, info->timeout);
2208 	CH_INFO_SET_ACTION_ID(ch_sw_info->buf_wptr, info->action_id);
2209 	CH_INFO_SET_EXTRA_INFO(ch_sw_info->buf_wptr, info->extra_info);
2210 
2211 	ch_sw_info->avl_buf_size = ch_sw_info->avl_buf_size - 4;
2212 	ch_sw_info->total_size = ch_sw_info->total_size + 4;
2213 	ch_sw_info->ch_num++;
2214 	ch_sw_info->extra_info_en = info->extra_info;
2215 	ch_sw_info->buf_wptr = ch_sw_info->buf_wptr + 4;
2216 
2217 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2218 
2219 	return HALMAC_RET_SUCCESS;
2220 }
2221 
2222 static enum halmac_cmd_construct_state
scan_cmd_cnstr_state_88xx(struct halmac_adapter * adapter)2223 scan_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
2224 {
2225 	return adapter->halmac_state.scan_state.cmd_cnstr_state;
2226 }
2227 
2228 static enum halmac_ret_status
cnv_scan_state_88xx(struct halmac_adapter * adapter,enum halmac_cmd_construct_state dest_state)2229 cnv_scan_state_88xx(struct halmac_adapter *adapter,
2230 		    enum halmac_cmd_construct_state dest_state)
2231 {
2232 	enum halmac_cmd_construct_state *state;
2233 
2234 	state = &adapter->halmac_state.scan_state.cmd_cnstr_state;
2235 
2236 	if (dest_state == HALMAC_CMD_CNSTR_IDLE) {
2237 		if ((*state == HALMAC_CMD_CNSTR_BUF_CLR) ||
2238 		    (*state == HALMAC_CMD_CNSTR_CNSTR))
2239 			return HALMAC_RET_ERROR_STATE;
2240 	} else if (dest_state == HALMAC_CMD_CNSTR_BUF_CLR) {
2241 		if (*state == HALMAC_CMD_CNSTR_H2C_SENT)
2242 			return HALMAC_RET_ERROR_STATE;
2243 	} else if (dest_state == HALMAC_CMD_CNSTR_CNSTR) {
2244 		if ((*state == HALMAC_CMD_CNSTR_IDLE) ||
2245 		    (*state == HALMAC_CMD_CNSTR_H2C_SENT))
2246 			return HALMAC_RET_ERROR_STATE;
2247 	} else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
2248 		if ((*state != HALMAC_CMD_CNSTR_CNSTR) &&
2249 		    (*state != HALMAC_CMD_CNSTR_BUF_CLR))
2250 			return HALMAC_RET_ERROR_STATE;
2251 	}
2252 
2253 	*state = dest_state;
2254 
2255 	return HALMAC_RET_SUCCESS;
2256 }
2257 
2258 /**
2259  * add_extra_ch_info_88xx() -add extra channel information
2260  * @adapter : the adapter of halmac
2261  * @info : extra channel information
2262  * Author : KaiYuan Chang/Ivan Lin
2263  * Return : enum halmac_ret_status
2264  * More details of status code can be found in prototype document
2265  */
2266 enum halmac_ret_status
add_extra_ch_info_88xx(struct halmac_adapter * adapter,struct halmac_ch_extra_info * info)2267 add_extra_ch_info_88xx(struct halmac_adapter *adapter,
2268 		       struct halmac_ch_extra_info *info)
2269 {
2270 	struct halmac_ch_sw_info *ch_sw_info = &adapter->ch_sw_info;
2271 
2272 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2273 
2274 	if (!ch_sw_info->buf) {
2275 		PLTFM_MSG_ERR("[ERR]buf = null!!\n");
2276 		return HALMAC_RET_CH_SW_SEQ_WRONG;
2277 	}
2278 
2279 	if (ch_sw_info->extra_info_en == 0) {
2280 		PLTFM_MSG_ERR("[ERR]extra info = 0!!\n");
2281 		return HALMAC_RET_CH_SW_SEQ_WRONG;
2282 	}
2283 
2284 	if (ch_sw_info->avl_buf_size < (u32)(info->extra_info_size + 2)) {
2285 		PLTFM_MSG_ERR("[ERR]no available buffer!!\n");
2286 		return HALMAC_RET_CH_SW_NO_BUF;
2287 	}
2288 
2289 	if (scan_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_CNSTR) {
2290 		PLTFM_MSG_WARN("[WARN]cmd state (ex scan)\n");
2291 		return HALMAC_RET_ERROR_STATE;
2292 	}
2293 
2294 	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_CNSTR) !=
2295 	    HALMAC_RET_SUCCESS)
2296 		return HALMAC_RET_ERROR_STATE;
2297 
2298 	CH_EXTRA_INFO_SET_ID(ch_sw_info->buf_wptr, info->extra_action_id);
2299 	CH_EXTRA_INFO_SET_INFO(ch_sw_info->buf_wptr, info->extra_info);
2300 	CH_EXTRA_INFO_SET_SIZE(ch_sw_info->buf_wptr, info->extra_info_size);
2301 	PLTFM_MEMCPY(ch_sw_info->buf_wptr + 2, info->extra_info_data,
2302 		     info->extra_info_size);
2303 
2304 	ch_sw_info->avl_buf_size -= (2 + info->extra_info_size);
2305 	ch_sw_info->total_size += (2 + info->extra_info_size);
2306 	ch_sw_info->extra_info_en = info->extra_info;
2307 	ch_sw_info->buf_wptr += (2 + info->extra_info_size);
2308 
2309 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2310 
2311 	return HALMAC_RET_SUCCESS;
2312 }
2313 
2314 /**
2315  * ctrl_ch_switch_88xx() -send channel switch cmd
2316  * @adapter : the adapter of halmac
2317  * @opt : channel switch config
2318  * Author : KaiYuan Chang/Ivan Lin
2319  * Return : enum halmac_ret_status
2320  * More details of status code can be found in prototype document
2321  */
2322 enum halmac_ret_status
ctrl_ch_switch_88xx(struct halmac_adapter * adapter,struct halmac_ch_switch_option * opt)2323 ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
2324 		    struct halmac_ch_switch_option *opt)
2325 {
2326 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2327 	enum halmac_cmd_construct_state state;
2328 	enum halmac_cmd_process_status *proc_status;
2329 
2330 	proc_status = &adapter->halmac_state.scan_state.proc_status;
2331 
2332 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
2333 		return HALMAC_RET_NO_DLFW;
2334 
2335 	if (adapter->fw_ver.h2c_version < 4)
2336 		return HALMAC_RET_FW_NO_SUPPORT;
2337 
2338 	if (adapter->ch_sw_info.total_size +
2339 	    (adapter->halmac_state.update_pkt_state.used_page <<
2340 	    TX_PAGE_SIZE_SHIFT_88XX) >
2341 	    (u32)adapter->txff_alloc.rsvd_pg_num << TX_PAGE_SIZE_SHIFT_88XX)
2342 		return HALMAC_RET_RSVD_PG_OVERFLOW_FAIL;
2343 
2344 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2345 
2346 	if (opt->switch_en == 0)
2347 		*proc_status = HALMAC_CMD_PROCESS_IDLE;
2348 
2349 	if ((*proc_status == HALMAC_CMD_PROCESS_SENDING) ||
2350 	    (*proc_status == HALMAC_CMD_PROCESS_RCVD)) {
2351 		PLTFM_MSG_TRACE("[TRACE]Wait event(scan)\n");
2352 		return HALMAC_RET_BUSY_STATE;
2353 	}
2354 
2355 	state = scan_cmd_cnstr_state_88xx(adapter);
2356 	if (opt->switch_en == 1) {
2357 		if (state != HALMAC_CMD_CNSTR_CNSTR) {
2358 			PLTFM_MSG_ERR("[ERR]state(en = 1)\n");
2359 			return HALMAC_RET_ERROR_STATE;
2360 		}
2361 	} else {
2362 		if (state != HALMAC_CMD_CNSTR_BUF_CLR) {
2363 			PLTFM_MSG_ERR("[ERR]state(en = 0)\n");
2364 			return HALMAC_RET_ERROR_STATE;
2365 		}
2366 	}
2367 
2368 	status = proc_ctrl_ch_switch_88xx(adapter, opt);
2369 	if (status != HALMAC_RET_SUCCESS) {
2370 		PLTFM_MSG_ERR("[ERR]ctrl ch sw!!\n");
2371 		return status;
2372 	}
2373 
2374 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2375 
2376 	return HALMAC_RET_SUCCESS;
2377 }
2378 
2379 static enum halmac_ret_status
proc_ctrl_ch_switch_88xx(struct halmac_adapter * adapter,struct halmac_ch_switch_option * opt)2380 proc_ctrl_ch_switch_88xx(struct halmac_adapter *adapter,
2381 			 struct halmac_ch_switch_option *opt)
2382 {
2383 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
2384 	u16 seq_num = 0;
2385 	u16 pg_addr = adapter->txff_alloc.rsvd_h2c_info_addr;
2386 	struct halmac_h2c_header_info hdr_info;
2387 	struct halmac_scan_rpt_info *scan_rpt_info = &adapter->scan_rpt_info;
2388 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2389 	enum halmac_cmd_process_status *proc_status;
2390 
2391 	proc_status = &adapter->halmac_state.scan_state.proc_status;
2392 
2393 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2394 
2395 	if (adapter->halmac_state.update_pkt_state.used_page > 0 &&
2396 	    opt->nlo_en == 1 && adapter->nlo_flag != 1)
2397 		PLTFM_MSG_WARN("[WARN]probe req is NOT nlo pkt!!\n");
2398 
2399 	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
2400 	    HALMAC_RET_SUCCESS)
2401 		return HALMAC_RET_ERROR_STATE;
2402 
2403 	*proc_status = HALMAC_CMD_PROCESS_SENDING;
2404 
2405 	if (opt->switch_en != 0) {
2406 		pg_addr += adapter->halmac_state.update_pkt_state.used_page;
2407 		status = dl_rsvd_page_88xx(adapter, pg_addr,
2408 					   adapter->ch_sw_info.buf,
2409 					   adapter->ch_sw_info.total_size);
2410 		if (status != HALMAC_RET_SUCCESS) {
2411 			PLTFM_MSG_ERR("[ERR]dl rsvd pg!!\n");
2412 			return status;
2413 		}
2414 		adapter->halmac_state.update_pkt_state.used_page = 0;
2415 	}
2416 
2417 	CH_SWITCH_SET_START(h2c_buf, opt->switch_en);
2418 	CH_SWITCH_SET_CH_NUM(h2c_buf, adapter->ch_sw_info.ch_num);
2419 	CH_SWITCH_SET_INFO_LOC(h2c_buf,
2420 			       pg_addr - adapter->txff_alloc.rsvd_boundary);
2421 	CH_SWITCH_SET_DEST_CH_EN(h2c_buf, opt->dest_ch_en);
2422 	CH_SWITCH_SET_DEST_CH(h2c_buf, opt->dest_ch);
2423 	CH_SWITCH_SET_PRI_CH_IDX(h2c_buf, opt->dest_pri_ch_idx);
2424 	CH_SWITCH_SET_ABSOLUTE_TIME(h2c_buf, opt->absolute_time_en);
2425 	CH_SWITCH_SET_TSF_LOW(h2c_buf, opt->tsf_low);
2426 	CH_SWITCH_SET_PERIODIC_OPT(h2c_buf, opt->periodic_option);
2427 	CH_SWITCH_SET_NORMAL_CYCLE(h2c_buf, opt->normal_cycle);
2428 	CH_SWITCH_SET_NORMAL_PERIOD(h2c_buf, opt->normal_period);
2429 	CH_SWITCH_SET_SLOW_PERIOD(h2c_buf, opt->phase_2_period);
2430 	CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_buf, opt->normal_period_sel);
2431 	CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_buf, opt->phase_2_period_sel);
2432 	CH_SWITCH_SET_SCAN_MODE(h2c_buf, opt->scan_mode_en);
2433 	CH_SWITCH_SET_INFO_SIZE(h2c_buf, adapter->ch_sw_info.total_size);
2434 
2435 	hdr_info.sub_cmd_id = SUB_CMD_ID_CH_SWITCH;
2436 	hdr_info.content_size = 20;
2437 	if (opt->nlo_en == 1)
2438 		hdr_info.ack = 0;
2439 	else
2440 		hdr_info.ack = 1;
2441 
2442 	if (opt->scan_mode_en == 1) {
2443 		adapter->ch_sw_info.scan_mode = 1;
2444 		if (!scan_rpt_info->buf) {
2445 			scan_rpt_info->buf =
2446 				(u8 *)PLTFM_MALLOC(SCAN_INFO_RSVDPG_SIZE);
2447 			if (!scan_rpt_info->buf)
2448 				return HALMAC_RET_NULL_POINTER;
2449 		} else {
2450 			PLTFM_MEMSET(scan_rpt_info->buf, 0,
2451 				     SCAN_INFO_RSVDPG_SIZE);
2452 		}
2453 		scan_rpt_info->buf_wptr = scan_rpt_info->buf;
2454 		scan_rpt_info->buf_size = SCAN_INFO_RSVDPG_SIZE;
2455 		scan_rpt_info->avl_buf_size = SCAN_INFO_RSVDPG_SIZE;
2456 		scan_rpt_info->total_size = 0;
2457 		scan_rpt_info->ack_tsf_high = 0;
2458 		scan_rpt_info->ack_tsf_low = 0;
2459 		scan_rpt_info->rpt_tsf_high = 0;
2460 		scan_rpt_info->rpt_tsf_low = 0;
2461 	} else {
2462 		adapter->ch_sw_info.scan_mode = 0;
2463 		if (!scan_rpt_info->buf)
2464 			PLTFM_FREE(scan_rpt_info->buf, scan_rpt_info->buf_size);
2465 		scan_rpt_info->buf_wptr = NULL;
2466 		scan_rpt_info->buf_size = 0;
2467 		scan_rpt_info->avl_buf_size = 0;
2468 		scan_rpt_info->total_size = 0;
2469 	}
2470 
2471 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
2472 	adapter->halmac_state.scan_state.seq_num = seq_num;
2473 
2474 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
2475 
2476 	if (status != HALMAC_RET_SUCCESS) {
2477 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
2478 		reset_ofld_feature_88xx(adapter, HALMAC_FEATURE_CHANNEL_SWITCH);
2479 	}
2480 	PLTFM_FREE(adapter->ch_sw_info.buf, adapter->ch_sw_info.buf_size);
2481 	adapter->ch_sw_info.buf = NULL;
2482 	adapter->ch_sw_info.buf_wptr = NULL;
2483 	adapter->ch_sw_info.extra_info_en = 0;
2484 	adapter->ch_sw_info.buf_size = 0;
2485 	adapter->ch_sw_info.avl_buf_size = 0;
2486 	adapter->ch_sw_info.total_size = 0;
2487 	adapter->ch_sw_info.ch_num = 0;
2488 
2489 	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
2490 	    HALMAC_RET_SUCCESS)
2491 		return HALMAC_RET_ERROR_STATE;
2492 
2493 	adapter->nlo_flag = 0;
2494 
2495 	return status;
2496 }
2497 
2498 /**
2499  * clear_ch_info_88xx() -clear channel information
2500  * @adapter : the adapter of halmac
2501  * Author : KaiYuan Chang/Ivan Lin
2502  * Return : enum halmac_ret_status
2503  * More details of status code can be found in prototype document
2504  */
2505 enum halmac_ret_status
clear_ch_info_88xx(struct halmac_adapter * adapter)2506 clear_ch_info_88xx(struct halmac_adapter *adapter)
2507 {
2508 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2509 
2510 	if (scan_cmd_cnstr_state_88xx(adapter) == HALMAC_CMD_CNSTR_H2C_SENT) {
2511 		PLTFM_MSG_WARN("[WARN]state(clear)\n");
2512 		return HALMAC_RET_ERROR_STATE;
2513 	}
2514 
2515 	if (cnv_scan_state_88xx(adapter, HALMAC_CMD_CNSTR_BUF_CLR) !=
2516 	    HALMAC_RET_SUCCESS)
2517 		return HALMAC_RET_ERROR_STATE;
2518 
2519 	PLTFM_FREE(adapter->ch_sw_info.buf, adapter->ch_sw_info.buf_size);
2520 	adapter->ch_sw_info.buf = NULL;
2521 	adapter->ch_sw_info.buf_wptr = NULL;
2522 	adapter->ch_sw_info.extra_info_en = 0;
2523 	adapter->ch_sw_info.buf_size = 0;
2524 	adapter->ch_sw_info.avl_buf_size = 0;
2525 	adapter->ch_sw_info.total_size = 0;
2526 	adapter->ch_sw_info.ch_num = 0;
2527 
2528 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2529 
2530 	return HALMAC_RET_SUCCESS;
2531 }
2532 
2533 /**
2534  * chk_txdesc_88xx() -check if the tx packet format is incorrect
2535  * @adapter : the adapter of halmac
2536  * @buf : tx Packet buffer, tx desc is included
2537  * @size : tx packet size
2538  * Author : KaiYuan Chang
2539  * Return : enum halmac_ret_status
2540  * More details of status code can be found in prototype document
2541  */
2542 enum halmac_ret_status
chk_txdesc_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)2543 chk_txdesc_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
2544 {
2545 	u32 mac_clk = 0;
2546 	u8 value8;
2547 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2548 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
2549 
2550 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2551 
2552 	if (GET_TX_DESC_BMC(buf) == 1 && GET_TX_DESC_AGG_EN(buf) == 1)
2553 		PLTFM_MSG_ERR("[ERR]txdesc - agg + bmc\n");
2554 
2555 	if (size < (GET_TX_DESC_TXPKTSIZE(buf) +
2556 		    adapter->hw_cfg_info.txdesc_size +
2557 		    (GET_TX_DESC_PKT_OFFSET(buf) << 3))) {
2558 		PLTFM_MSG_ERR("[ERR]txdesc - total size\n");
2559 		status = HALMAC_RET_TXDESC_SET_FAIL;
2560 	}
2561 
2562 	if (wlhdr_valid_88xx(adapter, buf) != HALMAC_RET_SUCCESS) {
2563 		PLTFM_MSG_ERR("[ERR]wlhdr\n");
2564 		status = HALMAC_RET_WLHDR_FAIL;
2565 	}
2566 
2567 	if (GET_TX_DESC_AMSDU_PAD_EN(buf) != 0) {
2568 		PLTFM_MSG_ERR("[ERR]txdesc - amsdu_pad\n");
2569 		status = HALMAC_RET_TXDESC_SET_FAIL;
2570 	}
2571 
2572 	if (GET_TX_DESC_USE_MAX_TIME_EN(buf) == 1) {
2573 		value8 = (u8)GET_TX_DESC_AMPDU_MAX_TIME(buf);
2574 		if (value8 > HALMAC_REG_R8(REG_AMPDU_MAX_TIME_V1)) {
2575 			PLTFM_MSG_ERR("[ERR]txdesc - ampdu_max_time\n");
2576 			status = HALMAC_RET_TXDESC_SET_FAIL;
2577 		}
2578 	}
2579 
2580 	switch (BIT_GET_MAC_CLK_SEL(HALMAC_REG_R32(REG_AFE_CTRL1))) {
2581 	case 0x0:
2582 		mac_clk = 80;
2583 		break;
2584 	case 0x1:
2585 		mac_clk = 40;
2586 		break;
2587 	case 0x2:
2588 		mac_clk = 20;
2589 		break;
2590 	case 0x3:
2591 		mac_clk = 10;
2592 		break;
2593 	}
2594 
2595 	PLTFM_MSG_ALWAYS("MAC clock : 0x%XM\n", mac_clk);
2596 	PLTFM_MSG_ALWAYS("mac agg en : 0x%X\n", GET_TX_DESC_AGG_EN(buf));
2597 	PLTFM_MSG_ALWAYS("mac agg num : 0x%X\n", GET_TX_DESC_MAX_AGG_NUM(buf));
2598 
2599 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2600 
2601 	return status;
2602 }
2603 
2604 static enum halmac_ret_status
wlhdr_valid_88xx(struct halmac_adapter * adapter,u8 * buf)2605 wlhdr_valid_88xx(struct halmac_adapter *adapter, u8 *buf)
2606 {
2607 	u32 txdesc_size = adapter->hw_cfg_info.txdesc_size +
2608 						GET_TX_DESC_PKT_OFFSET(buf);
2609 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2610 	struct wlhdr_frame_ctrl *wlhdr;
2611 
2612 	wlhdr = (struct wlhdr_frame_ctrl *)(buf + txdesc_size);
2613 
2614 	if (wlhdr->protocol != WLHDR_PROT_VER) {
2615 		PLTFM_MSG_ERR("[ERR]prot ver!!\n");
2616 		return HALMAC_RET_WLHDR_FAIL;
2617 	}
2618 
2619 	switch (wlhdr->type) {
2620 	case WLHDR_TYPE_MGMT:
2621 		if (wlhdr_mgmt_valid_88xx(adapter, wlhdr) != 1)
2622 			status = HALMAC_RET_WLHDR_FAIL;
2623 		break;
2624 	case WLHDR_TYPE_CTRL:
2625 		if (wlhdr_ctrl_valid_88xx(adapter, wlhdr) != 1)
2626 			status = HALMAC_RET_WLHDR_FAIL;
2627 		break;
2628 	case WLHDR_TYPE_DATA:
2629 		if (wlhdr_data_valid_88xx(adapter, wlhdr) != 1)
2630 			status = HALMAC_RET_WLHDR_FAIL;
2631 		break;
2632 	default:
2633 		PLTFM_MSG_ERR("[ERR]undefined type!!\n");
2634 		status = HALMAC_RET_WLHDR_FAIL;
2635 		break;
2636 	}
2637 
2638 	return status;
2639 }
2640 
2641 static u8
wlhdr_mgmt_valid_88xx(struct halmac_adapter * adapter,struct wlhdr_frame_ctrl * wlhdr)2642 wlhdr_mgmt_valid_88xx(struct halmac_adapter *adapter,
2643 		      struct wlhdr_frame_ctrl *wlhdr)
2644 {
2645 	u8 state;
2646 
2647 	switch (wlhdr->sub_type) {
2648 	case WLHDR_SUB_TYPE_ASSOC_REQ:
2649 	case WLHDR_SUB_TYPE_ASSOC_RSPNS:
2650 	case WLHDR_SUB_TYPE_REASSOC_REQ:
2651 	case WLHDR_SUB_TYPE_REASSOC_RSPNS:
2652 	case WLHDR_SUB_TYPE_PROBE_REQ:
2653 	case WLHDR_SUB_TYPE_PROBE_RSPNS:
2654 	case WLHDR_SUB_TYPE_BCN:
2655 	case WLHDR_SUB_TYPE_DISASSOC:
2656 	case WLHDR_SUB_TYPE_AUTH:
2657 	case WLHDR_SUB_TYPE_DEAUTH:
2658 	case WLHDR_SUB_TYPE_ACTION:
2659 	case WLHDR_SUB_TYPE_ACTION_NOACK:
2660 		state = 1;
2661 		break;
2662 	default:
2663 		PLTFM_MSG_ERR("[ERR]mgmt invalid!!\n");
2664 		state = 0;
2665 		break;
2666 	}
2667 
2668 	return state;
2669 }
2670 
2671 static u8
wlhdr_ctrl_valid_88xx(struct halmac_adapter * adapter,struct wlhdr_frame_ctrl * wlhdr)2672 wlhdr_ctrl_valid_88xx(struct halmac_adapter *adapter,
2673 		      struct wlhdr_frame_ctrl *wlhdr)
2674 {
2675 	u8 state;
2676 
2677 	switch (wlhdr->sub_type) {
2678 	case WLHDR_SUB_TYPE_BF_RPT_POLL:
2679 	case WLHDR_SUB_TYPE_NDPA:
2680 		state = 1;
2681 		break;
2682 	default:
2683 		PLTFM_MSG_ERR("[ERR]ctrl invalid!!\n");
2684 		state = 0;
2685 		break;
2686 	}
2687 
2688 	return state;
2689 }
2690 
2691 static u8
wlhdr_data_valid_88xx(struct halmac_adapter * adapter,struct wlhdr_frame_ctrl * wlhdr)2692 wlhdr_data_valid_88xx(struct halmac_adapter *adapter,
2693 		      struct wlhdr_frame_ctrl *wlhdr)
2694 {
2695 	u8 state;
2696 
2697 	switch (wlhdr->sub_type) {
2698 	case WLHDR_SUB_TYPE_DATA:
2699 	case WLHDR_SUB_TYPE_NULL:
2700 	case WLHDR_SUB_TYPE_QOS_DATA:
2701 	case WLHDR_SUB_TYPE_QOS_NULL:
2702 		state = 1;
2703 		break;
2704 	default:
2705 		PLTFM_MSG_ERR("[ERR]data invalid!!\n");
2706 		state = 0;
2707 		break;
2708 	}
2709 
2710 	return state;
2711 }
2712 
2713 /**
2714  * get_version_88xx() - get HALMAC version
2715  * @ver : return version of major, prototype, minor and patch information
2716  * Author : KaiYuan Chang / Ivan Lin
2717  * Return : enum halmac_ret_status
2718  * More details of status code can be found in prototype document
2719  */
2720 enum halmac_ret_status
get_version_88xx(struct halmac_adapter * adapter,struct halmac_ver * ver)2721 get_version_88xx(struct halmac_adapter *adapter, struct halmac_ver *ver)
2722 {
2723 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2724 
2725 	ver->major_ver = (u8)HALMAC_MAJOR_VER;
2726 	ver->prototype_ver = (u8)HALMAC_PROTOTYPE_VER;
2727 	ver->minor_ver = (u8)HALMAC_MINOR_VER;
2728 	ver->patch_ver = (u8)HALMAC_PATCH_VER;
2729 
2730 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2731 
2732 	return HALMAC_RET_SUCCESS;
2733 }
2734 
2735 enum halmac_ret_status
p2pps_88xx(struct halmac_adapter * adapter,struct halmac_p2pps * info)2736 p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info)
2737 {
2738 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2739 
2740 	if (halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
2741 		return HALMAC_RET_NO_DLFW;
2742 
2743 	if (adapter->fw_ver.h2c_version < 6)
2744 		return HALMAC_RET_FW_NO_SUPPORT;
2745 
2746 	status = proc_p2pps_88xx(adapter, info);
2747 	if (status != HALMAC_RET_SUCCESS) {
2748 		PLTFM_MSG_ERR("[ERR]p2pps!!\n");
2749 		return status;
2750 	}
2751 
2752 	return HALMAC_RET_SUCCESS;
2753 }
2754 
2755 static enum halmac_ret_status
proc_p2pps_88xx(struct halmac_adapter * adapter,struct halmac_p2pps * info)2756 proc_p2pps_88xx(struct halmac_adapter *adapter, struct halmac_p2pps *info)
2757 {
2758 	u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
2759 	u16 seq_num = 0;
2760 	struct halmac_h2c_header_info hdr_info;
2761 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2762 
2763 	P2PPS_SET_OFFLOAD_EN(h2c_buf, info->offload_en);
2764 	P2PPS_SET_ROLE(h2c_buf, info->role);
2765 	P2PPS_SET_CTWINDOW_EN(h2c_buf, info->ctwindow_en);
2766 	P2PPS_SET_NOA_EN(h2c_buf, info->noa_en);
2767 	P2PPS_SET_NOA_SEL(h2c_buf, info->noa_sel);
2768 	P2PPS_SET_ALLSTASLEEP(h2c_buf, info->all_sta_sleep);
2769 	P2PPS_SET_DISCOVERY(h2c_buf, info->discovery);
2770 	P2PPS_SET_DISABLE_CLOSERF(h2c_buf, info->disable_close_rf);
2771 	P2PPS_SET_P2P_PORT_ID(h2c_buf, info->p2p_port_id);
2772 	P2PPS_SET_P2P_GROUP(h2c_buf, info->p2p_group);
2773 	P2PPS_SET_P2P_MACID(h2c_buf, info->p2p_macid);
2774 
2775 	P2PPS_SET_CTWINDOW_LENGTH(h2c_buf, info->ctwindow_length);
2776 
2777 	P2PPS_SET_NOA_DURATION_PARA(h2c_buf, info->noa_duration_para);
2778 	P2PPS_SET_NOA_INTERVAL_PARA(h2c_buf, info->noa_interval_para);
2779 	P2PPS_SET_NOA_START_TIME_PARA(h2c_buf, info->noa_start_time_para);
2780 	P2PPS_SET_NOA_COUNT_PARA(h2c_buf, info->noa_count_para);
2781 
2782 	hdr_info.sub_cmd_id = SUB_CMD_ID_P2PPS;
2783 	hdr_info.content_size = 24;
2784 	hdr_info.ack = 0;
2785 	set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
2786 
2787 	status = send_h2c_pkt_88xx(adapter, h2c_buf);
2788 
2789 	if (status != HALMAC_RET_SUCCESS)
2790 		PLTFM_MSG_ERR("[ERR]send h2c!!\n");
2791 
2792 	return status;
2793 }
2794 
2795 /**
2796  * query_status_88xx() -query the offload feature status
2797  * @adapter : the adapter of halmac
2798  * @feature_id : feature_id
2799  * @proc_status : feature_status
2800  * @data : data buffer
2801  * @size : data size
2802  *
2803  * Note :
2804  * If user wants to know the data size, user can allocate zero
2805  * size buffer first. If this size less than the data size, halmac
2806  * will return  HALMAC_RET_BUFFER_TOO_SMALL. User need to
2807  * re-allocate data buffer with correct data size.
2808  *
2809  * Author : Ivan Lin/KaiYuan Chang
2810  * Return : enum halmac_ret_status
2811  * More details of status code can be found in prototype document
2812  */
2813 enum halmac_ret_status
query_status_88xx(struct halmac_adapter * adapter,enum halmac_feature_id feature_id,enum halmac_cmd_process_status * proc_status,u8 * data,u32 * size)2814 query_status_88xx(struct halmac_adapter *adapter,
2815 		  enum halmac_feature_id feature_id,
2816 		  enum halmac_cmd_process_status *proc_status, u8 *data,
2817 		  u32 *size)
2818 {
2819 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2820 
2821 	if (!proc_status)
2822 		return HALMAC_RET_NULL_POINTER;
2823 
2824 	switch (feature_id) {
2825 	case HALMAC_FEATURE_CFG_PARA:
2826 		status = get_cfg_param_status_88xx(adapter, proc_status);
2827 		break;
2828 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
2829 		status = get_dump_phy_efuse_status_88xx(adapter, proc_status,
2830 							data, size);
2831 		break;
2832 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
2833 		status = get_dump_log_efuse_status_88xx(adapter, proc_status,
2834 							data, size);
2835 		break;
2836 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE_MASK:
2837 		status = get_dump_log_efuse_mask_status_88xx(adapter,
2838 							     proc_status,
2839 							     data, size);
2840 		break;
2841 	case HALMAC_FEATURE_CHANNEL_SWITCH:
2842 		status = get_ch_switch_status_88xx(adapter, proc_status);
2843 		break;
2844 	case HALMAC_FEATURE_UPDATE_PACKET:
2845 		status = get_update_packet_status_88xx(adapter, proc_status);
2846 		break;
2847 	case HALMAC_FEATURE_SEND_SCAN_PACKET:
2848 		status = get_send_scan_packet_status_88xx(adapter, proc_status);
2849 		break;
2850 	case HALMAC_FEATURE_DROP_SCAN_PACKET:
2851 		status = get_drop_scan_packet_status_88xx(adapter, proc_status);
2852 		break;
2853 	case HALMAC_FEATURE_IQK:
2854 		status = get_iqk_status_88xx(adapter, proc_status);
2855 		break;
2856 	case HALMAC_FEATURE_POWER_TRACKING:
2857 		status = get_pwr_trk_status_88xx(adapter, proc_status);
2858 		break;
2859 	case HALMAC_FEATURE_PSD:
2860 		status = get_psd_status_88xx(adapter, proc_status, data, size);
2861 		break;
2862 	case HALMAC_FEATURE_FW_SNDING:
2863 		status = get_fw_snding_status_88xx(adapter, proc_status);
2864 		break;
2865 	case HALMAC_FEATURE_DPK:
2866 		status = get_dpk_status_88xx(adapter, proc_status, data, size);
2867 		break;
2868 	default:
2869 		return HALMAC_RET_INVALID_FEATURE_ID;
2870 	}
2871 
2872 	return status;
2873 }
2874 
2875 static enum halmac_ret_status
get_cfg_param_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status)2876 get_cfg_param_status_88xx(struct halmac_adapter *adapter,
2877 			  enum halmac_cmd_process_status *proc_status)
2878 {
2879 	*proc_status = adapter->halmac_state.cfg_param_state.proc_status;
2880 
2881 	return HALMAC_RET_SUCCESS;
2882 }
2883 
2884 static enum halmac_ret_status
get_ch_switch_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status)2885 get_ch_switch_status_88xx(struct halmac_adapter *adapter,
2886 			  enum halmac_cmd_process_status *proc_status)
2887 {
2888 	*proc_status = adapter->halmac_state.scan_state.proc_status;
2889 
2890 	return HALMAC_RET_SUCCESS;
2891 }
2892 
2893 static enum halmac_ret_status
get_update_packet_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status)2894 get_update_packet_status_88xx(struct halmac_adapter *adapter,
2895 			      enum halmac_cmd_process_status *proc_status)
2896 {
2897 	*proc_status = adapter->halmac_state.update_pkt_state.proc_status;
2898 
2899 	return HALMAC_RET_SUCCESS;
2900 }
2901 
2902 static enum halmac_ret_status
get_send_scan_packet_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status)2903 get_send_scan_packet_status_88xx(struct halmac_adapter *adapter,
2904 				 enum halmac_cmd_process_status *proc_status)
2905 {
2906 	*proc_status = adapter->halmac_state.scan_pkt_state.proc_status;
2907 
2908 	return HALMAC_RET_SUCCESS;
2909 }
2910 
2911 static enum halmac_ret_status
get_drop_scan_packet_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status)2912 get_drop_scan_packet_status_88xx(struct halmac_adapter *adapter,
2913 				 enum halmac_cmd_process_status *proc_status)
2914 {
2915 	*proc_status = adapter->halmac_state.drop_pkt_state.proc_status;
2916 
2917 	return HALMAC_RET_SUCCESS;
2918 }
2919 
2920 /**
2921  * cfg_drv_rsvd_pg_num_88xx() -config reserved page number for driver
2922  * @adapter : the adapter of halmac
2923  * @pg_num : page number
2924  * Author : KaiYuan Chang
2925  * Return : enum halmac_ret_status
2926  * More details of status code can be found in prototype document
2927  */
2928 enum halmac_ret_status
cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter * adapter,enum halmac_drv_rsvd_pg_num pg_num)2929 cfg_drv_rsvd_pg_num_88xx(struct halmac_adapter *adapter,
2930 			 enum halmac_drv_rsvd_pg_num pg_num)
2931 {
2932 	if (adapter->api_registry.cfg_drv_rsvd_pg_en == 0)
2933 		return HALMAC_RET_NOT_SUPPORT;
2934 
2935 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2936 	PLTFM_MSG_TRACE("[TRACE]pg_num = %d\n", pg_num);
2937 
2938 	switch (pg_num) {
2939 	case HALMAC_RSVD_PG_NUM8:
2940 		adapter->txff_alloc.rsvd_drv_pg_num = 8;
2941 		break;
2942 	case HALMAC_RSVD_PG_NUM16:
2943 		adapter->txff_alloc.rsvd_drv_pg_num = 16;
2944 		break;
2945 	case HALMAC_RSVD_PG_NUM24:
2946 		adapter->txff_alloc.rsvd_drv_pg_num = 24;
2947 		break;
2948 	case HALMAC_RSVD_PG_NUM32:
2949 		adapter->txff_alloc.rsvd_drv_pg_num = 32;
2950 		break;
2951 	case HALMAC_RSVD_PG_NUM64:
2952 		adapter->txff_alloc.rsvd_drv_pg_num = 64;
2953 		break;
2954 	case HALMAC_RSVD_PG_NUM128:
2955 		adapter->txff_alloc.rsvd_drv_pg_num = 128;
2956 		break;
2957 	case HALMAC_RSVD_PG_NUM256:
2958 		adapter->txff_alloc.rsvd_drv_pg_num = 256;
2959 		break;
2960 	case HALMAC_RSVD_PG_NUM512:
2961 		adapter->txff_alloc.rsvd_drv_pg_num = 512;
2962 		break;
2963 	case HALMAC_RSVD_PG_NUM1024:
2964 		adapter->txff_alloc.rsvd_drv_pg_num = 1024;
2965 		break;
2966 	case HALMAC_RSVD_PG_NUM1460:
2967 		adapter->txff_alloc.rsvd_drv_pg_num = 1460;
2968 		break;
2969 	}
2970 
2971 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2972 
2973 	return HALMAC_RET_SUCCESS;
2974 }
2975 
2976 /**
2977  * (debug API)h2c_lb_88xx() - send h2c loopback packet
2978  * @adapter : the adapter of halmac
2979  * Author : KaiYuan Chang/Ivan Lin
2980  * Return : enum halmac_ret_status
2981  * More details of status code can be found in prototype document
2982  */
2983 enum halmac_ret_status
h2c_lb_88xx(struct halmac_adapter * adapter)2984 h2c_lb_88xx(struct halmac_adapter *adapter)
2985 {
2986 	return HALMAC_RET_SUCCESS;
2987 }
2988 
2989 enum halmac_ret_status
pwr_seq_parser_88xx(struct halmac_adapter * adapter,struct halmac_wlan_pwr_cfg ** cmd_seq)2990 pwr_seq_parser_88xx(struct halmac_adapter *adapter,
2991 		    struct halmac_wlan_pwr_cfg **cmd_seq)
2992 {
2993 	u8 cut;
2994 	u8 intf;
2995 	u32 idx = 0;
2996 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2997 	struct halmac_wlan_pwr_cfg *cmd;
2998 
2999 	switch (adapter->chip_ver) {
3000 	case HALMAC_CHIP_VER_A_CUT:
3001 		cut = HALMAC_PWR_CUT_A_MSK;
3002 		break;
3003 	case HALMAC_CHIP_VER_B_CUT:
3004 		cut = HALMAC_PWR_CUT_B_MSK;
3005 		break;
3006 	case HALMAC_CHIP_VER_C_CUT:
3007 		cut = HALMAC_PWR_CUT_C_MSK;
3008 		break;
3009 	case HALMAC_CHIP_VER_D_CUT:
3010 		cut = HALMAC_PWR_CUT_D_MSK;
3011 		break;
3012 	case HALMAC_CHIP_VER_E_CUT:
3013 		cut = HALMAC_PWR_CUT_E_MSK;
3014 		break;
3015 	case HALMAC_CHIP_VER_F_CUT:
3016 		cut = HALMAC_PWR_CUT_F_MSK;
3017 		break;
3018 	case HALMAC_CHIP_VER_TEST:
3019 		cut = HALMAC_PWR_CUT_TESTCHIP_MSK;
3020 		break;
3021 	default:
3022 		PLTFM_MSG_ERR("[ERR]chip info!!\n");
3023 		return HALMAC_RET_SWITCH_CASE_ERROR;
3024 	}
3025 
3026 	switch (adapter->intf) {
3027 	case HALMAC_INTERFACE_PCIE:
3028 	case HALMAC_INTERFACE_AXI:
3029 		intf = HALMAC_PWR_INTF_PCI_MSK;
3030 		break;
3031 	case HALMAC_INTERFACE_USB:
3032 		intf = HALMAC_PWR_INTF_USB_MSK;
3033 		break;
3034 	case HALMAC_INTERFACE_SDIO:
3035 		intf = HALMAC_PWR_INTF_SDIO_MSK;
3036 		break;
3037 	default:
3038 		PLTFM_MSG_ERR("[ERR]interface!!\n");
3039 		return HALMAC_RET_SWITCH_CASE_ERROR;
3040 	}
3041 
3042 	do {
3043 		cmd = cmd_seq[idx];
3044 
3045 		if (!cmd)
3046 			break;
3047 
3048 		status = pwr_sub_seq_parser_88xx(adapter, cut, intf, cmd);
3049 		if (status != HALMAC_RET_SUCCESS) {
3050 			PLTFM_MSG_ERR("[ERR]pwr sub seq!!\n");
3051 			return status;
3052 		}
3053 
3054 		idx++;
3055 	} while (1);
3056 
3057 	return status;
3058 }
3059 
3060 static enum halmac_ret_status
pwr_sub_seq_parser_88xx(struct halmac_adapter * adapter,u8 cut,u8 intf,struct halmac_wlan_pwr_cfg * cmd)3061 pwr_sub_seq_parser_88xx(struct halmac_adapter *adapter, u8 cut, u8 intf,
3062 			struct halmac_wlan_pwr_cfg *cmd)
3063 {
3064 	u8 value;
3065 	u32 offset;
3066 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3067 
3068 	do {
3069 		if ((cmd->interface_msk & intf) && (cmd->cut_msk & cut)) {
3070 			switch (cmd->cmd) {
3071 			case HALMAC_PWR_CMD_WRITE:
3072 				offset = cmd->offset;
3073 
3074 				if (cmd->base == HALMAC_PWR_ADDR_SDIO)
3075 					offset |= SDIO_LOCAL_OFFSET;
3076 
3077 				value = HALMAC_REG_R8(offset);
3078 				value = (u8)(value & (u8)(~(cmd->msk)));
3079 				value = (u8)(value | (cmd->value & cmd->msk));
3080 
3081 				HALMAC_REG_W8(offset, value);
3082 				break;
3083 			case HALMAC_PWR_CMD_POLLING:
3084 				if (pwr_cmd_polling_88xx(adapter, cmd) !=
3085 				    HALMAC_RET_SUCCESS)
3086 					return HALMAC_RET_PWRSEQ_POLLING_FAIL;
3087 				break;
3088 			case HALMAC_PWR_CMD_DELAY:
3089 				if (cmd->value == HALMAC_PWR_DELAY_US)
3090 					PLTFM_DELAY_US(cmd->offset);
3091 				else
3092 					PLTFM_DELAY_US(1000 * cmd->offset);
3093 				break;
3094 			case HALMAC_PWR_CMD_READ:
3095 				break;
3096 			case HALMAC_PWR_CMD_END:
3097 				return HALMAC_RET_SUCCESS;
3098 			default:
3099 				return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
3100 			}
3101 		}
3102 		cmd++;
3103 	} while (1);
3104 
3105 	return HALMAC_RET_SUCCESS;
3106 }
3107 
3108 static enum halmac_ret_status
pwr_cmd_polling_88xx(struct halmac_adapter * adapter,struct halmac_wlan_pwr_cfg * cmd)3109 pwr_cmd_polling_88xx(struct halmac_adapter *adapter,
3110 		     struct halmac_wlan_pwr_cfg *cmd)
3111 {
3112 	u8 value;
3113 	u8 flg;
3114 	u8 poll_bit;
3115 	u32 offset;
3116 	u32 cnt;
3117 	static u32 stats;
3118 	enum halmac_interface intf;
3119 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3120 
3121 	poll_bit = 0;
3122 	cnt = HALMAC_PWR_POLLING_CNT;
3123 	flg = 0;
3124 	intf = adapter->intf;
3125 
3126 	if (cmd->base == HALMAC_PWR_ADDR_SDIO)
3127 		offset = cmd->offset | SDIO_LOCAL_OFFSET;
3128 	else
3129 		offset = cmd->offset;
3130 
3131 	do {
3132 		cnt--;
3133 		value = HALMAC_REG_R8(offset);
3134 		value = (u8)(value & cmd->msk);
3135 
3136 		if (value == (cmd->value & cmd->msk)) {
3137 			poll_bit = 1;
3138 		} else {
3139 			if (cnt == 0) {
3140 				if (intf == HALMAC_INTERFACE_PCIE && flg == 0) {
3141 					/* PCIE + USB package */
3142 					/* power bit polling timeout issue */
3143 					stats++;
3144 					PLTFM_MSG_WARN("[WARN]PCIE stats:%d\n",
3145 						       stats);
3146 					value = HALMAC_REG_R8(REG_SYS_PW_CTRL);
3147 					value |= BIT(3);
3148 					HALMAC_REG_W8(REG_SYS_PW_CTRL, value);
3149 					value &= ~BIT(3);
3150 					HALMAC_REG_W8(REG_SYS_PW_CTRL, value);
3151 					poll_bit = 0;
3152 					cnt = HALMAC_PWR_POLLING_CNT;
3153 					flg = 1;
3154 				} else {
3155 					PLTFM_MSG_ERR("[ERR]polling to!!\n");
3156 					PLTFM_MSG_ERR("[ERR]cmd offset:%X\n",
3157 						      cmd->offset);
3158 					PLTFM_MSG_ERR("[ERR]cmd value:%X\n",
3159 						      cmd->value);
3160 					PLTFM_MSG_ERR("[ERR]cmd msk:%X\n",
3161 						      cmd->msk);
3162 					PLTFM_MSG_ERR("[ERR]offset = %X\n",
3163 						      offset);
3164 					PLTFM_MSG_ERR("[ERR]value = %X\n",
3165 						      value);
3166 					return HALMAC_RET_PWRSEQ_POLLING_FAIL;
3167 				}
3168 			} else {
3169 				PLTFM_DELAY_US(50);
3170 			}
3171 		}
3172 	} while (!poll_bit);
3173 
3174 	return HALMAC_RET_SUCCESS;
3175 }
3176 
3177 enum halmac_ret_status
parse_intf_phy_88xx(struct halmac_adapter * adapter,struct halmac_intf_phy_para * param,enum halmac_intf_phy_platform pltfm,enum hal_intf_phy intf_phy)3178 parse_intf_phy_88xx(struct halmac_adapter *adapter,
3179 		    struct halmac_intf_phy_para *param,
3180 		    enum halmac_intf_phy_platform pltfm,
3181 		    enum hal_intf_phy intf_phy)
3182 {
3183 	u16 value;
3184 	u16 cur_cut;
3185 	u16 offset;
3186 	u16 ip_sel;
3187 	struct halmac_intf_phy_para *cur_param;
3188 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3189 	enum halmac_ret_status result = HALMAC_RET_SUCCESS;
3190 
3191 	switch (adapter->chip_ver) {
3192 	case HALMAC_CHIP_VER_A_CUT:
3193 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_A;
3194 		break;
3195 	case HALMAC_CHIP_VER_B_CUT:
3196 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_B;
3197 		break;
3198 	case HALMAC_CHIP_VER_C_CUT:
3199 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_C;
3200 		break;
3201 	case HALMAC_CHIP_VER_D_CUT:
3202 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_D;
3203 		break;
3204 	case HALMAC_CHIP_VER_E_CUT:
3205 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_E;
3206 		break;
3207 	case HALMAC_CHIP_VER_F_CUT:
3208 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_F;
3209 		break;
3210 	case HALMAC_CHIP_VER_TEST:
3211 		cur_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
3212 		break;
3213 	default:
3214 		return HALMAC_RET_FAIL;
3215 	}
3216 
3217 	cur_param = param;
3218 
3219 	do {
3220 		if ((cur_param->cut & cur_cut) &&
3221 		    (cur_param->plaform & (u16)pltfm)) {
3222 			offset =  cur_param->offset;
3223 			value = cur_param->value;
3224 			ip_sel = cur_param->ip_sel;
3225 
3226 			if (offset == 0xFFFF)
3227 				break;
3228 
3229 			if (ip_sel == HALMAC_IP_SEL_MAC) {
3230 				HALMAC_REG_W8((u32)offset, (u8)value);
3231 			} else if (intf_phy == HAL_INTF_PHY_USB2 ||
3232 				   intf_phy == HAL_INTF_PHY_USB3) {
3233 #if HALMAC_USB_SUPPORT
3234 				if (offset > 0x100)
3235 					usb_page_switch_88xx(adapter,
3236 							     intf_phy,
3237 							     1);
3238 				else
3239 					usb_page_switch_88xx(adapter,
3240 							     intf_phy,
3241 							     0);
3242 				offset = offset & 0xFF;
3243 				result = usbphy_write_88xx(adapter, (u8)offset,
3244 							   value, intf_phy);
3245 				if (result != HALMAC_RET_SUCCESS)
3246 					PLTFM_MSG_ERR("[ERR]usb phy!!\n");
3247 #endif
3248 			} else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1 ||
3249 				   intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
3250 #if HALMAC_PCIE_SUPPORT
3251 				if (ip_sel == HALMAC_IP_INTF_PHY)
3252 					result = mdio_write_88xx(adapter,
3253 								 (u8)offset,
3254 								 value,
3255 								 intf_phy);
3256 				else
3257 					result = dbi_w8_88xx(adapter, offset,
3258 							     (u8)value);
3259 				if (result != HALMAC_RET_SUCCESS)
3260 					PLTFM_MSG_ERR("[ERR]mdio/dbi!!\n");
3261 #endif
3262 			} else {
3263 				PLTFM_MSG_ERR("[ERR]intf phy sel!!\n");
3264 			}
3265 		}
3266 		cur_param++;
3267 	} while (1);
3268 
3269 	return result;
3270 }
3271 
3272 /**
3273  * txfifo_is_empty_88xx() -check if txfifo is empty
3274  * @adapter : the adapter of halmac
3275  * @chk_num : check number
3276  * Author : Ivan Lin
3277  * Return : enum halmac_ret_status
3278  * More details of status code can be found in prototype document
3279  */
3280 enum halmac_ret_status
txfifo_is_empty_88xx(struct halmac_adapter * adapter,u32 chk_num)3281 txfifo_is_empty_88xx(struct halmac_adapter *adapter, u32 chk_num)
3282 {
3283 	u32 cnt;
3284 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3285 
3286 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
3287 
3288 	cnt = (chk_num <= 10) ? 10 : chk_num;
3289 	do {
3290 		if (HALMAC_REG_R8(REG_TXPKT_EMPTY) != 0xFF)
3291 			return HALMAC_RET_TXFIFO_NO_EMPTY;
3292 
3293 		if ((HALMAC_REG_R8(REG_TXPKT_EMPTY + 1) & 0x06) != 0x06)
3294 			return HALMAC_RET_TXFIFO_NO_EMPTY;
3295 		cnt--;
3296 
3297 	} while (cnt != 0);
3298 
3299 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
3300 
3301 	return HALMAC_RET_SUCCESS;
3302 }
3303 
3304 /**
3305  * (internal use)
3306  * smart_malloc_88xx() - adapt malloc size
3307  * @adapter : the adapter of halmac
3308  * @size : expected malloc size
3309  * @pNew_size : real malloc size
3310  * Author : Ivan Lin
3311  * Return : address pointer
3312  */
3313 u8*
smart_malloc_88xx(struct halmac_adapter * adapter,u32 size,u32 * new_size)3314 smart_malloc_88xx(struct halmac_adapter *adapter, u32 size, u32 *new_size)
3315 {
3316 	u8 retry_num;
3317 	u8 *malloc_buf = NULL;
3318 
3319 	for (retry_num = 0; retry_num < 5; retry_num++) {
3320 		malloc_buf = (u8 *)PLTFM_MALLOC(size);
3321 
3322 		if (malloc_buf) {
3323 			*new_size = size;
3324 			return malloc_buf;
3325 		}
3326 
3327 		size = size >> 1;
3328 
3329 		if (size == 0)
3330 			break;
3331 	}
3332 
3333 	PLTFM_MSG_ERR("[ERR]adptive malloc!!\n");
3334 
3335 	return NULL;
3336 }
3337 
3338 /**
3339  * (internal use)
3340  * ltecoex_reg_read_88xx() - read ltecoex register
3341  * @adapter : the adapter of halmac
3342  * @offset : offset
3343  * @pValue : value
3344  * Author : Ivan Lin
3345  * Return : enum halmac_ret_status
3346  */
3347 enum halmac_ret_status
ltecoex_reg_read_88xx(struct halmac_adapter * adapter,u16 offset,u32 * value)3348 ltecoex_reg_read_88xx(struct halmac_adapter *adapter, u16 offset, u32 *value)
3349 {
3350 	u32 cnt;
3351 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3352 
3353 	cnt = 10000;
3354 	while ((HALMAC_REG_R8(LTECOEX_ACCESS_CTRL + 3) & BIT(5)) == 0) {
3355 		if (cnt == 0) {
3356 			PLTFM_MSG_ERR("[ERR]lte ready(R)\n");
3357 			return HALMAC_RET_LTECOEX_READY_FAIL;
3358 		}
3359 		cnt--;
3360 		PLTFM_DELAY_US(50);
3361 	}
3362 
3363 	HALMAC_REG_W32(LTECOEX_ACCESS_CTRL, 0x800F0000 | offset);
3364 	*value = HALMAC_REG_R32(REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1);
3365 
3366 	return HALMAC_RET_SUCCESS;
3367 }
3368 
3369 /**
3370  * (internal use)
3371  * ltecoex_reg_write_88xx() - write ltecoex register
3372  * @adapter : the adapter of halmac
3373  * @offset : offset
3374  * @value : value
3375  * Author : Ivan Lin
3376  * Return : enum halmac_ret_status
3377  */
3378 enum halmac_ret_status
ltecoex_reg_write_88xx(struct halmac_adapter * adapter,u16 offset,u32 value)3379 ltecoex_reg_write_88xx(struct halmac_adapter *adapter, u16 offset, u32 value)
3380 {
3381 	u32 cnt;
3382 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3383 
3384 	cnt = 10000;
3385 	while ((HALMAC_REG_R8(LTECOEX_ACCESS_CTRL + 3) & BIT(5)) == 0) {
3386 		if (cnt == 0) {
3387 			PLTFM_MSG_ERR("[ERR]lte ready(W)\n");
3388 			return HALMAC_RET_LTECOEX_READY_FAIL;
3389 		}
3390 		cnt--;
3391 		PLTFM_DELAY_US(50);
3392 	}
3393 
3394 	HALMAC_REG_W32(REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1, value);
3395 	HALMAC_REG_W32(LTECOEX_ACCESS_CTRL, 0xC00F0000 | offset);
3396 
3397 	return HALMAC_RET_SUCCESS;
3398 }
3399 
3400 static void
pwr_state_88xx(struct halmac_adapter * adapter,enum halmac_mac_power * state)3401 pwr_state_88xx(struct halmac_adapter *adapter, enum halmac_mac_power *state)
3402 {
3403 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3404 
3405 	if ((HALMAC_REG_R8(REG_SYS_FUNC_EN + 1) & BIT(3)) == 0)
3406 		*state = HALMAC_MAC_POWER_OFF;
3407 	else
3408 		*state = HALMAC_MAC_POWER_ON;
3409 }
3410 
3411 static u8
packet_in_nlo_88xx(struct halmac_adapter * adapter,enum halmac_packet_id pkt_id)3412 packet_in_nlo_88xx(struct halmac_adapter *adapter,
3413 		   enum halmac_packet_id pkt_id)
3414 {
3415 	enum halmac_packet_id nlo_pkt = HALMAC_PACKET_PROBE_REQ_NLO;
3416 
3417 	if (pkt_id >= nlo_pkt)
3418 		return 1;
3419 	else
3420 		return 0;
3421 }
3422 
3423 static enum halmac_packet_id
get_real_pkt_id_88xx(struct halmac_adapter * adapter,enum halmac_packet_id pkt_id)3424 get_real_pkt_id_88xx(struct halmac_adapter *adapter,
3425 		     enum halmac_packet_id pkt_id)
3426 {
3427 	enum halmac_packet_id real_pkt_id;
3428 
3429 	PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
3430 
3431 	switch (pkt_id) {
3432 	case HALMAC_PACKET_PROBE_REQ_NLO:
3433 		real_pkt_id = HALMAC_PACKET_PROBE_REQ;
3434 		break;
3435 	case HALMAC_PACKET_SYNC_BCN_NLO:
3436 		real_pkt_id = HALMAC_PACKET_SYNC_BCN;
3437 		break;
3438 	case HALMAC_PACKET_DISCOVERY_BCN_NLO:
3439 		real_pkt_id = HALMAC_PACKET_DISCOVERY_BCN;
3440 		break;
3441 	default:
3442 		real_pkt_id = pkt_id;
3443 	}
3444 	PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
3445 	return real_pkt_id;
3446 }
3447 
3448 static u32
get_update_packet_page_size(struct halmac_adapter * adapter,u32 size)3449 get_update_packet_page_size(struct halmac_adapter *adapter, u32 size)
3450 {
3451 	struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
3452 	u32 txdesc_size;
3453 	u32 total;
3454 
3455 	api->halmac_get_hw_value(adapter, HALMAC_HW_TX_DESC_SIZE, &txdesc_size);
3456 
3457 	total = size + txdesc_size;
3458 	return (total & 0x7f) > 0 ?
3459 		(total >> TX_PAGE_SIZE_SHIFT_88XX) + 1 :
3460 		total >> TX_PAGE_SIZE_SHIFT_88XX;
3461 }
3462 
3463 #endif /* HALMAC_88XX_SUPPORT */
3464