@@ -3526,6 +3526,10 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
35263526 else
35273527 wakeup_data .net_detect = cfg -> wowl .nd_info ;
35283528 }
3529+ if (wakeind & BRCMF_WOWL_GTK_FAILURE ) {
3530+ brcmf_dbg (INFO , "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n" );
3531+ wakeup_data .gtk_rekey_failure = true;
3532+ }
35293533 } else {
35303534 wakeup = NULL ;
35313535 }
@@ -3607,6 +3611,8 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
36073611 brcmf_fweh_register (cfg -> pub , BRCMF_E_PFN_NET_FOUND ,
36083612 brcmf_wowl_nd_results );
36093613 }
3614+ if (wowl -> gtk_rekey_failure )
3615+ wowl_config |= BRCMF_WOWL_GTK_FAILURE ;
36103616 if (!test_bit (BRCMF_VIF_STATUS_CONNECTED , & ifp -> vif -> sme_state ))
36113617 wowl_config |= BRCMF_WOWL_UNASSOC ;
36123618
@@ -4874,7 +4880,32 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
48744880 return ret ;
48754881}
48764882
4877- static struct cfg80211_ops wl_cfg80211_ops = {
4883+ #ifdef CONFIG_PM
4884+ static int
4885+ brcmf_cfg80211_set_rekey_data (struct wiphy * wiphy , struct net_device * ndev ,
4886+ struct cfg80211_gtk_rekey_data * gtk )
4887+ {
4888+ struct brcmf_if * ifp = netdev_priv (ndev );
4889+ struct brcmf_gtk_keyinfo_le gtk_le ;
4890+ int ret ;
4891+
4892+ brcmf_dbg (TRACE , "Enter, bssidx=%d\n" , ifp -> bsscfgidx );
4893+
4894+ memcpy (gtk_le .kck , gtk -> kck , sizeof (gtk_le .kck ));
4895+ memcpy (gtk_le .kek , gtk -> kek , sizeof (gtk_le .kek ));
4896+ memcpy (gtk_le .replay_counter , gtk -> replay_ctr ,
4897+ sizeof (gtk_le .replay_counter ));
4898+
4899+ ret = brcmf_fil_iovar_data_set (ifp , "gtk_key_info" , & gtk_le ,
4900+ sizeof (gtk_le ));
4901+ if (ret < 0 )
4902+ brcmf_err ("gtk_key_info iovar failed: ret=%d\n" , ret );
4903+
4904+ return ret ;
4905+ }
4906+ #endif
4907+
4908+ static struct cfg80211_ops brcmf_cfg80211_ops = {
48784909 .add_virtual_intf = brcmf_cfg80211_add_iface ,
48794910 .del_virtual_intf = brcmf_cfg80211_del_iface ,
48804911 .change_virtual_intf = brcmf_cfg80211_change_iface ,
@@ -6139,19 +6170,18 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
61396170{
61406171#ifdef CONFIG_PM
61416172 struct brcmf_cfg80211_info * cfg = wiphy_to_cfg (wiphy );
6142- s32 err ;
6143- u32 wowl_cap ;
61446173
61456174 if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_PNO )) {
6146- err = brcmf_fil_iovar_int_get (ifp , "wowl_cap" , & wowl_cap );
6147- if (!err ) {
6148- if (wowl_cap & BRCMF_WOWL_PFN_FOUND ) {
6149- brcmf_wowlan_support .flags |=
6150- WIPHY_WOWLAN_NET_DETECT ;
6151- init_waitqueue_head (& cfg -> wowl .nd_data_wait );
6152- }
6175+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_WOWL_ND )) {
6176+ brcmf_wowlan_support .flags |= WIPHY_WOWLAN_NET_DETECT ;
6177+ init_waitqueue_head (& cfg -> wowl .nd_data_wait );
61536178 }
61546179 }
6180+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_WOWL_GTK )) {
6181+ brcmf_wowlan_support .flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY ;
6182+ brcmf_wowlan_support .flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE ;
6183+ }
6184+
61556185 wiphy -> wowlan = & brcmf_wowlan_support ;
61566186#endif
61576187}
@@ -6538,6 +6568,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
65386568 struct net_device * ndev = brcmf_get_ifp (drvr , 0 )-> ndev ;
65396569 struct brcmf_cfg80211_info * cfg ;
65406570 struct wiphy * wiphy ;
6571+ struct cfg80211_ops * ops ;
65416572 struct brcmf_cfg80211_vif * vif ;
65426573 struct brcmf_if * ifp ;
65436574 s32 err = 0 ;
@@ -6549,8 +6580,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
65496580 return NULL ;
65506581 }
65516582
6583+ ops = kzalloc (sizeof (* ops ), GFP_KERNEL );
6584+ if (!ops )
6585+ return NULL ;
6586+
6587+ memcpy (ops , & brcmf_cfg80211_ops , sizeof (* ops ));
65526588 ifp = netdev_priv (ndev );
6553- wiphy = wiphy_new (& wl_cfg80211_ops , sizeof (struct brcmf_cfg80211_info ));
6589+ #ifdef CONFIG_PM
6590+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_WOWL_GTK ))
6591+ ops -> set_rekey_data = brcmf_cfg80211_set_rekey_data ;
6592+ #endif
6593+ wiphy = wiphy_new (ops , sizeof (struct brcmf_cfg80211_info ));
65546594 if (!wiphy ) {
65556595 brcmf_err ("Could not allocate wiphy device\n" );
65566596 return NULL ;
@@ -6560,6 +6600,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
65606600
65616601 cfg = wiphy_priv (wiphy );
65626602 cfg -> wiphy = wiphy ;
6603+ cfg -> ops = ops ;
65636604 cfg -> pub = drvr ;
65646605 init_vif_event (& cfg -> vif_event );
65656606 INIT_LIST_HEAD (& cfg -> vif_list );
@@ -6686,6 +6727,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
66866727 ifp -> vif = NULL ;
66876728wiphy_out :
66886729 brcmf_free_wiphy (wiphy );
6730+ kfree (ops );
66896731 return NULL ;
66906732}
66916733
@@ -6696,6 +6738,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
66966738
66976739 brcmf_btcoex_detach (cfg );
66986740 wiphy_unregister (cfg -> wiphy );
6741+ kfree (cfg -> ops );
66996742 wl_deinit_priv (cfg );
67006743 brcmf_free_wiphy (cfg -> wiphy );
67016744}
0 commit comments