net/atlantic: use EEPROM magic as a device address
[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 offset = 0;
336
337                 for (; offset < cnt; ++offset) {
338                         aq_hw_write_reg(self, 0x328, p[offset]);
339                         aq_hw_write_reg(self, 0x32C,
340                                 (0x80000000 | (0xFFFF & (offset * 4))));
341                         hw_atl_mcp_up_force_intr_set(self, 1);
342                         /* 1000 times by 10us = 10ms */
343                         AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
344                                         0x32C) & 0xF0000000) != 0x80000000,
345                                         10, 1000);
346                 }
347         } else {
348                 u32 offset = 0;
349
350                 aq_hw_write_reg(self, 0x208, a);
351
352                 for (; offset < cnt; ++offset) {
353                         aq_hw_write_reg(self, 0x20C, p[offset]);
354                         aq_hw_write_reg(self, 0x200, 0xC000);
355
356                         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U)
357                                         & 0x100) == 0, 10, 1000);
358                 }
359         }
360
361         hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
362
363 err_exit:
364         return err;
365 }
366
367 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
368 {
369         int err = 0;
370         const u32 dw_major_mask = 0xff000000U;
371         const u32 dw_minor_mask = 0x00ffffffU;
372
373         err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
374         if (err < 0)
375                 goto err_exit;
376         err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
377                 -EOPNOTSUPP : 0;
378 err_exit:
379         return err;
380 }
381
382 static int hw_atl_utils_init_ucp(struct aq_hw_s *self)
383 {
384         int err = 0;
385
386         if (!aq_hw_read_reg(self, 0x370U)) {
387                 unsigned int rnd = (uint32_t)rte_rand();
388                 unsigned int ucp_0x370 = 0U;
389
390                 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
391                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
392         }
393
394         hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
395
396         /* check 10 times by 1ms */
397         AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
398                        aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
399         AQ_HW_WAIT_FOR(0U != (self->rpc_addr =
400                        aq_hw_read_reg(self, 0x334U)), 1000U, 100U);
401
402         return err;
403 }
404
405 #define HW_ATL_RPC_CONTROL_ADR 0x0338U
406 #define HW_ATL_RPC_STATE_ADR   0x033CU
407
408 struct aq_hw_atl_utils_fw_rpc_tid_s {
409         union {
410                 u32 val;
411                 struct {
412                         u16 tid;
413                         u16 len;
414                 };
415         };
416 };
417
418 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
419
420 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
421 {
422         int err = 0;
423         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
424
425         if (!IS_CHIP_FEATURE(MIPS)) {
426                 err = -1;
427                 goto err_exit;
428         }
429         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
430                                             (u32 *)(void *)&self->rpc,
431                                             (rpc_size + sizeof(u32) -
432                                             sizeof(u8)) / sizeof(u32));
433         if (err < 0)
434                 goto err_exit;
435
436         sw.tid = 0xFFFFU & (++self->rpc_tid);
437         sw.len = (u16)rpc_size;
438         aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
439
440 err_exit:
441         return err;
442 }
443
444 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
445                                     struct hw_aq_atl_utils_fw_rpc **rpc)
446 {
447         int err = 0;
448         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
449         struct aq_hw_atl_utils_fw_rpc_tid_s fw;
450
451         do {
452                 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
453
454                 self->rpc_tid = sw.tid;
455
456                 AQ_HW_WAIT_FOR(sw.tid ==
457                                 (fw.val =
458                                 aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
459                                 fw.tid), 1000U, 100U);
460                 if (err < 0)
461                         goto err_exit;
462
463                 if (fw.len == 0xFFFFU) {
464                         err = hw_atl_utils_fw_rpc_call(self, sw.len);
465                         if (err < 0)
466                                 goto err_exit;
467                 }
468         } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
469
470         if (rpc) {
471                 if (fw.len) {
472                         err =
473                         hw_atl_utils_fw_downld_dwords(self,
474                                                       self->rpc_addr,
475                                                       (u32 *)(void *)
476                                                       &self->rpc,
477                                                       (fw.len + sizeof(u32) -
478                                                       sizeof(u8)) /
479                                                       sizeof(u32));
480                         if (err < 0)
481                                 goto err_exit;
482                 }
483
484                 *rpc = &self->rpc;
485         }
486
487 err_exit:
488         return err;
489 }
490
491 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
492 {
493         int err = 0;
494
495         err = hw_atl_utils_init_ucp(self);
496         if (err < 0)
497                 goto err_exit;
498
499         err = hw_atl_utils_fw_rpc_init(self);
500         if (err < 0)
501                 goto err_exit;
502
503 err_exit:
504         return err;
505 }
506
507 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
508                                struct hw_aq_atl_utils_mbox_header *pmbox)
509 {
510         return hw_atl_utils_fw_downld_dwords(self,
511                                       self->mbox_addr,
512                                       (u32 *)(void *)pmbox,
513                                       sizeof(*pmbox) / sizeof(u32));
514 }
515
516 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
517                                  struct hw_aq_atl_utils_mbox *pmbox)
518 {
519         int err = 0;
520
521         err = hw_atl_utils_fw_downld_dwords(self,
522                                             self->mbox_addr,
523                                             (u32 *)(void *)pmbox,
524                                             sizeof(*pmbox) / sizeof(u32));
525         if (err < 0)
526                 goto err_exit;
527
528         if (IS_CHIP_FEATURE(REVISION_A0)) {
529                 unsigned int mtu = 1514;
530                 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
531                 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
532         } else {
533                 pmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
534         }
535
536 err_exit:;
537 }
538
539 static
540 int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
541 {
542         u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
543
544         val = val & ~HW_ATL_MPI_SPEED_MSK;
545         val |= speed << HW_ATL_MPI_SPEED_SHIFT;
546         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
547
548         return 0;
549 }
550
551 int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
552                                 enum hal_atl_utils_fw_state_e state)
553 {
554         int err = 0;
555         u32 transaction_id = 0;
556         struct hw_aq_atl_utils_mbox_header mbox;
557         u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
558
559         if (state == MPI_RESET) {
560                 hw_atl_utils_mpi_read_mbox(self, &mbox);
561
562                 transaction_id = mbox.transaction_id;
563
564                 AQ_HW_WAIT_FOR(transaction_id !=
565                                 (hw_atl_utils_mpi_read_mbox(self, &mbox),
566                                  mbox.transaction_id),
567                                1000U, 100U);
568                 if (err < 0)
569                         goto err_exit;
570         }
571         /* On interface DEINIT we disable DW (raise bit)
572          * Otherwise enable DW (clear bit)
573          */
574         if (state == MPI_DEINIT || state == MPI_POWER)
575                 val |= HW_ATL_MPI_DIRTY_WAKE_MSK;
576         else
577                 val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK;
578
579         /* Set new state bits */
580         val = val & ~HW_ATL_MPI_STATE_MSK;
581         val |= state & HW_ATL_MPI_STATE_MSK;
582
583         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
584 err_exit:
585         return err;
586 }
587
588 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
589 {
590         u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
591         u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
592         struct aq_hw_link_status_s *link_status = &self->aq_link_status;
593
594         if (!link_speed_mask) {
595                 link_status->mbps = 0U;
596         } else {
597                 switch (link_speed_mask) {
598                 case HAL_ATLANTIC_RATE_10G:
599                         link_status->mbps = 10000U;
600                         break;
601
602                 case HAL_ATLANTIC_RATE_5G:
603                 case HAL_ATLANTIC_RATE_5GSR:
604                         link_status->mbps = 5000U;
605                         break;
606
607                 case HAL_ATLANTIC_RATE_2GS:
608                         link_status->mbps = 2500U;
609                         break;
610
611                 case HAL_ATLANTIC_RATE_1G:
612                         link_status->mbps = 1000U;
613                         break;
614
615                 case HAL_ATLANTIC_RATE_100M:
616                         link_status->mbps = 100U;
617                         break;
618
619                 default:
620                         return -EBUSY;
621                 }
622         }
623
624         return 0;
625 }
626
627 static int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
628                                    u8 *mac)
629 {
630         int err = 0;
631         u32 h = 0U;
632         u32 l = 0U;
633         u32 mac_addr[2];
634
635         if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
636                 unsigned int rnd = (uint32_t)rte_rand();
637                 unsigned int ucp_0x370 = 0;
638
639                 //get_random_bytes(&rnd, sizeof(unsigned int));
640
641                 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
642                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
643         }
644
645         err = hw_atl_utils_fw_downld_dwords(self,
646                                             aq_hw_read_reg(self, 0x00000374U) +
647                                             (40U * 4U),
648                                             mac_addr,
649                                             ARRAY_SIZE(mac_addr));
650         if (err < 0) {
651                 mac_addr[0] = 0U;
652                 mac_addr[1] = 0U;
653                 err = 0;
654         } else {
655                 mac_addr[0] = rte_constant_bswap32(mac_addr[0]);
656                 mac_addr[1] = rte_constant_bswap32(mac_addr[1]);
657         }
658
659         ether_addr_copy((struct ether_addr *)mac_addr,
660                         (struct ether_addr *)mac);
661
662         if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
663                 /* chip revision */
664                 l = 0xE3000000U
665                         | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
666                         | (0x00 << 16);
667                 h = 0x8001300EU;
668
669                 mac[5] = (u8)(0xFFU & l);
670                 l >>= 8;
671                 mac[4] = (u8)(0xFFU & l);
672                 l >>= 8;
673                 mac[3] = (u8)(0xFFU & l);
674                 l >>= 8;
675                 mac[2] = (u8)(0xFFU & l);
676                 mac[1] = (u8)(0xFFU & h);
677                 h >>= 8;
678                 mac[0] = (u8)(0xFFU & h);
679         }
680
681         return err;
682 }
683
684 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
685 {
686         unsigned int ret = 0U;
687
688         switch (mbps) {
689         case 100U:
690                 ret = 5U;
691                 break;
692
693         case 1000U:
694                 ret = 4U;
695                 break;
696
697         case 2500U:
698                 ret = 3U;
699                 break;
700
701         case 5000U:
702                 ret = 1U;
703                 break;
704
705         case 10000U:
706                 ret = 0U;
707                 break;
708
709         default:
710                 break;
711         }
712         return ret;
713 }
714
715 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
716 {
717         u32 chip_features = 0U;
718         u32 val = hw_atl_reg_glb_mif_id_get(self);
719         u32 mif_rev = val & 0xFFU;
720
721         if ((0xFU & mif_rev) == 1U) {
722                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
723                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
724                         HAL_ATLANTIC_UTILS_CHIP_MIPS;
725         } else if ((0xFU & mif_rev) == 2U) {
726                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
727                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
728                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
729                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
730                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
731         } else if ((0xFU & mif_rev) == 0xAU) {
732                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
733                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
734                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
735                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
736                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
737         }
738
739         *p = chip_features;
740 }
741
742 static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
743 {
744         hw_atl_utils_mpi_set_speed(self, 0);
745         hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
746         return 0;
747 }
748
749 int hw_atl_utils_update_stats(struct aq_hw_s *self)
750 {
751         struct hw_aq_atl_utils_mbox mbox;
752
753         hw_atl_utils_mpi_read_stats(self, &mbox);
754
755 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
756                         mbox.stats._N_ - self->last_stats._N_)
757
758         if (1) {//self->aq_link_status.mbps) {
759                 AQ_SDELTA(uprc);
760                 AQ_SDELTA(mprc);
761                 AQ_SDELTA(bprc);
762                 AQ_SDELTA(erpt);
763
764                 AQ_SDELTA(uptc);
765                 AQ_SDELTA(mptc);
766                 AQ_SDELTA(bptc);
767                 AQ_SDELTA(erpr);
768                 AQ_SDELTA(ubrc);
769                 AQ_SDELTA(ubtc);
770                 AQ_SDELTA(mbrc);
771                 AQ_SDELTA(mbtc);
772                 AQ_SDELTA(bbrc);
773                 AQ_SDELTA(bbtc);
774                 AQ_SDELTA(dpc);
775         }
776 #undef AQ_SDELTA
777         self->curr_stats.dma_pkt_rc =
778            hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self) +
779            ((u64)hw_atl_stats_rx_dma_good_pkt_countermsw_get(self) << 32);
780         self->curr_stats.dma_pkt_tc =
781            hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self) +
782            ((u64)hw_atl_stats_tx_dma_good_pkt_countermsw_get(self) << 32);
783         self->curr_stats.dma_oct_rc =
784            hw_atl_stats_rx_dma_good_octet_counterlsw_get(self) +
785            ((u64)hw_atl_stats_rx_dma_good_octet_countermsw_get(self) << 32);
786         self->curr_stats.dma_oct_tc =
787            hw_atl_stats_tx_dma_good_octet_counterlsw_get(self) +
788            ((u64)hw_atl_stats_tx_dma_good_octet_countermsw_get(self) << 32);
789
790         self->curr_stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
791
792         memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
793
794         return 0;
795 }
796
797 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
798 {
799         return &self->curr_stats;
800 }
801
802 static const u32 hw_atl_utils_hw_mac_regs[] = {
803         0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
804         0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
805         0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
806         0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
807         0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
808         0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
809         0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
810         0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
811         0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
812         0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
813         0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
814         0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
815         0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
816         0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
817         0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
818         0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
819         0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
820         0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
821         0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
822         0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
823         0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
824         0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
825 };
826
827 unsigned int hw_atl_utils_hw_get_reg_length(void)
828 {
829         return ARRAY_SIZE(hw_atl_utils_hw_mac_regs);
830 }
831
832 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
833                              u32 *regs_buff)
834 {
835         unsigned int i = 0U;
836         unsigned int mac_regs_count = hw_atl_utils_hw_get_reg_length();
837
838         for (i = 0; i < mac_regs_count; i++)
839                 regs_buff[i] = aq_hw_read_reg(self,
840                                               hw_atl_utils_hw_mac_regs[i]);
841         return 0;
842 }
843
844 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
845 {
846         *fw_version = aq_hw_read_reg(self, 0x18U);
847         return 0;
848 }
849
850 static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)
851 {
852         struct hw_aq_atl_utils_fw_rpc *prpc = NULL;
853         unsigned int rpc_size = 0U;
854         int err = 0;
855
856         err = hw_atl_utils_fw_rpc_wait(self, &prpc);
857         if (err < 0)
858                 goto err_exit;
859
860         memset(prpc, 0, sizeof(*prpc));
861
862         if (wol_enabled) {
863                 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
864
865                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
866                 prpc->msg_wol.priority = 0x10000000; /* normal priority */
867                 prpc->msg_wol.pattern_id = 1U;
868                 prpc->msg_wol.wol_packet_type = 2U; /* Magic Packet */
869
870                 ether_addr_copy((struct ether_addr *)mac,
871                         (struct ether_addr *)&prpc->msg_wol.wol_pattern);
872         } else {
873                 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
874
875                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
876                 prpc->msg_wol.pattern_id = 1U;
877         }
878
879         err = hw_atl_utils_fw_rpc_call(self, rpc_size);
880
881 err_exit:
882         return err;
883 }
884
885 static
886 int aq_fw1x_set_power(struct aq_hw_s *self,
887                       unsigned int power_state __rte_unused,
888                       u8 *mac)
889 {
890         struct hw_aq_atl_utils_fw_rpc *prpc = NULL;
891         unsigned int rpc_size = 0U;
892         int err = 0;
893         if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
894                 err = aq_fw1x_set_wol(self, 1, mac);
895
896                 if (err < 0)
897                         goto err_exit;
898
899                 rpc_size = sizeof(prpc->msg_id) +
900                                 sizeof(prpc->msg_enable_wakeup);
901
902                 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
903
904                 if (err < 0)
905                         goto err_exit;
906
907                 memset(prpc, 0, rpc_size);
908
909                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
910                 prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
911
912                 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
913                 if (err < 0)
914                         goto err_exit;
915         }
916
917         hw_atl_utils_mpi_set_speed(self, 0);
918         hw_atl_utils_mpi_set_state(self, MPI_POWER);
919 err_exit:
920         return err;
921 }
922
923
924
925 const struct aq_fw_ops aq_fw_1x_ops = {
926         .init = hw_atl_utils_mpi_create,
927         .deinit = hw_atl_fw1x_deinit,
928         .reset = NULL,
929         .get_mac_permanent = hw_atl_utils_get_mac_permanent,
930         .set_link_speed = hw_atl_utils_mpi_set_speed,
931         .set_state = hw_atl_utils_mpi_set_state,
932         .update_link_status = hw_atl_utils_mpi_get_link_status,
933         .update_stats = hw_atl_utils_update_stats,
934         .set_power = aq_fw1x_set_power,
935         .get_temp = NULL,
936         .get_cable_len = NULL,
937         .set_eee_rate = NULL,
938         .get_eee_rate = NULL,
939         .set_flow_control = NULL,
940         .led_control = NULL,
941         .get_eeprom = NULL,
942         .set_eeprom = NULL,
943 };