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