]> Git Repo - esp-hosted.git/blob - esp_hosted_ng/host/esp_cmd.c
Fix 6.1 cfg80211_ops changes
[esp-hosted.git] / esp_hosted_ng / host / esp_cmd.c
1 /*
2  * Espressif Systems Wireless LAN device driver
3  *
4  * Copyright (C) 2015-2021 Espressif Systems (Shanghai) PTE LTD
5  *
6  * This software file (the "File") is distributed by Espressif Systems (Shanghai)
7  * PTE LTD under the terms of the GNU General Public License Version 2, June 1991
8  * (the "License").  You may use, redistribute and/or modify this File in
9  * accordance with the terms and conditions of the License, a copy of which
10  * is available by writing to the Free Software Foundation, Inc.,
11  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13  *
14  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
17  * this warranty disclaimer.
18  */
19
20 #include "esp_cmd.h"
21 #include "esp_api.h"
22 #include "esp_wpa_utils.h"
23 #include "esp.h"
24 #include "esp_cfg80211.h"
25 #include "esp_kernel_port.h"
26
27 #define PRINT_HEXDUMP(STR,ARG, ARG_LEN,level) \
28         print_hex_dump(KERN_INFO, STR, DUMP_PREFIX_ADDRESS, 16, 1, ARG, ARG_LEN, 1);
29
30 #define COMMAND_RESPONSE_TIMEOUT (5 * HZ)
31 u8 ap_bssid[MAC_ADDR_LEN];
32
33 int internal_scan_request(struct esp_wifi_device *priv, char* ssid,
34                 uint8_t channel, uint8_t is_blocking);
35
36 struct beacon_probe_fixed_params {
37         __le64 timestamp;
38         __le16 beacon_interval;
39         __le16 cap_info;
40 } __packed;
41
42 static struct command_node * get_free_cmd_node(struct esp_adapter *adapter)
43 {
44         struct command_node *cmd_node;
45
46         spin_lock_bh(&adapter->cmd_free_queue_lock);
47
48         if (list_empty(&adapter->cmd_free_queue)) {
49                 spin_unlock_bh(&adapter->cmd_free_queue_lock);
50                 printk(KERN_ERR "esp32: No free cmd node found\n");
51                 return NULL;
52         }
53         cmd_node = list_first_entry(&adapter->cmd_free_queue,
54                                     struct command_node, list);
55         list_del(&cmd_node->list);
56         spin_unlock_bh(&adapter->cmd_free_queue_lock);
57
58         cmd_node->cmd_skb = esp_alloc_skb(ESP_SIZE_OF_CMD_NODE);
59         if (!cmd_node->cmd_skb) {
60                 printk(KERN_ERR "esp32: No free cmd node skb found\n");
61         }
62
63         return cmd_node;
64 }
65
66 static inline void reset_cmd_node(struct esp_adapter *adapter, struct command_node * cmd_node)
67 {
68         cmd_node->cmd_code = 0;
69
70         spin_lock_bh(&adapter->cmd_lock);
71         if (cmd_node->resp_skb) {
72                 dev_kfree_skb_any(cmd_node->resp_skb);
73                 cmd_node->resp_skb = NULL;
74         }
75         spin_unlock_bh(&adapter->cmd_lock);
76 }
77
78 static void queue_cmd_node(struct esp_adapter *adapter,
79                 struct command_node * cmd_node, u8 flag_high_prio)
80 {
81         spin_lock_bh(&adapter->cmd_pending_queue_lock);
82
83         if (flag_high_prio)
84                 list_add_rcu(&cmd_node->list, &adapter->cmd_pending_queue);
85         else
86                 list_add_tail_rcu(&cmd_node->list, &adapter->cmd_pending_queue);
87
88         spin_unlock_bh(&adapter->cmd_pending_queue_lock);
89 }
90
91 static int decode_get_mac_addr(struct esp_wifi_device *priv,
92                 struct command_node *cmd_node)
93 {
94         int ret = 0;
95         struct cmd_config_mac_address *header;
96
97         if (!priv || !cmd_node ||
98             !cmd_node->resp_skb ||
99             !cmd_node->resp_skb->data) {
100                 printk(KERN_INFO "%s: invalid arg\n", __func__);
101                 return -1;
102         }
103
104         header = (struct cmd_config_mac_address *) (cmd_node->resp_skb->data);
105
106         if (header->header.cmd_status != CMD_RESPONSE_SUCCESS) {
107                 printk(KERN_INFO "esp32: Command failed\n");
108                 ret = -1;
109         }
110
111         if (priv)
112                 memcpy(priv->mac_address, header->mac_addr, MAC_ADDR_LEN);
113         else
114                 printk(KERN_ERR "esp32: %s: priv not updated\n", __func__);
115
116         return ret;
117 }
118
119
120 static int decode_common_resp(struct command_node *cmd_node)
121 {
122         int ret = 0;
123         struct command_header *cmd;
124
125
126         if (!cmd_node || !cmd_node->resp_skb || !cmd_node->resp_skb->data) {
127
128                 printk(KERN_INFO "esp32: %s Failed. cmd_node:%p \n", __func__, cmd_node);
129
130                 if (cmd_node)
131                         printk(KERN_INFO "esp32: %s: code: %u resp_skb:%p \n",
132                                 __func__, cmd_node->cmd_code, cmd_node->resp_skb);
133
134                 return -1;
135         }
136
137         cmd = (struct command_header *) (cmd_node->resp_skb->data);
138
139         if (cmd->cmd_status != CMD_RESPONSE_SUCCESS) {
140                 printk(KERN_INFO "esp32: [0x%x] Command failed\n", cmd_node->cmd_code);
141                 ret = -1;
142         }
143
144         return ret;
145 }
146
147 static void recycle_cmd_node(struct esp_adapter *adapter,
148                 struct command_node * cmd_node)
149 {
150         if (!adapter || !cmd_node)
151                 return;
152
153         reset_cmd_node(adapter, cmd_node);
154
155         spin_lock_bh(&adapter->cmd_free_queue_lock);
156         list_add_tail(&cmd_node->list, &adapter->cmd_free_queue);
157         spin_unlock_bh(&adapter->cmd_free_queue_lock);
158 }
159
160
161 static int wait_and_decode_cmd_resp(struct esp_wifi_device *priv,
162                 struct command_node *cmd_node)
163 {
164         struct esp_adapter *adapter = NULL;
165         int ret = 0;
166
167         if (!priv || !priv->adapter || !cmd_node) {
168                 printk(KERN_INFO "%s invalid params\n", __func__);
169                 if (priv->adapter) {
170                         adapter = priv->adapter;
171                         if (adapter && cmd_node)
172                                 recycle_cmd_node(adapter, cmd_node);
173                 }
174                 return -EINVAL;
175         }
176
177         adapter = priv->adapter;
178
179         /* wait for command response */
180         ret = wait_event_interruptible_timeout(adapter->wait_for_cmd_resp,
181                         adapter->cmd_resp == cmd_node->cmd_code, COMMAND_RESPONSE_TIMEOUT);
182
183         if (!test_bit(ESP_DRIVER_ACTIVE, &adapter->state_flags))
184                 return 0;
185
186         if (ret == 0) {
187                 printk(KERN_ERR "esp32: Command[%u] timed out\n", cmd_node->cmd_code);
188                 ret = -EINVAL;
189         } else {
190                 /*printk(KERN_DEBUG "Resp for command [%u]\n", cmd_node->cmd_code);*/
191                 ret = 0;
192         }
193
194         spin_lock_bh(&adapter->cmd_lock);
195         adapter->cur_cmd = NULL;
196         adapter->cmd_resp = 0;
197         spin_unlock_bh(&adapter->cmd_lock);
198
199         switch (cmd_node->cmd_code) {
200
201         case CMD_SCAN_REQUEST:
202                 if (ret == 0)
203                         ret = decode_common_resp(cmd_node);
204
205                 if (ret)
206                         ESP_MARK_SCAN_DONE(priv, false);
207                 break;
208
209         case CMD_INIT_INTERFACE:
210         case CMD_DEINIT_INTERFACE:
211         case CMD_STA_AUTH:
212         case CMD_STA_ASSOC:
213         case CMD_STA_CONNECT:
214         case CMD_STA_DISCONNECT:
215         case CMD_ADD_KEY:
216         case CMD_DEL_KEY:
217         case CMD_SET_DEFAULT_KEY:
218         case CMD_SET_IP_ADDR:
219         case CMD_SET_MCAST_MAC_ADDR:
220                 /* intentional fallthrough */
221                 if (ret == 0)
222                         ret = decode_common_resp(cmd_node);
223                 break;
224
225         case CMD_GET_MAC:
226                 if (ret == 0)
227                         ret = decode_get_mac_addr(priv, cmd_node);
228                 break;
229
230         default:
231                 printk(KERN_INFO "esp32: %s Resp for [0x%x] ignored\n",
232                                 __func__,cmd_node->cmd_code);
233                 ret = -EINVAL;
234                 break;
235         }
236
237         recycle_cmd_node(adapter, cmd_node);
238         return ret;
239 }
240
241 static void free_esp_cmd_pool(struct esp_adapter *adapter)
242 {
243         int i;
244         struct command_node * cmd_pool = NULL;
245
246         if (!adapter || !adapter->cmd_pool)
247                 return;
248
249         cmd_pool = adapter->cmd_pool;
250
251         for (i=0; i<ESP_NUM_OF_CMD_NODES; i++) {
252
253                 spin_lock_bh(&adapter->cmd_lock);
254                 if (cmd_pool[i].resp_skb) {
255                         dev_kfree_skb_any(cmd_pool[i].resp_skb);
256                         cmd_pool[i].resp_skb = NULL;
257                 }
258                 spin_unlock_bh(&adapter->cmd_lock);
259         }
260
261         kfree(adapter->cmd_pool);
262         adapter->cmd_pool = NULL;
263 }
264
265 static int alloc_esp_cmd_pool(struct esp_adapter *adapter)
266 {
267         u16 i;
268
269         struct command_node * cmd_pool = kcalloc(ESP_NUM_OF_CMD_NODES,
270                 sizeof(struct command_node), GFP_KERNEL);
271
272         if(!cmd_pool)
273                 return -ENOMEM;
274
275         adapter->cmd_pool = cmd_pool;
276
277         for (i=0; i<ESP_NUM_OF_CMD_NODES; i++) {
278
279                 cmd_pool[i].cmd_skb = NULL;
280                 cmd_pool[i].resp_skb = NULL;
281                 recycle_cmd_node(adapter, &cmd_pool[i]);
282         }
283
284         return 0;
285 }
286
287 static void esp_cmd_work(struct work_struct *work)
288 {
289         int ret;
290         struct command_node *cmd_node = NULL;
291         struct esp_adapter * adapter = NULL;
292         struct esp_payload_header *payload_header = NULL;
293
294         adapter = esp_get_adapter();
295
296         if (!adapter)
297                 return;
298
299         if (!test_bit(ESP_DRIVER_ACTIVE, &adapter->state_flags))
300                 return;
301
302         synchronize_rcu();
303         spin_lock_bh(&adapter->cmd_lock);
304         if (adapter->cur_cmd) {
305                 /* Busy in another command */
306                 /*printk(KERN_DEBUG "esp32: Busy in another cmd execution\n");*/
307                 spin_unlock_bh(&adapter->cmd_lock);
308                 return;
309         }
310
311         spin_lock_bh(&adapter->cmd_pending_queue_lock);
312
313         if (list_empty(&adapter->cmd_pending_queue)) {
314                 /* No command to process */
315                 /*printk(KERN_DEBUG "esp32: No more command in queue.\n");*/
316                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
317                 spin_unlock_bh(&adapter->cmd_lock);
318                 return;
319         }
320
321         cmd_node = list_first_entry(&adapter->cmd_pending_queue,
322                                     struct command_node, list);
323         if (! cmd_node) {
324                 printk(KERN_DEBUG "esp32: cmd node NULL\n");
325                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
326                 spin_unlock_bh(&adapter->cmd_lock);
327                 return;
328         }
329         /*printk(KERN_DEBUG "esp32: Processing Command [0x%X]\n", cmd_node->cmd_code);*/
330
331         list_del(&cmd_node->list);
332
333         if (! cmd_node->cmd_skb) {
334                 printk(KERN_DEBUG "cmd_node->cmd_skb NULL \n");
335                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
336                 spin_unlock_bh(&adapter->cmd_lock);
337                 return;
338         }
339
340         /* Set as current cmd */
341         adapter->cur_cmd = cmd_node;
342
343         adapter->cmd_resp = 0;
344
345         payload_header = (struct esp_payload_header *)cmd_node->cmd_skb->data;
346         if (adapter->capabilities & ESP_CHECKSUM_ENABLED)
347                 payload_header->checksum = cpu_to_le16(compute_checksum(cmd_node->cmd_skb->data,
348                                         payload_header->len+payload_header->offset));
349
350         ret = esp_send_packet(adapter, cmd_node->cmd_skb);
351         spin_unlock_bh(&adapter->cmd_lock);
352
353         if (ret) {
354                 printk(KERN_ERR "esp32: %s: Failed to send command [0x%X] \n",
355                         __func__, cmd_node->cmd_code);
356                 adapter->cur_cmd = NULL;
357                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
358                 recycle_cmd_node(adapter, cmd_node);
359                 return;
360         }
361
362         if (!list_empty(&adapter->cmd_pending_queue)) {
363                 /*printk(KERN_DEBUG "Ym2: Pending cmds, queue work again\n");*/
364                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
365                 queue_work(adapter->cmd_wq, &adapter->cmd_work);
366                 return;
367         }
368         spin_unlock_bh(&adapter->cmd_pending_queue_lock);
369 }
370
371 static int create_cmd_wq(struct esp_adapter *adapter)
372 {
373         adapter->cmd_wq = alloc_workqueue("ESP_CMD_WORK_QUEUE", 0, 0);
374
375         RET_ON_FAIL(!adapter->cmd_wq);
376
377         INIT_WORK(&adapter->cmd_work, esp_cmd_work);
378
379         return 0;
380 }
381
382 static void destroy_cmd_wq(struct esp_adapter *adapter)
383 {
384         if (adapter->cmd_wq) {
385                 flush_scheduled_work();
386                 destroy_workqueue(adapter->cmd_wq);
387                 adapter->cmd_wq = NULL;
388         }
389 }
390
391 struct command_node * prepare_command_request(struct esp_adapter *adapter, u8 cmd_code, u16 len)
392 {
393         struct command_header *cmd;
394         struct esp_payload_header *payload_header;
395         struct command_node *node = NULL;
396
397         if (!adapter) {
398                 printk(KERN_INFO "%s:%u null adapter\n",__func__,__LINE__);
399                 return NULL;
400         }
401
402         if (!cmd_code || cmd_code >= CMD_MAX) {
403                 printk(KERN_ERR "esp32: %s: unsupported command code\n", __func__);
404                 return NULL;
405         }
406
407         node = get_free_cmd_node(adapter);
408
409         if (!node || !node->cmd_skb) {
410                 printk(KERN_ERR "esp32: %s: Failed to get new free cmd node\n", __func__);
411                 return NULL;
412         }
413
414         node->cmd_code = cmd_code;
415
416         len += sizeof(struct esp_payload_header);
417
418         payload_header = (struct esp_payload_header *)skb_put(node->cmd_skb, len);
419         memset(payload_header, 0, len);
420
421         payload_header->if_type = ESP_STA_IF;
422         payload_header->len = cpu_to_le16(len - sizeof(struct esp_payload_header));
423         payload_header->offset = cpu_to_le16(sizeof(struct esp_payload_header));
424         payload_header->packet_type = PACKET_TYPE_COMMAND_REQUEST;
425
426         cmd = (struct command_header *) (node->cmd_skb->data + payload_header->offset);
427         cmd->cmd_code = cmd_code;
428
429 /*      payload_header->checksum = cpu_to_le16(compute_checksum(skb->data, len));*/
430
431         return node;
432 }
433
434 int process_cmd_resp(struct esp_adapter *adapter, struct sk_buff *skb)
435 {
436         if (!skb || !adapter) {
437                 printk(KERN_ERR "esp32: CMD resp: invalid!\n");
438
439                 if (skb)
440                         dev_kfree_skb_any(skb);
441
442                 return -1;
443         }
444
445         if (!adapter->cur_cmd) {
446                 printk(KERN_ERR "esp32: Command response not expected\n");
447                 dev_kfree_skb_any(skb);
448                 return -1;
449         }
450
451         spin_lock_bh(&adapter->cmd_lock);
452         adapter->cur_cmd->resp_skb = skb;
453         adapter->cmd_resp = adapter->cur_cmd->cmd_code;
454         spin_unlock_bh(&adapter->cmd_lock);
455
456
457         wake_up_interruptible(&adapter->wait_for_cmd_resp);
458         queue_work(adapter->cmd_wq, &adapter->cmd_work);
459
460         return 0;
461 }
462
463 static void process_scan_result_event(struct esp_wifi_device *priv,
464                 struct scan_event *scan_evt)
465 {
466         struct cfg80211_bss *bss = NULL;
467         struct beacon_probe_fixed_params *fixed_params = NULL;
468         struct ieee80211_channel *chan = NULL;
469         u8 *ie_buf = NULL;
470         u64 timestamp;
471         u16 beacon_interval;
472         u16 cap_info;
473         u32 ie_len;
474         int freq;
475
476         if (!priv || !scan_evt) {
477                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
478                 return;
479         }
480
481         /*if (!priv->scan_in_progress) {
482                 return;
483         }*/
484
485         /* End of scan; notify cfg80211 */
486         if (scan_evt->header.status == 0) {
487
488                 ESP_MARK_SCAN_DONE(priv, false);
489                 if (priv->waiting_for_scan_done) {
490                         priv->waiting_for_scan_done = false;
491                         wake_up_interruptible(&priv->wait_for_scan_completion);
492                 }
493                 return;
494         }
495
496         ie_buf = (u8 *) scan_evt->frame;
497         ie_len = le16_to_cpu(scan_evt->frame_len);
498
499         fixed_params = (struct beacon_probe_fixed_params *) ie_buf;
500
501         timestamp = le64_to_cpu(fixed_params->timestamp);
502         beacon_interval = le16_to_cpu(fixed_params->beacon_interval);
503         cap_info = le16_to_cpu(fixed_params->cap_info);
504
505         freq = ieee80211_channel_to_frequency(scan_evt->channel, NL80211_BAND_2GHZ);
506         chan = ieee80211_get_channel(priv->adapter->wiphy, freq);
507
508         ie_buf += sizeof(struct beacon_probe_fixed_params);
509         ie_len -= sizeof(struct beacon_probe_fixed_params);
510
511         if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
512                 bss = CFG80211_INFORM_BSS(priv->adapter->wiphy, chan,
513                                 scan_evt->bssid, timestamp,
514                                 cap_info, beacon_interval, ie_buf, ie_len,
515                                 le32_to_cpu(scan_evt->rssi), GFP_ATOMIC);
516
517                 if (bss)
518                         cfg80211_put_bss(priv->adapter->wiphy, bss);
519         } else {
520                 printk(KERN_INFO "Scan report: Skip invalid or disabled channel\n");
521         }
522 }
523
524 static void process_auth_event(struct esp_wifi_device * priv,
525                 struct auth_event *event)
526 {
527         if (!priv || !event) {
528                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
529                 return;
530         }
531
532 #if 0
533         print_hex_dump(KERN_INFO, "Auth frame: ", DUMP_PREFIX_ADDRESS, 16, 1,
534                         event->frame, event->frame_len, 1);
535 #endif
536
537         cfg80211_rx_mlme_mgmt(priv->ndev, event->frame, event->frame_len);
538
539 }
540
541 static void process_disconnect_event(struct esp_wifi_device *priv,
542                 struct disconnect_event *event)
543 {
544         if (!priv || !event) {
545                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
546                 return;
547         }
548
549         printk(KERN_INFO "Disconnect event for ssid %s [reason:%d]\n",
550                         event->ssid, event->reason);
551
552         esp_mark_disconnect(priv, event->reason, true);
553 }
554
555 static void process_assoc_event(struct esp_wifi_device *priv,
556                 struct assoc_event *event)
557 {
558         u8 mac[6];
559 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
560         // cd47c0f57ae6607cfa3d161e341cbdd283bc444f
561         struct cfg80211_rx_assoc_resp resp = {
562                 .uapsd_queues = 0,
563         };
564 #endif
565
566         if (!priv || !event) {
567                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
568                 return;
569         }
570
571         printk(KERN_INFO "Connection status: %d\n", event->header.status);
572
573         memcpy(mac, event->bssid, MAC_ADDR_LEN);
574
575 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
576         // cd47c0f57ae6607cfa3d161e341cbdd283bc444f
577         resp.links[0].bss = priv->bss;
578         resp.buf = (u8 *)event->frame;
579         resp.len =  event->frame_len;
580         resp.req_ies = priv->assoc_req_ie;
581         resp.req_ies_len = priv->assoc_req_ie_len;
582         cfg80211_rx_assoc_resp(priv->ndev, &resp);
583
584 #else
585         cfg80211_rx_assoc_resp(priv->ndev, priv->bss, event->frame, event->frame_len,
586                         0, priv->assoc_req_ie, priv->assoc_req_ie_len);
587 #endif
588
589 #if 0
590         if (priv->bss) {
591                 cfg80211_connect_bss(priv->ndev, mac, priv->bss, NULL, 0, NULL, 0,
592                                 0, GFP_KERNEL, NL80211_TIMEOUT_UNSPECIFIED);
593         } else {
594                 cfg80211_connect_result(priv->ndev, mac, NULL, 0, NULL, 0,
595                                 0, GFP_KERNEL);
596         }
597 #endif
598
599         esp_port_open(priv);
600 }
601
602 int process_cmd_event(struct esp_wifi_device *priv, struct sk_buff *skb)
603 {
604         struct event_header *header;
605
606         if (!skb || !priv) {
607                 printk(KERN_ERR "esp32: CMD evnt: invalid!\n");
608                 return -1;
609         }
610
611         header = (struct event_header *) (skb->data);
612
613         switch (header->event_code) {
614
615         case EVENT_SCAN_RESULT:
616                 process_scan_result_event(priv,
617                                 (struct scan_event *)(skb->data));
618                 break;
619
620         case EVENT_ASSOC_RX:
621                 process_assoc_event(priv,
622                                 (struct assoc_event *)(skb->data));
623                 break;
624
625         case EVENT_STA_DISCONNECT:
626                 process_disconnect_event(priv,
627                                 (struct disconnect_event *)(skb->data));
628                 break;
629
630         case EVENT_AUTH_RX:
631                 process_auth_event(priv, (struct auth_event *)(skb->data));
632                 break;
633
634         default:
635                 printk(KERN_INFO "%s:%u unhandled event[%u]\n",
636                                 __func__, __LINE__, header->event_code);
637                 break;
638         }
639
640         return 0;
641 }
642
643 int cmd_set_mcast_mac_list(struct esp_wifi_device *priv, struct multicast_list *list)
644 {
645         struct command_node *cmd_node = NULL;
646         struct cmd_set_mcast_mac_addr *cmd_mcast_mac_list;
647
648         if (!priv || !priv->adapter) {
649                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
650                 return -EINVAL;
651         }
652
653         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags))
654                 return 0;
655
656         cmd_node = prepare_command_request(priv->adapter, CMD_SET_MCAST_MAC_ADDR,
657                         sizeof(struct cmd_set_mcast_mac_addr));
658
659         if (!cmd_node) {
660                 printk(KERN_ERR "Failed to get command node\n");
661                 return -ENOMEM;
662         }
663
664         cmd_mcast_mac_list = (struct cmd_set_mcast_mac_addr *)
665                 (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
666
667         cmd_mcast_mac_list->count = list->addr_count;
668         memcpy(cmd_mcast_mac_list->mcast_addr, list->mcast_addr,
669                         sizeof(cmd_mcast_mac_list->mcast_addr));
670
671         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
672         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
673
674         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
675         return 0;
676 }
677
678 int cmd_set_ip_address(struct esp_wifi_device *priv, u32 ip)
679 {
680         struct command_node *cmd_node = NULL;
681         struct cmd_set_ip_addr *cmd_set_ip;
682
683         if (!priv || !priv->adapter) {
684                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
685                 return -EINVAL;
686         }
687
688         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags))
689                 return 0;
690
691         cmd_node = prepare_command_request(priv->adapter, CMD_SET_IP_ADDR,
692                         sizeof(struct cmd_set_ip_addr));
693
694         if (!cmd_node) {
695                 printk(KERN_ERR "Failed to get command node\n");
696                 return -ENOMEM;
697         }
698
699         cmd_set_ip = (struct cmd_set_ip_addr *)
700                 (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
701
702         cmd_set_ip->ip = cpu_to_le32(ip);
703
704         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
705         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
706
707         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
708
709         return 0;
710 }
711
712 int cmd_disconnect_request(struct esp_wifi_device *priv, u16 reason_code)
713 {
714         struct command_node *cmd_node = NULL;
715         struct cmd_sta_disconnect *cmd_disconnect;
716
717         if (!priv || !priv->adapter) {
718                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
719                 return -EINVAL;
720         }
721
722         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags))
723                 return 0;
724
725         cmd_node = prepare_command_request(priv->adapter, CMD_STA_DISCONNECT,
726                         sizeof(struct cmd_sta_disconnect));
727
728         if (!cmd_node) {
729                 printk(KERN_ERR "Failed to get command node\n");
730                 return -ENOMEM;
731         }
732
733         cmd_disconnect = (struct cmd_sta_disconnect *)
734                 (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
735
736         cmd_disconnect->reason_code = reason_code;
737
738         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
739         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
740
741         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
742
743         return 0;
744 }
745
746 #if 0
747 int cmd_connect_request(struct esp_wifi_device *priv,
748                 struct cfg80211_connect_params *params)
749 {
750         u16 cmd_len;
751         struct command_node *cmd_node = NULL;
752         struct cmd_sta_connect *cmd;
753         struct ieee80211_channel *chan;
754         struct cfg80211_bss *bss;
755         struct esp_adapter *adapter = NULL;
756         u8 retry = 2;
757
758         if (!priv || !params || !priv->adapter) {
759                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
760                 return -EINVAL;
761         }
762
763         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
764                 printk(KERN_ERR "%s:%u cleanup in progress, return failure", __func__, __LINE__);
765                 return -EFAULT;
766         }
767
768         adapter = priv->adapter;
769
770         cmd_len = sizeof(struct cmd_sta_connect) + params->ie_len;
771
772         cmd_node = prepare_command_request(adapter, CMD_STA_CONNECT, cmd_len);
773         if (!cmd_node) {
774                 printk(KERN_ERR "Failed to get command node\n");
775                 return -ENOMEM;
776         }
777         cmd = (struct cmd_sta_connect *) (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
778
779         if (params->ssid_len)
780                 memcpy(cmd->ssid, params->ssid, MAX_SSID_LEN);
781         else
782                 printk(KERN_ERR "%s: No ssid\n", __func__);
783
784         if (params->bssid) {
785                 memcpy(ap_bssid, params->bssid, MAC_ADDR_LEN);
786                 memcpy(cmd->bssid, params->bssid, MAC_ADDR_LEN);
787         }
788
789         if (params->channel) {
790                 chan = params->channel;
791                 cmd->channel = chan->hw_value;
792         }
793
794         if (params->ie_len) {
795                 cmd->assoc_ie_len = cpu_to_le16(params->ie_len);
796                 memcpy(cmd->assoc_ie, params->ie, params->ie_len);
797         }
798
799         if (params->privacy)
800                 cmd->is_auth_open = 0;
801         else
802                 cmd->is_auth_open = 1;
803
804         printk(KERN_INFO "Connection request: %s %pM %d\n",
805                         cmd->ssid, params->bssid, cmd->channel);
806
807         do {
808                 bss = cfg80211_get_bss(adapter->wiphy, params->channel, params->bssid,
809                                 params->ssid, params->ssid_len, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
810
811                 if (bss) {
812                         break;
813                 } else {
814                         printk(KERN_INFO "No BSS in the list.. scanning..\n");
815                         internal_scan_request(priv, cmd->ssid, cmd->channel, true);
816                 }
817
818                 retry--;
819         } while (retry);
820
821         if (retry) {
822                 queue_cmd_node(adapter, cmd_node, ESP_CMD_DFLT_PRIO);
823                 queue_work(adapter->cmd_wq, &adapter->cmd_work);
824
825                 RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
826         } else {
827                 printk(KERN_INFO "Failed to find %s\n", cmd->ssid);
828                 return -EFAULT;
829         }
830
831         return 0;
832 }
833 #endif
834
835
836 int cmd_assoc_request(struct esp_wifi_device *priv,
837                 struct cfg80211_assoc_request *req)
838 {
839         struct command_node *cmd_node = NULL;
840         struct cmd_sta_assoc *cmd;
841         struct cfg80211_bss *bss;
842         struct esp_adapter *adapter = NULL;
843         u16 cmd_len;
844
845         if (!priv || !req || !req->bss || !priv->adapter) {
846                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
847                 return -EINVAL;
848         }
849
850         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
851                 printk(KERN_ERR "%s:%u cleanup in progress, return failure", __func__, __LINE__);
852                 return -EFAULT;
853         }
854
855         bss = req->bss;
856         adapter = priv->adapter;
857
858         cmd_len = sizeof(struct cmd_sta_assoc) + req->ie_len;
859
860         cmd_node = prepare_command_request(adapter, CMD_STA_ASSOC, cmd_len);
861
862         if (!cmd_node) {
863                 printk(KERN_ERR "Failed to get command node\n");
864                 return -ENOMEM;
865         }
866
867         cmd = (struct cmd_sta_assoc *) (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
868
869         cmd->assoc_ie_len = req->ie_len;
870         memcpy(cmd->assoc_ie, req->ie, req->ie_len);
871
872         /* Make a copy of assoc req IEs */
873         if (priv->assoc_req_ie) {
874                 kfree(priv->assoc_req_ie);
875                 priv->assoc_req_ie = NULL;
876         }
877
878         priv->assoc_req_ie = kmemdup(req->ie, req->ie_len, GFP_ATOMIC);
879
880         if (!priv->assoc_req_ie) {
881                 printk(KERN_ERR "Failed to allocate buffer for assoc request IEs \n");
882                 return -ENOMEM;
883         }
884
885         priv->assoc_req_ie_len = req->ie_len;
886
887         printk(KERN_INFO "Association request: %pM %d %d\n",
888                         bss->bssid, bss->channel->hw_value, cmd->assoc_ie_len);
889
890         queue_cmd_node(adapter, cmd_node, ESP_CMD_DFLT_PRIO);
891         queue_work(adapter->cmd_wq, &adapter->cmd_work);
892
893         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
894
895         return 0;
896 }
897
898 int cmd_auth_request(struct esp_wifi_device *priv,
899                 struct cfg80211_auth_request *req)
900 {
901         struct command_node *cmd_node = NULL;
902         struct cmd_sta_auth *cmd;
903         struct cfg80211_bss *bss;
904         /*struct cfg80211_bss *bss1;*/
905         struct esp_adapter *adapter = NULL;
906         u16 cmd_len;
907         /* u8 retry = 2; */
908
909         if (!priv || !req || !req->bss || !priv->adapter) {
910                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
911                 return -EINVAL;
912         }
913
914         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
915                 printk(KERN_ERR "%s:%u cleanup in progress, return failure", __func__, __LINE__);
916                 return -EFAULT;
917         }
918
919         bss = req->bss;
920
921         priv->bss = req->bss;
922
923         adapter = priv->adapter;
924
925         cmd_len = sizeof(struct cmd_sta_auth) + req->auth_data_len;
926
927         cmd_node = prepare_command_request(adapter, CMD_STA_AUTH, cmd_len);
928
929         if (!cmd_node) {
930                 printk(KERN_ERR "Failed to get command node\n");
931                 return -ENOMEM;
932         }
933         cmd = (struct cmd_sta_auth *) (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
934
935         memcpy(cmd->bssid, bss->bssid, MAC_ADDR_LEN);
936         cmd->channel = bss->channel->hw_value;
937         cmd->auth_type = req->auth_type;
938         cmd->auth_data_len = req->auth_data_len;
939         memcpy(cmd->auth_data, req->auth_data, req->auth_data_len);
940
941         printk(KERN_INFO "Authentication request: %pM %d %d %d %d\n",
942                         cmd->bssid, cmd->channel, cmd->auth_type, cmd->auth_data_len,
943                         (u32) req->ie_len);
944 #if 0
945         do {
946                 bss1 = cfg80211_get_bss(adapter->wiphy, bss->channel, bss->bssid,
947                                 NULL, 0, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
948
949                 if (bss1) {
950                         break;
951                 } else {
952                         printk(KERN_INFO "No BSS in the list.. scanning..\n");
953                         internal_scan_request(priv, cmd->ssid, cmd->channel, true);
954                 }
955
956                 retry--;
957         } while (retry);
958 #endif
959         queue_cmd_node(adapter, cmd_node, ESP_CMD_DFLT_PRIO);
960         queue_work(adapter->cmd_wq, &adapter->cmd_work);
961
962         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
963
964         return 0;
965 }
966
967 int cmd_set_default_key(struct esp_wifi_device *priv, u8 key_index)
968 {
969         u16 cmd_len;
970         struct command_node *cmd_node = NULL;
971         struct cmd_key_operation *cmd;
972         struct wifi_sec_key * key = NULL;
973
974         if (!priv || !priv->adapter) {
975                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
976                 return -EINVAL;
977         }
978
979 #if 0
980         if (key_index > ESP_MAX_KEY_INDEX) {
981                 printk(KERN_ERR "invalid key index[%u] > max[%u]\n",
982                                 key_index, ESP_MAX_KEY_INDEX);
983                 return -EINVAL;
984         }
985 #endif
986         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
987                 printk(KERN_ERR "%s:%u cleanup in progress, return", __func__, __LINE__);
988                 return 0;
989         }
990
991         cmd_len = sizeof(struct cmd_key_operation);
992
993         /* get new cmd node */
994         cmd_node = prepare_command_request(priv->adapter, CMD_SET_DEFAULT_KEY, cmd_len);
995         if (!cmd_node) {
996                 printk(KERN_ERR "Failed to get command node\n");
997                 return -ENOMEM;
998         }
999
1000         /* cmd specific update */
1001         cmd = (struct cmd_key_operation *) (cmd_node->cmd_skb->data +
1002                         sizeof(struct esp_payload_header));
1003         key = &cmd->key;
1004
1005         key->index = key_index;
1006         key->set_cur = 1;
1007
1008         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1009         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1010
1011         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1012
1013         return 0;
1014 }
1015
1016 int cmd_del_key(struct esp_wifi_device *priv, u8 key_index, bool pairwise,
1017                 const u8 *mac_addr)
1018 {
1019         u16 cmd_len;
1020         struct command_node *cmd_node = NULL;
1021         struct cmd_key_operation *cmd;
1022         struct wifi_sec_key * key = NULL;
1023         const u8 *mac = NULL;
1024         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1025
1026         if (!priv || !priv->adapter) {
1027                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1028                 return -EINVAL;
1029         }
1030
1031         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags))
1032                 return 0;
1033
1034 #if 0
1035         if (key_index > ESP_MAX_KEY_INDEX) {
1036                 printk(KERN_ERR "invalid key index[%u] > max[%u]\n",
1037                                 key_index, ESP_MAX_KEY_INDEX);
1038                 return -EINVAL;
1039         }
1040 #endif
1041
1042         mac = pairwise ? mac_addr : bc_mac;
1043
1044         cmd_len = sizeof(struct cmd_key_operation);
1045
1046         /* get new cmd node */
1047         cmd_node = prepare_command_request(priv->adapter, CMD_DEL_KEY, cmd_len);
1048         if (!cmd_node) {
1049                 printk(KERN_ERR "Failed to get command node\n");
1050                 return -ENOMEM;
1051         }
1052
1053         /* cmd specific update */
1054         cmd = (struct cmd_key_operation *) (cmd_node->cmd_skb->data +
1055                         sizeof(struct esp_payload_header));
1056         key = &cmd->key;
1057
1058         if (mac && !is_multicast_ether_addr(mac))
1059                 memcpy((char *)&key->mac_addr, (void *)mac, MAC_ADDR_LEN);
1060
1061         key->index = key_index;
1062         key->del = 1;
1063
1064         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1065         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1066
1067         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1068
1069         return 0;
1070 }
1071
1072 int cmd_add_key(struct esp_wifi_device *priv, u8 key_index, bool pairwise,
1073                 const u8 *mac_addr, struct key_params *params)
1074 {
1075         u16 cmd_len;
1076         struct command_node *cmd_node = NULL;
1077         struct cmd_key_operation *cmd;
1078         struct wifi_sec_key * key = NULL;
1079         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1080         const u8 *mac = NULL;
1081
1082 #if 0
1083         printk(KERN_INFO "%s:%u key_idx: %u pairwise: %u params->key_len: %u \nparams->seq_len:%u params->mode: 0x%x \nparams->cipher: 0x%x\n",
1084       __func__, __LINE__,
1085       key_index, pairwise, params->key_len, params->seq_len, params->mode, params->cipher);
1086 #endif
1087         if (!priv || !priv->adapter || !params ||
1088             !params->key || !params->key_len || !params->seq_len) {
1089                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1090                 return -EINVAL;
1091         }
1092
1093 #if 0
1094         if (key_index > ESP_MAX_KEY_INDEX) {
1095                 printk(KERN_ERR "invalid key index[%u] > max[%u]\n",
1096                                 key_index, ESP_MAX_KEY_INDEX);
1097                 return -EINVAL;
1098         }
1099 #endif
1100
1101         if (params->key_len > sizeof(key->data)) {
1102                 printk(KERN_ERR "Too long key length (%u)\n", params->key_len);
1103                 return -EINVAL;
1104         }
1105
1106         if (params->seq_len > sizeof(key->seq)) {
1107                 printk(KERN_ERR "Too long key seq length (%u)\n", params->seq_len);
1108                 return -EINVAL;
1109         }
1110
1111         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
1112                 printk(KERN_ERR "%s:%u cleanup in progress, return failure", __func__, __LINE__);
1113                 return -EFAULT;
1114         }
1115
1116         mac = pairwise ? mac_addr : bc_mac;
1117         if (mac) {
1118 #if 0
1119                 print_hex_dump(KERN_INFO, "mac: ", DUMP_PREFIX_ADDRESS, 16, 1,
1120                                 mac, MAC_ADDR_LEN, 1);
1121 #endif
1122         }
1123
1124         cmd_len = sizeof(struct cmd_key_operation);
1125
1126         cmd_node = prepare_command_request(priv->adapter, CMD_ADD_KEY, cmd_len);
1127         if (!cmd_node) {
1128                 printk(KERN_ERR "Failed to get command node\n");
1129                 return -ENOMEM;
1130         }
1131
1132         cmd = (struct cmd_key_operation *) (cmd_node->cmd_skb->data +
1133                         sizeof(struct esp_payload_header));
1134         key = &cmd->key;
1135
1136         if (mac && !is_multicast_ether_addr(mac))
1137                 memcpy((char *)&key->mac_addr, (void *)mac, MAC_ADDR_LEN);
1138
1139         key->index = key_index;
1140
1141         key->len = params->key_len;
1142         if (params->key && key->len)
1143                 memcpy(key->data, params->key, key->len);
1144
1145         key->seq_len = params->seq_len;
1146         if (params->seq && key->seq_len)
1147                 memcpy(key->seq, params->seq, key->seq_len);
1148
1149         key->algo = wpa_cipher_to_alg(params->cipher);
1150 #if 0
1151         if (key->algo == WIFI_WPA_ALG_NONE) {
1152                 printk(KERN_INFO "CIPHER NONE does not use pairwise keys");
1153                 return 0;
1154         }
1155 #endif
1156
1157 #if 0
1158         printk(KERN_ERR "%s:%u algo: %u idx: %u seq_len: %u len:%u \n", __func__, __LINE__,
1159                         key->algo, key->index, key->seq_len, key->len);
1160         PRINT_HEXDUMP("mac", key->mac_addr, 6, ESP_LOG_INFO);
1161         PRINT_HEXDUMP("seq", key->seq, key->seq_len, ESP_LOG_INFO);
1162         PRINT_HEXDUMP("key_data", key->data, key->len, ESP_LOG_INFO);
1163 #endif
1164
1165         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1166         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1167
1168         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1169
1170         return 0;
1171 }
1172
1173 int cmd_init_interface(struct esp_wifi_device *priv)
1174 {
1175         u16 cmd_len;
1176         struct command_node *cmd_node = NULL;
1177
1178         if (!priv || !priv->adapter) {
1179                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1180                 return -EINVAL;
1181         }
1182
1183         cmd_len = sizeof(struct command_header);
1184
1185         cmd_node = prepare_command_request(priv->adapter, CMD_INIT_INTERFACE, cmd_len);
1186
1187         if (!cmd_node) {
1188                 printk(KERN_ERR "esp32: Failed to get command node\n");
1189                 return -ENOMEM;
1190         }
1191
1192         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1193         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1194
1195         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1196
1197         return 0;
1198 }
1199
1200 int cmd_deinit_interface(struct esp_wifi_device *priv)
1201 {
1202         u16 cmd_len;
1203         struct command_node *cmd_node = NULL;
1204
1205         if (!priv || !priv->adapter)
1206                 return -EINVAL;
1207
1208         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
1209                 printk(KERN_ERR "%s:%u cleanup in progress, return\n", __func__, __LINE__);
1210                 return 0;
1211         }
1212
1213         cmd_len = sizeof(struct command_header);
1214
1215         cmd_node = prepare_command_request(priv->adapter, CMD_DEINIT_INTERFACE, cmd_len);
1216
1217         if (!cmd_node) {
1218                 printk(KERN_ERR "esp32: Failed to get command node\n");
1219                 return -ENOMEM;
1220         }
1221
1222         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1223         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1224
1225         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1226
1227         return 0;
1228 }
1229
1230 int internal_scan_request(struct esp_wifi_device *priv, char* ssid,
1231                 uint8_t channel, uint8_t is_blocking)
1232 {
1233         int ret = 0;
1234         u16 cmd_len;
1235         struct command_node *cmd_node = NULL;
1236         struct scan_request *scan_req;
1237
1238         if (!priv || !priv->adapter) {
1239                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1240                 return -EINVAL;
1241         }
1242
1243         if (priv->scan_in_progress) {
1244                 printk(KERN_ERR "Scan in progress.. return\n");
1245                 return -EBUSY;
1246         }
1247
1248         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
1249                 printk(KERN_ERR "%s:%u cleanup in progress, return", __func__, __LINE__);
1250                 return -EBUSY;
1251         }
1252
1253         cmd_len = sizeof(struct scan_request);
1254
1255         cmd_node = prepare_command_request(priv->adapter, CMD_SCAN_REQUEST, cmd_len);
1256
1257         if (!cmd_node) {
1258                 printk(KERN_ERR "esp32: Failed to get command node\n");
1259                 return -ENOMEM;
1260         }
1261
1262         scan_req = (struct scan_request *) (cmd_node->cmd_skb->data +
1263                         sizeof(struct esp_payload_header));
1264
1265         if (ssid) {
1266                 memcpy(scan_req->ssid, ssid, MAX_SSID_LEN);
1267         }
1268
1269         scan_req->channel = channel;
1270
1271         priv->scan_in_progress = true;
1272
1273         if (is_blocking)
1274                 priv->waiting_for_scan_done = true;
1275
1276         /* Enqueue command */
1277         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1278         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1279
1280         ret = wait_and_decode_cmd_resp(priv, cmd_node);
1281
1282         if (!ret && is_blocking) {
1283                 /* Wait for scan done */
1284                 wait_event_interruptible_timeout(priv->wait_for_scan_completion,
1285                                 priv->waiting_for_scan_done != true, COMMAND_RESPONSE_TIMEOUT);
1286         }
1287
1288         return ret;
1289 }
1290
1291 int cmd_scan_request(struct esp_wifi_device *priv, struct cfg80211_scan_request *request)
1292 {
1293         u16 cmd_len;
1294         struct command_node *cmd_node = NULL;
1295         struct scan_request *scan_req;
1296
1297         if (!priv || !priv->adapter || !request) {
1298                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1299                 return -EINVAL;
1300         }
1301
1302         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
1303                 printk(KERN_ERR "%s:%u cleanup in progress, return", __func__, __LINE__);
1304                 return -EBUSY;
1305         }
1306
1307         if (priv->scan_in_progress || priv->request) {
1308                 printk(KERN_ERR "Scan in progress.. return\n");
1309                 return -EBUSY;
1310         }
1311
1312         cmd_len = sizeof(struct scan_request);
1313
1314         cmd_node = prepare_command_request(priv->adapter, CMD_SCAN_REQUEST, cmd_len);
1315
1316         if (!cmd_node) {
1317                 printk(KERN_ERR "esp32: Failed to get command node\n");
1318                 return -ENOMEM;
1319         }
1320
1321         scan_req = (struct scan_request *) (cmd_node->cmd_skb->data +
1322                         sizeof(struct esp_payload_header));
1323
1324         /* TODO: Handle case of multiple SSIDs or channels */
1325         if(request->ssids && request->ssids[0].ssid_len) {
1326                 memcpy(scan_req->ssid, request->ssids[0].ssid, MAX_SSID_LEN);
1327         }
1328
1329 #if 0
1330         if (request->n_channels) {
1331                 chan = request->channels[0];
1332                 scan_req->channel = chan->hw_value;
1333         }
1334 #endif
1335
1336 #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 8, 0)
1337         scan_req->duration = request->duration;
1338 #endif
1339 #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 7, 0)
1340         memcpy(scan_req->bssid, request->bssid, MAC_ADDR_LEN);
1341 #endif
1342
1343         priv->scan_in_progress = true;
1344         priv->request = request;
1345
1346         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1347         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1348
1349         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1350
1351         return 0;
1352 }
1353
1354
1355 int cmd_get_mac(struct esp_wifi_device *priv)
1356 {
1357         u16 cmd_len;
1358         struct command_node *cmd_node = NULL;
1359
1360         if (!priv || !priv->adapter) {
1361                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1362                 return -EINVAL;
1363         }
1364
1365         cmd_len = sizeof(struct command_header);
1366
1367         cmd_node = prepare_command_request(priv->adapter, CMD_GET_MAC, cmd_len);
1368
1369         if (!cmd_node) {
1370                 printk(KERN_ERR "esp32: Failed to get command node\n");
1371                 return -ENOMEM;
1372         }
1373
1374         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1375         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1376
1377         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1378
1379         return 0;
1380 }
1381
1382
1383 int esp_commands_teardown(struct esp_adapter *adapter)
1384 {
1385 #define MAX_DEINIT_RETRY 5
1386         uint8_t iface_idx = 0;
1387         struct esp_wifi_device *priv = NULL;
1388
1389     if (!adapter) {
1390         return -EINVAL;
1391         }
1392
1393         set_bit(ESP_CLEANUP_IN_PROGRESS, &adapter->state_flags);
1394
1395         if (!test_bit(ESP_CMD_INIT_DONE, &adapter->state_flags))
1396                 return 0;
1397
1398
1399         for (iface_idx=0; iface_idx<ESP_MAX_INTERFACE; iface_idx++) {
1400
1401                 priv = adapter->priv[iface_idx];
1402
1403                 if (!priv)
1404                         continue;
1405
1406                 esp_mark_scan_done_and_disconnect(priv, false);
1407
1408                 esp_port_close(priv);
1409         }
1410
1411     destroy_cmd_wq(adapter);
1412     free_esp_cmd_pool(adapter);
1413
1414     return 0;
1415 }
1416
1417 int esp_commands_setup(struct esp_adapter *adapter)
1418 {
1419         if (!adapter) {
1420                 printk(KERN_ERR "esp32: %s failed\n", __func__);
1421                 return -EINVAL;
1422         }
1423
1424         init_waitqueue_head(&adapter->wait_for_cmd_resp);
1425
1426         spin_lock_init(&adapter->cmd_lock);
1427
1428         INIT_LIST_HEAD(&adapter->cmd_pending_queue);
1429         INIT_LIST_HEAD(&adapter->cmd_free_queue);
1430
1431         spin_lock_init(&adapter->cmd_pending_queue_lock);
1432         spin_lock_init(&adapter->cmd_free_queue_lock);
1433
1434         RET_ON_FAIL(create_cmd_wq(adapter));
1435
1436         RET_ON_FAIL(alloc_esp_cmd_pool(adapter));
1437
1438         set_bit(ESP_CMD_INIT_DONE, &adapter->state_flags);
1439         return 0;
1440 }
1441
This page took 0.109003 seconds and 4 git commands to generate.