2121static const struct ieee80211_txrx_stypes
2222 wilc_wfi_cfg80211_mgmt_types [NUM_NL80211_IFTYPES ] = {
2323 [NL80211_IFTYPE_STATION ] = {
24- .tx = 0xffff ,
24+ .tx = BIT (IEEE80211_STYPE_ACTION >> 4 ) |
25+ BIT (IEEE80211_STYPE_AUTH >> 4 ),
2526 .rx = BIT (IEEE80211_STYPE_ACTION >> 4 ) |
26- BIT (IEEE80211_STYPE_PROBE_REQ >> 4 )
27+ BIT (IEEE80211_STYPE_PROBE_REQ >> 4 ) |
28+ BIT (IEEE80211_STYPE_AUTH >> 4 ),
2729 },
2830 [NL80211_IFTYPE_AP ] = {
2931 .tx = 0xffff ,
@@ -382,6 +384,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
382384 int ret ;
383385 u32 i ;
384386 u8 security = WILC_FW_SEC_NO ;
387+ enum mfptype mfp_type = WILC_FW_MFP_NONE ;
385388 enum authtype auth_type = WILC_FW_AUTH_ANY ;
386389 u32 cipher_group ;
387390 struct cfg80211_bss * bss ;
@@ -394,6 +397,13 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
394397 "Connecting to SSID [%s] on netdev [%p] host if [%x]\n" ,
395398 sme -> ssid , dev , (u32 )priv -> hif_drv );
396399
400+ if (sme -> auth_type == NL80211_AUTHTYPE_SAE &&
401+ vif -> wilc -> chip == WILC_3000 ){
402+ pr_err ("WILC3000: WPA3 not supported\n" );
403+ ret = - ENOTSUPP ;
404+ goto out_error ;
405+ }
406+
397407 if (vif -> iftype == WILC_CLIENT_MODE )
398408 PRINT_INFO (vif -> ndev , CFG80211_DBG ,
399409 "Connected to Direct network,OBSS disabled\n" );
@@ -458,6 +468,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
458468 auth_type = WILC_FW_AUTH_OPEN_SYSTEM ;
459469 break ;
460470
471+ case NL80211_AUTHTYPE_SAE :
472+ auth_type = WILC_FW_AUTH_SAE ;
473+ if (sme -> ssid_len ) {
474+ memcpy (vif -> auth .ssid .ssid , sme -> ssid , sme -> ssid_len );
475+ vif -> auth .ssid .ssid_len = sme -> ssid_len ;
476+ }
477+ vif -> auth .key_mgmt_suite = cpu_to_be32 (sme -> crypto .akm_suites [0 ]);
478+ ether_addr_copy (vif -> auth .bssid , sme -> bssid );
479+ pr_debug ("%s: external SAE processing: bss=%pM action=%u akm=%u len[%d]\n" ,
480+ __func__ , sme -> bssid , vif -> auth .action ,
481+ vif -> auth .key_mgmt_suite , sme -> crypto .sae_pwd_len );
482+ break ;
461483 default :
462484 PRINT_INFO (vif -> ndev , CFG80211_DBG ,
463485 "Automatic Authentication type= %d\n" ,
@@ -466,8 +488,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
466488 }
467489
468490 if (sme -> crypto .n_akm_suites ) {
469- if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_8021X )
491+ if (sme -> crypto .akm_suites [0 ] == WLAN_AKM_SUITE_8021X ) {
492+ PRINT_INFO (vif -> ndev , CFG80211_DBG , "AUTH IEEE802.1X\n" );
470493 auth_type = WILC_FW_AUTH_IEEE8021 ;
494+ } else if (sme -> crypto .akm_suites [0 ] ==
495+ WLAN_AKM_SUITE_PSK_SHA256 ) {
496+ PRINT_INFO (vif -> ndev , CFG80211_DBG , "AUTH WPA-PSK-SHA256\n" );
497+ auth_type = WILC_FW_AUTH_OPEN_SYSTEM_SHA256 ;
498+ } else if (sme -> crypto .akm_suites [0 ] ==
499+ WLAN_AKM_SUITE_8021X_SHA256 ) {
500+ PRINT_INFO (vif -> ndev , CFG80211_DBG , "AUTH IEEE802.1X-SHA256\n" );
501+ auth_type = WILC_FW_AUTH_IEE8021X_SHA256 ;
502+ }
471503 }
472504
473505 if (wfi_drv -> usr_scan_req .scan_result ) {
@@ -494,6 +526,15 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
494526 ret = - EALREADY ;
495527 goto out_put_bss ;
496528 }
529+ PRINT_INFO (vif -> ndev , CFG80211_DBG , "Set MFP Type %d" , sme -> mfp );
530+
531+ if (sme -> mfp == NL80211_MFP_OPTIONAL ) {
532+ PRINT_INFO (vif -> ndev , CFG80211_DBG , "MFP Type Optional" );
533+ mfp_type = WILC_FW_MFP_OPTIONAL ;
534+ } else if (sme -> mfp == NL80211_MFP_REQUIRED ) {
535+ PRINT_INFO (vif -> ndev , CFG80211_DBG , "MFP Type Required" );
536+ mfp_type = WILC_FW_MFP_REQUIRED ;
537+ }
497538
498539 join_params = wilc_parse_join_bss_param (bss , & sme -> crypto );
499540 if (!join_params ) {
@@ -517,6 +558,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
517558 wfi_drv -> conn_info .conn_result = cfg_connect_result ;
518559 wfi_drv -> conn_info .arg = priv ;
519560 wfi_drv -> conn_info .param = join_params ;
561+ wfi_drv -> conn_info .mfp_type = mfp_type ;
520562
521563 ret = wilc_set_join_req (vif , bss -> bssid , sme -> ie , sme -> ie_len );
522564 if (ret ) {
@@ -594,6 +636,19 @@ static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
594636 return 0 ;
595637}
596638
639+ static int wilc_wfi_cfg_allocate_wpa_igtk_entry (struct wilc_priv * priv , u8 idx )
640+ {
641+ idx -= 4 ;
642+ if (!priv -> wilc_igtk [idx ]) {
643+ priv -> wilc_igtk [idx ] = kzalloc (sizeof (* priv -> wilc_igtk [idx ]),
644+ GFP_KERNEL );
645+ if (!priv -> wilc_igtk [idx ])
646+ return - ENOMEM ;
647+ }
648+
649+ return 0 ;
650+ }
651+
597652static int wilc_wfi_cfg_copy_wpa_info (struct wilc_wfi_key * key_info ,
598653 struct key_params * params )
599654{
@@ -623,13 +678,14 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
623678 bool pairwise , const u8 * mac_addr , struct key_params * params )
624679
625680{
626- int ret = 0 , keylen = params -> key_len ;
681+ int ret = 0 , keylen = params -> key_len , seqlen = params -> seq_len ;
627682 const u8 * rx_mic = NULL ;
628683 const u8 * tx_mic = NULL ;
629684 u8 mode = WILC_FW_SEC_NO ;
630685 u8 op_mode ;
631686 struct wilc_vif * vif = netdev_priv (netdev );
632687 struct wilc_priv * priv = & vif -> priv ;
688+ struct wilc_wfi_key * key ;
633689
634690 PRINT_INFO (vif -> ndev , CFG80211_DBG ,
635691 "Adding key with cipher suite = %x\n" , params -> cipher );
@@ -705,6 +761,28 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
705761
706762 break ;
707763
764+ case WLAN_CIPHER_SUITE_AES_CMAC :
765+ ret = wilc_wfi_cfg_allocate_wpa_igtk_entry (priv , key_index );
766+ if (ret )
767+ return - ENOMEM ;
768+
769+ key = priv -> wilc_igtk [key_index - 4 ];
770+
771+ ret = wilc_wfi_cfg_copy_wpa_info (key , params );
772+ if (ret )
773+ return - ENOMEM ;
774+
775+ if (priv -> wdev .iftype == NL80211_IFTYPE_AP ||
776+ priv -> wdev .iftype == NL80211_IFTYPE_P2P_GO )
777+ op_mode = WILC_AP_MODE ;
778+ else
779+ op_mode = WILC_STATION_MODE ;
780+
781+ ret = wilc_add_igtk (vif , params -> key , keylen , params -> seq ,
782+ seqlen , mac_addr , op_mode , key_index );
783+
784+ break ;
785+
708786 default :
709787 netdev_err (netdev , "%s: Unsupported cipher\n" , __func__ );
710788 ret = - ENOTSUPP ;
@@ -722,23 +800,34 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
722800 struct wilc_vif * vif = netdev_priv (netdev );
723801 struct wilc_priv * priv = & vif -> priv ;
724802
725- if (priv -> wilc_gtk [key_index ]) {
726- kfree (priv -> wilc_gtk [key_index ]-> key );
727- priv -> wilc_gtk [key_index ]-> key = NULL ;
728- kfree (priv -> wilc_gtk [key_index ]-> seq );
729- priv -> wilc_gtk [key_index ]-> seq = NULL ;
730-
731- kfree (priv -> wilc_gtk [key_index ]);
732- priv -> wilc_gtk [key_index ] = NULL ;
733- }
803+ if (!pairwise && (key_index == 4 || key_index == 5 )) {
804+ key_index -= 4 ;
805+ if (priv -> wilc_igtk [key_index ]) {
806+ kfree (priv -> wilc_igtk [key_index ]-> key );
807+ priv -> wilc_igtk [key_index ]-> key = NULL ;
808+ kfree (priv -> wilc_igtk [key_index ]-> seq );
809+ priv -> wilc_igtk [key_index ]-> seq = NULL ;
810+ kfree (priv -> wilc_igtk [key_index ]);
811+ priv -> wilc_igtk [key_index ] = NULL ;
812+ }
813+ } else {
814+ if (priv -> wilc_gtk [key_index ]) {
815+ kfree (priv -> wilc_gtk [key_index ]-> key );
816+ priv -> wilc_gtk [key_index ]-> key = NULL ;
817+ kfree (priv -> wilc_gtk [key_index ]-> seq );
818+ priv -> wilc_gtk [key_index ]-> seq = NULL ;
819+ kfree (priv -> wilc_gtk [key_index ]);
820+ priv -> wilc_gtk [key_index ] = NULL ;
821+ }
734822
735- if (priv -> wilc_ptk [key_index ]) {
736- kfree (priv -> wilc_ptk [key_index ]-> key );
737- priv -> wilc_ptk [key_index ]-> key = NULL ;
738- kfree (priv -> wilc_ptk [key_index ]-> seq );
739- priv -> wilc_ptk [key_index ]-> seq = NULL ;
740- kfree (priv -> wilc_ptk [key_index ]);
741- priv -> wilc_ptk [key_index ] = NULL ;
823+ if (priv -> wilc_ptk [key_index ]) {
824+ kfree (priv -> wilc_ptk [key_index ]-> key );
825+ priv -> wilc_ptk [key_index ]-> key = NULL ;
826+ kfree (priv -> wilc_ptk [key_index ]-> seq );
827+ priv -> wilc_ptk [key_index ]-> seq = NULL ;
828+ kfree (priv -> wilc_ptk [key_index ]);
829+ priv -> wilc_ptk [key_index ] = NULL ;
830+ }
742831 }
743832
744833 return ret ;
@@ -753,13 +842,25 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
753842 struct key_params key_params ;
754843
755844 if (!pairwise ) {
756- PRINT_INFO (vif -> ndev , CFG80211_DBG ,
757- "Getting group key idx: %x\n" , key_index );
758- key_params .key = priv -> wilc_gtk [key_index ]-> key ;
759- key_params .cipher = priv -> wilc_gtk [key_index ]-> cipher ;
760- key_params .key_len = priv -> wilc_gtk [key_index ]-> key_len ;
761- key_params .seq = priv -> wilc_gtk [key_index ]-> seq ;
762- key_params .seq_len = priv -> wilc_gtk [key_index ]-> seq_len ;
845+ if (key_index == 4 || key_index == 5 ) {
846+ PRINT_INFO (vif -> ndev , CFG80211_DBG ,
847+ "Getting integrity group key idx: %x\n" ,
848+ key_index );
849+ key_index -= 4 ;
850+ key_params .key = priv -> wilc_igtk [key_index ]-> key ;
851+ key_params .cipher = priv -> wilc_igtk [key_index ]-> cipher ;
852+ key_params .key_len = priv -> wilc_igtk [key_index ]-> key_len ;
853+ key_params .seq = priv -> wilc_igtk [key_index ]-> seq ;
854+ key_params .seq_len = priv -> wilc_igtk [key_index ]-> seq_len ;
855+ } else {
856+ PRINT_INFO (vif -> ndev , CFG80211_DBG ,
857+ "Getting group key idx: %x\n" , key_index );
858+ key_params .key = priv -> wilc_gtk [key_index ]-> key ;
859+ key_params .cipher = priv -> wilc_gtk [key_index ]-> cipher ;
860+ key_params .key_len = priv -> wilc_gtk [key_index ]-> key_len ;
861+ key_params .seq = priv -> wilc_gtk [key_index ]-> seq ;
862+ key_params .seq_len = priv -> wilc_gtk [key_index ]-> seq_len ;
863+ }
763864 } else {
764865 PRINT_INFO (vif -> ndev , CFG80211_DBG , "Getting pairwise key\n" );
765866 key_params .key = priv -> wilc_ptk [key_index ]-> key ;
@@ -1099,6 +1200,24 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
10991200 }
11001201}
11011202
1203+ bool wilc_wfi_mgmt_frame_rx (struct wilc_vif * vif , u8 * buff , u32 size )
1204+ {
1205+ struct wilc * wl = vif -> wilc ;
1206+ struct wilc_priv * priv = & vif -> priv ;
1207+ int freq , ret ;
1208+
1209+ #if KERNEL_VERSION (4 , 7 , 0 ) <= LINUX_VERSION_CODE
1210+ freq = ieee80211_channel_to_frequency (wl -> op_ch , NL80211_BAND_2GHZ );
1211+ #else
1212+ freq = ieee80211_channel_to_frequency (wl -> op_ch , IEEE80211_BAND_2GHZ );
1213+ #endif
1214+ PRINT_D (vif -> ndev , GENERIC_DBG , "%s Frame Type:%x\n" , __func__ ,
1215+ ((struct ieee80211_mgmt * )buff )-> frame_control );
1216+
1217+ ret = cfg80211_rx_mgmt (& priv -> wdev , freq , 0 , buff , size , 0 );
1218+ return ret ;
1219+ }
1220+
11021221bool wilc_wfi_p2p_rx (struct wilc_vif * vif , u8 * buff , u32 size )
11031222{
11041223 struct wilc * wl = vif -> wilc ;
@@ -1336,8 +1455,14 @@ static int mgmt_tx(struct wiphy *wiphy,
13361455 goto out_txq_add_pkt ;
13371456 }
13381457
1339- if (!ieee80211_is_public_action ((struct ieee80211_hdr * )buf , len ))
1458+ if (!ieee80211_is_public_action ((struct ieee80211_hdr * )buf , len )) {
1459+ if (chan )
1460+ wilc_set_mac_chnl_num (vif , chan -> hw_value );
1461+ else
1462+ wilc_set_mac_chnl_num (vif , vif -> wilc -> op_ch );
1463+
13401464 goto out_set_timeout ;
1465+ }
13411466
13421467 PRINT_INFO (vif -> ndev , GENERIC_DBG , "ACTION FRAME:%x\n" ,
13431468 (u16 )mgmt -> frame_control );
@@ -1424,6 +1549,7 @@ void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
14241549 struct wilc_vif * vif = netdev_priv (wdev -> netdev );
14251550 u32 presp_bit = BIT (IEEE80211_STYPE_PROBE_REQ >> 4 );
14261551 u32 action_bit = BIT (IEEE80211_STYPE_ACTION >> 4 );
1552+ u32 pauth_bit = BIT (IEEE80211_STYPE_AUTH >> 4 );
14271553
14281554 if (wl -> initialized ) {
14291555 bool prev = vif -> mgmt_reg_stypes & presp_bit ;
@@ -1437,10 +1563,16 @@ void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
14371563
14381564 if (now != prev )
14391565 wilc_frame_register (vif , IEEE80211_STYPE_ACTION , now );
1566+ prev = vif -> mgmt_reg_stypes & pauth_bit ;
1567+ now = upd -> interface_stypes & pauth_bit ;
1568+ if (now != prev ) {
1569+ pr_err ("%s setup authframe\n" , __func__ );
1570+ wilc_frame_register (vif , IEEE80211_STYPE_AUTH , now );
1571+ }
14401572 }
14411573
14421574 vif -> mgmt_reg_stypes =
1443- upd -> interface_stypes & (presp_bit | action_bit );
1575+ upd -> interface_stypes & (presp_bit | action_bit | pauth_bit );
14441576}
14451577#else
14461578void wilc_mgmt_frame_register (struct wiphy * wiphy , struct wireless_dev * wdev ,
@@ -1453,8 +1585,9 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
14531585 return ;
14541586
14551587 PRINT_D (vif -> ndev , GENERIC_DBG ,
1456- "Frame registering Frame Type: %x: Boolean: %d\n" ,
1457- frame_type , reg );
1588+ "Frame registering Frame Type: %x: Boolean: %d\n" , frame_type ,
1589+ reg );
1590+
14581591 switch (frame_type ) {
14591592 case IEEE80211_STYPE_PROBE_REQ :
14601593 vif -> frame_reg [0 ].type = frame_type ;
@@ -1465,6 +1598,10 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
14651598 vif -> frame_reg [1 ].type = frame_type ;
14661599 vif -> frame_reg [1 ].reg = reg ;
14671600 break ;
1601+ case IEEE80211_STYPE_AUTH :
1602+ vif -> frame_reg [2 ].type = frame_type ;
1603+ vif -> frame_reg [2 ].reg = reg ;
1604+ break ;
14681605
14691606 default :
14701607 break ;
@@ -2091,6 +2228,21 @@ static int set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
20912228 return ret ;
20922229}
20932230
2231+ static int external_auth (struct wiphy * wiphy , struct net_device * dev ,
2232+ struct cfg80211_external_auth_params * auth )
2233+ {
2234+ int ret = 0 ;
2235+ struct wilc_vif * vif = netdev_priv (dev );
2236+
2237+ pr_debug ("%s bssid: %pM" , __func__ , auth -> bssid );
2238+ if (auth -> status == WLAN_STATUS_SUCCESS )
2239+ wilc_set_external_auth_param (vif , auth );
2240+ else
2241+ pr_err ("%s failed [%d]\n" , __func__ , auth -> status );
2242+
2243+ return ret ;
2244+ }
2245+
20942246static const struct cfg80211_ops wilc_cfg80211_ops = {
20952247 .set_monitor_channel = set_channel ,
20962248 .scan = scan ,
@@ -2115,6 +2267,7 @@ static const struct cfg80211_ops wilc_cfg80211_ops = {
21152267 .change_bss = change_bss ,
21162268 .set_wiphy_params = set_wiphy_params ,
21172269
2270+ .external_auth = external_auth ,
21182271 .set_pmksa = set_pmksa ,
21192272 .del_pmksa = del_pmksa ,
21202273 .flush_pmksa = flush_pmksa ,
@@ -2292,6 +2445,7 @@ struct wilc *wilc_create_wiphy(struct device *dev)
22922445 BIT (NL80211_IFTYPE_P2P_GO ) |
22932446 BIT (NL80211_IFTYPE_P2P_CLIENT );
22942447 wiphy -> flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL ;
2448+ wiphy -> features |= NL80211_FEATURE_SAE ;
22952449 pr_info ("Max scan ids= %d,Max scan IE len= %d,Signal Type= %d,Interface Modes= %d\n" ,
22962450 wiphy -> max_scan_ssids , wiphy -> max_scan_ie_len ,
22972451 wiphy -> signal_type , wiphy -> interface_modes );
0 commit comments