mwifiex: implement cfg80211 mgmt_frame_register handler
[deliverable/linux.git] / drivers / net / wireless / mwifiex / cfg80211.c
1 /*
2 * Marvell Wireless LAN device driver: CFG80211
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * 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 "cfg80211.h"
21 #include "main.h"
22
23 static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
24 {
25 .max = 1, .types = BIT(NL80211_IFTYPE_STATION),
26 },
27 {
28 .max = 1, .types = BIT(NL80211_IFTYPE_AP),
29 },
30 };
31
32 static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
33 .limits = mwifiex_ap_sta_limits,
34 .num_different_channels = 1,
35 .n_limits = ARRAY_SIZE(mwifiex_ap_sta_limits),
36 .max_interfaces = MWIFIEX_MAX_BSS_NUM,
37 .beacon_int_infra_match = true,
38 };
39
40 static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
41 .n_reg_rules = 7,
42 .alpha2 = "99",
43 .reg_rules = {
44 /* Channel 1 - 11 */
45 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
46 /* Channel 12 - 13 */
47 REG_RULE(2467-10, 2472+10, 20, 3, 20,
48 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
49 /* Channel 14 */
50 REG_RULE(2484-10, 2484+10, 20, 3, 20,
51 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
52 NL80211_RRF_NO_OFDM),
53 /* Channel 36 - 48 */
54 REG_RULE(5180-10, 5240+10, 40, 3, 20,
55 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
56 /* Channel 149 - 165 */
57 REG_RULE(5745-10, 5825+10, 40, 3, 20,
58 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
59 /* Channel 52 - 64 */
60 REG_RULE(5260-10, 5320+10, 40, 3, 30,
61 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
62 NL80211_RRF_DFS),
63 /* Channel 100 - 140 */
64 REG_RULE(5500-10, 5700+10, 40, 3, 30,
65 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
66 NL80211_RRF_DFS),
67 }
68 };
69
70 /*
71 * This function maps the nl802.11 channel type into driver channel type.
72 *
73 * The mapping is as follows -
74 * NL80211_CHAN_NO_HT -> IEEE80211_HT_PARAM_CHA_SEC_NONE
75 * NL80211_CHAN_HT20 -> IEEE80211_HT_PARAM_CHA_SEC_NONE
76 * NL80211_CHAN_HT40PLUS -> IEEE80211_HT_PARAM_CHA_SEC_ABOVE
77 * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW
78 * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE
79 */
80 static u8
81 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
82 {
83 switch (chan_type) {
84 case NL80211_CHAN_NO_HT:
85 case NL80211_CHAN_HT20:
86 return IEEE80211_HT_PARAM_CHA_SEC_NONE;
87 case NL80211_CHAN_HT40PLUS:
88 return IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
89 case NL80211_CHAN_HT40MINUS:
90 return IEEE80211_HT_PARAM_CHA_SEC_BELOW;
91 default:
92 return IEEE80211_HT_PARAM_CHA_SEC_NONE;
93 }
94 }
95
96 /*
97 * This function checks whether WEP is set.
98 */
99 static int
100 mwifiex_is_alg_wep(u32 cipher)
101 {
102 switch (cipher) {
103 case WLAN_CIPHER_SUITE_WEP40:
104 case WLAN_CIPHER_SUITE_WEP104:
105 return 1;
106 default:
107 break;
108 }
109
110 return 0;
111 }
112
113 /*
114 * This function retrieves the private structure from kernel wiphy structure.
115 */
116 static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy)
117 {
118 return (void *) (*(unsigned long *) wiphy_priv(wiphy));
119 }
120
121 /*
122 * CFG802.11 operation handler to delete a network key.
123 */
124 static int
125 mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
126 u8 key_index, bool pairwise, const u8 *mac_addr)
127 {
128 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
129 const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
130 const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
131
132 if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
133 wiphy_err(wiphy, "deleting the crypto keys\n");
134 return -EFAULT;
135 }
136
137 wiphy_dbg(wiphy, "info: crypto keys deleted\n");
138 return 0;
139 }
140
141 /*
142 * This function forms an skb for management frame.
143 */
144 static int
145 mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
146 {
147 u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
148 u16 pkt_len;
149 u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
150 struct timeval tv;
151
152 pkt_len = len + ETH_ALEN;
153
154 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN +
155 MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
156 memcpy(skb_push(skb, sizeof(pkt_len)), &pkt_len, sizeof(pkt_len));
157
158 memcpy(skb_push(skb, sizeof(tx_control)),
159 &tx_control, sizeof(tx_control));
160
161 memcpy(skb_push(skb, sizeof(pkt_type)), &pkt_type, sizeof(pkt_type));
162
163 /* Add packet data and address4 */
164 memcpy(skb_put(skb, sizeof(struct ieee80211_hdr_3addr)), buf,
165 sizeof(struct ieee80211_hdr_3addr));
166 memcpy(skb_put(skb, ETH_ALEN), addr, ETH_ALEN);
167 memcpy(skb_put(skb, len - sizeof(struct ieee80211_hdr_3addr)),
168 buf + sizeof(struct ieee80211_hdr_3addr),
169 len - sizeof(struct ieee80211_hdr_3addr));
170
171 skb->priority = LOW_PRIO_TID;
172 do_gettimeofday(&tv);
173 skb->tstamp = timeval_to_ktime(tv);
174
175 return 0;
176 }
177
178 /*
179 * CFG802.11 operation handler to transmit a management frame.
180 */
181 static int
182 mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
183 struct ieee80211_channel *chan, bool offchan,
184 enum nl80211_channel_type channel_type,
185 bool channel_type_valid, unsigned int wait,
186 const u8 *buf, size_t len, bool no_cck,
187 bool dont_wait_for_ack, u64 *cookie)
188 {
189 struct sk_buff *skb;
190 u16 pkt_len;
191 const struct ieee80211_mgmt *mgmt;
192 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
193
194 if (!buf || !len) {
195 wiphy_err(wiphy, "invalid buffer and length\n");
196 return -EFAULT;
197 }
198
199 mgmt = (const struct ieee80211_mgmt *)buf;
200 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA &&
201 ieee80211_is_probe_resp(mgmt->frame_control)) {
202 /* Since we support offload probe resp, we need to skip probe
203 * resp in AP or GO mode */
204 wiphy_dbg(wiphy,
205 "info: skip to send probe resp in AP or GO mode\n");
206 return 0;
207 }
208
209 pkt_len = len + ETH_ALEN;
210 skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
211 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
212 pkt_len + sizeof(pkt_len));
213
214 if (!skb) {
215 wiphy_err(wiphy, "allocate skb failed for management frame\n");
216 return -ENOMEM;
217 }
218
219 mwifiex_form_mgmt_frame(skb, buf, len);
220 mwifiex_queue_tx_pkt(priv, skb);
221
222 *cookie = random32() | 1;
223 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC);
224
225 wiphy_dbg(wiphy, "info: management frame transmitted\n");
226 return 0;
227 }
228
229 /*
230 * CFG802.11 operation handler to register a mgmt frame.
231 */
232 static void
233 mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
234 struct wireless_dev *wdev,
235 u16 frame_type, bool reg)
236 {
237 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
238
239 if (reg)
240 priv->mgmt_frame_mask |= BIT(frame_type >> 4);
241 else
242 priv->mgmt_frame_mask &= ~BIT(frame_type >> 4);
243
244 mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
245 HostCmd_ACT_GEN_SET, 0, &priv->mgmt_frame_mask);
246
247 wiphy_dbg(wiphy, "info: mgmt frame registered\n");
248 }
249
250 /*
251 * CFG802.11 operation handler to set Tx power.
252 */
253 static int
254 mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
255 enum nl80211_tx_power_setting type,
256 int mbm)
257 {
258 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
259 struct mwifiex_private *priv;
260 struct mwifiex_power_cfg power_cfg;
261 int dbm = MBM_TO_DBM(mbm);
262
263 if (type == NL80211_TX_POWER_FIXED) {
264 power_cfg.is_power_auto = 0;
265 power_cfg.power_level = dbm;
266 } else {
267 power_cfg.is_power_auto = 1;
268 }
269
270 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
271
272 return mwifiex_set_tx_power(priv, &power_cfg);
273 }
274
275 /*
276 * CFG802.11 operation handler to set Power Save option.
277 *
278 * The timeout value, if provided, is currently ignored.
279 */
280 static int
281 mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
282 struct net_device *dev,
283 bool enabled, int timeout)
284 {
285 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
286 u32 ps_mode;
287
288 if (timeout)
289 wiphy_dbg(wiphy,
290 "info: ignore timeout value for IEEE Power Save\n");
291
292 ps_mode = enabled;
293
294 return mwifiex_drv_set_power(priv, &ps_mode);
295 }
296
297 /*
298 * CFG802.11 operation handler to set the default network key.
299 */
300 static int
301 mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
302 u8 key_index, bool unicast,
303 bool multicast)
304 {
305 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
306
307 /* Return if WEP key not configured */
308 if (!priv->sec_info.wep_enabled)
309 return 0;
310
311 if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
312 priv->wep_key_curr_index = key_index;
313 } else if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index,
314 NULL, 0)) {
315 wiphy_err(wiphy, "set default Tx key index\n");
316 return -EFAULT;
317 }
318
319 return 0;
320 }
321
322 /*
323 * CFG802.11 operation handler to add a network key.
324 */
325 static int
326 mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
327 u8 key_index, bool pairwise, const u8 *mac_addr,
328 struct key_params *params)
329 {
330 struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
331 struct mwifiex_wep_key *wep_key;
332 const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
333 const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
334
335 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
336 (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
337 params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
338 if (params->key && params->key_len) {
339 wep_key = &priv->wep_key[key_index];
340 memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
341 memcpy(wep_key->key_material, params->key,
342 params->key_len);
343 wep_key->key_index = key_index;
344 wep_key->key_length = params->key_len;
345 priv->sec_info.wep_enabled = 1;
346 }
347 return 0;
348 }
349
350 if (mwifiex_set_encode(priv, params, params->key, params->key_len,
351 key_index, peer_mac, 0)) {
352 wiphy_err(wiphy, "crypto keys added\n");
353 return -EFAULT;
354 }
355
356 return 0;
357 }
358
359 /*
360 * This function sends domain information to the firmware.
361 *
362 * The following information are passed to the firmware -
363 * - Country codes
364 * - Sub bands (first channel, number of channels, maximum Tx power)
365 */
366 static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
367 {
368 u8 no_of_triplet = 0;
369 struct ieee80211_country_ie_triplet *t;
370 u8 no_of_parsed_chan = 0;
371 u8 first_chan = 0, next_chan = 0, max_pwr = 0;
372 u8 i, flag = 0;
373 enum ieee80211_band band;
374 struct ieee80211_supported_band *sband;
375 struct ieee80211_channel *ch;
376 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
377 struct mwifiex_private *priv;
378 struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
379
380 /* Set country code */
381 domain_info->country_code[0] = adapter->country_code[0];
382 domain_info->country_code[1] = adapter->country_code[1];
383 domain_info->country_code[2] = ' ';
384
385 band = mwifiex_band_to_radio_type(adapter->config_bands);
386 if (!wiphy->bands[band]) {
387 wiphy_err(wiphy, "11D: setting domain info in FW\n");
388 return -1;
389 }
390
391 sband = wiphy->bands[band];
392
393 for (i = 0; i < sband->n_channels ; i++) {
394 ch = &sband->channels[i];
395 if (ch->flags & IEEE80211_CHAN_DISABLED)
396 continue;
397
398 if (!flag) {
399 flag = 1;
400 first_chan = (u32) ch->hw_value;
401 next_chan = first_chan;
402 max_pwr = ch->max_reg_power;
403 no_of_parsed_chan = 1;
404 continue;
405 }
406
407 if (ch->hw_value == next_chan + 1 &&
408 ch->max_reg_power == max_pwr) {
409 next_chan++;
410 no_of_parsed_chan++;
411 } else {
412 t = &domain_info->triplet[no_of_triplet];
413 t->chans.first_channel = first_chan;
414 t->chans.num_channels = no_of_parsed_chan;
415 t->chans.max_power = max_pwr;
416 no_of_triplet++;
417 first_chan = (u32) ch->hw_value;
418 next_chan = first_chan;
419 max_pwr = ch->max_reg_power;
420 no_of_parsed_chan = 1;
421 }
422 }
423
424 if (flag) {
425 t = &domain_info->triplet[no_of_triplet];
426 t->chans.first_channel = first_chan;
427 t->chans.num_channels = no_of_parsed_chan;
428 t->chans.max_power = max_pwr;
429 no_of_triplet++;
430 }
431
432 domain_info->no_of_triplet = no_of_triplet;
433
434 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
435
436 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
437 HostCmd_ACT_GEN_SET, 0, NULL)) {
438 wiphy_err(wiphy, "11D: setting domain info in FW\n");
439 return -1;
440 }
441
442 return 0;
443 }
444
445 /*
446 * CFG802.11 regulatory domain callback function.
447 *
448 * This function is called when the regulatory domain is changed due to the
449 * following reasons -
450 * - Set by driver
451 * - Set by system core
452 * - Set by user
453 * - Set bt Country IE
454 */
455 static int mwifiex_reg_notifier(struct wiphy *wiphy,
456 struct regulatory_request *request)
457 {
458 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
459
460 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n",
461 request->alpha2[0], request->alpha2[1]);
462
463 memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2));
464
465 switch (request->initiator) {
466 case NL80211_REGDOM_SET_BY_DRIVER:
467 case NL80211_REGDOM_SET_BY_CORE:
468 case NL80211_REGDOM_SET_BY_USER:
469 break;
470 /* Todo: apply driver specific changes in channel flags based
471 on the request initiator if necessary. */
472 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
473 break;
474 }
475 mwifiex_send_domain_info_cmd_fw(wiphy);
476
477 return 0;
478 }
479
480 /*
481 * This function sets the fragmentation threshold.
482 *
483 * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
484 * and MWIFIEX_FRAG_MAX_VALUE.
485 */
486 static int
487 mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
488 {
489 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
490 frag_thr > MWIFIEX_FRAG_MAX_VALUE)
491 frag_thr = MWIFIEX_FRAG_MAX_VALUE;
492
493 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
494 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
495 &frag_thr);
496 }
497
498 /*
499 * This function sets the RTS threshold.
500
501 * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
502 * and MWIFIEX_RTS_MAX_VALUE.
503 */
504 static int
505 mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
506 {
507 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
508 rts_thr = MWIFIEX_RTS_MAX_VALUE;
509
510 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
511 HostCmd_ACT_GEN_SET, RTS_THRESH_I,
512 &rts_thr);
513 }
514
515 /*
516 * CFG802.11 operation handler to set wiphy parameters.
517 *
518 * This function can be used to set the RTS threshold and the
519 * Fragmentation threshold of the driver.
520 */
521 static int
522 mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
523 {
524 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
525 struct mwifiex_private *priv;
526 struct mwifiex_uap_bss_param *bss_cfg;
527 int ret, bss_started, i;
528
529 for (i = 0; i < adapter->priv_num; i++) {
530 priv = adapter->priv[i];
531
532 switch (priv->bss_role) {
533 case MWIFIEX_BSS_ROLE_UAP:
534 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
535 GFP_KERNEL);
536 if (!bss_cfg)
537 return -ENOMEM;
538
539 mwifiex_set_sys_config_invalid_data(bss_cfg);
540
541 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
542 bss_cfg->rts_threshold = wiphy->rts_threshold;
543 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
544 bss_cfg->frag_threshold = wiphy->frag_threshold;
545 if (changed & WIPHY_PARAM_RETRY_LONG)
546 bss_cfg->retry_limit = wiphy->retry_long;
547
548 bss_started = priv->bss_started;
549
550 ret = mwifiex_send_cmd_sync(priv,
551 HostCmd_CMD_UAP_BSS_STOP,
552 HostCmd_ACT_GEN_SET, 0,
553 NULL);
554 if (ret) {
555 wiphy_err(wiphy, "Failed to stop the BSS\n");
556 kfree(bss_cfg);
557 return ret;
558 }
559
560 ret = mwifiex_send_cmd_async(priv,
561 HostCmd_CMD_UAP_SYS_CONFIG,
562 HostCmd_ACT_GEN_SET,
563 UAP_BSS_PARAMS_I, bss_cfg);
564
565 kfree(bss_cfg);
566
567 if (ret) {
568 wiphy_err(wiphy, "Failed to set bss config\n");
569 return ret;
570 }
571
572 if (!bss_started)
573 break;
574
575 ret = mwifiex_send_cmd_async(priv,
576 HostCmd_CMD_UAP_BSS_START,
577 HostCmd_ACT_GEN_SET, 0,
578 NULL);
579 if (ret) {
580 wiphy_err(wiphy, "Failed to start BSS\n");
581 return ret;
582 }
583
584 break;
585 case MWIFIEX_BSS_ROLE_STA:
586 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
587 ret = mwifiex_set_rts(priv,
588 wiphy->rts_threshold);
589 if (ret)
590 return ret;
591 }
592 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
593 ret = mwifiex_set_frag(priv,
594 wiphy->frag_threshold);
595 if (ret)
596 return ret;
597 }
598 break;
599 }
600 }
601
602 return 0;
603 }
604
605 /*
606 * CFG802.11 operation handler to change interface type.
607 */
608 static int
609 mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
610 struct net_device *dev,
611 enum nl80211_iftype type, u32 *flags,
612 struct vif_params *params)
613 {
614 int ret;
615 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
616
617 switch (dev->ieee80211_ptr->iftype) {
618 case NL80211_IFTYPE_ADHOC:
619 switch (type) {
620 case NL80211_IFTYPE_STATION:
621 break;
622 case NL80211_IFTYPE_UNSPECIFIED:
623 wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
624 case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
625 return 0;
626 case NL80211_IFTYPE_AP:
627 default:
628 wiphy_err(wiphy, "%s: changing to %d not supported\n",
629 dev->name, type);
630 return -EOPNOTSUPP;
631 }
632 break;
633 case NL80211_IFTYPE_STATION:
634 switch (type) {
635 case NL80211_IFTYPE_ADHOC:
636 break;
637 case NL80211_IFTYPE_UNSPECIFIED:
638 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
639 case NL80211_IFTYPE_STATION: /* This shouldn't happen */
640 return 0;
641 case NL80211_IFTYPE_AP:
642 default:
643 wiphy_err(wiphy, "%s: changing to %d not supported\n",
644 dev->name, type);
645 return -EOPNOTSUPP;
646 }
647 break;
648 case NL80211_IFTYPE_AP:
649 switch (type) {
650 case NL80211_IFTYPE_UNSPECIFIED:
651 wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
652 case NL80211_IFTYPE_AP: /* This shouldn't happen */
653 return 0;
654 case NL80211_IFTYPE_ADHOC:
655 case NL80211_IFTYPE_STATION:
656 default:
657 wiphy_err(wiphy, "%s: changing to %d not supported\n",
658 dev->name, type);
659 return -EOPNOTSUPP;
660 }
661 break;
662 default:
663 wiphy_err(wiphy, "%s: unknown iftype: %d\n",
664 dev->name, dev->ieee80211_ptr->iftype);
665 return -EOPNOTSUPP;
666 }
667
668 dev->ieee80211_ptr->iftype = type;
669 priv->bss_mode = type;
670 mwifiex_deauthenticate(priv, NULL);
671
672 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
673
674 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
675 HostCmd_ACT_GEN_SET, 0, NULL);
676
677 return ret;
678 }
679
680 /*
681 * This function dumps the station information on a buffer.
682 *
683 * The following information are shown -
684 * - Total bytes transmitted
685 * - Total bytes received
686 * - Total packets transmitted
687 * - Total packets received
688 * - Signal quality level
689 * - Transmission rate
690 */
691 static int
692 mwifiex_dump_station_info(struct mwifiex_private *priv,
693 struct station_info *sinfo)
694 {
695 u32 rate;
696
697 sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES |
698 STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS |
699 STATION_INFO_TX_BITRATE |
700 STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
701
702 /* Get signal information from the firmware */
703 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO,
704 HostCmd_ACT_GEN_GET, 0, NULL)) {
705 dev_err(priv->adapter->dev, "failed to get signal information\n");
706 return -EFAULT;
707 }
708
709 if (mwifiex_drv_get_data_rate(priv, &rate)) {
710 dev_err(priv->adapter->dev, "getting data rate\n");
711 return -EFAULT;
712 }
713
714 /* Get DTIM period information from firmware */
715 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
716 HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
717 &priv->dtim_period);
718
719 /*
720 * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
721 * MCS index values for us are 0 to 15.
722 */
723 if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
724 sinfo->txrate.mcs = priv->tx_rate;
725 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
726 /* 40MHz rate */
727 if (priv->tx_htinfo & BIT(1))
728 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
729 /* SGI enabled */
730 if (priv->tx_htinfo & BIT(2))
731 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
732 }
733
734 sinfo->signal_avg = priv->bcn_rssi_avg;
735 sinfo->rx_bytes = priv->stats.rx_bytes;
736 sinfo->tx_bytes = priv->stats.tx_bytes;
737 sinfo->rx_packets = priv->stats.rx_packets;
738 sinfo->tx_packets = priv->stats.tx_packets;
739 sinfo->signal = priv->bcn_rssi_avg;
740 /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
741 sinfo->txrate.legacy = rate * 5;
742
743 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
744 sinfo->filled |= STATION_INFO_BSS_PARAM;
745 sinfo->bss_param.flags = 0;
746 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
747 WLAN_CAPABILITY_SHORT_PREAMBLE)
748 sinfo->bss_param.flags |=
749 BSS_PARAM_FLAGS_SHORT_PREAMBLE;
750 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
751 WLAN_CAPABILITY_SHORT_SLOT_TIME)
752 sinfo->bss_param.flags |=
753 BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
754 sinfo->bss_param.dtim_period = priv->dtim_period;
755 sinfo->bss_param.beacon_interval =
756 priv->curr_bss_params.bss_descriptor.beacon_period;
757 }
758
759 return 0;
760 }
761
762 /*
763 * CFG802.11 operation handler to get station information.
764 *
765 * This function only works in connected mode, and dumps the
766 * requested station information, if available.
767 */
768 static int
769 mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
770 u8 *mac, struct station_info *sinfo)
771 {
772 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
773
774 if (!priv->media_connected)
775 return -ENOENT;
776 if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
777 return -ENOENT;
778
779 return mwifiex_dump_station_info(priv, sinfo);
780 }
781
782 /*
783 * CFG802.11 operation handler to dump station information.
784 */
785 static int
786 mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
787 int idx, u8 *mac, struct station_info *sinfo)
788 {
789 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
790
791 if (!priv->media_connected || idx)
792 return -ENOENT;
793
794 memcpy(mac, priv->cfg_bssid, ETH_ALEN);
795
796 return mwifiex_dump_station_info(priv, sinfo);
797 }
798
799 /* Supported rates to be advertised to the cfg80211 */
800 static struct ieee80211_rate mwifiex_rates[] = {
801 {.bitrate = 10, .hw_value = 2, },
802 {.bitrate = 20, .hw_value = 4, },
803 {.bitrate = 55, .hw_value = 11, },
804 {.bitrate = 110, .hw_value = 22, },
805 {.bitrate = 60, .hw_value = 12, },
806 {.bitrate = 90, .hw_value = 18, },
807 {.bitrate = 120, .hw_value = 24, },
808 {.bitrate = 180, .hw_value = 36, },
809 {.bitrate = 240, .hw_value = 48, },
810 {.bitrate = 360, .hw_value = 72, },
811 {.bitrate = 480, .hw_value = 96, },
812 {.bitrate = 540, .hw_value = 108, },
813 };
814
815 /* Channel definitions to be advertised to cfg80211 */
816 static struct ieee80211_channel mwifiex_channels_2ghz[] = {
817 {.center_freq = 2412, .hw_value = 1, },
818 {.center_freq = 2417, .hw_value = 2, },
819 {.center_freq = 2422, .hw_value = 3, },
820 {.center_freq = 2427, .hw_value = 4, },
821 {.center_freq = 2432, .hw_value = 5, },
822 {.center_freq = 2437, .hw_value = 6, },
823 {.center_freq = 2442, .hw_value = 7, },
824 {.center_freq = 2447, .hw_value = 8, },
825 {.center_freq = 2452, .hw_value = 9, },
826 {.center_freq = 2457, .hw_value = 10, },
827 {.center_freq = 2462, .hw_value = 11, },
828 {.center_freq = 2467, .hw_value = 12, },
829 {.center_freq = 2472, .hw_value = 13, },
830 {.center_freq = 2484, .hw_value = 14, },
831 };
832
833 static struct ieee80211_supported_band mwifiex_band_2ghz = {
834 .channels = mwifiex_channels_2ghz,
835 .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
836 .bitrates = mwifiex_rates,
837 .n_bitrates = ARRAY_SIZE(mwifiex_rates),
838 };
839
840 static struct ieee80211_channel mwifiex_channels_5ghz[] = {
841 {.center_freq = 5040, .hw_value = 8, },
842 {.center_freq = 5060, .hw_value = 12, },
843 {.center_freq = 5080, .hw_value = 16, },
844 {.center_freq = 5170, .hw_value = 34, },
845 {.center_freq = 5190, .hw_value = 38, },
846 {.center_freq = 5210, .hw_value = 42, },
847 {.center_freq = 5230, .hw_value = 46, },
848 {.center_freq = 5180, .hw_value = 36, },
849 {.center_freq = 5200, .hw_value = 40, },
850 {.center_freq = 5220, .hw_value = 44, },
851 {.center_freq = 5240, .hw_value = 48, },
852 {.center_freq = 5260, .hw_value = 52, },
853 {.center_freq = 5280, .hw_value = 56, },
854 {.center_freq = 5300, .hw_value = 60, },
855 {.center_freq = 5320, .hw_value = 64, },
856 {.center_freq = 5500, .hw_value = 100, },
857 {.center_freq = 5520, .hw_value = 104, },
858 {.center_freq = 5540, .hw_value = 108, },
859 {.center_freq = 5560, .hw_value = 112, },
860 {.center_freq = 5580, .hw_value = 116, },
861 {.center_freq = 5600, .hw_value = 120, },
862 {.center_freq = 5620, .hw_value = 124, },
863 {.center_freq = 5640, .hw_value = 128, },
864 {.center_freq = 5660, .hw_value = 132, },
865 {.center_freq = 5680, .hw_value = 136, },
866 {.center_freq = 5700, .hw_value = 140, },
867 {.center_freq = 5745, .hw_value = 149, },
868 {.center_freq = 5765, .hw_value = 153, },
869 {.center_freq = 5785, .hw_value = 157, },
870 {.center_freq = 5805, .hw_value = 161, },
871 {.center_freq = 5825, .hw_value = 165, },
872 };
873
874 static struct ieee80211_supported_band mwifiex_band_5ghz = {
875 .channels = mwifiex_channels_5ghz,
876 .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
877 .bitrates = mwifiex_rates + 4,
878 .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4,
879 };
880
881
882 /* Supported crypto cipher suits to be advertised to cfg80211 */
883 static const u32 mwifiex_cipher_suites[] = {
884 WLAN_CIPHER_SUITE_WEP40,
885 WLAN_CIPHER_SUITE_WEP104,
886 WLAN_CIPHER_SUITE_TKIP,
887 WLAN_CIPHER_SUITE_CCMP,
888 WLAN_CIPHER_SUITE_AES_CMAC,
889 };
890
891 /* Supported mgmt frame types to be advertised to cfg80211 */
892 static const struct ieee80211_txrx_stypes
893 mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES] = {
894 [NL80211_IFTYPE_STATION] = {
895 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
896 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
897 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
898 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
899 },
900 [NL80211_IFTYPE_AP] = {
901 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
902 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
903 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
904 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
905 },
906 [NL80211_IFTYPE_P2P_CLIENT] = {
907 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
908 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
909 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
910 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
911 },
912 [NL80211_IFTYPE_P2P_GO] = {
913 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
914 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
915 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
916 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
917 },
918 };
919
920 /*
921 * CFG802.11 operation handler for setting bit rates.
922 *
923 * Function configures data rates to firmware using bitrate mask
924 * provided by cfg80211.
925 */
926 static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
927 struct net_device *dev,
928 const u8 *peer,
929 const struct cfg80211_bitrate_mask *mask)
930 {
931 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
932 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
933 enum ieee80211_band band;
934
935 if (!priv->media_connected) {
936 dev_err(priv->adapter->dev,
937 "Can not set Tx data rate in disconnected state\n");
938 return -EINVAL;
939 }
940
941 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
942
943 memset(bitmap_rates, 0, sizeof(bitmap_rates));
944
945 /* Fill HR/DSSS rates. */
946 if (band == IEEE80211_BAND_2GHZ)
947 bitmap_rates[0] = mask->control[band].legacy & 0x000f;
948
949 /* Fill OFDM rates */
950 if (band == IEEE80211_BAND_2GHZ)
951 bitmap_rates[1] = (mask->control[band].legacy & 0x0ff0) >> 4;
952 else
953 bitmap_rates[1] = mask->control[band].legacy;
954
955 /* Fill MCS rates */
956 bitmap_rates[2] = mask->control[band].mcs[0];
957 if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2)
958 bitmap_rates[2] |= mask->control[band].mcs[1] << 8;
959
960 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
961 HostCmd_ACT_GEN_SET, 0, bitmap_rates);
962 }
963
964 /*
965 * CFG802.11 operation handler for connection quality monitoring.
966 *
967 * This function subscribes/unsubscribes HIGH_RSSI and LOW_RSSI
968 * events to FW.
969 */
970 static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
971 struct net_device *dev,
972 s32 rssi_thold, u32 rssi_hyst)
973 {
974 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
975 struct mwifiex_ds_misc_subsc_evt subsc_evt;
976
977 priv->cqm_rssi_thold = rssi_thold;
978 priv->cqm_rssi_hyst = rssi_hyst;
979
980 memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
981 subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
982
983 /* Subscribe/unsubscribe low and high rssi events */
984 if (rssi_thold && rssi_hyst) {
985 subsc_evt.action = HostCmd_ACT_BITWISE_SET;
986 subsc_evt.bcn_l_rssi_cfg.abs_value = abs(rssi_thold);
987 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold);
988 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
989 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
990 return mwifiex_send_cmd_sync(priv,
991 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
992 0, 0, &subsc_evt);
993 } else {
994 subsc_evt.action = HostCmd_ACT_BITWISE_CLR;
995 return mwifiex_send_cmd_sync(priv,
996 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
997 0, 0, &subsc_evt);
998 }
999
1000 return 0;
1001 }
1002
1003 /* cfg80211 operation handler for change_beacon.
1004 * Function retrieves and sets modified management IEs to FW.
1005 */
1006 static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
1007 struct net_device *dev,
1008 struct cfg80211_beacon_data *data)
1009 {
1010 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1011
1012 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
1013 wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
1014 return -EINVAL;
1015 }
1016
1017 if (!priv->bss_started) {
1018 wiphy_err(wiphy, "%s: bss not started\n", __func__);
1019 return -EINVAL;
1020 }
1021
1022 if (mwifiex_set_mgmt_ies(priv, data)) {
1023 wiphy_err(wiphy, "%s: setting mgmt ies failed\n", __func__);
1024 return -EFAULT;
1025 }
1026
1027 return 0;
1028 }
1029
1030 static int
1031 mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1032 {
1033 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
1034 struct mwifiex_private *priv = mwifiex_get_priv(adapter,
1035 MWIFIEX_BSS_ROLE_ANY);
1036 struct mwifiex_ds_ant_cfg ant_cfg;
1037
1038 if (!tx_ant || !rx_ant)
1039 return -EOPNOTSUPP;
1040
1041 if (adapter->hw_dev_mcs_support != HT_STREAM_2X2) {
1042 /* Not a MIMO chip. User should provide specific antenna number
1043 * for Tx/Rx path or enable all antennas for diversity
1044 */
1045 if (tx_ant != rx_ant)
1046 return -EOPNOTSUPP;
1047
1048 if ((tx_ant & (tx_ant - 1)) &&
1049 (tx_ant != BIT(adapter->number_of_antenna) - 1))
1050 return -EOPNOTSUPP;
1051
1052 if ((tx_ant == BIT(adapter->number_of_antenna) - 1) &&
1053 (priv->adapter->number_of_antenna > 1)) {
1054 tx_ant = RF_ANTENNA_AUTO;
1055 rx_ant = RF_ANTENNA_AUTO;
1056 }
1057 }
1058
1059 ant_cfg.tx_ant = tx_ant;
1060 ant_cfg.rx_ant = rx_ant;
1061
1062 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_ANTENNA,
1063 HostCmd_ACT_GEN_SET, 0, &ant_cfg);
1064 }
1065
1066 /* cfg80211 operation handler for stop ap.
1067 * Function stops BSS running at uAP interface.
1068 */
1069 static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1070 {
1071 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1072
1073 if (mwifiex_del_mgmt_ies(priv))
1074 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
1075
1076 priv->ap_11n_enabled = 0;
1077
1078 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
1079 HostCmd_ACT_GEN_SET, 0, NULL)) {
1080 wiphy_err(wiphy, "Failed to stop the BSS\n");
1081 return -1;
1082 }
1083
1084 return 0;
1085 }
1086
1087 /* cfg80211 operation handler for start_ap.
1088 * Function sets beacon period, DTIM period, SSID and security into
1089 * AP config structure.
1090 * AP is configured with these settings and BSS is started.
1091 */
1092 static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1093 struct net_device *dev,
1094 struct cfg80211_ap_settings *params)
1095 {
1096 struct mwifiex_uap_bss_param *bss_cfg;
1097 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1098 u8 config_bands = 0;
1099
1100 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP)
1101 return -1;
1102 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1103 return -1;
1104
1105 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
1106 if (!bss_cfg)
1107 return -ENOMEM;
1108
1109 mwifiex_set_sys_config_invalid_data(bss_cfg);
1110
1111 if (params->beacon_interval)
1112 bss_cfg->beacon_period = params->beacon_interval;
1113 if (params->dtim_period)
1114 bss_cfg->dtim_period = params->dtim_period;
1115
1116 if (params->ssid && params->ssid_len) {
1117 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
1118 bss_cfg->ssid.ssid_len = params->ssid_len;
1119 }
1120
1121 switch (params->hidden_ssid) {
1122 case NL80211_HIDDEN_SSID_NOT_IN_USE:
1123 bss_cfg->bcast_ssid_ctl = 1;
1124 break;
1125 case NL80211_HIDDEN_SSID_ZERO_LEN:
1126 bss_cfg->bcast_ssid_ctl = 0;
1127 break;
1128 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
1129 /* firmware doesn't support this type of hidden SSID */
1130 default:
1131 kfree(bss_cfg);
1132 return -EINVAL;
1133 }
1134
1135 bss_cfg->channel =
1136 (u8)ieee80211_frequency_to_channel(params->channel->center_freq);
1137
1138 /* Set appropriate bands */
1139 if (params->channel->band == IEEE80211_BAND_2GHZ) {
1140 bss_cfg->band_cfg = BAND_CONFIG_BG;
1141
1142 if (params->channel_type == NL80211_CHAN_NO_HT)
1143 config_bands = BAND_B | BAND_G;
1144 else
1145 config_bands = BAND_B | BAND_G | BAND_GN;
1146 } else {
1147 bss_cfg->band_cfg = BAND_CONFIG_A;
1148
1149 if (params->channel_type == NL80211_CHAN_NO_HT)
1150 config_bands = BAND_A;
1151 else
1152 config_bands = BAND_AN | BAND_A;
1153 }
1154
1155 if (!((config_bands | priv->adapter->fw_bands) &
1156 ~priv->adapter->fw_bands))
1157 priv->adapter->config_bands = config_bands;
1158
1159 mwifiex_set_uap_rates(bss_cfg, params);
1160 mwifiex_send_domain_info_cmd_fw(wiphy);
1161
1162 if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
1163 kfree(bss_cfg);
1164 wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
1165 return -1;
1166 }
1167
1168 mwifiex_set_ht_params(priv, bss_cfg, params);
1169
1170 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
1171 HostCmd_ACT_GEN_SET, 0, NULL)) {
1172 wiphy_err(wiphy, "Failed to stop the BSS\n");
1173 kfree(bss_cfg);
1174 return -1;
1175 }
1176
1177 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
1178 HostCmd_ACT_GEN_SET,
1179 UAP_BSS_PARAMS_I, bss_cfg)) {
1180 wiphy_err(wiphy, "Failed to set the SSID\n");
1181 kfree(bss_cfg);
1182 return -1;
1183 }
1184
1185 kfree(bss_cfg);
1186
1187 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START,
1188 HostCmd_ACT_GEN_SET, 0, NULL)) {
1189 wiphy_err(wiphy, "Failed to start the BSS\n");
1190 return -1;
1191 }
1192
1193 if (priv->sec_info.wep_enabled)
1194 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
1195 else
1196 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1197
1198 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
1199 HostCmd_ACT_GEN_SET, 0,
1200 &priv->curr_pkt_filter))
1201 return -1;
1202
1203 return 0;
1204 }
1205
1206 /*
1207 * CFG802.11 operation handler for disconnection request.
1208 *
1209 * This function does not work when there is already a disconnection
1210 * procedure going on.
1211 */
1212 static int
1213 mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1214 u16 reason_code)
1215 {
1216 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1217
1218 if (mwifiex_deauthenticate(priv, NULL))
1219 return -EFAULT;
1220
1221 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
1222 " reason code %d\n", priv->cfg_bssid, reason_code);
1223
1224 memset(priv->cfg_bssid, 0, ETH_ALEN);
1225
1226 return 0;
1227 }
1228
1229 /*
1230 * This function informs the CFG802.11 subsystem of a new IBSS.
1231 *
1232 * The following information are sent to the CFG802.11 subsystem
1233 * to register the new IBSS. If we do not register the new IBSS,
1234 * a kernel panic will result.
1235 * - SSID
1236 * - SSID length
1237 * - BSSID
1238 * - Channel
1239 */
1240 static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
1241 {
1242 struct ieee80211_channel *chan;
1243 struct mwifiex_bss_info bss_info;
1244 struct cfg80211_bss *bss;
1245 int ie_len;
1246 u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
1247 enum ieee80211_band band;
1248
1249 if (mwifiex_get_bss_info(priv, &bss_info))
1250 return -1;
1251
1252 ie_buf[0] = WLAN_EID_SSID;
1253 ie_buf[1] = bss_info.ssid.ssid_len;
1254
1255 memcpy(&ie_buf[sizeof(struct ieee_types_header)],
1256 &bss_info.ssid.ssid, bss_info.ssid.ssid_len);
1257 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
1258
1259 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1260 chan = __ieee80211_get_channel(priv->wdev->wiphy,
1261 ieee80211_channel_to_frequency(bss_info.bss_chan,
1262 band));
1263
1264 bss = cfg80211_inform_bss(priv->wdev->wiphy, chan,
1265 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
1266 0, ie_buf, ie_len, 0, GFP_KERNEL);
1267 cfg80211_put_bss(bss);
1268 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
1269
1270 return 0;
1271 }
1272
1273 /*
1274 * This function connects with a BSS.
1275 *
1276 * This function handles both Infra and Ad-Hoc modes. It also performs
1277 * validity checking on the provided parameters, disconnects from the
1278 * current BSS (if any), sets up the association/scan parameters,
1279 * including security settings, and performs specific SSID scan before
1280 * trying to connect.
1281 *
1282 * For Infra mode, the function returns failure if the specified SSID
1283 * is not found in scan table. However, for Ad-Hoc mode, it can create
1284 * the IBSS if it does not exist. On successful completion in either case,
1285 * the function notifies the CFG802.11 subsystem of the new BSS connection.
1286 */
1287 static int
1288 mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
1289 u8 *bssid, int mode, struct ieee80211_channel *channel,
1290 struct cfg80211_connect_params *sme, bool privacy)
1291 {
1292 struct cfg80211_ssid req_ssid;
1293 int ret, auth_type = 0;
1294 struct cfg80211_bss *bss = NULL;
1295 u8 is_scanning_required = 0, config_bands = 0;
1296
1297 memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
1298
1299 req_ssid.ssid_len = ssid_len;
1300 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
1301 dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
1302 return -EINVAL;
1303 }
1304
1305 memcpy(req_ssid.ssid, ssid, ssid_len);
1306 if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
1307 dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
1308 return -EINVAL;
1309 }
1310
1311 /* disconnect before try to associate */
1312 mwifiex_deauthenticate(priv, NULL);
1313
1314 if (channel) {
1315 if (mode == NL80211_IFTYPE_STATION) {
1316 if (channel->band == IEEE80211_BAND_2GHZ)
1317 config_bands = BAND_B | BAND_G | BAND_GN;
1318 else
1319 config_bands = BAND_A | BAND_AN;
1320
1321 if (!((config_bands | priv->adapter->fw_bands) &
1322 ~priv->adapter->fw_bands))
1323 priv->adapter->config_bands = config_bands;
1324 }
1325 }
1326
1327 /* As this is new association, clear locally stored
1328 * keys and security related flags */
1329 priv->sec_info.wpa_enabled = false;
1330 priv->sec_info.wpa2_enabled = false;
1331 priv->wep_key_curr_index = 0;
1332 priv->sec_info.encryption_mode = 0;
1333 priv->sec_info.is_authtype_auto = 0;
1334 ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
1335
1336 if (mode == NL80211_IFTYPE_ADHOC) {
1337 /* "privacy" is set only for ad-hoc mode */
1338 if (privacy) {
1339 /*
1340 * Keep WLAN_CIPHER_SUITE_WEP104 for now so that
1341 * the firmware can find a matching network from the
1342 * scan. The cfg80211 does not give us the encryption
1343 * mode at this stage so just setting it to WEP here.
1344 */
1345 priv->sec_info.encryption_mode =
1346 WLAN_CIPHER_SUITE_WEP104;
1347 priv->sec_info.authentication_mode =
1348 NL80211_AUTHTYPE_OPEN_SYSTEM;
1349 }
1350
1351 goto done;
1352 }
1353
1354 /* Now handle infra mode. "sme" is valid for infra mode only */
1355 if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
1356 auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1357 priv->sec_info.is_authtype_auto = 1;
1358 } else {
1359 auth_type = sme->auth_type;
1360 }
1361
1362 if (sme->crypto.n_ciphers_pairwise) {
1363 priv->sec_info.encryption_mode =
1364 sme->crypto.ciphers_pairwise[0];
1365 priv->sec_info.authentication_mode = auth_type;
1366 }
1367
1368 if (sme->crypto.cipher_group) {
1369 priv->sec_info.encryption_mode = sme->crypto.cipher_group;
1370 priv->sec_info.authentication_mode = auth_type;
1371 }
1372 if (sme->ie)
1373 ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
1374
1375 if (sme->key) {
1376 if (mwifiex_is_alg_wep(priv->sec_info.encryption_mode)) {
1377 dev_dbg(priv->adapter->dev,
1378 "info: setting wep encryption"
1379 " with key len %d\n", sme->key_len);
1380 priv->wep_key_curr_index = sme->key_idx;
1381 ret = mwifiex_set_encode(priv, NULL, sme->key,
1382 sme->key_len, sme->key_idx,
1383 NULL, 0);
1384 }
1385 }
1386 done:
1387 /*
1388 * Scan entries are valid for some time (15 sec). So we can save one
1389 * active scan time if we just try cfg80211_get_bss first. If it fails
1390 * then request scan and cfg80211_get_bss() again for final output.
1391 */
1392 while (1) {
1393 if (is_scanning_required) {
1394 /* Do specific SSID scanning */
1395 if (mwifiex_request_scan(priv, &req_ssid)) {
1396 dev_err(priv->adapter->dev, "scan error\n");
1397 return -EFAULT;
1398 }
1399 }
1400
1401 /* Find the BSS we want using available scan results */
1402 if (mode == NL80211_IFTYPE_ADHOC)
1403 bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1404 bssid, ssid, ssid_len,
1405 WLAN_CAPABILITY_IBSS,
1406 WLAN_CAPABILITY_IBSS);
1407 else
1408 bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1409 bssid, ssid, ssid_len,
1410 WLAN_CAPABILITY_ESS,
1411 WLAN_CAPABILITY_ESS);
1412
1413 if (!bss) {
1414 if (is_scanning_required) {
1415 dev_warn(priv->adapter->dev,
1416 "assoc: requested bss not found in scan results\n");
1417 break;
1418 }
1419 is_scanning_required = 1;
1420 } else {
1421 dev_dbg(priv->adapter->dev,
1422 "info: trying to associate to '%s' bssid %pM\n",
1423 (char *) req_ssid.ssid, bss->bssid);
1424 memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
1425 break;
1426 }
1427 }
1428
1429 if (mwifiex_bss_start(priv, bss, &req_ssid))
1430 return -EFAULT;
1431
1432 if (mode == NL80211_IFTYPE_ADHOC) {
1433 /* Inform the BSS information to kernel, otherwise
1434 * kernel will give a panic after successful assoc */
1435 if (mwifiex_cfg80211_inform_ibss_bss(priv))
1436 return -EFAULT;
1437 }
1438
1439 return ret;
1440 }
1441
1442 /*
1443 * CFG802.11 operation handler for association request.
1444 *
1445 * This function does not work when the current mode is set to Ad-Hoc, or
1446 * when there is already an association procedure going on. The given BSS
1447 * information is used to associate.
1448 */
1449 static int
1450 mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1451 struct cfg80211_connect_params *sme)
1452 {
1453 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1454 int ret = 0;
1455
1456 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
1457 wiphy_err(wiphy, "received infra assoc request "
1458 "when station is in ibss mode\n");
1459 goto done;
1460 }
1461
1462 if (priv->bss_mode == NL80211_IFTYPE_AP) {
1463 wiphy_err(wiphy, "skip association request for AP interface\n");
1464 goto done;
1465 }
1466
1467 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1468 (char *) sme->ssid, sme->bssid);
1469
1470 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
1471 priv->bss_mode, sme->channel, sme, 0);
1472 done:
1473 if (!ret) {
1474 cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
1475 NULL, 0, WLAN_STATUS_SUCCESS,
1476 GFP_KERNEL);
1477 dev_dbg(priv->adapter->dev,
1478 "info: associated to bssid %pM successfully\n",
1479 priv->cfg_bssid);
1480 } else {
1481 dev_dbg(priv->adapter->dev,
1482 "info: association to bssid %pM failed\n",
1483 priv->cfg_bssid);
1484 memset(priv->cfg_bssid, 0, ETH_ALEN);
1485 }
1486
1487 return ret;
1488 }
1489
1490 /*
1491 * This function sets following parameters for ibss network.
1492 * - channel
1493 * - start band
1494 * - 11n flag
1495 * - secondary channel offset
1496 */
1497 static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1498 struct cfg80211_ibss_params *params)
1499 {
1500 struct wiphy *wiphy = priv->wdev->wiphy;
1501 struct mwifiex_adapter *adapter = priv->adapter;
1502 int index = 0, i;
1503 u8 config_bands = 0;
1504
1505 if (params->channel->band == IEEE80211_BAND_2GHZ) {
1506 if (!params->basic_rates) {
1507 config_bands = BAND_B | BAND_G;
1508 } else {
1509 for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) {
1510 /*
1511 * Rates below 6 Mbps in the table are CCK
1512 * rates; 802.11b and from 6 they are OFDM;
1513 * 802.11G
1514 */
1515 if (mwifiex_rates[i].bitrate == 60) {
1516 index = 1 << i;
1517 break;
1518 }
1519 }
1520
1521 if (params->basic_rates < index) {
1522 config_bands = BAND_B;
1523 } else {
1524 config_bands = BAND_G;
1525 if (params->basic_rates % index)
1526 config_bands |= BAND_B;
1527 }
1528 }
1529
1530 if (params->channel_type != NL80211_CHAN_NO_HT)
1531 config_bands |= BAND_GN;
1532 } else {
1533 if (params->channel_type == NL80211_CHAN_NO_HT)
1534 config_bands = BAND_A;
1535 else
1536 config_bands = BAND_AN | BAND_A;
1537 }
1538
1539 if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) {
1540 adapter->config_bands = config_bands;
1541 adapter->adhoc_start_band = config_bands;
1542
1543 if ((config_bands & BAND_GN) || (config_bands & BAND_AN))
1544 adapter->adhoc_11n_enabled = true;
1545 else
1546 adapter->adhoc_11n_enabled = false;
1547 }
1548
1549 adapter->sec_chan_offset =
1550 mwifiex_chan_type_to_sec_chan_offset(params->channel_type);
1551 priv->adhoc_channel =
1552 ieee80211_frequency_to_channel(params->channel->center_freq);
1553
1554 wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
1555 config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
1556
1557 return 0;
1558 }
1559
1560 /*
1561 * CFG802.11 operation handler to join an IBSS.
1562 *
1563 * This function does not work in any mode other than Ad-Hoc, or if
1564 * a join operation is already in progress.
1565 */
1566 static int
1567 mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1568 struct cfg80211_ibss_params *params)
1569 {
1570 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1571 int ret = 0;
1572
1573 if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
1574 wiphy_err(wiphy, "request to join ibss received "
1575 "when station is not in ibss mode\n");
1576 goto done;
1577 }
1578
1579 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
1580 (char *) params->ssid, params->bssid);
1581
1582 mwifiex_set_ibss_params(priv, params);
1583
1584 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1585 params->bssid, priv->bss_mode,
1586 params->channel, NULL, params->privacy);
1587 done:
1588 if (!ret) {
1589 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
1590 dev_dbg(priv->adapter->dev,
1591 "info: joined/created adhoc network with bssid"
1592 " %pM successfully\n", priv->cfg_bssid);
1593 } else {
1594 dev_dbg(priv->adapter->dev,
1595 "info: failed creating/joining adhoc network\n");
1596 }
1597
1598 return ret;
1599 }
1600
1601 /*
1602 * CFG802.11 operation handler to leave an IBSS.
1603 *
1604 * This function does not work if a leave operation is
1605 * already in progress.
1606 */
1607 static int
1608 mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1609 {
1610 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1611
1612 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
1613 priv->cfg_bssid);
1614 if (mwifiex_deauthenticate(priv, NULL))
1615 return -EFAULT;
1616
1617 memset(priv->cfg_bssid, 0, ETH_ALEN);
1618
1619 return 0;
1620 }
1621
1622 /*
1623 * CFG802.11 operation handler for scan request.
1624 *
1625 * This function issues a scan request to the firmware based upon
1626 * the user specified scan configuration. On successfull completion,
1627 * it also informs the results.
1628 */
1629 static int
1630 mwifiex_cfg80211_scan(struct wiphy *wiphy,
1631 struct cfg80211_scan_request *request)
1632 {
1633 struct net_device *dev = request->wdev->netdev;
1634 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1635 int i;
1636 struct ieee80211_channel *chan;
1637
1638 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1639
1640 if (atomic_read(&priv->wmm.tx_pkts_queued) >=
1641 MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) {
1642 dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n");
1643 return -EBUSY;
1644 }
1645
1646 priv->scan_request = request;
1647
1648 priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
1649 GFP_KERNEL);
1650 if (!priv->user_scan_cfg) {
1651 dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
1652 return -ENOMEM;
1653 }
1654
1655 priv->user_scan_cfg->num_ssids = request->n_ssids;
1656 priv->user_scan_cfg->ssid_list = request->ssids;
1657
1658 if (request->ie && request->ie_len) {
1659 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
1660 if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR)
1661 continue;
1662 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN;
1663 memcpy(&priv->vs_ie[i].ie, request->ie,
1664 request->ie_len);
1665 break;
1666 }
1667 }
1668
1669 for (i = 0; i < request->n_channels; i++) {
1670 chan = request->channels[i];
1671 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1672 priv->user_scan_cfg->chan_list[i].radio_type = chan->band;
1673
1674 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
1675 priv->user_scan_cfg->chan_list[i].scan_type =
1676 MWIFIEX_SCAN_TYPE_PASSIVE;
1677 else
1678 priv->user_scan_cfg->chan_list[i].scan_type =
1679 MWIFIEX_SCAN_TYPE_ACTIVE;
1680
1681 priv->user_scan_cfg->chan_list[i].scan_time = 0;
1682 }
1683 if (mwifiex_scan_networks(priv, priv->user_scan_cfg))
1684 return -EFAULT;
1685
1686 if (request->ie && request->ie_len) {
1687 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
1688 if (priv->vs_ie[i].mask == MWIFIEX_VSIE_MASK_SCAN) {
1689 priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_CLEAR;
1690 memset(&priv->vs_ie[i].ie, 0,
1691 MWIFIEX_MAX_VSIE_LEN);
1692 }
1693 }
1694 }
1695 return 0;
1696 }
1697
1698 /*
1699 * This function sets up the CFG802.11 specific HT capability fields
1700 * with default values.
1701 *
1702 * The following default values are set -
1703 * - HT Supported = True
1704 * - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K
1705 * - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE
1706 * - HT Capabilities supported by firmware
1707 * - MCS information, Rx mask = 0xff
1708 * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01)
1709 */
1710 static void
1711 mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
1712 struct mwifiex_private *priv)
1713 {
1714 int rx_mcs_supp;
1715 struct ieee80211_mcs_info mcs_set;
1716 u8 *mcs = (u8 *)&mcs_set;
1717 struct mwifiex_adapter *adapter = priv->adapter;
1718
1719 ht_info->ht_supported = true;
1720 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
1721 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1722
1723 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
1724
1725 /* Fill HT capability information */
1726 if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
1727 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1728 else
1729 ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1730
1731 if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap))
1732 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
1733 else
1734 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20;
1735
1736 if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap))
1737 ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
1738 else
1739 ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40;
1740
1741 if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap))
1742 ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
1743 else
1744 ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
1745
1746 if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
1747 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
1748 else
1749 ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
1750
1751 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
1752 ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
1753
1754 rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support);
1755 /* Set MCS for 1x1 */
1756 memset(mcs, 0xff, rx_mcs_supp);
1757 /* Clear all the other values */
1758 memset(&mcs[rx_mcs_supp], 0,
1759 sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
1760 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
1761 ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
1762 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
1763 SETHT_MCS32(mcs_set.rx_mask);
1764
1765 memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info));
1766
1767 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1768 }
1769
1770 /*
1771 * create a new virtual interface with the given name
1772 */
1773 struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1774 const char *name,
1775 enum nl80211_iftype type,
1776 u32 *flags,
1777 struct vif_params *params)
1778 {
1779 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
1780 struct mwifiex_private *priv;
1781 struct net_device *dev;
1782 void *mdev_priv;
1783 struct wireless_dev *wdev;
1784
1785 if (!adapter)
1786 return ERR_PTR(-EFAULT);
1787
1788 switch (type) {
1789 case NL80211_IFTYPE_UNSPECIFIED:
1790 case NL80211_IFTYPE_STATION:
1791 case NL80211_IFTYPE_ADHOC:
1792 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
1793 if (priv->bss_mode) {
1794 wiphy_err(wiphy,
1795 "cannot create multiple sta/adhoc ifaces\n");
1796 return ERR_PTR(-EINVAL);
1797 }
1798
1799 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1800 if (!wdev)
1801 return ERR_PTR(-ENOMEM);
1802
1803 wdev->wiphy = wiphy;
1804 priv->wdev = wdev;
1805 wdev->iftype = NL80211_IFTYPE_STATION;
1806
1807 if (type == NL80211_IFTYPE_UNSPECIFIED)
1808 priv->bss_mode = NL80211_IFTYPE_STATION;
1809 else
1810 priv->bss_mode = type;
1811
1812 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
1813 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1814 priv->bss_priority = 0;
1815 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
1816 priv->bss_num = 0;
1817
1818 break;
1819 case NL80211_IFTYPE_AP:
1820 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP];
1821
1822 if (priv->bss_mode) {
1823 wiphy_err(wiphy, "Can't create multiple AP interfaces");
1824 return ERR_PTR(-EINVAL);
1825 }
1826
1827 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1828 if (!wdev)
1829 return ERR_PTR(-ENOMEM);
1830
1831 priv->wdev = wdev;
1832 wdev->wiphy = wiphy;
1833 wdev->iftype = NL80211_IFTYPE_AP;
1834
1835 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
1836 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1837 priv->bss_priority = 0;
1838 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
1839 priv->bss_started = 0;
1840 priv->bss_num = 0;
1841 priv->bss_mode = type;
1842
1843 break;
1844 default:
1845 wiphy_err(wiphy, "type not supported\n");
1846 return ERR_PTR(-EINVAL);
1847 }
1848
1849 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name,
1850 ether_setup, 1);
1851 if (!dev) {
1852 wiphy_err(wiphy, "no memory available for netdevice\n");
1853 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
1854 return ERR_PTR(-ENOMEM);
1855 }
1856
1857 mwifiex_init_priv_params(priv, dev);
1858 priv->netdev = dev;
1859
1860 mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
1861
1862 if (adapter->config_bands & BAND_A)
1863 mwifiex_setup_ht_caps(
1864 &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
1865
1866 dev_net_set(dev, wiphy_net(wiphy));
1867 dev->ieee80211_ptr = priv->wdev;
1868 dev->ieee80211_ptr->iftype = priv->bss_mode;
1869 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
1870 memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
1871 SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
1872
1873 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1874 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
1875 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
1876
1877 mdev_priv = netdev_priv(dev);
1878 *((unsigned long *) mdev_priv) = (unsigned long) priv;
1879
1880 SET_NETDEV_DEV(dev, adapter->dev);
1881
1882 /* Register network device */
1883 if (register_netdevice(dev)) {
1884 wiphy_err(wiphy, "cannot register virtual network device\n");
1885 free_netdev(dev);
1886 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
1887 return ERR_PTR(-EFAULT);
1888 }
1889
1890 sema_init(&priv->async_sem, 1);
1891 priv->scan_pending_on_block = false;
1892
1893 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
1894
1895 #ifdef CONFIG_DEBUG_FS
1896 mwifiex_dev_debugfs_init(priv);
1897 #endif
1898 return wdev;
1899 }
1900 EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
1901
1902 /*
1903 * del_virtual_intf: remove the virtual interface determined by dev
1904 */
1905 int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
1906 {
1907 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
1908
1909 #ifdef CONFIG_DEBUG_FS
1910 mwifiex_dev_debugfs_remove(priv);
1911 #endif
1912
1913 if (!netif_queue_stopped(priv->netdev))
1914 netif_stop_queue(priv->netdev);
1915
1916 if (netif_carrier_ok(priv->netdev))
1917 netif_carrier_off(priv->netdev);
1918
1919 if (wdev->netdev->reg_state == NETREG_REGISTERED)
1920 unregister_netdevice(wdev->netdev);
1921
1922 if (wdev->netdev->reg_state == NETREG_UNREGISTERED)
1923 free_netdev(wdev->netdev);
1924
1925 /* Clear the priv in adapter */
1926 priv->netdev = NULL;
1927
1928 priv->media_connected = false;
1929
1930 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
1931
1932 return 0;
1933 }
1934 EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
1935
1936 /* station cfg80211 operations */
1937 static struct cfg80211_ops mwifiex_cfg80211_ops = {
1938 .add_virtual_intf = mwifiex_add_virtual_intf,
1939 .del_virtual_intf = mwifiex_del_virtual_intf,
1940 .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
1941 .scan = mwifiex_cfg80211_scan,
1942 .connect = mwifiex_cfg80211_connect,
1943 .disconnect = mwifiex_cfg80211_disconnect,
1944 .get_station = mwifiex_cfg80211_get_station,
1945 .dump_station = mwifiex_cfg80211_dump_station,
1946 .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
1947 .join_ibss = mwifiex_cfg80211_join_ibss,
1948 .leave_ibss = mwifiex_cfg80211_leave_ibss,
1949 .add_key = mwifiex_cfg80211_add_key,
1950 .del_key = mwifiex_cfg80211_del_key,
1951 .mgmt_tx = mwifiex_cfg80211_mgmt_tx,
1952 .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
1953 .set_default_key = mwifiex_cfg80211_set_default_key,
1954 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
1955 .set_tx_power = mwifiex_cfg80211_set_tx_power,
1956 .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
1957 .start_ap = mwifiex_cfg80211_start_ap,
1958 .stop_ap = mwifiex_cfg80211_stop_ap,
1959 .change_beacon = mwifiex_cfg80211_change_beacon,
1960 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
1961 .set_antenna = mwifiex_cfg80211_set_antenna,
1962 };
1963
1964 /*
1965 * This function registers the device with CFG802.11 subsystem.
1966 *
1967 * The function creates the wireless device/wiphy, populates it with
1968 * default parameters and handler function pointers, and finally
1969 * registers the device.
1970 */
1971
1972 int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
1973 {
1974 int ret;
1975 void *wdev_priv;
1976 struct wiphy *wiphy;
1977 struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
1978 u8 *country_code;
1979
1980 /* create a new wiphy for use with cfg80211 */
1981 wiphy = wiphy_new(&mwifiex_cfg80211_ops,
1982 sizeof(struct mwifiex_adapter *));
1983 if (!wiphy) {
1984 dev_err(adapter->dev, "%s: creating new wiphy\n", __func__);
1985 return -ENOMEM;
1986 }
1987 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
1988 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
1989 wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
1990 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1991 BIT(NL80211_IFTYPE_ADHOC) |
1992 BIT(NL80211_IFTYPE_AP);
1993
1994 wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
1995 if (adapter->config_bands & BAND_A)
1996 wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
1997 else
1998 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1999
2000 wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta;
2001 wiphy->n_iface_combinations = 1;
2002
2003 /* Initialize cipher suits */
2004 wiphy->cipher_suites = mwifiex_cipher_suites;
2005 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
2006
2007 memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
2008 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2009 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
2010 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2011 WIPHY_FLAG_CUSTOM_REGULATORY;
2012
2013 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2014
2015 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
2016 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
2017 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
2018
2019 wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1;
2020 wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
2021
2022 wiphy->features = NL80211_FEATURE_HT_IBSS;
2023
2024 /* Reserve space for mwifiex specific private data for BSS */
2025 wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
2026
2027 wiphy->reg_notifier = mwifiex_reg_notifier;
2028
2029 /* Set struct mwifiex_adapter pointer in wiphy_priv */
2030 wdev_priv = wiphy_priv(wiphy);
2031 *(unsigned long *)wdev_priv = (unsigned long)adapter;
2032
2033 set_wiphy_dev(wiphy, priv->adapter->dev);
2034
2035 ret = wiphy_register(wiphy);
2036 if (ret < 0) {
2037 dev_err(adapter->dev,
2038 "%s: wiphy_register failed: %d\n", __func__, ret);
2039 wiphy_free(wiphy);
2040 return ret;
2041 }
2042 country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
2043 if (country_code)
2044 dev_info(adapter->dev,
2045 "ignoring F/W country code %2.2s\n", country_code);
2046
2047 adapter->wiphy = wiphy;
2048 return ret;
2049 }
This page took 0.079481 seconds and 5 git commands to generate.