Merge tag 'pstore-v4.17-rc1-fix' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / drivers / net / ethernet / aquantia / atlantic / hw_atl / hw_atl_utils.c
1 /*
2  * aQuantia Corporation Network Driver
3  * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
4  *
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.
8  */
9
10 /* File hw_atl_utils.c: Definition of common functions for Atlantic hardware
11  * abstraction layer.
12  */
13
14 #include "../aq_nic.h"
15 #include "../aq_hw_utils.h"
16 #include "hw_atl_utils.h"
17 #include "hw_atl_llh.h"
18 #include "hw_atl_llh_internal.h"
19
20 #include <linux/random.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    0xFFFF0000U
36 #define HW_ATL_MPI_SPEED_SHIFT  16U
37
38 #define HW_ATL_MPI_DAISY_CHAIN_STATUS   0x704
39 #define HW_ATL_MPI_BOOT_EXIT_CODE       0x388
40
41 #define HW_ATL_MAC_PHY_CONTROL  0x4000
42 #define HW_ATL_MAC_PHY_MPI_RESET_BIT 0x1D
43
44 #define HW_ATL_FW_VER_1X 0x01050006U
45 #define HW_ATL_FW_VER_2X 0x02000000U
46 #define HW_ATL_FW_VER_3X 0x03000000U
47
48 #define FORCE_FLASHLESS 0
49
50 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
51
52 int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
53 {
54         int err = 0;
55
56         err = hw_atl_utils_soft_reset(self);
57         if (err)
58                 return err;
59
60         hw_atl_utils_hw_chip_features_init(self,
61                                            &self->chip_features);
62
63         hw_atl_utils_get_fw_version(self, &self->fw_ver_actual);
64
65         if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
66                                    self->fw_ver_actual) == 0) {
67                 *fw_ops = &aq_fw_1x_ops;
68         } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
69                                         self->fw_ver_actual) == 0) {
70                 *fw_ops = &aq_fw_2x_ops;
71         } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
72                                         self->fw_ver_actual) == 0) {
73                 *fw_ops = &aq_fw_2x_ops;
74         } else {
75                 aq_pr_err("Bad FW version detected: %x\n",
76                           self->fw_ver_actual);
77                 return -EOPNOTSUPP;
78         }
79         self->aq_fw_ops = *fw_ops;
80         err = self->aq_fw_ops->init(self);
81         return err;
82 }
83
84 static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
85 {
86         u32 gsr, val;
87         int k = 0;
88
89         aq_hw_write_reg(self, 0x404, 0x40e1);
90         AQ_HW_SLEEP(50);
91
92         /* Cleanup SPI */
93         val = aq_hw_read_reg(self, 0x53C);
94         aq_hw_write_reg(self, 0x53C, val | 0x10);
95
96         gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
97         aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
98
99         /* Kickstart MAC */
100         aq_hw_write_reg(self, 0x404, 0x80e0);
101         aq_hw_write_reg(self, 0x32a8, 0x0);
102         aq_hw_write_reg(self, 0x520, 0x1);
103
104         /* Reset SPI again because of possible interrupted SPI burst */
105         val = aq_hw_read_reg(self, 0x53C);
106         aq_hw_write_reg(self, 0x53C, val | 0x10);
107         AQ_HW_SLEEP(10);
108         /* Clear SPI reset state */
109         aq_hw_write_reg(self, 0x53C, val & ~0x10);
110
111         aq_hw_write_reg(self, 0x404, 0x180e0);
112
113         for (k = 0; k < 1000; k++) {
114                 u32 flb_status = aq_hw_read_reg(self,
115                                                 HW_ATL_MPI_DAISY_CHAIN_STATUS);
116
117                 flb_status = flb_status & 0x10;
118                 if (flb_status)
119                         break;
120                 AQ_HW_SLEEP(10);
121         }
122         if (k == 1000) {
123                 aq_pr_err("MAC kickstart failed\n");
124                 return -EIO;
125         }
126
127         /* FW reset */
128         aq_hw_write_reg(self, 0x404, 0x80e0);
129         AQ_HW_SLEEP(50);
130         aq_hw_write_reg(self, 0x3a0, 0x1);
131
132         /* Kickstart PHY - skipped */
133
134         /* Global software reset*/
135         hw_atl_rx_rx_reg_res_dis_set(self, 0U);
136         hw_atl_tx_tx_reg_res_dis_set(self, 0U);
137         aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
138                             BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
139                             HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
140         gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
141         aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
142
143         for (k = 0; k < 1000; k++) {
144                 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
145
146                 if (fw_state)
147                         break;
148                 AQ_HW_SLEEP(10);
149         }
150         if (k == 1000) {
151                 aq_pr_err("FW kickstart failed\n");
152                 return -EIO;
153         }
154         /* Old FW requires fixed delay after init */
155         AQ_HW_SLEEP(15);
156
157         return 0;
158 }
159
160 static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
161 {
162         u32 gsr, val, rbl_status;
163         int k;
164
165         aq_hw_write_reg(self, 0x404, 0x40e1);
166         aq_hw_write_reg(self, 0x3a0, 0x1);
167         aq_hw_write_reg(self, 0x32a8, 0x0);
168
169         /* Alter RBL status */
170         aq_hw_write_reg(self, 0x388, 0xDEAD);
171
172         /* Cleanup SPI */
173         val = aq_hw_read_reg(self, 0x53C);
174         aq_hw_write_reg(self, 0x53C, val | 0x10);
175
176         /* Global software reset*/
177         hw_atl_rx_rx_reg_res_dis_set(self, 0U);
178         hw_atl_tx_tx_reg_res_dis_set(self, 0U);
179         aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
180                             BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
181                             HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
182         gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
183         aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR,
184                         (gsr & 0xFFFFBFFF) | 0x8000);
185
186         if (FORCE_FLASHLESS)
187                 aq_hw_write_reg(self, 0x534, 0x0);
188
189         aq_hw_write_reg(self, 0x404, 0x40e0);
190
191         /* Wait for RBL boot */
192         for (k = 0; k < 1000; k++) {
193                 rbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF;
194                 if (rbl_status && rbl_status != 0xDEAD)
195                         break;
196                 AQ_HW_SLEEP(10);
197         }
198         if (!rbl_status || rbl_status == 0xDEAD) {
199                 aq_pr_err("RBL Restart failed");
200                 return -EIO;
201         }
202
203         /* Restore NVR */
204         if (FORCE_FLASHLESS)
205                 aq_hw_write_reg(self, 0x534, 0xA0);
206
207         if (rbl_status == 0xF1A7) {
208                 aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
209                 return -ENOTSUPP;
210         }
211
212         for (k = 0; k < 1000; k++) {
213                 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
214
215                 if (fw_state)
216                         break;
217                 AQ_HW_SLEEP(10);
218         }
219         if (k == 1000) {
220                 aq_pr_err("FW kickstart failed\n");
221                 return -EIO;
222         }
223         /* Old FW requires fixed delay after init */
224         AQ_HW_SLEEP(15);
225
226         return 0;
227 }
228
229 int hw_atl_utils_soft_reset(struct aq_hw_s *self)
230 {
231         int k;
232         u32 boot_exit_code = 0;
233
234         for (k = 0; k < 1000; ++k) {
235                 u32 flb_status = aq_hw_read_reg(self,
236                                                 HW_ATL_MPI_DAISY_CHAIN_STATUS);
237                 boot_exit_code = aq_hw_read_reg(self,
238                                                 HW_ATL_MPI_BOOT_EXIT_CODE);
239                 if (flb_status != 0x06000000 || boot_exit_code != 0)
240                         break;
241         }
242
243         if (k == 1000) {
244                 aq_pr_err("Neither RBL nor FLB firmware started\n");
245                 return -EOPNOTSUPP;
246         }
247
248         self->rbl_enabled = (boot_exit_code != 0);
249
250         if (self->rbl_enabled)
251                 return hw_atl_utils_soft_reset_rbl(self);
252         else
253                 return hw_atl_utils_soft_reset_flb(self);
254 }
255
256 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
257                                   u32 *p, u32 cnt)
258 {
259         int err = 0;
260
261         AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
262                                                   HW_ATL_FW_SM_RAM) == 1U,
263                                                   1U, 10000U);
264
265         if (err < 0) {
266                 bool is_locked;
267
268                 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
269                 is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
270                 if (!is_locked) {
271                         err = -ETIME;
272                         goto err_exit;
273                 }
274         }
275
276         aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
277
278         for (++cnt; --cnt && !err;) {
279                 aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
280
281                 if (IS_CHIP_FEATURE(REVISION_B1))
282                         AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
283                                                            HW_ATL_MIF_ADDR),
284                                        1, 1000U);
285                 else
286                         AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
287                                                            HW_ATL_MIF_CMD)),
288                                        1, 1000U);
289
290                 *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
291                 a += 4;
292         }
293
294         hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
295
296 err_exit:
297         return err;
298 }
299
300 static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
301                                          u32 cnt)
302 {
303         int err = 0;
304         bool is_locked;
305
306         is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
307         if (!is_locked) {
308                 err = -ETIME;
309                 goto err_exit;
310         }
311
312         aq_hw_write_reg(self, 0x00000208U, a);
313
314         for (++cnt; --cnt;) {
315                 u32 i = 0U;
316
317                 aq_hw_write_reg(self, 0x0000020CU, *(p++));
318                 aq_hw_write_reg(self, 0x00000200U, 0xC000U);
319
320                 for (i = 1024U;
321                         (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
322                 }
323         }
324
325         hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
326
327 err_exit:
328         return err;
329 }
330
331 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
332 {
333         int err = 0;
334         const u32 dw_major_mask = 0xff000000U;
335         const u32 dw_minor_mask = 0x00ffffffU;
336
337         err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
338         if (err < 0)
339                 goto err_exit;
340         err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
341                 -EOPNOTSUPP : 0;
342 err_exit:
343         return err;
344 }
345
346 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
347                                  const struct aq_hw_caps_s *aq_hw_caps)
348 {
349         int err = 0;
350
351         if (!aq_hw_read_reg(self, 0x370U)) {
352                 unsigned int rnd = 0U;
353                 unsigned int ucp_0x370 = 0U;
354
355                 get_random_bytes(&rnd, sizeof(unsigned int));
356
357                 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
358                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
359         }
360
361         hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
362
363         /* check 10 times by 1ms */
364         AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
365                         aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
366
367         return err;
368 }
369
370 #define HW_ATL_RPC_CONTROL_ADR 0x0338U
371 #define HW_ATL_RPC_STATE_ADR   0x033CU
372
373 struct aq_hw_atl_utils_fw_rpc_tid_s {
374         union {
375                 u32 val;
376                 struct {
377                         u16 tid;
378                         u16 len;
379                 };
380         };
381 };
382
383 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
384
385 static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
386 {
387         int err = 0;
388         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
389
390         if (!IS_CHIP_FEATURE(MIPS)) {
391                 err = -1;
392                 goto err_exit;
393         }
394         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
395                                             (u32 *)(void *)&self->rpc,
396                                             (rpc_size + sizeof(u32) -
397                                             sizeof(u8)) / sizeof(u32));
398         if (err < 0)
399                 goto err_exit;
400
401         sw.tid = 0xFFFFU & (++self->rpc_tid);
402         sw.len = (u16)rpc_size;
403         aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
404
405 err_exit:
406         return err;
407 }
408
409 static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
410                                     struct hw_aq_atl_utils_fw_rpc **rpc)
411 {
412         int err = 0;
413         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
414         struct aq_hw_atl_utils_fw_rpc_tid_s fw;
415
416         do {
417                 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
418
419                 self->rpc_tid = sw.tid;
420
421                 AQ_HW_WAIT_FOR(sw.tid ==
422                                 (fw.val =
423                                 aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
424                                 fw.tid), 1000U, 100U);
425                 if (err < 0)
426                         goto err_exit;
427
428                 if (fw.len == 0xFFFFU) {
429                         err = hw_atl_utils_fw_rpc_call(self, sw.len);
430                         if (err < 0)
431                                 goto err_exit;
432                 }
433         } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
434         if (err < 0)
435                 goto err_exit;
436
437         if (rpc) {
438                 if (fw.len) {
439                         err =
440                         hw_atl_utils_fw_downld_dwords(self,
441                                                       self->rpc_addr,
442                                                       (u32 *)(void *)
443                                                       &self->rpc,
444                                                       (fw.len + sizeof(u32) -
445                                                       sizeof(u8)) /
446                                                       sizeof(u32));
447                         if (err < 0)
448                                 goto err_exit;
449                 }
450
451                 *rpc = &self->rpc;
452         }
453
454 err_exit:
455         return err;
456 }
457
458 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
459 {
460         int err = 0;
461
462         err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps);
463         if (err < 0)
464                 goto err_exit;
465
466         err = hw_atl_utils_fw_rpc_init(self);
467         if (err < 0)
468                 goto err_exit;
469
470 err_exit:
471         return err;
472 }
473
474 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
475                                struct hw_aq_atl_utils_mbox_header *pmbox)
476 {
477         return hw_atl_utils_fw_downld_dwords(self,
478                                       self->mbox_addr,
479                                       (u32 *)(void *)pmbox,
480                                       sizeof(*pmbox) / sizeof(u32));
481 }
482
483 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
484                                  struct hw_aq_atl_utils_mbox *pmbox)
485 {
486         int err = 0;
487
488         err = hw_atl_utils_fw_downld_dwords(self,
489                                             self->mbox_addr,
490                                             (u32 *)(void *)pmbox,
491                                             sizeof(*pmbox) / sizeof(u32));
492         if (err < 0)
493                 goto err_exit;
494
495         if (IS_CHIP_FEATURE(REVISION_A0)) {
496                 unsigned int mtu = self->aq_nic_cfg ?
497                                         self->aq_nic_cfg->mtu : 1514U;
498                 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
499                 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
500                 pmbox->stats.dpc = atomic_read(&self->dpc);
501         } else {
502                 pmbox->stats.dpc = hw_atl_reg_rx_dma_stat_counter7get(self);
503         }
504
505 err_exit:;
506 }
507
508 static int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
509 {
510         u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
511
512         val = (val & HW_ATL_MPI_STATE_MSK) | (speed << HW_ATL_MPI_SPEED_SHIFT);
513         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
514
515         return 0;
516 }
517
518 void hw_atl_utils_mpi_set(struct aq_hw_s *self,
519                           enum hal_atl_utils_fw_state_e state,
520                           u32 speed)
521 {
522         int err = 0;
523         u32 transaction_id = 0;
524         struct hw_aq_atl_utils_mbox_header mbox;
525
526         if (state == MPI_RESET) {
527                 hw_atl_utils_mpi_read_mbox(self, &mbox);
528
529                 transaction_id = mbox.transaction_id;
530
531                 AQ_HW_WAIT_FOR(transaction_id !=
532                                 (hw_atl_utils_mpi_read_mbox(self, &mbox),
533                                  mbox.transaction_id),
534                                1000U, 100U);
535                 if (err < 0)
536                         goto err_exit;
537         }
538
539         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR,
540                         (speed << HW_ATL_MPI_SPEED_SHIFT) | state);
541
542 err_exit:;
543 }
544
545 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
546                                       enum hal_atl_utils_fw_state_e state)
547 {
548         u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
549
550         val = state | (val & HW_ATL_MPI_SPEED_MSK);
551         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
552         return 0;
553 }
554
555 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
556 {
557         u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
558         u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
559         struct aq_hw_link_status_s *link_status = &self->aq_link_status;
560
561         if (!link_speed_mask) {
562                 link_status->mbps = 0U;
563         } else {
564                 switch (link_speed_mask) {
565                 case HAL_ATLANTIC_RATE_10G:
566                         link_status->mbps = 10000U;
567                         break;
568
569                 case HAL_ATLANTIC_RATE_5G:
570                 case HAL_ATLANTIC_RATE_5GSR:
571                         link_status->mbps = 5000U;
572                         break;
573
574                 case HAL_ATLANTIC_RATE_2GS:
575                         link_status->mbps = 2500U;
576                         break;
577
578                 case HAL_ATLANTIC_RATE_1G:
579                         link_status->mbps = 1000U;
580                         break;
581
582                 case HAL_ATLANTIC_RATE_100M:
583                         link_status->mbps = 100U;
584                         break;
585
586                 default:
587                         return -EBUSY;
588                 }
589         }
590
591         return 0;
592 }
593
594 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
595                                    u8 *mac)
596 {
597         int err = 0;
598         u32 h = 0U;
599         u32 l = 0U;
600         u32 mac_addr[2];
601
602         if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
603                 unsigned int rnd = 0;
604                 unsigned int ucp_0x370 = 0;
605
606                 get_random_bytes(&rnd, sizeof(unsigned int));
607
608                 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
609                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
610         }
611
612         err = hw_atl_utils_fw_downld_dwords(self,
613                                             aq_hw_read_reg(self, 0x00000374U) +
614                                             (40U * 4U),
615                                             mac_addr,
616                                             ARRAY_SIZE(mac_addr));
617         if (err < 0) {
618                 mac_addr[0] = 0U;
619                 mac_addr[1] = 0U;
620                 err = 0;
621         } else {
622                 mac_addr[0] = __swab32(mac_addr[0]);
623                 mac_addr[1] = __swab32(mac_addr[1]);
624         }
625
626         ether_addr_copy(mac, (u8 *)mac_addr);
627
628         if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
629                 /* chip revision */
630                 l = 0xE3000000U
631                         | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
632                         | (0x00 << 16);
633                 h = 0x8001300EU;
634
635                 mac[5] = (u8)(0xFFU & l);
636                 l >>= 8;
637                 mac[4] = (u8)(0xFFU & l);
638                 l >>= 8;
639                 mac[3] = (u8)(0xFFU & l);
640                 l >>= 8;
641                 mac[2] = (u8)(0xFFU & l);
642                 mac[1] = (u8)(0xFFU & h);
643                 h >>= 8;
644                 mac[0] = (u8)(0xFFU & h);
645         }
646
647         return err;
648 }
649
650 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
651 {
652         unsigned int ret = 0U;
653
654         switch (mbps) {
655         case 100U:
656                 ret = 5U;
657                 break;
658
659         case 1000U:
660                 ret = 4U;
661                 break;
662
663         case 2500U:
664                 ret = 3U;
665                 break;
666
667         case 5000U:
668                 ret = 1U;
669                 break;
670
671         case 10000U:
672                 ret = 0U;
673                 break;
674
675         default:
676                 break;
677         }
678         return ret;
679 }
680
681 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
682 {
683         u32 chip_features = 0U;
684         u32 val = hw_atl_reg_glb_mif_id_get(self);
685         u32 mif_rev = val & 0xFFU;
686
687         if ((0xFU & mif_rev) == 1U) {
688                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
689                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
690                         HAL_ATLANTIC_UTILS_CHIP_MIPS;
691         } else if ((0xFU & mif_rev) == 2U) {
692                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
693                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
694                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
695                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
696                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
697         } else if ((0xFU & mif_rev) == 0xAU) {
698                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
699                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
700                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
701                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
702                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
703         }
704
705         *p = chip_features;
706 }
707
708 int hw_atl_utils_hw_deinit(struct aq_hw_s *self)
709 {
710         hw_atl_utils_mpi_set(self, MPI_DEINIT, 0x0U);
711         return 0;
712 }
713
714 int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
715                               unsigned int power_state)
716 {
717         hw_atl_utils_mpi_set(self, MPI_POWER, 0x0U);
718         return 0;
719 }
720
721 int hw_atl_utils_update_stats(struct aq_hw_s *self)
722 {
723         struct hw_aq_atl_utils_mbox mbox;
724
725         hw_atl_utils_mpi_read_stats(self, &mbox);
726
727 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
728                         mbox.stats._N_ - self->last_stats._N_)
729
730         if (self->aq_link_status.mbps) {
731                 AQ_SDELTA(uprc);
732                 AQ_SDELTA(mprc);
733                 AQ_SDELTA(bprc);
734                 AQ_SDELTA(erpt);
735
736                 AQ_SDELTA(uptc);
737                 AQ_SDELTA(mptc);
738                 AQ_SDELTA(bptc);
739                 AQ_SDELTA(erpr);
740
741                 AQ_SDELTA(ubrc);
742                 AQ_SDELTA(ubtc);
743                 AQ_SDELTA(mbrc);
744                 AQ_SDELTA(mbtc);
745                 AQ_SDELTA(bbrc);
746                 AQ_SDELTA(bbtc);
747                 AQ_SDELTA(dpc);
748         }
749 #undef AQ_SDELTA
750         self->curr_stats.dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self);
751         self->curr_stats.dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self);
752         self->curr_stats.dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counterlsw_get(self);
753         self->curr_stats.dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counterlsw_get(self);
754
755         memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
756
757         return 0;
758 }
759
760 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
761 {
762         return &self->curr_stats;
763 }
764
765 static const u32 hw_atl_utils_hw_mac_regs[] = {
766         0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
767         0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
768         0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
769         0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
770         0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
771         0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
772         0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
773         0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
774         0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
775         0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
776         0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
777         0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
778         0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
779         0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
780         0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
781         0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
782         0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
783         0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
784         0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
785         0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
786         0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
787         0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
788 };
789
790 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
791                              const struct aq_hw_caps_s *aq_hw_caps,
792                              u32 *regs_buff)
793 {
794         unsigned int i = 0U;
795
796         for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
797                 regs_buff[i] = aq_hw_read_reg(self,
798                                               hw_atl_utils_hw_mac_regs[i]);
799         return 0;
800 }
801
802 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
803 {
804         *fw_version = aq_hw_read_reg(self, 0x18U);
805         return 0;
806 }
807
808 const struct aq_fw_ops aq_fw_1x_ops = {
809         .init = hw_atl_utils_mpi_create,
810         .reset = NULL,
811         .get_mac_permanent = hw_atl_utils_get_mac_permanent,
812         .set_link_speed = hw_atl_utils_mpi_set_speed,
813         .set_state = hw_atl_utils_mpi_set_state,
814         .update_link_status = hw_atl_utils_mpi_get_link_status,
815         .update_stats = hw_atl_utils_update_stats,
816 };