* @beacon_interval: beacon interval to use
  * @privacy: this is a protected network, keys will be configured
  *     after joining
+ * @control_port: whether user space controls IEEE 802.1X port, i.e.,
+ *     sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ *     required to assume that the port is unauthorized until authorized by
+ *     user space. Otherwise, port is marked authorized by default.
  * @basic_rates: bitmap of basic rates to use when creating the IBSS
  * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
  */
        u32 basic_rates;
        bool channel_fixed;
        bool privacy;
+       bool control_port;
        int mcast_rate[IEEE80211_NUM_BANDS];
 };
 
 
 
        sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
        sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
-       sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
+       /* authorize the station only if the network is not RSN protected. If
+        * not wait for the userspace to authorize it */
+       if (!sta->sdata->u.ibss.control_port)
+               sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
        rate_control_rate_init(sta);
 
                sdata->u.ibss.fixed_bssid = false;
 
        sdata->u.ibss.privacy = params->privacy;
+       sdata->u.ibss.control_port = params->control_port;
        sdata->u.ibss.basic_rates = params->basic_rates;
        memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
               sizeof(params->mcast_rate));
 
        bool fixed_channel;
        bool privacy;
 
+       bool control_port;
+
        u8 bssid[ETH_ALEN];
        u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 ssid_len, ie_len;
 
                break;
        case NL80211_IFTYPE_P2P_CLIENT:
        case NL80211_IFTYPE_STATION:
-               /* disallow things sta doesn't support */
-               if (params.plink_action)
-                       return -EINVAL;
-               if (params.ht_capa)
-                       return -EINVAL;
-               if (params.listen_interval >= 0)
-                       return -EINVAL;
                /*
                 * Don't allow userspace to change the TDLS_PEER flag,
                 * but silently ignore attempts to change it since we
                 * to change the flag.
                 */
                params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
-
+               /* fall through */
+       case NL80211_IFTYPE_ADHOC:
+               /* disallow things sta doesn't support */
+               if (params.plink_action)
+                       return -EINVAL;
+               if (params.ht_capa)
+                       return -EINVAL;
+               if (params.listen_interval >= 0)
+                       return -EINVAL;
                /* reject any changes other than AUTHORIZED */
                if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
                        return -EINVAL;
                        return PTR_ERR(connkeys);
        }
 
+       ibss.control_port =
+               nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
+
        err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
        if (err)
                kfree(connkeys);