@@ -268,6 +268,8 @@ mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
268
268
269
269
if (mask != priv -> mgmt_frame_mask ) {
270
270
priv -> mgmt_frame_mask = mask ;
271
+ if (priv -> host_mlme_reg )
272
+ priv -> mgmt_frame_mask |= HOST_MLME_MGMT_MASK ;
271
273
mwifiex_send_cmd (priv , HostCmd_CMD_MGMT_FRAME_REG ,
272
274
HostCmd_ACT_GEN_SET , 0 ,
273
275
& priv -> mgmt_frame_mask , false);
@@ -848,6 +850,7 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
848
850
struct mwifiex_adapter * adapter = priv -> adapter ;
849
851
unsigned long flags ;
850
852
853
+ priv -> host_mlme_reg = false;
851
854
priv -> mgmt_frame_mask = 0 ;
852
855
if (mwifiex_send_cmd (priv , HostCmd_CMD_MGMT_FRAME_REG ,
853
856
HostCmd_ACT_GEN_SET , 0 ,
@@ -3633,6 +3636,9 @@ static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
3633
3636
if (!ISSUPP_FIRMWARE_SUPPLICANT (priv -> adapter -> fw_cap_info ))
3634
3637
return - EOPNOTSUPP ;
3635
3638
3639
+ if (priv -> adapter -> host_mlme_enabled )
3640
+ return 0 ;
3641
+
3636
3642
return mwifiex_send_cmd (priv , HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG ,
3637
3643
HostCmd_ACT_GEN_SET , 0 , data , true);
3638
3644
}
@@ -4206,6 +4212,305 @@ mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
4206
4212
return ret ;
4207
4213
}
4208
4214
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
+
4209
4514
/* station cfg80211 operations */
4210
4515
static struct cfg80211_ops mwifiex_cfg80211_ops = {
4211
4516
.add_virtual_intf = mwifiex_add_virtual_intf ,
@@ -4351,6 +4656,16 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
4351
4656
"%s: creating new wiphy\n" , __func__ );
4352
4657
return - ENOMEM ;
4353
4658
}
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
+ }
4354
4669
wiphy -> max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH ;
4355
4670
wiphy -> max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN ;
4356
4671
wiphy -> mgmt_stypes = mwifiex_mgmt_stypes ;
@@ -4434,6 +4749,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
4434
4749
NL80211_FEATURE_LOW_PRIORITY_SCAN |
4435
4750
NL80211_FEATURE_NEED_OBSS_SCAN ;
4436
4751
4752
+ if (adapter -> host_mlme_enabled )
4753
+ wiphy -> features |= NL80211_FEATURE_SAE ;
4754
+
4437
4755
if (ISSUPP_ADHOC_ENABLED (adapter -> fw_cap_info ))
4438
4756
wiphy -> features |= NL80211_FEATURE_HT_IBSS ;
4439
4757
0 commit comments