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