netfilter: netns: shrink netns_ct struct
[linux-2.6-microblaze.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
53 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
54                                       enum hal_atl_utils_fw_state_e state);
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                 aq_pr_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                 aq_pr_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                 aq_pr_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                 aq_pr_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                 aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
213                 return -ENOTSUPP;
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                 aq_pr_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 k;
236         u32 boot_exit_code = 0;
237
238         for (k = 0; k < 1000; ++k) {
239                 u32 flb_status = aq_hw_read_reg(self,
240                                                 HW_ATL_MPI_DAISY_CHAIN_STATUS);
241                 boot_exit_code = aq_hw_read_reg(self,
242                                                 HW_ATL_MPI_BOOT_EXIT_CODE);
243                 if (flb_status != 0x06000000 || boot_exit_code != 0)
244                         break;
245         }
246
247         if (k == 1000) {
248                 aq_pr_err("Neither RBL nor FLB firmware started\n");
249                 return -EOPNOTSUPP;
250         }
251
252         self->rbl_enabled = (boot_exit_code != 0);
253
254         /* FW 1.x may bootup in an invalid POWER state (WOL feature).
255          * We should work around this by forcing its state back to DEINIT
256          */
257         if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
258                                     aq_hw_read_reg(self,
259                                                    HW_ATL_MPI_FW_VERSION))) {
260                 int err = 0;
261
262                 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
263                 AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
264                                 HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
265                                10, 1000U);
266         }
267
268         if (self->rbl_enabled)
269                 return hw_atl_utils_soft_reset_rbl(self);
270         else
271                 return hw_atl_utils_soft_reset_flb(self);
272 }
273
274 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
275                                   u32 *p, u32 cnt)
276 {
277         int err = 0;
278
279         AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
280                                                   HW_ATL_FW_SM_RAM) == 1U,
281                        1U, 10000U);
282
283         if (err < 0) {
284                 bool is_locked;
285
286                 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
287                 is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
288                 if (!is_locked) {
289                         err = -ETIME;
290                         goto err_exit;
291                 }
292         }
293
294         aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
295
296         for (++cnt; --cnt && !err;) {
297                 aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
298
299                 if (IS_CHIP_FEATURE(REVISION_B1))
300                         AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
301                                                            HW_ATL_MIF_ADDR),
302                                        1, 1000U);
303                 else
304                         AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
305                                                            HW_ATL_MIF_CMD)),
306                                        1, 1000U);
307
308                 *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
309                 a += 4;
310         }
311
312         hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
313
314 err_exit:
315         return err;
316 }
317
318 static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
319                                          u32 cnt)
320 {
321         int err = 0;
322         bool is_locked;
323
324         is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
325         if (!is_locked) {
326                 err = -ETIME;
327                 goto err_exit;
328         }
329         if (IS_CHIP_FEATURE(REVISION_B1)) {
330                 u32 offset = 0;
331
332                 for (; offset < cnt; ++offset) {
333                         aq_hw_write_reg(self, 0x328, p[offset]);
334                         aq_hw_write_reg(self, 0x32C,
335                                         (0x80000000 | (0xFFFF & (offset * 4))));
336                         hw_atl_mcp_up_force_intr_set(self, 1);
337                         /* 1000 times by 10us = 10ms */
338                         AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
339                                                        0x32C) & 0xF0000000) !=
340                                        0x80000000,
341                                        10, 1000);
342                 }
343         } else {
344                 u32 offset = 0;
345
346                 aq_hw_write_reg(self, 0x208, a);
347
348                 for (; offset < cnt; ++offset) {
349                         aq_hw_write_reg(self, 0x20C, p[offset]);
350                         aq_hw_write_reg(self, 0x200, 0xC000);
351
352                         AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) &
353                                         0x100) == 0, 10, 1000);
354                 }
355         }
356
357         hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
358
359 err_exit:
360         return err;
361 }
362
363 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
364 {
365         int err = 0;
366         const u32 dw_major_mask = 0xff000000U;
367         const u32 dw_minor_mask = 0x00ffffffU;
368
369         err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
370         if (err < 0)
371                 goto err_exit;
372         err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
373                 -EOPNOTSUPP : 0;
374 err_exit:
375         return err;
376 }
377
378 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
379                                  const struct aq_hw_caps_s *aq_hw_caps)
380 {
381         int err = 0;
382
383         if (!aq_hw_read_reg(self, 0x370U)) {
384                 unsigned int rnd = 0U;
385                 unsigned int ucp_0x370 = 0U;
386
387                 get_random_bytes(&rnd, sizeof(unsigned int));
388
389                 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
390                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
391         }
392
393         hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
394
395         /* check 10 times by 1ms */
396         AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
397                               aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
398
399         return err;
400 }
401
402 #define HW_ATL_RPC_CONTROL_ADR 0x0338U
403 #define HW_ATL_RPC_STATE_ADR   0x033CU
404
405 struct aq_hw_atl_utils_fw_rpc_tid_s {
406         union {
407                 u32 val;
408                 struct {
409                         u16 tid;
410                         u16 len;
411                 };
412         };
413 };
414
415 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
416
417 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
418 {
419         int err = 0;
420         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
421
422         if (!IS_CHIP_FEATURE(MIPS)) {
423                 err = -1;
424                 goto err_exit;
425         }
426         err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
427                                             (u32 *)(void *)&self->rpc,
428                                             (rpc_size + sizeof(u32) -
429                                              sizeof(u8)) / sizeof(u32));
430         if (err < 0)
431                 goto err_exit;
432
433         sw.tid = 0xFFFFU & (++self->rpc_tid);
434         sw.len = (u16)rpc_size;
435         aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
436
437 err_exit:
438         return err;
439 }
440
441 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
442                              struct hw_atl_utils_fw_rpc **rpc)
443 {
444         int err = 0;
445         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
446         struct aq_hw_atl_utils_fw_rpc_tid_s fw;
447
448         do {
449                 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
450
451                 self->rpc_tid = sw.tid;
452
453                 AQ_HW_WAIT_FOR(sw.tid ==
454                                (fw.val =
455                                 aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
456                                 fw.tid), 1000U, 100U);
457                 if (err < 0)
458                         goto err_exit;
459
460                 if (fw.len == 0xFFFFU) {
461                         err = hw_atl_utils_fw_rpc_call(self, sw.len);
462                         if (err < 0)
463                                 goto err_exit;
464                 }
465         } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
466         if (err < 0)
467                 goto err_exit;
468
469         if (rpc) {
470                 if (fw.len) {
471                         err =
472                         hw_atl_utils_fw_downld_dwords(self,
473                                                       self->rpc_addr,
474                                                       (u32 *)(void *)
475                                                       &self->rpc,
476                                                       (fw.len + sizeof(u32) -
477                                                        sizeof(u8)) /
478                                                       sizeof(u32));
479                         if (err < 0)
480                                 goto err_exit;
481                 }
482
483                 *rpc = &self->rpc;
484         }
485
486 err_exit:
487         return err;
488 }
489
490 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
491 {
492         int err = 0;
493
494         err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps);
495         if (err < 0)
496                 goto err_exit;
497
498         err = hw_atl_utils_fw_rpc_init(self);
499         if (err < 0)
500                 goto err_exit;
501
502 err_exit:
503         return err;
504 }
505
506 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
507                                struct hw_atl_utils_mbox_header *pmbox)
508 {
509         return hw_atl_utils_fw_downld_dwords(self,
510                                              self->mbox_addr,
511                                              (u32 *)(void *)pmbox,
512                                              sizeof(*pmbox) / sizeof(u32));
513 }
514
515 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
516                                  struct hw_atl_utils_mbox *pmbox)
517 {
518         int err = 0;
519
520         err = hw_atl_utils_fw_downld_dwords(self,
521                                             self->mbox_addr,
522                                             (u32 *)(void *)pmbox,
523                                             sizeof(*pmbox) / sizeof(u32));
524         if (err < 0)
525                 goto err_exit;
526
527         if (IS_CHIP_FEATURE(REVISION_A0)) {
528                 unsigned int mtu = self->aq_nic_cfg ?
529                                         self->aq_nic_cfg->mtu : 1514U;
530                 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
531                 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
532                 pmbox->stats.dpc = atomic_read(&self->dpc);
533         } else {
534                 pmbox->stats.dpc = hw_atl_reg_rx_dma_stat_counter7get(self);
535         }
536
537 err_exit:;
538 }
539
540 static 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 static 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_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 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 = 0;
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] = __swab32(mac_addr[0]);
656                 mac_addr[1] = __swab32(mac_addr[1]);
657         }
658
659         ether_addr_copy(mac, (u8 *)mac_addr);
660
661         if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
662                 /* chip revision */
663                 l = 0xE3000000U |
664                     (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
665                     (0x00 << 16);
666                 h = 0x8001300EU;
667
668                 mac[5] = (u8)(0xFFU & l);
669                 l >>= 8;
670                 mac[4] = (u8)(0xFFU & l);
671                 l >>= 8;
672                 mac[3] = (u8)(0xFFU & l);
673                 l >>= 8;
674                 mac[2] = (u8)(0xFFU & l);
675                 mac[1] = (u8)(0xFFU & h);
676                 h >>= 8;
677                 mac[0] = (u8)(0xFFU & h);
678         }
679
680         return err;
681 }
682
683 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
684 {
685         unsigned int ret = 0U;
686
687         switch (mbps) {
688         case 100U:
689                 ret = 5U;
690                 break;
691
692         case 1000U:
693                 ret = 4U;
694                 break;
695
696         case 2500U:
697                 ret = 3U;
698                 break;
699
700         case 5000U:
701                 ret = 1U;
702                 break;
703
704         case 10000U:
705                 ret = 0U;
706                 break;
707
708         default:
709                 break;
710         }
711         return ret;
712 }
713
714 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
715 {
716         u32 chip_features = 0U;
717         u32 val = hw_atl_reg_glb_mif_id_get(self);
718         u32 mif_rev = val & 0xFFU;
719
720         if ((0xFU & mif_rev) == 1U) {
721                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
722                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
723                         HAL_ATLANTIC_UTILS_CHIP_MIPS;
724         } else if ((0xFU & mif_rev) == 2U) {
725                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
726                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
727                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
728                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
729                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
730         } else if ((0xFU & mif_rev) == 0xAU) {
731                 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
732                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
733                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
734                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
735                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
736         }
737
738         *p = chip_features;
739 }
740
741 static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
742 {
743         hw_atl_utils_mpi_set_speed(self, 0);
744         hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
745         return 0;
746 }
747
748 int hw_atl_utils_update_stats(struct aq_hw_s *self)
749 {
750         struct hw_atl_utils_mbox mbox;
751
752         hw_atl_utils_mpi_read_stats(self, &mbox);
753
754 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
755                         mbox.stats._N_ - self->last_stats._N_)
756
757         if (self->aq_link_status.mbps) {
758                 AQ_SDELTA(uprc);
759                 AQ_SDELTA(mprc);
760                 AQ_SDELTA(bprc);
761                 AQ_SDELTA(erpt);
762
763                 AQ_SDELTA(uptc);
764                 AQ_SDELTA(mptc);
765                 AQ_SDELTA(bptc);
766                 AQ_SDELTA(erpr);
767
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 = hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self);
778         self->curr_stats.dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self);
779         self->curr_stats.dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counterlsw_get(self);
780         self->curr_stats.dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counterlsw_get(self);
781
782         memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
783
784         return 0;
785 }
786
787 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
788 {
789         return &self->curr_stats;
790 }
791
792 static const u32 hw_atl_utils_hw_mac_regs[] = {
793         0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
794         0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
795         0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
796         0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
797         0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
798         0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
799         0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
800         0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
801         0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
802         0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
803         0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
804         0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
805         0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
806         0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
807         0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
808         0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
809         0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
810         0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
811         0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
812         0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
813         0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
814         0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
815 };
816
817 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
818                              const struct aq_hw_caps_s *aq_hw_caps,
819                              u32 *regs_buff)
820 {
821         unsigned int i = 0U;
822
823         for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
824                 regs_buff[i] = aq_hw_read_reg(self,
825                                               hw_atl_utils_hw_mac_regs[i]);
826         return 0;
827 }
828
829 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
830 {
831         *fw_version = aq_hw_read_reg(self, 0x18U);
832         return 0;
833 }
834
835 static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)
836 {
837         struct hw_atl_utils_fw_rpc *prpc = NULL;
838         unsigned int rpc_size = 0U;
839         int err = 0;
840
841         err = hw_atl_utils_fw_rpc_wait(self, &prpc);
842         if (err < 0)
843                 goto err_exit;
844
845         memset(prpc, 0, sizeof(*prpc));
846
847         if (wol_enabled) {
848                 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
849
850                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
851                 prpc->msg_wol.priority =
852                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
853                 prpc->msg_wol.pattern_id =
854                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
855                 prpc->msg_wol.wol_packet_type =
856                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
857
858                 ether_addr_copy((u8 *)&prpc->msg_wol.wol_pattern, mac);
859         } else {
860                 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
861
862                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
863                 prpc->msg_wol.pattern_id =
864                                 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
865         }
866
867         err = hw_atl_utils_fw_rpc_call(self, rpc_size);
868
869 err_exit:
870         return err;
871 }
872
873 static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
874                              u8 *mac)
875 {
876         struct hw_atl_utils_fw_rpc *prpc = NULL;
877         unsigned int rpc_size = 0U;
878         int err = 0;
879
880         if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
881                 err = aq_fw1x_set_wol(self, 1, mac);
882
883                 if (err < 0)
884                         goto err_exit;
885
886                 rpc_size = sizeof(prpc->msg_id) +
887                            sizeof(prpc->msg_enable_wakeup);
888
889                 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
890
891                 if (err < 0)
892                         goto err_exit;
893
894                 memset(prpc, 0, rpc_size);
895
896                 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
897                 prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
898
899                 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
900                 if (err < 0)
901                         goto err_exit;
902         }
903         hw_atl_utils_mpi_set_speed(self, 0);
904         hw_atl_utils_mpi_set_state(self, MPI_POWER);
905
906 err_exit:
907         return err;
908 }
909
910 const struct aq_fw_ops aq_fw_1x_ops = {
911         .init = hw_atl_utils_mpi_create,
912         .deinit = hw_atl_fw1x_deinit,
913         .reset = NULL,
914         .get_mac_permanent = hw_atl_utils_get_mac_permanent,
915         .set_link_speed = hw_atl_utils_mpi_set_speed,
916         .set_state = hw_atl_utils_mpi_set_state,
917         .update_link_status = hw_atl_utils_mpi_get_link_status,
918         .update_stats = hw_atl_utils_update_stats,
919         .set_power = aq_fw1x_set_power,
920         .set_eee_rate = NULL,
921         .get_eee_rate = NULL,
922         .set_flow_control = NULL,
923 };