net:wireless:Support eswin usb wifi ECR6600U
[platform/kernel/linux-starfive.git] / drivers / net / wireless / eswin / usb / core.c
1 #include <linux/firmware.h>\r
2 #include "core.h"\r
3 #include "fw.h"\r
4 //#include "debug.h"\r
5 #include "ecrnx_platform.h"\r
6 #include "usb.h"\r
7 #include "ecrnx_rx.h"\r
8 #include "eswin_utils.h"\r
9 #include "ecrnx_defs.h"\r
10 #include "usb_host_interface.h"\r
11 \r
12 bool loopback;\r
13 module_param(loopback, bool, S_IRUSR | S_IWUSR);\r
14 MODULE_PARM_DESC(loopback, "HIF loopback");\r
15 \r
16 int power_save;\r
17 module_param(power_save, int, S_IRUSR | S_IWUSR);\r
18 MODULE_PARM_DESC(power_save, "Power Save(0: disable, 1:enable)");\r
19 \r
20 int disable_cqm = 0;\r
21 module_param(disable_cqm, int, S_IRUSR | S_IWUSR);\r
22 MODULE_PARM_DESC(disable_cqm, "Disable CQM (0: disable, 1:enable)");\r
23 \r
24 \r
25 int listen_interval = 0;\r
26 module_param(listen_interval, int, S_IRUSR | S_IWUSR);\r
27 MODULE_PARM_DESC(listen_interval, "Listen Interval");\r
28 \r
29 int bss_max_idle = 0;\r
30 module_param(bss_max_idle, int, S_IRUSR | S_IWUSR);\r
31 MODULE_PARM_DESC(bss_max_idle, "BSS Max Idle");\r
32 \r
33 \r
34 bool dl_fw = true;\r
35 module_param(dl_fw, bool, S_IRUSR | S_IWUSR);\r
36 MODULE_PARM_DESC(dl_fw, "download firmware");\r
37 \r
38 \r
39 #ifdef CONFIG_ECRNX_WIFO_CAIL\r
40 bool amt_mode;\r
41 module_param(amt_mode, bool, S_IRUSR | S_IWUSR);\r
42 MODULE_PARM_DESC(amt_mode, "calibrate mode");\r
43 #endif\r
44 \r
45 bool set_gain;\r
46 module_param(set_gain, bool, S_IRUSR | S_IWUSR);\r
47 MODULE_PARM_DESC(set_gain, "set gain delta");\r
48 \r
49 char *fw_name = NULL;\r
50 struct eswin *pEswin = NULL;\r
51 bool usb_status = false;\r
52 \r
53 module_param(fw_name, charp, S_IRUGO);\r
54 MODULE_PARM_DESC(fw_name, "Firmware file name");\r
55 \r
56 extern int ecrnx_data_cfm_callback(void *priv, void *host_id);\r
57 extern int ecrnx_msg_cfm_callback(void *priv, void *host_id);\r
58 static void eswin_core_register_work(struct work_struct *work)\r
59 {\r
60         int ret;\r
61         struct eswin *tr = container_of(work, struct eswin, register_work.work);\r
62 \r
63         ECRNX_DBG("%s entry, dl_fw = %d!!", __func__, dl_fw);\r
64 \r
65     if(dl_fw){\r
66         if (fw_name) {\r
67                 ECRNX_PRINT("fw file name: %s\n",fw_name);\r
68         }\r
69         else {\r
70                 fw_name = "ECR6600U_transport.bin";\r
71         }\r
72     }\r
73         \r
74         if (dl_fw  && eswin_fw_file_chech(tr)) {\r
75             ECRNX_DBG("%s entry, start fw download!!", __func__);\r
76         if( eswin_fw_file_download(tr) < 0)\r
77         {\r
78             release_firmware(tr->fw);\r
79             return;\r
80         } \r
81         release_firmware(tr->fw);\r
82                 dl_fw = false;\r
83                 ECRNX_DBG("%s entry, finish and stop fw download!!", __func__);\r
84                 schedule_delayed_work(&tr->register_work, msecs_to_jiffies(1000));\r
85                 return;\r
86         }\r
87 \r
88 #ifdef CONFIG_ECRNX_WIFO_CAIL\r
89         ECRNX_DBG("%s entry, amt_mode = %d!!", __func__, amt_mode);\r
90 #endif\r
91 \r
92         tr->rx_callback = ecrnx_rx_callback;\r
93         tr->data_cfm_callback = ecrnx_data_cfm_callback;\r
94         tr->msg_cfm_callback = ecrnx_msg_cfm_callback;\r
95         tr->ops->start(tr);\r
96         ret = ecrnx_platform_init(tr, &tr->umac_priv);\r
97         set_bit(ESWIN_FLAG_CORE_REGISTERED, &tr->dev_flags);\r
98 \r
99     ECRNX_DBG("%s exit!!", __func__);\r
100 \r
101     return;\r
102 }\r
103 bool register_status = false;\r
104 \r
105 int eswin_core_register(struct eswin *tr)\r
106 {\r
107     if(register_status == true)\r
108     {\r
109         return 0;\r
110     }\r
111     register_status = true;\r
112         ECRNX_DBG("%s entry!!", __func__);\r
113         schedule_delayed_work(&tr->register_work, msecs_to_jiffies(1));\r
114         return 0;\r
115 }\r
116 \r
117 void eswin_core_unregister(struct eswin *tr)\r
118 {\r
119         ECRNX_DBG("%s entry!!", __func__);\r
120     if(register_status == false)\r
121     {\r
122         return;\r
123     }\r
124     register_status = false;\r
125     msleep(20);\r
126         cancel_delayed_work_sync(&tr->register_work);\r
127 \r
128         if (!test_bit(ESWIN_FLAG_CORE_REGISTERED, &tr->dev_flags))\r
129                 return;\r
130     tr->rx_callback = NULL;\r
131     ecrnx_platform_deinit(tr->umac_priv);\r
132     eswin_core_destroy(tr);\r
133 }\r
134 \r
135 int usb_host_send(void *buff, int len, int flag)\r
136 {\r
137         int ret = -1;\r
138         struct eswin * tr= pEswin;\r
139         struct sk_buff *skb = NULL;\r
140 \r
141     //ECRNX_DBG("%s-%d: flag:0x%08x, mask:0x%x, desc:0x%x, type:0x%x \n", __func__, __LINE__, flag, FLAG_MSG_TYPE_MASK, TX_FLAG_TX_DESC, (flag & FLAG_MSG_TYPE_MASK));\r
142         if((u8_l)(flag & FLAG_MSG_TYPE_MASK) == TX_FLAG_TX_DESC)\r
143         {\r
144             skb = (struct sk_buff*)buff;\r
145         }\r
146         else\r
147         {\r
148         skb = dev_alloc_skb(len + sizeof(int)); //add the flag length (len + 4)\r
149 \r
150         memcpy(skb->data, (char*)&flag, sizeof(int));\r
151         memcpy((char*)skb->data + sizeof(int), buff, len); //put rx desc tag to skb\r
152         skb->len = len + sizeof(int);\r
153         }\r
154 \r
155         ECRNX_DBG("usb_host_send, skb:0x%08x, skb_len:%d, frame_len:%d, flag:0x%08x \n", skb, skb->len, len, flag);\r
156 \r
157         if (tr->ops->xmit) {\r
158                 ret = tr->ops->xmit(tr, skb);\r
159         } else {\r
160                 ECRNX_ERR("eswin_sdio_work error, ops->xmit is null\n");\r
161         }\r
162 \r
163         return ret;\r
164 }\r
165 \r
166 extern void ecrnx_send_handle_register(void * fn);\r
167 struct eswin * eswin_core_create(size_t priv_size, struct device *dev, struct usb_ops * ops)\r
168 {\r
169         struct eswin * tr;\r
170 \r
171         tr = (struct eswin *)kzalloc(sizeof(struct eswin) + priv_size, GFP_KERNEL);\r
172         if(!tr) {\r
173                 return NULL;\r
174         }\r
175 \r
176         pEswin = tr;\r
177 \r
178         tr->dev = dev;\r
179         tr->ops = ops;\r
180 \r
181         ecrnx_send_handle_register(usb_host_send);\r
182 \r
183     if(usb_status == false)\r
184     {\r
185         INIT_DELAYED_WORK(&tr->register_work, eswin_core_register_work);\r
186         usb_status = true;\r
187     }\r
188 \r
189         tr->state = ESWIN_STATE_INIT;\r
190 \r
191         ECRNX_DBG(" %s exit!!", __func__);\r
192         return tr;\r
193 \r
194 }\r
195 \r
196 void eswin_core_destroy(struct eswin *tr)\r
197 {\r
198         tr->state = ESWIN_STATE_CLOSEED;\r
199 \r
200         ECRNX_DBG("%s entry!!", __func__);\r
201     usb_status = false;\r
202 \r
203         //flush_workqueue(tr->workqueue);\r
204         //destroy_workqueue(tr->workqueue);\r
205     //TODO:\r
206         //eswin_mac_destroy(tr);\r
207 }\r
208 \r
209 \r
210 //MODULE_AUTHOR("Transa-Semi");\r
211 //MODULE_LICENSE("Dual BSD/GPL");\r
212 //MODULE_DESCRIPTION("Core module for Transa-Semi 802.11 WLAN SDIO driver");\r