• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14 #include "halmac_88xx_cfg.h"
15 
16 static enum halmac_ret_status
17 halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter);
18 
19 static enum halmac_ret_status
20 halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter);
21 
22 static enum halmac_ret_status
23 halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
24 			       struct halmac_pg_efuse_info *pg_efuse_info,
25 			       u8 *eeprom_mask_updated);
26 
27 static enum halmac_ret_status
28 halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
29 			       struct halmac_pg_efuse_info *pg_efuse_info,
30 			       u8 *eeprom_mask_updated);
31 
32 static enum halmac_ret_status
33 halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
34 			  struct halmac_pg_efuse_info *pg_efuse_info,
35 			  u8 *eeprom_mask_updated);
36 
37 static enum halmac_ret_status
38 halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
39 			      u8 fab, u8 intf,
40 			      struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg);
41 
42 static enum halmac_ret_status
43 halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
44 			    u32 c2h_size);
45 
46 static enum halmac_ret_status
47 halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
48 				  u8 *c2h_buf, u32 c2h_size);
49 
50 static enum halmac_ret_status
51 halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
52 			   u32 c2h_size);
53 
54 static enum halmac_ret_status
55 halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
56 			     u32 c2h_size);
57 
58 static enum halmac_ret_status
59 halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
60 			  u32 c2h_size);
61 
62 static enum halmac_ret_status
63 halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
64 			      struct halmac_phy_parameter_info *para_info,
65 			      u8 *curr_buff_wptr, bool *end_cmd);
66 
67 static enum halmac_ret_status
68 halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
69 				    u8 *c2h_buf, u32 c2h_size);
70 
71 static enum halmac_ret_status
72 halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
73 				   u8 *c2h_buf, u32 c2h_size);
74 
75 static enum halmac_ret_status
76 halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
77 			     u8 *h2c_buff);
78 
79 static enum halmac_ret_status
80 halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
81 					u8 *c2h_buf, u32 c2h_size);
82 
83 static enum halmac_ret_status
84 halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
85 					  u8 *c2h_buf, u32 c2h_size);
86 
87 static enum halmac_ret_status
88 halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
89 				       u8 *c2h_buf, u32 c2h_size);
90 
91 static enum halmac_ret_status
92 halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
93 					 u8 *c2h_buf, u32 c2h_size);
94 
95 static enum halmac_ret_status
96 halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
97 			      u8 *c2h_buf, u32 c2h_size);
98 
99 static enum halmac_ret_status
100 halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
101 					 u8 *c2h_buf, u32 c2h_size);
102 
halmac_init_offload_feature_state_machine_88xx(struct halmac_adapter * halmac_adapter)103 void halmac_init_offload_feature_state_machine_88xx(
104 	struct halmac_adapter *halmac_adapter)
105 {
106 	struct halmac_state *state = &halmac_adapter->halmac_state;
107 
108 	state->efuse_state_set.efuse_cmd_construct_state =
109 		HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
110 	state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
111 	state->efuse_state_set.seq_num = halmac_adapter->h2c_packet_seq;
112 
113 	state->cfg_para_state_set.cfg_para_cmd_construct_state =
114 		HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
115 	state->cfg_para_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
116 	state->cfg_para_state_set.seq_num = halmac_adapter->h2c_packet_seq;
117 
118 	state->scan_state_set.scan_cmd_construct_state =
119 		HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
120 	state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
121 	state->scan_state_set.seq_num = halmac_adapter->h2c_packet_seq;
122 
123 	state->update_packet_set.process_status = HALMAC_CMD_PROCESS_IDLE;
124 	state->update_packet_set.seq_num = halmac_adapter->h2c_packet_seq;
125 
126 	state->iqk_set.process_status = HALMAC_CMD_PROCESS_IDLE;
127 	state->iqk_set.seq_num = halmac_adapter->h2c_packet_seq;
128 
129 	state->power_tracking_set.process_status = HALMAC_CMD_PROCESS_IDLE;
130 	state->power_tracking_set.seq_num = halmac_adapter->h2c_packet_seq;
131 
132 	state->psd_set.process_status = HALMAC_CMD_PROCESS_IDLE;
133 	state->psd_set.seq_num = halmac_adapter->h2c_packet_seq;
134 	state->psd_set.data_size = 0;
135 	state->psd_set.segment_size = 0;
136 	state->psd_set.data = NULL;
137 }
138 
139 enum halmac_ret_status
halmac_dump_efuse_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_read_cfg cfg)140 halmac_dump_efuse_88xx(struct halmac_adapter *halmac_adapter,
141 		       enum halmac_efuse_read_cfg cfg)
142 {
143 	u32 chk_h2c_init;
144 	void *driver_adapter = NULL;
145 	struct halmac_api *halmac_api =
146 		(struct halmac_api *)halmac_adapter->halmac_api;
147 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
148 	enum halmac_cmd_process_status *process_status =
149 		&halmac_adapter->halmac_state.efuse_state_set.process_status;
150 
151 	driver_adapter = halmac_adapter->driver_adapter;
152 
153 	*process_status = HALMAC_CMD_PROCESS_SENDING;
154 
155 	if (halmac_transition_efuse_state_88xx(
156 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) !=
157 	    HALMAC_RET_SUCCESS)
158 		return HALMAC_RET_ERROR_STATE;
159 
160 	if (cfg == HALMAC_EFUSE_R_AUTO) {
161 		chk_h2c_init = HALMAC_REG_READ_32(halmac_adapter,
162 						  REG_H2C_PKT_READADDR);
163 		if (halmac_adapter->halmac_state.dlfw_state ==
164 			    HALMAC_DLFW_NONE ||
165 		    chk_h2c_init == 0)
166 			status = halmac_dump_efuse_drv_88xx(halmac_adapter);
167 		else
168 			status = halmac_dump_efuse_fw_88xx(halmac_adapter);
169 	} else if (cfg == HALMAC_EFUSE_R_FW) {
170 		status = halmac_dump_efuse_fw_88xx(halmac_adapter);
171 	} else {
172 		status = halmac_dump_efuse_drv_88xx(halmac_adapter);
173 	}
174 
175 	if (status != HALMAC_RET_SUCCESS) {
176 		pr_err("halmac_read_efuse error = %x\n", status);
177 		return status;
178 	}
179 
180 	return status;
181 }
182 
183 enum halmac_ret_status
halmac_func_read_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u32 size,u8 * efuse_map)184 halmac_func_read_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
185 			    u32 size, u8 *efuse_map)
186 {
187 	void *driver_adapter = NULL;
188 
189 	driver_adapter = halmac_adapter->driver_adapter;
190 
191 	if (!efuse_map) {
192 		pr_err("Malloc for dump efuse map error\n");
193 		return HALMAC_RET_NULL_POINTER;
194 	}
195 
196 	if (halmac_adapter->hal_efuse_map_valid)
197 		memcpy(efuse_map, halmac_adapter->hal_efuse_map + offset, size);
198 	else if (halmac_read_hw_efuse_88xx(halmac_adapter, offset, size,
199 					   efuse_map) != HALMAC_RET_SUCCESS)
200 		return HALMAC_RET_EFUSE_R_FAIL;
201 
202 	return HALMAC_RET_SUCCESS;
203 }
204 
205 enum halmac_ret_status
halmac_read_hw_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u32 size,u8 * efuse_map)206 halmac_read_hw_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
207 			  u32 size, u8 *efuse_map)
208 {
209 	u8 value8;
210 	u32 value32;
211 	u32 address;
212 	u32 tmp32, counter;
213 	void *driver_adapter = NULL;
214 	struct halmac_api *halmac_api;
215 
216 	driver_adapter = halmac_adapter->driver_adapter;
217 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
218 
219 	/* Read efuse no need 2.5V LDO */
220 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3);
221 	if (value8 & BIT(7))
222 		HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
223 				   (u8)(value8 & ~(BIT(7))));
224 
225 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
226 
227 	for (address = offset; address < offset + size; address++) {
228 		value32 = value32 &
229 			  ~((BIT_MASK_EF_DATA) |
230 			    (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
231 		value32 = value32 |
232 			  ((address & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
233 		HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
234 				    value32 & (~BIT_EF_FLAG));
235 
236 		counter = 1000000;
237 		do {
238 			udelay(1);
239 			tmp32 = HALMAC_REG_READ_32(halmac_adapter,
240 						   REG_EFUSE_CTRL);
241 			counter--;
242 			if (counter == 0) {
243 				pr_err("HALMAC_RET_EFUSE_R_FAIL\n");
244 				return HALMAC_RET_EFUSE_R_FAIL;
245 			}
246 		} while ((tmp32 & BIT_EF_FLAG) == 0);
247 
248 		*(efuse_map + address - offset) =
249 			(u8)(tmp32 & BIT_MASK_EF_DATA);
250 	}
251 
252 	return HALMAC_RET_SUCCESS;
253 }
254 
255 static enum halmac_ret_status
halmac_dump_efuse_drv_88xx(struct halmac_adapter * halmac_adapter)256 halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter)
257 {
258 	u8 *efuse_map = NULL;
259 	u32 efuse_size;
260 	void *driver_adapter = NULL;
261 
262 	driver_adapter = halmac_adapter->driver_adapter;
263 
264 	efuse_size = halmac_adapter->hw_config_info.efuse_size;
265 
266 	if (!halmac_adapter->hal_efuse_map) {
267 		halmac_adapter->hal_efuse_map = kzalloc(efuse_size, GFP_KERNEL);
268 		if (!halmac_adapter->hal_efuse_map)
269 			return HALMAC_RET_MALLOC_FAIL;
270 	}
271 
272 	efuse_map = kzalloc(efuse_size, GFP_KERNEL);
273 	if (!efuse_map)
274 		return HALMAC_RET_MALLOC_FAIL;
275 
276 	if (halmac_read_hw_efuse_88xx(halmac_adapter, 0, efuse_size,
277 				      efuse_map) != HALMAC_RET_SUCCESS) {
278 		kfree(efuse_map);
279 		return HALMAC_RET_EFUSE_R_FAIL;
280 	}
281 
282 	spin_lock(&halmac_adapter->efuse_lock);
283 	memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
284 	halmac_adapter->hal_efuse_map_valid = true;
285 	spin_unlock(&halmac_adapter->efuse_lock);
286 
287 	kfree(efuse_map);
288 
289 	return HALMAC_RET_SUCCESS;
290 }
291 
292 static enum halmac_ret_status
halmac_dump_efuse_fw_88xx(struct halmac_adapter * halmac_adapter)293 halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter)
294 {
295 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
296 	u16 h2c_seq_mum = 0;
297 	void *driver_adapter = NULL;
298 	struct halmac_h2c_header_info h2c_header_info;
299 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
300 
301 	driver_adapter = halmac_adapter->driver_adapter;
302 
303 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
304 	h2c_header_info.content_size = 0;
305 	h2c_header_info.ack = true;
306 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
307 					      &h2c_header_info, &h2c_seq_mum);
308 	halmac_adapter->halmac_state.efuse_state_set.seq_num = h2c_seq_mum;
309 
310 	if (!halmac_adapter->hal_efuse_map) {
311 		halmac_adapter->hal_efuse_map = kzalloc(
312 			halmac_adapter->hw_config_info.efuse_size, GFP_KERNEL);
313 		if (!halmac_adapter->hal_efuse_map)
314 			return HALMAC_RET_MALLOC_FAIL;
315 	}
316 
317 	if (!halmac_adapter->hal_efuse_map_valid) {
318 		status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
319 						  HALMAC_H2C_CMD_SIZE_88XX,
320 						  true);
321 		if (status != HALMAC_RET_SUCCESS) {
322 			pr_err("halmac_read_efuse_fw Fail = %x!!\n", status);
323 			return status;
324 		}
325 	}
326 
327 	return HALMAC_RET_SUCCESS;
328 }
329 
330 enum halmac_ret_status
halmac_func_write_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u8 value)331 halmac_func_write_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
332 			     u8 value)
333 {
334 	const u8 wite_protect_code = 0x69;
335 	u32 value32, tmp32, counter;
336 	void *driver_adapter = NULL;
337 	struct halmac_api *halmac_api;
338 
339 	driver_adapter = halmac_adapter->driver_adapter;
340 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
341 
342 	spin_lock(&halmac_adapter->efuse_lock);
343 	halmac_adapter->hal_efuse_map_valid = false;
344 	spin_unlock(&halmac_adapter->efuse_lock);
345 
346 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3,
347 			   wite_protect_code);
348 
349 	/* Enable 2.5V LDO */
350 	HALMAC_REG_WRITE_8(
351 		halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
352 		(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) |
353 		     BIT(7)));
354 
355 	value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
356 	value32 =
357 		value32 &
358 		~((BIT_MASK_EF_DATA) | (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
359 	value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
360 		  (value & BIT_MASK_EF_DATA);
361 	HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
362 			    value32 | BIT_EF_FLAG);
363 
364 	counter = 1000000;
365 	do {
366 		udelay(1);
367 		tmp32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
368 		counter--;
369 		if (counter == 0) {
370 			pr_err("halmac_write_efuse Fail !!\n");
371 			return HALMAC_RET_EFUSE_W_FAIL;
372 		}
373 	} while ((tmp32 & BIT_EF_FLAG) == BIT_EF_FLAG);
374 
375 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3, 0x00);
376 
377 	/* Disable 2.5V LDO */
378 	HALMAC_REG_WRITE_8(
379 		halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
380 		(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) &
381 		     ~(BIT(7))));
382 
383 	return HALMAC_RET_SUCCESS;
384 }
385 
386 enum halmac_ret_status
halmac_func_switch_efuse_bank_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_bank efuse_bank)387 halmac_func_switch_efuse_bank_88xx(struct halmac_adapter *halmac_adapter,
388 				   enum halmac_efuse_bank efuse_bank)
389 {
390 	u8 reg_value;
391 	struct halmac_api *halmac_api;
392 
393 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
394 
395 	if (halmac_transition_efuse_state_88xx(
396 		    halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) !=
397 	    HALMAC_RET_SUCCESS)
398 		return HALMAC_RET_ERROR_STATE;
399 
400 	reg_value = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1);
401 
402 	if (efuse_bank == (reg_value & (BIT(0) | BIT(1))))
403 		return HALMAC_RET_SUCCESS;
404 
405 	reg_value &= ~(BIT(0) | BIT(1));
406 	reg_value |= efuse_bank;
407 	HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1, reg_value);
408 
409 	if ((HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1) &
410 	     (BIT(0) | BIT(1))) != efuse_bank)
411 		return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
412 
413 	return HALMAC_RET_SUCCESS;
414 }
415 
416 enum halmac_ret_status
halmac_eeprom_parser_88xx(struct halmac_adapter * halmac_adapter,u8 * physical_efuse_map,u8 * logical_efuse_map)417 halmac_eeprom_parser_88xx(struct halmac_adapter *halmac_adapter,
418 			  u8 *physical_efuse_map, u8 *logical_efuse_map)
419 {
420 	u8 j;
421 	u8 value8;
422 	u8 block_index;
423 	u8 valid_word_enable, word_enable;
424 	u8 efuse_read_header, efuse_read_header2 = 0;
425 	u32 eeprom_index;
426 	u32 efuse_index = 0;
427 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
428 	void *driver_adapter = NULL;
429 
430 	driver_adapter = halmac_adapter->driver_adapter;
431 
432 	memset(logical_efuse_map, 0xFF, eeprom_size);
433 
434 	do {
435 		value8 = *(physical_efuse_map + efuse_index);
436 		efuse_read_header = value8;
437 
438 		if ((efuse_read_header & 0x1f) == 0x0f) {
439 			efuse_index++;
440 			value8 = *(physical_efuse_map + efuse_index);
441 			efuse_read_header2 = value8;
442 			block_index = ((efuse_read_header2 & 0xF0) >> 1) |
443 				      ((efuse_read_header >> 5) & 0x07);
444 			word_enable = efuse_read_header2 & 0x0F;
445 		} else {
446 			block_index = (efuse_read_header & 0xF0) >> 4;
447 			word_enable = efuse_read_header & 0x0F;
448 		}
449 
450 		if (efuse_read_header == 0xff)
451 			break;
452 
453 		efuse_index++;
454 
455 		if (efuse_index >= halmac_adapter->hw_config_info.efuse_size -
456 					   HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
457 			return HALMAC_RET_EEPROM_PARSING_FAIL;
458 
459 		for (j = 0; j < 4; j++) {
460 			valid_word_enable =
461 				(u8)((~(word_enable >> j)) & BIT(0));
462 			if (valid_word_enable != 1)
463 				continue;
464 
465 			eeprom_index = (block_index << 3) + (j << 1);
466 
467 			if ((eeprom_index + 1) > eeprom_size) {
468 				pr_err("Error: EEPROM addr exceeds eeprom_size:0x%X, at eFuse 0x%X\n",
469 				       eeprom_size, efuse_index - 1);
470 				if ((efuse_read_header & 0x1f) == 0x0f)
471 					pr_err("Error: EEPROM header: 0x%X, 0x%X,\n",
472 					       efuse_read_header,
473 					       efuse_read_header2);
474 				else
475 					pr_err("Error: EEPROM header: 0x%X,\n",
476 					       efuse_read_header);
477 
478 				return HALMAC_RET_EEPROM_PARSING_FAIL;
479 			}
480 
481 			value8 = *(physical_efuse_map + efuse_index);
482 			*(logical_efuse_map + eeprom_index) = value8;
483 
484 			eeprom_index++;
485 			efuse_index++;
486 
487 			if (efuse_index >
488 			    halmac_adapter->hw_config_info.efuse_size -
489 				    HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
490 				return HALMAC_RET_EEPROM_PARSING_FAIL;
491 
492 			value8 = *(physical_efuse_map + efuse_index);
493 			*(logical_efuse_map + eeprom_index) = value8;
494 
495 			efuse_index++;
496 
497 			if (efuse_index >
498 			    halmac_adapter->hw_config_info.efuse_size -
499 				    HALMAC_PROTECTED_EFUSE_SIZE_88XX)
500 				return HALMAC_RET_EEPROM_PARSING_FAIL;
501 		}
502 	} while (1);
503 
504 	halmac_adapter->efuse_end = efuse_index;
505 
506 	return HALMAC_RET_SUCCESS;
507 }
508 
509 enum halmac_ret_status
halmac_read_logical_efuse_map_88xx(struct halmac_adapter * halmac_adapter,u8 * map)510 halmac_read_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
511 				   u8 *map)
512 {
513 	u8 *efuse_map = NULL;
514 	u32 efuse_size;
515 	void *driver_adapter = NULL;
516 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
517 
518 	driver_adapter = halmac_adapter->driver_adapter;
519 	efuse_size = halmac_adapter->hw_config_info.efuse_size;
520 
521 	if (!halmac_adapter->hal_efuse_map_valid) {
522 		efuse_map = kzalloc(efuse_size, GFP_KERNEL);
523 		if (!efuse_map)
524 			return HALMAC_RET_MALLOC_FAIL;
525 
526 		status = halmac_func_read_efuse_88xx(halmac_adapter, 0,
527 						     efuse_size, efuse_map);
528 		if (status != HALMAC_RET_SUCCESS) {
529 			pr_err("[ERR]halmac_read_efuse error = %x\n", status);
530 			kfree(efuse_map);
531 			return status;
532 		}
533 
534 		if (!halmac_adapter->hal_efuse_map) {
535 			halmac_adapter->hal_efuse_map =
536 				kzalloc(efuse_size, GFP_KERNEL);
537 			if (!halmac_adapter->hal_efuse_map) {
538 				kfree(efuse_map);
539 				return HALMAC_RET_MALLOC_FAIL;
540 			}
541 		}
542 
543 		spin_lock(&halmac_adapter->efuse_lock);
544 		memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
545 		halmac_adapter->hal_efuse_map_valid = true;
546 		spin_unlock(&halmac_adapter->efuse_lock);
547 
548 		kfree(efuse_map);
549 	}
550 
551 	if (halmac_eeprom_parser_88xx(halmac_adapter,
552 				      halmac_adapter->hal_efuse_map,
553 				      map) != HALMAC_RET_SUCCESS)
554 		return HALMAC_RET_EEPROM_PARSING_FAIL;
555 
556 	return status;
557 }
558 
559 enum halmac_ret_status
halmac_func_write_logical_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u8 value)560 halmac_func_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
561 				     u32 offset, u8 value)
562 {
563 	u8 pg_efuse_byte1, pg_efuse_byte2;
564 	u8 pg_block, pg_block_index;
565 	u8 pg_efuse_header, pg_efuse_header2;
566 	u8 *eeprom_map = NULL;
567 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
568 	u32 efuse_end, pg_efuse_num;
569 	void *driver_adapter = NULL;
570 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
571 
572 	driver_adapter = halmac_adapter->driver_adapter;
573 
574 	eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
575 	if (!eeprom_map)
576 		return HALMAC_RET_MALLOC_FAIL;
577 	memset(eeprom_map, 0xFF, eeprom_size);
578 
579 	status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
580 	if (status != HALMAC_RET_SUCCESS) {
581 		pr_err("[ERR]halmac_read_logical_efuse_map_88xx error = %x\n",
582 		       status);
583 		kfree(eeprom_map);
584 		return status;
585 	}
586 
587 	if (*(eeprom_map + offset) != value) {
588 		efuse_end = halmac_adapter->efuse_end;
589 		pg_block = (u8)(offset >> 3);
590 		pg_block_index = (u8)((offset & (8 - 1)) >> 1);
591 
592 		if (offset > 0x7f) {
593 			pg_efuse_header =
594 				(((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
595 			pg_efuse_header2 =
596 				(u8)(((pg_block & 0x78) << 1) +
597 				     ((0x1 << pg_block_index) ^ 0x0F));
598 		} else {
599 			pg_efuse_header =
600 				(u8)((pg_block << 4) +
601 				     ((0x01 << pg_block_index) ^ 0x0F));
602 		}
603 
604 		if ((offset & 1) == 0) {
605 			pg_efuse_byte1 = value;
606 			pg_efuse_byte2 = *(eeprom_map + offset + 1);
607 		} else {
608 			pg_efuse_byte1 = *(eeprom_map + offset - 1);
609 			pg_efuse_byte2 = value;
610 		}
611 
612 		if (offset > 0x7f) {
613 			pg_efuse_num = 4;
614 			if (halmac_adapter->hw_config_info.efuse_size <=
615 			    (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
616 			     halmac_adapter->efuse_end)) {
617 				kfree(eeprom_map);
618 				return HALMAC_RET_EFUSE_NOT_ENOUGH;
619 			}
620 			halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
621 						     pg_efuse_header);
622 			halmac_func_write_efuse_88xx(halmac_adapter,
623 						     efuse_end + 1,
624 						     pg_efuse_header2);
625 			halmac_func_write_efuse_88xx(
626 				halmac_adapter, efuse_end + 2, pg_efuse_byte1);
627 			status = halmac_func_write_efuse_88xx(
628 				halmac_adapter, efuse_end + 3, pg_efuse_byte2);
629 		} else {
630 			pg_efuse_num = 3;
631 			if (halmac_adapter->hw_config_info.efuse_size <=
632 			    (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
633 			     halmac_adapter->efuse_end)) {
634 				kfree(eeprom_map);
635 				return HALMAC_RET_EFUSE_NOT_ENOUGH;
636 			}
637 			halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
638 						     pg_efuse_header);
639 			halmac_func_write_efuse_88xx(
640 				halmac_adapter, efuse_end + 1, pg_efuse_byte1);
641 			status = halmac_func_write_efuse_88xx(
642 				halmac_adapter, efuse_end + 2, pg_efuse_byte2);
643 		}
644 
645 		if (status != HALMAC_RET_SUCCESS) {
646 			pr_err("[ERR]halmac_write_logical_efuse error = %x\n",
647 			       status);
648 			kfree(eeprom_map);
649 			return status;
650 		}
651 	}
652 
653 	kfree(eeprom_map);
654 
655 	return HALMAC_RET_SUCCESS;
656 }
657 
658 enum halmac_ret_status
halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,enum halmac_efuse_read_cfg cfg)659 halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
660 				 struct halmac_pg_efuse_info *pg_efuse_info,
661 				 enum halmac_efuse_read_cfg cfg)
662 {
663 	u8 *eeprom_mask_updated = NULL;
664 	u32 eeprom_mask_size = halmac_adapter->hw_config_info.eeprom_size >> 4;
665 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
666 
667 	eeprom_mask_updated = kzalloc(eeprom_mask_size, GFP_KERNEL);
668 	if (!eeprom_mask_updated)
669 		return HALMAC_RET_MALLOC_FAIL;
670 
671 	status = halmac_update_eeprom_mask_88xx(halmac_adapter, pg_efuse_info,
672 						eeprom_mask_updated);
673 
674 	if (status != HALMAC_RET_SUCCESS) {
675 		pr_err("[ERR]halmac_update_eeprom_mask_88xx error = %x\n",
676 		       status);
677 		kfree(eeprom_mask_updated);
678 		return status;
679 	}
680 
681 	status = halmac_check_efuse_enough_88xx(halmac_adapter, pg_efuse_info,
682 						eeprom_mask_updated);
683 
684 	if (status != HALMAC_RET_SUCCESS) {
685 		pr_err("[ERR]halmac_check_efuse_enough_88xx error = %x\n",
686 		       status);
687 		kfree(eeprom_mask_updated);
688 		return status;
689 	}
690 
691 	status = halmac_program_efuse_88xx(halmac_adapter, pg_efuse_info,
692 					   eeprom_mask_updated);
693 
694 	if (status != HALMAC_RET_SUCCESS) {
695 		pr_err("[ERR]halmac_program_efuse_88xx error = %x\n", status);
696 		kfree(eeprom_mask_updated);
697 		return status;
698 	}
699 
700 	kfree(eeprom_mask_updated);
701 
702 	return HALMAC_RET_SUCCESS;
703 }
704 
705 static enum halmac_ret_status
halmac_update_eeprom_mask_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,u8 * eeprom_mask_updated)706 halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
707 			       struct halmac_pg_efuse_info *pg_efuse_info,
708 			       u8 *eeprom_mask_updated)
709 {
710 	u8 *eeprom_map = NULL;
711 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
712 	u8 *eeprom_map_pg, *eeprom_mask;
713 	u16 i, j;
714 	u16 map_byte_offset, mask_byte_offset;
715 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
716 
717 	void *driver_adapter = NULL;
718 
719 	driver_adapter = halmac_adapter->driver_adapter;
720 
721 	eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
722 	if (!eeprom_map)
723 		return HALMAC_RET_MALLOC_FAIL;
724 
725 	memset(eeprom_map, 0xFF, eeprom_size);
726 	memset(eeprom_mask_updated, 0x00, pg_efuse_info->efuse_mask_size);
727 
728 	status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
729 
730 	if (status != HALMAC_RET_SUCCESS) {
731 		kfree(eeprom_map);
732 		return status;
733 	}
734 
735 	eeprom_map_pg = pg_efuse_info->efuse_map;
736 	eeprom_mask = pg_efuse_info->efuse_mask;
737 
738 	for (i = 0; i < pg_efuse_info->efuse_mask_size; i++)
739 		*(eeprom_mask_updated + i) = *(eeprom_mask + i);
740 
741 	for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 16) {
742 		for (j = 0; j < 16; j = j + 2) {
743 			map_byte_offset = i + j;
744 			mask_byte_offset = i >> 4;
745 			if (*(eeprom_map_pg + map_byte_offset) ==
746 			    *(eeprom_map + map_byte_offset)) {
747 				if (*(eeprom_map_pg + map_byte_offset + 1) ==
748 				    *(eeprom_map + map_byte_offset + 1)) {
749 					switch (j) {
750 					case 0:
751 						*(eeprom_mask_updated +
752 						  mask_byte_offset) =
753 							*(eeprom_mask_updated +
754 							  mask_byte_offset) &
755 							(BIT(4) ^ 0xFF);
756 						break;
757 					case 2:
758 						*(eeprom_mask_updated +
759 						  mask_byte_offset) =
760 							*(eeprom_mask_updated +
761 							  mask_byte_offset) &
762 							(BIT(5) ^ 0xFF);
763 						break;
764 					case 4:
765 						*(eeprom_mask_updated +
766 						  mask_byte_offset) =
767 							*(eeprom_mask_updated +
768 							  mask_byte_offset) &
769 							(BIT(6) ^ 0xFF);
770 						break;
771 					case 6:
772 						*(eeprom_mask_updated +
773 						  mask_byte_offset) =
774 							*(eeprom_mask_updated +
775 							  mask_byte_offset) &
776 							(BIT(7) ^ 0xFF);
777 						break;
778 					case 8:
779 						*(eeprom_mask_updated +
780 						  mask_byte_offset) =
781 							*(eeprom_mask_updated +
782 							  mask_byte_offset) &
783 							(BIT(0) ^ 0xFF);
784 						break;
785 					case 10:
786 						*(eeprom_mask_updated +
787 						  mask_byte_offset) =
788 							*(eeprom_mask_updated +
789 							  mask_byte_offset) &
790 							(BIT(1) ^ 0xFF);
791 						break;
792 					case 12:
793 						*(eeprom_mask_updated +
794 						  mask_byte_offset) =
795 							*(eeprom_mask_updated +
796 							  mask_byte_offset) &
797 							(BIT(2) ^ 0xFF);
798 						break;
799 					case 14:
800 						*(eeprom_mask_updated +
801 						  mask_byte_offset) =
802 							*(eeprom_mask_updated +
803 							  mask_byte_offset) &
804 							(BIT(3) ^ 0xFF);
805 						break;
806 					default:
807 						break;
808 					}
809 				}
810 			}
811 		}
812 	}
813 
814 	kfree(eeprom_map);
815 
816 	return status;
817 }
818 
819 static enum halmac_ret_status
halmac_check_efuse_enough_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,u8 * eeprom_mask_updated)820 halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
821 			       struct halmac_pg_efuse_info *pg_efuse_info,
822 			       u8 *eeprom_mask_updated)
823 {
824 	u8 pre_word_enb, word_enb;
825 	u8 pg_efuse_header, pg_efuse_header2;
826 	u8 pg_block;
827 	u16 i, j;
828 	u32 efuse_end;
829 	u32 tmp_eeprom_offset, pg_efuse_num = 0;
830 
831 	efuse_end = halmac_adapter->efuse_end;
832 
833 	for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
834 		tmp_eeprom_offset = i;
835 
836 		if ((tmp_eeprom_offset & 7) > 0) {
837 			pre_word_enb =
838 				(*(eeprom_mask_updated + (i >> 4)) & 0x0F);
839 			word_enb = pre_word_enb ^ 0x0F;
840 		} else {
841 			pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
842 			word_enb = pre_word_enb ^ 0x0F;
843 		}
844 
845 		pg_block = (u8)(tmp_eeprom_offset >> 3);
846 
847 		if (pre_word_enb > 0) {
848 			if (tmp_eeprom_offset > 0x7f) {
849 				pg_efuse_header =
850 					(((pg_block & 0x07) << 5) & 0xE0) |
851 					0x0F;
852 				pg_efuse_header2 = (u8)(
853 					((pg_block & 0x78) << 1) + word_enb);
854 			} else {
855 				pg_efuse_header =
856 					(u8)((pg_block << 4) + word_enb);
857 			}
858 
859 			if (tmp_eeprom_offset > 0x7f) {
860 				pg_efuse_num++;
861 				pg_efuse_num++;
862 				efuse_end = efuse_end + 2;
863 				for (j = 0; j < 4; j++) {
864 					if (((pre_word_enb >> j) & 0x1) > 0) {
865 						pg_efuse_num++;
866 						pg_efuse_num++;
867 						efuse_end = efuse_end + 2;
868 					}
869 				}
870 			} else {
871 				pg_efuse_num++;
872 				efuse_end = efuse_end + 1;
873 				for (j = 0; j < 4; j++) {
874 					if (((pre_word_enb >> j) & 0x1) > 0) {
875 						pg_efuse_num++;
876 						pg_efuse_num++;
877 						efuse_end = efuse_end + 2;
878 					}
879 				}
880 			}
881 		}
882 	}
883 
884 	if (halmac_adapter->hw_config_info.efuse_size <=
885 	    (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
886 	     halmac_adapter->efuse_end))
887 		return HALMAC_RET_EFUSE_NOT_ENOUGH;
888 
889 	return HALMAC_RET_SUCCESS;
890 }
891 
892 static enum halmac_ret_status
halmac_program_efuse_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,u8 * eeprom_mask_updated)893 halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
894 			  struct halmac_pg_efuse_info *pg_efuse_info,
895 			  u8 *eeprom_mask_updated)
896 {
897 	u8 pre_word_enb, word_enb;
898 	u8 pg_efuse_header, pg_efuse_header2;
899 	u8 pg_block;
900 	u16 i, j;
901 	u32 efuse_end;
902 	u32 tmp_eeprom_offset;
903 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
904 
905 	efuse_end = halmac_adapter->efuse_end;
906 
907 	for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
908 		tmp_eeprom_offset = i;
909 
910 		if (((tmp_eeprom_offset >> 3) & 1) > 0) {
911 			pre_word_enb =
912 				(*(eeprom_mask_updated + (i >> 4)) & 0x0F);
913 			word_enb = pre_word_enb ^ 0x0F;
914 		} else {
915 			pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
916 			word_enb = pre_word_enb ^ 0x0F;
917 		}
918 
919 		pg_block = (u8)(tmp_eeprom_offset >> 3);
920 
921 		if (pre_word_enb <= 0)
922 			continue;
923 
924 		if (tmp_eeprom_offset > 0x7f) {
925 			pg_efuse_header =
926 				(((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
927 			pg_efuse_header2 =
928 				(u8)(((pg_block & 0x78) << 1) + word_enb);
929 		} else {
930 			pg_efuse_header = (u8)((pg_block << 4) + word_enb);
931 		}
932 
933 		if (tmp_eeprom_offset > 0x7f) {
934 			halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
935 						     pg_efuse_header);
936 			status = halmac_func_write_efuse_88xx(halmac_adapter,
937 							      efuse_end + 1,
938 							      pg_efuse_header2);
939 			efuse_end = efuse_end + 2;
940 			for (j = 0; j < 4; j++) {
941 				if (((pre_word_enb >> j) & 0x1) > 0) {
942 					halmac_func_write_efuse_88xx(
943 						halmac_adapter, efuse_end,
944 						*(pg_efuse_info->efuse_map +
945 						  tmp_eeprom_offset +
946 						  (j << 1)));
947 					status = halmac_func_write_efuse_88xx(
948 						halmac_adapter, efuse_end + 1,
949 						*(pg_efuse_info->efuse_map +
950 						  tmp_eeprom_offset + (j << 1) +
951 						  1));
952 					efuse_end = efuse_end + 2;
953 				}
954 			}
955 		} else {
956 			status = halmac_func_write_efuse_88xx(
957 				halmac_adapter, efuse_end, pg_efuse_header);
958 			efuse_end = efuse_end + 1;
959 			for (j = 0; j < 4; j++) {
960 				if (((pre_word_enb >> j) & 0x1) > 0) {
961 					halmac_func_write_efuse_88xx(
962 						halmac_adapter, efuse_end,
963 						*(pg_efuse_info->efuse_map +
964 						  tmp_eeprom_offset +
965 						  (j << 1)));
966 					status = halmac_func_write_efuse_88xx(
967 						halmac_adapter, efuse_end + 1,
968 						*(pg_efuse_info->efuse_map +
969 						  tmp_eeprom_offset + (j << 1) +
970 						  1));
971 					efuse_end = efuse_end + 2;
972 				}
973 			}
974 		}
975 	}
976 
977 	return status;
978 }
979 
980 enum halmac_ret_status
halmac_dlfw_to_mem_88xx(struct halmac_adapter * halmac_adapter,u8 * ram_code,u32 dest,u32 code_size)981 halmac_dlfw_to_mem_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
982 			u32 dest, u32 code_size)
983 {
984 	u8 *code_ptr;
985 	u8 first_part;
986 	u32 mem_offset;
987 	u32 pkt_size_tmp, send_pkt_size;
988 	void *driver_adapter = NULL;
989 	struct halmac_api *halmac_api;
990 
991 	driver_adapter = halmac_adapter->driver_adapter;
992 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
993 
994 	code_ptr = ram_code;
995 	mem_offset = 0;
996 	first_part = 1;
997 	pkt_size_tmp = code_size;
998 
999 	HALMAC_REG_WRITE_32(
1000 		halmac_adapter, REG_DDMA_CH0CTRL,
1001 		HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) |
1002 			BIT_DDMACH0_RESET_CHKSUM_STS);
1003 
1004 	while (pkt_size_tmp != 0) {
1005 		if (pkt_size_tmp >= halmac_adapter->max_download_size)
1006 			send_pkt_size = halmac_adapter->max_download_size;
1007 		else
1008 			send_pkt_size = pkt_size_tmp;
1009 
1010 		if (halmac_send_fwpkt_88xx(
1011 			    halmac_adapter, code_ptr + mem_offset,
1012 			    send_pkt_size) != HALMAC_RET_SUCCESS) {
1013 			pr_err("halmac_send_fwpkt_88xx fail!!\n");
1014 			return HALMAC_RET_DLFW_FAIL;
1015 		}
1016 
1017 		if (halmac_iddma_dlfw_88xx(
1018 			    halmac_adapter,
1019 			    HALMAC_OCPBASE_TXBUF_88XX +
1020 				    halmac_adapter->hw_config_info.txdesc_size,
1021 			    dest + mem_offset, send_pkt_size,
1022 			    first_part) != HALMAC_RET_SUCCESS) {
1023 			pr_err("halmac_iddma_dlfw_88xx fail!!\n");
1024 			return HALMAC_RET_DLFW_FAIL;
1025 		}
1026 
1027 		first_part = 0;
1028 		mem_offset += send_pkt_size;
1029 		pkt_size_tmp -= send_pkt_size;
1030 	}
1031 
1032 	if (halmac_check_fw_chksum_88xx(halmac_adapter, dest) !=
1033 	    HALMAC_RET_SUCCESS) {
1034 		pr_err("halmac_check_fw_chksum_88xx fail!!\n");
1035 		return HALMAC_RET_DLFW_FAIL;
1036 	}
1037 
1038 	return HALMAC_RET_SUCCESS;
1039 }
1040 
1041 enum halmac_ret_status
halmac_send_fwpkt_88xx(struct halmac_adapter * halmac_adapter,u8 * ram_code,u32 code_size)1042 halmac_send_fwpkt_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
1043 		       u32 code_size)
1044 {
1045 	if (halmac_download_rsvd_page_88xx(halmac_adapter, ram_code,
1046 					   code_size) != HALMAC_RET_SUCCESS) {
1047 		pr_err("PLATFORM_SEND_RSVD_PAGE 0 error!!\n");
1048 		return HALMAC_RET_DL_RSVD_PAGE_FAIL;
1049 	}
1050 
1051 	return HALMAC_RET_SUCCESS;
1052 }
1053 
1054 enum halmac_ret_status
halmac_iddma_dlfw_88xx(struct halmac_adapter * halmac_adapter,u32 source,u32 dest,u32 length,u8 first)1055 halmac_iddma_dlfw_88xx(struct halmac_adapter *halmac_adapter, u32 source,
1056 		       u32 dest, u32 length, u8 first)
1057 {
1058 	u32 counter;
1059 	u32 ch0_control = (u32)(BIT_DDMACH0_CHKSUM_EN | BIT_DDMACH0_OWN);
1060 	void *driver_adapter = NULL;
1061 	struct halmac_api *halmac_api;
1062 
1063 	driver_adapter = halmac_adapter->driver_adapter;
1064 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1065 
1066 	counter = HALMC_DDMA_POLLING_COUNT;
1067 	while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1068 	       BIT_DDMACH0_OWN) {
1069 		counter--;
1070 		if (counter == 0) {
1071 			pr_err("%s error-1!!\n", __func__);
1072 			return HALMAC_RET_DDMA_FAIL;
1073 		}
1074 	}
1075 
1076 	ch0_control |= (length & BIT_MASK_DDMACH0_DLEN);
1077 	if (first == 0)
1078 		ch0_control |= BIT_DDMACH0_CHKSUM_CONT;
1079 
1080 	HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0SA, source);
1081 	HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0DA, dest);
1082 	HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0CTRL, ch0_control);
1083 
1084 	counter = HALMC_DDMA_POLLING_COUNT;
1085 	while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1086 	       BIT_DDMACH0_OWN) {
1087 		counter--;
1088 		if (counter == 0) {
1089 			pr_err("%s error-2!!\n", __func__);
1090 			return HALMAC_RET_DDMA_FAIL;
1091 		}
1092 	}
1093 
1094 	return HALMAC_RET_SUCCESS;
1095 }
1096 
1097 enum halmac_ret_status
halmac_check_fw_chksum_88xx(struct halmac_adapter * halmac_adapter,u32 memory_address)1098 halmac_check_fw_chksum_88xx(struct halmac_adapter *halmac_adapter,
1099 			    u32 memory_address)
1100 {
1101 	u8 mcu_fw_ctrl;
1102 	void *driver_adapter = NULL;
1103 	struct halmac_api *halmac_api;
1104 	enum halmac_ret_status status;
1105 
1106 	driver_adapter = halmac_adapter->driver_adapter;
1107 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1108 
1109 	mcu_fw_ctrl = HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL);
1110 
1111 	if (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1112 	    BIT_DDMACH0_CHKSUM_STS) {
1113 		if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
1114 			mcu_fw_ctrl |= BIT_IMEM_DW_OK;
1115 			HALMAC_REG_WRITE_8(
1116 				halmac_adapter, REG_MCUFW_CTRL,
1117 				(u8)(mcu_fw_ctrl & ~(BIT_IMEM_CHKSUM_OK)));
1118 		} else {
1119 			mcu_fw_ctrl |= BIT_DMEM_DW_OK;
1120 			HALMAC_REG_WRITE_8(
1121 				halmac_adapter, REG_MCUFW_CTRL,
1122 				(u8)(mcu_fw_ctrl & ~(BIT_DMEM_CHKSUM_OK)));
1123 		}
1124 
1125 		pr_err("%s error!!\n", __func__);
1126 
1127 		status = HALMAC_RET_FW_CHECKSUM_FAIL;
1128 	} else {
1129 		if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
1130 			mcu_fw_ctrl |= BIT_IMEM_DW_OK;
1131 			HALMAC_REG_WRITE_8(
1132 				halmac_adapter, REG_MCUFW_CTRL,
1133 				(u8)(mcu_fw_ctrl | BIT_IMEM_CHKSUM_OK));
1134 		} else {
1135 			mcu_fw_ctrl |= BIT_DMEM_DW_OK;
1136 			HALMAC_REG_WRITE_8(
1137 				halmac_adapter, REG_MCUFW_CTRL,
1138 				(u8)(mcu_fw_ctrl | BIT_DMEM_CHKSUM_OK));
1139 		}
1140 
1141 		status = HALMAC_RET_SUCCESS;
1142 	}
1143 
1144 	return status;
1145 }
1146 
1147 enum halmac_ret_status
halmac_dlfw_end_flow_88xx(struct halmac_adapter * halmac_adapter)1148 halmac_dlfw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
1149 {
1150 	u8 value8;
1151 	u32 counter;
1152 	void *driver_adapter = halmac_adapter->driver_adapter;
1153 	struct halmac_api *halmac_api =
1154 		(struct halmac_api *)halmac_adapter->halmac_api;
1155 
1156 	HALMAC_REG_WRITE_32(halmac_adapter, REG_TXDMA_STATUS, BIT(2));
1157 
1158 	/* Check IMEM & DMEM checksum is OK or not */
1159 	if ((HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) & 0x50) == 0x50)
1160 		HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
1161 				    (u16)(HALMAC_REG_READ_16(halmac_adapter,
1162 							     REG_MCUFW_CTRL) |
1163 					  BIT_FW_DW_RDY));
1164 	else
1165 		return HALMAC_RET_DLFW_FAIL;
1166 
1167 	HALMAC_REG_WRITE_8(
1168 		halmac_adapter, REG_MCUFW_CTRL,
1169 		(u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
1170 		     ~(BIT(0))));
1171 
1172 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
1173 	value8 = (u8)(value8 | BIT(0));
1174 	HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
1175 
1176 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
1177 	value8 = (u8)(value8 | BIT(2));
1178 	HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
1179 			   value8); /* Release MCU reset */
1180 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1181 			"Download Finish, Reset CPU\n");
1182 
1183 	counter = 10000;
1184 	while (HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) != 0xC078) {
1185 		if (counter == 0) {
1186 			pr_err("Check 0x80 = 0xC078 fail\n");
1187 			if ((HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG7) &
1188 			     0xFFFFFF00) == 0xFAAAAA00)
1189 				pr_err("Key fail\n");
1190 			return HALMAC_RET_DLFW_FAIL;
1191 		}
1192 		counter--;
1193 		usleep_range(50, 60);
1194 	}
1195 
1196 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1197 			"Check 0x80 = 0xC078 counter = %d\n", counter);
1198 
1199 	return HALMAC_RET_SUCCESS;
1200 }
1201 
1202 enum halmac_ret_status
halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter * halmac_adapter)1203 halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
1204 {
1205 	u32 counter;
1206 	struct halmac_api *halmac_api =
1207 		(struct halmac_api *)halmac_adapter->halmac_api;
1208 
1209 	counter = 100;
1210 	while (HALMAC_REG_READ_8(halmac_adapter, REG_HMETFR + 3) != 0) {
1211 		counter--;
1212 		if (counter == 0) {
1213 			pr_err("[ERR]0x1CF != 0\n");
1214 			return HALMAC_RET_DLFW_FAIL;
1215 		}
1216 		usleep_range(50, 60);
1217 	}
1218 
1219 	HALMAC_REG_WRITE_8(halmac_adapter, REG_HMETFR + 3,
1220 			   ID_INFORM_DLEMEM_RDY);
1221 
1222 	counter = 10000;
1223 	while (HALMAC_REG_READ_8(halmac_adapter, REG_C2HEVT_3 + 3) !=
1224 	       ID_INFORM_DLEMEM_RDY) {
1225 		counter--;
1226 		if (counter == 0) {
1227 			pr_err("[ERR]0x1AF != 0x80\n");
1228 			return HALMAC_RET_DLFW_FAIL;
1229 		}
1230 		usleep_range(50, 60);
1231 	}
1232 
1233 	HALMAC_REG_WRITE_8(halmac_adapter, REG_C2HEVT_3 + 3, 0);
1234 
1235 	return HALMAC_RET_SUCCESS;
1236 }
1237 
1238 enum halmac_ret_status
halmac_pwr_seq_parser_88xx(struct halmac_adapter * halmac_adapter,u8 cut,u8 fab,u8 intf,struct halmac_wl_pwr_cfg_ ** pp_pwr_seq_cfg)1239 halmac_pwr_seq_parser_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
1240 			   u8 fab, u8 intf,
1241 			   struct halmac_wl_pwr_cfg_ **pp_pwr_seq_cfg)
1242 {
1243 	u32 seq_idx = 0;
1244 	void *driver_adapter = NULL;
1245 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1246 	struct halmac_wl_pwr_cfg_ *seq_cmd;
1247 
1248 	driver_adapter = halmac_adapter->driver_adapter;
1249 
1250 	do {
1251 		seq_cmd = pp_pwr_seq_cfg[seq_idx];
1252 
1253 		if (!seq_cmd)
1254 			break;
1255 
1256 		status = halmac_pwr_sub_seq_parer_88xx(halmac_adapter, cut, fab,
1257 						       intf, seq_cmd);
1258 		if (status != HALMAC_RET_SUCCESS) {
1259 			pr_err("[Err]pwr sub seq parser fail, status = 0x%X!\n",
1260 			       status);
1261 			return status;
1262 		}
1263 
1264 		seq_idx++;
1265 	} while (1);
1266 
1267 	return status;
1268 }
1269 
1270 static enum halmac_ret_status
halmac_pwr_sub_seq_parer_do_cmd_88xx(struct halmac_adapter * halmac_adapter,struct halmac_wl_pwr_cfg_ * sub_seq_cmd,bool * reti)1271 halmac_pwr_sub_seq_parer_do_cmd_88xx(struct halmac_adapter *halmac_adapter,
1272 				     struct halmac_wl_pwr_cfg_ *sub_seq_cmd,
1273 				     bool *reti)
1274 {
1275 	void *driver_adapter = NULL;
1276 	struct halmac_api *halmac_api;
1277 	u8 value, flag;
1278 	u8 polling_bit;
1279 	u32 polling_count;
1280 	static u32 poll_to_static;
1281 	u32 offset;
1282 
1283 	driver_adapter = halmac_adapter->driver_adapter;
1284 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1285 	*reti = true;
1286 
1287 	switch (sub_seq_cmd->cmd) {
1288 	case HALMAC_PWR_CMD_WRITE:
1289 		if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
1290 			offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
1291 		else
1292 			offset = sub_seq_cmd->offset;
1293 
1294 		value = HALMAC_REG_READ_8(halmac_adapter, offset);
1295 		value = (u8)(value & (u8)(~(sub_seq_cmd->msk)));
1296 		value = (u8)(value |
1297 			     (u8)(sub_seq_cmd->value & sub_seq_cmd->msk));
1298 
1299 		HALMAC_REG_WRITE_8(halmac_adapter, offset, value);
1300 		break;
1301 	case HALMAC_PWR_CMD_POLLING:
1302 		polling_bit = 0;
1303 		polling_count = HALMAC_POLLING_READY_TIMEOUT_COUNT;
1304 		flag = 0;
1305 
1306 		if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
1307 			offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
1308 		else
1309 			offset = sub_seq_cmd->offset;
1310 
1311 		do {
1312 			polling_count--;
1313 			value = HALMAC_REG_READ_8(halmac_adapter, offset);
1314 			value = (u8)(value & sub_seq_cmd->msk);
1315 
1316 			if (value == (sub_seq_cmd->value & sub_seq_cmd->msk)) {
1317 				polling_bit = 1;
1318 				continue;
1319 			}
1320 
1321 			if (polling_count != 0) {
1322 				usleep_range(50, 60);
1323 				continue;
1324 			}
1325 
1326 			if (halmac_adapter->halmac_interface ==
1327 				    HALMAC_INTERFACE_PCIE &&
1328 			    flag == 0) {
1329 				/* For PCIE + USB package poll power bit
1330 				 * timeout issue
1331 				 */
1332 				poll_to_static++;
1333 				HALMAC_RT_TRACE(
1334 					driver_adapter, HALMAC_MSG_PWR,
1335 					DBG_WARNING,
1336 					"[WARN]PCIE polling timeout : %d!!\n",
1337 					poll_to_static);
1338 				HALMAC_REG_WRITE_8(
1339 					halmac_adapter, REG_SYS_PW_CTRL,
1340 					HALMAC_REG_READ_8(halmac_adapter,
1341 							  REG_SYS_PW_CTRL) |
1342 						BIT(3));
1343 				HALMAC_REG_WRITE_8(
1344 					halmac_adapter, REG_SYS_PW_CTRL,
1345 					HALMAC_REG_READ_8(halmac_adapter,
1346 							  REG_SYS_PW_CTRL) &
1347 						~BIT(3));
1348 				polling_bit = 0;
1349 				polling_count =
1350 					HALMAC_POLLING_READY_TIMEOUT_COUNT;
1351 				flag = 1;
1352 			} else {
1353 				pr_err("[ERR]Pwr cmd polling timeout!!\n");
1354 				pr_err("[ERR]Pwr cmd offset : %X!!\n",
1355 				       sub_seq_cmd->offset);
1356 				pr_err("[ERR]Pwr cmd value : %X!!\n",
1357 				       sub_seq_cmd->value);
1358 				pr_err("[ERR]Pwr cmd msk : %X!!\n",
1359 				       sub_seq_cmd->msk);
1360 				pr_err("[ERR]Read offset = %X value = %X!!\n",
1361 				       offset, value);
1362 				return HALMAC_RET_PWRSEQ_POLLING_FAIL;
1363 			}
1364 		} while (!polling_bit);
1365 		break;
1366 	case HALMAC_PWR_CMD_DELAY:
1367 		if (sub_seq_cmd->value == HALMAC_PWRSEQ_DELAY_US)
1368 			udelay(sub_seq_cmd->offset);
1369 		else
1370 			usleep_range(1000 * sub_seq_cmd->offset,
1371 				     1000 * sub_seq_cmd->offset + 100);
1372 
1373 		break;
1374 	case HALMAC_PWR_CMD_READ:
1375 		break;
1376 	case HALMAC_PWR_CMD_END:
1377 		return HALMAC_RET_SUCCESS;
1378 	default:
1379 		return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
1380 	}
1381 
1382 	*reti = false;
1383 
1384 	return HALMAC_RET_SUCCESS;
1385 }
1386 
1387 static enum halmac_ret_status
halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter * halmac_adapter,u8 cut,u8 fab,u8 intf,struct halmac_wl_pwr_cfg_ * pwr_sub_seq_cfg)1388 halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
1389 			      u8 fab, u8 intf,
1390 			      struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg)
1391 {
1392 	struct halmac_wl_pwr_cfg_ *sub_seq_cmd;
1393 	bool reti;
1394 	enum halmac_ret_status status;
1395 
1396 	for (sub_seq_cmd = pwr_sub_seq_cfg;; sub_seq_cmd++) {
1397 		if ((sub_seq_cmd->interface_msk & intf) &&
1398 		    (sub_seq_cmd->fab_msk & fab) &&
1399 		    (sub_seq_cmd->cut_msk & cut)) {
1400 			status = halmac_pwr_sub_seq_parer_do_cmd_88xx(
1401 				halmac_adapter, sub_seq_cmd, &reti);
1402 
1403 			if (reti)
1404 				return status;
1405 		}
1406 	}
1407 
1408 	return HALMAC_RET_SUCCESS;
1409 }
1410 
1411 enum halmac_ret_status
halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter * halmac_adapter)1412 halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter *halmac_adapter)
1413 {
1414 	u32 hw_wptr, fw_rptr;
1415 	struct halmac_api *halmac_api =
1416 		(struct halmac_api *)halmac_adapter->halmac_api;
1417 
1418 	hw_wptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_WRITEADDR) &
1419 		  BIT_MASK_H2C_WR_ADDR;
1420 	fw_rptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_READADDR) &
1421 		  BIT_MASK_H2C_READ_ADDR;
1422 
1423 	if (hw_wptr >= fw_rptr)
1424 		halmac_adapter->h2c_buf_free_space =
1425 			halmac_adapter->h2c_buff_size - (hw_wptr - fw_rptr);
1426 	else
1427 		halmac_adapter->h2c_buf_free_space = fw_rptr - hw_wptr;
1428 
1429 	return HALMAC_RET_SUCCESS;
1430 }
1431 
1432 enum halmac_ret_status
halmac_send_h2c_pkt_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_h2c_cmd,u32 size,bool ack)1433 halmac_send_h2c_pkt_88xx(struct halmac_adapter *halmac_adapter, u8 *hal_h2c_cmd,
1434 			 u32 size, bool ack)
1435 {
1436 	u32 counter = 100;
1437 	void *driver_adapter = halmac_adapter->driver_adapter;
1438 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1439 
1440 	while (halmac_adapter->h2c_buf_free_space <=
1441 	       HALMAC_H2C_CMD_SIZE_UNIT_88XX) {
1442 		halmac_get_h2c_buff_free_space_88xx(halmac_adapter);
1443 		counter--;
1444 		if (counter == 0) {
1445 			pr_err("h2c free space is not enough!!\n");
1446 			return HALMAC_RET_H2C_SPACE_FULL;
1447 		}
1448 	}
1449 
1450 	/* Send TxDesc + H2C_CMD */
1451 	if (!PLATFORM_SEND_H2C_PKT(driver_adapter, hal_h2c_cmd, size)) {
1452 		pr_err("Send H2C_CMD pkt error!!\n");
1453 		return HALMAC_RET_SEND_H2C_FAIL;
1454 	}
1455 
1456 	halmac_adapter->h2c_buf_free_space -= HALMAC_H2C_CMD_SIZE_UNIT_88XX;
1457 
1458 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1459 			"H2C free space : %d\n",
1460 			halmac_adapter->h2c_buf_free_space);
1461 
1462 	return status;
1463 }
1464 
1465 enum halmac_ret_status
halmac_download_rsvd_page_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_buf,u32 size)1466 halmac_download_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
1467 			       u8 *hal_buf, u32 size)
1468 {
1469 	u8 restore[3];
1470 	u8 value8;
1471 	u32 counter;
1472 	void *driver_adapter = NULL;
1473 	struct halmac_api *halmac_api;
1474 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1475 
1476 	driver_adapter = halmac_adapter->driver_adapter;
1477 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1478 
1479 	if (size == 0) {
1480 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1481 				"Rsvd page packet size is zero!!\n");
1482 		return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
1483 	}
1484 
1485 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
1486 	value8 = (u8)(value8 | BIT(7));
1487 	HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1, value8);
1488 
1489 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
1490 	restore[0] = value8;
1491 	value8 = (u8)(value8 | BIT(0));
1492 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, value8);
1493 
1494 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
1495 	restore[1] = value8;
1496 	value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
1497 	HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, value8);
1498 
1499 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
1500 	restore[2] = value8;
1501 	value8 = (u8)(value8 & ~(BIT(6)));
1502 	HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, value8);
1503 
1504 	if (!PLATFORM_SEND_RSVD_PAGE(driver_adapter, hal_buf, size)) {
1505 		pr_err("PLATFORM_SEND_RSVD_PAGE 1 error!!\n");
1506 		status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
1507 	}
1508 
1509 	/* Check Bcn_Valid_Bit */
1510 	counter = 1000;
1511 	while (!(HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1) &
1512 		 BIT(7))) {
1513 		udelay(10);
1514 		counter--;
1515 		if (counter == 0) {
1516 			pr_err("Polling Bcn_Valid_Fail error!!\n");
1517 			status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
1518 			break;
1519 		}
1520 	}
1521 
1522 	value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
1523 	HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1,
1524 			   (value8 | BIT(7)));
1525 
1526 	HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, restore[2]);
1527 	HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, restore[1]);
1528 	HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, restore[0]);
1529 
1530 	return status;
1531 }
1532 
1533 enum halmac_ret_status
halmac_set_h2c_header_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_h2c_hdr,u16 * seq,bool ack)1534 halmac_set_h2c_header_88xx(struct halmac_adapter *halmac_adapter,
1535 			   u8 *hal_h2c_hdr, u16 *seq, bool ack)
1536 {
1537 	void *driver_adapter = halmac_adapter->driver_adapter;
1538 
1539 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1540 			"%s!!\n", __func__);
1541 
1542 	H2C_CMD_HEADER_SET_CATEGORY(hal_h2c_hdr, 0x00);
1543 	H2C_CMD_HEADER_SET_TOTAL_LEN(hal_h2c_hdr, 16);
1544 
1545 	spin_lock(&halmac_adapter->h2c_seq_lock);
1546 	H2C_CMD_HEADER_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
1547 	*seq = halmac_adapter->h2c_packet_seq;
1548 	halmac_adapter->h2c_packet_seq++;
1549 	spin_unlock(&halmac_adapter->h2c_seq_lock);
1550 
1551 	if (ack)
1552 		H2C_CMD_HEADER_SET_ACK(hal_h2c_hdr, 1);
1553 
1554 	return HALMAC_RET_SUCCESS;
1555 }
1556 
halmac_set_fw_offload_h2c_header_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_h2c_hdr,struct halmac_h2c_header_info * h2c_header_info,u16 * seq_num)1557 enum halmac_ret_status halmac_set_fw_offload_h2c_header_88xx(
1558 	struct halmac_adapter *halmac_adapter, u8 *hal_h2c_hdr,
1559 	struct halmac_h2c_header_info *h2c_header_info, u16 *seq_num)
1560 {
1561 	void *driver_adapter = halmac_adapter->driver_adapter;
1562 
1563 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1564 			"%s!!\n", __func__);
1565 
1566 	FW_OFFLOAD_H2C_SET_TOTAL_LEN(hal_h2c_hdr,
1567 				     8 + h2c_header_info->content_size);
1568 	FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hal_h2c_hdr, h2c_header_info->sub_cmd_id);
1569 
1570 	FW_OFFLOAD_H2C_SET_CATEGORY(hal_h2c_hdr, 0x01);
1571 	FW_OFFLOAD_H2C_SET_CMD_ID(hal_h2c_hdr, 0xFF);
1572 
1573 	spin_lock(&halmac_adapter->h2c_seq_lock);
1574 	FW_OFFLOAD_H2C_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
1575 	*seq_num = halmac_adapter->h2c_packet_seq;
1576 	halmac_adapter->h2c_packet_seq++;
1577 	spin_unlock(&halmac_adapter->h2c_seq_lock);
1578 
1579 	if (h2c_header_info->ack)
1580 		FW_OFFLOAD_H2C_SET_ACK(hal_h2c_hdr, 1);
1581 
1582 	return HALMAC_RET_SUCCESS;
1583 }
1584 
1585 enum halmac_ret_status
halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter * halmac_adapter,struct halmac_fwlps_option * hal_fw_lps_opt)1586 halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter *halmac_adapter,
1587 				  struct halmac_fwlps_option *hal_fw_lps_opt)
1588 {
1589 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX];
1590 	u8 *h2c_header, *h2c_cmd;
1591 	u16 seq = 0;
1592 	void *driver_adapter = NULL;
1593 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1594 
1595 	driver_adapter = halmac_adapter->driver_adapter;
1596 
1597 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1598 			"%s!!\n", __func__);
1599 
1600 	h2c_header = h2c_buff;
1601 	h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1602 
1603 	memset(h2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1604 
1605 	SET_PWR_MODE_SET_CMD_ID(h2c_cmd, CMD_ID_SET_PWR_MODE);
1606 	SET_PWR_MODE_SET_CLASS(h2c_cmd, CLASS_SET_PWR_MODE);
1607 	SET_PWR_MODE_SET_MODE(h2c_cmd, hal_fw_lps_opt->mode);
1608 	SET_PWR_MODE_SET_CLK_REQUEST(h2c_cmd, hal_fw_lps_opt->clk_request);
1609 	SET_PWR_MODE_SET_RLBM(h2c_cmd, hal_fw_lps_opt->rlbm);
1610 	SET_PWR_MODE_SET_SMART_PS(h2c_cmd, hal_fw_lps_opt->smart_ps);
1611 	SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_cmd,
1612 					hal_fw_lps_opt->awake_interval);
1613 	SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(h2c_cmd,
1614 					   hal_fw_lps_opt->all_queue_uapsd);
1615 	SET_PWR_MODE_SET_PWR_STATE(h2c_cmd, hal_fw_lps_opt->pwr_state);
1616 	SET_PWR_MODE_SET_ANT_AUTO_SWITCH(h2c_cmd,
1617 					 hal_fw_lps_opt->ant_auto_switch);
1618 	SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(
1619 		h2c_cmd, hal_fw_lps_opt->ps_allow_bt_high_priority);
1620 	SET_PWR_MODE_SET_PROTECT_BCN(h2c_cmd, hal_fw_lps_opt->protect_bcn);
1621 	SET_PWR_MODE_SET_SILENCE_PERIOD(h2c_cmd,
1622 					hal_fw_lps_opt->silence_period);
1623 	SET_PWR_MODE_SET_FAST_BT_CONNECT(h2c_cmd,
1624 					 hal_fw_lps_opt->fast_bt_connect);
1625 	SET_PWR_MODE_SET_TWO_ANTENNA_EN(h2c_cmd,
1626 					hal_fw_lps_opt->two_antenna_en);
1627 	SET_PWR_MODE_SET_ADOPT_USER_SETTING(h2c_cmd,
1628 					    hal_fw_lps_opt->adopt_user_setting);
1629 	SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(
1630 		h2c_cmd, hal_fw_lps_opt->drv_bcn_early_shift);
1631 
1632 	halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1633 
1634 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1635 					  HALMAC_H2C_CMD_SIZE_88XX, true);
1636 
1637 	if (status != HALMAC_RET_SUCCESS) {
1638 		pr_err("%s Fail = %x!!\n", __func__, status);
1639 		return status;
1640 	}
1641 
1642 	return HALMAC_RET_SUCCESS;
1643 }
1644 
1645 enum halmac_ret_status
halmac_func_send_original_h2c_88xx(struct halmac_adapter * halmac_adapter,u8 * original_h2c,u16 * seq,u8 ack)1646 halmac_func_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
1647 				   u8 *original_h2c, u16 *seq, u8 ack)
1648 {
1649 	u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1650 	u8 *h2c_header, *h2c_cmd;
1651 	void *driver_adapter = NULL;
1652 	struct halmac_api *halmac_api;
1653 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1654 
1655 	driver_adapter = halmac_adapter->driver_adapter;
1656 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1657 
1658 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1659 			"halmac_send_original_h2c ==========>\n");
1660 
1661 	h2c_header = H2c_buff;
1662 	h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1663 	memcpy(h2c_cmd, original_h2c, 8); /* Original H2C 8 byte */
1664 
1665 	halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, seq, ack);
1666 
1667 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1668 					  HALMAC_H2C_CMD_SIZE_88XX, ack);
1669 
1670 	if (status != HALMAC_RET_SUCCESS) {
1671 		pr_err("halmac_send_original_h2c Fail = %x!!\n", status);
1672 		return status;
1673 	}
1674 
1675 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1676 			"halmac_send_original_h2c <==========\n");
1677 
1678 	return HALMAC_RET_SUCCESS;
1679 }
1680 
1681 enum halmac_ret_status
halmac_media_status_rpt_88xx(struct halmac_adapter * halmac_adapter,u8 op_mode,u8 mac_id_ind,u8 mac_id,u8 mac_id_end)1682 halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode,
1683 			     u8 mac_id_ind, u8 mac_id, u8 mac_id_end)
1684 {
1685 	u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1686 	u8 *h2c_header, *h2c_cmd;
1687 	u16 seq = 0;
1688 	void *driver_adapter = NULL;
1689 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1690 
1691 	driver_adapter = halmac_adapter->driver_adapter;
1692 
1693 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1694 			"halmac_send_h2c_set_pwr_mode_88xx!!\n");
1695 
1696 	h2c_header = H2c_buff;
1697 	h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1698 
1699 	memset(H2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1700 
1701 	MEDIA_STATUS_RPT_SET_CMD_ID(h2c_cmd, CMD_ID_MEDIA_STATUS_RPT);
1702 	MEDIA_STATUS_RPT_SET_CLASS(h2c_cmd, CLASS_MEDIA_STATUS_RPT);
1703 	MEDIA_STATUS_RPT_SET_OP_MODE(h2c_cmd, op_mode);
1704 	MEDIA_STATUS_RPT_SET_MACID_IN(h2c_cmd, mac_id_ind);
1705 	MEDIA_STATUS_RPT_SET_MACID(h2c_cmd, mac_id);
1706 	MEDIA_STATUS_RPT_SET_MACID_END(h2c_cmd, mac_id_end);
1707 
1708 	halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1709 
1710 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1711 					  HALMAC_H2C_CMD_SIZE_88XX, true);
1712 
1713 	if (status != HALMAC_RET_SUCCESS) {
1714 		pr_err("%s Fail = %x!!\n", __func__, status);
1715 		return status;
1716 	}
1717 
1718 	return HALMAC_RET_SUCCESS;
1719 }
1720 
1721 enum halmac_ret_status
halmac_send_h2c_update_packet_88xx(struct halmac_adapter * halmac_adapter,enum halmac_packet_id pkt_id,u8 * pkt,u32 pkt_size)1722 halmac_send_h2c_update_packet_88xx(struct halmac_adapter *halmac_adapter,
1723 				   enum halmac_packet_id pkt_id, u8 *pkt,
1724 				   u32 pkt_size)
1725 {
1726 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1727 	u16 h2c_seq_mum = 0;
1728 	void *driver_adapter = NULL;
1729 	struct halmac_api *halmac_api;
1730 	struct halmac_h2c_header_info h2c_header_info;
1731 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
1732 
1733 	driver_adapter = halmac_adapter->driver_adapter;
1734 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1735 
1736 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1737 			    (u16)(halmac_adapter->txff_allocation
1738 					  .rsvd_h2c_extra_info_pg_bndy &
1739 				  BIT_MASK_BCN_HEAD_1_V1));
1740 
1741 	ret_status =
1742 		halmac_download_rsvd_page_88xx(halmac_adapter, pkt, pkt_size);
1743 
1744 	if (ret_status != HALMAC_RET_SUCCESS) {
1745 		pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
1746 		       ret_status);
1747 		HALMAC_REG_WRITE_16(
1748 			halmac_adapter, REG_FIFOPAGE_CTRL_2,
1749 			(u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1750 			      BIT_MASK_BCN_HEAD_1_V1));
1751 		return ret_status;
1752 	}
1753 
1754 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1755 			    (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1756 				  BIT_MASK_BCN_HEAD_1_V1));
1757 
1758 	UPDATE_PACKET_SET_SIZE(
1759 		h2c_buff,
1760 		pkt_size + halmac_adapter->hw_config_info.txdesc_size);
1761 	UPDATE_PACKET_SET_PACKET_ID(h2c_buff, pkt_id);
1762 	UPDATE_PACKET_SET_PACKET_LOC(
1763 		h2c_buff,
1764 		halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
1765 			halmac_adapter->txff_allocation.rsvd_pg_bndy);
1766 
1767 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PACKET;
1768 	h2c_header_info.content_size = 8;
1769 	h2c_header_info.ack = true;
1770 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1771 					      &h2c_header_info, &h2c_seq_mum);
1772 	halmac_adapter->halmac_state.update_packet_set.seq_num = h2c_seq_mum;
1773 
1774 	ret_status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1775 					      HALMAC_H2C_CMD_SIZE_88XX, true);
1776 
1777 	if (ret_status != HALMAC_RET_SUCCESS) {
1778 		pr_err("%s Fail = %x!!\n", __func__, ret_status);
1779 		return ret_status;
1780 	}
1781 
1782 	return ret_status;
1783 }
1784 
1785 enum halmac_ret_status
halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter * halmac_adapter,struct halmac_phy_parameter_info * para_info,bool full_fifo)1786 halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter *halmac_adapter,
1787 				   struct halmac_phy_parameter_info *para_info,
1788 				   bool full_fifo)
1789 {
1790 	bool drv_trigger_send = false;
1791 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1792 	u16 h2c_seq_mum = 0;
1793 	u32 info_size = 0;
1794 	void *driver_adapter = NULL;
1795 	struct halmac_api *halmac_api;
1796 	struct halmac_h2c_header_info h2c_header_info;
1797 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1798 	struct halmac_config_para_info *config_para_info;
1799 
1800 	driver_adapter = halmac_adapter->driver_adapter;
1801 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1802 	config_para_info = &halmac_adapter->config_para_info;
1803 
1804 	if (!config_para_info->cfg_para_buf) {
1805 		if (full_fifo)
1806 			config_para_info->para_buf_size =
1807 				HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_88XX;
1808 		else
1809 			config_para_info->para_buf_size =
1810 				HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
1811 
1812 		config_para_info->cfg_para_buf =
1813 			kzalloc(config_para_info->para_buf_size, GFP_KERNEL);
1814 
1815 		if (config_para_info->cfg_para_buf) {
1816 			memset(config_para_info->cfg_para_buf, 0x00,
1817 			       config_para_info->para_buf_size);
1818 			config_para_info->full_fifo_mode = full_fifo;
1819 			config_para_info->para_buf_w =
1820 				config_para_info->cfg_para_buf;
1821 			config_para_info->para_num = 0;
1822 			config_para_info->avai_para_buf_size =
1823 				config_para_info->para_buf_size;
1824 			config_para_info->value_accumulation = 0;
1825 			config_para_info->offset_accumulation = 0;
1826 		} else {
1827 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
1828 					DBG_DMESG,
1829 					"Allocate cfg_para_buf fail!!\n");
1830 			return HALMAC_RET_MALLOC_FAIL;
1831 		}
1832 	}
1833 
1834 	if (halmac_transition_cfg_para_state_88xx(
1835 		    halmac_adapter,
1836 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) !=
1837 	    HALMAC_RET_SUCCESS)
1838 		return HALMAC_RET_ERROR_STATE;
1839 
1840 	halmac_enqueue_para_buff_88xx(halmac_adapter, para_info,
1841 				      config_para_info->para_buf_w,
1842 				      &drv_trigger_send);
1843 
1844 	if (para_info->cmd_id != HALMAC_PARAMETER_CMD_END) {
1845 		config_para_info->para_num++;
1846 		config_para_info->para_buf_w += HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1847 		config_para_info->avai_para_buf_size =
1848 			config_para_info->avai_para_buf_size -
1849 			HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1850 	}
1851 
1852 	if ((config_para_info->avai_para_buf_size -
1853 	     halmac_adapter->hw_config_info.txdesc_size) >
1854 		    HALMAC_FW_OFFLOAD_CMD_SIZE_88XX &&
1855 	    !drv_trigger_send)
1856 		return HALMAC_RET_SUCCESS;
1857 
1858 	if (config_para_info->para_num == 0) {
1859 		kfree(config_para_info->cfg_para_buf);
1860 		config_para_info->cfg_para_buf = NULL;
1861 		config_para_info->para_buf_w = NULL;
1862 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_WARNING,
1863 				"no cfg parameter element!!\n");
1864 
1865 		if (halmac_transition_cfg_para_state_88xx(
1866 			    halmac_adapter,
1867 			    HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1868 		    HALMAC_RET_SUCCESS)
1869 			return HALMAC_RET_ERROR_STATE;
1870 
1871 		return HALMAC_RET_SUCCESS;
1872 	}
1873 
1874 	if (halmac_transition_cfg_para_state_88xx(
1875 		    halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) !=
1876 	    HALMAC_RET_SUCCESS)
1877 		return HALMAC_RET_ERROR_STATE;
1878 
1879 	halmac_adapter->halmac_state.cfg_para_state_set.process_status =
1880 		HALMAC_CMD_PROCESS_SENDING;
1881 
1882 	if (config_para_info->full_fifo_mode)
1883 		HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0);
1884 	else
1885 		HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1886 				    (u16)(halmac_adapter->txff_allocation
1887 						  .rsvd_h2c_extra_info_pg_bndy &
1888 					  BIT_MASK_BCN_HEAD_1_V1));
1889 
1890 	info_size =
1891 		config_para_info->para_num * HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1892 
1893 	status = halmac_download_rsvd_page_88xx(
1894 		halmac_adapter, (u8 *)config_para_info->cfg_para_buf,
1895 		info_size);
1896 
1897 	if (status != HALMAC_RET_SUCCESS) {
1898 		pr_err("halmac_download_rsvd_page_88xx Fail!!\n");
1899 	} else {
1900 		halmac_gen_cfg_para_h2c_88xx(halmac_adapter, h2c_buff);
1901 
1902 		h2c_header_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAMETER;
1903 		h2c_header_info.content_size = 4;
1904 		h2c_header_info.ack = true;
1905 		halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1906 						      &h2c_header_info,
1907 						      &h2c_seq_mum);
1908 
1909 		halmac_adapter->halmac_state.cfg_para_state_set.seq_num =
1910 			h2c_seq_mum;
1911 
1912 		status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1913 						  HALMAC_H2C_CMD_SIZE_88XX,
1914 						  true);
1915 
1916 		if (status != HALMAC_RET_SUCCESS)
1917 			pr_err("halmac_send_h2c_pkt_88xx Fail!!\n");
1918 
1919 		HALMAC_RT_TRACE(
1920 			driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1921 			"config parameter time = %d\n",
1922 			HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG6));
1923 	}
1924 
1925 	kfree(config_para_info->cfg_para_buf);
1926 	config_para_info->cfg_para_buf = NULL;
1927 	config_para_info->para_buf_w = NULL;
1928 
1929 	/* Restore bcn head */
1930 	HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1931 			    (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1932 				  BIT_MASK_BCN_HEAD_1_V1));
1933 
1934 	if (halmac_transition_cfg_para_state_88xx(
1935 		    halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1936 	    HALMAC_RET_SUCCESS)
1937 		return HALMAC_RET_ERROR_STATE;
1938 
1939 	if (!drv_trigger_send) {
1940 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1941 				"Buffer full trigger sending H2C!!\n");
1942 		return HALMAC_RET_PARA_SENDING;
1943 	}
1944 
1945 	return status;
1946 }
1947 
1948 static enum halmac_ret_status
halmac_enqueue_para_buff_88xx(struct halmac_adapter * halmac_adapter,struct halmac_phy_parameter_info * para_info,u8 * curr_buff_wptr,bool * end_cmd)1949 halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
1950 			      struct halmac_phy_parameter_info *para_info,
1951 			      u8 *curr_buff_wptr, bool *end_cmd)
1952 {
1953 	struct halmac_config_para_info *config_para_info =
1954 		&halmac_adapter->config_para_info;
1955 
1956 	*end_cmd = false;
1957 
1958 	PHY_PARAMETER_INFO_SET_LENGTH(curr_buff_wptr,
1959 				      HALMAC_FW_OFFLOAD_CMD_SIZE_88XX);
1960 	PHY_PARAMETER_INFO_SET_IO_CMD(curr_buff_wptr, para_info->cmd_id);
1961 
1962 	switch (para_info->cmd_id) {
1963 	case HALMAC_PARAMETER_CMD_BB_W8:
1964 	case HALMAC_PARAMETER_CMD_BB_W16:
1965 	case HALMAC_PARAMETER_CMD_BB_W32:
1966 	case HALMAC_PARAMETER_CMD_MAC_W8:
1967 	case HALMAC_PARAMETER_CMD_MAC_W16:
1968 	case HALMAC_PARAMETER_CMD_MAC_W32:
1969 		PHY_PARAMETER_INFO_SET_IO_ADDR(
1970 			curr_buff_wptr, para_info->content.MAC_REG_W.offset);
1971 		PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
1972 					    para_info->content.MAC_REG_W.value);
1973 		PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
1974 					    para_info->content.MAC_REG_W.msk);
1975 		PHY_PARAMETER_INFO_SET_MSK_EN(
1976 			curr_buff_wptr, para_info->content.MAC_REG_W.msk_en);
1977 		config_para_info->value_accumulation +=
1978 			para_info->content.MAC_REG_W.value;
1979 		config_para_info->offset_accumulation +=
1980 			para_info->content.MAC_REG_W.offset;
1981 		break;
1982 	case HALMAC_PARAMETER_CMD_RF_W:
1983 		/*In rf register, the address is only 1 byte*/
1984 		PHY_PARAMETER_INFO_SET_RF_ADDR(
1985 			curr_buff_wptr, para_info->content.RF_REG_W.offset);
1986 		PHY_PARAMETER_INFO_SET_RF_PATH(
1987 			curr_buff_wptr, para_info->content.RF_REG_W.rf_path);
1988 		PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
1989 					    para_info->content.RF_REG_W.value);
1990 		PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
1991 					    para_info->content.RF_REG_W.msk);
1992 		PHY_PARAMETER_INFO_SET_MSK_EN(
1993 			curr_buff_wptr, para_info->content.RF_REG_W.msk_en);
1994 		config_para_info->value_accumulation +=
1995 			para_info->content.RF_REG_W.value;
1996 		config_para_info->offset_accumulation +=
1997 			(para_info->content.RF_REG_W.offset +
1998 			 (para_info->content.RF_REG_W.rf_path << 8));
1999 		break;
2000 	case HALMAC_PARAMETER_CMD_DELAY_US:
2001 	case HALMAC_PARAMETER_CMD_DELAY_MS:
2002 		PHY_PARAMETER_INFO_SET_DELAY_VALUE(
2003 			curr_buff_wptr,
2004 			para_info->content.DELAY_TIME.delay_time);
2005 		break;
2006 	case HALMAC_PARAMETER_CMD_END:
2007 		*end_cmd = true;
2008 		break;
2009 	default:
2010 		pr_err(" halmac_send_h2c_phy_parameter_88xx illegal cmd_id!!\n");
2011 		break;
2012 	}
2013 
2014 	return HALMAC_RET_SUCCESS;
2015 }
2016 
2017 static enum halmac_ret_status
halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter * halmac_adapter,u8 * h2c_buff)2018 halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
2019 			     u8 *h2c_buff)
2020 {
2021 	struct halmac_config_para_info *config_para_info =
2022 		&halmac_adapter->config_para_info;
2023 
2024 	CFG_PARAMETER_SET_NUM(h2c_buff, config_para_info->para_num);
2025 
2026 	if (config_para_info->full_fifo_mode) {
2027 		CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x1);
2028 		CFG_PARAMETER_SET_PHY_PARAMETER_LOC(h2c_buff, 0);
2029 	} else {
2030 		CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x0);
2031 		CFG_PARAMETER_SET_PHY_PARAMETER_LOC(
2032 			h2c_buff,
2033 			halmac_adapter->txff_allocation
2034 					.rsvd_h2c_extra_info_pg_bndy -
2035 				halmac_adapter->txff_allocation.rsvd_pg_bndy);
2036 	}
2037 
2038 	return HALMAC_RET_SUCCESS;
2039 }
2040 
2041 enum halmac_ret_status
halmac_send_h2c_run_datapack_88xx(struct halmac_adapter * halmac_adapter,enum halmac_data_type halmac_data_type)2042 halmac_send_h2c_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2043 				  enum halmac_data_type halmac_data_type)
2044 {
2045 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2046 	u16 h2c_seq_mum = 0;
2047 	void *driver_adapter = NULL;
2048 	struct halmac_h2c_header_info h2c_header_info;
2049 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2050 
2051 	driver_adapter = halmac_adapter->driver_adapter;
2052 
2053 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2054 			"%s!!\n", __func__);
2055 
2056 	RUN_DATAPACK_SET_DATAPACK_ID(h2c_buff, halmac_data_type);
2057 
2058 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_RUN_DATAPACK;
2059 	h2c_header_info.content_size = 4;
2060 	h2c_header_info.ack = true;
2061 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2062 					      &h2c_header_info, &h2c_seq_mum);
2063 
2064 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2065 					  HALMAC_H2C_CMD_SIZE_88XX, true);
2066 
2067 	if (status != HALMAC_RET_SUCCESS) {
2068 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2069 		return status;
2070 	}
2071 
2072 	return HALMAC_RET_SUCCESS;
2073 }
2074 
2075 enum halmac_ret_status
halmac_send_bt_coex_cmd_88xx(struct halmac_adapter * halmac_adapter,u8 * bt_buf,u32 bt_size,u8 ack)2076 halmac_send_bt_coex_cmd_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
2077 			     u32 bt_size, u8 ack)
2078 {
2079 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2080 	u16 h2c_seq_mum = 0;
2081 	void *driver_adapter = NULL;
2082 	struct halmac_h2c_header_info h2c_header_info;
2083 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2084 
2085 	driver_adapter = halmac_adapter->driver_adapter;
2086 
2087 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2088 			"%s!!\n", __func__);
2089 
2090 	memcpy(h2c_buff + 8, bt_buf, bt_size);
2091 
2092 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
2093 	h2c_header_info.content_size = (u16)bt_size;
2094 	h2c_header_info.ack = ack;
2095 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2096 					      &h2c_header_info, &h2c_seq_mum);
2097 
2098 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2099 					  HALMAC_H2C_CMD_SIZE_88XX, ack);
2100 
2101 	if (status != HALMAC_RET_SUCCESS) {
2102 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2103 		return status;
2104 	}
2105 
2106 	return HALMAC_RET_SUCCESS;
2107 }
2108 
2109 enum halmac_ret_status
halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ch_switch_option * cs_option)2110 halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
2111 				struct halmac_ch_switch_option *cs_option)
2112 {
2113 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2114 	u16 h2c_seq_mum = 0;
2115 	void *driver_adapter = NULL;
2116 	struct halmac_api *halmac_api;
2117 	struct halmac_h2c_header_info h2c_header_info;
2118 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2119 	enum halmac_cmd_process_status *process_status =
2120 		&halmac_adapter->halmac_state.scan_state_set.process_status;
2121 
2122 	driver_adapter = halmac_adapter->driver_adapter;
2123 
2124 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2125 			"halmac_ctrl_ch_switch!!\n");
2126 
2127 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2128 
2129 	if (halmac_transition_scan_state_88xx(
2130 		    halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) !=
2131 	    HALMAC_RET_SUCCESS)
2132 		return HALMAC_RET_ERROR_STATE;
2133 
2134 	*process_status = HALMAC_CMD_PROCESS_SENDING;
2135 
2136 	if (cs_option->switch_en != 0) {
2137 		HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
2138 				    (u16)(halmac_adapter->txff_allocation
2139 						  .rsvd_h2c_extra_info_pg_bndy &
2140 					  BIT_MASK_BCN_HEAD_1_V1));
2141 
2142 		status = halmac_download_rsvd_page_88xx(
2143 			halmac_adapter, halmac_adapter->ch_sw_info.ch_info_buf,
2144 			halmac_adapter->ch_sw_info.total_size);
2145 
2146 		if (status != HALMAC_RET_SUCCESS) {
2147 			pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
2148 			       status);
2149 			HALMAC_REG_WRITE_16(
2150 				halmac_adapter, REG_FIFOPAGE_CTRL_2,
2151 				(u16)(halmac_adapter->txff_allocation
2152 					      .rsvd_pg_bndy &
2153 				      BIT_MASK_BCN_HEAD_1_V1));
2154 			return status;
2155 		}
2156 
2157 		HALMAC_REG_WRITE_16(
2158 			halmac_adapter, REG_FIFOPAGE_CTRL_2,
2159 			(u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
2160 			      BIT_MASK_BCN_HEAD_1_V1));
2161 	}
2162 
2163 	CHANNEL_SWITCH_SET_SWITCH_START(h2c_buff, cs_option->switch_en);
2164 	CHANNEL_SWITCH_SET_CHANNEL_NUM(h2c_buff,
2165 				       halmac_adapter->ch_sw_info.ch_num);
2166 	CHANNEL_SWITCH_SET_CHANNEL_INFO_LOC(
2167 		h2c_buff,
2168 		halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
2169 			halmac_adapter->txff_allocation.rsvd_pg_bndy);
2170 	CHANNEL_SWITCH_SET_DEST_CH_EN(h2c_buff, cs_option->dest_ch_en);
2171 	CHANNEL_SWITCH_SET_DEST_CH(h2c_buff, cs_option->dest_ch);
2172 	CHANNEL_SWITCH_SET_PRI_CH_IDX(h2c_buff, cs_option->dest_pri_ch_idx);
2173 	CHANNEL_SWITCH_SET_ABSOLUTE_TIME(h2c_buff, cs_option->absolute_time_en);
2174 	CHANNEL_SWITCH_SET_TSF_LOW(h2c_buff, cs_option->tsf_low);
2175 	CHANNEL_SWITCH_SET_PERIODIC_OPTION(h2c_buff,
2176 					   cs_option->periodic_option);
2177 	CHANNEL_SWITCH_SET_NORMAL_CYCLE(h2c_buff, cs_option->normal_cycle);
2178 	CHANNEL_SWITCH_SET_NORMAL_PERIOD(h2c_buff, cs_option->normal_period);
2179 	CHANNEL_SWITCH_SET_SLOW_PERIOD(h2c_buff, cs_option->phase_2_period);
2180 	CHANNEL_SWITCH_SET_CHANNEL_INFO_SIZE(
2181 		h2c_buff, halmac_adapter->ch_sw_info.total_size);
2182 
2183 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_CHANNEL_SWITCH;
2184 	h2c_header_info.content_size = 20;
2185 	h2c_header_info.ack = true;
2186 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2187 					      &h2c_header_info, &h2c_seq_mum);
2188 	halmac_adapter->halmac_state.scan_state_set.seq_num = h2c_seq_mum;
2189 
2190 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2191 					  HALMAC_H2C_CMD_SIZE_88XX, true);
2192 
2193 	if (status != HALMAC_RET_SUCCESS)
2194 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2195 
2196 	kfree(halmac_adapter->ch_sw_info.ch_info_buf);
2197 	halmac_adapter->ch_sw_info.ch_info_buf = NULL;
2198 	halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
2199 	halmac_adapter->ch_sw_info.extra_info_en = 0;
2200 	halmac_adapter->ch_sw_info.buf_size = 0;
2201 	halmac_adapter->ch_sw_info.avai_buf_size = 0;
2202 	halmac_adapter->ch_sw_info.total_size = 0;
2203 	halmac_adapter->ch_sw_info.ch_num = 0;
2204 
2205 	if (halmac_transition_scan_state_88xx(halmac_adapter,
2206 					      HALMAC_SCAN_CMD_CONSTRUCT_IDLE) !=
2207 	    HALMAC_RET_SUCCESS)
2208 		return HALMAC_RET_ERROR_STATE;
2209 
2210 	return status;
2211 }
2212 
2213 enum halmac_ret_status
halmac_func_send_general_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_general_info * general_info)2214 halmac_func_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
2215 				   struct halmac_general_info *general_info)
2216 {
2217 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2218 	u16 h2c_seq_mum = 0;
2219 	void *driver_adapter = NULL;
2220 	struct halmac_h2c_header_info h2c_header_info;
2221 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2222 
2223 	driver_adapter = halmac_adapter->driver_adapter;
2224 
2225 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2226 			"halmac_send_general_info!!\n");
2227 
2228 	GENERAL_INFO_SET_REF_TYPE(h2c_buff, general_info->rfe_type);
2229 	GENERAL_INFO_SET_RF_TYPE(h2c_buff, general_info->rf_type);
2230 	GENERAL_INFO_SET_FW_TX_BOUNDARY(
2231 		h2c_buff,
2232 		halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy -
2233 			halmac_adapter->txff_allocation.rsvd_pg_bndy);
2234 
2235 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_GENERAL_INFO;
2236 	h2c_header_info.content_size = 4;
2237 	h2c_header_info.ack = false;
2238 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2239 					      &h2c_header_info, &h2c_seq_mum);
2240 
2241 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2242 					  HALMAC_H2C_CMD_SIZE_88XX, true);
2243 
2244 	if (status != HALMAC_RET_SUCCESS)
2245 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2246 
2247 	return status;
2248 }
2249 
halmac_send_h2c_update_bcn_parse_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_bcn_ie_info * bcn_ie_info)2250 enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx(
2251 	struct halmac_adapter *halmac_adapter,
2252 	struct halmac_bcn_ie_info *bcn_ie_info)
2253 {
2254 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2255 	u16 h2c_seq_mum = 0;
2256 	void *driver_adapter = halmac_adapter->driver_adapter;
2257 	struct halmac_h2c_header_info h2c_header_info;
2258 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2259 
2260 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2261 			"%s!!\n", __func__);
2262 
2263 	UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_buff, bcn_ie_info->func_en);
2264 	UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_buff, bcn_ie_info->size_th);
2265 	UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_buff, bcn_ie_info->timeout);
2266 
2267 	UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(
2268 		h2c_buff, (u32)(bcn_ie_info->ie_bmp[0]));
2269 	UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(
2270 		h2c_buff, (u32)(bcn_ie_info->ie_bmp[1]));
2271 	UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(
2272 		h2c_buff, (u32)(bcn_ie_info->ie_bmp[2]));
2273 	UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(
2274 		h2c_buff, (u32)(bcn_ie_info->ie_bmp[3]));
2275 	UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(
2276 		h2c_buff, (u32)(bcn_ie_info->ie_bmp[4]));
2277 
2278 	h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO;
2279 	h2c_header_info.content_size = 24;
2280 	h2c_header_info.ack = true;
2281 	halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2282 					      &h2c_header_info, &h2c_seq_mum);
2283 
2284 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2285 					  HALMAC_H2C_CMD_SIZE_88XX, true);
2286 
2287 	if (status != HALMAC_RET_SUCCESS) {
2288 		pr_err("halmac_send_h2c_pkt_88xx Fail =%x !!\n", status);
2289 		return status;
2290 	}
2291 
2292 	return status;
2293 }
2294 
2295 enum halmac_ret_status
halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter * halmac_adapter)2296 halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter *halmac_adapter)
2297 {
2298 	u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2299 	u8 *h2c_header, *h2c_cmd;
2300 	u16 seq = 0;
2301 	void *driver_adapter = NULL;
2302 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2303 
2304 	driver_adapter = halmac_adapter->driver_adapter;
2305 
2306 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2307 			"%s!!\n", __func__);
2308 
2309 	h2c_header = h2c_buff;
2310 	h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
2311 
2312 	halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, false);
2313 
2314 	status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2315 					  HALMAC_H2C_CMD_SIZE_88XX, false);
2316 
2317 	if (status != HALMAC_RET_SUCCESS) {
2318 		pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2319 		return status;
2320 	}
2321 
2322 	return status;
2323 }
2324 
2325 enum halmac_ret_status
halmac_parse_c2h_packet_88xx(struct halmac_adapter * halmac_adapter,u8 * halmac_buf,u32 halmac_size)2326 halmac_parse_c2h_packet_88xx(struct halmac_adapter *halmac_adapter,
2327 			     u8 *halmac_buf, u32 halmac_size)
2328 {
2329 	u8 c2h_cmd, c2h_sub_cmd_id;
2330 	u8 *c2h_buf = halmac_buf + halmac_adapter->hw_config_info.rxdesc_size;
2331 	u32 c2h_size = halmac_size - halmac_adapter->hw_config_info.rxdesc_size;
2332 	void *driver_adapter = halmac_adapter->driver_adapter;
2333 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2334 
2335 	c2h_cmd = (u8)C2H_HDR_GET_CMD_ID(c2h_buf);
2336 
2337 	/* FW offload C2H cmd is 0xFF */
2338 	if (c2h_cmd != 0xFF) {
2339 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2340 				"C2H_PKT not for FwOffloadC2HFormat!!\n");
2341 		return HALMAC_RET_C2H_NOT_HANDLED;
2342 	}
2343 
2344 	/* Get C2H sub cmd ID */
2345 	c2h_sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_buf);
2346 
2347 	switch (c2h_sub_cmd_id) {
2348 	case C2H_SUB_CMD_ID_C2H_DBG:
2349 		status = halmac_parse_c2h_debug_88xx(halmac_adapter, c2h_buf,
2350 						     c2h_size);
2351 		break;
2352 	case C2H_SUB_CMD_ID_H2C_ACK_HDR:
2353 		status = halmac_parse_h2c_ack_88xx(halmac_adapter, c2h_buf,
2354 						   c2h_size);
2355 		break;
2356 	case C2H_SUB_CMD_ID_BT_COEX_INFO:
2357 		status = HALMAC_RET_C2H_NOT_HANDLED;
2358 		break;
2359 	case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
2360 		status = halmac_parse_scan_status_rpt_88xx(halmac_adapter,
2361 							   c2h_buf, c2h_size);
2362 		break;
2363 	case C2H_SUB_CMD_ID_PSD_DATA:
2364 		status = halmac_parse_psd_data_88xx(halmac_adapter, c2h_buf,
2365 						    c2h_size);
2366 		break;
2367 
2368 	case C2H_SUB_CMD_ID_EFUSE_DATA:
2369 		status = halmac_parse_efuse_data_88xx(halmac_adapter, c2h_buf,
2370 						      c2h_size);
2371 		break;
2372 	default:
2373 		pr_err("c2h_sub_cmd_id switch case out of boundary!!\n");
2374 		pr_err("[ERR]c2h pkt : %.8X %.8X!!\n", *(u32 *)c2h_buf,
2375 		       *(u32 *)(c2h_buf + 4));
2376 		status = HALMAC_RET_C2H_NOT_HANDLED;
2377 		break;
2378 	}
2379 
2380 	return status;
2381 }
2382 
2383 static enum halmac_ret_status
halmac_parse_c2h_debug_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2384 halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2385 			    u32 c2h_size)
2386 {
2387 	void *driver_adapter = NULL;
2388 	u8 *c2h_buf_local = (u8 *)NULL;
2389 	u32 c2h_size_local = 0;
2390 	u8 dbg_content_length = 0;
2391 	u8 dbg_seq_num = 0;
2392 
2393 	driver_adapter = halmac_adapter->driver_adapter;
2394 	c2h_buf_local = c2h_buf;
2395 	c2h_size_local = c2h_size;
2396 
2397 	dbg_content_length = (u8)C2H_HDR_GET_LEN((u8 *)c2h_buf_local);
2398 
2399 	if (dbg_content_length > C2H_DBG_CONTENT_MAX_LENGTH)
2400 		return HALMAC_RET_SUCCESS;
2401 
2402 	*(c2h_buf_local + C2H_DBG_HEADER_LENGTH + dbg_content_length - 2) =
2403 		'\n';
2404 	dbg_seq_num = (u8)(*(c2h_buf_local + C2H_DBG_HEADER_LENGTH));
2405 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2406 			"[RTKFW, SEQ=%d]: %s", dbg_seq_num,
2407 			(char *)(c2h_buf_local + C2H_DBG_HEADER_LENGTH + 1));
2408 
2409 	return HALMAC_RET_SUCCESS;
2410 }
2411 
2412 static enum halmac_ret_status
halmac_parse_scan_status_rpt_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2413 halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
2414 				  u8 *c2h_buf, u32 c2h_size)
2415 {
2416 	u8 h2c_return_code;
2417 	void *driver_adapter = halmac_adapter->driver_adapter;
2418 	enum halmac_cmd_process_status process_status;
2419 
2420 	h2c_return_code = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(c2h_buf);
2421 	process_status = (enum halmac_h2c_return_code)h2c_return_code ==
2422 					 HALMAC_H2C_RETURN_SUCCESS ?
2423 				 HALMAC_CMD_PROCESS_DONE :
2424 				 HALMAC_CMD_PROCESS_ERROR;
2425 
2426 	PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2427 				  process_status, NULL, 0);
2428 
2429 	halmac_adapter->halmac_state.scan_state_set.process_status =
2430 		process_status;
2431 
2432 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2433 			"[TRACE]scan status : %X\n", process_status);
2434 
2435 	return HALMAC_RET_SUCCESS;
2436 }
2437 
2438 static enum halmac_ret_status
halmac_parse_psd_data_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2439 halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2440 			   u32 c2h_size)
2441 {
2442 	u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2443 	u16 total_size;
2444 	void *driver_adapter = halmac_adapter->driver_adapter;
2445 	enum halmac_cmd_process_status process_status;
2446 	struct halmac_psd_state_set *psd_set =
2447 		&halmac_adapter->halmac_state.psd_set;
2448 
2449 	h2c_seq = (u8)PSD_DATA_GET_H2C_SEQ(c2h_buf);
2450 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2451 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2452 			psd_set->seq_num, h2c_seq);
2453 	if (h2c_seq != psd_set->seq_num) {
2454 		pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2455 		       psd_set->seq_num, h2c_seq);
2456 		return HALMAC_RET_SUCCESS;
2457 	}
2458 
2459 	if (psd_set->process_status != HALMAC_CMD_PROCESS_SENDING) {
2460 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2461 		return HALMAC_RET_SUCCESS;
2462 	}
2463 
2464 	total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(c2h_buf);
2465 	segment_id = (u8)PSD_DATA_GET_SEGMENT_ID(c2h_buf);
2466 	segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf);
2467 	psd_set->data_size = total_size;
2468 
2469 	if (!psd_set->data) {
2470 		psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL);
2471 		if (!psd_set->data)
2472 			return HALMAC_RET_MALLOC_FAIL;
2473 	}
2474 
2475 	if (segment_id == 0)
2476 		psd_set->segment_size = segment_size;
2477 
2478 	memcpy(psd_set->data + segment_id * psd_set->segment_size,
2479 	       c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2480 
2481 	if (!PSD_DATA_GET_END_SEGMENT(c2h_buf))
2482 		return HALMAC_RET_SUCCESS;
2483 
2484 	process_status = HALMAC_CMD_PROCESS_DONE;
2485 	psd_set->process_status = process_status;
2486 
2487 	PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_PSD,
2488 				  process_status, psd_set->data,
2489 				  psd_set->data_size);
2490 
2491 	return HALMAC_RET_SUCCESS;
2492 }
2493 
2494 static enum halmac_ret_status
halmac_parse_efuse_data_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2495 halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2496 			     u32 c2h_size)
2497 {
2498 	u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2499 	u8 *eeprom_map = NULL;
2500 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
2501 	u8 h2c_return_code = 0;
2502 	void *driver_adapter = halmac_adapter->driver_adapter;
2503 	enum halmac_cmd_process_status process_status;
2504 
2505 	h2c_seq = (u8)EFUSE_DATA_GET_H2C_SEQ(c2h_buf);
2506 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2507 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2508 			halmac_adapter->halmac_state.efuse_state_set.seq_num,
2509 			h2c_seq);
2510 	if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2511 		pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2512 		       halmac_adapter->halmac_state.efuse_state_set.seq_num,
2513 		       h2c_seq);
2514 		return HALMAC_RET_SUCCESS;
2515 	}
2516 
2517 	if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2518 	    HALMAC_CMD_PROCESS_SENDING) {
2519 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2520 		return HALMAC_RET_SUCCESS;
2521 	}
2522 
2523 	segment_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(c2h_buf);
2524 	segment_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(c2h_buf);
2525 	if (segment_id == 0)
2526 		halmac_adapter->efuse_segment_size = segment_size;
2527 
2528 	eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2529 	if (!eeprom_map)
2530 		return HALMAC_RET_MALLOC_FAIL;
2531 	memset(eeprom_map, 0xFF, eeprom_size);
2532 
2533 	spin_lock(&halmac_adapter->efuse_lock);
2534 	memcpy(halmac_adapter->hal_efuse_map +
2535 		       segment_id * halmac_adapter->efuse_segment_size,
2536 	       c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2537 	spin_unlock(&halmac_adapter->efuse_lock);
2538 
2539 	if (!EFUSE_DATA_GET_END_SEGMENT(c2h_buf)) {
2540 		kfree(eeprom_map);
2541 		return HALMAC_RET_SUCCESS;
2542 	}
2543 
2544 	h2c_return_code =
2545 		halmac_adapter->halmac_state.efuse_state_set.fw_return_code;
2546 
2547 	if ((enum halmac_h2c_return_code)h2c_return_code ==
2548 	    HALMAC_H2C_RETURN_SUCCESS) {
2549 		process_status = HALMAC_CMD_PROCESS_DONE;
2550 		halmac_adapter->halmac_state.efuse_state_set.process_status =
2551 			process_status;
2552 
2553 		spin_lock(&halmac_adapter->efuse_lock);
2554 		halmac_adapter->hal_efuse_map_valid = true;
2555 		spin_unlock(&halmac_adapter->efuse_lock);
2556 
2557 		if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2558 			PLATFORM_EVENT_INDICATION(
2559 				driver_adapter,
2560 				HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2561 				process_status, halmac_adapter->hal_efuse_map,
2562 				halmac_adapter->hw_config_info.efuse_size);
2563 			halmac_adapter->event_trigger.physical_efuse_map = 0;
2564 		}
2565 
2566 		if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2567 			if (halmac_eeprom_parser_88xx(
2568 				    halmac_adapter,
2569 				    halmac_adapter->hal_efuse_map,
2570 				    eeprom_map) != HALMAC_RET_SUCCESS) {
2571 				kfree(eeprom_map);
2572 				return HALMAC_RET_EEPROM_PARSING_FAIL;
2573 			}
2574 			PLATFORM_EVENT_INDICATION(
2575 				driver_adapter,
2576 				HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2577 				process_status, eeprom_map, eeprom_size);
2578 			halmac_adapter->event_trigger.logical_efuse_map = 0;
2579 		}
2580 	} else {
2581 		process_status = HALMAC_CMD_PROCESS_ERROR;
2582 		halmac_adapter->halmac_state.efuse_state_set.process_status =
2583 			process_status;
2584 
2585 		if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2586 			PLATFORM_EVENT_INDICATION(
2587 				driver_adapter,
2588 				HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2589 				process_status,
2590 				&halmac_adapter->halmac_state.efuse_state_set
2591 					 .fw_return_code,
2592 				1);
2593 			halmac_adapter->event_trigger.physical_efuse_map = 0;
2594 		}
2595 
2596 		if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2597 			if (halmac_eeprom_parser_88xx(
2598 				    halmac_adapter,
2599 				    halmac_adapter->hal_efuse_map,
2600 				    eeprom_map) != HALMAC_RET_SUCCESS) {
2601 				kfree(eeprom_map);
2602 				return HALMAC_RET_EEPROM_PARSING_FAIL;
2603 			}
2604 			PLATFORM_EVENT_INDICATION(
2605 				driver_adapter,
2606 				HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2607 				process_status,
2608 				&halmac_adapter->halmac_state.efuse_state_set
2609 					 .fw_return_code,
2610 				1);
2611 			halmac_adapter->event_trigger.logical_efuse_map = 0;
2612 		}
2613 	}
2614 
2615 	kfree(eeprom_map);
2616 
2617 	return HALMAC_RET_SUCCESS;
2618 }
2619 
2620 static enum halmac_ret_status
halmac_parse_h2c_ack_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2621 halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2622 			  u32 c2h_size)
2623 {
2624 	u8 h2c_cmd_id, h2c_sub_cmd_id;
2625 	u8 h2c_return_code;
2626 	void *driver_adapter = halmac_adapter->driver_adapter;
2627 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2628 
2629 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2630 			"Ack for C2H!!\n");
2631 
2632 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2633 	if ((enum halmac_h2c_return_code)h2c_return_code !=
2634 	    HALMAC_H2C_RETURN_SUCCESS)
2635 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2636 				"C2H_PKT Status Error!! Status = %d\n",
2637 				h2c_return_code);
2638 
2639 	h2c_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(c2h_buf);
2640 
2641 	if (h2c_cmd_id != 0xFF) {
2642 		pr_err("original h2c ack is not handled!!\n");
2643 		status = HALMAC_RET_C2H_NOT_HANDLED;
2644 	} else {
2645 		h2c_sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(c2h_buf);
2646 
2647 		switch (h2c_sub_cmd_id) {
2648 		case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
2649 			status = halmac_parse_h2c_ack_phy_efuse_88xx(
2650 				halmac_adapter, c2h_buf, c2h_size);
2651 			break;
2652 		case H2C_SUB_CMD_ID_CFG_PARAMETER_ACK:
2653 			status = halmac_parse_h2c_ack_cfg_para_88xx(
2654 				halmac_adapter, c2h_buf, c2h_size);
2655 			break;
2656 		case H2C_SUB_CMD_ID_UPDATE_PACKET_ACK:
2657 			status = halmac_parse_h2c_ack_update_packet_88xx(
2658 				halmac_adapter, c2h_buf, c2h_size);
2659 			break;
2660 		case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
2661 			status = halmac_parse_h2c_ack_update_datapack_88xx(
2662 				halmac_adapter, c2h_buf, c2h_size);
2663 			break;
2664 		case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
2665 			status = halmac_parse_h2c_ack_run_datapack_88xx(
2666 				halmac_adapter, c2h_buf, c2h_size);
2667 			break;
2668 		case H2C_SUB_CMD_ID_CHANNEL_SWITCH_ACK:
2669 			status = halmac_parse_h2c_ack_channel_switch_88xx(
2670 				halmac_adapter, c2h_buf, c2h_size);
2671 			break;
2672 		case H2C_SUB_CMD_ID_IQK_ACK:
2673 			status = halmac_parse_h2c_ack_iqk_88xx(
2674 				halmac_adapter, c2h_buf, c2h_size);
2675 			break;
2676 		case H2C_SUB_CMD_ID_POWER_TRACKING_ACK:
2677 			status = halmac_parse_h2c_ack_power_tracking_88xx(
2678 				halmac_adapter, c2h_buf, c2h_size);
2679 			break;
2680 		case H2C_SUB_CMD_ID_PSD_ACK:
2681 			break;
2682 		default:
2683 			pr_err("h2c_sub_cmd_id switch case out of boundary!!\n");
2684 			status = HALMAC_RET_C2H_NOT_HANDLED;
2685 			break;
2686 		}
2687 	}
2688 
2689 	return status;
2690 }
2691 
2692 static enum halmac_ret_status
halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2693 halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
2694 				    u8 *c2h_buf, u32 c2h_size)
2695 {
2696 	u8 h2c_seq = 0;
2697 	u8 h2c_return_code;
2698 	void *driver_adapter = halmac_adapter->driver_adapter;
2699 
2700 	h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2701 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2702 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2703 			halmac_adapter->halmac_state.efuse_state_set.seq_num,
2704 			h2c_seq);
2705 	if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2706 		pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2707 		       halmac_adapter->halmac_state.efuse_state_set.seq_num,
2708 		       h2c_seq);
2709 		return HALMAC_RET_SUCCESS;
2710 	}
2711 
2712 	if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2713 	    HALMAC_CMD_PROCESS_SENDING) {
2714 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2715 		return HALMAC_RET_SUCCESS;
2716 	}
2717 
2718 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2719 	halmac_adapter->halmac_state.efuse_state_set.fw_return_code =
2720 		h2c_return_code;
2721 
2722 	return HALMAC_RET_SUCCESS;
2723 }
2724 
2725 static enum halmac_ret_status
halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2726 halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
2727 				   u8 *c2h_buf, u32 c2h_size)
2728 {
2729 	u8 h2c_seq = 0;
2730 	u8 h2c_return_code;
2731 	u32 offset_accu = 0, value_accu = 0;
2732 	void *driver_adapter = halmac_adapter->driver_adapter;
2733 	enum halmac_cmd_process_status process_status =
2734 		HALMAC_CMD_PROCESS_UNDEFINE;
2735 
2736 	h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2737 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2738 			"Seq num : h2c -> %d c2h -> %d\n",
2739 			halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2740 			h2c_seq);
2741 	if (h2c_seq !=
2742 	    halmac_adapter->halmac_state.cfg_para_state_set.seq_num) {
2743 		pr_err("Seq num mismatch : h2c -> %d c2h -> %d\n",
2744 		       halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2745 		       h2c_seq);
2746 		return HALMAC_RET_SUCCESS;
2747 	}
2748 
2749 	if (halmac_adapter->halmac_state.cfg_para_state_set.process_status !=
2750 	    HALMAC_CMD_PROCESS_SENDING) {
2751 		pr_err("Not in HALMAC_CMD_PROCESS_SENDING\n");
2752 		return HALMAC_RET_SUCCESS;
2753 	}
2754 
2755 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2756 	halmac_adapter->halmac_state.cfg_para_state_set.fw_return_code =
2757 		h2c_return_code;
2758 	offset_accu = CFG_PARAMETER_ACK_GET_OFFSET_ACCUMULATION(c2h_buf);
2759 	value_accu = CFG_PARAMETER_ACK_GET_VALUE_ACCUMULATION(c2h_buf);
2760 
2761 	if ((offset_accu !=
2762 	     halmac_adapter->config_para_info.offset_accumulation) ||
2763 	    (value_accu !=
2764 	     halmac_adapter->config_para_info.value_accumulation)) {
2765 		pr_err("[C2H]offset_accu : %x, value_accu : %x!!\n",
2766 		       offset_accu, value_accu);
2767 		pr_err("[Adapter]offset_accu : %x, value_accu : %x!!\n",
2768 		       halmac_adapter->config_para_info.offset_accumulation,
2769 		       halmac_adapter->config_para_info.value_accumulation);
2770 		process_status = HALMAC_CMD_PROCESS_ERROR;
2771 	}
2772 
2773 	if ((enum halmac_h2c_return_code)h2c_return_code ==
2774 		    HALMAC_H2C_RETURN_SUCCESS &&
2775 	    process_status != HALMAC_CMD_PROCESS_ERROR) {
2776 		process_status = HALMAC_CMD_PROCESS_DONE;
2777 		halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2778 			process_status;
2779 		PLATFORM_EVENT_INDICATION(driver_adapter,
2780 					  HALMAC_FEATURE_CFG_PARA,
2781 					  process_status, NULL, 0);
2782 	} else {
2783 		process_status = HALMAC_CMD_PROCESS_ERROR;
2784 		halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2785 			process_status;
2786 		PLATFORM_EVENT_INDICATION(
2787 			driver_adapter, HALMAC_FEATURE_CFG_PARA, process_status,
2788 			&halmac_adapter->halmac_state.cfg_para_state_set
2789 				 .fw_return_code,
2790 			1);
2791 	}
2792 
2793 	return HALMAC_RET_SUCCESS;
2794 }
2795 
2796 static enum halmac_ret_status
halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2797 halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2798 					u8 *c2h_buf, u32 c2h_size)
2799 {
2800 	u8 h2c_seq = 0;
2801 	u8 h2c_return_code;
2802 	void *driver_adapter = halmac_adapter->driver_adapter;
2803 	enum halmac_cmd_process_status process_status;
2804 
2805 	h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2806 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2807 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2808 			halmac_adapter->halmac_state.update_packet_set.seq_num,
2809 			h2c_seq);
2810 	if (h2c_seq != halmac_adapter->halmac_state.update_packet_set.seq_num) {
2811 		pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2812 		       halmac_adapter->halmac_state.update_packet_set.seq_num,
2813 		       h2c_seq);
2814 		return HALMAC_RET_SUCCESS;
2815 	}
2816 
2817 	if (halmac_adapter->halmac_state.update_packet_set.process_status !=
2818 	    HALMAC_CMD_PROCESS_SENDING) {
2819 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2820 		return HALMAC_RET_SUCCESS;
2821 	}
2822 
2823 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2824 	halmac_adapter->halmac_state.update_packet_set.fw_return_code =
2825 		h2c_return_code;
2826 
2827 	if ((enum halmac_h2c_return_code)h2c_return_code ==
2828 	    HALMAC_H2C_RETURN_SUCCESS) {
2829 		process_status = HALMAC_CMD_PROCESS_DONE;
2830 		halmac_adapter->halmac_state.update_packet_set.process_status =
2831 			process_status;
2832 		PLATFORM_EVENT_INDICATION(driver_adapter,
2833 					  HALMAC_FEATURE_UPDATE_PACKET,
2834 					  process_status, NULL, 0);
2835 	} else {
2836 		process_status = HALMAC_CMD_PROCESS_ERROR;
2837 		halmac_adapter->halmac_state.update_packet_set.process_status =
2838 			process_status;
2839 		PLATFORM_EVENT_INDICATION(
2840 			driver_adapter, HALMAC_FEATURE_UPDATE_PACKET,
2841 			process_status,
2842 			&halmac_adapter->halmac_state.update_packet_set
2843 				 .fw_return_code,
2844 			1);
2845 	}
2846 
2847 	return HALMAC_RET_SUCCESS;
2848 }
2849 
2850 static enum halmac_ret_status
halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2851 halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2852 					  u8 *c2h_buf, u32 c2h_size)
2853 {
2854 	void *driver_adapter = halmac_adapter->driver_adapter;
2855 	enum halmac_cmd_process_status process_status =
2856 		HALMAC_CMD_PROCESS_UNDEFINE;
2857 
2858 	PLATFORM_EVENT_INDICATION(driver_adapter,
2859 				  HALMAC_FEATURE_UPDATE_DATAPACK,
2860 				  process_status, NULL, 0);
2861 
2862 	return HALMAC_RET_SUCCESS;
2863 }
2864 
2865 static enum halmac_ret_status
halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2866 halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2867 				       u8 *c2h_buf, u32 c2h_size)
2868 {
2869 	void *driver_adapter = halmac_adapter->driver_adapter;
2870 	enum halmac_cmd_process_status process_status =
2871 		HALMAC_CMD_PROCESS_UNDEFINE;
2872 
2873 	PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_RUN_DATAPACK,
2874 				  process_status, NULL, 0);
2875 
2876 	return HALMAC_RET_SUCCESS;
2877 }
2878 
2879 static enum halmac_ret_status
halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2880 halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
2881 					 u8 *c2h_buf, u32 c2h_size)
2882 {
2883 	u8 h2c_seq = 0;
2884 	u8 h2c_return_code;
2885 	void *driver_adapter = halmac_adapter->driver_adapter;
2886 	enum halmac_cmd_process_status process_status;
2887 
2888 	h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2889 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2890 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2891 			halmac_adapter->halmac_state.scan_state_set.seq_num,
2892 			h2c_seq);
2893 	if (h2c_seq != halmac_adapter->halmac_state.scan_state_set.seq_num) {
2894 		pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2895 		       halmac_adapter->halmac_state.scan_state_set.seq_num,
2896 		       h2c_seq);
2897 		return HALMAC_RET_SUCCESS;
2898 	}
2899 
2900 	if (halmac_adapter->halmac_state.scan_state_set.process_status !=
2901 	    HALMAC_CMD_PROCESS_SENDING) {
2902 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2903 		return HALMAC_RET_SUCCESS;
2904 	}
2905 
2906 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2907 	halmac_adapter->halmac_state.scan_state_set.fw_return_code =
2908 		h2c_return_code;
2909 
2910 	if ((enum halmac_h2c_return_code)h2c_return_code ==
2911 	    HALMAC_H2C_RETURN_SUCCESS) {
2912 		process_status = HALMAC_CMD_PROCESS_RCVD;
2913 		halmac_adapter->halmac_state.scan_state_set.process_status =
2914 			process_status;
2915 		PLATFORM_EVENT_INDICATION(driver_adapter,
2916 					  HALMAC_FEATURE_CHANNEL_SWITCH,
2917 					  process_status, NULL, 0);
2918 	} else {
2919 		process_status = HALMAC_CMD_PROCESS_ERROR;
2920 		halmac_adapter->halmac_state.scan_state_set.process_status =
2921 			process_status;
2922 		PLATFORM_EVENT_INDICATION(
2923 			driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2924 			process_status, &halmac_adapter->halmac_state
2925 						 .scan_state_set.fw_return_code,
2926 			1);
2927 	}
2928 
2929 	return HALMAC_RET_SUCCESS;
2930 }
2931 
2932 static enum halmac_ret_status
halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2933 halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
2934 			      u8 *c2h_buf, u32 c2h_size)
2935 {
2936 	u8 h2c_seq = 0;
2937 	u8 h2c_return_code;
2938 	void *driver_adapter = halmac_adapter->driver_adapter;
2939 	enum halmac_cmd_process_status process_status;
2940 
2941 	h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2942 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2943 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2944 			halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2945 	if (h2c_seq != halmac_adapter->halmac_state.iqk_set.seq_num) {
2946 		pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2947 		       halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2948 		return HALMAC_RET_SUCCESS;
2949 	}
2950 
2951 	if (halmac_adapter->halmac_state.iqk_set.process_status !=
2952 	    HALMAC_CMD_PROCESS_SENDING) {
2953 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2954 		return HALMAC_RET_SUCCESS;
2955 	}
2956 
2957 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2958 	halmac_adapter->halmac_state.iqk_set.fw_return_code = h2c_return_code;
2959 
2960 	if ((enum halmac_h2c_return_code)h2c_return_code ==
2961 	    HALMAC_H2C_RETURN_SUCCESS) {
2962 		process_status = HALMAC_CMD_PROCESS_DONE;
2963 		halmac_adapter->halmac_state.iqk_set.process_status =
2964 			process_status;
2965 		PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_IQK,
2966 					  process_status, NULL, 0);
2967 	} else {
2968 		process_status = HALMAC_CMD_PROCESS_ERROR;
2969 		halmac_adapter->halmac_state.iqk_set.process_status =
2970 			process_status;
2971 		PLATFORM_EVENT_INDICATION(
2972 			driver_adapter, HALMAC_FEATURE_IQK, process_status,
2973 			&halmac_adapter->halmac_state.iqk_set.fw_return_code,
2974 			1);
2975 	}
2976 
2977 	return HALMAC_RET_SUCCESS;
2978 }
2979 
2980 static enum halmac_ret_status
halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)2981 halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
2982 					 u8 *c2h_buf, u32 c2h_size)
2983 {
2984 	u8 h2c_seq = 0;
2985 	u8 h2c_return_code;
2986 	void *driver_adapter = halmac_adapter->driver_adapter;
2987 	enum halmac_cmd_process_status process_status;
2988 
2989 	h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2990 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2991 			"[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2992 			halmac_adapter->halmac_state.power_tracking_set.seq_num,
2993 			h2c_seq);
2994 	if (h2c_seq !=
2995 	    halmac_adapter->halmac_state.power_tracking_set.seq_num) {
2996 		pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2997 		       halmac_adapter->halmac_state.power_tracking_set.seq_num,
2998 		       h2c_seq);
2999 		return HALMAC_RET_SUCCESS;
3000 	}
3001 
3002 	if (halmac_adapter->halmac_state.power_tracking_set.process_status !=
3003 	    HALMAC_CMD_PROCESS_SENDING) {
3004 		pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
3005 		return HALMAC_RET_SUCCESS;
3006 	}
3007 
3008 	h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
3009 	halmac_adapter->halmac_state.power_tracking_set.fw_return_code =
3010 		h2c_return_code;
3011 
3012 	if ((enum halmac_h2c_return_code)h2c_return_code ==
3013 	    HALMAC_H2C_RETURN_SUCCESS) {
3014 		process_status = HALMAC_CMD_PROCESS_DONE;
3015 		halmac_adapter->halmac_state.power_tracking_set.process_status =
3016 			process_status;
3017 		PLATFORM_EVENT_INDICATION(driver_adapter,
3018 					  HALMAC_FEATURE_POWER_TRACKING,
3019 					  process_status, NULL, 0);
3020 	} else {
3021 		process_status = HALMAC_CMD_PROCESS_ERROR;
3022 		halmac_adapter->halmac_state.power_tracking_set.process_status =
3023 			process_status;
3024 		PLATFORM_EVENT_INDICATION(
3025 			driver_adapter, HALMAC_FEATURE_POWER_TRACKING,
3026 			process_status,
3027 			&halmac_adapter->halmac_state.power_tracking_set
3028 				 .fw_return_code,
3029 			1);
3030 	}
3031 
3032 	return HALMAC_RET_SUCCESS;
3033 }
3034 
3035 enum halmac_ret_status
halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter * halmac_adapter,u32 * halmac_offset)3036 halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter *halmac_adapter,
3037 				       u32 *halmac_offset)
3038 {
3039 	void *driver_adapter = NULL;
3040 
3041 	driver_adapter = halmac_adapter->driver_adapter;
3042 
3043 	switch ((*halmac_offset) & 0xFFFF0000) {
3044 	case WLAN_IOREG_OFFSET:
3045 		*halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
3046 				 (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
3047 		break;
3048 	case SDIO_LOCAL_OFFSET:
3049 		*halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
3050 				 (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
3051 		break;
3052 	default:
3053 		*halmac_offset = 0xFFFFFFFF;
3054 		pr_err("Unknown base address!!\n");
3055 		return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
3056 	}
3057 
3058 	return HALMAC_RET_SUCCESS;
3059 }
3060 
3061 enum halmac_ret_status
halmac_update_sdio_free_page_88xx(struct halmac_adapter * halmac_adapter)3062 halmac_update_sdio_free_page_88xx(struct halmac_adapter *halmac_adapter)
3063 {
3064 	u32 free_page = 0, free_page2 = 0, free_page3 = 0;
3065 	void *driver_adapter = NULL;
3066 	struct halmac_api *halmac_api;
3067 	struct halmac_sdio_free_space *sdio_free_space;
3068 	u8 data[12] = {0};
3069 
3070 	driver_adapter = halmac_adapter->driver_adapter;
3071 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3072 
3073 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3074 			"%s ==========>\n", __func__);
3075 
3076 	sdio_free_space = &halmac_adapter->sdio_free_space;
3077 	/*need to use HALMAC_REG_READ_N, 20160316, Soar*/
3078 	HALMAC_REG_SDIO_CMD53_READ_N(halmac_adapter, REG_SDIO_FREE_TXPG, 12,
3079 				     data);
3080 	free_page =
3081 		data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
3082 	free_page2 =
3083 		data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24);
3084 	free_page3 =
3085 		data[8] | (data[9] << 8) | (data[10] << 16) | (data[11] << 24);
3086 
3087 	sdio_free_space->high_queue_number =
3088 		(u16)BIT_GET_HIQ_FREEPG_V1(free_page);
3089 	sdio_free_space->normal_queue_number =
3090 		(u16)BIT_GET_MID_FREEPG_V1(free_page);
3091 	sdio_free_space->low_queue_number =
3092 		(u16)BIT_GET_LOW_FREEPG_V1(free_page2);
3093 	sdio_free_space->public_queue_number =
3094 		(u16)BIT_GET_PUB_FREEPG_V1(free_page2);
3095 	sdio_free_space->extra_queue_number =
3096 		(u16)BIT_GET_EXQ_FREEPG_V1(free_page3);
3097 	sdio_free_space->ac_oqt_number = (u8)((free_page3 >> 16) & 0xFF);
3098 	sdio_free_space->non_ac_oqt_number = (u8)((free_page3 >> 24) & 0xFF);
3099 
3100 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3101 			"%s <==========\n", __func__);
3102 
3103 	return HALMAC_RET_SUCCESS;
3104 }
3105 
3106 enum halmac_ret_status
halmac_update_oqt_free_space_88xx(struct halmac_adapter * halmac_adapter)3107 halmac_update_oqt_free_space_88xx(struct halmac_adapter *halmac_adapter)
3108 {
3109 	void *driver_adapter = NULL;
3110 	struct halmac_api *halmac_api;
3111 	struct halmac_sdio_free_space *sdio_free_space;
3112 
3113 	driver_adapter = halmac_adapter->driver_adapter;
3114 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3115 
3116 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3117 			"%s ==========>\n", __func__);
3118 
3119 	sdio_free_space = &halmac_adapter->sdio_free_space;
3120 
3121 	sdio_free_space->ac_oqt_number = HALMAC_REG_READ_8(
3122 		halmac_adapter, REG_SDIO_OQT_FREE_TXPG_V1 + 2);
3123 	sdio_free_space->ac_empty =
3124 		HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY);
3125 
3126 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3127 			"%s <==========\n", __func__);
3128 
3129 	return HALMAC_RET_SUCCESS;
3130 }
3131 
3132 enum halmac_efuse_cmd_construct_state
halmac_query_efuse_curr_state_88xx(struct halmac_adapter * halmac_adapter)3133 halmac_query_efuse_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3134 {
3135 	return halmac_adapter->halmac_state.efuse_state_set
3136 		.efuse_cmd_construct_state;
3137 }
3138 
halmac_transition_efuse_state_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_cmd_construct_state dest_state)3139 enum halmac_ret_status halmac_transition_efuse_state_88xx(
3140 	struct halmac_adapter *halmac_adapter,
3141 	enum halmac_efuse_cmd_construct_state dest_state)
3142 {
3143 	struct halmac_efuse_state_set *efuse_state =
3144 		&halmac_adapter->halmac_state.efuse_state_set;
3145 
3146 	if (efuse_state->efuse_cmd_construct_state !=
3147 		    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE &&
3148 	    efuse_state->efuse_cmd_construct_state !=
3149 		    HALMAC_EFUSE_CMD_CONSTRUCT_BUSY &&
3150 	    efuse_state->efuse_cmd_construct_state !=
3151 		    HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3152 		return HALMAC_RET_ERROR_STATE;
3153 
3154 	if (efuse_state->efuse_cmd_construct_state == dest_state)
3155 		return HALMAC_RET_ERROR_STATE;
3156 
3157 	if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) {
3158 		if (efuse_state->efuse_cmd_construct_state ==
3159 		    HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3160 			return HALMAC_RET_ERROR_STATE;
3161 	} else if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) {
3162 		if (efuse_state->efuse_cmd_construct_state ==
3163 		    HALMAC_EFUSE_CMD_CONSTRUCT_IDLE)
3164 			return HALMAC_RET_ERROR_STATE;
3165 	}
3166 
3167 	efuse_state->efuse_cmd_construct_state = dest_state;
3168 
3169 	return HALMAC_RET_SUCCESS;
3170 }
3171 
3172 enum halmac_cfg_para_cmd_construct_state
halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter * halmac_adapter)3173 halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3174 {
3175 	return halmac_adapter->halmac_state.cfg_para_state_set
3176 		.cfg_para_cmd_construct_state;
3177 }
3178 
halmac_transition_cfg_para_state_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cfg_para_cmd_construct_state dest_state)3179 enum halmac_ret_status halmac_transition_cfg_para_state_88xx(
3180 	struct halmac_adapter *halmac_adapter,
3181 	enum halmac_cfg_para_cmd_construct_state dest_state)
3182 {
3183 	struct halmac_cfg_para_state_set *cfg_para =
3184 		&halmac_adapter->halmac_state.cfg_para_state_set;
3185 
3186 	if (cfg_para->cfg_para_cmd_construct_state !=
3187 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
3188 	    cfg_para->cfg_para_cmd_construct_state !=
3189 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING &&
3190 	    cfg_para->cfg_para_cmd_construct_state !=
3191 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3192 		return HALMAC_RET_ERROR_STATE;
3193 
3194 	if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) {
3195 		if (cfg_para->cfg_para_cmd_construct_state ==
3196 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING)
3197 			return HALMAC_RET_ERROR_STATE;
3198 	} else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
3199 		if (cfg_para->cfg_para_cmd_construct_state ==
3200 		    HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3201 			return HALMAC_RET_ERROR_STATE;
3202 	} else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) {
3203 		if (cfg_para->cfg_para_cmd_construct_state ==
3204 			    HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE ||
3205 		    cfg_para->cfg_para_cmd_construct_state ==
3206 			    HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3207 			return HALMAC_RET_ERROR_STATE;
3208 	}
3209 
3210 	cfg_para->cfg_para_cmd_construct_state = dest_state;
3211 
3212 	return HALMAC_RET_SUCCESS;
3213 }
3214 
3215 enum halmac_scan_cmd_construct_state
halmac_query_scan_curr_state_88xx(struct halmac_adapter * halmac_adapter)3216 halmac_query_scan_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3217 {
3218 	return halmac_adapter->halmac_state.scan_state_set
3219 		.scan_cmd_construct_state;
3220 }
3221 
halmac_transition_scan_state_88xx(struct halmac_adapter * halmac_adapter,enum halmac_scan_cmd_construct_state dest_state)3222 enum halmac_ret_status halmac_transition_scan_state_88xx(
3223 	struct halmac_adapter *halmac_adapter,
3224 	enum halmac_scan_cmd_construct_state dest_state)
3225 {
3226 	struct halmac_scan_state_set *scan =
3227 		&halmac_adapter->halmac_state.scan_state_set;
3228 
3229 	if (scan->scan_cmd_construct_state > HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3230 		return HALMAC_RET_ERROR_STATE;
3231 
3232 	if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_IDLE) {
3233 		if (scan->scan_cmd_construct_state ==
3234 			    HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED ||
3235 		    scan->scan_cmd_construct_state ==
3236 			    HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING)
3237 			return HALMAC_RET_ERROR_STATE;
3238 	} else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
3239 		if (scan->scan_cmd_construct_state ==
3240 		    HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3241 			return HALMAC_RET_ERROR_STATE;
3242 	} else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
3243 		if (scan->scan_cmd_construct_state ==
3244 			    HALMAC_SCAN_CMD_CONSTRUCT_IDLE ||
3245 		    scan->scan_cmd_construct_state ==
3246 			    HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3247 			return HALMAC_RET_ERROR_STATE;
3248 	} else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
3249 		if (scan->scan_cmd_construct_state !=
3250 			    HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING &&
3251 		    scan->scan_cmd_construct_state !=
3252 			    HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED)
3253 			return HALMAC_RET_ERROR_STATE;
3254 	}
3255 
3256 	scan->scan_cmd_construct_state = dest_state;
3257 
3258 	return HALMAC_RET_SUCCESS;
3259 }
3260 
halmac_query_cfg_para_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3261 enum halmac_ret_status halmac_query_cfg_para_status_88xx(
3262 	struct halmac_adapter *halmac_adapter,
3263 	enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3264 {
3265 	struct halmac_cfg_para_state_set *cfg_para_state_set =
3266 		&halmac_adapter->halmac_state.cfg_para_state_set;
3267 
3268 	*process_status = cfg_para_state_set->process_status;
3269 
3270 	return HALMAC_RET_SUCCESS;
3271 }
3272 
halmac_query_dump_physical_efuse_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3273 enum halmac_ret_status halmac_query_dump_physical_efuse_status_88xx(
3274 	struct halmac_adapter *halmac_adapter,
3275 	enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3276 {
3277 	void *driver_adapter = NULL;
3278 	struct halmac_efuse_state_set *efuse_state_set =
3279 		&halmac_adapter->halmac_state.efuse_state_set;
3280 
3281 	driver_adapter = halmac_adapter->driver_adapter;
3282 
3283 	*process_status = efuse_state_set->process_status;
3284 
3285 	if (!data)
3286 		return HALMAC_RET_NULL_POINTER;
3287 
3288 	if (!size)
3289 		return HALMAC_RET_NULL_POINTER;
3290 
3291 	if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3292 		if (*size < halmac_adapter->hw_config_info.efuse_size) {
3293 			*size = halmac_adapter->hw_config_info.efuse_size;
3294 			return HALMAC_RET_BUFFER_TOO_SMALL;
3295 		}
3296 
3297 		*size = halmac_adapter->hw_config_info.efuse_size;
3298 		memcpy(data, halmac_adapter->hal_efuse_map, *size);
3299 	}
3300 
3301 	return HALMAC_RET_SUCCESS;
3302 }
3303 
halmac_query_dump_logical_efuse_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3304 enum halmac_ret_status halmac_query_dump_logical_efuse_status_88xx(
3305 	struct halmac_adapter *halmac_adapter,
3306 	enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3307 {
3308 	u8 *eeprom_map = NULL;
3309 	u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
3310 	void *driver_adapter = NULL;
3311 	struct halmac_efuse_state_set *efuse_state_set =
3312 		&halmac_adapter->halmac_state.efuse_state_set;
3313 
3314 	driver_adapter = halmac_adapter->driver_adapter;
3315 
3316 	*process_status = efuse_state_set->process_status;
3317 
3318 	if (!data)
3319 		return HALMAC_RET_NULL_POINTER;
3320 
3321 	if (!size)
3322 		return HALMAC_RET_NULL_POINTER;
3323 
3324 	if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3325 		if (*size < eeprom_size) {
3326 			*size = eeprom_size;
3327 			return HALMAC_RET_BUFFER_TOO_SMALL;
3328 		}
3329 
3330 		*size = eeprom_size;
3331 
3332 		eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
3333 		if (!eeprom_map)
3334 			return HALMAC_RET_MALLOC_FAIL;
3335 		memset(eeprom_map, 0xFF, eeprom_size);
3336 
3337 		if (halmac_eeprom_parser_88xx(
3338 			    halmac_adapter, halmac_adapter->hal_efuse_map,
3339 			    eeprom_map) != HALMAC_RET_SUCCESS) {
3340 			kfree(eeprom_map);
3341 			return HALMAC_RET_EEPROM_PARSING_FAIL;
3342 		}
3343 
3344 		memcpy(data, eeprom_map, *size);
3345 
3346 		kfree(eeprom_map);
3347 	}
3348 
3349 	return HALMAC_RET_SUCCESS;
3350 }
3351 
halmac_query_channel_switch_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3352 enum halmac_ret_status halmac_query_channel_switch_status_88xx(
3353 	struct halmac_adapter *halmac_adapter,
3354 	enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3355 {
3356 	struct halmac_scan_state_set *scan_state_set =
3357 		&halmac_adapter->halmac_state.scan_state_set;
3358 
3359 	*process_status = scan_state_set->process_status;
3360 
3361 	return HALMAC_RET_SUCCESS;
3362 }
3363 
halmac_query_update_packet_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3364 enum halmac_ret_status halmac_query_update_packet_status_88xx(
3365 	struct halmac_adapter *halmac_adapter,
3366 	enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3367 {
3368 	struct halmac_update_packet_state_set *update_packet_set =
3369 		&halmac_adapter->halmac_state.update_packet_set;
3370 
3371 	*process_status = update_packet_set->process_status;
3372 
3373 	return HALMAC_RET_SUCCESS;
3374 }
3375 
3376 enum halmac_ret_status
halmac_query_iqk_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3377 halmac_query_iqk_status_88xx(struct halmac_adapter *halmac_adapter,
3378 			     enum halmac_cmd_process_status *process_status,
3379 			     u8 *data, u32 *size)
3380 {
3381 	struct halmac_iqk_state_set *iqk_set =
3382 		&halmac_adapter->halmac_state.iqk_set;
3383 
3384 	*process_status = iqk_set->process_status;
3385 
3386 	return HALMAC_RET_SUCCESS;
3387 }
3388 
halmac_query_power_tracking_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3389 enum halmac_ret_status halmac_query_power_tracking_status_88xx(
3390 	struct halmac_adapter *halmac_adapter,
3391 	enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3392 {
3393 	struct halmac_power_tracking_state_set *power_tracking_state_set =
3394 		&halmac_adapter->halmac_state.power_tracking_set;
3395 	;
3396 
3397 	*process_status = power_tracking_state_set->process_status;
3398 
3399 	return HALMAC_RET_SUCCESS;
3400 }
3401 
3402 enum halmac_ret_status
halmac_query_psd_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)3403 halmac_query_psd_status_88xx(struct halmac_adapter *halmac_adapter,
3404 			     enum halmac_cmd_process_status *process_status,
3405 			     u8 *data, u32 *size)
3406 {
3407 	void *driver_adapter = NULL;
3408 	struct halmac_psd_state_set *psd_set =
3409 		&halmac_adapter->halmac_state.psd_set;
3410 
3411 	driver_adapter = halmac_adapter->driver_adapter;
3412 
3413 	*process_status = psd_set->process_status;
3414 
3415 	if (!data)
3416 		return HALMAC_RET_NULL_POINTER;
3417 
3418 	if (!size)
3419 		return HALMAC_RET_NULL_POINTER;
3420 
3421 	if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3422 		if (*size < psd_set->data_size) {
3423 			*size = psd_set->data_size;
3424 			return HALMAC_RET_BUFFER_TOO_SMALL;
3425 		}
3426 
3427 		*size = psd_set->data_size;
3428 		memcpy(data, psd_set->data, *size);
3429 	}
3430 
3431 	return HALMAC_RET_SUCCESS;
3432 }
3433 
3434 enum halmac_ret_status
halmac_verify_io_88xx(struct halmac_adapter * halmac_adapter)3435 halmac_verify_io_88xx(struct halmac_adapter *halmac_adapter)
3436 {
3437 	u8 value8, wvalue8;
3438 	u32 value32, value32_2, wvalue32;
3439 	u32 halmac_offset;
3440 	void *driver_adapter = NULL;
3441 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3442 
3443 	driver_adapter = halmac_adapter->driver_adapter;
3444 
3445 	if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
3446 		halmac_offset = REG_PAGE5_DUMMY;
3447 		if ((halmac_offset & 0xFFFF0000) == 0)
3448 			halmac_offset |= WLAN_IOREG_OFFSET;
3449 
3450 		ret_status = halmac_convert_to_sdio_bus_offset_88xx(
3451 			halmac_adapter, &halmac_offset);
3452 
3453 		/* Verify CMD52 R/W */
3454 		wvalue8 = 0xab;
3455 		PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
3456 					  wvalue8);
3457 
3458 		value8 =
3459 			PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
3460 
3461 		if (value8 != wvalue8) {
3462 			pr_err("cmd52 r/w fail write = %X read = %X\n", wvalue8,
3463 			       value8);
3464 			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3465 		} else {
3466 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3467 					DBG_DMESG, "cmd52 r/w ok\n");
3468 		}
3469 
3470 		/* Verify CMD53 R/W */
3471 		PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, 0xaa);
3472 		PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
3473 					  0xbb);
3474 		PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
3475 					  0xcc);
3476 		PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 3,
3477 					  0xdd);
3478 
3479 		value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3480 						      halmac_offset);
3481 
3482 		if (value32 != 0xddccbbaa) {
3483 			pr_err("cmd53 r fail : read = %X\n", value32);
3484 			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3485 		} else {
3486 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3487 					DBG_DMESG, "cmd53 r ok\n");
3488 		}
3489 
3490 		wvalue32 = 0x11223344;
3491 		PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3492 					     wvalue32);
3493 
3494 		value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3495 						      halmac_offset);
3496 
3497 		if (value32 != wvalue32) {
3498 			pr_err("cmd53 w fail\n");
3499 			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3500 		} else {
3501 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3502 					DBG_DMESG, "cmd53 w ok\n");
3503 		}
3504 
3505 		value32 = PLATFORM_SDIO_CMD53_READ_32(
3506 			driver_adapter,
3507 			halmac_offset + 2); /* value32 should be 0x33441122 */
3508 
3509 		wvalue32 = 0x11225566;
3510 		PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3511 					     wvalue32);
3512 
3513 		value32_2 = PLATFORM_SDIO_CMD53_READ_32(
3514 			driver_adapter,
3515 			halmac_offset + 2); /* value32 should be 0x55661122 */
3516 		if (value32_2 == value32) {
3517 			pr_err("cmd52 is used for HAL_SDIO_CMD53_READ_32\n");
3518 			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3519 		} else {
3520 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3521 					DBG_DMESG, "cmd53 is correctly used\n");
3522 		}
3523 	} else {
3524 		wvalue32 = 0x77665511;
3525 		PLATFORM_REG_WRITE_32(driver_adapter, REG_PAGE5_DUMMY,
3526 				      wvalue32);
3527 
3528 		value32 = PLATFORM_REG_READ_32(driver_adapter, REG_PAGE5_DUMMY);
3529 		if (value32 != wvalue32) {
3530 			pr_err("reg rw\n");
3531 			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3532 		} else {
3533 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3534 					DBG_DMESG, "reg rw ok\n");
3535 		}
3536 	}
3537 
3538 	return ret_status;
3539 }
3540 
3541 enum halmac_ret_status
halmac_verify_send_rsvd_page_88xx(struct halmac_adapter * halmac_adapter)3542 halmac_verify_send_rsvd_page_88xx(struct halmac_adapter *halmac_adapter)
3543 {
3544 	u8 *rsvd_buf = NULL;
3545 	u8 *rsvd_page = NULL;
3546 	u32 i;
3547 	u32 h2c_pkt_verify_size = 64, h2c_pkt_verify_payload = 0xab;
3548 	void *driver_adapter = NULL;
3549 	enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3550 
3551 	driver_adapter = halmac_adapter->driver_adapter;
3552 
3553 	rsvd_buf = kzalloc(h2c_pkt_verify_size, GFP_KERNEL);
3554 
3555 	if (!rsvd_buf)
3556 		return HALMAC_RET_MALLOC_FAIL;
3557 
3558 	memset(rsvd_buf, (u8)h2c_pkt_verify_payload, h2c_pkt_verify_size);
3559 
3560 	ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, rsvd_buf,
3561 						    h2c_pkt_verify_size);
3562 
3563 	if (ret_status != HALMAC_RET_SUCCESS) {
3564 		kfree(rsvd_buf);
3565 		return ret_status;
3566 	}
3567 
3568 	rsvd_page = kzalloc(h2c_pkt_verify_size +
3569 				    halmac_adapter->hw_config_info.txdesc_size,
3570 			    GFP_KERNEL);
3571 
3572 	if (!rsvd_page) {
3573 		kfree(rsvd_buf);
3574 		return HALMAC_RET_MALLOC_FAIL;
3575 	}
3576 
3577 	ret_status = halmac_dump_fifo_88xx(
3578 		halmac_adapter, HAL_FIFO_SEL_RSVD_PAGE, 0,
3579 		h2c_pkt_verify_size +
3580 			halmac_adapter->hw_config_info.txdesc_size,
3581 		rsvd_page);
3582 
3583 	if (ret_status != HALMAC_RET_SUCCESS) {
3584 		kfree(rsvd_buf);
3585 		kfree(rsvd_page);
3586 		return ret_status;
3587 	}
3588 
3589 	for (i = 0; i < h2c_pkt_verify_size; i++) {
3590 		if (*(rsvd_buf + i) !=
3591 		    *(rsvd_page +
3592 		      (i + halmac_adapter->hw_config_info.txdesc_size))) {
3593 			pr_err("[ERR]Compare RSVD page Fail\n");
3594 			ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3595 		}
3596 	}
3597 
3598 	kfree(rsvd_buf);
3599 	kfree(rsvd_page);
3600 
3601 	return ret_status;
3602 }
3603 
halmac_power_save_cb_88xx(void * cb_data)3604 void halmac_power_save_cb_88xx(void *cb_data)
3605 {
3606 	void *driver_adapter = NULL;
3607 	struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
3608 
3609 	halmac_adapter = (struct halmac_adapter *)cb_data;
3610 	driver_adapter = halmac_adapter->driver_adapter;
3611 
3612 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
3613 			"%s\n", __func__);
3614 }
3615 
3616 enum halmac_ret_status
halmac_buffer_read_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u32 size,enum hal_fifo_sel halmac_fifo_sel,u8 * fifo_map)3617 halmac_buffer_read_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
3618 			u32 size, enum hal_fifo_sel halmac_fifo_sel,
3619 			u8 *fifo_map)
3620 {
3621 	u32 start_page, value_read;
3622 	u32 i, counter = 0, residue;
3623 	struct halmac_api *halmac_api;
3624 
3625 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3626 
3627 	if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3628 		offset = offset +
3629 			 (halmac_adapter->txff_allocation.rsvd_pg_bndy << 7);
3630 
3631 	start_page = offset >> 12;
3632 	residue = offset & (4096 - 1);
3633 
3634 	if (halmac_fifo_sel == HAL_FIFO_SEL_TX ||
3635 	    halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3636 		start_page += 0x780;
3637 	else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3638 		start_page += 0x700;
3639 	else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3640 		start_page += 0x660;
3641 	else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3642 		start_page += 0x650;
3643 	else
3644 		return HALMAC_RET_NOT_SUPPORT;
3645 
3646 	value_read = HALMAC_REG_READ_16(halmac_adapter, REG_PKTBUF_DBG_CTRL);
3647 
3648 	do {
3649 		HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3650 				    (u16)(start_page | (value_read & 0xF000)));
3651 
3652 		for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
3653 			*(u32 *)(fifo_map + counter) =
3654 				HALMAC_REG_READ_32(halmac_adapter, i);
3655 			*(u32 *)(fifo_map + counter) =
3656 				le32_to_cpu(*(__le32 *)(fifo_map + counter));
3657 			counter += 4;
3658 			if (size == counter)
3659 				goto HALMAC_BUF_READ_OK;
3660 		}
3661 
3662 		residue = 0;
3663 		start_page++;
3664 	} while (1);
3665 
3666 HALMAC_BUF_READ_OK:
3667 	HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3668 			    (u16)value_read);
3669 
3670 	return HALMAC_RET_SUCCESS;
3671 }
3672 
halmac_restore_mac_register_88xx(struct halmac_adapter * halmac_adapter,struct halmac_restore_info * restore_info,u32 restore_num)3673 void halmac_restore_mac_register_88xx(struct halmac_adapter *halmac_adapter,
3674 				      struct halmac_restore_info *restore_info,
3675 				      u32 restore_num)
3676 {
3677 	u8 value_length;
3678 	u32 i;
3679 	u32 mac_register;
3680 	u32 mac_value;
3681 	struct halmac_api *halmac_api;
3682 	struct halmac_restore_info *curr_restore_info = restore_info;
3683 
3684 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3685 
3686 	for (i = 0; i < restore_num; i++) {
3687 		mac_register = curr_restore_info->mac_register;
3688 		mac_value = curr_restore_info->value;
3689 		value_length = curr_restore_info->length;
3690 
3691 		if (value_length == 1)
3692 			HALMAC_REG_WRITE_8(halmac_adapter, mac_register,
3693 					   (u8)mac_value);
3694 		else if (value_length == 2)
3695 			HALMAC_REG_WRITE_16(halmac_adapter, mac_register,
3696 					    (u16)mac_value);
3697 		else if (value_length == 4)
3698 			HALMAC_REG_WRITE_32(halmac_adapter, mac_register,
3699 					    mac_value);
3700 
3701 		curr_restore_info++;
3702 	}
3703 }
3704 
halmac_api_record_id_88xx(struct halmac_adapter * halmac_adapter,enum halmac_api_id api_id)3705 void halmac_api_record_id_88xx(struct halmac_adapter *halmac_adapter,
3706 			       enum halmac_api_id api_id)
3707 {
3708 }
3709 
3710 enum halmac_ret_status
halmac_set_usb_mode_88xx(struct halmac_adapter * halmac_adapter,enum halmac_usb_mode usb_mode)3711 halmac_set_usb_mode_88xx(struct halmac_adapter *halmac_adapter,
3712 			 enum halmac_usb_mode usb_mode)
3713 {
3714 	u32 usb_temp;
3715 	void *driver_adapter = NULL;
3716 	struct halmac_api *halmac_api;
3717 	enum halmac_usb_mode current_usb_mode;
3718 
3719 	driver_adapter = halmac_adapter->driver_adapter;
3720 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3721 
3722 	current_usb_mode =
3723 		HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) == 0x20 ?
3724 			HALMAC_USB_MODE_U3 :
3725 			HALMAC_USB_MODE_U2;
3726 
3727 	/*check if HW supports usb2_usb3 swtich*/
3728 	usb_temp = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2);
3729 	if (!BIT_GET_USB23_SW_MODE_V1(usb_temp) &&
3730 	    !(usb_temp & BIT_USB3_USB2_TRANSITION)) {
3731 		pr_err("HALMAC_HW_USB_MODE usb mode HW unsupport\n");
3732 		return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
3733 	}
3734 
3735 	if (usb_mode == current_usb_mode) {
3736 		pr_err("HALMAC_HW_USB_MODE usb mode unchange\n");
3737 		return HALMAC_RET_USB_MODE_UNCHANGE;
3738 	}
3739 
3740 	usb_temp &= ~(BIT_USB23_SW_MODE_V1(0x3));
3741 
3742 	if (usb_mode == HALMAC_USB_MODE_U2) {
3743 		/* usb3 to usb2 */
3744 		HALMAC_REG_WRITE_32(
3745 			halmac_adapter, REG_PAD_CTRL2,
3746 			usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
3747 				BIT_RSM_EN_V1);
3748 	} else {
3749 		/* usb2 to usb3 */
3750 		HALMAC_REG_WRITE_32(
3751 			halmac_adapter, REG_PAD_CTRL2,
3752 			usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
3753 				BIT_RSM_EN_V1);
3754 	}
3755 
3756 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PAD_CTRL2 + 1,
3757 			   4); /* set counter down timer 4x64 ms */
3758 	HALMAC_REG_WRITE_16(
3759 		halmac_adapter, REG_SYS_PW_CTRL,
3760 		HALMAC_REG_READ_16(halmac_adapter, REG_SYS_PW_CTRL) |
3761 			BIT_APFM_OFFMAC);
3762 	usleep_range(1000, 1100);
3763 	HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL2,
3764 			    HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2) |
3765 				    BIT_NO_PDN_CHIPOFF_V1);
3766 
3767 	return HALMAC_RET_SUCCESS;
3768 }
3769 
halmac_enable_bb_rf_88xx(struct halmac_adapter * halmac_adapter,u8 enable)3770 void halmac_enable_bb_rf_88xx(struct halmac_adapter *halmac_adapter, u8 enable)
3771 {
3772 	u8 value8;
3773 	u32 value32;
3774 	struct halmac_api *halmac_api;
3775 
3776 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3777 
3778 	if (enable == 1) {
3779 		value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3780 		value8 = value8 | BIT(0) | BIT(1);
3781 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3782 
3783 		value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3784 		value8 = value8 | BIT(0) | BIT(1) | BIT(2);
3785 		HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3786 
3787 		value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3788 		value32 = value32 | BIT(24) | BIT(25) | BIT(26);
3789 		HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3790 	} else {
3791 		value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3792 		value8 = value8 & (~(BIT(0) | BIT(1)));
3793 		HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3794 
3795 		value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3796 		value8 = value8 & (~(BIT(0) | BIT(1) | BIT(2)));
3797 		HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3798 
3799 		value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3800 		value32 = value32 & (~(BIT(24) | BIT(25) | BIT(26)));
3801 		HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3802 	}
3803 }
3804 
halmac_config_sdio_tx_page_threshold_88xx(struct halmac_adapter * halmac_adapter,struct halmac_tx_page_threshold_info * threshold_info)3805 void halmac_config_sdio_tx_page_threshold_88xx(
3806 	struct halmac_adapter *halmac_adapter,
3807 	struct halmac_tx_page_threshold_info *threshold_info)
3808 {
3809 	struct halmac_api *halmac_api;
3810 
3811 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3812 
3813 	switch (threshold_info->dma_queue_sel) {
3814 	case HALMAC_MAP2_HQ:
3815 		HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT1,
3816 				    threshold_info->threshold);
3817 		break;
3818 	case HALMAC_MAP2_NQ:
3819 		HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT2,
3820 				    threshold_info->threshold);
3821 		break;
3822 	case HALMAC_MAP2_LQ:
3823 		HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT3,
3824 				    threshold_info->threshold);
3825 		break;
3826 	case HALMAC_MAP2_EXQ:
3827 		HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT4,
3828 				    threshold_info->threshold);
3829 		break;
3830 	default:
3831 		break;
3832 	}
3833 }
3834 
halmac_config_ampdu_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ampdu_config * ampdu_config)3835 void halmac_config_ampdu_88xx(struct halmac_adapter *halmac_adapter,
3836 			      struct halmac_ampdu_config *ampdu_config)
3837 {
3838 	struct halmac_api *halmac_api;
3839 
3840 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3841 
3842 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 2,
3843 			   ampdu_config->max_agg_num);
3844 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 3,
3845 			   ampdu_config->max_agg_num);
3846 };
3847 
3848 enum halmac_ret_status
halmac_check_oqt_88xx(struct halmac_adapter * halmac_adapter,u32 tx_agg_num,u8 * halmac_buf)3849 halmac_check_oqt_88xx(struct halmac_adapter *halmac_adapter, u32 tx_agg_num,
3850 		      u8 *halmac_buf)
3851 {
3852 	u32 counter = 10;
3853 
3854 	/*S0, S1 are not allowed to use, 0x4E4[0] should be 0. Soar 20160323*/
3855 	/*no need to check non_ac_oqt_number. HI and MGQ blocked will cause
3856 	 *protocal issue before H_OQT being full
3857 	 */
3858 	switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf)) {
3859 	case HALMAC_QUEUE_SELECT_VO:
3860 	case HALMAC_QUEUE_SELECT_VO_V2:
3861 	case HALMAC_QUEUE_SELECT_VI:
3862 	case HALMAC_QUEUE_SELECT_VI_V2:
3863 	case HALMAC_QUEUE_SELECT_BE:
3864 	case HALMAC_QUEUE_SELECT_BE_V2:
3865 	case HALMAC_QUEUE_SELECT_BK:
3866 	case HALMAC_QUEUE_SELECT_BK_V2:
3867 		counter = 10;
3868 		do {
3869 			if (halmac_adapter->sdio_free_space.ac_empty > 0) {
3870 				halmac_adapter->sdio_free_space.ac_empty -= 1;
3871 				break;
3872 			}
3873 
3874 			if (halmac_adapter->sdio_free_space.ac_oqt_number >=
3875 			    tx_agg_num) {
3876 				halmac_adapter->sdio_free_space.ac_oqt_number -=
3877 					(u8)tx_agg_num;
3878 				break;
3879 			}
3880 
3881 			halmac_update_oqt_free_space_88xx(halmac_adapter);
3882 
3883 			counter--;
3884 			if (counter == 0)
3885 				return HALMAC_RET_OQT_NOT_ENOUGH;
3886 		} while (1);
3887 		break;
3888 	default:
3889 		break;
3890 	}
3891 
3892 	return HALMAC_RET_SUCCESS;
3893 }
3894 
3895 enum halmac_ret_status
halmac_rqpn_parser_88xx(struct halmac_adapter * halmac_adapter,enum halmac_trx_mode halmac_trx_mode,struct halmac_rqpn_ * rqpn_table)3896 halmac_rqpn_parser_88xx(struct halmac_adapter *halmac_adapter,
3897 			enum halmac_trx_mode halmac_trx_mode,
3898 			struct halmac_rqpn_ *rqpn_table)
3899 {
3900 	u8 search_flag;
3901 	u32 i;
3902 	void *driver_adapter = NULL;
3903 	struct halmac_api *halmac_api;
3904 
3905 	driver_adapter = halmac_adapter->driver_adapter;
3906 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3907 
3908 	search_flag = 0;
3909 	for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3910 		if (halmac_trx_mode == rqpn_table[i].mode) {
3911 			halmac_adapter
3912 				->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO] =
3913 				rqpn_table[i].dma_map_vo;
3914 			halmac_adapter
3915 				->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI] =
3916 				rqpn_table[i].dma_map_vi;
3917 			halmac_adapter
3918 				->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE] =
3919 				rqpn_table[i].dma_map_be;
3920 			halmac_adapter
3921 				->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK] =
3922 				rqpn_table[i].dma_map_bk;
3923 			halmac_adapter
3924 				->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG] =
3925 				rqpn_table[i].dma_map_mg;
3926 			halmac_adapter
3927 				->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
3928 				rqpn_table[i].dma_map_hi;
3929 			search_flag = 1;
3930 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3931 					DBG_DMESG, "%s done\n", __func__);
3932 			break;
3933 		}
3934 	}
3935 
3936 	if (search_flag == 0) {
3937 		pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
3938 		return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
3939 	}
3940 
3941 	return HALMAC_RET_SUCCESS;
3942 }
3943 
3944 enum halmac_ret_status
halmac_pg_num_parser_88xx(struct halmac_adapter * halmac_adapter,enum halmac_trx_mode halmac_trx_mode,struct halmac_pg_num_ * pg_num_table)3945 halmac_pg_num_parser_88xx(struct halmac_adapter *halmac_adapter,
3946 			  enum halmac_trx_mode halmac_trx_mode,
3947 			  struct halmac_pg_num_ *pg_num_table)
3948 {
3949 	u8 search_flag;
3950 	u16 HPQ_num = 0, lpq_nnum = 0, NPQ_num = 0, GAPQ_num = 0;
3951 	u16 EXPQ_num = 0, PUBQ_num = 0;
3952 	u32 i = 0;
3953 	void *driver_adapter = NULL;
3954 	struct halmac_api *halmac_api;
3955 
3956 	driver_adapter = halmac_adapter->driver_adapter;
3957 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3958 
3959 	search_flag = 0;
3960 	for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3961 		if (halmac_trx_mode == pg_num_table[i].mode) {
3962 			HPQ_num = pg_num_table[i].hq_num;
3963 			lpq_nnum = pg_num_table[i].lq_num;
3964 			NPQ_num = pg_num_table[i].nq_num;
3965 			EXPQ_num = pg_num_table[i].exq_num;
3966 			GAPQ_num = pg_num_table[i].gap_num;
3967 			PUBQ_num = halmac_adapter->txff_allocation.ac_q_pg_num -
3968 				   HPQ_num - lpq_nnum - NPQ_num - EXPQ_num -
3969 				   GAPQ_num;
3970 			search_flag = 1;
3971 			HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3972 					DBG_DMESG, "%s done\n", __func__);
3973 			break;
3974 		}
3975 	}
3976 
3977 	if (search_flag == 0) {
3978 		pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
3979 		return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
3980 	}
3981 
3982 	if (halmac_adapter->txff_allocation.ac_q_pg_num <
3983 	    HPQ_num + lpq_nnum + NPQ_num + EXPQ_num + GAPQ_num)
3984 		return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
3985 
3986 	halmac_adapter->txff_allocation.high_queue_pg_num = HPQ_num;
3987 	halmac_adapter->txff_allocation.low_queue_pg_num = lpq_nnum;
3988 	halmac_adapter->txff_allocation.normal_queue_pg_num = NPQ_num;
3989 	halmac_adapter->txff_allocation.extra_queue_pg_num = EXPQ_num;
3990 	halmac_adapter->txff_allocation.pub_queue_pg_num = PUBQ_num;
3991 
3992 	return HALMAC_RET_SUCCESS;
3993 }
3994 
3995 enum halmac_ret_status
halmac_parse_intf_phy_88xx(struct halmac_adapter * halmac_adapter,struct halmac_intf_phy_para_ * intf_phy_para,enum halmac_intf_phy_platform platform,enum hal_intf_phy intf_phy)3996 halmac_parse_intf_phy_88xx(struct halmac_adapter *halmac_adapter,
3997 			   struct halmac_intf_phy_para_ *intf_phy_para,
3998 			   enum halmac_intf_phy_platform platform,
3999 			   enum hal_intf_phy intf_phy)
4000 {
4001 	u16 value;
4002 	u16 curr_cut;
4003 	u16 offset;
4004 	u16 ip_sel;
4005 	struct halmac_intf_phy_para_ *curr_phy_para;
4006 	struct halmac_api *halmac_api;
4007 	void *driver_adapter = NULL;
4008 	u8 result = HALMAC_RET_SUCCESS;
4009 
4010 	driver_adapter = halmac_adapter->driver_adapter;
4011 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4012 
4013 	switch (halmac_adapter->chip_version) {
4014 	case HALMAC_CHIP_VER_A_CUT:
4015 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_A;
4016 		break;
4017 	case HALMAC_CHIP_VER_B_CUT:
4018 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_B;
4019 		break;
4020 	case HALMAC_CHIP_VER_C_CUT:
4021 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_C;
4022 		break;
4023 	case HALMAC_CHIP_VER_D_CUT:
4024 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_D;
4025 		break;
4026 	case HALMAC_CHIP_VER_E_CUT:
4027 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_E;
4028 		break;
4029 	case HALMAC_CHIP_VER_F_CUT:
4030 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_F;
4031 		break;
4032 	case HALMAC_CHIP_VER_TEST:
4033 		curr_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
4034 		break;
4035 	default:
4036 		return HALMAC_RET_FAIL;
4037 	}
4038 
4039 	for (curr_phy_para = intf_phy_para;; curr_phy_para++) {
4040 		if (!(curr_phy_para->cut & curr_cut) ||
4041 		    !(curr_phy_para->plaform & (u16)platform))
4042 			continue;
4043 
4044 		offset = curr_phy_para->offset;
4045 		value = curr_phy_para->value;
4046 		ip_sel = curr_phy_para->ip_sel;
4047 
4048 		if (offset == 0xFFFF)
4049 			break;
4050 
4051 		if (ip_sel == HALMAC_IP_SEL_MAC) {
4052 			HALMAC_REG_WRITE_8(halmac_adapter, (u32)offset,
4053 					   (u8)value);
4054 		} else if (intf_phy == HAL_INTF_PHY_USB2) {
4055 			result = halmac_usbphy_write_88xx(halmac_adapter,
4056 							  (u8)offset, value,
4057 							  HAL_INTF_PHY_USB2);
4058 
4059 			if (result != HALMAC_RET_SUCCESS)
4060 				pr_err("[ERR]Write USB2PHY fail!\n");
4061 
4062 		} else if (intf_phy == HAL_INTF_PHY_USB3) {
4063 			result = halmac_usbphy_write_88xx(halmac_adapter,
4064 							  (u8)offset, value,
4065 							  HAL_INTF_PHY_USB3);
4066 
4067 			if (result != HALMAC_RET_SUCCESS)
4068 				pr_err("[ERR]Write USB3PHY fail!\n");
4069 
4070 		} else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1) {
4071 			if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4072 				result = halmac_mdio_write_88xx(
4073 					halmac_adapter, (u8)offset, value,
4074 					HAL_INTF_PHY_PCIE_GEN1);
4075 			else
4076 				result = halmac_dbi_write8_88xx(
4077 					halmac_adapter, offset, (u8)value);
4078 
4079 			if (result != HALMAC_RET_SUCCESS)
4080 				pr_err("[ERR]MDIO write GEN1 fail!\n");
4081 
4082 		} else if (intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
4083 			if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4084 				result = halmac_mdio_write_88xx(
4085 					halmac_adapter, (u8)offset, value,
4086 					HAL_INTF_PHY_PCIE_GEN2);
4087 			else
4088 				result = halmac_dbi_write8_88xx(
4089 					halmac_adapter, offset, (u8)value);
4090 
4091 			if (result != HALMAC_RET_SUCCESS)
4092 				pr_err("[ERR]MDIO write GEN2 fail!\n");
4093 		} else {
4094 			pr_err("[ERR]Parse intf phy cfg error!\n");
4095 		}
4096 	}
4097 
4098 	return HALMAC_RET_SUCCESS;
4099 }
4100 
4101 enum halmac_ret_status
halmac_dbi_write32_88xx(struct halmac_adapter * halmac_adapter,u16 addr,u32 data)4102 halmac_dbi_write32_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
4103 			u32 data)
4104 {
4105 	u8 tmp_u1b = 0;
4106 	u32 count = 0;
4107 	u16 write_addr = 0;
4108 	void *driver_adapter = NULL;
4109 	struct halmac_api *halmac_api;
4110 
4111 	driver_adapter = halmac_adapter->driver_adapter;
4112 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4113 
4114 	HALMAC_REG_WRITE_32(halmac_adapter, REG_DBI_WDATA_V1, data);
4115 
4116 	write_addr = ((addr & 0x0ffc) | (0x000F << 12));
4117 	HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4118 
4119 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4120 			"WriteAddr = %x\n", write_addr);
4121 
4122 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4123 	tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4124 
4125 	count = 20;
4126 	while (tmp_u1b && count != 0) {
4127 		udelay(10);
4128 		tmp_u1b =
4129 			HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4130 		count--;
4131 	}
4132 
4133 	if (tmp_u1b) {
4134 		pr_err("DBI write fail!\n");
4135 		return HALMAC_RET_FAIL;
4136 	} else {
4137 		return HALMAC_RET_SUCCESS;
4138 	}
4139 }
4140 
halmac_dbi_read32_88xx(struct halmac_adapter * halmac_adapter,u16 addr)4141 u32 halmac_dbi_read32_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4142 {
4143 	u16 read_addr = addr & 0x0ffc;
4144 	u8 tmp_u1b = 0;
4145 	u32 count = 0;
4146 	u32 ret = 0;
4147 	void *driver_adapter = NULL;
4148 	struct halmac_api *halmac_api;
4149 
4150 	driver_adapter = halmac_adapter->driver_adapter;
4151 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4152 
4153 	HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4154 
4155 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4156 	tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4157 
4158 	count = 20;
4159 	while (tmp_u1b && count != 0) {
4160 		udelay(10);
4161 		tmp_u1b =
4162 			HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4163 		count--;
4164 	}
4165 
4166 	if (tmp_u1b) {
4167 		ret = 0xFFFF;
4168 		pr_err("DBI read fail!\n");
4169 	} else {
4170 		ret = HALMAC_REG_READ_32(halmac_adapter, REG_DBI_RDATA_V1);
4171 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4172 				"Read Value = %x\n", ret);
4173 	}
4174 
4175 	return ret;
4176 }
4177 
4178 enum halmac_ret_status
halmac_dbi_write8_88xx(struct halmac_adapter * halmac_adapter,u16 addr,u8 data)4179 halmac_dbi_write8_88xx(struct halmac_adapter *halmac_adapter, u16 addr, u8 data)
4180 {
4181 	u8 tmp_u1b = 0;
4182 	u32 count = 0;
4183 	u16 write_addr = 0;
4184 	u16 remainder = addr & (4 - 1);
4185 	void *driver_adapter = NULL;
4186 	struct halmac_api *halmac_api;
4187 
4188 	driver_adapter = halmac_adapter->driver_adapter;
4189 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4190 
4191 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_WDATA_V1 + remainder, data);
4192 
4193 	write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
4194 
4195 	HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4196 
4197 	HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4198 			"WriteAddr = %x\n", write_addr);
4199 
4200 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4201 
4202 	tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4203 
4204 	count = 20;
4205 	while (tmp_u1b && count != 0) {
4206 		udelay(10);
4207 		tmp_u1b =
4208 			HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4209 		count--;
4210 	}
4211 
4212 	if (tmp_u1b) {
4213 		pr_err("DBI write fail!\n");
4214 		return HALMAC_RET_FAIL;
4215 	} else {
4216 		return HALMAC_RET_SUCCESS;
4217 	}
4218 }
4219 
halmac_dbi_read8_88xx(struct halmac_adapter * halmac_adapter,u16 addr)4220 u8 halmac_dbi_read8_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4221 {
4222 	u16 read_addr = addr & 0x0ffc;
4223 	u8 tmp_u1b = 0;
4224 	u32 count = 0;
4225 	u8 ret = 0;
4226 	void *driver_adapter = NULL;
4227 	struct halmac_api *halmac_api;
4228 
4229 	driver_adapter = halmac_adapter->driver_adapter;
4230 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4231 
4232 	HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4233 	HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4234 
4235 	tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4236 
4237 	count = 20;
4238 	while (tmp_u1b && count != 0) {
4239 		udelay(10);
4240 		tmp_u1b =
4241 			HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4242 		count--;
4243 	}
4244 
4245 	if (tmp_u1b) {
4246 		ret = 0xFF;
4247 		pr_err("DBI read fail!\n");
4248 	} else {
4249 		ret = HALMAC_REG_READ_8(halmac_adapter,
4250 					REG_DBI_RDATA_V1 + (addr & (4 - 1)));
4251 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4252 				"Read Value = %x\n", ret);
4253 	}
4254 
4255 	return ret;
4256 }
4257 
4258 enum halmac_ret_status
halmac_mdio_write_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u16 data,u8 speed)4259 halmac_mdio_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr, u16 data,
4260 		       u8 speed)
4261 {
4262 	u8 tmp_u1b = 0;
4263 	u32 count = 0;
4264 	void *driver_adapter = NULL;
4265 	struct halmac_api *halmac_api;
4266 	u8 real_addr = 0;
4267 
4268 	driver_adapter = halmac_adapter->driver_adapter;
4269 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4270 
4271 	HALMAC_REG_WRITE_16(halmac_adapter, REG_MDIO_V1, data);
4272 
4273 	/* address : 5bit */
4274 	real_addr = (addr & 0x1F);
4275 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4276 
4277 	if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4278 		/* GEN1 page 0 */
4279 		if (addr < 0x20) {
4280 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4281 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4282 					   0x00);
4283 
4284 			/* GEN1 page 1 */
4285 		} else {
4286 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4287 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4288 					   0x01);
4289 		}
4290 
4291 	} else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4292 		/* GEN2 page 0 */
4293 		if (addr < 0x20) {
4294 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4295 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4296 					   0x02);
4297 
4298 			/* GEN2 page 1 */
4299 		} else {
4300 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4301 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4302 					   0x03);
4303 		}
4304 	} else {
4305 		pr_err("Error Speed !\n");
4306 	}
4307 
4308 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4309 			   HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4310 				   BIT_MDIO_WFLAG_V1);
4311 
4312 	tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4313 		  BIT_MDIO_WFLAG_V1;
4314 	count = 20;
4315 
4316 	while (tmp_u1b && count != 0) {
4317 		udelay(10);
4318 		tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4319 			  BIT_MDIO_WFLAG_V1;
4320 		count--;
4321 	}
4322 
4323 	if (tmp_u1b) {
4324 		pr_err("MDIO write fail!\n");
4325 		return HALMAC_RET_FAIL;
4326 	} else {
4327 		return HALMAC_RET_SUCCESS;
4328 	}
4329 }
4330 
halmac_mdio_read_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u8 speed)4331 u16 halmac_mdio_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4332 			  u8 speed
4333 
4334 			  )
4335 {
4336 	u16 ret = 0;
4337 	u8 tmp_u1b = 0;
4338 	u32 count = 0;
4339 	void *driver_adapter = NULL;
4340 	struct halmac_api *halmac_api;
4341 	u8 real_addr = 0;
4342 
4343 	driver_adapter = halmac_adapter->driver_adapter;
4344 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4345 
4346 	/* address : 5bit */
4347 	real_addr = (addr & 0x1F);
4348 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4349 
4350 	if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4351 		/* GEN1 page 0 */
4352 		if (addr < 0x20) {
4353 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4354 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4355 					   0x00);
4356 
4357 			/* GEN1 page 1 */
4358 		} else {
4359 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4360 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4361 					   0x01);
4362 		}
4363 
4364 	} else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4365 		/* GEN2 page 0 */
4366 		if (addr < 0x20) {
4367 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4368 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4369 					   0x02);
4370 
4371 			/* GEN2 page 1 */
4372 		} else {
4373 			/* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4374 			HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4375 					   0x03);
4376 		}
4377 	} else {
4378 		pr_err("Error Speed !\n");
4379 	}
4380 
4381 	HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4382 			   HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4383 				   BIT_MDIO_RFLAG_V1);
4384 
4385 	tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4386 		  BIT_MDIO_RFLAG_V1;
4387 	count = 20;
4388 
4389 	while (tmp_u1b && count != 0) {
4390 		udelay(10);
4391 		tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4392 			  BIT_MDIO_RFLAG_V1;
4393 		count--;
4394 	}
4395 
4396 	if (tmp_u1b) {
4397 		ret = 0xFFFF;
4398 		pr_err("MDIO read fail!\n");
4399 
4400 	} else {
4401 		ret = HALMAC_REG_READ_16(halmac_adapter, REG_MDIO_V1 + 2);
4402 		HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_MDIO, DBG_DMESG,
4403 				"Read Value = %x\n", ret);
4404 	}
4405 
4406 	return ret;
4407 }
4408 
4409 enum halmac_ret_status
halmac_usbphy_write_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u16 data,u8 speed)4410 halmac_usbphy_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4411 			 u16 data, u8 speed)
4412 {
4413 	void *driver_adapter = NULL;
4414 	struct halmac_api *halmac_api;
4415 
4416 	driver_adapter = halmac_adapter->driver_adapter;
4417 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4418 
4419 	if (speed == HAL_INTF_PHY_USB3) {
4420 		HALMAC_REG_WRITE_8(halmac_adapter, 0xff0d, (u8)data);
4421 		HALMAC_REG_WRITE_8(halmac_adapter, 0xff0e, (u8)(data >> 8));
4422 		HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(7));
4423 	} else if (speed == HAL_INTF_PHY_USB2) {
4424 		HALMAC_REG_WRITE_8(halmac_adapter, 0xfe41, (u8)data);
4425 		HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4426 		HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4427 	} else {
4428 		pr_err("[ERR]Error USB Speed !\n");
4429 		return HALMAC_RET_NOT_SUPPORT;
4430 	}
4431 
4432 	return HALMAC_RET_SUCCESS;
4433 }
4434 
halmac_usbphy_read_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u8 speed)4435 u16 halmac_usbphy_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4436 			    u8 speed)
4437 {
4438 	void *driver_adapter = NULL;
4439 	struct halmac_api *halmac_api;
4440 	u16 value = 0;
4441 
4442 	driver_adapter = halmac_adapter->driver_adapter;
4443 	halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4444 
4445 	if (speed == HAL_INTF_PHY_USB3) {
4446 		HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(6));
4447 		value = (u16)(HALMAC_REG_READ_32(halmac_adapter, 0xff0c) >> 8);
4448 	} else if (speed == HAL_INTF_PHY_USB2) {
4449 		if ((addr >= 0xE0) /*&& (addr <= 0xFF)*/)
4450 			addr -= 0x20;
4451 		if ((addr >= 0xC0) && (addr <= 0xDF)) {
4452 			HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4453 			HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4454 			value = HALMAC_REG_READ_8(halmac_adapter, 0xfe43);
4455 		} else {
4456 			pr_err("[ERR]Error USB2PHY offset!\n");
4457 			return HALMAC_RET_NOT_SUPPORT;
4458 		}
4459 	} else {
4460 		pr_err("[ERR]Error USB Speed !\n");
4461 		return HALMAC_RET_NOT_SUPPORT;
4462 	}
4463 
4464 	return value;
4465 }
4466