aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c532
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
23static 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
32static 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 */
70static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy) 87static 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)
272static int mwifiex_reg_notifier(struct wiphy *wiphy, 298static 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 */
372static int
373mwifiex_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,
399static int 402static int
400mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) 403mwifiex_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)
439static int 437static int
440mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 438mwifiex_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 */
902static 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 */
923static 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 }
977done: 1166done:
@@ -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 */
1419int mwifiex_register_cfg80211(struct mwifiex_private *priv) 1671
1672int 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}