net:wireless:Support eswin usb wifi ECR6600U
[platform/kernel/linux-starfive.git] / drivers / net / wireless / eswin / ecrnx_platform.c
1 /**
2  ******************************************************************************
3  *
4  * @file ecrnx_platform.c
5  *
6  * Copyright (C) ESWIN 2015-2020
7  *
8  ******************************************************************************
9  */
10
11 #include <linux/module.h>
12 #include <linux/firmware.h>
13 #include <linux/delay.h>
14
15 #include "ecrnx_platform.h"
16 #include "reg_access.h"
17 #include "hal_desc.h"
18 #include "ecrnx_main.h"
19
20 #ifndef CONFIG_ECRNX_ESWIN
21 #include "ecrnx_pci.h"
22 #ifndef CONFIG_ECRNX_FHOST
23 #include "ipc_host.h"
24 #endif /* !CONFIG_ECRNX_FHOST */
25 #endif /* CONFIG_ECRNX_ESWIN */
26
27 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
28 #include "sdio.h"
29 #include "ecrnx_sdio.h"
30 #elif defined(CONFIG_ECRNX_ESWIN_USB)
31 #include "usb.h"
32 #include "ecrnx_usb.h"
33 #endif
34 #ifdef CONFIG_ECRNX_WIFO_CAIL
35 #include "core.h"
36 #include "ecrnx_amt.h"
37 #endif
38
39 #ifdef CONFIG_ECRNX_TL4
40 /**
41  * ecrnx_plat_tl4_fw_upload() - Load the requested FW into embedded side.
42  *
43  * @ecrnx_plat: pointer to platform structure
44  * @fw_addr: Virtual address where the fw must be loaded
45  * @filename: Name of the fw.
46  *
47  * Load a fw, stored as a hex file, into the specified address
48  */
49 static int ecrnx_plat_tl4_fw_upload(struct ecrnx_plat *ecrnx_plat, u8* fw_addr,
50                                    char *filename)
51 {
52     struct device *dev = ecrnx_platform_get_dev(ecrnx_plat);
53     const struct firmware *fw;
54     int err = 0;
55     u32 *dst;
56     u8 const *file_data;
57     char typ0, typ1;
58     u32 addr0, addr1;
59     u32 dat0, dat1;
60     int remain;
61
62     err = request_firmware(&fw, filename, dev);
63     if (err) {
64         return err;
65     }
66     file_data = fw->data;
67     remain = fw->size;
68
69     /* Copy the file on the Embedded side */
70     dev_dbg(dev, "\n### Now copy %s firmware, @ = %p\n", filename, fw_addr);
71
72     /* Walk through all the lines of the configuration file */
73     while (remain >= 16) {
74         u32 data, offset;
75
76         if (sscanf(file_data, "%c:%08X %04X", &typ0, &addr0, &dat0) != 3)
77             break;
78         if ((addr0 & 0x01) != 0) {
79             addr0 = addr0 - 1;
80             dat0 = 0;
81         } else {
82             file_data += 16;
83             remain -= 16;
84         }
85         if ((remain < 16) ||
86             (sscanf(file_data, "%c:%08X %04X", &typ1, &addr1, &dat1) != 3) ||
87             (typ1 != typ0) || (addr1 != (addr0 + 1))) {
88             typ1 = typ0;
89             addr1 = addr0 + 1;
90             dat1 = 0;
91         } else {
92             file_data += 16;
93             remain -= 16;
94         }
95
96         if (typ0 == 'C') {
97             offset = 0x00200000;
98             if ((addr1 % 4) == 3)
99                 offset += 2*(addr1 - 3);
100             else
101                 offset += 2*(addr1 + 1);
102
103             data = dat1 | (dat0 << 16);
104         } else {
105             offset = 2*(addr1 - 1);
106             data = dat0 | (dat1 << 16);
107         }
108         dst = (u32 *)(fw_addr + offset);
109         *dst = data;
110     }
111
112     release_firmware(fw);
113
114     return err;
115 }
116 #endif
117
118 /**
119  * ecrnx_plat_bin_fw_upload() - Load the requested binary FW into embedded side.
120  *
121  * @ecrnx_plat: pointer to platform structure
122  * @fw_addr: Virtual address where the fw must be loaded
123  * @filename: Name of the fw.
124  *
125  * Load a fw, stored as a binary file, into the specified address
126  */
127 #ifndef CONFIG_ECRNX_ESWIN
128 static int ecrnx_plat_bin_fw_upload(struct ecrnx_plat *ecrnx_plat, u8* fw_addr,
129                                char *filename)
130 {
131     const struct firmware *fw;
132     struct device *dev = ecrnx_platform_get_dev(ecrnx_plat);
133     int err = 0;
134     unsigned int i, size;
135     u32 *src, *dst;
136
137     err = request_firmware(&fw, filename, dev);
138     if (err) {
139         return err;
140     }
141
142     /* Copy the file on the Embedded side */
143     dev_dbg(dev, "\n### Now copy %s firmware, @ = %p\n", filename, fw_addr);
144
145     src = (u32 *)fw->data;
146     dst = (u32 *)fw_addr;
147     size = (unsigned int)fw->size;
148
149     /* check potential platform bug on multiple stores vs memcpy */
150     for (i = 0; i < size; i += 4) {
151         *dst++ = *src++;
152     }
153
154     release_firmware(fw);
155
156     return err;
157 }
158 #endif
159
160 #ifndef CONFIG_ECRNX_TL4
161 #define IHEX_REC_DATA           0
162 #define IHEX_REC_EOF            1
163 #define IHEX_REC_EXT_SEG_ADD    2
164 #define IHEX_REC_START_SEG_ADD  3
165 #define IHEX_REC_EXT_LIN_ADD    4
166 #define IHEX_REC_START_LIN_ADD  5
167
168 /**
169  * ecrnx_plat_ihex_fw_upload() - Load the requested intel hex 8 FW into embedded side.
170  *
171  * @ecrnx_plat: pointer to platform structure
172  * @fw_addr: Virtual address where the fw must be loaded
173  * @filename: Name of the fw.
174  *
175  * Load a fw, stored as a ihex file, into the specified address.
176  */
177 #ifndef CONFIG_ECRNX_ESWIN
178 static int ecrnx_plat_ihex_fw_upload(struct ecrnx_plat *ecrnx_plat, u8* fw_addr,
179                                     char *filename)
180 {
181     const struct firmware *fw;
182     struct device *dev = ecrnx_platform_get_dev(ecrnx_plat);
183     u8 const *src, *end;
184     u32 *dst;
185     u16 haddr, segaddr, addr;
186     u32 hwaddr;
187     u8 load_fw, byte_count, checksum, csum, rec_type;
188     int err, rec_idx;
189     char hex_buff[9];
190
191     err = request_firmware(&fw, filename, dev);
192     if (err) {
193         return err;
194     }
195
196     /* Copy the file on the Embedded side */
197     dev_dbg(dev, "\n### Now copy %s firmware, @ = %p\n", filename, fw_addr);
198
199     src = fw->data;
200     end = src + (unsigned int)fw->size;
201     haddr = 0;
202     segaddr = 0;
203     load_fw = 1;
204     err = -EINVAL;
205     rec_idx = 0;
206     hwaddr = 0;
207
208 #define IHEX_READ8(_val, _cs) {                  \
209         hex_buff[2] = 0;                         \
210         strncpy(hex_buff, src, 2);               \
211         if (kstrtou8(hex_buff, 16, &_val))       \
212             goto end;                            \
213         src += 2;                                \
214         if (_cs)                                 \
215             csum += _val;                        \
216     }
217
218 #define IHEX_READ16(_val) {                        \
219         hex_buff[4] = 0;                           \
220         strncpy(hex_buff, src, 4);                 \
221         if (kstrtou16(hex_buff, 16, &_val))        \
222             goto end;                              \
223         src += 4;                                  \
224         csum += (_val & 0xff) + (_val >> 8);       \
225     }
226
227 #define IHEX_READ32(_val) {                              \
228         hex_buff[8] = 0;                                 \
229         strncpy(hex_buff, src, 8);                       \
230         if (kstrtouint(hex_buff, 16, &_val))             \
231             goto end;                                    \
232         src += 8;                                        \
233         csum += (_val & 0xff) + ((_val >> 8) & 0xff) +   \
234             ((_val >> 16) & 0xff) + (_val >> 24);        \
235     }
236
237 #define IHEX_READ32_PAD(_val, _nb) {                    \
238         memset(hex_buff, '0', 8);                       \
239         hex_buff[8] = 0;                                \
240         strncpy(hex_buff, src, (2 * _nb));              \
241         if (kstrtouint(hex_buff, 16, &_val))            \
242             goto end;                                   \
243         src += (2 * _nb);                               \
244         csum += (_val & 0xff) + ((_val >> 8) & 0xff) +  \
245             ((_val >> 16) & 0xff) + (_val >> 24);       \
246 }
247
248     /* loop until end of file is read*/
249     while (load_fw) {
250         rec_idx++;
251         csum = 0;
252
253         /* Find next colon start code */
254         while (*src != ':') {
255             src++;
256             if ((src + 3) >= end) /* 3 = : + rec_len */
257                 goto end;
258         }
259         src++;
260
261         /* Read record len */
262         IHEX_READ8(byte_count, 1);
263         if ((src + (byte_count * 2) + 8) >= end) /* 8 = rec_addr + rec_type + chksum */
264             goto end;
265
266         /* Read record addr */
267         IHEX_READ16(addr);
268
269         /* Read record type */
270         IHEX_READ8(rec_type, 1);
271
272         switch(rec_type) {
273             case IHEX_REC_DATA:
274             {
275                 /* Update destination address */
276                 dst = (u32 *) (fw_addr + hwaddr + addr);
277
278                 while (byte_count) {
279                     u32 val;
280                     if (byte_count >= 4) {
281                         IHEX_READ32(val);
282                         byte_count -= 4;
283                     } else {
284                         IHEX_READ32_PAD(val, byte_count);
285                         byte_count = 0;
286                     }
287                     *dst++ = __swab32(val);
288                 }
289                 break;
290             }
291             case IHEX_REC_EOF:
292             {
293                 load_fw = 0;
294                 err = 0;
295                 break;
296             }
297             case IHEX_REC_EXT_SEG_ADD: /* Extended Segment Address */
298             {
299                 IHEX_READ16(segaddr);
300                 hwaddr = (haddr << 16) + (segaddr << 4);
301                 break;
302             }
303             case IHEX_REC_EXT_LIN_ADD: /* Extended Linear Address */
304             {
305                 IHEX_READ16(haddr);
306                 hwaddr = (haddr << 16) + (segaddr << 4);
307                 break;
308             }
309             case IHEX_REC_START_LIN_ADD: /* Start Linear Address */
310             {
311                 u32 val;
312                 IHEX_READ32(val); /* need to read for checksum */
313                 break;
314             }
315             case IHEX_REC_START_SEG_ADD:
316             default:
317             {
318                 dev_err(dev, "ihex: record type %d not supported\n", rec_type);
319                 load_fw = 0;
320             }
321         }
322
323         /* Read and compare checksum */
324         IHEX_READ8(checksum, 0);
325         if (checksum != (u8)(~csum + 1))
326             goto end;
327     }
328
329 #undef IHEX_READ8
330 #undef IHEX_READ16
331 #undef IHEX_READ32
332 #undef IHEX_READ32_PAD
333
334   end:
335     release_firmware(fw);
336
337     if (err)
338         dev_err(dev, "%s: Invalid ihex record around line %d\n", filename, rec_idx);
339
340     return err;
341 }
342 #endif /* CONFIG_ECRNX_TL4 */
343 #endif
344
345 #ifndef CONFIG_ECRNX_ESWIN
346 #ifndef CONFIG_ECRNX_SDM
347 /**
348  * ecrnx_plat_get_rf() - Retrun the RF used in the platform
349  *
350  * @ecrnx_plat: pointer to platform structure
351  */
352 static u32 ecrnx_plat_get_rf(struct ecrnx_plat *ecrnx_plat)
353 {
354     u32 ver;
355     ver = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, MDM_HDMCONFIG_ADDR);
356
357     ver = __MDM_PHYCFG_FROM_VERS(ver);
358     WARN(((ver != MDM_PHY_CONFIG_TRIDENT) &&
359           (ver != MDM_PHY_CONFIG_CATAXIA) &&
360           (ver != MDM_PHY_CONFIG_KARST)),
361          "Unknown PHY version 0x%08x\n", ver);
362
363     return ver;
364 }
365 #endif
366
367 /**
368  * ecrnx_plat_get_clkctrl_addr() - Return the clock control register address
369  *
370  * @ecrnx_plat: platform data
371  */
372 #ifndef CONFIG_ECRNX_SDM
373 #ifndef CONFIG_ECRNX_ESWIN
374 static u32 ecrnx_plat_get_clkctrl_addr(struct ecrnx_plat *ecrnx_plat)
375 {
376     u32 regval;
377     if (ecrnx_plat_get_rf(ecrnx_plat) ==  MDM_PHY_CONFIG_TRIDENT)
378         return MDM_MEMCLKCTRL0_ADDR;
379     regval = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, SYSCTRL_SIGNATURE_ADDR);
380     if (__FPGA_TYPE(regval) == 0xC0CA)
381         return CRM_CLKGATEFCTRL0_ADDR;
382     else
383         return MDM_CLKGATEFCTRL0_ADDR;
384 }
385 #endif /* CONFIG_ECRNX_SDM */
386 #endif
387
388 /**
389  * ecrnx_plat_stop_agcfsm() - Stop a AGC state machine
390  *
391  * @ecrnx_plat: pointer to platform structure
392  * @agg_reg: Address of the agccntl register (within ECRNX_ADDR_SYSTEM)
393  * @agcctl: Updated with value of the agccntl rgister before stop
394  * @memclk: Updated with value of the clock register before stop
395  * @agc_ver: Version of the AGC load procedure
396  * @clkctrladdr: Indicates which AGC clock register should be accessed
397  */
398 #ifndef CONFIG_ECRNX_ESWIN
399 static void ecrnx_plat_stop_agcfsm(struct ecrnx_plat *ecrnx_plat, int agc_reg,
400                                   u32 *agcctl, u32 *memclk, u8 agc_ver,
401                                   u32 clkctrladdr)
402 {
403     /* First read agcctnl and clock registers */
404     *memclk = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, clkctrladdr);
405
406     /* Stop state machine : xxAGCCNTL0[AGCFSMRESET]=1 */
407     *agcctl = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, agc_reg);
408     ECRNX_REG_WRITE((*agcctl) | BIT(12), ecrnx_plat, ECRNX_ADDR_SYSTEM, agc_reg);
409
410     /* Force clock */
411     if (agc_ver > 0) {
412         /* CLKGATEFCTRL0[AGCCLKFORCE]=1 */
413         ECRNX_REG_WRITE((*memclk) | BIT(29), ecrnx_plat, ECRNX_ADDR_SYSTEM,
414                        clkctrladdr);
415     } else {
416         /* MEMCLKCTRL0[AGCMEMCLKCTRL]=0 */
417         ECRNX_REG_WRITE((*memclk) & ~BIT(3), ecrnx_plat, ECRNX_ADDR_SYSTEM,
418                        clkctrladdr);
419     }
420 }
421 #endif
422
423 /**
424  * ecrnx_plat_start_agcfsm() - Restart a AGC state machine
425  *
426  * @ecrnx_plat: pointer to platform structure
427  * @agg_reg: Address of the agccntl register (within ECRNX_ADDR_SYSTEM)
428  * @agcctl: value of the agccntl register to restore
429  * @memclk: value of the clock register to restore
430  * @agc_ver: Version of the AGC load procedure
431  * @clkctrladdr: Indicates which AGC clock register should be accessed
432  */
433 #ifndef CONFIG_ECRNX_ESWIN
434 static void ecrnx_plat_start_agcfsm(struct ecrnx_plat *ecrnx_plat, int agc_reg,
435                                    u32 agcctl, u32 memclk, u8 agc_ver,
436                                    u32 clkctrladdr)
437 {
438
439     /* Release clock */
440     if (agc_ver > 0)
441         /* CLKGATEFCTRL0[AGCCLKFORCE]=0 */
442         ECRNX_REG_WRITE(memclk & ~BIT(29), ecrnx_plat, ECRNX_ADDR_SYSTEM,
443                        clkctrladdr);
444     else
445         /* MEMCLKCTRL0[AGCMEMCLKCTRL]=1 */
446         ECRNX_REG_WRITE(memclk | BIT(3), ecrnx_plat, ECRNX_ADDR_SYSTEM,
447                        clkctrladdr);
448
449     /* Restart state machine: xxAGCCNTL0[AGCFSMRESET]=0 */
450     ECRNX_REG_WRITE(agcctl & ~BIT(12), ecrnx_plat, ECRNX_ADDR_SYSTEM, agc_reg);
451 }
452 #endif
453 #endif
454
455 /**
456  * ecrnx_plat_get_agc_load_version() - Return the agc load protocol version and the
457  * address of the clock control register
458  *
459  * @ecrnx_plat: platform data
460  * @rf: rf in used
461  * @clkctrladdr: returned clock control register address
462  *
463  */
464 #ifndef CONFIG_ECRNX_ESWIN
465 #ifndef CONFIG_ECRNX_SDM
466 static u8 ecrnx_plat_get_agc_load_version(struct ecrnx_plat *ecrnx_plat, u32 rf,
467                                          u32 *clkctrladdr)
468 {
469     u8 agc_load_ver = 0;
470     u32 agc_ver;
471     u32 regval;
472
473     *clkctrladdr = ecrnx_plat_get_clkctrl_addr(ecrnx_plat);
474     /* Trident and Elma PHY use old method */
475     if (rf ==  MDM_PHY_CONFIG_TRIDENT)
476         return 0;
477
478     /* Get the FPGA signature */
479     regval = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, SYSCTRL_SIGNATURE_ADDR);
480
481
482     /* Read RIU version register */
483     agc_ver = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, RIU_ECRNXVERSION_ADDR);
484     agc_load_ver = __RIU_AGCLOAD_FROM_VERS(agc_ver);
485
486     return agc_load_ver;
487 }
488 #endif /* CONFIG_ECRNX_SDM */
489 #endif
490
491 /**
492  * ecrnx_plat_agc_load() - Load AGC ucode
493  *
494  * @ecrnx_plat: platform data
495  */
496 #ifndef CONFIG_ECRNX_ESWIN
497 static int ecrnx_plat_agc_load(struct ecrnx_plat *ecrnx_plat)
498 {
499     int ret = 0;
500 #ifndef CONFIG_ECRNX_SDM
501     u32 agc = 0, agcctl, memclk;
502     u32 clkctrladdr;
503     u32 rf = ecrnx_plat_get_rf(ecrnx_plat);
504     u8 agc_ver;
505
506     switch (rf) {
507         case MDM_PHY_CONFIG_TRIDENT:
508             agc = AGC_ECRNXAGCCNTL_ADDR;
509             break;
510         case MDM_PHY_CONFIG_CATAXIA:
511         case MDM_PHY_CONFIG_KARST:
512             agc = RIU_ECRNXAGCCNTL_ADDR;
513             break;
514         default:
515             return -1;
516     }
517
518     agc_ver = ecrnx_plat_get_agc_load_version(ecrnx_plat, rf, &clkctrladdr);
519
520     ecrnx_plat_stop_agcfsm(ecrnx_plat, agc, &agcctl, &memclk, agc_ver, clkctrladdr);
521
522     ret = ecrnx_plat_bin_fw_upload(ecrnx_plat,
523                               ECRNX_ADDR(ecrnx_plat, ECRNX_ADDR_SYSTEM, PHY_AGC_UCODE_ADDR),
524                               ECRNX_AGC_FW_NAME);
525
526     if (!ret && (agc_ver == 1)) {
527         /* Run BIST to ensure that the AGC RAM was correctly loaded */
528         ECRNX_REG_WRITE(BIT(28), ecrnx_plat, ECRNX_ADDR_SYSTEM,
529                        RIU_ECRNXDYNAMICCONFIG_ADDR);
530         while (ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM,
531                              RIU_ECRNXDYNAMICCONFIG_ADDR) & BIT(28));
532
533         if (!(ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM,
534                             RIU_AGCMEMBISTSTAT_ADDR) & BIT(0))) {
535             dev_err(ecrnx_platform_get_dev(ecrnx_plat),
536                     "AGC RAM not loaded correctly 0x%08x\n",
537                     ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM,
538                                   RIU_AGCMEMSIGNATURESTAT_ADDR));
539             ret = -EIO;
540         }
541     }
542
543     ecrnx_plat_start_agcfsm(ecrnx_plat, agc, agcctl, memclk, agc_ver, clkctrladdr);
544
545 #endif
546     return ret;
547 }
548 #endif
549
550 /**
551  * ecrnx_ldpc_load() - Load LDPC RAM
552  *
553  * @ecrnx_hw: Main driver data
554  */
555 #ifndef CONFIG_ECRNX_ESWIN
556 static int ecrnx_ldpc_load(struct ecrnx_hw *ecrnx_hw)
557 {
558 #ifndef CONFIG_ECRNX_SDM
559     struct ecrnx_plat *ecrnx_plat = ecrnx_hw->plat;
560     u32 rf = ecrnx_plat_get_rf(ecrnx_plat);
561     u32 phy_feat = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, MDM_HDMCONFIG_ADDR);
562     u32 phy_vers = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, MDM_HDMVERSION_ADDR);
563
564     if (((rf !=  MDM_PHY_CONFIG_KARST) && (rf !=  MDM_PHY_CONFIG_CATAXIA)) ||
565         (phy_feat & (MDM_LDPCDEC_BIT | MDM_LDPCENC_BIT)) !=
566         (MDM_LDPCDEC_BIT | MDM_LDPCENC_BIT)) {
567         goto disable_ldpc;
568     }
569     if (__MDM_VERSION(phy_vers) > 30) {
570         return 0;
571     }
572
573     if (ecrnx_plat_bin_fw_upload(ecrnx_plat,
574                             ECRNX_ADDR(ecrnx_plat, ECRNX_ADDR_SYSTEM, PHY_LDPC_RAM_ADDR),
575                             ECRNX_LDPC_RAM_NAME)) {
576         goto disable_ldpc;
577     }
578
579     return 0;
580
581   disable_ldpc:
582     ecrnx_hw->mod_params->ldpc_on = false;
583
584 #endif /* CONFIG_ECRNX_SDM */
585     return 0;
586 }
587 #endif
588 /**
589  * ecrnx_plat_lmac_load() - Load FW code
590  *
591  * @ecrnx_plat: platform data
592  */
593 #ifndef CONFIG_ECRNX_ESWIN
594 static int ecrnx_plat_lmac_load(struct ecrnx_plat *ecrnx_plat)
595 {
596     int ret;
597
598     #ifdef CONFIG_ECRNX_TL4
599     ret = ecrnx_plat_tl4_fw_upload(ecrnx_plat,
600                                   ECRNX_ADDR(ecrnx_plat, ECRNX_ADDR_CPU, RAM_LMAC_FW_ADDR),
601                                   ECRNX_MAC_FW_NAME);
602     #else
603     ret = ecrnx_plat_ihex_fw_upload(ecrnx_plat,
604                                    ECRNX_ADDR(ecrnx_plat, ECRNX_ADDR_CPU, RAM_LMAC_FW_ADDR),
605                                    ECRNX_MAC_FW_NAME);
606     if (ret == -ENOENT)
607     {
608         ret = ecrnx_plat_bin_fw_upload(ecrnx_plat,
609                                       ECRNX_ADDR(ecrnx_plat, ECRNX_ADDR_CPU, RAM_LMAC_FW_ADDR),
610                                       ECRNX_MAC_FW_NAME2);
611     }
612     #endif
613
614     return ret;
615 }
616 #endif
617
618 /**
619  * ecrnx_rf_fw_load() - Load RF FW if any
620  *
621  * @ecrnx_hw: Main driver data
622  */
623 #ifndef CONFIG_ECRNX_ESWIN
624 static int ecrnx_plat_rf_fw_load(struct ecrnx_hw *ecrnx_hw)
625 {
626 #ifndef CONFIG_ECRNX_SDM
627     struct ecrnx_plat *ecrnx_plat = ecrnx_hw->plat;
628     u32 rf = ecrnx_plat_get_rf(ecrnx_plat);
629     struct device *dev = ecrnx_platform_get_dev(ecrnx_plat);
630     const struct firmware *fw;
631     int err = 0;
632     u8 const *file_data;
633     int remain;
634     u32 clkforce;
635     u32 clkctrladdr;
636
637     // Today only Cataxia has a FW to load
638     if (rf !=  MDM_PHY_CONFIG_CATAXIA)
639         return 0;
640
641     err = request_firmware(&fw, ECRNX_CATAXIA_FW_NAME, dev);
642     if (err)
643     {
644         dev_err(dev, "Make sure your board has up-to-date packages.");
645         dev_err(dev, "Run \"sudo smart update\" \"sudo smart upgrade\" commands.\n");
646         return err;
647     }
648
649     file_data = fw->data;
650     remain = fw->size;
651
652     // Get address of clock control register
653     clkctrladdr = ecrnx_plat_get_clkctrl_addr(ecrnx_plat);
654
655     // Force RC clock
656     clkforce = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, clkctrladdr);
657     ECRNX_REG_WRITE(clkforce | BIT(27), ecrnx_plat, ECRNX_ADDR_SYSTEM, clkctrladdr);
658     mdelay(1);
659
660     // Reset RC
661     ECRNX_REG_WRITE(0x00003100, ecrnx_plat, ECRNX_ADDR_SYSTEM, RC_SYSTEM_CONFIGURATION_ADDR);
662     mdelay(20);
663
664     // Reset RF
665     ECRNX_REG_WRITE(0x00133100, ecrnx_plat, ECRNX_ADDR_SYSTEM, RC_SYSTEM_CONFIGURATION_ADDR);
666     mdelay(20);
667
668     // Select trx 2 HB
669     ECRNX_REG_WRITE(0x00103100, ecrnx_plat, ECRNX_ADDR_SYSTEM, RC_SYSTEM_CONFIGURATION_ADDR);
670     mdelay(1);
671
672     // Set ASP freeze
673     ECRNX_REG_WRITE(0xC1010001, ecrnx_plat, ECRNX_ADDR_SYSTEM, RC_ACCES_TO_CATAXIA_REG_ADDR);
674     mdelay(1);
675
676     /* Walk through all the lines of the FW file */
677     while (remain >= 10) {
678         u32 data;
679
680         if (sscanf(file_data, "0x%08X", &data) != 1)
681         {
682             // Corrupted FW file
683             err = -1;
684             break;
685         }
686         file_data += 11;
687         remain -= 11;
688
689         ECRNX_REG_WRITE(data, ecrnx_plat, ECRNX_ADDR_SYSTEM, RC_ACCES_TO_CATAXIA_REG_ADDR);
690         udelay(50);
691     }
692
693     // Clear ASP freeze
694     ECRNX_REG_WRITE(0xE0010011, ecrnx_plat, ECRNX_ADDR_SYSTEM, RC_ACCES_TO_CATAXIA_REG_ADDR);
695     mdelay(1);
696
697     // Unforce RC clock
698     ECRNX_REG_WRITE(clkforce, ecrnx_plat, ECRNX_ADDR_SYSTEM, clkctrladdr);
699
700     release_firmware(fw);
701
702 #endif /* CONFIG_ECRNX_SDM */
703     return err;
704 }
705 #endif
706
707 /**
708  * ecrnx_plat_mpif_sel() - Select the MPIF according to the FPGA signature
709  *
710  * @ecrnx_plat: platform data
711  */
712 #ifndef CONFIG_ECRNX_ESWIN
713 static void ecrnx_plat_mpif_sel(struct ecrnx_plat *ecrnx_plat)
714 {
715 #ifndef CONFIG_ECRNX_SDM
716     u32 regval;
717     u32 type;
718
719     /* Get the FPGA signature */
720     regval = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, SYSCTRL_SIGNATURE_ADDR);
721     type = __FPGA_TYPE(regval);
722
723     /* Check if we need to switch to the old MPIF or not */
724     if ((type != 0xCAFE) && (type != 0XC0CA) && (regval & 0xF) < 0x3)
725     {
726         /* A old FPGA A is used, so configure the FPGA B to use the old MPIF */
727         ECRNX_REG_WRITE(0x3, ecrnx_plat, ECRNX_ADDR_SYSTEM, FPGAB_MPIF_SEL_ADDR);
728     }
729 #endif
730 }
731 #endif
732
733 /**
734  * ecrnx_platform_reset() - Reset the platform
735  *
736  * @ecrnx_plat: platform data
737  */
738 #ifndef CONFIG_ECRNX_ESWIN
739 static int ecrnx_platform_reset(struct ecrnx_plat *ecrnx_plat)
740 {
741     u32 regval;
742
743     /* the doc states that SOFT implies FPGA_B_RESET
744      * adding FPGA_B_RESET is clearer */
745     ECRNX_REG_WRITE(SOFT_RESET | FPGA_B_RESET, ecrnx_plat,
746                    ECRNX_ADDR_SYSTEM, SYSCTRL_MISC_CNTL_ADDR);
747     msleep(100);
748
749     regval = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM, SYSCTRL_MISC_CNTL_ADDR);
750
751     if (regval & SOFT_RESET) {
752         dev_err(ecrnx_platform_get_dev(ecrnx_plat), "reset: failed\n");
753         return -EIO;
754     }
755
756     ECRNX_REG_WRITE(regval & ~FPGA_B_RESET, ecrnx_plat,
757                    ECRNX_ADDR_SYSTEM, SYSCTRL_MISC_CNTL_ADDR);
758     msleep(100);
759     return 0;
760 }
761 #endif
762
763 /**
764  * rwmx_platform_save_config() - Save hardware config before reload
765  *
766  * @ecrnx_plat: Pointer to platform data
767  *
768  * Return configuration registers values.
769  */
770 #ifndef CONFIG_ECRNX_ESWIN
771 static void* ecrnx_term_save_config(struct ecrnx_plat *ecrnx_plat)
772 {
773     const u32 *reg_list;
774     u32 *reg_value, *res;
775     int i, size = 0;
776
777     if (ecrnx_plat->get_config_reg) {
778         size = ecrnx_plat->get_config_reg(ecrnx_plat, &reg_list);
779     }
780
781     if (size <= 0)
782         return NULL;
783
784     res = kmalloc(sizeof(u32) * size, GFP_KERNEL);
785     if (!res)
786         return NULL;
787
788     reg_value = res;
789     for (i = 0; i < size; i++) {
790         *reg_value++ = ECRNX_REG_READ(ecrnx_plat, ECRNX_ADDR_SYSTEM,
791                                      *reg_list++);
792     }
793
794     return res;
795 }
796 #endif
797
798 /**
799  * rwmx_platform_restore_config() - Restore hardware config after reload
800  *
801  * @ecrnx_plat: Pointer to platform data
802  * @reg_value: Pointer of value to restore
803  * (obtained with rwmx_platform_save_config())
804  *
805  * Restore configuration registers value.
806  */
807 #ifndef CONFIG_ECRNX_ESWIN
808 static void ecrnx_term_restore_config(struct ecrnx_plat *ecrnx_plat,
809                                      u32 *reg_value)
810 {
811     const u32 *reg_list;
812     int i, size = 0;
813
814     if (!reg_value || !ecrnx_plat->get_config_reg)
815         return;
816
817     size = ecrnx_plat->get_config_reg(ecrnx_plat, &reg_list);
818
819     for (i = 0; i < size; i++) {
820         ECRNX_REG_WRITE(*reg_value++, ecrnx_plat, ECRNX_ADDR_SYSTEM,
821                        *reg_list++);
822     }
823 }
824 #endif
825
826 #ifndef CONFIG_ECRNX_ESWIN
827 static int ecrnx_check_fw_compatibility(struct ecrnx_hw *ecrnx_hw)
828 {
829     int res = 0;
830
831     struct ipc_shared_env_tag *shared = ecrnx_hw->ipc_env->shared;
832     #ifdef CONFIG_ECRNX_SOFTMAC
833     struct wiphy *wiphy = ecrnx_hw->hw->wiphy;
834     #else //CONFIG_ECRNX_SOFTMAC
835     struct wiphy *wiphy = ecrnx_hw->wiphy;
836     #endif //CONFIG_ECRNX_SOFTMAC
837     #ifdef CONFIG_ECRNX_OLD_IPC
838     int ipc_shared_version = 10;
839     #else //CONFIG_ECRNX_OLD_IPC
840     int ipc_shared_version = 11;
841     #endif //CONFIG_ECRNX_OLD_IPC
842
843     if(shared->comp_info.ipc_shared_version != ipc_shared_version)
844     {
845         wiphy_err(wiphy, "Different versions of IPC shared version between driver and FW (%d != %d)\n ",
846                   ipc_shared_version, shared->comp_info.ipc_shared_version);
847         res = -1;
848     }
849
850     if(shared->comp_info.radarbuf_cnt != IPC_RADARBUF_CNT)
851     {
852         wiphy_err(wiphy, "Different number of host buffers available for Radar events handling "\
853                   "between driver and FW (%d != %d)\n", IPC_RADARBUF_CNT,
854                   shared->comp_info.radarbuf_cnt);
855         res = -1;
856     }
857
858     if(shared->comp_info.unsuprxvecbuf_cnt != IPC_UNSUPRXVECBUF_CNT)
859     {
860         wiphy_err(wiphy, "Different number of host buffers available for unsupported Rx vectors "\
861                   "handling between driver and FW (%d != %d)\n", IPC_UNSUPRXVECBUF_CNT,
862                   shared->comp_info.unsuprxvecbuf_cnt);
863         res = -1;
864     }
865
866     #ifdef CONFIG_ECRNX_FULLMAC
867     if(shared->comp_info.rxdesc_cnt != IPC_RXDESC_CNT)
868     {
869         wiphy_err(wiphy, "Different number of shared descriptors available for Data RX handling "\
870                   "between driver and FW (%d != %d)\n", IPC_RXDESC_CNT,
871                   shared->comp_info.rxdesc_cnt);
872         res = -1;
873     }
874     #endif /* CONFIG_ECRNX_FULLMAC */
875
876     if(shared->comp_info.rxbuf_cnt != IPC_RXBUF_CNT)
877     {
878         wiphy_err(wiphy, "Different number of host buffers available for Data Rx handling "\
879                   "between driver and FW (%d != %d)\n", IPC_RXBUF_CNT,
880                   shared->comp_info.rxbuf_cnt);
881         res = -1;
882     }
883
884     if(shared->comp_info.msge2a_buf_cnt != IPC_MSGE2A_BUF_CNT)
885     {
886         wiphy_err(wiphy, "Different number of host buffers available for Emb->App MSGs "\
887                   "sending between driver and FW (%d != %d)\n", IPC_MSGE2A_BUF_CNT,
888                   shared->comp_info.msge2a_buf_cnt);
889         res = -1;
890     }
891
892     if(shared->comp_info.dbgbuf_cnt != IPC_DBGBUF_CNT)
893     {
894         wiphy_err(wiphy, "Different number of host buffers available for debug messages "\
895                   "sending between driver and FW (%d != %d)\n", IPC_DBGBUF_CNT,
896                   shared->comp_info.dbgbuf_cnt);
897         res = -1;
898     }
899
900     if(shared->comp_info.bk_txq != NX_TXDESC_CNT0)
901     {
902         wiphy_err(wiphy, "Driver and FW have different sizes of BK TX queue (%d != %d)\n",
903                   NX_TXDESC_CNT0, shared->comp_info.bk_txq);
904         res = -1;
905     }
906
907     if(shared->comp_info.be_txq != NX_TXDESC_CNT1)
908     {
909         wiphy_err(wiphy, "Driver and FW have different sizes of BE TX queue (%d != %d)\n",
910                   NX_TXDESC_CNT1, shared->comp_info.be_txq);
911         res = -1;
912     }
913
914     if(shared->comp_info.vi_txq != NX_TXDESC_CNT2)
915     {
916         wiphy_err(wiphy, "Driver and FW have different sizes of VI TX queue (%d != %d)\n",
917                   NX_TXDESC_CNT2, shared->comp_info.vi_txq);
918         res = -1;
919     }
920
921     if(shared->comp_info.vo_txq != NX_TXDESC_CNT3)
922     {
923         wiphy_err(wiphy, "Driver and FW have different sizes of VO TX queue (%d != %d)\n",
924                   NX_TXDESC_CNT3, shared->comp_info.vo_txq);
925         res = -1;
926     }
927
928     #if NX_TXQ_CNT == 5
929     if(shared->comp_info.bcn_txq != NX_TXDESC_CNT4)
930     {
931         wiphy_err(wiphy, "Driver and FW have different sizes of BCN TX queue (%d != %d)\n",
932                 NX_TXDESC_CNT4, shared->comp_info.bcn_txq);
933         res = -1;
934     }
935     #else
936     if (shared->comp_info.bcn_txq > 0)
937     {
938         wiphy_err(wiphy, "BCMC enabled in firmware but disabled in driver\n");
939         res = -1;
940     }
941     #endif /* NX_TXQ_CNT == 5 */
942
943     if(shared->comp_info.ipc_shared_size != sizeof(ipc_shared_env))
944     {
945         wiphy_err(wiphy, "Different sizes of IPC shared between driver and FW (%zd != %d)\n",
946                   sizeof(ipc_shared_env), shared->comp_info.ipc_shared_size);
947         res = -1;
948     }
949
950     if(shared->comp_info.msg_api != MSG_API_VER)
951     {
952         wiphy_err(wiphy, "Different supported message API versions between "\
953                    "driver and FW (%d != %d)\n", MSG_API_VER, shared->comp_info.msg_api);
954         res = -1;
955     }
956
957     return res;
958 }
959 #endif /* !CONFIG_ECRNX_ESWIN */
960
961 /**
962  * ecrnx_platform_on() - Start the platform
963  *
964  * @ecrnx_hw: Main driver data
965  * @config: Config to restore (NULL if nothing to restore)
966  *
967  * It starts the platform :
968  * - load fw and ucodes
969  * - initialize IPC
970  * - boot the fw
971  * - enable link communication/IRQ
972  *
973  * Called by 802.11 part
974  */
975 int ecrnx_platform_on(struct ecrnx_hw *ecrnx_hw, void *config)
976 {
977     u8 *shared_ram;
978     int ret;
979     
980     ECRNX_DBG("%s entry!!", __func__);
981     shared_ram = kzalloc(sizeof(struct ipc_shared_env_tag), GFP_KERNEL);
982     if (!shared_ram)
983         return -ENOMEM;
984
985     if ((ret = ecrnx_ipc_init(ecrnx_hw, shared_ram)))
986        return ret;
987
988     ECRNX_DBG("%s exit!!", __func__);
989     return 0;
990 }
991
992 /**
993  * ecrnx_platform_off() - Stop the platform
994  *
995  * @ecrnx_hw: Main driver data
996  * @config: Updated with pointer to config, to be able to restore it with
997  * ecrnx_platform_on(). It's up to the caller to free the config. Set to NULL
998  * if configuration is not needed.
999  *
1000  * Called by 802.11 part
1001  */
1002 void ecrnx_platform_off(struct ecrnx_hw *ecrnx_hw, void **config)
1003 {
1004     ecrnx_ipc_deinit(ecrnx_hw);
1005 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
1006      ecrnx_sdio_deinit(ecrnx_hw);
1007 #elif defined(CONFIG_ECRNX_ESWIN_USB)
1008     ecrnx_usb_deinit(ecrnx_hw);
1009 #else
1010    #error "config error drv";
1011 #endif
1012 }
1013
1014 /**
1015  * ecrnx_platform_init() - Initialize the platform
1016  *
1017  * @ecrnx_plat: platform data (already updated by platform driver)
1018  * @platform_data: Pointer to store the main driver data pointer (aka ecrnx_hw)
1019  *                That will be set as driver data for the platform driver
1020  * Return: 0 on success, < 0 otherwise
1021  *
1022  * Called by the platform driver after it has been probed
1023  */
1024 int ecrnx_platform_init(void *ecrnx_plat, void **platform_data)
1025 {
1026     ECRNX_DBG(ECRNX_FN_ENTRY_STR);
1027 #if defined CONFIG_ECRNX_SOFTMAC
1028     return ecrnx_mac80211_init(ecrnx_plat, platform_data);
1029 #elif defined CONFIG_ECRNX_FULLMAC
1030 #ifdef CONFIG_ECRNX_WIFO_CAIL
1031         if (amt_mode == true) {
1032                 return ecrnx_amt_init();
1033         }
1034         else
1035 #endif
1036     return ecrnx_cfg80211_init(ecrnx_plat, platform_data);
1037 #elif defined CONFIG_ECRNX_FHOST
1038     return ecrnx_fhost_init(ecrnx_plat, platform_data);
1039 #endif
1040 }
1041
1042 /**
1043  * ecrnx_platform_deinit() - Deinitialize the platform
1044  *
1045  * @ecrnx_hw: main driver data
1046  *
1047  * Called by the platform driver after it is removed
1048  */
1049 void ecrnx_platform_deinit(struct ecrnx_hw *ecrnx_hw)
1050 {
1051     ECRNX_DBG(ECRNX_FN_ENTRY_STR);
1052
1053 #if defined CONFIG_ECRNX_SOFTMAC
1054     ecrnx_mac80211_deinit(ecrnx_hw);
1055 #elif defined CONFIG_ECRNX_FULLMAC
1056 #ifdef CONFIG_ECRNX_WIFO_CAIL
1057         if (amt_mode == true) {
1058                 ecrnx_amt_deinit();
1059         }
1060         else
1061 #endif
1062     ecrnx_cfg80211_deinit(ecrnx_hw);
1063 #elif defined CONFIG_ECRNX_FHOST
1064     ecrnx_fhost_deinit(ecrnx_hw);
1065 #endif
1066 }
1067
1068
1069 /**
1070  * ecrnx_platform_register_drv() - Register all possible platform drivers
1071  */
1072 int ecrnx_platform_register_drv(void)
1073 {
1074 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
1075     return ecrnx_sdio_register_drv();
1076 #elif defined(CONFIG_ECRNX_ESWIN_USB)
1077     return ecrnx_usb_register_drv();
1078 #else
1079     #error "config error drv"
1080 #endif
1081 }
1082
1083
1084 /**
1085  * ecrnx_platform_unregister_drv() - Unegister all platform drivers
1086  */
1087 void ecrnx_platform_unregister_drv(void)
1088 {
1089 #if defined(CONFIG_ECRNX_ESWIN_SDIO)
1090     return ecrnx_sdio_unregister_drv();
1091 #elif defined(CONFIG_ECRNX_ESWIN_USB)
1092     return ecrnx_usb_unregister_drv();
1093 #else
1094     #error "config error drv"
1095 #endif
1096 }
1097
1098
1099 #ifndef CONFIG_ECRNX_SDM
1100 MODULE_FIRMWARE(ECRNX_AGC_FW_NAME);
1101 MODULE_FIRMWARE(ECRNX_FCU_FW_NAME);
1102 MODULE_FIRMWARE(ECRNX_LDPC_RAM_NAME);
1103 #endif
1104 MODULE_FIRMWARE(ECRNX_MAC_FW_NAME);
1105 #ifndef CONFIG_ECRNX_TL4
1106 MODULE_FIRMWARE(ECRNX_MAC_FW_NAME2);
1107 #endif