Merge tag 'xfs-4.15-fixes-10' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[sfrench/cifs-2.6.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         hw_atl_utils_mpi_read_stats(self, &mbox);
507
508 #define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
509                         mbox.stats._N_ - hw_self->last_stats._N_)
510         if (self->aq_link_status.mbps) {
511                 AQ_SDELTA(uprc);
512                 AQ_SDELTA(mprc);
513                 AQ_SDELTA(bprc);
514                 AQ_SDELTA(erpt);
515
516                 AQ_SDELTA(uptc);
517                 AQ_SDELTA(mptc);
518                 AQ_SDELTA(bptc);
519                 AQ_SDELTA(erpr);
520
521                 AQ_SDELTA(ubrc);
522                 AQ_SDELTA(ubtc);
523                 AQ_SDELTA(mbrc);
524                 AQ_SDELTA(mbtc);
525                 AQ_SDELTA(bbrc);
526                 AQ_SDELTA(bbtc);
527                 AQ_SDELTA(dpc);
528         }
529 #undef AQ_SDELTA
530         hw_self->curr_stats.dma_pkt_rc = stats_rx_dma_good_pkt_counterlsw_get(self);
531         hw_self->curr_stats.dma_pkt_tc = stats_tx_dma_good_pkt_counterlsw_get(self);
532         hw_self->curr_stats.dma_oct_rc = stats_rx_dma_good_octet_counterlsw_get(self);
533         hw_self->curr_stats.dma_oct_tc = stats_tx_dma_good_octet_counterlsw_get(self);
534
535         memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));
536
537         return 0;
538 }
539
540 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
541 {
542         return &PHAL_ATLANTIC->curr_stats;
543 }
544
545 static const u32 hw_atl_utils_hw_mac_regs[] = {
546         0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
547         0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
548         0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
549         0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
550         0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
551         0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
552         0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
553         0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
554         0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
555         0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
556         0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
557         0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
558         0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
559         0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
560         0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
561         0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
562         0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
563         0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
564         0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
565         0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
566         0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
567         0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
568 };
569
570 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
571                              struct aq_hw_caps_s *aq_hw_caps,
572                              u32 *regs_buff)
573 {
574         unsigned int i = 0U;
575
576         for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
577                 regs_buff[i] = aq_hw_read_reg(self,
578                         hw_atl_utils_hw_mac_regs[i]);
579         return 0;
580 }
581
582 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
583 {
584         *fw_version = aq_hw_read_reg(self, 0x18U);
585         return 0;
586 }