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.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index de86ef879509..701c17980f6d 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -398,13 +398,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
398 int ret = 0; 398 int ret = 0;
399 int status = 0; 399 int status = 0;
400 struct mwifiex_ds_band_cfg band_cfg; 400 struct mwifiex_ds_band_cfg band_cfg;
401 int mode;
402 u8 wait_option = MWIFIEX_IOCTL_WAIT;
403 u32 config_bands = 0; 401 u32 config_bands = 0;
404 struct wiphy *wiphy = priv->wdev->wiphy; 402 struct wiphy *wiphy = priv->wdev->wiphy;
405 403
406 mode = mwifiex_drv_get_mode(priv, wait_option);
407
408 if (chan) { 404 if (chan) {
409 memset(&band_cfg, 0, sizeof(band_cfg)); 405 memset(&band_cfg, 0, sizeof(band_cfg));
410 /* Set appropriate bands */ 406 /* Set appropriate bands */
@@ -412,10 +408,10 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
412 config_bands = BAND_B | BAND_G | BAND_GN; 408 config_bands = BAND_B | BAND_G | BAND_GN;
413 else 409 else
414 config_bands = BAND_AN | BAND_A; 410 config_bands = BAND_AN | BAND_A;
415 if (mode == MWIFIEX_BSS_MODE_INFRA 411 if (priv->bss_mode == NL80211_IFTYPE_STATION
416 || mode == MWIFIEX_BSS_MODE_AUTO) { 412 || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) {
417 band_cfg.config_bands = config_bands; 413 band_cfg.config_bands = config_bands;
418 } else if (mode == MWIFIEX_BSS_MODE_IBSS) { 414 } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
419 band_cfg.config_bands = config_bands; 415 band_cfg.config_bands = config_bands;
420 band_cfg.adhoc_start_band = config_bands; 416 band_cfg.adhoc_start_band = config_bands;
421 } 417 }
@@ -432,7 +428,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
432 } 428 }
433 429
434 wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " 430 wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and "
435 "mode %d\n", config_bands, band_cfg.sec_chan_offset, mode); 431 "mode %d\n", config_bands, band_cfg.sec_chan_offset,
432 priv->bss_mode);
436 if (!chan) 433 if (!chan)
437 return ret; 434 return ret;
438 435
@@ -561,14 +558,6 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
561 558
562/* 559/*
563 * CFG802.11 operation handler to change interface type. 560 * CFG802.11 operation handler to change interface type.
564 *
565 * This function creates an IOCTL request, populates it accordingly
566 * and issues an IOCTL.
567 *
568 * The function also maps the CFG802.11 mode type into driver mode type.
569 * NL80211_IFTYPE_ADHOC -> MWIFIEX_BSS_MODE_IBSS
570 * NL80211_IFTYPE_STATION -> MWIFIEX_BSS_MODE_INFRA
571 * NL80211_IFTYPE_UNSPECIFIED -> MWIFIEX_BSS_MODE_AUTO
572 */ 561 */
573static int 562static int
574mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, 563mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
@@ -578,41 +567,50 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
578{ 567{
579 int ret = 0; 568 int ret = 0;
580 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 569 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
581 int mode = -1;
582 struct mwifiex_wait_queue *wait = NULL; 570 struct mwifiex_wait_queue *wait = NULL;
583 int status = 0;
584 571
585 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); 572 if (priv->bss_mode == type) {
586 if (!wait) 573 wiphy_warn(wiphy, "already set to required type\n");
587 return -ENOMEM; 574 return 0;
575 }
576
577 priv->bss_mode = type;
588 578
589 switch (type) { 579 switch (type) {
590 case NL80211_IFTYPE_ADHOC: 580 case NL80211_IFTYPE_ADHOC:
591 mode = MWIFIEX_BSS_MODE_IBSS;
592 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; 581 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC;
593 wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); 582 wiphy_dbg(wiphy, "info: setting interface type to adhoc\n");
594 break; 583 break;
595 case NL80211_IFTYPE_STATION: 584 case NL80211_IFTYPE_STATION:
596 mode = MWIFIEX_BSS_MODE_INFRA;
597 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 585 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
598 wiphy_dbg(wiphy, "info: Setting interface type to managed\n"); 586 wiphy_dbg(wiphy, "info: setting interface type to managed\n");
599 break; 587 break;
600 case NL80211_IFTYPE_UNSPECIFIED: 588 case NL80211_IFTYPE_UNSPECIFIED:
601 mode = MWIFIEX_BSS_MODE_AUTO;
602 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 589 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
603 wiphy_dbg(wiphy, "info: setting interface type to auto\n"); 590 wiphy_dbg(wiphy, "info: setting interface type to auto\n");
604 break; 591 return 0;
605 default: 592 default:
606 ret = -EINVAL; 593 wiphy_err(wiphy, "unknown interface type: %d\n", type);
594 return -EINVAL;
607 } 595 }
608 if (ret)
609 goto done;
610 status = mwifiex_bss_ioctl_mode(priv, wait, HostCmd_ACT_GEN_SET, &mode);
611 596
612 if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) 597 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
598 if (!wait)
599 return -ENOMEM;
600
601 mwifiex_deauthenticate(priv, wait, NULL);
602
603 priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN;
604
605 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
606 HostCmd_ACT_GEN_SET, 0, wait, NULL);
607 if (!ret)
608 ret = -EINPROGRESS;
609
610 ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT);
611 if (ret)
613 ret = -EFAULT; 612 ret = -EFAULT;
614 613
615done:
616 kfree(wait); 614 kfree(wait);
617 return ret; 615 return ret;
618} 616}
@@ -1046,7 +1044,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
1046 1044
1047 ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ 1045 ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */
1048 1046
1049 if (mode == MWIFIEX_BSS_MODE_IBSS) { 1047 if (mode == NL80211_IFTYPE_ADHOC) {
1050 /* "privacy" is set only for ad-hoc mode */ 1048 /* "privacy" is set only for ad-hoc mode */
1051 if (privacy) { 1049 if (privacy) {
1052 /* 1050 /*
@@ -1108,7 +1106,7 @@ done:
1108 1106
1109 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); 1107 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
1110 1108
1111 if (mode != MWIFIEX_BSS_MODE_IBSS) { 1109 if (mode != NL80211_IFTYPE_ADHOC) {
1112 if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, 1110 if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT,
1113 &ssid_bssid)) 1111 &ssid_bssid))
1114 return -EFAULT; 1112 return -EFAULT;
@@ -1129,7 +1127,7 @@ done:
1129 if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) 1127 if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid))
1130 return -EFAULT; 1128 return -EFAULT;
1131 1129
1132 if (mode == MWIFIEX_BSS_MODE_IBSS) { 1130 if (mode == NL80211_IFTYPE_ADHOC) {
1133 /* Inform the BSS information to kernel, otherwise 1131 /* Inform the BSS information to kernel, otherwise
1134 * kernel will give a panic after successful assoc */ 1132 * kernel will give a panic after successful assoc */
1135 if (mwifiex_cfg80211_inform_ibss_bss(priv)) 1133 if (mwifiex_cfg80211_inform_ibss_bss(priv))
@@ -1152,14 +1150,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1152{ 1150{
1153 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1151 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1154 int ret = 0; 1152 int ret = 0;
1155 int mode = 0;
1156 1153
1157 if (priv->assoc_request) 1154 if (priv->assoc_request)
1158 return -EBUSY; 1155 return -EBUSY;
1159 1156
1160 mode = mwifiex_drv_get_mode(priv, MWIFIEX_IOCTL_WAIT); 1157 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
1161
1162 if (mode == MWIFIEX_BSS_MODE_IBSS) {
1163 wiphy_err(wiphy, "received infra assoc request " 1158 wiphy_err(wiphy, "received infra assoc request "
1164 "when station is in ibss mode\n"); 1159 "when station is in ibss mode\n");
1165 goto done; 1160 goto done;
@@ -1171,7 +1166,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1171 (char *) sme->ssid, sme->bssid); 1166 (char *) sme->ssid, sme->bssid);
1172 1167
1173 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, 1168 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
1174 mode, sme->channel, sme, 0); 1169 priv->bss_mode, sme->channel, sme, 0);
1175 1170
1176done: 1171done:
1177 priv->assoc_result = ret; 1172 priv->assoc_result = ret;
@@ -1191,13 +1186,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1191{ 1186{
1192 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 1187 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1193 int ret = 0; 1188 int ret = 0;
1194 int mode = 0;
1195 1189
1196 if (priv->ibss_join_request) 1190 if (priv->ibss_join_request)
1197 return -EBUSY; 1191 return -EBUSY;
1198 1192
1199 mode = mwifiex_drv_get_mode(priv, MWIFIEX_IOCTL_WAIT); 1193 if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
1200 if (mode != MWIFIEX_BSS_MODE_IBSS) {
1201 wiphy_err(wiphy, "request to join ibss received " 1194 wiphy_err(wiphy, "request to join ibss received "
1202 "when station is not in ibss mode\n"); 1195 "when station is not in ibss mode\n");
1203 goto done; 1196 goto done;
@@ -1209,8 +1202,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1209 (char *) params->ssid, params->bssid); 1202 (char *) params->ssid, params->bssid);
1210 1203
1211 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1204 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1212 params->bssid, mode, params->channel, NULL, 1205 params->bssid, priv->bss_mode,
1213 params->privacy); 1206 params->channel, NULL, params->privacy);
1214done: 1207done:
1215 priv->ibss_join_result = ret; 1208 priv->ibss_join_result = ret;
1216 queue_work(priv->workqueue, &priv->cfg_workqueue); 1209 queue_work(priv->workqueue, &priv->cfg_workqueue);
@@ -1301,7 +1294,7 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
1301 /* Clear all the other values */ 1294 /* Clear all the other values */
1302 memset(&mcs[rx_mcs_supp], 0, 1295 memset(&mcs[rx_mcs_supp], 0,
1303 sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); 1296 sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
1304 if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || 1297 if (priv->bss_mode == NL80211_IFTYPE_STATION ||
1305 ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) 1298 ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
1306 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ 1299 /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
1307 SETHT_MCS32(mcs_set.rx_mask); 1300 SETHT_MCS32(mcs_set.rx_mask);