]> Git Repo - esp-hosted.git/blob - esp_hosted_ng/host/esp_cfg80211.c
fix/corrected_licenses Corrected SPDX-License-Identifier
[esp-hosted.git] / esp_hosted_ng / host / esp_cfg80211.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Espressif Systems Wireless LAN device driver
4  *
5  * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
6  *
7  */
8 #include "utils.h"
9 #include "esp.h"
10 #include "esp_api.h"
11 #include "esp_cfg80211.h"
12 #include "esp_cmd.h"
13 #include "esp_kernel_port.h"
14
15 /**
16   * @brief WiFi PHY rate encodings
17   *
18   */
19 typedef enum {
20         WIFI_PHY_RATE_1M_L      = 0x00, /**< 1 Mbps with long preamble */
21         WIFI_PHY_RATE_2M_L      = 0x01, /**< 2 Mbps with long preamble */
22         WIFI_PHY_RATE_5M_L      = 0x02, /**< 5.5 Mbps with long preamble */
23         WIFI_PHY_RATE_11M_L     = 0x03, /**< 11 Mbps with long preamble */
24         WIFI_PHY_RATE_2M_S      = 0x05, /**< 2 Mbps with short preamble */
25         WIFI_PHY_RATE_5M_S      = 0x06, /**< 5.5 Mbps with short preamble */
26         WIFI_PHY_RATE_11M_S     = 0x07, /**< 11 Mbps with short preamble */
27         WIFI_PHY_RATE_48M       = 0x08, /**< 48 Mbps */
28         WIFI_PHY_RATE_24M       = 0x09, /**< 24 Mbps */
29         WIFI_PHY_RATE_12M       = 0x0A, /**< 12 Mbps */
30         WIFI_PHY_RATE_6M        = 0x0B, /**< 6 Mbps */
31         WIFI_PHY_RATE_54M       = 0x0C, /**< 54 Mbps */
32         WIFI_PHY_RATE_36M       = 0x0D, /**< 36 Mbps */
33         WIFI_PHY_RATE_18M       = 0x0E, /**< 18 Mbps */
34         WIFI_PHY_RATE_9M        = 0x0F, /**< 9 Mbps */
35         WIFI_PHY_RATE_MCS0_LGI  = 0x10, /**< MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz */
36         WIFI_PHY_RATE_MCS1_LGI  = 0x11, /**< MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz */
37         WIFI_PHY_RATE_MCS2_LGI  = 0x12, /**< MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz */
38         WIFI_PHY_RATE_MCS3_LGI  = 0x13, /**< MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz */
39         WIFI_PHY_RATE_MCS4_LGI  = 0x14, /**< MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz */
40         WIFI_PHY_RATE_MCS5_LGI  = 0x15, /**< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz */
41         WIFI_PHY_RATE_MCS6_LGI  = 0x16, /**< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz */
42         WIFI_PHY_RATE_MCS7_LGI  = 0x17, /**< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */
43         WIFI_PHY_RATE_MCS0_SGI  = 0x18, /**< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz */
44         WIFI_PHY_RATE_MCS1_SGI  = 0x19, /**< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz */
45         WIFI_PHY_RATE_MCS2_SGI  = 0x1A, /**< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz */
46         WIFI_PHY_RATE_MCS3_SGI  = 0x1B, /**< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz */
47         WIFI_PHY_RATE_MCS4_SGI  = 0x1C, /**< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz */
48         WIFI_PHY_RATE_MCS5_SGI  = 0x1D, /**< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz */
49         WIFI_PHY_RATE_MCS6_SGI  = 0x1E, /**< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */
50         WIFI_PHY_RATE_MCS7_SGI  = 0x1F, /**< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz */
51         WIFI_PHY_RATE_LORA_250K = 0x29, /**< 250 Kbps */
52         WIFI_PHY_RATE_LORA_500K = 0x2A, /**< 500 Kbps */
53         WIFI_PHY_RATE_MAX,
54 } wifi_phy_rate_t;
55
56 /* Supported rates to be advertised to the cfg80211 */
57 static struct ieee80211_rate esp_rates[] = {
58         {.bitrate = 10, .hw_value = WIFI_PHY_RATE_1M_L, },
59         {.bitrate = 20, .hw_value = WIFI_PHY_RATE_2M_L, },
60         {.bitrate = 55, .hw_value = WIFI_PHY_RATE_5M_L, .hw_value_short = WIFI_PHY_RATE_5M_S},
61         {.bitrate = 110, .hw_value = WIFI_PHY_RATE_11M_L, .hw_value_short = WIFI_PHY_RATE_11M_S},
62         {.bitrate = 60, .hw_value = WIFI_PHY_RATE_6M, },
63         {.bitrate = 90, .hw_value = WIFI_PHY_RATE_9M, },
64         {.bitrate = 120, .hw_value = WIFI_PHY_RATE_12M, },
65         {.bitrate = 180, .hw_value = WIFI_PHY_RATE_18M, },
66         {.bitrate = 240, .hw_value = WIFI_PHY_RATE_24M, },
67         {.bitrate = 360, .hw_value = WIFI_PHY_RATE_36M, },
68         {.bitrate = 480, .hw_value = WIFI_PHY_RATE_48M, },
69         {.bitrate = 540, .hw_value = WIFI_PHY_RATE_54M, },
70 };
71
72
73 /* Channel definitions to be advertised to cfg80211 */
74 static struct ieee80211_channel esp_channels_2ghz[] = {
75         {.center_freq = 2412, .hw_value = 1, },
76         {.center_freq = 2417, .hw_value = 2, },
77         {.center_freq = 2422, .hw_value = 3, },
78         {.center_freq = 2427, .hw_value = 4, },
79         {.center_freq = 2432, .hw_value = 5, },
80         {.center_freq = 2437, .hw_value = 6, },
81         {.center_freq = 2442, .hw_value = 7, },
82         {.center_freq = 2447, .hw_value = 8, },
83         {.center_freq = 2452, .hw_value = 9, },
84         {.center_freq = 2457, .hw_value = 10, },
85         {.center_freq = 2462, .hw_value = 11, },
86         {.center_freq = 2467, .hw_value = 12, },
87         {.center_freq = 2472, .hw_value = 13, },
88         {.center_freq = 2484, .hw_value = 14, },
89 };
90
91 static struct ieee80211_supported_band esp_wifi_bands = {
92         .channels = esp_channels_2ghz,
93         .n_channels = ARRAY_SIZE(esp_channels_2ghz),
94         .bitrates = esp_rates,
95         .n_bitrates = ARRAY_SIZE(esp_rates),
96 };
97
98 /* Supported crypto cipher suits to be advertised to cfg80211 */
99 static const u32 esp_cipher_suites[] = {
100         WLAN_CIPHER_SUITE_WEP40,
101         WLAN_CIPHER_SUITE_WEP104,
102         WLAN_CIPHER_SUITE_TKIP,
103         WLAN_CIPHER_SUITE_CCMP,
104         WLAN_CIPHER_SUITE_SMS4,
105         WLAN_CIPHER_SUITE_AES_CMAC,
106 };
107
108 static const struct wiphy_wowlan_support esp_wowlan_support = {
109         .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_MAGIC_PKT,
110         .n_patterns = 0,
111         .pattern_max_len = 0,
112         .pattern_min_len = 0,
113         .max_pkt_offset = 0,
114 };
115
116 static int esp_inetaddr_event(struct notifier_block *nb,
117         unsigned long event, void *data)
118 {
119         struct in_ifaddr *ifa = data;
120         struct net_device *netdev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
121         struct esp_wifi_device *priv = netdev_priv(netdev);
122
123         /*esp_info("------- IP event -------: %d\n", priv->if_type);*/
124
125         if (!strstr(netdev->name, "espsta")) {
126                 return 0;
127         }
128
129         switch (event) {
130
131         case NETDEV_UP:
132                 if (priv && (priv->if_type == ESP_STA_IF)) {
133                         cmd_set_ip_address(priv, ifa->ifa_local);
134                         esp_info("NETDEV_UP interface %s ip changed to  %pi4\n",
135                                         netdev->name, &ifa->ifa_local);
136                 }
137                 break;
138
139         case NETDEV_DOWN:
140                 esp_info("Interface Down: %d\n", priv->if_type);
141                 if (priv && (priv->if_type == ESP_STA_IF))
142                         cmd_set_ip_address(priv, 0);
143                 break;
144         }
145
146         return 0;
147 }
148
149 struct wireless_dev *esp_cfg80211_add_iface(struct wiphy *wiphy,
150                 const char *name,
151                 unsigned char name_assign_type,
152                 enum nl80211_iftype type,
153                 struct vif_params *params)
154 {
155         struct esp_device *esp_dev = NULL;
156 /*      struct wireless_dev *wdev = NULL;*/
157         struct net_device *ndev;
158         struct esp_wifi_device *esp_wdev;
159         uint8_t esp_nw_if_num = 0;
160
161         if (!wiphy || !name) {
162                 esp_info("%u invalid input\n", __LINE__);
163                 return NULL;
164         }
165
166         esp_dev = wiphy_priv(wiphy);
167
168         if (!esp_dev || !esp_dev->adapter) {
169                 esp_info("%u invalid input\n", __LINE__);
170                 return NULL;
171         }
172
173         if (type == NL80211_IFTYPE_STATION) {
174                 esp_nw_if_num = ESP_STA_NW_IF;
175         } else if (type == NL80211_IFTYPE_AP) {
176                 esp_nw_if_num = ESP_AP_NW_IF;
177         } else {
178                 esp_info("%u network type[%u] is not supported\n",
179                                  __LINE__, type);
180                 return NULL;
181         }
182
183         ndev = ALLOC_NETDEV(sizeof(struct esp_wifi_device), name, name_assign_type,
184                         ether_setup);
185
186         if (!ndev)
187                 return ERR_PTR(-ENOMEM);
188
189         set_bit(ESP_DRIVER_ACTIVE, &esp_dev->adapter->state_flags);
190         esp_wdev = netdev_priv(ndev);
191
192         ndev->ieee80211_ptr = &esp_wdev->wdev;
193         esp_wdev->wdev.wiphy = wiphy;
194         esp_wdev->esp_dev = esp_dev;
195         esp_wdev->ndev = ndev;
196         esp_wdev->adapter = esp_dev->adapter;
197         esp_wdev->adapter->priv[esp_nw_if_num] = esp_wdev;
198         /*esp_info("Updated priv[%u] to %px\n",
199          * esp_nw_if_num, esp_wdev->adapter->priv[esp_nw_if_num]);*/
200         dev_net_set(ndev, wiphy_net(wiphy));
201         SET_NETDEV_DEV(ndev, wiphy_dev(esp_wdev->wdev.wiphy));
202         esp_wdev->wdev.netdev = ndev;
203         esp_wdev->wdev.iftype = type;
204
205         init_waitqueue_head(&esp_wdev->wait_for_scan_completion);
206         esp_wdev->stop_data = 1;
207         esp_wdev->port_open = 0;
208
209         if (cmd_init_interface(esp_wdev))
210                 goto free_and_return;
211
212         if (cmd_get_mac(esp_wdev))
213                 goto free_and_return;
214
215         eth_hw_addr_set(ndev, esp_wdev->mac_address);
216
217         esp_init_priv(ndev);
218
219         if (register_netdevice(ndev))
220                 goto free_and_return;
221
222
223         set_bit(ESP_NETWORK_UP, &esp_wdev->priv_flags);
224         clear_bit(ESP_CLEANUP_IN_PROGRESS, &esp_dev->adapter->state_flags);
225
226         esp_wdev->nb.notifier_call = esp_inetaddr_event;
227         register_inetaddr_notifier(&esp_wdev->nb);
228
229         return &esp_wdev->wdev;
230
231 free_and_return:
232         clear_bit(ESP_DRIVER_ACTIVE, &esp_wdev->adapter->state_flags);
233         dev_net_set(ndev, NULL);
234         free_netdev(ndev);
235         esp_wdev->ndev = NULL;
236         esp_wdev->wdev.netdev = NULL;
237         ndev = NULL;
238         return NULL;
239 }
240
241 #if 0
242 static int esp_cfg80211_del_iface(struct wiphy *wiphy,
243                                                           struct wireless_dev *wdev)
244 {
245         return 0;
246 }
247
248 static int esp_cfg80211_change_iface(struct wiphy *wiphy,
249                                                           struct net_device *ndev,
250                                                           enum nl80211_iftype type,
251                                                           struct vif_params *params)
252 {
253         return 0;
254 }
255 #endif
256
257 static int esp_cfg80211_scan(struct wiphy *wiphy,
258                 struct cfg80211_scan_request *request)
259 {
260
261         struct net_device *ndev = NULL;
262         struct esp_wifi_device *priv = NULL;
263
264         if (!wiphy || !request || !request->wdev || !request->wdev->netdev) {
265                 esp_info("%u invalid input\n", __LINE__);
266                 return -EINVAL;
267         }
268
269         ndev = request->wdev->netdev;
270         priv = netdev_priv(ndev);
271
272         esp_dbg("\n");
273         if (!priv) {
274                 esp_err("Empty priv\n");
275                 return -EINVAL;
276         }
277
278         return cmd_scan_request(priv, request);
279 }
280
281 #if 0
282 static int esp_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
283                                                           struct cfg80211_connect_params *sme)
284 {
285         struct esp_wifi_device *priv = netdev_priv(dev);
286
287         esp_dbg("\n");
288         if (!priv) {
289                 esp_err("Empty priv\n");
290                 return -EINVAL;
291         }
292
293         return cmd_connect_request(priv, sme);
294 }
295 #endif
296
297 static ESP_MGMT_TX_PROTOTYPE()
298 {
299         return 0;
300 }
301
302 static int esp_cfg80211_set_default_key(struct wiphy *wiphy,
303                                         struct net_device *dev, INT_LINK_ID
304                                         u8 key_index, bool unicast, bool multicast)
305 {
306         struct esp_wifi_device *priv = NULL;
307
308         if (!wiphy || !dev) {
309                 esp_err("%u invalid params\n", __LINE__);
310                 return -EINVAL;
311         }
312
313         priv = netdev_priv(dev);
314         if (!priv) {
315                 esp_err("Empty priv");
316                 return -EINVAL;
317         }
318
319         return cmd_set_default_key(priv, key_index);
320 }
321
322 static int esp_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
323                                 INT_LINK_ID u8 key_index, bool pairwise,
324                                 const u8 *mac_addr)
325 {
326         struct esp_wifi_device *priv = NULL;
327
328         if (!wiphy || !dev) {
329                 esp_err("%u invalid params\n", __LINE__);
330                 return -EINVAL;
331         }
332
333         priv = netdev_priv(dev);
334         if (!priv) {
335                 esp_err("Empty priv\n");
336                 return -EINVAL;
337         }
338         esp_dbg("\n");
339
340         return cmd_del_key(priv, key_index, pairwise, mac_addr);
341 }
342
343 static int esp_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
344                                 INT_LINK_ID u8 key_index, bool pairwise,
345                                 const u8 *mac_addr, struct key_params *params)
346 {
347         struct esp_wifi_device *priv = NULL;
348
349         if (!wiphy || !dev || !params) {
350                 esp_err("%u invalid params\n", __LINE__);
351                 return -EINVAL;
352         }
353
354         priv = netdev_priv(dev);
355         if (!priv) {
356                 esp_err("Empty priv\n");
357                 return -EINVAL;
358         }
359         esp_dbg("\n");
360
361         if (params->key_len == 0) {
362                 return esp_cfg80211_del_key(wiphy, dev, ZERO_LINK_ID key_index, pairwise, mac_addr);
363         }
364         return cmd_add_key(priv, key_index, pairwise, mac_addr, params);
365 }
366
367 static int esp_cfg80211_disconnect(struct wiphy *wiphy,
368                 struct net_device *dev, u16 reason_code)
369 {
370         struct esp_wifi_device *priv = NULL;
371
372         if (!wiphy || !dev) {
373                 esp_info("%u invalid input\n",  __LINE__);
374                 return -EINVAL;
375         }
376
377         priv = netdev_priv(dev);
378
379         if (!priv) {
380                 esp_err("empty priv\n");
381                 return 0;
382         }
383         esp_dbg("\n");
384
385         return cmd_disconnect_request(priv, reason_code);
386 }
387
388 static int esp_cfg80211_authenticate(struct wiphy *wiphy, struct net_device *dev,
389                 struct cfg80211_auth_request *req)
390 {
391         struct esp_wifi_device *priv = NULL;
392
393         if (!wiphy || !dev || !req) {
394                 esp_info("%u invalid input\n", __LINE__);
395                 return -EINVAL;
396         }
397
398         esp_dbg("\n");
399
400         priv = netdev_priv(dev);
401
402         if (!priv) {
403                 esp_err("Empty priv\n");
404                 return 0;
405         }
406
407         return cmd_auth_request(priv, req);
408 }
409
410
411 static int esp_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev,
412                 struct cfg80211_assoc_request *req)
413 {
414         struct esp_wifi_device *priv = NULL;
415
416         if (!wiphy || !dev || !req) {
417                 esp_info("%u invalid input\n", __LINE__);
418                 return -EINVAL;
419         }
420
421         priv = netdev_priv(dev);
422
423         esp_dbg("\n");
424
425         if (!priv) {
426                 esp_err("Empty priv\n");
427                 return 0;
428         }
429
430         return cmd_assoc_request(priv, req);
431 }
432
433 static int esp_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev,
434                 struct cfg80211_deauth_request *req)
435 {
436         struct esp_wifi_device *priv = NULL;
437
438         if (!wiphy || !dev || !req) {
439                 esp_info("%u invalid input\n", __LINE__);
440                 return -EINVAL;
441         }
442
443         esp_dbg("\n");
444         priv = netdev_priv(dev);
445
446         if (!priv) {
447                 esp_err("Empty priv\n");
448                 return 0;
449         }
450
451         return cmd_disconnect_request(priv, req->reason_code);
452 }
453
454 static int esp_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
455                 struct cfg80211_disassoc_request *req)
456 {
457         struct esp_wifi_device *priv = NULL;
458
459         if (!wiphy || !dev || !req) {
460                 esp_info("%u invalid input\n", __LINE__);
461                 return -EINVAL;
462         }
463
464         esp_dbg("\n");
465         priv = netdev_priv(dev);
466
467         if (!priv) {
468                 esp_err("Empty priv\n");
469                 return 0;
470         }
471
472         return cmd_disconnect_request(priv, req->reason_code);
473 }
474
475 static int esp_cfg80211_suspend(struct wiphy *wiphy,
476                         struct cfg80211_wowlan *wowlan)
477 {
478         /*esp_dbg("\n");*/
479         return 0;
480 }
481
482 static int esp_cfg80211_resume(struct wiphy *wiphy)
483 {
484         /*esp_dbg("\n");*/
485         return 0;
486 }
487
488 static void esp_cfg80211_set_wakeup(struct wiphy *wiphy,
489                         bool enabled)
490 {
491         /*esp_dbg("\n");*/
492 }
493
494 /* TODO get MAX_TX_POWER_MBM from Firmware for future chips */
495 #define MAX_TX_POWER_MBM (20 * 100)
496 static bool is_txpwr_valid(int mbm)
497 {
498         if (mbm > MAX_TX_POWER_MBM)
499                 return false;
500
501         return true;
502 }
503
504 static int mbm_to_esp_pwr(int mbm)
505 {
506         return ((mbm * 4) / 100);
507 }
508
509 static int esp_pwr_to_dbm(int power)
510 {
511         return ((power / 4));
512 }
513
514 static int esp_cfg80211_set_tx_power(struct wiphy *wiphy,
515                                      struct wireless_dev *wdev,
516                                      enum nl80211_tx_power_setting type, int mbm)
517 {
518         struct esp_adapter *adapter = esp_get_adapter();
519         struct esp_wifi_device *priv = NULL;
520
521         if (!wiphy || !adapter) {
522                 esp_info("%u invalid input %p %p \n", __LINE__, wiphy, wdev);
523                 return -EINVAL;
524         }
525
526         esp_dbg("\n");
527
528         priv = adapter->priv[0];
529         if (!priv) {
530                 esp_err("Empty priv\n");
531                 return 0;
532         }
533
534         switch (type) {
535         case NL80211_TX_POWER_AUTOMATIC:
536                 priv->tx_pwr_type = NL80211_TX_POWER_AUTOMATIC;
537                 priv->tx_pwr = mbm_to_esp_pwr(MAX_TX_POWER_MBM);
538                 break;
539         case NL80211_TX_POWER_LIMITED:
540                 if (!is_txpwr_valid(mbm)) {
541                         esp_warn("mbm:%d not support\n", mbm);
542                         return -EOPNOTSUPP;
543                 }
544                 priv->tx_pwr_type = NL80211_TX_POWER_LIMITED;
545                 priv->tx_pwr = mbm_to_esp_pwr(mbm);
546                 break;
547         case NL80211_TX_POWER_FIXED:
548                 return -EOPNOTSUPP;
549                 break;
550         default:
551                 esp_warn("unknown type:%d\n", type);
552         }
553
554         return cmd_set_tx_power(priv, priv->tx_pwr);
555 }
556
557 static int esp_cfg80211_get_tx_power(struct wiphy *wiphy,
558                                      struct wireless_dev *wdev,
559                                      int *dbm)
560 {
561         struct esp_wifi_device *priv = NULL;
562
563         if (!wiphy || !wdev || !dbm || !wdev->netdev) {
564                 esp_info("%u invalid input\n", __LINE__);
565                 return -EINVAL;
566         }
567
568         esp_dbg("\n");
569         priv = netdev_priv(wdev->netdev);
570
571         if (!priv) {
572                 esp_err("Empty priv\n");
573                 return -EINVAL;
574         }
575
576         *dbm = esp_pwr_to_dbm(priv->tx_pwr);
577
578         return 0;
579 }
580
581 static struct cfg80211_ops esp_cfg80211_ops = {
582 #if 0
583         .add_virtual_intf = esp_cfg80211_add_iface,
584         .del_virtual_intf = esp_cfg80211_del_iface,
585         .change_virtual_intf = esp_cfg80211_change_iface,
586 #endif
587         .scan = esp_cfg80211_scan,
588         /*.connect = esp_cfg80211_connect,*/
589         .disconnect = esp_cfg80211_disconnect,
590         .add_key = esp_cfg80211_add_key,
591         .del_key = esp_cfg80211_del_key,
592         .set_default_key = esp_cfg80211_set_default_key,
593         .mgmt_tx = esp_cfg80211_mgmt_tx,
594         .auth = esp_cfg80211_authenticate,
595         .deauth = esp_cfg80211_deauth,
596         .disassoc = esp_cfg80211_disassoc,
597         .assoc = esp_cfg80211_associate,
598         .suspend = esp_cfg80211_suspend,
599         .resume = esp_cfg80211_resume,
600         .set_wakeup = esp_cfg80211_set_wakeup,
601         .set_tx_power = esp_cfg80211_set_tx_power,
602         .get_tx_power = esp_cfg80211_get_tx_power,
603 };
604
605 int esp_cfg80211_register(struct esp_adapter *adapter)
606 {
607         struct wiphy *wiphy;
608         struct esp_device *esp_dev;
609         int ret = 0;
610
611         wiphy = wiphy_new(&esp_cfg80211_ops, sizeof(struct esp_device));
612
613         if (!wiphy) {
614                 esp_err("Failed to create wiphy\n");
615                 return -EFAULT;
616         }
617
618         adapter->wiphy = wiphy;
619
620         esp_dev = wiphy_priv(wiphy);
621         esp_dev->wiphy = wiphy;
622         esp_dev->adapter = adapter;
623
624         esp_dev->dev = adapter->dev;
625
626         set_wiphy_dev(wiphy, esp_dev->dev);
627
628         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
629         wiphy->bands[NL80211_BAND_2GHZ] = &esp_wifi_bands;
630
631         /* Initialize cipher suits */
632         wiphy->cipher_suites = esp_cipher_suites;
633         wiphy->n_cipher_suites = ARRAY_SIZE(esp_cipher_suites);
634
635         /* TODO: check and finalize the numbers */
636         wiphy->max_scan_ssids = 10;
637         /*      wiphy->max_match_sets = 10;*/
638         wiphy->max_scan_ie_len = 1000;
639         wiphy->max_sched_scan_ssids = 10;
640         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
641         wiphy->wowlan = &esp_wowlan_support;
642
643         /* Advertise SAE support */
644         wiphy->features |= NL80211_FEATURE_SAE;
645
646         ret = wiphy_register(wiphy);
647
648         return ret;
649 }
650
651 int esp_mark_disconnect(struct esp_wifi_device *priv, uint16_t reason,
652                 uint8_t locally_disconnect)
653 {
654         if (priv && priv->ndev)
655                 if (priv->ndev->reg_state == NETREG_REGISTERED)
656                         CFG80211_DISCONNECTED(priv->ndev, reason, NULL, 0, locally_disconnect,
657                                         GFP_KERNEL);
658         return 0;
659 }
660
661 int esp_mark_scan_done_and_disconnect(struct esp_wifi_device *priv,
662                 uint8_t locally_disconnect)
663 {
664
665         if (!priv)
666                 return -EINVAL;
667
668         ESP_MARK_SCAN_DONE(priv, true);
669
670         ESP_CANCEL_SCHED_SCAN();
671
672         esp_mark_disconnect(priv, 0, locally_disconnect);
673
674         return 0;
675 }
This page took 0.063437 seconds and 4 git commands to generate.