1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Atlantic Network Driver
3  *
4  * Copyright (C) 2014-2019 aQuantia Corporation
5  * Copyright (C) 2019-2020 Marvell International Ltd.
6  */
7 
8 /* File hw_atl_utils.c: Definition of common functions for Atlantic hardware
9  * abstraction layer.
10  */
11 
12 #include "../aq_nic.h"
13 #include "../aq_hw_utils.h"
14 #include "hw_atl_utils.h"
15 #include "hw_atl_llh.h"
16 #include "hw_atl_llh_internal.h"
17 
18 #include <linux/random.h>
19 
20 #define HW_ATL_UCP_0X370_REG    0x0370U
21 
22 #define HW_ATL_MIF_CMD          0x0200U
23 #define HW_ATL_MIF_ADDR         0x0208U
24 #define HW_ATL_MIF_VAL          0x020CU
25 
26 #define HW_ATL_MPI_RPC_ADDR     0x0334U
27 #define HW_ATL_RPC_CONTROL_ADR  0x0338U
28 #define HW_ATL_RPC_STATE_ADR    0x033CU
29 
30 #define HW_ATL_MPI_FW_VERSION	0x18
31 #define HW_ATL_MPI_CONTROL_ADR  0x0368U
32 #define HW_ATL_MPI_STATE_ADR    0x036CU
33 
34 #define HW_ATL_MPI_STATE_MSK      0x00FFU
35 #define HW_ATL_MPI_STATE_SHIFT    0U
36 #define HW_ATL_MPI_SPEED_MSK      0x00FF0000U
37 #define HW_ATL_MPI_SPEED_SHIFT    16U
38 #define HW_ATL_MPI_DIRTY_WAKE_MSK 0x02000000U
39 
40 #define HW_ATL_MPI_DAISY_CHAIN_STATUS	0x704
41 #define HW_ATL_MPI_BOOT_EXIT_CODE	0x388
42 
43 #define HW_ATL_MAC_PHY_CONTROL	0x4000
44 #define HW_ATL_MAC_PHY_MPI_RESET_BIT 0x1D
45 
46 #define HW_ATL_FW_VER_1X 0x01050006U
47 #define HW_ATL_FW_VER_2X 0x02000000U
48 #define HW_ATL_FW_VER_3X 0x03000000U
49 
50 #define FORCE_FLASHLESS 0
51 
52 enum mcp_area {
53 	MCP_AREA_CONFIG = 0x80000000,
54 	MCP_AREA_SETTINGS = 0x20000000,
55 };
56 
57 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
58 				      enum hal_atl_utils_fw_state_e state);
59 static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
60 static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
61 static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
62 static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
63 static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
64 static u32 aq_fw1x_rpc_get(struct aq_hw_s *self);
65 
66 int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
67 {
68 	int err = 0;
69 
70 	hw_atl_utils_hw_chip_features_init(self,
71 					   &self->chip_features);
72 
73 	self->fw_ver_actual = hw_atl_utils_get_fw_version(self);
74 
75 	if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
76 				   self->fw_ver_actual) == 0) {
77 		*fw_ops = &aq_fw_1x_ops;
78 	} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
79 					  self->fw_ver_actual) == 0) {
80 		*fw_ops = &aq_fw_2x_ops;
81 	} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
82 					  self->fw_ver_actual) == 0) {
83 		*fw_ops = &aq_fw_2x_ops;
84 	} else {
85 		aq_pr_err("Bad FW version detected: %x\n",
86 			  self->fw_ver_actual);
87 		return -EOPNOTSUPP;
88 	}
89 	self->aq_fw_ops = *fw_ops;
90 	err = self->aq_fw_ops->init(self);
91 
92 	return err;
93 }
94 
95 static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
96 {
97 	u32 gsr, val;
98 	int k = 0;
99 
100 	aq_hw_write_reg(self, 0x404, 0x40e1);
101 	AQ_HW_SLEEP(50);
102 
103 	/* Cleanup SPI */
104 	val = aq_hw_read_reg(self, 0x53C);
105 	aq_hw_write_reg(self, 0x53C, val | 0x10);
106 
107 	gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
108 	aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
109 
110 	/* Kickstart MAC */
111 	aq_hw_write_reg(self, 0x404, 0x80e0);
112 	aq_hw_write_reg(self, 0x32a8, 0x0);
113 	aq_hw_write_reg(self, 0x520, 0x1);
114 
115 	/* Reset SPI again because of possible interrupted SPI burst */
116 	val = aq_hw_read_reg(self, 0x53C);
117 	aq_hw_write_reg(self, 0x53C, val | 0x10);
118 	AQ_HW_SLEEP(10);
119 	/* Clear SPI reset state */
120 	aq_hw_write_reg(self, 0x53C, val & ~0x10);
121 
122 	aq_hw_write_reg(self, 0x404, 0x180e0);
123 
124 	for (k = 0; k < 1000; k++) {
125 		u32 flb_status = aq_hw_read_reg(self,
126 						HW_ATL_MPI_DAISY_CHAIN_STATUS);
127 
128 		flb_status = flb_status & 0x10;
129 		if (flb_status)
130 			break;
131 		AQ_HW_SLEEP(10);
132 	}
133 	if (k == 1000) {
134 		aq_pr_err("MAC kickstart failed\n");
135 		return -EIO;
136 	}
137 
138 	/* FW reset */
139 	aq_hw_write_reg(self, 0x404, 0x80e0);
140 	AQ_HW_SLEEP(50);
141 	aq_hw_write_reg(self, 0x3a0, 0x1);
142 
143 	/* Kickstart PHY - skipped */
144 
145 	/* Global software reset*/
146 	hw_atl_rx_rx_reg_res_dis_set(self, 0U);
147 	hw_atl_tx_tx_reg_res_dis_set(self, 0U);
148 	aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
149 			    BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
150 			    HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
151 	gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
152 	aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
153 
154 	for (k = 0; k < 1000; k++) {
155 		u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
156 
157 		if (fw_state)
158 			break;
159 		AQ_HW_SLEEP(10);
160 	}
161 	if (k == 1000) {
162 		aq_pr_err("FW kickstart failed\n");
163 		return -EIO;
164 	}
165 	/* Old FW requires fixed delay after init */
166 	AQ_HW_SLEEP(15);
167 
168 	return 0;
169 }
170 
171 static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
172 {
173 	u32 gsr, val, rbl_status;
174 	int k;
175 
176 	aq_hw_write_reg(self, 0x404, 0x40e1);
177 	aq_hw_write_reg(self, 0x3a0, 0x1);
178 	aq_hw_write_reg(self, 0x32a8, 0x0);
179 
180 	/* Alter RBL status */
181 	aq_hw_write_reg(self, 0x388, 0xDEAD);
182 
183 	/* Cleanup SPI */
184 	val = aq_hw_read_reg(self, 0x53C);
185 	aq_hw_write_reg(self, 0x53C, val | 0x10);
186 
187 	/* Global software reset*/
188 	hw_atl_rx_rx_reg_res_dis_set(self, 0U);
189 	hw_atl_tx_tx_reg_res_dis_set(self, 0U);
190 	aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
191 			    BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
192 			    HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
193 	gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
194 	aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR,
195 			(gsr & 0xFFFFBFFF) | 0x8000);
196 
197 	if (FORCE_FLASHLESS)
198 		aq_hw_write_reg(self, 0x534, 0x0);
199 
200 	aq_hw_write_reg(self, 0x404, 0x40e0);
201 
202 	/* Wait for RBL boot */
203 	for (k = 0; k < 1000; k++) {
204 		rbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF;
205 		if (rbl_status && rbl_status != 0xDEAD)
206 			break;
207 		AQ_HW_SLEEP(10);
208 	}
209 	if (!rbl_status || rbl_status == 0xDEAD) {
210 		aq_pr_err("RBL Restart failed");
211 		return -EIO;
212 	}
213 
214 	/* Restore NVR */
215 	if (FORCE_FLASHLESS)
216 		aq_hw_write_reg(self, 0x534, 0xA0);
217 
218 	if (rbl_status == 0xF1A7) {
219 		aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
220 		return -ENOTSUPP;
221 	}
222 
223 	for (k = 0; k < 1000; k++) {
224 		u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
225 
226 		if (fw_state)
227 			break;
228 		AQ_HW_SLEEP(10);
229 	}
230 	if (k == 1000) {
231 		aq_pr_err("FW kickstart failed\n");
232 		return -EIO;
233 	}
234 	/* Old FW requires fixed delay after init */
235 	AQ_HW_SLEEP(15);
236 
237 	return 0;
238 }
239 
240 int hw_atl_utils_soft_reset(struct aq_hw_s *self)
241 {
242 	u32 boot_exit_code = 0;
243 	u32 val;
244 	int k;
245 
246 	for (k = 0; k < 1000; ++k) {
247 		u32 flb_status = aq_hw_read_reg(self,
248 						HW_ATL_MPI_DAISY_CHAIN_STATUS);
249 		boot_exit_code = aq_hw_read_reg(self,
250 						HW_ATL_MPI_BOOT_EXIT_CODE);
251 		if (flb_status != 0x06000000 || boot_exit_code != 0)
252 			break;
253 	}
254 
255 	if (k == 1000) {
256 		aq_pr_err("Neither RBL nor FLB firmware started\n");
257 		return -EOPNOTSUPP;
258 	}
259 
260 	self->rbl_enabled = (boot_exit_code != 0);
261 
262 	/* FW 1.x may bootup in an invalid POWER state (WOL feature).
263 	 * We should work around this by forcing its state back to DEINIT
264 	 */
265 	if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
266 				    aq_hw_read_reg(self,
267 						   HW_ATL_MPI_FW_VERSION))) {
268 		int err = 0;
269 
270 		hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
271 		err = readx_poll_timeout_atomic(hw_atl_utils_mpi_get_state,
272 						self, val,
273 						(val & HW_ATL_MPI_STATE_MSK) ==
274 						 MPI_DEINIT,
275 						10, 10000U);
276 		if (err)
277 			return err;
278 	}
279 
280 	if (self->rbl_enabled)
281 		return hw_atl_utils_soft_reset_rbl(self);
282 	else
283 		return hw_atl_utils_soft_reset_flb(self);
284 }
285 
286 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
287 				  u32 *p, u32 cnt)
288 {
289 	int err = 0;
290 	u32 val;
291 
292 	err = readx_poll_timeout_atomic(hw_atl_sem_ram_get,
293 					self, val, val == 1U,
294 					1U, 10000U);
295 
296 	if (err < 0) {
297 		bool is_locked;
298 
299 		hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
300 		is_locked = hw_atl_sem_ram_get(self);
301 		if (!is_locked) {
302 			err = -ETIME;
303 			goto err_exit;
304 		}
305 	}
306 
307 	aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
308 
309 	for (++cnt; --cnt && !err;) {
310 		aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
311 
312 		if (ATL_HW_IS_CHIP_FEATURE(self, REVISION_B1))
313 			err = readx_poll_timeout_atomic(hw_atl_utils_mif_addr_get,
314 							self, val, val != a,
315 							1U, 1000U);
316 		else
317 			err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
318 							self, val,
319 							!(val & 0x100),
320 							1U, 1000U);
321 
322 		*(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
323 		a += 4;
324 	}
325 
326 	hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
327 
328 err_exit:
329 	return err;
330 }
331 
332 static int hw_atl_utils_write_b1_mbox(struct aq_hw_s *self, u32 addr,
333 				      u32 *p, u32 cnt, enum mcp_area area)
334 {
335 	u32 data_offset = 0;
336 	u32 offset = addr;
337 	int err = 0;
338 	u32 val;
339 
340 	switch (area) {
341 	case MCP_AREA_CONFIG:
342 		offset -= self->rpc_addr;
343 		break;
344 
345 	case MCP_AREA_SETTINGS:
346 		offset -= self->settings_addr;
347 		break;
348 	}
349 
350 	offset = offset / sizeof(u32);
351 
352 	for (; data_offset < cnt; ++data_offset, ++offset) {
353 		aq_hw_write_reg(self, 0x328, p[data_offset]);
354 		aq_hw_write_reg(self, 0x32C,
355 				(area | (0xFFFF & (offset * 4))));
356 		hw_atl_mcp_up_force_intr_set(self, 1);
357 		/* 1000 times by 10us = 10ms */
358 		err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
359 						self, val,
360 						(val & 0xF0000000) !=
361 						area,
362 						10U, 10000U);
363 
364 		if (err < 0)
365 			break;
366 	}
367 
368 	return err;
369 }
370 
371 static int hw_atl_utils_write_b0_mbox(struct aq_hw_s *self, u32 addr,
372 				      u32 *p, u32 cnt)
373 {
374 	u32 offset = 0;
375 	int err = 0;
376 	u32 val;
377 
378 	aq_hw_write_reg(self, 0x208, addr);
379 
380 	for (; offset < cnt; ++offset) {
381 		aq_hw_write_reg(self, 0x20C, p[offset]);
382 		aq_hw_write_reg(self, 0x200, 0xC000);
383 
384 		err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
385 						self, val,
386 						(val & 0x100) == 0U,
387 						10U, 10000U);
388 
389 		if (err < 0)
390 			break;
391 	}
392 
393 	return err;
394 }
395 
396 static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 addr, u32 *p,
397 					 u32 cnt, enum mcp_area area)
398 {
399 	int err = 0;
400 	u32 val;
401 
402 	err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, self,
403 					val, val == 1U,
404 					10U, 100000U);
405 	if (err < 0)
406 		goto err_exit;
407 
408 	if (ATL_HW_IS_CHIP_FEATURE(self, REVISION_B1))
409 		err = hw_atl_utils_write_b1_mbox(self, addr, p, cnt, area);
410 	else
411 		err = hw_atl_utils_write_b0_mbox(self, addr, p, cnt);
412 
413 	hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
414 
415 	if (err < 0)
416 		goto err_exit;
417 
418 	err = aq_hw_err_from_flags(self);
419 
420 err_exit:
421 	return err;
422 }
423 
424 int hw_atl_write_fwcfg_dwords(struct aq_hw_s *self, u32 *p, u32 cnt)
425 {
426 	return hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, p,
427 					     cnt, MCP_AREA_CONFIG);
428 }
429 
430 int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
431 				   u32 cnt)
432 {
433 	return hw_atl_utils_fw_upload_dwords(self, self->settings_addr + offset,
434 					     p, cnt, MCP_AREA_SETTINGS);
435 }
436 
437 int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
438 {
439 	const u32 dw_major_mask = 0xff000000U;
440 	const u32 dw_minor_mask = 0x00ffffffU;
441 	int err = 0;
442 
443 	err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
444 	if (err < 0)
445 		goto err_exit;
446 	err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
447 		-EOPNOTSUPP : 0;
448 
449 err_exit:
450 	return err;
451 }
452 
453 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
454 				 const struct aq_hw_caps_s *aq_hw_caps)
455 {
456 	int err = 0;
457 
458 	if (!aq_hw_read_reg(self, 0x370U)) {
459 		unsigned int rnd = 0U;
460 		unsigned int ucp_0x370 = 0U;
461 
462 		get_random_bytes(&rnd, sizeof(unsigned int));
463 
464 		ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
465 		aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
466 	}
467 
468 	hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
469 
470 	/* check 10 times by 1ms */
471 	err = readx_poll_timeout_atomic(hw_atl_scrpad25_get,
472 					self, self->mbox_addr,
473 					self->mbox_addr != 0U,
474 					1000U, 10000U);
475 	err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
476 					self->rpc_addr,
477 					self->rpc_addr != 0U,
478 					1000U, 100000U);
479 
480 	return err;
481 }
482 
483 struct aq_hw_atl_utils_fw_rpc_tid_s {
484 	union {
485 		u32 val;
486 		struct {
487 			u16 tid;
488 			u16 len;
489 		};
490 	};
491 };
492 
493 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
494 
495 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
496 {
497 	struct aq_hw_atl_utils_fw_rpc_tid_s sw;
498 	int err = 0;
499 
500 	if (!ATL_HW_IS_CHIP_FEATURE(self, MIPS)) {
501 		err = -1;
502 		goto err_exit;
503 	}
504 	err = hw_atl_write_fwcfg_dwords(self, (u32 *)(void *)&self->rpc,
505 					(rpc_size + sizeof(u32) -
506 					 sizeof(u8)) / sizeof(u32));
507 	if (err < 0)
508 		goto err_exit;
509 
510 	sw.tid = 0xFFFFU & (++self->rpc_tid);
511 	sw.len = (u16)rpc_size;
512 	aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
513 
514 err_exit:
515 	return err;
516 }
517 
518 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
519 			     struct hw_atl_utils_fw_rpc **rpc)
520 {
521 	struct aq_hw_atl_utils_fw_rpc_tid_s sw;
522 	struct aq_hw_atl_utils_fw_rpc_tid_s fw;
523 	int err = 0;
524 
525 	do {
526 		sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
527 
528 		self->rpc_tid = sw.tid;
529 
530 		err = readx_poll_timeout_atomic(hw_atl_utils_rpc_state_get,
531 						self, fw.val,
532 						sw.tid == fw.tid,
533 						1000U, 100000U);
534 		if (err < 0)
535 			goto err_exit;
536 
537 		err = aq_hw_err_from_flags(self);
538 		if (err < 0)
539 			goto err_exit;
540 
541 		if (fw.len == 0xFFFFU) {
542 			err = hw_atl_utils_fw_rpc_call(self, sw.len);
543 			if (err < 0)
544 				goto err_exit;
545 		}
546 	} while (sw.tid != fw.tid || 0xFFFFU == fw.len);
547 
548 	if (rpc) {
549 		if (fw.len) {
550 			err =
551 			hw_atl_utils_fw_downld_dwords(self,
552 						      self->rpc_addr,
553 						      (u32 *)(void *)
554 						      &self->rpc,
555 						      (fw.len + sizeof(u32) -
556 						       sizeof(u8)) /
557 						      sizeof(u32));
558 			if (err < 0)
559 				goto err_exit;
560 		}
561 
562 		*rpc = &self->rpc;
563 	}
564 
565 err_exit:
566 	return err;
567 }
568 
569 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
570 {
571 	int err = 0;
572 
573 	err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps);
574 	if (err < 0)
575 		goto err_exit;
576 
577 	err = hw_atl_utils_fw_rpc_init(self);
578 	if (err < 0)
579 		goto err_exit;
580 
581 err_exit:
582 	return err;
583 }
584 
585 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
586 			       struct hw_atl_utils_mbox_header *pmbox)
587 {
588 	return hw_atl_utils_fw_downld_dwords(self,
589 					     self->mbox_addr,
590 					     (u32 *)(void *)pmbox,
591 					     sizeof(*pmbox) / sizeof(u32));
592 }
593 
594 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
595 				 struct hw_atl_utils_mbox *pmbox)
596 {
597 	int err = 0;
598 
599 	err = hw_atl_utils_fw_downld_dwords(self,
600 					    self->mbox_addr,
601 					    (u32 *)(void *)pmbox,
602 					    sizeof(*pmbox) / sizeof(u32));
603 	if (err < 0)
604 		goto err_exit;
605 
606 	if (ATL_HW_IS_CHIP_FEATURE(self, REVISION_A0)) {
607 		unsigned int mtu = self->aq_nic_cfg ?
608 					self->aq_nic_cfg->mtu : 1514U;
609 		pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
610 		pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
611 		pmbox->stats.dpc = atomic_read(&self->dpc);
612 	} else {
613 		pmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
614 	}
615 
616 err_exit:;
617 }
618 
619 static int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
620 {
621 	u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
622 
623 	val = val & ~HW_ATL_MPI_SPEED_MSK;
624 	val |= speed << HW_ATL_MPI_SPEED_SHIFT;
625 	aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
626 
627 	return 0;
628 }
629 
630 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
631 				      enum hal_atl_utils_fw_state_e state)
632 {
633 	u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
634 	struct hw_atl_utils_mbox_header mbox;
635 	u32 transaction_id = 0;
636 	int err = 0;
637 
638 	if (state == MPI_RESET) {
639 		hw_atl_utils_mpi_read_mbox(self, &mbox);
640 
641 		transaction_id = mbox.transaction_id;
642 
643 		err = readx_poll_timeout_atomic(hw_atl_utils_get_mpi_mbox_tid,
644 						self, mbox.transaction_id,
645 						transaction_id !=
646 						mbox.transaction_id,
647 						1000U, 100000U);
648 		if (err < 0)
649 			goto err_exit;
650 	}
651 	/* On interface DEINIT we disable DW (raise bit)
652 	 * Otherwise enable DW (clear bit)
653 	 */
654 	if (state == MPI_DEINIT || state == MPI_POWER)
655 		val |= HW_ATL_MPI_DIRTY_WAKE_MSK;
656 	else
657 		val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK;
658 
659 	/* Set new state bits */
660 	val = val & ~HW_ATL_MPI_STATE_MSK;
661 	val |= state & HW_ATL_MPI_STATE_MSK;
662 
663 	aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
664 
665 err_exit:
666 	return err;
667 }
668 
669 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
670 {
671 	struct aq_hw_link_status_s *link_status = &self->aq_link_status;
672 	u32 mpi_state;
673 	u32 speed;
674 
675 	mpi_state = hw_atl_utils_mpi_get_state(self);
676 	speed = mpi_state >> HW_ATL_MPI_SPEED_SHIFT;
677 
678 	if (!speed) {
679 		link_status->mbps = 0U;
680 	} else {
681 		switch (speed) {
682 		case HAL_ATLANTIC_RATE_10G:
683 			link_status->mbps = 10000U;
684 			break;
685 
686 		case HAL_ATLANTIC_RATE_5G:
687 		case HAL_ATLANTIC_RATE_5GSR:
688 			link_status->mbps = 5000U;
689 			break;
690 
691 		case HAL_ATLANTIC_RATE_2G5:
692 			link_status->mbps = 2500U;
693 			break;
694 
695 		case HAL_ATLANTIC_RATE_1G:
696 			link_status->mbps = 1000U;
697 			break;
698 
699 		case HAL_ATLANTIC_RATE_100M:
700 			link_status->mbps = 100U;
701 			break;
702 
703 		default:
704 			return -EBUSY;
705 		}
706 	}
707 
708 	return 0;
709 }
710 
711 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
712 				   u8 *mac)
713 {
714 	u32 mac_addr[2];
715 	u32 efuse_addr;
716 	int err = 0;
717 	u32 h = 0U;
718 	u32 l = 0U;
719 
720 	if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
721 		unsigned int ucp_0x370 = 0;
722 		unsigned int rnd = 0;
723 
724 		get_random_bytes(&rnd, sizeof(unsigned int));
725 
726 		ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
727 		aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
728 	}
729 
730 	efuse_addr = aq_hw_read_reg(self, 0x00000374U);
731 
732 	err = hw_atl_utils_fw_downld_dwords(self, efuse_addr + (40U * 4U),
733 					    mac_addr, ARRAY_SIZE(mac_addr));
734 	if (err < 0) {
735 		mac_addr[0] = 0U;
736 		mac_addr[1] = 0U;
737 		err = 0;
738 	} else {
739 		mac_addr[0] = __swab32(mac_addr[0]);
740 		mac_addr[1] = __swab32(mac_addr[1]);
741 	}
742 
743 	ether_addr_copy(mac, (u8 *)mac_addr);
744 
745 	if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
746 		/* chip revision */
747 		l = 0xE3000000U |
748 		    (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
749 		    (0x00 << 16);
750 		h = 0x8001300EU;
751 
752 		mac[5] = (u8)(0xFFU & l);
753 		l >>= 8;
754 		mac[4] = (u8)(0xFFU & l);
755 		l >>= 8;
756 		mac[3] = (u8)(0xFFU & l);
757 		l >>= 8;
758 		mac[2] = (u8)(0xFFU & l);
759 		mac[1] = (u8)(0xFFU & h);
760 		h >>= 8;
761 		mac[0] = (u8)(0xFFU & h);
762 	}
763 
764 	return err;
765 }
766 
767 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
768 {
769 	unsigned int ret = 0U;
770 
771 	switch (mbps) {
772 	case 100U:
773 		ret = 5U;
774 		break;
775 
776 	case 1000U:
777 		ret = 4U;
778 		break;
779 
780 	case 2500U:
781 		ret = 3U;
782 		break;
783 
784 	case 5000U:
785 		ret = 1U;
786 		break;
787 
788 	case 10000U:
789 		ret = 0U;
790 		break;
791 
792 	default:
793 		break;
794 	}
795 
796 	return ret;
797 }
798 
799 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
800 {
801 	u32 val = hw_atl_reg_glb_mif_id_get(self);
802 	u32 mif_rev = val & 0xFFU;
803 	u32 chip_features = 0U;
804 
805 	chip_features |= ATL_HW_CHIP_ATLANTIC;
806 
807 	if ((0xFU & mif_rev) == 1U) {
808 		chip_features |= ATL_HW_CHIP_REVISION_A0 |
809 			ATL_HW_CHIP_MPI_AQ |
810 			ATL_HW_CHIP_MIPS;
811 	} else if ((0xFU & mif_rev) == 2U) {
812 		chip_features |= ATL_HW_CHIP_REVISION_B0 |
813 			ATL_HW_CHIP_MPI_AQ |
814 			ATL_HW_CHIP_MIPS |
815 			ATL_HW_CHIP_TPO2 |
816 			ATL_HW_CHIP_RPF2;
817 	} else if ((0xFU & mif_rev) == 0xAU) {
818 		chip_features |= ATL_HW_CHIP_REVISION_B1 |
819 			ATL_HW_CHIP_MPI_AQ |
820 			ATL_HW_CHIP_MIPS |
821 			ATL_HW_CHIP_TPO2 |
822 			ATL_HW_CHIP_RPF2;
823 	}
824 
825 	*p = chip_features;
826 }
827 
828 static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
829 {
830 	hw_atl_utils_mpi_set_speed(self, 0);
831 	hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
832 
833 	return 0;
834 }
835 
836 int hw_atl_utils_update_stats(struct aq_hw_s *self)
837 {
838 	struct aq_stats_s *cs = &self->curr_stats;
839 	struct hw_atl_utils_mbox mbox;
840 
841 	hw_atl_utils_mpi_read_stats(self, &mbox);
842 
843 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
844 			mbox.stats._N_ - self->last_stats._N_)
845 
846 	if (self->aq_link_status.mbps) {
847 		AQ_SDELTA(uprc);
848 		AQ_SDELTA(mprc);
849 		AQ_SDELTA(bprc);
850 		AQ_SDELTA(erpt);
851 
852 		AQ_SDELTA(uptc);
853 		AQ_SDELTA(mptc);
854 		AQ_SDELTA(bptc);
855 		AQ_SDELTA(erpr);
856 
857 		AQ_SDELTA(ubrc);
858 		AQ_SDELTA(ubtc);
859 		AQ_SDELTA(mbrc);
860 		AQ_SDELTA(mbtc);
861 		AQ_SDELTA(bbrc);
862 		AQ_SDELTA(bbtc);
863 		AQ_SDELTA(dpc);
864 	}
865 #undef AQ_SDELTA
866 
867 	cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self);
868 	cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self);
869 	cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self);
870 	cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self);
871 
872 	memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
873 
874 	return 0;
875 }
876 
877 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
878 {
879 	return &self->curr_stats;
880 }
881 
882 static const u32 hw_atl_utils_hw_mac_regs[] = {
883 	0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
884 	0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
885 	0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
886 	0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
887 	0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
888 	0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
889 	0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
890 	0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
891 	0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
892 	0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
893 	0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
894 	0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
895 	0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
896 	0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
897 	0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
898 	0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
899 	0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
900 	0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
901 	0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
902 	0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
903 	0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
904 	0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
905 };
906 
907 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
908 			     const struct aq_hw_caps_s *aq_hw_caps,
909 			     u32 *regs_buff)
910 {
911 	unsigned int i = 0U;
912 
913 	for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
914 		regs_buff[i] = aq_hw_read_reg(self,
915 					      hw_atl_utils_hw_mac_regs[i]);
916 
917 	return 0;
918 }
919 
920 u32 hw_atl_utils_get_fw_version(struct aq_hw_s *self)
921 {
922 	return aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
923 }
924 
925 static int aq_fw1x_set_wake_magic(struct aq_hw_s *self, bool wol_enabled,
926 				  u8 *mac)
927 {
928 	struct hw_atl_utils_fw_rpc *prpc = NULL;
929 	unsigned int rpc_size = 0U;
930 	int err = 0;
931 
932 	err = hw_atl_utils_fw_rpc_wait(self, &prpc);
933 	if (err < 0)
934 		goto err_exit;
935 
936 	memset(prpc, 0, sizeof(*prpc));
937 
938 	if (wol_enabled) {
939 		rpc_size = offsetof(struct hw_atl_utils_fw_rpc, msg_wol_add) +
940 			   sizeof(prpc->msg_wol_add);
941 
942 
943 		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
944 		prpc->msg_wol_add.priority =
945 				HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
946 		prpc->msg_wol_add.pattern_id =
947 				HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
948 		prpc->msg_wol_add.packet_type =
949 				HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
950 
951 		ether_addr_copy((u8 *)&prpc->msg_wol_add.magic_packet_pattern,
952 				mac);
953 	} else {
954 		rpc_size = sizeof(prpc->msg_wol_remove) +
955 			   offsetof(struct hw_atl_utils_fw_rpc, msg_wol_remove);
956 
957 		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
958 		prpc->msg_wol_add.pattern_id =
959 				HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
960 	}
961 
962 	err = hw_atl_utils_fw_rpc_call(self, rpc_size);
963 
964 err_exit:
965 	return err;
966 }
967 
968 static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
969 			     u8 *mac)
970 {
971 	struct hw_atl_utils_fw_rpc *prpc = NULL;
972 	unsigned int rpc_size = 0U;
973 	int err = 0;
974 
975 	if (self->aq_nic_cfg->wol & WAKE_MAGIC) {
976 		err = aq_fw1x_set_wake_magic(self, 1, mac);
977 
978 		if (err < 0)
979 			goto err_exit;
980 
981 		rpc_size = sizeof(prpc->msg_id) +
982 			   sizeof(prpc->msg_enable_wakeup);
983 
984 		err = hw_atl_utils_fw_rpc_wait(self, &prpc);
985 
986 		if (err < 0)
987 			goto err_exit;
988 
989 		memset(prpc, 0, rpc_size);
990 
991 		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
992 		prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
993 
994 		err = hw_atl_utils_fw_rpc_call(self, rpc_size);
995 		if (err < 0)
996 			goto err_exit;
997 	}
998 	hw_atl_utils_mpi_set_speed(self, 0);
999 	hw_atl_utils_mpi_set_state(self, MPI_POWER);
1000 
1001 err_exit:
1002 	return err;
1003 }
1004 
1005 static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self)
1006 {
1007 	struct hw_atl_utils_mbox_header mbox;
1008 
1009 	hw_atl_utils_mpi_read_mbox(self, &mbox);
1010 
1011 	return mbox.transaction_id;
1012 }
1013 
1014 static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self)
1015 {
1016 	return aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
1017 }
1018 
1019 static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self)
1020 {
1021 	return aq_hw_read_reg(self, HW_ATL_MIF_CMD);
1022 }
1023 
1024 static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self)
1025 {
1026 	return aq_hw_read_reg(self, HW_ATL_MIF_ADDR);
1027 }
1028 
1029 static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
1030 {
1031 	return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
1032 }
1033 
1034 static u32 aq_fw1x_rpc_get(struct aq_hw_s *self)
1035 {
1036 	return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR);
1037 }
1038 
1039 const struct aq_fw_ops aq_fw_1x_ops = {
1040 	.init = hw_atl_utils_mpi_create,
1041 	.deinit = hw_atl_fw1x_deinit,
1042 	.reset = NULL,
1043 	.get_mac_permanent = hw_atl_utils_get_mac_permanent,
1044 	.set_link_speed = hw_atl_utils_mpi_set_speed,
1045 	.set_state = hw_atl_utils_mpi_set_state,
1046 	.update_link_status = hw_atl_utils_mpi_get_link_status,
1047 	.update_stats = hw_atl_utils_update_stats,
1048 	.get_phy_temp = NULL,
1049 	.set_power = aq_fw1x_set_power,
1050 	.set_eee_rate = NULL,
1051 	.get_eee_rate = NULL,
1052 	.set_flow_control = NULL,
1053 	.send_fw_request = NULL,
1054 	.enable_ptp = NULL,
1055 	.led_control = NULL,
1056 };
1057