diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 532 |
1 files changed, 388 insertions, 144 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c7e89188c350..015fec3371a0 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -20,6 +20,23 @@ | |||
20 | #include "cfg80211.h" | 20 | #include "cfg80211.h" |
21 | #include "main.h" | 21 | #include "main.h" |
22 | 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 | |||
23 | /* | 40 | /* |
24 | * This function maps the nl802.11 channel type into driver channel type. | 41 | * This function maps the nl802.11 channel type into driver channel type. |
25 | * | 42 | * |
@@ -67,7 +84,7 @@ mwifiex_is_alg_wep(u32 cipher) | |||
67 | /* | 84 | /* |
68 | * This function retrieves the private structure from kernel wiphy structure. | 85 | * This function retrieves the private structure from kernel wiphy structure. |
69 | */ | 86 | */ |
70 | static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy) | 87 | static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy) |
71 | { | 88 | { |
72 | return (void *) (*(unsigned long *) wiphy_priv(wiphy)); | 89 | return (void *) (*(unsigned long *) wiphy_priv(wiphy)); |
73 | } | 90 | } |
@@ -80,8 +97,10 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, | |||
80 | u8 key_index, bool pairwise, const u8 *mac_addr) | 97 | u8 key_index, bool pairwise, const u8 *mac_addr) |
81 | { | 98 | { |
82 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); | 99 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); |
100 | const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
101 | const u8 *peer_mac = pairwise ? mac_addr : bc_mac; | ||
83 | 102 | ||
84 | if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { | 103 | if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) { |
85 | wiphy_err(wiphy, "deleting the crypto keys\n"); | 104 | wiphy_err(wiphy, "deleting the crypto keys\n"); |
86 | return -EFAULT; | 105 | return -EFAULT; |
87 | } | 106 | } |
@@ -98,7 +117,8 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, | |||
98 | enum nl80211_tx_power_setting type, | 117 | enum nl80211_tx_power_setting type, |
99 | int mbm) | 118 | int mbm) |
100 | { | 119 | { |
101 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 120 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
121 | struct mwifiex_private *priv; | ||
102 | struct mwifiex_power_cfg power_cfg; | 122 | struct mwifiex_power_cfg power_cfg; |
103 | int dbm = MBM_TO_DBM(mbm); | 123 | int dbm = MBM_TO_DBM(mbm); |
104 | 124 | ||
@@ -109,6 +129,8 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, | |||
109 | power_cfg.is_power_auto = 1; | 129 | power_cfg.is_power_auto = 1; |
110 | } | 130 | } |
111 | 131 | ||
132 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | ||
133 | |||
112 | return mwifiex_set_tx_power(priv, &power_cfg); | 134 | return mwifiex_set_tx_power(priv, &power_cfg); |
113 | } | 135 | } |
114 | 136 | ||
@@ -148,7 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, | |||
148 | if (!priv->sec_info.wep_enabled) | 170 | if (!priv->sec_info.wep_enabled) |
149 | return 0; | 171 | return 0; |
150 | 172 | ||
151 | if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { | 173 | if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { |
152 | wiphy_err(wiphy, "set default Tx key index\n"); | 174 | wiphy_err(wiphy, "set default Tx key index\n"); |
153 | return -EFAULT; | 175 | return -EFAULT; |
154 | } | 176 | } |
@@ -165,9 +187,11 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, | |||
165 | struct key_params *params) | 187 | struct key_params *params) |
166 | { | 188 | { |
167 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); | 189 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); |
190 | const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
191 | const u8 *peer_mac = pairwise ? mac_addr : bc_mac; | ||
168 | 192 | ||
169 | if (mwifiex_set_encode(priv, params->key, params->key_len, | 193 | if (mwifiex_set_encode(priv, params->key, params->key_len, |
170 | key_index, 0)) { | 194 | key_index, peer_mac, 0)) { |
171 | wiphy_err(wiphy, "crypto keys added\n"); | 195 | wiphy_err(wiphy, "crypto keys added\n"); |
172 | return -EFAULT; | 196 | return -EFAULT; |
173 | } | 197 | } |
@@ -192,13 +216,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
192 | enum ieee80211_band band; | 216 | enum ieee80211_band band; |
193 | struct ieee80211_supported_band *sband; | 217 | struct ieee80211_supported_band *sband; |
194 | struct ieee80211_channel *ch; | 218 | struct ieee80211_channel *ch; |
195 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 219 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
196 | struct mwifiex_adapter *adapter = priv->adapter; | 220 | struct mwifiex_private *priv; |
197 | struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; | 221 | struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; |
198 | 222 | ||
199 | /* Set country code */ | 223 | /* Set country code */ |
200 | domain_info->country_code[0] = priv->country_code[0]; | 224 | domain_info->country_code[0] = adapter->country_code[0]; |
201 | domain_info->country_code[1] = priv->country_code[1]; | 225 | domain_info->country_code[1] = adapter->country_code[1]; |
202 | domain_info->country_code[2] = ' '; | 226 | domain_info->country_code[2] = ' '; |
203 | 227 | ||
204 | band = mwifiex_band_to_radio_type(adapter->config_bands); | 228 | band = mwifiex_band_to_radio_type(adapter->config_bands); |
@@ -250,6 +274,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
250 | 274 | ||
251 | domain_info->no_of_triplet = no_of_triplet; | 275 | domain_info->no_of_triplet = no_of_triplet; |
252 | 276 | ||
277 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | ||
278 | |||
253 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, | 279 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, |
254 | HostCmd_ACT_GEN_SET, 0, NULL)) { | 280 | HostCmd_ACT_GEN_SET, 0, NULL)) { |
255 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); | 281 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); |
@@ -272,12 +298,12 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
272 | static int mwifiex_reg_notifier(struct wiphy *wiphy, | 298 | static int mwifiex_reg_notifier(struct wiphy *wiphy, |
273 | struct regulatory_request *request) | 299 | struct regulatory_request *request) |
274 | { | 300 | { |
275 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 301 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
276 | 302 | ||
277 | wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain" | 303 | wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n", |
278 | " %c%c\n", request->alpha2[0], request->alpha2[1]); | 304 | request->alpha2[0], request->alpha2[1]); |
279 | 305 | ||
280 | memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); | 306 | memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2)); |
281 | 307 | ||
282 | switch (request->initiator) { | 308 | switch (request->initiator) { |
283 | case NL80211_REGDOM_SET_BY_DRIVER: | 309 | case NL80211_REGDOM_SET_BY_DRIVER: |
@@ -361,33 +387,10 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
361 | if (mwifiex_bss_set_channel(priv, &cfp)) | 387 | if (mwifiex_bss_set_channel(priv, &cfp)) |
362 | return -EFAULT; | 388 | return -EFAULT; |
363 | 389 | ||
364 | return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); | 390 | if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) |
365 | } | 391 | return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); |
366 | |||
367 | /* | ||
368 | * CFG802.11 operation handler to set channel. | ||
369 | * | ||
370 | * This function can only be used when station is not connected. | ||
371 | */ | ||
372 | static int | ||
373 | mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, | ||
374 | struct ieee80211_channel *chan, | ||
375 | enum nl80211_channel_type channel_type) | ||
376 | { | ||
377 | struct mwifiex_private *priv; | ||
378 | |||
379 | if (dev) | ||
380 | priv = mwifiex_netdev_get_priv(dev); | ||
381 | else | 392 | else |
382 | priv = mwifiex_cfg80211_get_priv(wiphy); | 393 | return mwifiex_uap_set_channel(priv, cfp.channel); |
383 | |||
384 | if (priv->media_connected) { | ||
385 | wiphy_err(wiphy, "This setting is valid only when station " | ||
386 | "is not connected\n"); | ||
387 | return -EINVAL; | ||
388 | } | ||
389 | |||
390 | return mwifiex_set_rf_channel(priv, chan, channel_type); | ||
391 | } | 394 | } |
392 | 395 | ||
393 | /* | 396 | /* |
@@ -399,18 +402,13 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, | |||
399 | static int | 402 | static int |
400 | mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) | 403 | mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) |
401 | { | 404 | { |
402 | int ret; | ||
403 | |||
404 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || | 405 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || |
405 | frag_thr > MWIFIEX_FRAG_MAX_VALUE) | 406 | frag_thr > MWIFIEX_FRAG_MAX_VALUE) |
406 | return -EINVAL; | 407 | frag_thr = MWIFIEX_FRAG_MAX_VALUE; |
407 | |||
408 | /* Send request to firmware */ | ||
409 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, | ||
410 | HostCmd_ACT_GEN_SET, FRAG_THRESH_I, | ||
411 | &frag_thr); | ||
412 | 408 | ||
413 | return ret; | 409 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, |
410 | HostCmd_ACT_GEN_SET, FRAG_THRESH_I, | ||
411 | &frag_thr); | ||
414 | } | 412 | } |
415 | 413 | ||
416 | /* | 414 | /* |
@@ -439,19 +437,85 @@ mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) | |||
439 | static int | 437 | static int |
440 | mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | 438 | mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) |
441 | { | 439 | { |
442 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 440 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
443 | int ret = 0; | 441 | struct mwifiex_private *priv; |
442 | struct mwifiex_uap_bss_param *bss_cfg; | ||
443 | int ret, bss_started, i; | ||
444 | |||
445 | for (i = 0; i < adapter->priv_num; i++) { | ||
446 | priv = adapter->priv[i]; | ||
447 | |||
448 | switch (priv->bss_role) { | ||
449 | case MWIFIEX_BSS_ROLE_UAP: | ||
450 | bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), | ||
451 | GFP_KERNEL); | ||
452 | if (!bss_cfg) | ||
453 | return -ENOMEM; | ||
454 | |||
455 | mwifiex_set_sys_config_invalid_data(bss_cfg); | ||
456 | |||
457 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) | ||
458 | bss_cfg->rts_threshold = wiphy->rts_threshold; | ||
459 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) | ||
460 | bss_cfg->frag_threshold = wiphy->frag_threshold; | ||
461 | if (changed & WIPHY_PARAM_RETRY_LONG) | ||
462 | bss_cfg->retry_limit = wiphy->retry_long; | ||
463 | |||
464 | bss_started = priv->bss_started; | ||
465 | |||
466 | ret = mwifiex_send_cmd_sync(priv, | ||
467 | HostCmd_CMD_UAP_BSS_STOP, | ||
468 | HostCmd_ACT_GEN_SET, 0, | ||
469 | NULL); | ||
470 | if (ret) { | ||
471 | wiphy_err(wiphy, "Failed to stop the BSS\n"); | ||
472 | kfree(bss_cfg); | ||
473 | return ret; | ||
474 | } | ||
444 | 475 | ||
445 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) { | 476 | ret = mwifiex_send_cmd_async(priv, |
446 | ret = mwifiex_set_rts(priv, wiphy->rts_threshold); | 477 | HostCmd_CMD_UAP_SYS_CONFIG, |
447 | if (ret) | 478 | HostCmd_ACT_GEN_SET, |
448 | return ret; | 479 | UAP_BSS_PARAMS_I, bss_cfg); |
449 | } | ||
450 | 480 | ||
451 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) | 481 | kfree(bss_cfg); |
452 | ret = mwifiex_set_frag(priv, wiphy->frag_threshold); | ||
453 | 482 | ||
454 | return ret; | 483 | if (ret) { |
484 | wiphy_err(wiphy, "Failed to set bss config\n"); | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | if (!bss_started) | ||
489 | break; | ||
490 | |||
491 | ret = mwifiex_send_cmd_async(priv, | ||
492 | HostCmd_CMD_UAP_BSS_START, | ||
493 | HostCmd_ACT_GEN_SET, 0, | ||
494 | NULL); | ||
495 | if (ret) { | ||
496 | wiphy_err(wiphy, "Failed to start BSS\n"); | ||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | break; | ||
501 | case MWIFIEX_BSS_ROLE_STA: | ||
502 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) { | ||
503 | ret = mwifiex_set_rts(priv, | ||
504 | wiphy->rts_threshold); | ||
505 | if (ret) | ||
506 | return ret; | ||
507 | } | ||
508 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { | ||
509 | ret = mwifiex_set_frag(priv, | ||
510 | wiphy->frag_threshold); | ||
511 | if (ret) | ||
512 | return ret; | ||
513 | } | ||
514 | break; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | return 0; | ||
455 | } | 519 | } |
456 | 520 | ||
457 | /* | 521 | /* |
@@ -466,31 +530,59 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, | |||
466 | int ret; | 530 | int ret; |
467 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 531 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
468 | 532 | ||
469 | if (priv->bss_mode == type) { | 533 | switch (dev->ieee80211_ptr->iftype) { |
470 | wiphy_warn(wiphy, "already set to required type\n"); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | priv->bss_mode = type; | ||
475 | |||
476 | switch (type) { | ||
477 | case NL80211_IFTYPE_ADHOC: | 534 | case NL80211_IFTYPE_ADHOC: |
478 | dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; | 535 | switch (type) { |
479 | wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); | 536 | case NL80211_IFTYPE_STATION: |
537 | break; | ||
538 | case NL80211_IFTYPE_UNSPECIFIED: | ||
539 | wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name); | ||
540 | case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */ | ||
541 | return 0; | ||
542 | case NL80211_IFTYPE_AP: | ||
543 | default: | ||
544 | wiphy_err(wiphy, "%s: changing to %d not supported\n", | ||
545 | dev->name, type); | ||
546 | return -EOPNOTSUPP; | ||
547 | } | ||
480 | break; | 548 | break; |
481 | case NL80211_IFTYPE_STATION: | 549 | case NL80211_IFTYPE_STATION: |
482 | dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; | 550 | switch (type) { |
483 | wiphy_dbg(wiphy, "info: setting interface type to managed\n"); | 551 | case NL80211_IFTYPE_ADHOC: |
552 | break; | ||
553 | case NL80211_IFTYPE_UNSPECIFIED: | ||
554 | wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name); | ||
555 | case NL80211_IFTYPE_STATION: /* This shouldn't happen */ | ||
556 | return 0; | ||
557 | case NL80211_IFTYPE_AP: | ||
558 | default: | ||
559 | wiphy_err(wiphy, "%s: changing to %d not supported\n", | ||
560 | dev->name, type); | ||
561 | return -EOPNOTSUPP; | ||
562 | } | ||
563 | break; | ||
564 | case NL80211_IFTYPE_AP: | ||
565 | switch (type) { | ||
566 | case NL80211_IFTYPE_UNSPECIFIED: | ||
567 | wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name); | ||
568 | case NL80211_IFTYPE_AP: /* This shouldn't happen */ | ||
569 | return 0; | ||
570 | case NL80211_IFTYPE_ADHOC: | ||
571 | case NL80211_IFTYPE_STATION: | ||
572 | default: | ||
573 | wiphy_err(wiphy, "%s: changing to %d not supported\n", | ||
574 | dev->name, type); | ||
575 | return -EOPNOTSUPP; | ||
576 | } | ||
484 | break; | 577 | break; |
485 | case NL80211_IFTYPE_UNSPECIFIED: | ||
486 | dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; | ||
487 | wiphy_dbg(wiphy, "info: setting interface type to auto\n"); | ||
488 | return 0; | ||
489 | default: | 578 | default: |
490 | wiphy_err(wiphy, "unknown interface type: %d\n", type); | 579 | wiphy_err(wiphy, "%s: unknown iftype: %d\n", |
491 | return -EINVAL; | 580 | dev->name, dev->ieee80211_ptr->iftype); |
581 | return -EOPNOTSUPP; | ||
492 | } | 582 | } |
493 | 583 | ||
584 | dev->ieee80211_ptr->iftype = type; | ||
585 | priv->bss_mode = type; | ||
494 | mwifiex_deauthenticate(priv, NULL); | 586 | mwifiex_deauthenticate(priv, NULL); |
495 | 587 | ||
496 | priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; | 588 | priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; |
@@ -804,6 +896,103 @@ static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, | |||
804 | return 0; | 896 | return 0; |
805 | } | 897 | } |
806 | 898 | ||
899 | /* cfg80211 operation handler for stop ap. | ||
900 | * Function stops BSS running at uAP interface. | ||
901 | */ | ||
902 | static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | ||
903 | { | ||
904 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | ||
905 | |||
906 | if (mwifiex_del_mgmt_ies(priv)) | ||
907 | wiphy_err(wiphy, "Failed to delete mgmt IEs!\n"); | ||
908 | |||
909 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, | ||
910 | HostCmd_ACT_GEN_SET, 0, NULL)) { | ||
911 | wiphy_err(wiphy, "Failed to stop the BSS\n"); | ||
912 | return -1; | ||
913 | } | ||
914 | |||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | /* cfg80211 operation handler for start_ap. | ||
919 | * Function sets beacon period, DTIM period, SSID and security into | ||
920 | * AP config structure. | ||
921 | * AP is configured with these settings and BSS is started. | ||
922 | */ | ||
923 | static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | ||
924 | struct net_device *dev, | ||
925 | struct cfg80211_ap_settings *params) | ||
926 | { | ||
927 | struct mwifiex_uap_bss_param *bss_cfg; | ||
928 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | ||
929 | |||
930 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) | ||
931 | return -1; | ||
932 | if (mwifiex_set_mgmt_ies(priv, params)) | ||
933 | return -1; | ||
934 | |||
935 | bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); | ||
936 | if (!bss_cfg) | ||
937 | return -ENOMEM; | ||
938 | |||
939 | mwifiex_set_sys_config_invalid_data(bss_cfg); | ||
940 | |||
941 | if (params->beacon_interval) | ||
942 | bss_cfg->beacon_period = params->beacon_interval; | ||
943 | if (params->dtim_period) | ||
944 | bss_cfg->dtim_period = params->dtim_period; | ||
945 | |||
946 | if (params->ssid && params->ssid_len) { | ||
947 | memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len); | ||
948 | bss_cfg->ssid.ssid_len = params->ssid_len; | ||
949 | } | ||
950 | |||
951 | switch (params->hidden_ssid) { | ||
952 | case NL80211_HIDDEN_SSID_NOT_IN_USE: | ||
953 | bss_cfg->bcast_ssid_ctl = 1; | ||
954 | break; | ||
955 | case NL80211_HIDDEN_SSID_ZERO_LEN: | ||
956 | bss_cfg->bcast_ssid_ctl = 0; | ||
957 | break; | ||
958 | case NL80211_HIDDEN_SSID_ZERO_CONTENTS: | ||
959 | /* firmware doesn't support this type of hidden SSID */ | ||
960 | default: | ||
961 | return -EINVAL; | ||
962 | } | ||
963 | |||
964 | if (mwifiex_set_secure_params(priv, bss_cfg, params)) { | ||
965 | kfree(bss_cfg); | ||
966 | wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); | ||
967 | return -1; | ||
968 | } | ||
969 | |||
970 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, | ||
971 | HostCmd_ACT_GEN_SET, 0, NULL)) { | ||
972 | wiphy_err(wiphy, "Failed to stop the BSS\n"); | ||
973 | kfree(bss_cfg); | ||
974 | return -1; | ||
975 | } | ||
976 | |||
977 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, | ||
978 | HostCmd_ACT_GEN_SET, | ||
979 | UAP_BSS_PARAMS_I, bss_cfg)) { | ||
980 | wiphy_err(wiphy, "Failed to set the SSID\n"); | ||
981 | kfree(bss_cfg); | ||
982 | return -1; | ||
983 | } | ||
984 | |||
985 | kfree(bss_cfg); | ||
986 | |||
987 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_BSS_START, | ||
988 | HostCmd_ACT_GEN_SET, 0, NULL)) { | ||
989 | wiphy_err(wiphy, "Failed to start the BSS\n"); | ||
990 | return -1; | ||
991 | } | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
807 | /* | 996 | /* |
808 | * CFG802.11 operation handler for disconnection request. | 997 | * CFG802.11 operation handler for disconnection request. |
809 | * | 998 | * |
@@ -923,7 +1112,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
923 | priv->wep_key_curr_index = 0; | 1112 | priv->wep_key_curr_index = 0; |
924 | priv->sec_info.encryption_mode = 0; | 1113 | priv->sec_info.encryption_mode = 0; |
925 | priv->sec_info.is_authtype_auto = 0; | 1114 | priv->sec_info.is_authtype_auto = 0; |
926 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); | 1115 | ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1); |
927 | 1116 | ||
928 | if (mode == NL80211_IFTYPE_ADHOC) { | 1117 | if (mode == NL80211_IFTYPE_ADHOC) { |
929 | /* "privacy" is set only for ad-hoc mode */ | 1118 | /* "privacy" is set only for ad-hoc mode */ |
@@ -971,7 +1160,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
971 | " with key len %d\n", sme->key_len); | 1160 | " with key len %d\n", sme->key_len); |
972 | priv->wep_key_curr_index = sme->key_idx; | 1161 | priv->wep_key_curr_index = sme->key_idx; |
973 | ret = mwifiex_set_encode(priv, sme->key, sme->key_len, | 1162 | ret = mwifiex_set_encode(priv, sme->key, sme->key_len, |
974 | sme->key_idx, 0); | 1163 | sme->key_idx, NULL, 0); |
975 | } | 1164 | } |
976 | } | 1165 | } |
977 | done: | 1166 | done: |
@@ -1050,6 +1239,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
1050 | goto done; | 1239 | goto done; |
1051 | } | 1240 | } |
1052 | 1241 | ||
1242 | if (priv->bss_mode == NL80211_IFTYPE_AP) { | ||
1243 | wiphy_err(wiphy, "skip association request for AP interface\n"); | ||
1244 | goto done; | ||
1245 | } | ||
1246 | |||
1053 | wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", | 1247 | wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", |
1054 | (char *) sme->ssid, sme->bssid); | 1248 | (char *) sme->ssid, sme->bssid); |
1055 | 1249 | ||
@@ -1162,6 +1356,17 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1162 | priv->user_scan_cfg->num_ssids = request->n_ssids; | 1356 | priv->user_scan_cfg->num_ssids = request->n_ssids; |
1163 | priv->user_scan_cfg->ssid_list = request->ssids; | 1357 | priv->user_scan_cfg->ssid_list = request->ssids; |
1164 | 1358 | ||
1359 | if (request->ie && request->ie_len) { | ||
1360 | for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) { | ||
1361 | if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR) | ||
1362 | continue; | ||
1363 | priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN; | ||
1364 | memcpy(&priv->vs_ie[i].ie, request->ie, | ||
1365 | request->ie_len); | ||
1366 | break; | ||
1367 | } | ||
1368 | } | ||
1369 | |||
1165 | for (i = 0; i < request->n_channels; i++) { | 1370 | for (i = 0; i < request->n_channels; i++) { |
1166 | chan = request->channels[i]; | 1371 | chan = request->channels[i]; |
1167 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; | 1372 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; |
@@ -1179,6 +1384,15 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1179 | if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) | 1384 | if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) |
1180 | return -EFAULT; | 1385 | return -EFAULT; |
1181 | 1386 | ||
1387 | if (request->ie && request->ie_len) { | ||
1388 | for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) { | ||
1389 | if (priv->vs_ie[i].mask == MWIFIEX_VSIE_MASK_SCAN) { | ||
1390 | priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_CLEAR; | ||
1391 | memset(&priv->vs_ie[i].ie, 0, | ||
1392 | MWIFIEX_MAX_VSIE_LEN); | ||
1393 | } | ||
1394 | } | ||
1395 | } | ||
1182 | return 0; | 1396 | return 0; |
1183 | } | 1397 | } |
1184 | 1398 | ||
@@ -1263,15 +1477,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1263 | u32 *flags, | 1477 | u32 *flags, |
1264 | struct vif_params *params) | 1478 | struct vif_params *params) |
1265 | { | 1479 | { |
1266 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 1480 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
1267 | struct mwifiex_adapter *adapter; | 1481 | struct mwifiex_private *priv; |
1268 | struct net_device *dev; | 1482 | struct net_device *dev; |
1269 | void *mdev_priv; | 1483 | void *mdev_priv; |
1484 | struct wireless_dev *wdev; | ||
1270 | 1485 | ||
1271 | if (!priv) | ||
1272 | return NULL; | ||
1273 | |||
1274 | adapter = priv->adapter; | ||
1275 | if (!adapter) | 1486 | if (!adapter) |
1276 | return NULL; | 1487 | return NULL; |
1277 | 1488 | ||
@@ -1279,12 +1490,21 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1279 | case NL80211_IFTYPE_UNSPECIFIED: | 1490 | case NL80211_IFTYPE_UNSPECIFIED: |
1280 | case NL80211_IFTYPE_STATION: | 1491 | case NL80211_IFTYPE_STATION: |
1281 | case NL80211_IFTYPE_ADHOC: | 1492 | case NL80211_IFTYPE_ADHOC: |
1493 | priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; | ||
1282 | if (priv->bss_mode) { | 1494 | if (priv->bss_mode) { |
1283 | wiphy_err(wiphy, "cannot create multiple" | 1495 | wiphy_err(wiphy, |
1284 | " station/adhoc interfaces\n"); | 1496 | "cannot create multiple sta/adhoc ifaces\n"); |
1285 | return NULL; | 1497 | return NULL; |
1286 | } | 1498 | } |
1287 | 1499 | ||
1500 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); | ||
1501 | if (!wdev) | ||
1502 | return NULL; | ||
1503 | |||
1504 | wdev->wiphy = wiphy; | ||
1505 | priv->wdev = wdev; | ||
1506 | wdev->iftype = NL80211_IFTYPE_STATION; | ||
1507 | |||
1288 | if (type == NL80211_IFTYPE_UNSPECIFIED) | 1508 | if (type == NL80211_IFTYPE_UNSPECIFIED) |
1289 | priv->bss_mode = NL80211_IFTYPE_STATION; | 1509 | priv->bss_mode = NL80211_IFTYPE_STATION; |
1290 | else | 1510 | else |
@@ -1292,11 +1512,36 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1292 | 1512 | ||
1293 | priv->bss_type = MWIFIEX_BSS_TYPE_STA; | 1513 | priv->bss_type = MWIFIEX_BSS_TYPE_STA; |
1294 | priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; | 1514 | priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; |
1295 | priv->bss_priority = 0; | 1515 | priv->bss_priority = MWIFIEX_BSS_ROLE_STA; |
1296 | priv->bss_role = MWIFIEX_BSS_ROLE_STA; | 1516 | priv->bss_role = MWIFIEX_BSS_ROLE_STA; |
1297 | priv->bss_num = 0; | 1517 | priv->bss_num = 0; |
1298 | 1518 | ||
1299 | break; | 1519 | break; |
1520 | case NL80211_IFTYPE_AP: | ||
1521 | priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP]; | ||
1522 | |||
1523 | if (priv->bss_mode) { | ||
1524 | wiphy_err(wiphy, "Can't create multiple AP interfaces"); | ||
1525 | return NULL; | ||
1526 | } | ||
1527 | |||
1528 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); | ||
1529 | if (!wdev) | ||
1530 | return NULL; | ||
1531 | |||
1532 | priv->wdev = wdev; | ||
1533 | wdev->wiphy = wiphy; | ||
1534 | wdev->iftype = NL80211_IFTYPE_AP; | ||
1535 | |||
1536 | priv->bss_type = MWIFIEX_BSS_TYPE_UAP; | ||
1537 | priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; | ||
1538 | priv->bss_priority = MWIFIEX_BSS_ROLE_UAP; | ||
1539 | priv->bss_role = MWIFIEX_BSS_ROLE_UAP; | ||
1540 | priv->bss_started = 0; | ||
1541 | priv->bss_num = 0; | ||
1542 | priv->bss_mode = type; | ||
1543 | |||
1544 | break; | ||
1300 | default: | 1545 | default: |
1301 | wiphy_err(wiphy, "type not supported\n"); | 1546 | wiphy_err(wiphy, "type not supported\n"); |
1302 | return NULL; | 1547 | return NULL; |
@@ -1309,6 +1554,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1309 | goto error; | 1554 | goto error; |
1310 | } | 1555 | } |
1311 | 1556 | ||
1557 | mwifiex_init_priv_params(priv, dev); | ||
1558 | priv->netdev = dev; | ||
1559 | |||
1560 | mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); | ||
1561 | |||
1562 | if (adapter->config_bands & BAND_A) | ||
1563 | mwifiex_setup_ht_caps( | ||
1564 | &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); | ||
1565 | |||
1312 | dev_net_set(dev, wiphy_net(wiphy)); | 1566 | dev_net_set(dev, wiphy_net(wiphy)); |
1313 | dev->ieee80211_ptr = priv->wdev; | 1567 | dev->ieee80211_ptr = priv->wdev; |
1314 | dev->ieee80211_ptr->iftype = priv->bss_mode; | 1568 | dev->ieee80211_ptr->iftype = priv->bss_mode; |
@@ -1323,9 +1577,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1323 | mdev_priv = netdev_priv(dev); | 1577 | mdev_priv = netdev_priv(dev); |
1324 | *((unsigned long *) mdev_priv) = (unsigned long) priv; | 1578 | *((unsigned long *) mdev_priv) = (unsigned long) priv; |
1325 | 1579 | ||
1326 | priv->netdev = dev; | ||
1327 | mwifiex_init_priv_params(priv, dev); | ||
1328 | |||
1329 | SET_NETDEV_DEV(dev, adapter->dev); | 1580 | SET_NETDEV_DEV(dev, adapter->dev); |
1330 | 1581 | ||
1331 | /* Register network device */ | 1582 | /* Register network device */ |
@@ -1397,7 +1648,6 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { | |||
1397 | .get_station = mwifiex_cfg80211_get_station, | 1648 | .get_station = mwifiex_cfg80211_get_station, |
1398 | .dump_station = mwifiex_cfg80211_dump_station, | 1649 | .dump_station = mwifiex_cfg80211_dump_station, |
1399 | .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, | 1650 | .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, |
1400 | .set_channel = mwifiex_cfg80211_set_channel, | ||
1401 | .join_ibss = mwifiex_cfg80211_join_ibss, | 1651 | .join_ibss = mwifiex_cfg80211_join_ibss, |
1402 | .leave_ibss = mwifiex_cfg80211_leave_ibss, | 1652 | .leave_ibss = mwifiex_cfg80211_leave_ibss, |
1403 | .add_key = mwifiex_cfg80211_add_key, | 1653 | .add_key = mwifiex_cfg80211_add_key, |
@@ -1406,6 +1656,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { | |||
1406 | .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, | 1656 | .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, |
1407 | .set_tx_power = mwifiex_cfg80211_set_tx_power, | 1657 | .set_tx_power = mwifiex_cfg80211_set_tx_power, |
1408 | .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, | 1658 | .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, |
1659 | .start_ap = mwifiex_cfg80211_start_ap, | ||
1660 | .stop_ap = mwifiex_cfg80211_stop_ap, | ||
1409 | .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, | 1661 | .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, |
1410 | }; | 1662 | }; |
1411 | 1663 | ||
@@ -1416,75 +1668,67 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { | |||
1416 | * default parameters and handler function pointers, and finally | 1668 | * default parameters and handler function pointers, and finally |
1417 | * registers the device. | 1669 | * registers the device. |
1418 | */ | 1670 | */ |
1419 | int mwifiex_register_cfg80211(struct mwifiex_private *priv) | 1671 | |
1672 | int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) | ||
1420 | { | 1673 | { |
1421 | int ret; | 1674 | int ret; |
1422 | void *wdev_priv; | 1675 | void *wdev_priv; |
1423 | struct wireless_dev *wdev; | 1676 | struct wiphy *wiphy; |
1424 | struct ieee80211_sta_ht_cap *ht_info; | 1677 | struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; |
1425 | 1678 | u8 *country_code; | |
1426 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); | 1679 | |
1427 | if (!wdev) { | 1680 | /* create a new wiphy for use with cfg80211 */ |
1428 | dev_err(priv->adapter->dev, "%s: allocating wireless device\n", | 1681 | wiphy = wiphy_new(&mwifiex_cfg80211_ops, |
1429 | __func__); | 1682 | sizeof(struct mwifiex_adapter *)); |
1683 | if (!wiphy) { | ||
1684 | dev_err(adapter->dev, "%s: creating new wiphy\n", __func__); | ||
1430 | return -ENOMEM; | 1685 | return -ENOMEM; |
1431 | } | 1686 | } |
1432 | wdev->wiphy = | 1687 | wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH; |
1433 | wiphy_new(&mwifiex_cfg80211_ops, | 1688 | wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; |
1434 | sizeof(struct mwifiex_private *)); | 1689 | wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1435 | if (!wdev->wiphy) { | 1690 | BIT(NL80211_IFTYPE_ADHOC) | |
1436 | kfree(wdev); | 1691 | BIT(NL80211_IFTYPE_AP); |
1437 | return -ENOMEM; | 1692 | |
1438 | } | 1693 | wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; |
1439 | wdev->iftype = NL80211_IFTYPE_STATION; | 1694 | if (adapter->config_bands & BAND_A) |
1440 | wdev->wiphy->max_scan_ssids = 10; | 1695 | wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; |
1441 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 1696 | else |
1442 | BIT(NL80211_IFTYPE_ADHOC); | 1697 | wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
1443 | |||
1444 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; | ||
1445 | ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; | ||
1446 | mwifiex_setup_ht_caps(ht_info, priv); | ||
1447 | |||
1448 | if (priv->adapter->config_bands & BAND_A) { | ||
1449 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; | ||
1450 | ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; | ||
1451 | mwifiex_setup_ht_caps(ht_info, priv); | ||
1452 | } else { | ||
1453 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; | ||
1454 | } | ||
1455 | 1698 | ||
1456 | /* Initialize cipher suits */ | 1699 | wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; |
1457 | wdev->wiphy->cipher_suites = mwifiex_cipher_suites; | 1700 | wiphy->n_iface_combinations = 1; |
1458 | wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); | ||
1459 | 1701 | ||
1460 | memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN); | 1702 | /* Initialize cipher suits */ |
1461 | wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 1703 | wiphy->cipher_suites = mwifiex_cipher_suites; |
1704 | wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); | ||
1462 | 1705 | ||
1463 | /* Reserve space for bss band information */ | 1706 | memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); |
1464 | wdev->wiphy->bss_priv_size = sizeof(u8); | 1707 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
1708 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY; | ||
1465 | 1709 | ||
1466 | wdev->wiphy->reg_notifier = mwifiex_reg_notifier; | 1710 | /* Reserve space for mwifiex specific private data for BSS */ |
1711 | wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); | ||
1467 | 1712 | ||
1468 | /* Set struct mwifiex_private pointer in wiphy_priv */ | 1713 | wiphy->reg_notifier = mwifiex_reg_notifier; |
1469 | wdev_priv = wiphy_priv(wdev->wiphy); | ||
1470 | 1714 | ||
1471 | *(unsigned long *) wdev_priv = (unsigned long) priv; | 1715 | /* Set struct mwifiex_adapter pointer in wiphy_priv */ |
1716 | wdev_priv = wiphy_priv(wiphy); | ||
1717 | *(unsigned long *)wdev_priv = (unsigned long)adapter; | ||
1472 | 1718 | ||
1473 | set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); | 1719 | set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev); |
1474 | 1720 | ||
1475 | ret = wiphy_register(wdev->wiphy); | 1721 | ret = wiphy_register(wiphy); |
1476 | if (ret < 0) { | 1722 | if (ret < 0) { |
1477 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", | 1723 | dev_err(adapter->dev, |
1478 | __func__); | 1724 | "%s: wiphy_register failed: %d\n", __func__, ret); |
1479 | wiphy_free(wdev->wiphy); | 1725 | wiphy_free(wiphy); |
1480 | kfree(wdev); | ||
1481 | return ret; | 1726 | return ret; |
1482 | } else { | ||
1483 | dev_dbg(priv->adapter->dev, | ||
1484 | "info: successfully registered wiphy device\n"); | ||
1485 | } | 1727 | } |
1728 | country_code = mwifiex_11d_code_2_region(priv->adapter->region_code); | ||
1729 | if (country_code && regulatory_hint(wiphy, country_code)) | ||
1730 | dev_err(adapter->dev, "regulatory_hint() failed\n"); | ||
1486 | 1731 | ||
1487 | priv->wdev = wdev; | 1732 | adapter->wiphy = wiphy; |
1488 | |||
1489 | return ret; | 1733 | return ret; |
1490 | } | 1734 | } |