forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
....@@ -1,10 +1,8 @@
1
-/*
2
- * aQuantia Corporation Network Driver
3
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
1
+// SPDX-License-Identifier: GPL-2.0-only
2
+/* Atlantic Network Driver
43 *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
4
+ * Copyright (C) 2014-2019 aQuantia Corporation
5
+ * Copyright (C) 2019-2020 Marvell International Ltd.
86 */
97
108 /* File hw_atl_utils.c: Definition of common functions for Atlantic hardware
....@@ -25,7 +23,10 @@
2523 #define HW_ATL_MIF_ADDR 0x0208U
2624 #define HW_ATL_MIF_VAL 0x020CU
2725
28
-#define HW_ATL_FW_SM_RAM 0x2U
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
+
2930 #define HW_ATL_MPI_FW_VERSION 0x18
3031 #define HW_ATL_MPI_CONTROL_ADR 0x0368U
3132 #define HW_ATL_MPI_STATE_ADR 0x036CU
....@@ -45,34 +46,40 @@
4546 #define HW_ATL_FW_VER_1X 0x01050006U
4647 #define HW_ATL_FW_VER_2X 0x02000000U
4748 #define HW_ATL_FW_VER_3X 0x03000000U
49
+#define HW_ATL_FW_VER_4X 0x04000000U
4850
4951 #define FORCE_FLASHLESS 0
5052
51
-static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
53
+enum mcp_area {
54
+ MCP_AREA_CONFIG = 0x80000000,
55
+ MCP_AREA_SETTINGS = 0x20000000,
56
+};
57
+
5258 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
5359 enum hal_atl_utils_fw_state_e state);
60
+static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
61
+static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
62
+static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
63
+static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
64
+static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
65
+static u32 aq_fw1x_rpc_get(struct aq_hw_s *self);
5466
5567 int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
5668 {
5769 int err = 0;
5870
59
- err = hw_atl_utils_soft_reset(self);
60
- if (err)
61
- return err;
62
-
6371 hw_atl_utils_hw_chip_features_init(self,
6472 &self->chip_features);
6573
66
- hw_atl_utils_get_fw_version(self, &self->fw_ver_actual);
74
+ self->fw_ver_actual = hw_atl_utils_get_fw_version(self);
6775
68
- if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
69
- self->fw_ver_actual) == 0) {
76
+ if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, self->fw_ver_actual)) {
7077 *fw_ops = &aq_fw_1x_ops;
71
- } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
72
- self->fw_ver_actual) == 0) {
78
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X, self->fw_ver_actual)) {
7379 *fw_ops = &aq_fw_2x_ops;
74
- } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
75
- self->fw_ver_actual) == 0) {
80
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X, self->fw_ver_actual)) {
81
+ *fw_ops = &aq_fw_2x_ops;
82
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_4X, self->fw_ver_actual)) {
7683 *fw_ops = &aq_fw_2x_ops;
7784 } else {
7885 aq_pr_err("Bad FW version detected: %x\n",
....@@ -81,6 +88,7 @@
8188 }
8289 self->aq_fw_ops = *fw_ops;
8390 err = self->aq_fw_ops->init(self);
91
+
8492 return err;
8593 }
8694
....@@ -209,7 +217,7 @@
209217
210218 if (rbl_status == 0xF1A7) {
211219 aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
212
- return -ENOTSUPP;
220
+ return -EOPNOTSUPP;
213221 }
214222
215223 for (k = 0; k < 1000; k++) {
....@@ -231,8 +239,10 @@
231239
232240 int hw_atl_utils_soft_reset(struct aq_hw_s *self)
233241 {
234
- int k;
242
+ int ver = hw_atl_utils_get_fw_version(self);
235243 u32 boot_exit_code = 0;
244
+ u32 val;
245
+ int k;
236246
237247 for (k = 0; k < 1000; ++k) {
238248 u32 flb_status = aq_hw_read_reg(self,
....@@ -250,20 +260,41 @@
250260
251261 self->rbl_enabled = (boot_exit_code != 0);
252262
253
- /* FW 1.x may bootup in an invalid POWER state (WOL feature).
254
- * We should work around this by forcing its state back to DEINIT
255
- */
256
- if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
257
- aq_hw_read_reg(self,
258
- HW_ATL_MPI_FW_VERSION))) {
263
+ if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, ver)) {
259264 int err = 0;
260265
266
+ /* FW 1.x may bootup in an invalid POWER state (WOL feature).
267
+ * We should work around this by forcing its state back to DEINIT
268
+ */
261269 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
262
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
263
- HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
264
- 10, 1000U);
270
+ err = readx_poll_timeout_atomic(hw_atl_utils_mpi_get_state,
271
+ self, val,
272
+ (val & HW_ATL_MPI_STATE_MSK) ==
273
+ MPI_DEINIT,
274
+ 10, 10000U);
265275 if (err)
266276 return err;
277
+ } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_4X, ver)) {
278
+ u64 sem_timeout = aq_hw_read_reg(self, HW_ATL_MIF_RESET_TIMEOUT_ADR);
279
+
280
+ /* Acquire 2 semaphores before issuing reset for FW 4.x */
281
+ if (sem_timeout > 3000)
282
+ sem_timeout = 3000;
283
+ sem_timeout = sem_timeout * 1000;
284
+
285
+ if (sem_timeout != 0) {
286
+ int err;
287
+
288
+ err = readx_poll_timeout_atomic(hw_atl_sem_reset1_get, self, val,
289
+ val == 1U, 1U, sem_timeout);
290
+ if (err)
291
+ aq_pr_err("reset sema1 timeout");
292
+
293
+ err = readx_poll_timeout_atomic(hw_atl_sem_reset2_get, self, val,
294
+ val == 1U, 1U, sem_timeout);
295
+ if (err)
296
+ aq_pr_err("reset sema2 timeout");
297
+ }
267298 }
268299
269300 if (self->rbl_enabled)
....@@ -276,16 +307,17 @@
276307 u32 *p, u32 cnt)
277308 {
278309 int err = 0;
310
+ u32 val;
279311
280
- AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
281
- HW_ATL_FW_SM_RAM) == 1U,
282
- 1U, 10000U);
312
+ err = readx_poll_timeout_atomic(hw_atl_sem_ram_get,
313
+ self, val, val == 1U,
314
+ 1U, 10000U);
283315
284316 if (err < 0) {
285317 bool is_locked;
286318
287319 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
288
- is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
320
+ is_locked = hw_atl_sem_ram_get(self);
289321 if (!is_locked) {
290322 err = -ETIME;
291323 goto err_exit;
....@@ -297,14 +329,15 @@
297329 for (++cnt; --cnt && !err;) {
298330 aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
299331
300
- if (IS_CHIP_FEATURE(REVISION_B1))
301
- AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
302
- HW_ATL_MIF_ADDR),
303
- 1, 1000U);
332
+ if (ATL_HW_IS_CHIP_FEATURE(self, REVISION_B1))
333
+ err = readx_poll_timeout_atomic(hw_atl_utils_mif_addr_get,
334
+ self, val, val != a,
335
+ 1U, 1000U);
304336 else
305
- AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
306
- HW_ATL_MIF_CMD)),
307
- 1, 1000U);
337
+ err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
338
+ self, val,
339
+ !(val & 0x100),
340
+ 1U, 1000U);
308341
309342 *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
310343 a += 4;
....@@ -316,64 +349,125 @@
316349 return err;
317350 }
318351
319
-static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
320
- u32 cnt)
352
+static int hw_atl_utils_write_b1_mbox(struct aq_hw_s *self, u32 addr,
353
+ u32 *p, u32 cnt, enum mcp_area area)
354
+{
355
+ u32 data_offset = 0;
356
+ u32 offset = addr;
357
+ int err = 0;
358
+ u32 val;
359
+
360
+ switch (area) {
361
+ case MCP_AREA_CONFIG:
362
+ offset -= self->rpc_addr;
363
+ break;
364
+
365
+ case MCP_AREA_SETTINGS:
366
+ offset -= self->settings_addr;
367
+ break;
368
+ }
369
+
370
+ offset = offset / sizeof(u32);
371
+
372
+ for (; data_offset < cnt; ++data_offset, ++offset) {
373
+ aq_hw_write_reg(self, 0x328, p[data_offset]);
374
+ aq_hw_write_reg(self, 0x32C,
375
+ (area | (0xFFFF & (offset * 4))));
376
+ hw_atl_mcp_up_force_intr_set(self, 1);
377
+ /* 1000 times by 10us = 10ms */
378
+ err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
379
+ self, val,
380
+ (val & 0xF0000000) !=
381
+ area,
382
+ 10U, 10000U);
383
+
384
+ if (err < 0)
385
+ break;
386
+ }
387
+
388
+ return err;
389
+}
390
+
391
+static int hw_atl_utils_write_b0_mbox(struct aq_hw_s *self, u32 addr,
392
+ u32 *p, u32 cnt)
393
+{
394
+ u32 offset = 0;
395
+ int err = 0;
396
+ u32 val;
397
+
398
+ aq_hw_write_reg(self, 0x208, addr);
399
+
400
+ for (; offset < cnt; ++offset) {
401
+ aq_hw_write_reg(self, 0x20C, p[offset]);
402
+ aq_hw_write_reg(self, 0x200, 0xC000);
403
+
404
+ err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
405
+ self, val,
406
+ (val & 0x100) == 0U,
407
+ 10U, 10000U);
408
+
409
+ if (err < 0)
410
+ break;
411
+ }
412
+
413
+ return err;
414
+}
415
+
416
+static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 addr, u32 *p,
417
+ u32 cnt, enum mcp_area area)
321418 {
322419 int err = 0;
323
- bool is_locked;
420
+ u32 val;
324421
325
- is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
326
- if (!is_locked) {
327
- err = -ETIME;
422
+ err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, self,
423
+ val, val == 1U,
424
+ 10U, 100000U);
425
+ if (err < 0)
328426 goto err_exit;
329
- }
330
- if (IS_CHIP_FEATURE(REVISION_B1)) {
331
- u32 offset = 0;
332427
333
- for (; offset < cnt; ++offset) {
334
- aq_hw_write_reg(self, 0x328, p[offset]);
335
- aq_hw_write_reg(self, 0x32C,
336
- (0x80000000 | (0xFFFF & (offset * 4))));
337
- hw_atl_mcp_up_force_intr_set(self, 1);
338
- /* 1000 times by 10us = 10ms */
339
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
340
- 0x32C) & 0xF0000000) !=
341
- 0x80000000,
342
- 10, 1000);
343
- }
344
- } else {
345
- u32 offset = 0;
346
-
347
- aq_hw_write_reg(self, 0x208, a);
348
-
349
- for (; offset < cnt; ++offset) {
350
- aq_hw_write_reg(self, 0x20C, p[offset]);
351
- aq_hw_write_reg(self, 0x200, 0xC000);
352
-
353
- AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) &
354
- 0x100) == 0, 10, 1000);
355
- }
356
- }
428
+ if (ATL_HW_IS_CHIP_FEATURE(self, REVISION_B1))
429
+ err = hw_atl_utils_write_b1_mbox(self, addr, p, cnt, area);
430
+ else
431
+ err = hw_atl_utils_write_b0_mbox(self, addr, p, cnt);
357432
358433 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
434
+
435
+ if (err < 0)
436
+ goto err_exit;
437
+
438
+ err = aq_hw_err_from_flags(self);
359439
360440 err_exit:
361441 return err;
362442 }
363443
364
-static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
444
+int hw_atl_write_fwcfg_dwords(struct aq_hw_s *self, u32 *p, u32 cnt)
365445 {
366
- int err = 0;
446
+ return hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, p,
447
+ cnt, MCP_AREA_CONFIG);
448
+}
449
+
450
+int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
451
+ u32 cnt)
452
+{
453
+ return hw_atl_utils_fw_upload_dwords(self, self->settings_addr + offset,
454
+ p, cnt, MCP_AREA_SETTINGS);
455
+}
456
+
457
+bool hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
458
+{
367459 const u32 dw_major_mask = 0xff000000U;
368460 const u32 dw_minor_mask = 0x00ffffffU;
461
+ bool ver_match;
369462
370
- err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
371
- if (err < 0)
463
+ ver_match = (dw_major_mask & (ver_expected ^ ver_actual)) ? false : true;
464
+ if (!ver_match)
372465 goto err_exit;
373
- err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
374
- -EOPNOTSUPP : 0;
466
+ ver_match = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
467
+ false : true;
468
+
375469 err_exit:
376
- return err;
470
+ return ver_match;
377471 }
378472
379473 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
....@@ -394,14 +488,17 @@
394488 hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
395489
396490 /* check 10 times by 1ms */
397
- AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
398
- aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
491
+ err = readx_poll_timeout_atomic(hw_atl_scrpad25_get,
492
+ self, self->mbox_addr,
493
+ self->mbox_addr != 0U,
494
+ 1000U, 10000U);
495
+ err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
496
+ self->rpc_addr,
497
+ self->rpc_addr != 0U,
498
+ 1000U, 100000U);
399499
400500 return err;
401501 }
402
-
403
-#define HW_ATL_RPC_CONTROL_ADR 0x0338U
404
-#define HW_ATL_RPC_STATE_ADR 0x033CU
405502
406503 struct aq_hw_atl_utils_fw_rpc_tid_s {
407504 union {
....@@ -417,17 +514,16 @@
417514
418515 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
419516 {
420
- int err = 0;
421517 struct aq_hw_atl_utils_fw_rpc_tid_s sw;
518
+ int err = 0;
422519
423
- if (!IS_CHIP_FEATURE(MIPS)) {
520
+ if (!ATL_HW_IS_CHIP_FEATURE(self, MIPS)) {
424521 err = -1;
425522 goto err_exit;
426523 }
427
- err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
428
- (u32 *)(void *)&self->rpc,
429
- (rpc_size + sizeof(u32) -
430
- sizeof(u8)) / sizeof(u32));
524
+ err = hw_atl_write_fwcfg_dwords(self, (u32 *)(void *)&self->rpc,
525
+ (rpc_size + sizeof(u32) -
526
+ sizeof(u8)) / sizeof(u32));
431527 if (err < 0)
432528 goto err_exit;
433529
....@@ -440,21 +536,25 @@
440536 }
441537
442538 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
443
- struct hw_aq_atl_utils_fw_rpc **rpc)
539
+ struct hw_atl_utils_fw_rpc **rpc)
444540 {
445
- int err = 0;
446541 struct aq_hw_atl_utils_fw_rpc_tid_s sw;
447542 struct aq_hw_atl_utils_fw_rpc_tid_s fw;
543
+ int err = 0;
448544
449545 do {
450546 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
451547
452548 self->rpc_tid = sw.tid;
453549
454
- AQ_HW_WAIT_FOR(sw.tid ==
455
- (fw.val =
456
- aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
457
- fw.tid), 1000U, 100U);
550
+ err = readx_poll_timeout_atomic(hw_atl_utils_rpc_state_get,
551
+ self, fw.val,
552
+ sw.tid == fw.tid,
553
+ 1000U, 100000U);
554
+ if (err < 0)
555
+ goto err_exit;
556
+
557
+ err = aq_hw_err_from_flags(self);
458558 if (err < 0)
459559 goto err_exit;
460560
....@@ -469,8 +569,6 @@
469569 goto err_exit;
470570 }
471571 } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
472
- if (err < 0)
473
- goto err_exit;
474572
475573 if (rpc) {
476574 if (fw.len) {
....@@ -485,7 +583,7 @@
485583 (u32 *)(void *)
486584 &self->rpc,
487585 (fw.len + sizeof(u32) -
488
- sizeof(u8)) /
586
+ sizeof(u8)) /
489587 sizeof(u32));
490588 if (err < 0)
491589 goto err_exit;
....@@ -515,16 +613,16 @@
515613 }
516614
517615 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
518
- struct hw_aq_atl_utils_mbox_header *pmbox)
616
+ struct hw_atl_utils_mbox_header *pmbox)
519617 {
520618 return hw_atl_utils_fw_downld_dwords(self,
521
- self->mbox_addr,
522
- (u32 *)(void *)pmbox,
523
- sizeof(*pmbox) / sizeof(u32));
619
+ self->mbox_addr,
620
+ (u32 *)(void *)pmbox,
621
+ sizeof(*pmbox) / sizeof(u32));
524622 }
525623
526624 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
527
- struct hw_aq_atl_utils_mbox *pmbox)
625
+ struct hw_atl_utils_mbox *pmbox)
528626 {
529627 int err = 0;
530628
....@@ -535,14 +633,14 @@
535633 if (err < 0)
536634 goto err_exit;
537635
538
- if (IS_CHIP_FEATURE(REVISION_A0)) {
636
+ if (ATL_HW_IS_CHIP_FEATURE(self, REVISION_A0)) {
539637 unsigned int mtu = self->aq_nic_cfg ?
540638 self->aq_nic_cfg->mtu : 1514U;
541639 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
542640 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
543641 pmbox->stats.dpc = atomic_read(&self->dpc);
544642 } else {
545
- pmbox->stats.dpc = hw_atl_reg_rx_dma_stat_counter7get(self);
643
+ pmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
546644 }
547645
548646 err_exit:;
....@@ -562,20 +660,21 @@
562660 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
563661 enum hal_atl_utils_fw_state_e state)
564662 {
565
- int err = 0;
566
- u32 transaction_id = 0;
567
- struct hw_aq_atl_utils_mbox_header mbox;
568663 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
664
+ struct hw_atl_utils_mbox_header mbox;
665
+ u32 transaction_id = 0;
666
+ int err = 0;
569667
570668 if (state == MPI_RESET) {
571669 hw_atl_utils_mpi_read_mbox(self, &mbox);
572670
573671 transaction_id = mbox.transaction_id;
574672
575
- AQ_HW_WAIT_FOR(transaction_id !=
576
- (hw_atl_utils_mpi_read_mbox(self, &mbox),
577
- mbox.transaction_id),
578
- 1000U, 100U);
673
+ err = readx_poll_timeout_atomic(hw_atl_utils_get_mpi_mbox_tid,
674
+ self, mbox.transaction_id,
675
+ transaction_id !=
676
+ mbox.transaction_id,
677
+ 1000U, 100000U);
579678 if (err < 0)
580679 goto err_exit;
581680 }
....@@ -592,20 +691,24 @@
592691 val |= state & HW_ATL_MPI_STATE_MSK;
593692
594693 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
694
+
595695 err_exit:
596696 return err;
597697 }
598698
599699 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
600700 {
601
- u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
602
- u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
603701 struct aq_hw_link_status_s *link_status = &self->aq_link_status;
702
+ u32 mpi_state;
703
+ u32 speed;
604704
605
- if (!link_speed_mask) {
705
+ mpi_state = hw_atl_utils_mpi_get_state(self);
706
+ speed = mpi_state >> HW_ATL_MPI_SPEED_SHIFT;
707
+
708
+ if (!speed) {
606709 link_status->mbps = 0U;
607710 } else {
608
- switch (link_speed_mask) {
711
+ switch (speed) {
609712 case HAL_ATLANTIC_RATE_10G:
610713 link_status->mbps = 10000U;
611714 break;
....@@ -615,7 +718,7 @@
615718 link_status->mbps = 5000U;
616719 break;
617720
618
- case HAL_ATLANTIC_RATE_2GS:
721
+ case HAL_ATLANTIC_RATE_2G5:
619722 link_status->mbps = 2500U;
620723 break;
621724
....@@ -631,6 +734,7 @@
631734 return -EBUSY;
632735 }
633736 }
737
+ link_status->full_duplex = true;
634738
635739 return 0;
636740 }
....@@ -638,14 +742,15 @@
638742 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
639743 u8 *mac)
640744 {
745
+ u32 mac_addr[2];
746
+ u32 efuse_addr;
641747 int err = 0;
642748 u32 h = 0U;
643749 u32 l = 0U;
644
- u32 mac_addr[2];
645750
646751 if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
647
- unsigned int rnd = 0;
648752 unsigned int ucp_0x370 = 0;
753
+ unsigned int rnd = 0;
649754
650755 get_random_bytes(&rnd, sizeof(unsigned int));
651756
....@@ -653,11 +758,10 @@
653758 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
654759 }
655760
656
- err = hw_atl_utils_fw_downld_dwords(self,
657
- aq_hw_read_reg(self, 0x00000374U) +
658
- (40U * 4U),
659
- mac_addr,
660
- ARRAY_SIZE(mac_addr));
761
+ efuse_addr = aq_hw_read_reg(self, 0x00000374U);
762
+
763
+ err = hw_atl_utils_fw_downld_dwords(self, efuse_addr + (40U * 4U),
764
+ mac_addr, ARRAY_SIZE(mac_addr));
661765 if (err < 0) {
662766 mac_addr[0] = 0U;
663767 mac_addr[1] = 0U;
....@@ -671,9 +775,9 @@
671775
672776 if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
673777 /* chip revision */
674
- l = 0xE3000000U
675
- | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
676
- | (0x00 << 16);
778
+ l = 0xE3000000U |
779
+ (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
780
+ (0x00 << 16);
677781 h = 0x8001300EU;
678782
679783 mac[5] = (u8)(0xFFU & l);
....@@ -719,31 +823,34 @@
719823 default:
720824 break;
721825 }
826
+
722827 return ret;
723828 }
724829
725830 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
726831 {
727
- u32 chip_features = 0U;
728832 u32 val = hw_atl_reg_glb_mif_id_get(self);
729833 u32 mif_rev = val & 0xFFU;
834
+ u32 chip_features = 0U;
835
+
836
+ chip_features |= ATL_HW_CHIP_ATLANTIC;
730837
731838 if ((0xFU & mif_rev) == 1U) {
732
- chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
733
- HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
734
- HAL_ATLANTIC_UTILS_CHIP_MIPS;
839
+ chip_features |= ATL_HW_CHIP_REVISION_A0 |
840
+ ATL_HW_CHIP_MPI_AQ |
841
+ ATL_HW_CHIP_MIPS;
735842 } else if ((0xFU & mif_rev) == 2U) {
736
- chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
737
- HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
738
- HAL_ATLANTIC_UTILS_CHIP_MIPS |
739
- HAL_ATLANTIC_UTILS_CHIP_TPO2 |
740
- HAL_ATLANTIC_UTILS_CHIP_RPF2;
843
+ chip_features |= ATL_HW_CHIP_REVISION_B0 |
844
+ ATL_HW_CHIP_MPI_AQ |
845
+ ATL_HW_CHIP_MIPS |
846
+ ATL_HW_CHIP_TPO2 |
847
+ ATL_HW_CHIP_RPF2;
741848 } else if ((0xFU & mif_rev) == 0xAU) {
742
- chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
743
- HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
744
- HAL_ATLANTIC_UTILS_CHIP_MIPS |
745
- HAL_ATLANTIC_UTILS_CHIP_TPO2 |
746
- HAL_ATLANTIC_UTILS_CHIP_RPF2;
849
+ chip_features |= ATL_HW_CHIP_REVISION_B1 |
850
+ ATL_HW_CHIP_MPI_AQ |
851
+ ATL_HW_CHIP_MIPS |
852
+ ATL_HW_CHIP_TPO2 |
853
+ ATL_HW_CHIP_RPF2;
747854 }
748855
749856 *p = chip_features;
....@@ -753,25 +860,27 @@
753860 {
754861 hw_atl_utils_mpi_set_speed(self, 0);
755862 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
756
- return 0;
757
-}
758863
759
-int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
760
- unsigned int power_state)
761
-{
762
- hw_atl_utils_mpi_set_speed(self, 0);
763
- hw_atl_utils_mpi_set_state(self, MPI_POWER);
764864 return 0;
765865 }
766866
767867 int hw_atl_utils_update_stats(struct aq_hw_s *self)
768868 {
769
- struct hw_aq_atl_utils_mbox mbox;
869
+ struct aq_stats_s *cs = &self->curr_stats;
870
+ struct aq_stats_s curr_stats = *cs;
871
+ struct hw_atl_utils_mbox mbox;
872
+ bool corrupted_stats = false;
770873
771874 hw_atl_utils_mpi_read_stats(self, &mbox);
772875
773
-#define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
774
- mbox.stats._N_ - self->last_stats._N_)
876
+#define AQ_SDELTA(_N_) \
877
+do { \
878
+ if (!corrupted_stats && \
879
+ ((s64)(mbox.stats._N_ - self->last_stats._N_)) >= 0) \
880
+ curr_stats._N_ += mbox.stats._N_ - self->last_stats._N_; \
881
+ else \
882
+ corrupted_stats = true; \
883
+} while (0)
775884
776885 if (self->aq_link_status.mbps) {
777886 AQ_SDELTA(uprc);
....@@ -791,12 +900,16 @@
791900 AQ_SDELTA(bbrc);
792901 AQ_SDELTA(bbtc);
793902 AQ_SDELTA(dpc);
903
+
904
+ if (!corrupted_stats)
905
+ *cs = curr_stats;
794906 }
795907 #undef AQ_SDELTA
796
- self->curr_stats.dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self);
797
- self->curr_stats.dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self);
798
- self->curr_stats.dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counterlsw_get(self);
799
- self->curr_stats.dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counterlsw_get(self);
908
+
909
+ cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self);
910
+ cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self);
911
+ cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self);
912
+ cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self);
800913
801914 memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
802915
....@@ -842,13 +955,127 @@
842955 for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
843956 regs_buff[i] = aq_hw_read_reg(self,
844957 hw_atl_utils_hw_mac_regs[i]);
958
+
845959 return 0;
846960 }
847961
848
-int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
962
+u32 hw_atl_utils_get_fw_version(struct aq_hw_s *self)
849963 {
850
- *fw_version = aq_hw_read_reg(self, 0x18U);
851
- return 0;
964
+ return aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
965
+}
966
+
967
+static int aq_fw1x_set_wake_magic(struct aq_hw_s *self, bool wol_enabled,
968
+ u8 *mac)
969
+{
970
+ struct hw_atl_utils_fw_rpc *prpc = NULL;
971
+ unsigned int rpc_size = 0U;
972
+ int err = 0;
973
+
974
+ err = hw_atl_utils_fw_rpc_wait(self, &prpc);
975
+ if (err < 0)
976
+ goto err_exit;
977
+
978
+ memset(prpc, 0, sizeof(*prpc));
979
+
980
+ if (wol_enabled) {
981
+ rpc_size = offsetof(struct hw_atl_utils_fw_rpc, msg_wol_add) +
982
+ sizeof(prpc->msg_wol_add);
983
+
984
+
985
+ prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
986
+ prpc->msg_wol_add.priority =
987
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
988
+ prpc->msg_wol_add.pattern_id =
989
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
990
+ prpc->msg_wol_add.packet_type =
991
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
992
+
993
+ ether_addr_copy((u8 *)&prpc->msg_wol_add.magic_packet_pattern,
994
+ mac);
995
+ } else {
996
+ rpc_size = sizeof(prpc->msg_wol_remove) +
997
+ offsetof(struct hw_atl_utils_fw_rpc, msg_wol_remove);
998
+
999
+ prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
1000
+ prpc->msg_wol_add.pattern_id =
1001
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
1002
+ }
1003
+
1004
+ err = hw_atl_utils_fw_rpc_call(self, rpc_size);
1005
+
1006
+err_exit:
1007
+ return err;
1008
+}
1009
+
1010
+static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
1011
+ u8 *mac)
1012
+{
1013
+ struct hw_atl_utils_fw_rpc *prpc = NULL;
1014
+ unsigned int rpc_size = 0U;
1015
+ int err = 0;
1016
+
1017
+ if (self->aq_nic_cfg->wol & WAKE_MAGIC) {
1018
+ err = aq_fw1x_set_wake_magic(self, 1, mac);
1019
+
1020
+ if (err < 0)
1021
+ goto err_exit;
1022
+
1023
+ rpc_size = sizeof(prpc->msg_id) +
1024
+ sizeof(prpc->msg_enable_wakeup);
1025
+
1026
+ err = hw_atl_utils_fw_rpc_wait(self, &prpc);
1027
+
1028
+ if (err < 0)
1029
+ goto err_exit;
1030
+
1031
+ memset(prpc, 0, rpc_size);
1032
+
1033
+ prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
1034
+ prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
1035
+
1036
+ err = hw_atl_utils_fw_rpc_call(self, rpc_size);
1037
+ if (err < 0)
1038
+ goto err_exit;
1039
+ }
1040
+ hw_atl_utils_mpi_set_speed(self, 0);
1041
+ hw_atl_utils_mpi_set_state(self, MPI_POWER);
1042
+
1043
+err_exit:
1044
+ return err;
1045
+}
1046
+
1047
+static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self)
1048
+{
1049
+ struct hw_atl_utils_mbox_header mbox;
1050
+
1051
+ hw_atl_utils_mpi_read_mbox(self, &mbox);
1052
+
1053
+ return mbox.transaction_id;
1054
+}
1055
+
1056
+static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self)
1057
+{
1058
+ return aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
1059
+}
1060
+
1061
+static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self)
1062
+{
1063
+ return aq_hw_read_reg(self, HW_ATL_MIF_CMD);
1064
+}
1065
+
1066
+static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self)
1067
+{
1068
+ return aq_hw_read_reg(self, HW_ATL_MIF_ADDR);
1069
+}
1070
+
1071
+static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
1072
+{
1073
+ return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
1074
+}
1075
+
1076
+static u32 aq_fw1x_rpc_get(struct aq_hw_s *self)
1077
+{
1078
+ return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR);
8521079 }
8531080
8541081 const struct aq_fw_ops aq_fw_1x_ops = {
....@@ -860,5 +1087,13 @@
8601087 .set_state = hw_atl_utils_mpi_set_state,
8611088 .update_link_status = hw_atl_utils_mpi_get_link_status,
8621089 .update_stats = hw_atl_utils_update_stats,
1090
+ .get_mac_temp = NULL,
1091
+ .get_phy_temp = NULL,
1092
+ .set_power = aq_fw1x_set_power,
1093
+ .set_eee_rate = NULL,
1094
+ .get_eee_rate = NULL,
8631095 .set_flow_control = NULL,
1096
+ .send_fw_request = NULL,
1097
+ .enable_ptp = NULL,
1098
+ .led_control = NULL,
8641099 };