]> Git Repo - esp-hosted.git/blob - host/esp_cmd.c
ESP-Hosted cfg80211 support
[esp-hosted.git] / 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
24 #define PRINT_HEXDUMP(STR,ARG, ARG_LEN,level) \
25         print_hex_dump(KERN_INFO, STR, DUMP_PREFIX_ADDRESS, 16, 1, ARG, ARG_LEN, 1);
26
27 #define COMMAND_RESPONSE_TIMEOUT (5 * HZ)
28 u8 ap_bssid[MAC_ADDR_LEN];
29
30 int internal_scan_request(struct esp_wifi_device *priv, char* ssid,
31                 uint8_t channel, uint8_t is_blocking);
32
33 struct beacon_probe_fixed_params {
34         __le64 timestamp;
35         __le16 beacon_interval;
36         __le16 cap_info;
37 } __packed;
38
39
40 static struct command_node * get_free_cmd_node(struct esp_adapter *adapter)
41 {
42         struct command_node *cmd_node;
43
44         spin_lock_bh(&adapter->cmd_free_queue_lock);
45
46         if (list_empty(&adapter->cmd_free_queue)) {
47                 spin_unlock_bh(&adapter->cmd_free_queue_lock);
48                 printk(KERN_ERR "esp32: No free cmd node found\n");
49                 return NULL;
50         }
51         cmd_node = list_first_entry(&adapter->cmd_free_queue,
52                                     struct command_node, list);
53         list_del(&cmd_node->list);
54         spin_unlock_bh(&adapter->cmd_free_queue_lock);
55
56         cmd_node->cmd_skb = esp_alloc_skb(ESP_SIZE_OF_CMD_NODE);
57         if (!cmd_node->cmd_skb) {
58                 printk(KERN_ERR "esp32: No free cmd node skb found\n");
59         }
60
61         return cmd_node;
62 }
63
64 static inline void reset_cmd_node(struct command_node * cmd_node)
65 {
66         cmd_node->cmd_code = 0;
67
68         if (cmd_node->resp_skb) {
69                 dev_kfree_skb_any(cmd_node->resp_skb);
70                 cmd_node->resp_skb = NULL;
71         }
72 }
73
74 static void queue_cmd_node(struct esp_adapter *adapter,
75                 struct command_node * cmd_node, u8 flag_high_prio)
76 {
77         spin_lock_bh(&adapter->cmd_pending_queue_lock);
78
79         if (flag_high_prio)
80                 list_add(&cmd_node->list, &adapter->cmd_pending_queue);
81         else
82                 list_add_tail(&cmd_node->list, &adapter->cmd_pending_queue);
83
84         spin_unlock_bh(&adapter->cmd_pending_queue_lock);
85 }
86
87 static int decode_get_mac_addr(struct esp_wifi_device *priv,
88                 struct command_node *cmd_node)
89 {
90         int ret = 0;
91         struct cmd_config_mac_address *header;
92
93         if (!priv || !cmd_node ||
94             !cmd_node->resp_skb ||
95             !cmd_node->resp_skb->data) {
96                 printk(KERN_INFO "%s: invalid arg\n", __func__);
97                 return -1;
98         }
99
100         header = (struct cmd_config_mac_address *) (cmd_node->resp_skb->data);
101
102         if (header->header.cmd_status != CMD_RESPONSE_SUCCESS) {
103                 printk(KERN_INFO "esp32: Command failed\n");
104                 ret = -1;
105         }
106
107         if (priv)
108                 memcpy(priv->mac_address, header->mac_addr, MAC_ADDR_LEN);
109         else
110                 printk(KERN_ERR "esp32: %s: priv not updated\n", __func__);
111
112         return ret;
113 }
114
115
116 static int decode_common_resp(struct command_node *cmd_node)
117 {
118         int ret = 0;
119         struct command_header *cmd;
120
121
122         if (!cmd_node || !cmd_node->resp_skb || !cmd_node->resp_skb->data) {
123                 printk(KERN_INFO "%s: invalid arg\n", __func__);
124                 return -1;
125         }
126
127         cmd = (struct command_header *) (cmd_node->resp_skb->data);
128
129         if (cmd->cmd_status != CMD_RESPONSE_SUCCESS) {
130                 printk(KERN_INFO "esp32: [0x%x] Command failed\n", cmd_node->cmd_code);
131                 ret = -1;
132         }
133
134         return ret;
135 }
136
137 static void recycle_cmd_node(struct esp_adapter *adapter,
138                 struct command_node * cmd_node)
139 {
140         if (!adapter || !cmd_node)
141                 return;
142
143         reset_cmd_node(cmd_node);
144
145         spin_lock_bh(&adapter->cmd_free_queue_lock);
146         list_add_tail(&cmd_node->list, &adapter->cmd_free_queue);
147         spin_unlock_bh(&adapter->cmd_free_queue_lock);
148 }
149
150
151 static int wait_and_decode_cmd_resp(struct esp_wifi_device *priv,
152                 struct command_node *cmd_node)
153 {
154         struct esp_adapter *adapter = NULL;
155         int ret = 0;
156
157         if (!priv || !priv->adapter || !cmd_node) {
158                 printk(KERN_INFO "%s invalid params\n", __func__);
159                 if (priv->adapter) {
160                         adapter = priv->adapter;
161                         if (adapter && cmd_node)
162                                 recycle_cmd_node(adapter, cmd_node);
163                 }
164                 return -EINVAL;
165         }
166
167         adapter = priv->adapter;
168
169         /* wait for command response */
170         ret = wait_event_interruptible_timeout(adapter->wait_for_cmd_resp,
171                         adapter->cmd_resp != 0, COMMAND_RESPONSE_TIMEOUT);
172
173         if (ret == 0) {
174                 printk(KERN_ERR "esp32: Command[%u] timed out\n",cmd_node->cmd_code);
175                 ret = -EINVAL;
176         } else {
177                 ret = 0;
178         }
179
180         spin_lock_bh(&adapter->cmd_lock);
181         adapter->cur_cmd = NULL;
182         adapter->cmd_resp = 0;
183         spin_unlock_bh(&adapter->cmd_lock);
184
185         switch (cmd_node->cmd_code) {
186
187         case CMD_SCAN_REQUEST:
188                 if (ret == 0)
189                         ret = decode_common_resp(cmd_node);
190
191                 if (ret) {
192                         priv->scan_in_progress = false;
193                         priv->request = NULL;
194                 }
195                 break;
196
197         case CMD_INIT_INTERFACE:
198         case CMD_DEINIT_INTERFACE:
199         case CMD_STA_CONNECT:
200         case CMD_STA_DISCONNECT:
201         case CMD_ADD_KEY:
202         case CMD_DEL_KEY:
203         case CMD_SET_DEFAULT_KEY:
204                 /* intentional fallthrough */
205                 if (ret == 0)
206                         ret = decode_common_resp(cmd_node);
207                 break;
208
209         case CMD_GET_MAC:
210                 if (ret == 0)
211                         ret = decode_get_mac_addr(priv, cmd_node);
212                 break;
213
214         default:
215                 printk(KERN_INFO "esp32: %s Resp for [0x%x] ignored\n",
216                                 __func__,cmd_node->cmd_code);
217                 ret = -EINVAL;
218                 break;
219         }
220
221         recycle_cmd_node(adapter, cmd_node);
222         return ret;
223 }
224
225 static void free_esp_cmd_pool(struct esp_adapter *adapter)
226 {
227         int i;
228         struct command_node * cmd_pool = NULL;
229
230         if (!adapter || !adapter->cmd_pool)
231                 return;
232
233         cmd_pool = adapter->cmd_pool;
234
235         for (i=0; i<ESP_NUM_OF_CMD_NODES; i++) {
236
237                 if (cmd_pool[i].resp_skb) {
238                         dev_kfree_skb_any(cmd_pool[i].resp_skb);
239                         cmd_pool[i].resp_skb = NULL;
240                 }
241         }
242
243         kfree(adapter->cmd_pool);
244         adapter->cmd_pool = NULL;
245 }
246
247 static int alloc_esp_cmd_pool(struct esp_adapter *adapter)
248 {
249         u16 i;
250
251         struct command_node * cmd_pool = kcalloc(ESP_NUM_OF_CMD_NODES,
252                 sizeof(struct command_node), GFP_KERNEL);
253
254         if(!cmd_pool)
255                 return -ENOMEM;
256
257         adapter->cmd_pool = cmd_pool;
258
259         for (i=0; i<ESP_NUM_OF_CMD_NODES; i++) {
260
261                 cmd_pool[i].cmd_skb = NULL;
262                 cmd_pool[i].resp_skb = NULL;
263                 recycle_cmd_node(adapter, &cmd_pool[i]);
264         }
265
266         return 0;
267 }
268
269 #if 0
270 static int is_command_pending(struct esp_adapter *adapter)
271 {
272         int is_cmd_pend_q_empty;
273
274         spin_lock_bh(&adapter->cmd_pending_queue_lock);
275         is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_queue);
276         spin_unlock_bh(&adapter->cmd_pending_queue_lock);
277
278         return !is_cmd_pend_q_empty;
279 }
280 #endif
281
282 static void esp_cmd_work(struct work_struct *work)
283 {
284         int ret;
285         struct command_node *cmd_node = NULL;
286         struct esp_adapter * adapter = NULL;
287
288         adapter = esp_get_adapter();
289
290         if (!adapter)
291                 return;
292
293         if (adapter->cur_cmd) {
294                 //TODO: there should be failure reported to
295                 //cmd in progress. it should fail and not time out.
296                 // applicable other neg cases also
297                 return;
298         }
299
300         spin_lock_bh(&adapter->cmd_pending_queue_lock);
301
302         if (list_empty(&adapter->cmd_pending_queue)) {
303                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
304                 return;
305         }
306
307         cmd_node = list_first_entry(&adapter->cmd_pending_queue,
308                                     struct command_node, list);
309         if (! cmd_node) {
310                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
311                 return;
312         }
313         list_del(&cmd_node->list);
314
315         if (! cmd_node->cmd_skb) {
316                 printk (KERN_ERR "cmd_node->cmd_skb NULL \n");
317                 spin_unlock_bh(&adapter->cmd_pending_queue_lock);
318                 return;
319         }
320
321         spin_lock_bh(&adapter->cmd_lock);
322         adapter->cur_cmd = cmd_node;
323         adapter->cmd_resp = 0;
324         spin_unlock_bh(&adapter->cmd_lock);
325
326         spin_unlock_bh(&adapter->cmd_pending_queue_lock);
327
328         ret = esp_send_packet(adapter, cmd_node->cmd_skb);
329
330         if (ret) {
331                 printk (KERN_ERR "Failed to send command\n");
332                 spin_lock_bh(&adapter->cmd_lock);
333                 adapter->cur_cmd = NULL;
334                 spin_unlock_bh(&adapter->cmd_lock);
335                 recycle_cmd_node(adapter, cmd_node);
336                 return;
337         }
338 }
339
340 static int create_cmd_wq(struct esp_adapter *adapter)
341 {
342         adapter->cmd_wq = alloc_workqueue("ESP_CMD_WORK_QUEUE", 0, 0);
343
344         RET_ON_FAIL(!adapter->cmd_wq);
345
346         INIT_WORK(&adapter->cmd_work, esp_cmd_work);
347
348         return 0;
349 }
350
351 static void destroy_cmd_wq(struct esp_adapter *adapter)
352 {
353         if (adapter->cmd_wq) {
354                 flush_scheduled_work();
355                 destroy_workqueue(adapter->cmd_wq);
356                 adapter->cmd_wq = NULL;
357         }
358 }
359
360 struct command_node * prepare_command_request(struct esp_adapter *adapter, u8 cmd_code, u16 len)
361 {
362         struct command_header *cmd;
363         struct esp_payload_header *payload_header;
364         struct command_node *node = NULL;
365
366         if (!adapter) {
367                 printk(KERN_INFO "%s:%u null adapter\n",__func__,__LINE__);
368                 return NULL;
369         }
370
371         if (!cmd_code || cmd_code >= CMD_MAX) {
372                 printk (KERN_ERR "esp32: %s: unsupported command code\n", __func__);
373                 return NULL;
374         }
375
376         node = get_free_cmd_node(adapter);
377
378         if (!node || !node->cmd_skb) {
379                 printk (KERN_ERR "esp32: %s: Failed to get new free cmd node\n", __func__);
380                 return NULL;
381         }
382
383         node->cmd_code = cmd_code;
384
385         len += sizeof(struct esp_payload_header);
386
387         payload_header = skb_put(node->cmd_skb, len);
388         memset(payload_header, 0, len);
389
390         payload_header->if_type = ESP_STA_IF;
391         payload_header->len = cpu_to_le16(len - sizeof(struct esp_payload_header));
392         payload_header->offset = cpu_to_le16(sizeof(struct esp_payload_header));
393         payload_header->packet_type = PACKET_TYPE_COMMAND_REQUEST;
394
395         cmd = (struct command_header *) (node->cmd_skb->data + payload_header->offset);
396         cmd->cmd_code = cmd_code;
397
398 /*      payload_header->checksum = cpu_to_le16(compute_checksum(skb->data, len));*/
399
400         return node;
401 }
402
403 int process_command_response(struct esp_adapter *adapter, struct sk_buff *skb)
404 {
405         if (!skb || !adapter) {
406                 printk (KERN_ERR "esp32: CMD resp: invalid!\n");
407
408                 if (skb)
409                         dev_kfree_skb_any(skb);
410
411                 return -1;
412         }
413
414         if (!adapter->cur_cmd) {
415                 printk (KERN_ERR "esp32: Command response not expected\n");
416                 dev_kfree_skb_any(skb);
417                 return -1;
418         }
419
420         spin_lock_bh(&adapter->cmd_lock);
421         adapter->cur_cmd->resp_skb = skb;
422         spin_unlock_bh(&adapter->cmd_lock);
423
424         adapter->cmd_resp = 1;
425
426         wake_up_interruptible(&adapter->wait_for_cmd_resp);
427         queue_work(adapter->cmd_wq, &adapter->cmd_work);
428
429         return 0;
430 }
431
432 static void process_scan_result_event(struct esp_wifi_device *priv,
433                 struct scan_event *scan_evt)
434 {
435         struct cfg80211_bss *bss;
436         struct beacon_probe_fixed_params *fixed_params;
437         u64 timestamp;
438         u16 beacon_interval;
439         u16 cap_info;
440         u8 *ie_buf;
441         u32 ie_len;
442         int freq;
443         struct ieee80211_channel *chan;
444
445         if (!priv || !scan_evt) {
446                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
447                 return;
448         }
449
450         /* End of scan; notify cfg80211 */
451         if (scan_evt->header.status == 0) {
452                 struct cfg80211_scan_info info = {
453                         .aborted = false,
454                 };
455
456                 if (priv->request) {
457                         /* scan completion */
458                         cfg80211_scan_done(priv->request, &info);
459                         priv->request = NULL;
460                 }
461
462                 priv->scan_in_progress = false;
463
464                 if (priv->waiting_for_scan_done) {
465                         priv->waiting_for_scan_done = false;
466                         wake_up_interruptible(&priv->wait_for_scan_completion);
467                 }
468                 return;
469         }
470
471         ie_buf = (u8 *) scan_evt->frame;
472         ie_len = le16_to_cpu(scan_evt->frame_len);
473
474         fixed_params = (struct beacon_probe_fixed_params *) ie_buf;
475
476         timestamp = le64_to_cpu(fixed_params->timestamp);
477         beacon_interval = le16_to_cpu(fixed_params->beacon_interval);
478         cap_info = le16_to_cpu(fixed_params->cap_info);
479
480         freq = ieee80211_channel_to_frequency(scan_evt->channel, NL80211_BAND_2GHZ);
481         chan = ieee80211_get_channel(priv->adapter->wiphy, freq);
482
483         ie_buf += sizeof(struct beacon_probe_fixed_params);
484         ie_len -= sizeof(struct beacon_probe_fixed_params);
485
486         if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
487                 bss = cfg80211_inform_bss(priv->adapter->wiphy, chan,
488                                 CFG80211_BSS_FTYPE_UNKNOWN, scan_evt->bssid, timestamp,
489                                 cap_info, beacon_interval, ie_buf, ie_len,
490                                 le32_to_cpu(scan_evt->rssi), GFP_ATOMIC);
491
492                 if (bss)
493                         cfg80211_put_bss(priv->adapter->wiphy, bss);
494         } else {
495                 printk (KERN_INFO "Scan report: Skip invalid or disabled channel\n");
496         }
497 }
498
499 static void process_disconnect_event(struct esp_wifi_device *priv,
500                 struct disconnect_event *event)
501 {
502         if (!priv || !event) {
503                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
504                 return;
505         }
506
507         printk(KERN_INFO "Disconnect event for ssid %s [%d]\n", event->ssid,
508                         event->reason);
509
510         esp_port_close(priv);
511         if (priv->ndev)
512                 cfg80211_disconnected(priv->ndev, event->reason, NULL, 0, true,
513                         GFP_KERNEL);
514 }
515
516 static void process_connect_status_event(struct esp_wifi_device *priv,
517                 struct connect_event *event)
518 {
519         u8 mac[6];
520
521         if (!priv || !event) {
522                 printk(KERN_ERR "%s: Invalid arguments\n", __func__);
523                 return;
524         }
525
526         printk(KERN_INFO "Connection status: %d\n", event->header.status);
527
528         if (!event->bssid) {
529                 printk(KERN_INFO "bssid input as NULL. Ignoring the connect statuc event\n");
530                 return;
531         }
532         memcpy(mac, event->bssid, MAC_ADDR_LEN);
533
534         cfg80211_connect_result(priv->ndev, mac, NULL, 0, NULL, 0,
535                         0, GFP_KERNEL);
536
537         esp_port_open(priv);
538 }
539
540 int process_event(struct esp_wifi_device *priv, struct sk_buff *skb)
541 {
542         struct event_header *header;
543
544         if (!skb || !priv) {
545                 printk (KERN_ERR "esp32: CMD resp: invalid!\n");
546
547                 if (skb)
548                         dev_kfree_skb_any(skb);
549
550                 return -1;
551         }
552
553         header = (struct event_header *) (skb->data);
554
555         switch (header->event_code) {
556
557         case EVENT_SCAN_RESULT:
558                 process_scan_result_event(priv,
559                                 (struct scan_event *)(skb->data));
560                 break;
561
562         case EVENT_STA_CONNECT:
563                 process_connect_status_event(priv,
564                                 (struct connect_event *)(skb->data));
565                 break;
566
567         case EVENT_STA_DISCONNECT:
568                 process_disconnect_event(priv,
569                                 (struct disconnect_event *)(skb->data));
570                 break;
571
572         default:
573                 printk(KERN_INFO "%s:%u unhandled event[%u]\n",
574                                 __func__, __LINE__, header->event_code);
575                 break;
576         }
577
578         return 0;
579 }
580
581 int cmd_disconnect_request(struct esp_wifi_device *priv, u16 reason_code)
582 {
583         struct command_node *cmd_node = NULL;
584         struct cmd_sta_disconnect *cmd_disconnect;
585
586         if (!priv || !priv->adapter) {
587                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
588                 return -EINVAL;
589         }
590
591         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags))
592                 return 0;
593
594         cmd_node = prepare_command_request(priv->adapter, CMD_STA_DISCONNECT,
595                         sizeof(struct cmd_sta_disconnect));
596
597         if (!cmd_node) {
598                 printk(KERN_ERR "Failed to get command node\n");
599                 return -ENOMEM;
600         }
601
602         cmd_disconnect = (struct cmd_sta_disconnect *)
603                 (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
604
605         cmd_disconnect->reason_code = reason_code;
606
607         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
608         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
609
610         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
611
612         return 0;
613 }
614
615 int cmd_connect_request(struct esp_wifi_device *priv,
616                 struct cfg80211_connect_params *params)
617 {
618         u16 cmd_len;
619         struct command_node *cmd_node = NULL;
620         struct cmd_sta_connect *cmd;
621         struct ieee80211_channel *chan;
622         struct cfg80211_bss *bss;
623         struct esp_adapter *adapter = NULL;
624
625         u8 retry = 2;
626
627         if (!priv || !params || !priv->adapter) {
628                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
629                 return -EINVAL;
630         }
631
632         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
633                 printk(KERN_ERR "%s:%u cleanup in progress, return failure", __func__, __LINE__);
634                 return -EFAULT;
635         }
636
637         adapter = priv->adapter;
638
639         cmd_len = sizeof(struct cmd_sta_connect) + params->ie_len;
640
641         cmd_node = prepare_command_request(adapter, CMD_STA_CONNECT, cmd_len);
642         if (!cmd_node) {
643                 printk(KERN_ERR "Failed to get command node\n");
644                 return -ENOMEM;
645         }
646         cmd = (struct cmd_sta_connect *) (cmd_node->cmd_skb->data + sizeof(struct esp_payload_header));
647
648         if (params->ssid_len)
649                 memcpy(cmd->ssid, params->ssid, MAX_SSID_LEN);
650         else
651                 printk(KERN_ERR "%s: No ssid\n", __func__);
652
653         if (params->bssid) {
654                 memcpy(ap_bssid, params->bssid, MAC_ADDR_LEN);
655                 memcpy(cmd->bssid, params->bssid, MAC_ADDR_LEN);
656         }
657
658         if (params->channel) {
659                 chan = params->channel;
660                 cmd->channel = chan->hw_value;
661         }
662
663         if (params->ie_len) {
664                 cmd->assoc_ie_len = cpu_to_le16(params->ie_len);
665                 memcpy(cmd->assoc_ie, params->ie, params->ie_len);
666         }
667
668         if (params->privacy)
669                 cmd->is_auth_open = 0;
670         else
671                 cmd->is_auth_open = 1;
672
673         printk (KERN_INFO "Connection request: %s %pM %d\n",
674                         cmd->ssid, params->bssid, cmd->channel);
675
676         do {
677                 bss = cfg80211_get_bss(adapter->wiphy, params->channel, params->bssid,
678                                 params->ssid, params->ssid_len, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
679
680                 if (bss) {
681                         break;
682                 } else {
683                         printk (KERN_INFO "No BSS in the list.. scanning..\n");
684                         internal_scan_request(priv, cmd->ssid, cmd->channel, true);
685                 }
686
687                 retry--;
688         } while (retry);
689
690         if (retry) {
691                 queue_cmd_node(adapter, cmd_node, ESP_CMD_DFLT_PRIO);
692                 queue_work(adapter->cmd_wq, &adapter->cmd_work);
693
694                 RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
695         } else {
696                 printk(KERN_INFO "Failed to find %s\n", cmd->ssid);
697                 return -EFAULT;
698         }
699
700         return 0;
701 }
702
703 int cmd_set_default_key(struct esp_wifi_device *priv, u8 key_index)
704 {
705         u16 cmd_len;
706         struct command_node *cmd_node = NULL;
707         struct cmd_key_operation *cmd;
708         struct wifi_sec_key * key = NULL;
709
710         if (!priv || !priv->adapter) {
711                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
712                 return -EINVAL;
713         }
714
715 #if 0
716         if (key_index > ESP_MAX_KEY_INDEX) {
717                 printk(KERN_ERR "invalid key index[%u] > max[%u]\n",
718                                 key_index, ESP_MAX_KEY_INDEX);
719                 return -EINVAL;
720         }
721 #endif
722         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
723                 printk(KERN_ERR "%s:%u cleanup in progress, return", __func__, __LINE__);
724                 return 0;
725         }
726
727
728         cmd_len = sizeof(struct cmd_key_operation);
729
730         /* get new cmd node */
731         cmd_node = prepare_command_request(priv->adapter, CMD_SET_DEFAULT_KEY, cmd_len);
732         if (!cmd_node) {
733                 printk(KERN_ERR "Failed to get command node\n");
734                 return -ENOMEM;
735         }
736
737         /* cmd specific update */
738         cmd = (struct cmd_key_operation *) (cmd_node->cmd_skb->data +
739                         sizeof(struct esp_payload_header));
740         key = &cmd->key;
741
742         key->index = key_index;
743         key->set_cur = 1;
744
745         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
746         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
747
748         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
749
750         return 0;
751 }
752
753 int cmd_del_key(struct esp_wifi_device *priv, u8 key_index, bool pairwise,
754                 const u8 *mac_addr)
755 {
756         u16 cmd_len;
757         struct command_node *cmd_node = NULL;
758         struct cmd_key_operation *cmd;
759         struct wifi_sec_key * key = NULL;
760         const u8 *mac = NULL;
761         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
762
763         if (!priv || !priv->adapter) {
764                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
765                 return -EINVAL;
766         }
767
768         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags))
769                 return 0;
770
771 #if 0
772         if (key_index > ESP_MAX_KEY_INDEX) {
773                 printk(KERN_ERR "invalid key index[%u] > max[%u]\n",
774                                 key_index, ESP_MAX_KEY_INDEX);
775                 return -EINVAL;
776         }
777 #endif
778
779         mac = pairwise ? mac_addr : bc_mac;
780         print_hex_dump(KERN_INFO, "mac_addr: ", DUMP_PREFIX_ADDRESS, 16, 1,
781                         mac, MAC_ADDR_LEN, 1);
782
783         cmd_len = sizeof(struct cmd_key_operation);
784
785         /* get new cmd node */
786         cmd_node = prepare_command_request(priv->adapter, CMD_DEL_KEY, cmd_len);
787         if (!cmd_node) {
788                 printk(KERN_ERR "Failed to get command node\n");
789                 return -ENOMEM;
790         }
791
792         /* cmd specific update */
793         cmd = (struct cmd_key_operation *) (cmd_node->cmd_skb->data +
794                         sizeof(struct esp_payload_header));
795         key = &cmd->key;
796
797         if (mac && !is_multicast_ether_addr(mac))
798                 memcpy((char *)&key->mac_addr, (void *)mac, MAC_ADDR_LEN);
799
800         key->index = key_index;
801         key->del = 1;
802
803         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
804         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
805
806         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
807
808         return 0;
809 }
810
811 int cmd_add_key(struct esp_wifi_device *priv, u8 key_index, bool pairwise,
812                 const u8 *mac_addr, struct key_params *params)
813 {
814         u16 cmd_len;
815         struct command_node *cmd_node = NULL;
816         struct cmd_key_operation *cmd;
817         struct wifi_sec_key * key = NULL;
818         const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
819         const u8 *mac = NULL;
820
821 #if 0
822         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",
823       __func__, __LINE__,
824       key_index, pairwise, params->key_len, params->seq_len, params->mode, params->cipher);
825 #endif
826         if (!priv || !priv->adapter || !params ||
827             !params->key || !params->key_len || !params->seq_len) {
828                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
829                 return -EINVAL;
830         }
831
832 #if 0
833         if (key_index > ESP_MAX_KEY_INDEX) {
834                 printk(KERN_ERR "invalid key index[%u] > max[%u]\n",
835                                 key_index, ESP_MAX_KEY_INDEX);
836                 return -EINVAL;
837         }
838 #endif
839
840         if (params->key_len > sizeof(key->data)) {
841                 printk(KERN_ERR "Too long key length (%u)\n", params->key_len);
842                 return -EINVAL;
843         }
844
845         if (params->seq_len > sizeof(key->seq)) {
846                 printk(KERN_ERR "Too long key seq length (%u)\n", params->seq_len);
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         mac = pairwise ? mac_addr : bc_mac;
856         if (mac) {
857                 print_hex_dump(KERN_INFO, "mac: ", DUMP_PREFIX_ADDRESS, 16, 1,
858                                 mac, MAC_ADDR_LEN, 1);
859         }
860
861         cmd_len = sizeof(struct cmd_key_operation);
862
863         cmd_node = prepare_command_request(priv->adapter, CMD_ADD_KEY, cmd_len);
864         if (!cmd_node) {
865                 printk(KERN_ERR "Failed to get command node\n");
866                 return -ENOMEM;
867         }
868
869         cmd = (struct cmd_key_operation *) (cmd_node->cmd_skb->data +
870                         sizeof(struct esp_payload_header));
871         key = &cmd->key;
872
873         if (mac && !is_multicast_ether_addr(mac))
874                 memcpy((char *)&key->mac_addr, (void *)mac, MAC_ADDR_LEN);
875
876         key->index = key_index;
877
878         key->len = params->key_len;
879         if (params->key && key->len)
880                 memcpy(key->data, params->key, key->len);
881
882         key->seq_len = params->seq_len;
883         if (params->seq && key->seq_len)
884                 memcpy(key->seq, params->seq, key->seq_len);
885
886         key->set_tx = params->mode & NL80211_KEY_SET_TX;
887
888         key->algo = wpa_cipher_to_alg(params->cipher);
889 #if 0
890         if (key->algo == WIFI_WPA_ALG_NONE) {
891                 printk(KERN_INFO "CIPHER NONE does not use pairwise keys");
892                 return 0;
893         }
894 #endif
895
896 #if 0
897         printk(KERN_ERR "%s:%u algo: %u idx: %u set_tx: %u seq_len: %u len:%u \n", __func__, __LINE__,
898                         key->algo, key->index, key->set_tx, key->seq_len, key->len);
899         PRINT_HEXDUMP("mac", key->mac_addr, 6, ESP_LOG_INFO);
900         PRINT_HEXDUMP("seq", key->seq, key->seq_len, ESP_LOG_INFO);
901         PRINT_HEXDUMP("key_data", key->data, key->len, ESP_LOG_INFO);
902 #endif
903
904         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
905         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
906
907         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
908
909         return 0;
910 }
911
912 int cmd_init_interface(struct esp_wifi_device *priv)
913 {
914         u16 cmd_len;
915         struct command_node *cmd_node = NULL;
916
917         if (!priv || !priv->adapter) {
918                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
919                 return -EINVAL;
920         }
921
922         cmd_len = sizeof(struct command_header);
923
924         cmd_node = prepare_command_request(priv->adapter, CMD_INIT_INTERFACE, cmd_len);
925
926         if (!cmd_node) {
927                 printk(KERN_ERR "esp32: Failed to get command node\n");
928                 return -ENOMEM;
929         }
930
931         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
932         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
933
934         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
935
936         return 0;
937 }
938
939 int cmd_deinit_interface(struct esp_wifi_device *priv)
940 {
941         u16 cmd_len;
942         struct command_node *cmd_node = NULL;
943
944         if (!priv || !priv->adapter)
945                 return -EINVAL;
946
947         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
948                 printk(KERN_ERR "%s:%u cleanup in progress, return\n", __func__, __LINE__);
949                 return 0;
950         }
951
952         cmd_len = sizeof(struct command_header);
953
954         cmd_node = prepare_command_request(priv->adapter, CMD_DEINIT_INTERFACE, cmd_len);
955
956         if (!cmd_node) {
957                 printk(KERN_ERR "esp32: Failed to get command node\n");
958                 return -ENOMEM;
959         }
960
961         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
962         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
963
964         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
965
966         return 0;
967 }
968
969 int internal_scan_request(struct esp_wifi_device *priv, char* ssid,
970                 uint8_t channel, uint8_t is_blocking)
971 {
972         int ret = 0;
973         u16 cmd_len;
974         struct command_node *cmd_node = NULL;
975         struct scan_request *scan_req;
976
977         if (!priv || !priv->adapter) {
978                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
979                 return -EINVAL;
980         }
981
982         if (priv->scan_in_progress) {
983                 printk(KERN_ERR "Scan in progress.. return\n");
984                 return -EBUSY;
985         }
986
987         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
988                 printk(KERN_ERR "%s:%u cleanup in progress, return", __func__, __LINE__);
989                 return 0;
990         }
991
992         cmd_len = sizeof(struct scan_request);
993
994         cmd_node = prepare_command_request(priv->adapter, CMD_SCAN_REQUEST, cmd_len);
995
996         if (!cmd_node) {
997                 printk(KERN_ERR "esp32: Failed to get command node\n");
998                 return -ENOMEM;
999         }
1000
1001         scan_req = (struct scan_request *) (cmd_node->cmd_skb->data +
1002                         sizeof(struct esp_payload_header));
1003
1004         if (ssid) {
1005                 memcpy(scan_req->ssid, ssid, MAX_SSID_LEN);
1006         }
1007
1008         scan_req->channel = channel;
1009
1010         priv->scan_in_progress = true;
1011
1012         if (is_blocking)
1013                 priv->waiting_for_scan_done = true;
1014
1015         /* Enqueue command */
1016         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1017         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1018
1019         ret = wait_and_decode_cmd_resp(priv, cmd_node);
1020
1021         if (!ret && is_blocking) {
1022                 /* Wait for scan done */
1023                 wait_event_interruptible_timeout(priv->wait_for_scan_completion,
1024                                 priv->waiting_for_scan_done != true, COMMAND_RESPONSE_TIMEOUT);
1025         }
1026
1027         return ret;
1028 }
1029
1030 int cmd_scan_request(struct esp_wifi_device *priv, struct cfg80211_scan_request *request)
1031 {
1032         u16 cmd_len;
1033         struct command_node *cmd_node = NULL;
1034         struct scan_request *scan_req;
1035
1036         if (!priv || !priv->adapter || !request) {
1037                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1038                 return -EINVAL;
1039         }
1040
1041         if (test_bit(ESP_CLEANUP_IN_PROGRESS, &priv->adapter->state_flags)) {
1042                 printk(KERN_ERR "%s:%u cleanup in progress, return", __func__, __LINE__);
1043                 return 0;
1044         }
1045
1046
1047         if (priv->scan_in_progress || priv->request) {
1048                 printk(KERN_ERR "Scan in progress.. return\n");
1049                 return -EBUSY;
1050         }
1051
1052         cmd_len = sizeof(struct scan_request);
1053
1054         cmd_node = prepare_command_request(priv->adapter, CMD_SCAN_REQUEST, cmd_len);
1055
1056         if (!cmd_node) {
1057                 printk(KERN_ERR "esp32: Failed to get command node\n");
1058                 return -ENOMEM;
1059         }
1060
1061         scan_req = (struct scan_request *) (cmd_node->cmd_skb->data +
1062                         sizeof(struct esp_payload_header));
1063
1064         /* TODO: Handle case of multiple SSIDs or channels */
1065         if(request->ssids[0].ssid_len) {
1066                 memcpy(scan_req->ssid, request->ssids[0].ssid, MAX_SSID_LEN);
1067         }
1068
1069 #if 0
1070         if (request->n_channels) {
1071                 chan = request->channels[0];
1072                 scan_req->channel = chan->hw_value;
1073         }
1074 #endif
1075
1076         scan_req->duration = request->duration;
1077         memcpy(scan_req->bssid, request->bssid, MAC_ADDR_LEN);
1078
1079         priv->scan_in_progress = true;
1080         priv->request = request;
1081
1082         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1083         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1084
1085         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1086
1087         return 0;
1088 }
1089
1090
1091 int cmd_get_mac(struct esp_wifi_device *priv)
1092 {
1093         u16 cmd_len;
1094         struct command_node *cmd_node = NULL;
1095
1096         if (!priv || !priv->adapter) {
1097                 printk(KERN_ERR "%s: Invalid argument\n", __func__);
1098                 return -EINVAL;
1099         }
1100
1101         cmd_len = sizeof(struct command_header);
1102
1103         cmd_node = prepare_command_request(priv->adapter, CMD_GET_MAC, cmd_len);
1104
1105         if (!cmd_node) {
1106                 printk(KERN_ERR "esp32: Failed to get command node\n");
1107                 return -ENOMEM;
1108         }
1109
1110         queue_cmd_node(priv->adapter, cmd_node, ESP_CMD_DFLT_PRIO);
1111         queue_work(priv->adapter->cmd_wq, &priv->adapter->cmd_work);
1112
1113         RET_ON_FAIL(wait_and_decode_cmd_resp(priv, cmd_node));
1114
1115         return 0;
1116 }
1117
1118
1119 int deinit_esp_dev(struct esp_adapter *adapter)
1120 {
1121 #define MAX_DEINIT_RETRY 5
1122         uint8_t iface_idx = 0;
1123
1124     if (!adapter) {
1125         return -EINVAL;
1126         }
1127
1128         set_bit(ESP_CLEANUP_IN_PROGRESS, &adapter->state_flags);
1129
1130         if (!test_bit(ESP_CMD_INIT_DONE, &adapter->state_flags))
1131                 return 0;
1132
1133         wake_up_interruptible(&adapter->wait_for_cmd_resp);
1134         spin_lock_bh(&adapter->cmd_pending_queue_lock);
1135
1136         for (iface_idx=0; iface_idx<ESP_MAX_INTERFACE; iface_idx++) {
1137                 if (adapter->priv[iface_idx] &&
1138                     adapter->priv[iface_idx]->ndev &&
1139                     adapter->priv[iface_idx]->wdev.current_bss)
1140                         cfg80211_disconnected(adapter->priv[iface_idx]->ndev, 0, NULL, 0, false,
1141                                         GFP_KERNEL);
1142
1143                 esp_port_close(adapter->priv[iface_idx]);
1144         }
1145
1146         list_del(&adapter->cmd_pending_queue);
1147         spin_unlock_bh(&adapter->cmd_pending_queue_lock);
1148
1149         spin_lock_bh(&adapter->cmd_free_queue_lock);
1150         list_del(&adapter->cmd_free_queue);
1151         spin_unlock_bh(&adapter->cmd_free_queue_lock);
1152
1153     destroy_cmd_wq(adapter);
1154     free_esp_cmd_pool(adapter);
1155
1156     return 0;
1157 }
1158
1159 int init_esp_dev(struct esp_adapter *adapter)
1160 {
1161         if (!adapter) {
1162                 printk(KERN_ERR "esp32: %s failed\n", __func__);
1163                 return -EINVAL;
1164         }
1165
1166         init_waitqueue_head(&adapter->wait_for_cmd_resp);
1167
1168         spin_lock_init(&adapter->cmd_lock);
1169
1170         INIT_LIST_HEAD(&adapter->cmd_pending_queue);
1171         INIT_LIST_HEAD(&adapter->cmd_free_queue);
1172
1173         spin_lock_init(&adapter->cmd_pending_queue_lock);
1174         spin_lock_init(&adapter->cmd_free_queue_lock);
1175
1176         RET_ON_FAIL(create_cmd_wq(adapter));
1177
1178         RET_ON_FAIL(alloc_esp_cmd_pool(adapter));
1179
1180         set_bit(ESP_CMD_INIT_DONE, &adapter->state_flags);
1181         return 0;
1182 }
1183
This page took 0.092295 seconds and 4 git commands to generate.