@ -3089,52 +3089,11 @@ unlock:
sdata_unlock ( sdata ) ;
}
int ieee80211_channel_switch ( struct wiphy * wiphy , struct net_device * dev ,
struct cfg80211_csa_settings * params )
static int ieee80211_set_csa_beacon ( struct ieee80211_sub_if_data * sdata ,
struct cfg80211_csa_settings * params ,
u32 * changed )
{
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF ( dev ) ;
struct ieee80211_local * local = sdata - > local ;
struct ieee80211_chanctx_conf * chanctx_conf ;
struct ieee80211_chanctx * chanctx ;
struct ieee80211_if_mesh __maybe_unused * ifmsh ;
int err , num_chanctx , changed = 0 ;
sdata_assert_lock ( sdata ) ;
if ( ! list_empty ( & local - > roc_list ) | | local - > scanning )
return - EBUSY ;
if ( sdata - > wdev . cac_started )
return - EBUSY ;
if ( cfg80211_chandef_identical ( & params - > chandef ,
& sdata - > vif . bss_conf . chandef ) )
return - EINVAL ;
rcu_read_lock ( ) ;
chanctx_conf = rcu_dereference ( sdata - > vif . chanctx_conf ) ;
if ( ! chanctx_conf ) {
rcu_read_unlock ( ) ;
return - EBUSY ;
}
/* don't handle for multi-VIF cases */
chanctx = container_of ( chanctx_conf , struct ieee80211_chanctx , conf ) ;
if ( chanctx - > refcount > 1 ) {
rcu_read_unlock ( ) ;
return - EBUSY ;
}
num_chanctx = 0 ;
list_for_each_entry_rcu ( chanctx , & local - > chanctx_list , list )
num_chanctx + + ;
rcu_read_unlock ( ) ;
if ( num_chanctx > 1 )
return - EBUSY ;
/* don't allow another channel switch if one is already active. */
if ( sdata - > vif . csa_active )
return - EBUSY ;
int err ;
switch ( sdata - > vif . type ) {
case NL80211_IFTYPE_AP :
@ -3170,7 +3129,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
kfree ( sdata - > u . ap . next_beacon ) ;
return err ;
}
changed | = err ;
* changed | = err ;
break ;
case NL80211_IFTYPE_ADHOC :
@ -3204,15 +3163,15 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
err = ieee80211_ibss_csa_beacon ( sdata , params ) ;
if ( err < 0 )
return err ;
changed | = err ;
* changed | = err ;
}
ieee80211_send_action_csa ( sdata , params ) ;
break ;
# ifdef CONFIG_MAC80211_MESH
case NL80211_IFTYPE_MESH_POINT :
ifmsh = & sdata - > u . mesh ;
case NL80211_IFTYPE_MESH_POINT : {
struct ieee80211_if_mesh * ifmsh = & sdata - > u . mesh ;
if ( params - > chandef . width ! = sdata - > vif . bss_conf . chandef . width )
return - EINVAL ;
@ -3237,18 +3196,72 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
ifmsh - > csa_role = IEEE80211_MESH_CSA_ROLE_NONE ;
return err ;
}
changed | = err ;
* changed | = err ;
}
if ( ifmsh - > csa_role = = IEEE80211_MESH_CSA_ROLE_INIT )
ieee80211_send_action_csa ( sdata , params ) ;
break ;
}
# endif
default :
return - EOPNOTSUPP ;
}
return 0 ;
}
int ieee80211_channel_switch ( struct wiphy * wiphy , struct net_device * dev ,
struct cfg80211_csa_settings * params )
{
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF ( dev ) ;
struct ieee80211_local * local = sdata - > local ;
struct ieee80211_chanctx_conf * chanctx_conf ;
struct ieee80211_chanctx * chanctx ;
int err , num_chanctx , changed = 0 ;
sdata_assert_lock ( sdata ) ;
if ( ! list_empty ( & local - > roc_list ) | | local - > scanning )
return - EBUSY ;
if ( sdata - > wdev . cac_started )
return - EBUSY ;
if ( cfg80211_chandef_identical ( & params - > chandef ,
& sdata - > vif . bss_conf . chandef ) )
return - EINVAL ;
rcu_read_lock ( ) ;
chanctx_conf = rcu_dereference ( sdata - > vif . chanctx_conf ) ;
if ( ! chanctx_conf ) {
rcu_read_unlock ( ) ;
return - EBUSY ;
}
/* don't handle for multi-VIF cases */
chanctx = container_of ( chanctx_conf , struct ieee80211_chanctx , conf ) ;
if ( chanctx - > refcount > 1 ) {
rcu_read_unlock ( ) ;
return - EBUSY ;
}
num_chanctx = 0 ;
list_for_each_entry_rcu ( chanctx , & local - > chanctx_list , list )
num_chanctx + + ;
rcu_read_unlock ( ) ;
if ( num_chanctx > 1 )
return - EBUSY ;
/* don't allow another channel switch if one is already active. */
if ( sdata - > vif . csa_active )
return - EBUSY ;
err = ieee80211_set_csa_beacon ( sdata , params , & changed ) ;
if ( err )
return err ;
sdata - > csa_radar_required = params - > radar_required ;
if ( params - > block_tx )