wifi->esp8089:
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / esp8089 / esp_driver / esp_main.c
1 /*
2  * Copyright (c) 2010 - 2014 Espressif System.
3  *
4  * main routine
5  */
6
7 #include <linux/netdevice.h>
8 #include <linux/etherdevice.h>
9 #include <linux/rtnetlink.h>
10 #include <linux/firmware.h>
11 #include <linux/sched.h>
12 #include <net/cfg80211.h>
13 #include <net/mac80211.h>
14 #include <linux/time.h>
15 #include <linux/moduleparam.h>
16
17 #include "esp_pub.h"
18 #include "esp_sip.h"
19 #include "esp_sif.h"
20 #include "esp_debug.h"
21 #include "esp_file.h"
22 #include "esp_wl.h"
23
24 struct completion *gl_bootup_cplx = NULL;
25
26 #ifndef FPGA_DEBUG
27 static int esp_download_fw(struct esp_pub * epub);
28 #endif /* !FGPA_DEBUG */
29
30 static int modparam_no_txampdu = 0;
31 static int modparam_no_rxampdu = 0;
32 module_param_named(no_txampdu, modparam_no_txampdu, int, 0444);
33 MODULE_PARM_DESC(no_txampdu, "Disable tx ampdu.");
34 module_param_named(no_rxampdu, modparam_no_rxampdu, int, 0444);
35 MODULE_PARM_DESC(no_rxampdu, "Disable rx ampdu.");
36
37 static char *modparam_eagle_path = "";
38 module_param_named(eagle_path, modparam_eagle_path, charp, 0444);
39 MODULE_PARM_DESC(eagle_path, "eagle path");
40
41 bool mod_support_no_txampdu()
42 {
43         return modparam_no_txampdu;
44 }
45
46 bool mod_support_no_rxampdu()
47 {
48         return modparam_no_rxampdu;
49 }
50
51 void mod_support_no_txampdu_set(bool value)
52 {
53         modparam_no_txampdu = value;
54 }
55
56 char *mod_eagle_path_get(void)
57 {
58         if (modparam_eagle_path[0] == '\0')
59                 return NULL;
60
61         return modparam_eagle_path;
62 }
63
64 int esp_pub_init_all(struct esp_pub *epub)
65 {
66         int ret = 0;
67         
68         /* completion for bootup event poll*/
69         DECLARE_COMPLETION_ONSTACK(complete);
70         atomic_set(&epub->ps.state, ESP_PM_OFF);
71         if(epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT){
72                 epub->sip = sip_attach(epub);
73                 if (epub->sip == NULL) {
74                         printk(KERN_ERR "%s sip alloc failed\n", __func__);
75                         return -ENOMEM;
76                 }
77
78                 esp_dump_var("esp_msg_level", NULL, &esp_msg_level, ESP_U32);
79
80 #ifdef ESP_ANDROID_LOGGER
81                 esp_dump_var("log_off", NULL, &log_off, ESP_U32);
82 #endif /* ESP_ANDROID_LOGGER */
83         } else {
84                 atomic_set(&epub->sip->state, SIP_PREPARE_BOOT);
85                 atomic_set(&epub->sip->tx_credits, 0);
86     }
87
88         epub->sip->to_host_seq = 0;
89
90 #ifdef TEST_MODE
91     if(sif_get_ate_config() != 0 &&  sif_get_ate_config() != 1 && sif_get_ate_config() !=6 )
92     {
93         esp_test_init(epub);
94         return -1;
95     }
96 #endif
97
98 #ifndef FPGA_DEBUG
99         ret = esp_download_fw(epub);
100 #ifdef ESP_USE_SPI
101         if(sif_get_ate_config() != 1)
102                 epub->enable_int = 1;
103 #endif  
104 #ifdef TEST_MODE
105         if(sif_get_ate_config() == 6)
106         {
107             sif_enable_irq(epub);
108             mdelay(500);
109             sif_disable_irq(epub);
110             mdelay(1000);
111             esp_test_init(epub);
112             return -1;
113         }
114 #endif
115         if (ret) {
116                 esp_dbg(ESP_DBG_ERROR, "download firmware failed\n");
117                 return ret;
118         }
119
120         esp_dbg(ESP_DBG_TRACE, "download firmware OK \n");
121 #else
122         sip_send_bootup(epub->sip);
123 #endif /* FPGA_DEBUG */
124
125         gl_bootup_cplx = &complete;
126         epub->wait_reset = 0;
127         sif_enable_irq(epub);
128         
129         if(epub->sdio_state == ESP_SDIO_STATE_SECOND_INIT || sif_get_ate_config() == 1){
130                 ret = sip_poll_bootup_event(epub->sip);
131         } else {
132                 ret = sip_poll_resetting_event(epub->sip);
133         if (ret == 0) {
134             sif_lock_bus(epub);
135             sif_interrupt_target(epub, 7);
136             sif_unlock_bus(epub);
137         }
138                 
139         }
140
141         gl_bootup_cplx = NULL;
142
143         if (sif_get_ate_config() == 1)
144                 ret = -EOPNOTSUPP;
145
146         return ret;
147 }
148
149 void
150 esp_dsr(struct esp_pub *epub)
151 {
152         sip_rx(epub);
153 }
154
155
156 struct esp_fw_hdr {
157         u8 magic;
158         u8 blocks;
159         u8 pad[2];
160         u32 entry_addr;
161 } __packed;
162
163 struct esp_fw_blk_hdr {
164         u32 load_addr;
165         u32 data_len;
166 } __packed;
167
168 #define ESP_FW_NAME1 "eagle_fw1.bin"
169 #define ESP_FW_NAME2 "eagle_fw2.bin"
170 #define ESP_FW_NAME3 "eagle_fw3.bin"
171
172 #ifndef FPGA_DEBUG
173 static int esp_download_fw(struct esp_pub * epub)
174 {
175 #ifndef HAS_FW
176         const struct firmware *fw_entry;
177 #endif /* !HAS_FW */
178         u8 * fw_buf = NULL;
179         u32 offset = 0;
180         int ret = 0;
181         u8 blocks;
182         struct esp_fw_hdr *fhdr;
183         struct esp_fw_blk_hdr *bhdr=NULL;
184         struct sip_cmd_bootup bootcmd;
185
186 #ifndef HAS_FW
187
188         if(sif_get_ate_config() == 1) {
189                 char * esp_fw_name = ESP_FW_NAME3;
190         } else {
191                 char * esp_fw_name = epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT ? ESP_FW_NAME1 : ESP_FW_NAME2;
192         }
193         ret = esp_request_firmware(&fw_entry, esp_fw_name, epub->dev);
194
195         if (ret)
196                 return ret;
197
198         fw_buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
199
200         esp_release_firmware(fw_entry);
201
202         if (fw_buf == NULL) {
203                 return -ENOMEM;
204         }
205 #else
206
207 #include "eagle_fw1.h"
208 #include "eagle_fw2.h"
209 #include "eagle_fw3.h"
210         if(sif_get_ate_config() == 1){
211             fw_buf =  &eagle_fw3[0];
212         } else {
213             fw_buf = epub->sdio_state == ESP_SDIO_STATE_FIRST_INIT ? &eagle_fw1[0] : &eagle_fw2[0];
214         }
215 #endif /* HAS_FW */
216
217         fhdr = (struct esp_fw_hdr *)fw_buf;
218
219         if (fhdr->magic != 0xE9) {
220                 esp_dbg(ESP_DBG_ERROR, "%s wrong magic! \n", __func__);
221                 goto _err;
222         }
223
224         blocks = fhdr->blocks;
225         offset += sizeof(struct esp_fw_hdr);
226
227         while (blocks) {
228
229                 bhdr = (struct esp_fw_blk_hdr *)(&fw_buf[offset]);
230                 offset += sizeof(struct esp_fw_blk_hdr);
231
232                 ret = sip_write_memory(epub->sip, bhdr->load_addr, &fw_buf[offset], bhdr->data_len);
233
234                 if (ret) {
235                         esp_dbg(ESP_DBG_ERROR, "%s Failed to write fw, err: %d\n", __func__, ret);
236                         goto _err;
237                 }
238
239                 blocks--;
240                 offset += bhdr->data_len;
241         }
242
243         /* TODO: last byte should be the checksum and skip checksum for now */
244
245         bootcmd.boot_addr = fhdr->entry_addr;
246         ret = sip_send_cmd(epub->sip, SIP_CMD_BOOTUP, sizeof(struct sip_cmd_bootup), &bootcmd);
247
248         if (ret)
249                 goto _err;
250
251 _err:
252 #ifndef HAS_FW
253         kfree(fw_buf);
254 #endif /* !HAS_FW */
255
256         return ret;
257
258 }
259 #endif /* !FPGA_DEBUG */
260
261
262
263