GNU Linux-libre 4.14.266-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_hw.h"
15 #include "../aq_hw_utils.h"
16 #include "../aq_pci_func.h"
17 #include "../aq_ring.h"
18 #include "../aq_vec.h"
19 #include "hw_atl_utils.h"
20 #include "hw_atl_llh.h"
21
22 #include <linux/random.h>
23
24 #define HW_ATL_UCP_0X370_REG    0x0370U
25
26 #define HW_ATL_FW_SM_RAM        0x2U
27 #define HW_ATL_MPI_CONTROL_ADR  0x0368U
28 #define HW_ATL_MPI_STATE_ADR    0x036CU
29
30 #define HW_ATL_MPI_STATE_MSK    0x00FFU
31 #define HW_ATL_MPI_STATE_SHIFT  0U
32 #define HW_ATL_MPI_SPEED_MSK    0xFFFFU
33 #define HW_ATL_MPI_SPEED_SHIFT  16U
34
35 static int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
36                                          u32 *p, u32 cnt)
37 {
38         int err = 0;
39
40         AQ_HW_WAIT_FOR(reg_glb_cpu_sem_get(self,
41                                            HW_ATL_FW_SM_RAM) == 1U,
42                                            1U, 10000U);
43
44         if (err < 0) {
45                 bool is_locked;
46
47                 reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
48                 is_locked = reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
49                 if (!is_locked) {
50                         err = -ETIME;
51                         goto err_exit;
52                 }
53         }
54
55         aq_hw_write_reg(self, 0x00000208U, a);
56
57         for (++cnt; --cnt;) {
58                 u32 i = 0U;
59
60                 aq_hw_write_reg(self, 0x00000200U, 0x00008000U);
61
62                 for (i = 1024U;
63                         (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
64                 }
65
66                 *(p++) = aq_hw_read_reg(self, 0x0000020CU);
67         }
68
69         reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
70
71 err_exit:
72         return err;
73 }
74
75 static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
76                                          u32 cnt)
77 {
78         int err = 0;
79         bool is_locked;
80
81         is_locked = reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
82         if (!is_locked) {
83                 err = -ETIME;
84                 goto err_exit;
85         }
86
87         aq_hw_write_reg(self, 0x00000208U, a);
88
89         for (++cnt; --cnt;) {
90                 u32 i = 0U;
91
92                 aq_hw_write_reg(self, 0x0000020CU, *(p++));
93                 aq_hw_write_reg(self, 0x00000200U, 0xC000U);
94
95                 for (i = 1024U;
96                         (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
97                 }
98         }
99
100         reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
101
102 err_exit:
103         return err;
104 }
105
106 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
107 {
108         int err = 0;
109         const u32 dw_major_mask = 0xff000000U;
110         const u32 dw_minor_mask = 0x00ffffffU;
111
112         err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
113         if (err < 0)
114                 goto err_exit;
115         err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
116                 -EOPNOTSUPP : 0;
117 err_exit:
118         return err;
119 }
120
121 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
122                                  struct aq_hw_caps_s *aq_hw_caps)
123 {
124         int err = 0;
125
126         if (!aq_hw_read_reg(self, 0x370U)) {
127                 unsigned int rnd = 0U;
128                 unsigned int ucp_0x370 = 0U;
129
130                 get_random_bytes(&rnd, sizeof(unsigned int));
131
132                 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
133                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
134         }
135
136         reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
137
138         /* check 10 times by 1ms */
139         AQ_HW_WAIT_FOR(0U != (PHAL_ATLANTIC_A0->mbox_addr =
140                         aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
141
142         err = hw_atl_utils_ver_match(aq_hw_caps->fw_ver_expected,
143                                      aq_hw_read_reg(self, 0x18U));
144
145         if (err < 0)
146                 pr_err("%s: Bad FW version detected: expected=%x, actual=%x\n",
147                        AQ_CFG_DRV_NAME,
148                        aq_hw_caps->fw_ver_expected,
149                        aq_hw_read_reg(self, 0x18U));
150         return err;
151 }
152
153 #define HW_ATL_RPC_CONTROL_ADR 0x0338U
154 #define HW_ATL_RPC_STATE_ADR   0x033CU
155
156 struct aq_hw_atl_utils_fw_rpc_tid_s {
157         union {
158                 u32 val;
159                 struct {
160                         u16 tid;
161                         u16 len;
162                 };
163         };
164 };
165
166 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
167
168 static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
169 {
170         int err = 0;
171         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
172
173         if (!IS_CHIP_FEATURE(MIPS)) {
174                 err = -1;
175                 goto err_exit;
176         }
177         err = hw_atl_utils_fw_upload_dwords(self, PHAL_ATLANTIC->rpc_addr,
178                                             (u32 *)(void *)&PHAL_ATLANTIC->rpc,
179                                             (rpc_size + sizeof(u32) -
180                                             sizeof(u8)) / sizeof(u32));
181         if (err < 0)
182                 goto err_exit;
183
184         sw.tid = 0xFFFFU & (++PHAL_ATLANTIC->rpc_tid);
185         sw.len = (u16)rpc_size;
186         aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
187
188 err_exit:
189         return err;
190 }
191
192 static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
193                                     struct hw_aq_atl_utils_fw_rpc **rpc)
194 {
195         int err = 0;
196         struct aq_hw_atl_utils_fw_rpc_tid_s sw;
197         struct aq_hw_atl_utils_fw_rpc_tid_s fw;
198
199         do {
200                 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
201
202                 PHAL_ATLANTIC->rpc_tid = sw.tid;
203
204                 AQ_HW_WAIT_FOR(sw.tid ==
205                                 (fw.val =
206                                 aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
207                                 fw.tid), 1000U, 100U);
208                 if (err < 0)
209                         goto err_exit;
210
211                 if (fw.len == 0xFFFFU) {
212                         err = hw_atl_utils_fw_rpc_call(self, sw.len);
213                         if (err < 0)
214                                 goto err_exit;
215                 }
216         } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
217         if (err < 0)
218                 goto err_exit;
219
220         if (rpc) {
221                 if (fw.len) {
222                         err =
223                         hw_atl_utils_fw_downld_dwords(self,
224                                                       PHAL_ATLANTIC->rpc_addr,
225                                                       (u32 *)(void *)
226                                                       &PHAL_ATLANTIC->rpc,
227                                                       (fw.len + sizeof(u32) -
228                                                       sizeof(u8)) /
229                                                       sizeof(u32));
230                         if (err < 0)
231                                 goto err_exit;
232                 }
233
234                 *rpc = &PHAL_ATLANTIC->rpc;
235         }
236
237 err_exit:
238         return err;
239 }
240
241 static int hw_atl_utils_mpi_create(struct aq_hw_s *self,
242                                    struct aq_hw_caps_s *aq_hw_caps)
243 {
244         int err = 0;
245
246         err = hw_atl_utils_init_ucp(self, aq_hw_caps);
247         if (err < 0)
248                 goto err_exit;
249
250         err = hw_atl_utils_fw_rpc_init(self);
251         if (err < 0)
252                 goto err_exit;
253
254 err_exit:
255         return err;
256 }
257
258 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
259                                struct hw_aq_atl_utils_mbox_header *pmbox)
260 {
261         return hw_atl_utils_fw_downld_dwords(self,
262                                       PHAL_ATLANTIC->mbox_addr,
263                                       (u32 *)(void *)pmbox,
264                                       sizeof(*pmbox) / sizeof(u32));
265 }
266
267 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
268                                  struct hw_aq_atl_utils_mbox *pmbox)
269 {
270         int err = 0;
271
272         err = hw_atl_utils_fw_downld_dwords(self,
273                                             PHAL_ATLANTIC->mbox_addr,
274                                             (u32 *)(void *)pmbox,
275                                             sizeof(*pmbox) / sizeof(u32));
276         if (err < 0)
277                 goto err_exit;
278
279         if (IS_CHIP_FEATURE(REVISION_A0)) {
280                 unsigned int mtu = self->aq_nic_cfg ?
281                                         self->aq_nic_cfg->mtu : 1514U;
282                 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
283                 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
284                 pmbox->stats.dpc = atomic_read(&PHAL_ATLANTIC_A0->dpc);
285         } else {
286                 pmbox->stats.dpc = reg_rx_dma_stat_counter7get(self);
287         }
288
289 err_exit:;
290 }
291
292 int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
293                                enum hal_atl_utils_fw_state_e state)
294 {
295         u32 ucp_0x368 = 0;
296
297         ucp_0x368 = (speed << HW_ATL_MPI_SPEED_SHIFT) | state;
298         aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368);
299
300         return 0;
301 }
302
303 void hw_atl_utils_mpi_set(struct aq_hw_s *self,
304                           enum hal_atl_utils_fw_state_e state, u32 speed)
305 {
306         int err = 0;
307         u32 transaction_id = 0;
308         struct hw_aq_atl_utils_mbox_header mbox;
309
310         if (state == MPI_RESET) {
311                 hw_atl_utils_mpi_read_mbox(self, &mbox);
312
313                 transaction_id = mbox.transaction_id;
314
315                 AQ_HW_WAIT_FOR(transaction_id !=
316                                 (hw_atl_utils_mpi_read_mbox(self, &mbox),
317                                  mbox.transaction_id),
318                                1000U, 100U);
319                 if (err < 0)
320                         goto err_exit;
321         }
322
323         err = hw_atl_utils_mpi_set_speed(self, speed, state);
324
325 err_exit:;
326 }
327
328 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
329 {
330         u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
331         u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
332         struct aq_hw_link_status_s *link_status = &self->aq_link_status;
333
334         if (!link_speed_mask) {
335                 link_status->mbps = 0U;
336         } else {
337                 switch (link_speed_mask) {
338                 case HAL_ATLANTIC_RATE_10G:
339                         link_status->mbps = 10000U;
340                         break;
341
342                 case HAL_ATLANTIC_RATE_5G:
343                 case HAL_ATLANTIC_RATE_5GSR:
344                         link_status->mbps = 5000U;
345                         break;
346
347                 case HAL_ATLANTIC_RATE_2GS:
348                         link_status->mbps = 2500U;
349                         break;
350
351                 case HAL_ATLANTIC_RATE_1G:
352                         link_status->mbps = 1000U;
353                         break;
354
355                 case HAL_ATLANTIC_RATE_100M:
356                         link_status->mbps = 100U;
357                         break;
358
359                 default:
360                         return -EBUSY;
361                 }
362         }
363
364         return 0;
365 }
366
367 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
368                                    struct aq_hw_caps_s *aq_hw_caps,
369                                    u8 *mac)
370 {
371         int err = 0;
372         u32 h = 0U;
373         u32 l = 0U;
374         u32 mac_addr[2];
375
376         self->mmio = aq_pci_func_get_mmio(self->aq_pci_func);
377
378         hw_atl_utils_hw_chip_features_init(self,
379                                            &PHAL_ATLANTIC_A0->chip_features);
380
381         err = hw_atl_utils_mpi_create(self, aq_hw_caps);
382         if (err < 0)
383                 goto err_exit;
384
385         if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
386                 unsigned int rnd = 0;
387                 unsigned int ucp_0x370 = 0;
388
389                 get_random_bytes(&rnd, sizeof(unsigned int));
390
391                 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
392                 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
393         }
394
395         err = hw_atl_utils_fw_downld_dwords(self,
396                                             aq_hw_read_reg(self, 0x00000374U) +
397                                             (40U * 4U),
398                                             mac_addr,
399                                             AQ_DIMOF(mac_addr));
400         if (err < 0) {
401                 mac_addr[0] = 0U;
402                 mac_addr[1] = 0U;
403                 err = 0;
404         } else {
405                 mac_addr[0] = __swab32(mac_addr[0]);
406                 mac_addr[1] = __swab32(mac_addr[1]);
407         }
408
409         ether_addr_copy(mac, (u8 *)mac_addr);
410
411         if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
412                 /* chip revision */
413                 l = 0xE3000000U
414                         | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
415                         | (0x00 << 16);
416                 h = 0x8001300EU;
417
418                 mac[5] = (u8)(0xFFU & l);
419                 l >>= 8;
420                 mac[4] = (u8)(0xFFU & l);
421                 l >>= 8;
422                 mac[3] = (u8)(0xFFU & l);
423                 l >>= 8;
424                 mac[2] = (u8)(0xFFU & l);
425                 mac[1] = (u8)(0xFFU & h);
426                 h >>= 8;
427                 mac[0] = (u8)(0xFFU & h);
428         }
429
430 err_exit:
431         return err;
432 }
433
434 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
435 {
436         unsigned int ret = 0U;
437
438         switch (mbps) {
439         case 100U:
440                 ret = 5U;
441                 break;
442
443         case 1000U:
444                 ret = 4U;
445                 break;
446
447         case 2500U:
448                 ret = 3U;
449                 break;
450
451         case 5000U:
452                 ret = 1U;
453                 break;
454
455         case 10000U:
456                 ret = 0U;
457                 break;
458
459         default:
460                 break;
461         }
462         return ret;
463 }
464
465 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
466 {
467         u32 chip_features = 0U;
468         u32 val = reg_glb_mif_id_get(self);
469         u32 mif_rev = val & 0xFFU;
470
471         if ((3U & mif_rev) == 1U) {
472                 chip_features |=
473                         HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
474                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
475                         HAL_ATLANTIC_UTILS_CHIP_MIPS;
476         } else if ((3U & mif_rev) == 2U) {
477                 chip_features |=
478                         HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
479                         HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
480                         HAL_ATLANTIC_UTILS_CHIP_MIPS |
481                         HAL_ATLANTIC_UTILS_CHIP_TPO2 |
482                         HAL_ATLANTIC_UTILS_CHIP_RPF2;
483         }
484
485         *p = chip_features;
486 }
487
488 int hw_atl_utils_hw_deinit(struct aq_hw_s *self)
489 {
490         hw_atl_utils_mpi_set(self, MPI_DEINIT, 0x0U);
491         return 0;
492 }
493
494 int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
495                               unsigned int power_state)
496 {
497         hw_atl_utils_mpi_set(self, MPI_POWER, 0x0U);
498         return 0;
499 }
500
501 int hw_atl_utils_update_stats(struct aq_hw_s *self)
502 {
503         struct hw_atl_s *hw_self = PHAL_ATLANTIC;
504         struct hw_aq_atl_utils_mbox mbox;
505
506         if (!self->aq_link_status.mbps)
507                 return 0;
508
509         hw_atl_utils_mpi_read_stats(self, &mbox);
510
511 #define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
512                         mbox.stats._N_ - hw_self->last_stats._N_)
513
514         AQ_SDELTA(uprc);
515         AQ_SDELTA(mprc);
516         AQ_SDELTA(bprc);
517         AQ_SDELTA(erpt);
518
519         AQ_SDELTA(uptc);
520         AQ_SDELTA(mptc);
521         AQ_SDELTA(bptc);
522         AQ_SDELTA(erpr);
523
524         AQ_SDELTA(ubrc);
525         AQ_SDELTA(ubtc);
526         AQ_SDELTA(mbrc);
527         AQ_SDELTA(mbtc);
528         AQ_SDELTA(bbrc);
529         AQ_SDELTA(bbtc);
530         AQ_SDELTA(dpc);
531
532 #undef AQ_SDELTA
533
534         memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));
535
536         return 0;
537 }
538
539 int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
540                               u64 *data, unsigned int *p_count)
541 {
542         struct hw_atl_s *hw_self = PHAL_ATLANTIC;
543         struct hw_atl_stats_s *stats = &hw_self->curr_stats;
544         int i = 0;
545
546         data[i] = stats->uprc + stats->mprc + stats->bprc;
547         data[++i] = stats->uprc;
548         data[++i] = stats->mprc;
549         data[++i] = stats->bprc;
550         data[++i] = stats->erpt;
551         data[++i] = stats->uptc + stats->mptc + stats->bptc;
552         data[++i] = stats->uptc;
553         data[++i] = stats->mptc;
554         data[++i] = stats->bptc;
555         data[++i] = stats->ubrc;
556         data[++i] = stats->ubtc;
557         data[++i] = stats->mbrc;
558         data[++i] = stats->mbtc;
559         data[++i] = stats->bbrc;
560         data[++i] = stats->bbtc;
561         data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
562         data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
563         data[++i] = stats_rx_dma_good_pkt_counterlsw_get(self);
564         data[++i] = stats_tx_dma_good_pkt_counterlsw_get(self);
565         data[++i] = stats_rx_dma_good_octet_counterlsw_get(self);
566         data[++i] = stats_tx_dma_good_octet_counterlsw_get(self);
567         data[++i] = stats->dpc;
568
569         if (p_count)
570                 *p_count = ++i;
571
572         return 0;
573 }
574
575 static const u32 hw_atl_utils_hw_mac_regs[] = {
576         0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
577         0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
578         0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
579         0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
580         0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
581         0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
582         0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
583         0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
584         0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
585         0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
586         0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
587         0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
588         0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
589         0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
590         0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
591         0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
592         0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
593         0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
594         0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
595         0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
596         0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
597         0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
598 };
599
600 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
601                              struct aq_hw_caps_s *aq_hw_caps,
602                              u32 *regs_buff)
603 {
604         unsigned int i = 0U;
605
606         for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
607                 regs_buff[i] = aq_hw_read_reg(self,
608                         hw_atl_utils_hw_mac_regs[i]);
609         return 0;
610 }
611
612 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
613 {
614         *fw_version = aq_hw_read_reg(self, 0x18U);
615         return 0;
616 }