]> Git Repo - esp-hosted.git/blame - esp_hosted_ng/host/esp_cfg80211.c
Merge branch 'bugfix/kernel_crash_ym2_6sep' into 'master'
[esp-hosted.git] / esp_hosted_ng / host / esp_cfg80211.c
CommitLineData
774e9b2e
MM
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.h"
21#include "esp_api.h"
22#include "esp_cfg80211.h"
23#include "esp_cmd.h"
24
25/**
26 * @brief WiFi PHY rate encodings
27 *
28 */
29typedef enum {
30 WIFI_PHY_RATE_1M_L = 0x00, /**< 1 Mbps with long preamble */
31 WIFI_PHY_RATE_2M_L = 0x01, /**< 2 Mbps with long preamble */
32 WIFI_PHY_RATE_5M_L = 0x02, /**< 5.5 Mbps with long preamble */
33 WIFI_PHY_RATE_11M_L = 0x03, /**< 11 Mbps with long preamble */
34 WIFI_PHY_RATE_2M_S = 0x05, /**< 2 Mbps with short preamble */
35 WIFI_PHY_RATE_5M_S = 0x06, /**< 5.5 Mbps with short preamble */
36 WIFI_PHY_RATE_11M_S = 0x07, /**< 11 Mbps with short preamble */
37 WIFI_PHY_RATE_48M = 0x08, /**< 48 Mbps */
38 WIFI_PHY_RATE_24M = 0x09, /**< 24 Mbps */
39 WIFI_PHY_RATE_12M = 0x0A, /**< 12 Mbps */
40 WIFI_PHY_RATE_6M = 0x0B, /**< 6 Mbps */
41 WIFI_PHY_RATE_54M = 0x0C, /**< 54 Mbps */
42 WIFI_PHY_RATE_36M = 0x0D, /**< 36 Mbps */
43 WIFI_PHY_RATE_18M = 0x0E, /**< 18 Mbps */
44 WIFI_PHY_RATE_9M = 0x0F, /**< 9 Mbps */
45 WIFI_PHY_RATE_MCS0_LGI = 0x10, /**< MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz */
46 WIFI_PHY_RATE_MCS1_LGI = 0x11, /**< MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz */
47 WIFI_PHY_RATE_MCS2_LGI = 0x12, /**< MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz */
48 WIFI_PHY_RATE_MCS3_LGI = 0x13, /**< MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz */
49 WIFI_PHY_RATE_MCS4_LGI = 0x14, /**< MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz */
50 WIFI_PHY_RATE_MCS5_LGI = 0x15, /**< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz */
51 WIFI_PHY_RATE_MCS6_LGI = 0x16, /**< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz */
52 WIFI_PHY_RATE_MCS7_LGI = 0x17, /**< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */
53 WIFI_PHY_RATE_MCS0_SGI = 0x18, /**< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz */
54 WIFI_PHY_RATE_MCS1_SGI = 0x19, /**< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz */
55 WIFI_PHY_RATE_MCS2_SGI = 0x1A, /**< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz */
56 WIFI_PHY_RATE_MCS3_SGI = 0x1B, /**< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz */
57 WIFI_PHY_RATE_MCS4_SGI = 0x1C, /**< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz */
58 WIFI_PHY_RATE_MCS5_SGI = 0x1D, /**< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz */
59 WIFI_PHY_RATE_MCS6_SGI = 0x1E, /**< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */
60 WIFI_PHY_RATE_MCS7_SGI = 0x1F, /**< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz */
61 WIFI_PHY_RATE_LORA_250K = 0x29, /**< 250 Kbps */
62 WIFI_PHY_RATE_LORA_500K = 0x2A, /**< 500 Kbps */
63 WIFI_PHY_RATE_MAX,
64} wifi_phy_rate_t;
65
66/* Supported rates to be advertised to the cfg80211 */
67static struct ieee80211_rate esp_rates[] = {
68 {.bitrate = 10, .hw_value = WIFI_PHY_RATE_1M_L, },
69 {.bitrate = 20, .hw_value = WIFI_PHY_RATE_2M_L, },
70 {.bitrate = 55, .hw_value = WIFI_PHY_RATE_5M_L, .hw_value_short = WIFI_PHY_RATE_5M_S},
71 {.bitrate = 110, .hw_value = WIFI_PHY_RATE_11M_L, .hw_value_short = WIFI_PHY_RATE_11M_S},
72 {.bitrate = 60, .hw_value = WIFI_PHY_RATE_6M, },
73 {.bitrate = 90, .hw_value = WIFI_PHY_RATE_9M, },
74 {.bitrate = 120, .hw_value = WIFI_PHY_RATE_12M, },
75 {.bitrate = 180, .hw_value = WIFI_PHY_RATE_18M, },
76 {.bitrate = 240, .hw_value = WIFI_PHY_RATE_24M, },
77 {.bitrate = 360, .hw_value = WIFI_PHY_RATE_36M, },
78 {.bitrate = 480, .hw_value = WIFI_PHY_RATE_48M, },
79 {.bitrate = 540, .hw_value = WIFI_PHY_RATE_54M, },
80};
81
82
83/* Channel definitions to be advertised to cfg80211 */
84static struct ieee80211_channel esp_channels_2ghz[] = {
85 {.center_freq = 2412, .hw_value = 1, },
86 {.center_freq = 2417, .hw_value = 2, },
87 {.center_freq = 2422, .hw_value = 3, },
88 {.center_freq = 2427, .hw_value = 4, },
89 {.center_freq = 2432, .hw_value = 5, },
90 {.center_freq = 2437, .hw_value = 6, },
91 {.center_freq = 2442, .hw_value = 7, },
92 {.center_freq = 2447, .hw_value = 8, },
93 {.center_freq = 2452, .hw_value = 9, },
94 {.center_freq = 2457, .hw_value = 10, },
95 {.center_freq = 2462, .hw_value = 11, },
96 {.center_freq = 2467, .hw_value = 12, },
97 {.center_freq = 2472, .hw_value = 13, },
98 {.center_freq = 2484, .hw_value = 14, },
99};
100
101static struct ieee80211_supported_band esp_wifi_bands = {
102 .channels = esp_channels_2ghz,
103 .n_channels = ARRAY_SIZE(esp_channels_2ghz),
104 .bitrates = esp_rates,
105 .n_bitrates = ARRAY_SIZE(esp_rates),
106};
107
108/* Supported crypto cipher suits to be advertised to cfg80211 */
109static const u32 esp_cipher_suites[] = {
110 WLAN_CIPHER_SUITE_WEP40,
111 WLAN_CIPHER_SUITE_WEP104,
112 WLAN_CIPHER_SUITE_TKIP,
113 WLAN_CIPHER_SUITE_CCMP,
114 WLAN_CIPHER_SUITE_SMS4,
115 WLAN_CIPHER_SUITE_AES_CMAC,
116};
117
118struct wireless_dev *esp_cfg80211_add_iface(struct wiphy *wiphy,
119 const char *name,
120 unsigned char name_assign_type,
121 enum nl80211_iftype type,
122 struct vif_params *params)
123{
124 struct esp_device *esp_dev = wiphy_priv(wiphy);
125/* struct wireless_dev *wdev = NULL;*/
126 struct net_device *ndev;
127 struct esp_wifi_device *esp_wdev;
128 uint8_t esp_nw_if_num = 0;
129
130 if (NL80211_IFTYPE_STATION == type) {
131 esp_nw_if_num = ESP_STA_NW_IF;
132 } else if (NL80211_IFTYPE_AP == type) {
133 esp_nw_if_num = ESP_AP_NW_IF;
134 } else {
135 printk(KERN_INFO "%s:%u network type[%u] is not supported\n",
136 __func__, __LINE__, type);
137 return NULL;
138 }
139
140 ndev = alloc_netdev(sizeof(struct esp_wifi_device), name, name_assign_type,
141 ether_setup);
142
143 if (!ndev)
144 return ERR_PTR(-ENOMEM);
145
225e14eb 146 set_bit(ESP_DRIVER_ACTIVE, &esp_dev->adapter->state_flags);
774e9b2e
MM
147 esp_wdev = netdev_priv(ndev);
148
149 ndev->ieee80211_ptr = &esp_wdev->wdev;
150 esp_wdev->wdev.wiphy = wiphy;
151 esp_wdev->esp_dev = esp_dev;
152 esp_wdev->ndev = ndev;
153 esp_wdev->adapter = esp_dev->adapter;
154 esp_wdev->adapter->priv[esp_nw_if_num] = esp_wdev;
155 /*printk(KERN_INFO "Updated priv[%u] to %px\n",
156 * esp_nw_if_num, esp_wdev->adapter->priv[esp_nw_if_num]);*/
157 dev_net_set(ndev, wiphy_net(wiphy));
158 SET_NETDEV_DEV(ndev, wiphy_dev(esp_wdev->wdev.wiphy));
159 esp_wdev->wdev.netdev = ndev;
160 esp_wdev->wdev.iftype = type;
161
162 init_waitqueue_head(&esp_wdev->wait_for_scan_completion);
163 esp_wdev->stop_data = 1;
164 esp_wdev->port_open = 0;
165
166 if (cmd_init_interface(esp_wdev))
167 goto free_and_return;
168
169 if (cmd_get_mac(esp_wdev))
170 goto free_and_return;
171
172/* memcpy(ndev->dev_addr, esp_wdev->mac_address, ETH_ALEN);*/
173 ether_addr_copy(ndev->dev_addr, esp_wdev->mac_address);
174
175 esp_init_priv(ndev);
176
177 if (register_netdevice(ndev))
178 goto free_and_return;
179
180
181 set_bit(ESP_NETWORK_UP, &esp_wdev->priv_flags);
225e14eb
YM
182 clear_bit(ESP_CLEANUP_IN_PROGRESS, &esp_dev->adapter->state_flags);
183
774e9b2e
MM
184 return &esp_wdev->wdev;
185
186free_and_return:
225e14eb 187 clear_bit(ESP_DRIVER_ACTIVE, &esp_wdev->adapter->state_flags);
774e9b2e
MM
188 dev_net_set(ndev, NULL);
189 free_netdev(ndev);
190 esp_wdev->ndev = NULL;
191 esp_wdev->wdev.netdev = NULL;
192 ndev = NULL;
193 return NULL;
194}
195
196#if 0
197static int esp_cfg80211_del_iface(struct wiphy *wiphy,
198 struct wireless_dev *wdev)
199{
200 return 0;
201}
202
203static int esp_cfg80211_change_iface(struct wiphy *wiphy,
204 struct net_device *ndev,
205 enum nl80211_iftype type,
206 struct vif_params *params)
207{
208 return 0;
209}
210#endif
211
212static int esp_cfg80211_scan(struct wiphy *wiphy,
213 struct cfg80211_scan_request *request)
214{
215 struct net_device *ndev = request->wdev->netdev;
216 struct esp_wifi_device *priv = netdev_priv(ndev);
217
218 if (!priv) {
219 printk(KERN_ERR "%s: empty priv\n", __func__);
220 return -EINVAL;
221 }
222
223 return cmd_scan_request(priv, request);
224}
225
226static int esp_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
227 struct cfg80211_connect_params *sme)
228{
229 struct esp_wifi_device *priv = netdev_priv(dev);
230
231 if (!priv) {
232 printk(KERN_ERR "%s: empty priv\n", __func__);
233 return -EINVAL;
234 }
235
236 return cmd_connect_request(priv, sme);
237}
238
239static int esp_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *dev,
240 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
241{
242 return 0;
243}
244
245static int esp_cfg80211_set_default_key(struct wiphy *wiphy,
246 struct net_device *dev, u8 key_index, bool unicast, bool multicast)
247{
248 struct esp_wifi_device *priv = netdev_priv(dev);
249
250 if (!priv) {
251 printk(KERN_ERR "%s: empty priv\n", __func__);
252 return -EINVAL;
253 }
254
255 return cmd_set_default_key(priv, key_index);
256}
257
258static int esp_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
259 u8 key_index, bool pairwise, const u8 *mac_addr)
260{
261 struct esp_wifi_device *priv = netdev_priv(dev);
262
263 if (!priv) {
264 printk(KERN_ERR "%s: empty priv\n", __func__);
265 return -EINVAL;
266 }
267
268 return cmd_del_key(priv, key_index, pairwise, mac_addr);
269}
270
271static int esp_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
272 u8 key_index, bool pairwise, const u8 *mac_addr,
273 struct key_params *params)
274{
275 struct esp_wifi_device *priv = netdev_priv(dev);
276
277 if (!priv) {
278 printk(KERN_ERR "%s: empty priv\n", __func__);
279 return -EINVAL;
280 }
281
282 if (params->key_len == 0)
283 return esp_cfg80211_del_key(wiphy, dev, key_index, pairwise, mac_addr);
284
285 return cmd_add_key(priv, key_index, pairwise, mac_addr, params);
286}
287
288static int esp_cfg80211_disconnect(struct wiphy *wiphy,
289 struct net_device *dev, u16 reason_code)
290{
291 struct esp_wifi_device *priv = netdev_priv(dev);
292
293 if (!priv) {
294 printk(KERN_ERR "%s: empty priv\n", __func__);
295 return 0;
296 }
297
298 return cmd_disconnect_request(priv, reason_code);
299}
300
301static struct cfg80211_ops esp_cfg80211_ops = {
302#if 0
303 .add_virtual_intf = esp_cfg80211_add_iface,
304 .del_virtual_intf = esp_cfg80211_del_iface,
305 .change_virtual_intf = esp_cfg80211_change_iface,
306#endif
307 .scan = esp_cfg80211_scan,
308 .connect = esp_cfg80211_connect,
309 .disconnect = esp_cfg80211_disconnect,
310 .add_key = esp_cfg80211_add_key,
311 .del_key = esp_cfg80211_del_key,
312 .set_default_key = esp_cfg80211_set_default_key,
313 .mgmt_tx = esp_cfg80211_mgmt_tx,
314};
315
316int esp_cfg80211_register(struct esp_adapter *adapter)
317{
318 struct wiphy *wiphy;
319 struct esp_device *esp_dev;
320 int ret = 0;
321
322 wiphy = wiphy_new(&esp_cfg80211_ops, sizeof(struct esp_device));
323
324 if (!wiphy) {
325 printk(KERN_ERR "Failed to create wiphy\n");
326 return -EFAULT;
327 }
328
329 adapter->wiphy = wiphy;
330
331 esp_dev = wiphy_priv(wiphy);
332 esp_dev->wiphy = wiphy;
333 esp_dev->adapter = adapter;
334
335 esp_dev->dev = adapter->dev;
336
337 set_wiphy_dev(wiphy, esp_dev->dev);
338
339 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
340 wiphy->bands[NL80211_BAND_2GHZ] = &esp_wifi_bands;
341
342 /* Initialize cipher suits */
343 wiphy->cipher_suites = esp_cipher_suites;
344 wiphy->n_cipher_suites = ARRAY_SIZE(esp_cipher_suites);
345
346 /* TODO: check and finalize the numbers */
347 wiphy->max_scan_ssids = 10;
348 /* wiphy->max_match_sets = 10;*/
349 wiphy->max_scan_ie_len = 1000;
350 wiphy->max_sched_scan_ssids = 10;
351 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
352
353 ret = wiphy_register(wiphy);
354
355 return ret;
356}
357
225e14eb
YM
358int esp_mark_scan_done(struct esp_wifi_device *priv)
359{
360 struct cfg80211_scan_info info = {
361 .aborted = false,
362 };
363
364 if (!priv)
365 return -EINVAL;
366
367 if (priv->request)
368 cfg80211_scan_done(priv->request, &info);
369
370 priv->scan_in_progress = false;
371 priv->request = NULL;
372
373 return 0;
374}
375
376int esp_mark_disconnect(struct esp_wifi_device *priv, uint16_t reason,
377 uint8_t locally_disconnect)
378{
379 if (priv && priv->ndev)
380 cfg80211_disconnected(priv->ndev, reason, NULL, 0, locally_disconnect,
381 GFP_KERNEL);
382 return 0;
383}
384
385int esp_mark_scan_done_and_disconnect(struct esp_wifi_device *priv,
386 uint8_t locally_disconnect)
387{
388 struct net_device *ndev = NULL;
389 struct cfg80211_scan_info info = {
390 .aborted = false,
391 };
392
393 if (!priv)
394 return -EINVAL;
395
396 if (priv->request)
397 cfg80211_scan_done(priv->request, &info);
398
399 ESP_CANCEL_SCHED_SCAN();
400
401 priv->scan_in_progress = false;
402 priv->request = NULL;
403
404 /* clear cfg80211 states */
405 ndev = priv->ndev;
406 if (ndev) {
407 if (ndev->reg_state == NETREG_REGISTERED) {
408 cfg80211_disconnected(ndev, 0, NULL, 0, locally_disconnect,
409 GFP_KERNEL);
410 }
411 }
412 return 0;
413}
This page took 0.080065 seconds and 4 git commands to generate.