@@ -268,6 +268,8 @@ mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
268268
269269 if (mask != priv -> mgmt_frame_mask ) {
270270 priv -> mgmt_frame_mask = mask ;
271+ if (priv -> host_mlme_reg )
272+ priv -> mgmt_frame_mask |= HOST_MLME_MGMT_MASK ;
271273 mwifiex_send_cmd (priv , HostCmd_CMD_MGMT_FRAME_REG ,
272274 HostCmd_ACT_GEN_SET , 0 ,
273275 & priv -> mgmt_frame_mask , false);
@@ -848,6 +850,7 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
848850 struct mwifiex_adapter * adapter = priv -> adapter ;
849851 unsigned long flags ;
850852
853+ priv -> host_mlme_reg = false;
851854 priv -> mgmt_frame_mask = 0 ;
852855 if (mwifiex_send_cmd (priv , HostCmd_CMD_MGMT_FRAME_REG ,
853856 HostCmd_ACT_GEN_SET , 0 ,
@@ -3633,6 +3636,9 @@ static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
36333636 if (!ISSUPP_FIRMWARE_SUPPLICANT (priv -> adapter -> fw_cap_info ))
36343637 return - EOPNOTSUPP ;
36353638
3639+ if (priv -> adapter -> host_mlme_enabled )
3640+ return 0 ;
3641+
36363642 return mwifiex_send_cmd (priv , HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG ,
36373643 HostCmd_ACT_GEN_SET , 0 , data , true);
36383644}
@@ -4206,6 +4212,305 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
42064212 return ret ;
42074213}
42084214
4215+ static int
4216+ mwifiex_cfg80211_authenticate (struct wiphy * wiphy ,
4217+ struct net_device * dev ,
4218+ struct cfg80211_auth_request * req )
4219+ {
4220+ struct mwifiex_private * priv = mwifiex_netdev_get_priv (dev );
4221+ struct mwifiex_adapter * adapter = priv -> adapter ;
4222+ struct sk_buff * skb ;
4223+ u16 pkt_len , auth_alg ;
4224+ int ret ;
4225+ struct mwifiex_ieee80211_mgmt * mgmt ;
4226+ struct mwifiex_txinfo * tx_info ;
4227+ u32 tx_control = 0 , pkt_type = PKT_TYPE_MGMT ;
4228+ u8 trans = 1 , status_code = 0 ;
4229+ u8 * varptr ;
4230+
4231+ if (GET_BSS_ROLE (priv ) == MWIFIEX_BSS_ROLE_UAP ) {
4232+ mwifiex_dbg (priv -> adapter , ERROR , "Interface role is AP\n" );
4233+ return - EFAULT ;
4234+ }
4235+
4236+ if (priv -> wdev .iftype != NL80211_IFTYPE_STATION ) {
4237+ mwifiex_dbg (priv -> adapter , ERROR ,
4238+ "Interface type is not correct (type %d)\n" ,
4239+ priv -> wdev .iftype );
4240+ return - EINVAL ;
4241+ }
4242+
4243+ if (priv -> auth_alg != WLAN_AUTH_SAE &&
4244+ (priv -> auth_flag & HOST_MLME_AUTH_PENDING )) {
4245+ mwifiex_dbg (priv -> adapter , ERROR , "Pending auth on going\n" );
4246+ return - EBUSY ;
4247+ }
4248+
4249+ if (!priv -> host_mlme_reg ) {
4250+ priv -> host_mlme_reg = true;
4251+ priv -> mgmt_frame_mask |= HOST_MLME_MGMT_MASK ;
4252+ mwifiex_send_cmd (priv , HostCmd_CMD_MGMT_FRAME_REG ,
4253+ HostCmd_ACT_GEN_SET , 0 ,
4254+ & priv -> mgmt_frame_mask , false);
4255+ }
4256+
4257+ switch (req -> auth_type ) {
4258+ case NL80211_AUTHTYPE_OPEN_SYSTEM :
4259+ auth_alg = WLAN_AUTH_OPEN ;
4260+ break ;
4261+ case NL80211_AUTHTYPE_SHARED_KEY :
4262+ auth_alg = WLAN_AUTH_SHARED_KEY ;
4263+ break ;
4264+ case NL80211_AUTHTYPE_FT :
4265+ auth_alg = WLAN_AUTH_FT ;
4266+ break ;
4267+ case NL80211_AUTHTYPE_NETWORK_EAP :
4268+ auth_alg = WLAN_AUTH_LEAP ;
4269+ break ;
4270+ case NL80211_AUTHTYPE_SAE :
4271+ auth_alg = WLAN_AUTH_SAE ;
4272+ break ;
4273+ default :
4274+ mwifiex_dbg (priv -> adapter , ERROR ,
4275+ "unsupported auth type=%d\n" , req -> auth_type );
4276+ return - EOPNOTSUPP ;
4277+ }
4278+
4279+ if (!priv -> auth_flag ) {
4280+ ret = mwifiex_remain_on_chan_cfg (priv , HostCmd_ACT_GEN_SET ,
4281+ req -> bss -> channel ,
4282+ AUTH_TX_DEFAULT_WAIT_TIME );
4283+
4284+ if (!ret ) {
4285+ priv -> roc_cfg .cookie = get_random_u32 () | 1 ;
4286+ priv -> roc_cfg .chan = * req -> bss -> channel ;
4287+ } else {
4288+ return - EFAULT ;
4289+ }
4290+ }
4291+
4292+ priv -> sec_info .authentication_mode = auth_alg ;
4293+
4294+ mwifiex_cancel_scan (adapter );
4295+
4296+ pkt_len = (u16 )req -> ie_len + req -> auth_data_len +
4297+ MWIFIEX_MGMT_HEADER_LEN + MWIFIEX_AUTH_BODY_LEN ;
4298+ if (req -> auth_data_len >= 4 )
4299+ pkt_len -= 4 ;
4300+
4301+ skb = dev_alloc_skb (MWIFIEX_MIN_DATA_HEADER_LEN +
4302+ MWIFIEX_MGMT_FRAME_HEADER_SIZE +
4303+ pkt_len + sizeof (pkt_len ));
4304+ if (!skb ) {
4305+ mwifiex_dbg (priv -> adapter , ERROR ,
4306+ "allocate skb failed for management frame\n" );
4307+ return - ENOMEM ;
4308+ }
4309+
4310+ tx_info = MWIFIEX_SKB_TXCB (skb );
4311+ memset (tx_info , 0 , sizeof (* tx_info ));
4312+ tx_info -> bss_num = priv -> bss_num ;
4313+ tx_info -> bss_type = priv -> bss_type ;
4314+ tx_info -> pkt_len = pkt_len ;
4315+
4316+ skb_reserve (skb , MWIFIEX_MIN_DATA_HEADER_LEN +
4317+ MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof (pkt_len ));
4318+ memcpy (skb_push (skb , sizeof (pkt_len )), & pkt_len , sizeof (pkt_len ));
4319+ memcpy (skb_push (skb , sizeof (tx_control )),
4320+ & tx_control , sizeof (tx_control ));
4321+ memcpy (skb_push (skb , sizeof (pkt_type )), & pkt_type , sizeof (pkt_type ));
4322+
4323+ mgmt = (struct mwifiex_ieee80211_mgmt * )skb_put (skb , pkt_len );
4324+ memset (mgmt , 0 , pkt_len );
4325+ mgmt -> frame_control =
4326+ cpu_to_le16 (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH );
4327+ memcpy (mgmt -> da , req -> bss -> bssid , ETH_ALEN );
4328+ memcpy (mgmt -> sa , priv -> curr_addr , ETH_ALEN );
4329+ memcpy (mgmt -> bssid , req -> bss -> bssid , ETH_ALEN );
4330+ eth_broadcast_addr (mgmt -> addr4 );
4331+
4332+ if (req -> auth_data_len >= 4 ) {
4333+ if (req -> auth_type == NL80211_AUTHTYPE_SAE ) {
4334+ __le16 * pos = (__le16 * )req -> auth_data ;
4335+
4336+ trans = le16_to_cpu (pos [0 ]);
4337+ status_code = le16_to_cpu (pos [1 ]);
4338+ }
4339+ memcpy ((u8 * )(& mgmt -> auth .variable ), req -> auth_data + 4 ,
4340+ req -> auth_data_len - 4 );
4341+ varptr = (u8 * )& mgmt -> auth .variable +
4342+ (req -> auth_data_len - 4 );
4343+ }
4344+
4345+ mgmt -> auth .auth_alg = cpu_to_le16 (auth_alg );
4346+ mgmt -> auth .auth_transaction = cpu_to_le16 (trans );
4347+ mgmt -> auth .status_code = cpu_to_le16 (status_code );
4348+
4349+ if (req -> ie && req -> ie_len ) {
4350+ if (!varptr )
4351+ varptr = (u8 * )& mgmt -> auth .variable ;
4352+ memcpy ((u8 * )varptr , req -> ie , req -> ie_len );
4353+ }
4354+
4355+ priv -> auth_flag = HOST_MLME_AUTH_PENDING ;
4356+ priv -> auth_alg = auth_alg ;
4357+
4358+ skb -> priority = WMM_HIGHEST_PRIORITY ;
4359+ __net_timestamp (skb );
4360+
4361+ mwifiex_dbg (priv -> adapter , MSG ,
4362+ "auth: send authentication to %pM\n" , req -> bss -> bssid );
4363+
4364+ mwifiex_queue_tx_pkt (priv , skb );
4365+
4366+ return 0 ;
4367+ }
4368+
4369+ static int
4370+ mwifiex_cfg80211_associate (struct wiphy * wiphy , struct net_device * dev ,
4371+ struct cfg80211_assoc_request * req )
4372+ {
4373+ struct mwifiex_private * priv = mwifiex_netdev_get_priv (dev );
4374+ struct mwifiex_adapter * adapter = priv -> adapter ;
4375+ int ret ;
4376+ struct cfg80211_ssid req_ssid ;
4377+ const u8 * ssid_ie ;
4378+
4379+ if (GET_BSS_ROLE (priv ) != MWIFIEX_BSS_ROLE_STA ) {
4380+ mwifiex_dbg (adapter , ERROR ,
4381+ "%s: reject infra assoc request in non-STA role\n" ,
4382+ dev -> name );
4383+ return - EINVAL ;
4384+ }
4385+
4386+ if (test_bit (MWIFIEX_SURPRISE_REMOVED , & adapter -> work_flags ) ||
4387+ test_bit (MWIFIEX_IS_CMD_TIMEDOUT , & adapter -> work_flags )) {
4388+ mwifiex_dbg (adapter , ERROR ,
4389+ "%s: Ignore association.\t"
4390+ "Card removed or FW in bad state\n" ,
4391+ dev -> name );
4392+ return - EFAULT ;
4393+ }
4394+
4395+ if (priv -> auth_alg == WLAN_AUTH_SAE )
4396+ priv -> auth_flag = HOST_MLME_AUTH_DONE ;
4397+
4398+ if (priv -> auth_flag && !(priv -> auth_flag & HOST_MLME_AUTH_DONE ))
4399+ return - EBUSY ;
4400+
4401+ if (priv -> roc_cfg .cookie ) {
4402+ ret = mwifiex_remain_on_chan_cfg (priv , HostCmd_ACT_GEN_REMOVE ,
4403+ & priv -> roc_cfg .chan , 0 );
4404+ if (!ret )
4405+ memset (& priv -> roc_cfg , 0 ,
4406+ sizeof (struct mwifiex_roc_cfg ));
4407+ else
4408+ return - EFAULT ;
4409+ }
4410+
4411+ if (!mwifiex_stop_bg_scan (priv ))
4412+ cfg80211_sched_scan_stopped_locked (priv -> wdev .wiphy , 0 );
4413+
4414+ memset (& req_ssid , 0 , sizeof (struct cfg80211_ssid ));
4415+ rcu_read_lock ();
4416+ ssid_ie = ieee80211_bss_get_ie (req -> bss , WLAN_EID_SSID );
4417+
4418+ if (!ssid_ie )
4419+ goto ssid_err ;
4420+
4421+ req_ssid .ssid_len = ssid_ie [1 ];
4422+ if (req_ssid .ssid_len > IEEE80211_MAX_SSID_LEN ) {
4423+ mwifiex_dbg (adapter , ERROR , "invalid SSID - aborting\n" );
4424+ goto ssid_err ;
4425+ }
4426+
4427+ memcpy (req_ssid .ssid , ssid_ie + 2 , req_ssid .ssid_len );
4428+ if (!req_ssid .ssid_len || req_ssid .ssid [0 ] < 0x20 ) {
4429+ mwifiex_dbg (adapter , ERROR , "invalid SSID - aborting\n" );
4430+ goto ssid_err ;
4431+ }
4432+ rcu_read_unlock ();
4433+
4434+ /* As this is new association, clear locally stored
4435+ * keys and security related flags
4436+ */
4437+ priv -> sec_info .wpa_enabled = false;
4438+ priv -> sec_info .wpa2_enabled = false;
4439+ priv -> wep_key_curr_index = 0 ;
4440+ priv -> sec_info .encryption_mode = 0 ;
4441+ priv -> sec_info .is_authtype_auto = 0 ;
4442+ if (mwifiex_set_encode (priv , NULL , NULL , 0 , 0 , NULL , 1 )) {
4443+ mwifiex_dbg (priv -> adapter , ERROR , "deleting the crypto keys\n" );
4444+ return - EFAULT ;
4445+ }
4446+
4447+ if (req -> crypto .n_ciphers_pairwise )
4448+ priv -> sec_info .encryption_mode =
4449+ req -> crypto .ciphers_pairwise [0 ];
4450+
4451+ if (req -> crypto .cipher_group )
4452+ priv -> sec_info .encryption_mode = req -> crypto .cipher_group ;
4453+
4454+ if (req -> ie )
4455+ mwifiex_set_gen_ie (priv , req -> ie , req -> ie_len );
4456+
4457+ memcpy (priv -> cfg_bssid , req -> bss -> bssid , ETH_ALEN );
4458+
4459+ mwifiex_dbg (adapter , MSG ,
4460+ "assoc: send association to %pM\n" , req -> bss -> bssid );
4461+
4462+ cfg80211_ref_bss (adapter -> wiphy , req -> bss );
4463+ ret = mwifiex_bss_start (priv , req -> bss , & req_ssid );
4464+ if (ret ) {
4465+ priv -> auth_flag = 0 ;
4466+ priv -> auth_alg = WLAN_AUTH_NONE ;
4467+ eth_zero_addr (priv -> cfg_bssid );
4468+ }
4469+
4470+ if (priv -> assoc_rsp_size ) {
4471+ priv -> req_bss = req -> bss ;
4472+ adapter -> assoc_resp_received = true;
4473+ queue_work (adapter -> host_mlme_workqueue ,
4474+ & adapter -> host_mlme_work );
4475+ }
4476+
4477+ cfg80211_put_bss (priv -> adapter -> wiphy , req -> bss );
4478+
4479+ return 0 ;
4480+
4481+ ssid_err :
4482+ rcu_read_unlock ();
4483+ return - EFAULT ;
4484+ }
4485+
4486+ static int
4487+ mwifiex_cfg80211_deauthenticate (struct wiphy * wiphy ,
4488+ struct net_device * dev ,
4489+ struct cfg80211_deauth_request * req )
4490+ {
4491+ return mwifiex_cfg80211_disconnect (wiphy , dev , req -> reason_code );
4492+ }
4493+
4494+ static int
4495+ mwifiex_cfg80211_disassociate (struct wiphy * wiphy ,
4496+ struct net_device * dev ,
4497+ struct cfg80211_disassoc_request * req )
4498+ {
4499+ return mwifiex_cfg80211_disconnect (wiphy , dev , req -> reason_code );
4500+ }
4501+
4502+ static int
4503+ mwifiex_cfg80211_probe_client (struct wiphy * wiphy ,
4504+ struct net_device * dev , const u8 * peer ,
4505+ u64 * cookie )
4506+ {
4507+ /* hostapd looks for NL80211_CMD_PROBE_CLIENT support; otherwise,
4508+ * it requires monitor-mode support (which mwifiex doesn't support).
4509+ * Provide fake probe_client support to work around this.
4510+ */
4511+ return - EOPNOTSUPP ;
4512+ }
4513+
42094514/* station cfg80211 operations */
42104515static struct cfg80211_ops mwifiex_cfg80211_ops = {
42114516 .add_virtual_intf = mwifiex_add_virtual_intf ,
@@ -4351,6 +4656,16 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
43514656 "%s: creating new wiphy\n" , __func__ );
43524657 return - ENOMEM ;
43534658 }
4659+ if (adapter -> host_mlme_enabled ) {
4660+ mwifiex_cfg80211_ops .auth = mwifiex_cfg80211_authenticate ;
4661+ mwifiex_cfg80211_ops .assoc = mwifiex_cfg80211_associate ;
4662+ mwifiex_cfg80211_ops .deauth = mwifiex_cfg80211_deauthenticate ;
4663+ mwifiex_cfg80211_ops .disassoc = mwifiex_cfg80211_disassociate ;
4664+ mwifiex_cfg80211_ops .disconnect = NULL ;
4665+ mwifiex_cfg80211_ops .connect = NULL ;
4666+ mwifiex_cfg80211_ops .probe_client =
4667+ mwifiex_cfg80211_probe_client ;
4668+ }
43544669 wiphy -> max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH ;
43554670 wiphy -> max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN ;
43564671 wiphy -> mgmt_stypes = mwifiex_mgmt_stypes ;
@@ -4434,6 +4749,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
44344749 NL80211_FEATURE_LOW_PRIORITY_SCAN |
44354750 NL80211_FEATURE_NEED_OBSS_SCAN ;
44364751
4752+ if (adapter -> host_mlme_enabled )
4753+ wiphy -> features |= NL80211_FEATURE_SAE ;
4754+
44374755 if (ISSUPP_ADHOC_ENABLED (adapter -> fw_cap_info ))
44384756 wiphy -> features |= NL80211_FEATURE_HT_IBSS ;
44394757
0 commit comments