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