diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 85 |
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 | */ |
573 | static int | 562 | static int |
574 | mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, | 563 | mwifiex_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 | ||
615 | done: | ||
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 | ||
1176 | done: | 1171 | done: |
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); |
1214 | done: | 1207 | done: |
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); |