@ -141,91 +141,143 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
return ret ;
}
/*
* This function fills bss descriptor structure using provided
* information .
*/
int mwifiex_fill_new_bss_desc ( struct mwifiex_private * priv ,
u8 * bssid , s32 rssi , u8 * ie_buf ,
size_t ie_len , u16 beacon_period ,
u16 cap_info_bitmap ,
struct mwifiex_bssdescriptor * bss_desc )
{
int ret ;
memcpy ( bss_desc - > mac_address , bssid , ETH_ALEN ) ;
bss_desc - > rssi = rssi ;
bss_desc - > beacon_buf = ie_buf ;
bss_desc - > beacon_buf_size = ie_len ;
bss_desc - > beacon_period = beacon_period ;
bss_desc - > cap_info_bitmap = cap_info_bitmap ;
if ( bss_desc - > cap_info_bitmap & WLAN_CAPABILITY_PRIVACY ) {
dev_dbg ( priv - > adapter - > dev , " info: InterpretIE: AP WEP enabled \n " ) ;
bss_desc - > privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP ;
} else {
bss_desc - > privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL ;
}
if ( bss_desc - > cap_info_bitmap & WLAN_CAPABILITY_IBSS )
bss_desc - > bss_mode = NL80211_IFTYPE_ADHOC ;
else
bss_desc - > bss_mode = NL80211_IFTYPE_STATION ;
ret = mwifiex_update_bss_desc_with_ie ( priv - > adapter , bss_desc ,
ie_buf , ie_len ) ;
return ret ;
}
/*
* In Ad - Hoc mode , the IBSS is created if not found in scan list .
* In both Ad - Hoc and infra mode , an deauthentication is performed
* first .
*/
int mwifiex_bss_start ( struct mwifiex_private * priv ,
struct mwifiex_ssid_bssid * ssid_bssid )
int mwifiex_bss_start ( struct mwifiex_private * priv , struct cfg80211_bss * bss ,
struct mwifiex_802_11_ssid * req_ ssid )
{
int ret ;
struct mwifiex_adapter * adapter = priv - > adapter ;
s32 i = - 1 ;
struct mwifiex_bssdescriptor * bss_desc = NULL ;
u8 * beacon_ie = NULL ;
priv - > scan_block = false ;
if ( ! ssid_bssid )
return - 1 ;
if ( bss ) {
/* Allocate and fill new bss descriptor */
bss_desc = kzalloc ( sizeof ( struct mwifiex_bssdescriptor ) ,
GFP_KERNEL ) ;
if ( ! bss_desc ) {
dev_err ( priv - > adapter - > dev , " failed to alloc bss_desc \n " ) ;
return - ENOMEM ;
}
beacon_ie = kzalloc ( bss - > len_beacon_ies , GFP_KERNEL ) ;
if ( ! beacon_ie ) {
dev_err ( priv - > adapter - > dev , " failed to alloc bss_desc \n " ) ;
return - ENOMEM ;
}
memcpy ( beacon_ie , bss - > information_elements ,
bss - > len_beacon_ies ) ;
ret = mwifiex_fill_new_bss_desc ( priv , bss - > bssid , bss - > signal ,
beacon_ie , bss - > len_beacon_ies ,
bss - > beacon_interval ,
bss - > capability , bss_desc ) ;
if ( ret )
goto done ;
}
if ( priv - > bss_mode = = NL80211_IFTYPE_STATION ) {
/* Infra mode */
ret = mwifiex_deauthenticate ( priv , NULL ) ;
if ( ret )
return ret ;
goto done ;
/* Search for the requested SSID in the scan table */
if ( ssid_bssid - > ssid . ssid_len )
i = mwifiex_find_ssid_in_list ( priv , & ssid_bssid - > ssid ,
NULL , NL80211_IFTYPE_STATION ) ;
else
i = mwifiex_find_bssid_in_list ( priv ,
( u8 * ) & ssid_bssid - > bssid ,
NL80211_IFTYPE_STATION ) ;
if ( i < 0 )
return - 1 ;
ret = mwifiex_check_network_compatibility ( priv , bss_desc ) ;
if ( ret )
goto done ;
dev_dbg ( adapter - > dev , " info: SSID found in scan list ... "
" associating... \n " ) ;
dev_dbg ( adapter - > dev ,
" info: SSID found in scan list ... associating... \n " ) ;
if ( ! netif_queue_stopped ( priv - > netdev ) )
netif_stop_queue ( priv - > netdev ) ;
/* Clear any past association response stored for
* application retrieval */
priv - > assoc_rsp_size = 0 ;
ret = mwifiex_associate ( priv , & adapter - > scan_table [ i ] ) ;
if ( ret )
return ret ;
ret = mwifiex_associate ( priv , bss_desc ) ;
if ( bss )
cfg80211_put_bss ( bss ) ;
} else {
/* Adhoc mode */
/* If the requested SSID matches current SSID, return */
if ( ssid_bssid - > ssid . ssid_len & &
if ( bss_desc & & bss_desc - > ssid . ssid_len & &
( ! mwifiex_ssid_cmp
( & priv - > curr_bss_params . bss_descriptor . ssid ,
& ssid_bssid - > ssid ) ) )
& bss_desc - > ssid ) ) ) {
kfree ( bss_desc ) ;
kfree ( beacon_ie ) ;
return 0 ;
}
/* Exit Adhoc mode first */
dev_dbg ( adapter - > dev , " info: Sending Adhoc Stop \n " ) ;
ret = mwifiex_deauthenticate ( priv , NULL ) ;
if ( ret )
return ret ;
goto done ;
priv - > adhoc_is_link_sensed = false ;
/* Search for the requested network in the scan table */
if ( ssid_bssid - > ssid . ssid_len )
i = mwifiex_find_ssid_in_list ( priv ,
& ssid_bssid - > ssid , NULL ,
NL80211_IFTYPE_ADHOC ) ;
else
i = mwifiex_find_bssid_in_list ( priv ,
( u8 * ) & ssid_bssid - > bssid ,
NL80211_IFTYPE_ADHOC ) ;
if ( i > = 0 ) {
ret = mwifiex_check_network_compatibility ( priv , bss_desc ) ;
if ( ! netif_queue_stopped ( priv - > netdev ) )
netif_stop_queue ( priv - > netdev ) ;
if ( ! ret ) {
dev_dbg ( adapter - > dev , " info: network found in scan "
" list. Joining... \n " ) ;
ret = mwifiex_adhoc_join ( priv , & adapter - > scan_table [ i ] ) ;
if ( ret )
return ret ;
ret = mwifiex_adhoc_join ( priv , bss_desc ) ;
if ( bss )
cfg80211_put_bss ( bss ) ;
} else {
dev_dbg ( adapter - > dev , " info: Network not found in "
" the list, creating adhoc with ssid = %s \n " ,
ssid_bssid - > ssid . ssid ) ;
ret = mwifiex_adhoc_start ( priv , & ssid_bssid - > ssid ) ;
if ( ret )
return ret ;
req_ssid - > ssid ) ;
ret = mwifiex_adhoc_start ( priv , req_ssid ) ;
}
}
done :
kfree ( bss_desc ) ;
kfree ( beacon_ie ) ;
return ret ;
}
@ -573,50 +625,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
action , 0 , channel ) ;
}
/*
* IOCTL request handler to find a particular BSS .
*
* The BSS can be searched with either a BSSID or a SSID . If none of
* these are provided , just the best BSS ( best RSSI ) is returned .
*/
int mwifiex_bss_ioctl_find_bss ( struct mwifiex_private * priv ,
struct mwifiex_ssid_bssid * ssid_bssid )
{
struct mwifiex_adapter * adapter = priv - > adapter ;
struct mwifiex_bssdescriptor * bss_desc ;
u8 zero_mac [ ETH_ALEN ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
u8 mac [ ETH_ALEN ] ;
int i = 0 ;
if ( memcmp ( ssid_bssid - > bssid , zero_mac , sizeof ( zero_mac ) ) ) {
i = mwifiex_find_bssid_in_list ( priv ,
( u8 * ) ssid_bssid - > bssid ,
priv - > bss_mode ) ;
if ( i < 0 ) {
memcpy ( mac , ssid_bssid - > bssid , sizeof ( mac ) ) ;
dev_err ( adapter - > dev , " cannot find bssid %pM \n " , mac ) ;
return - 1 ;
}
bss_desc = & adapter - > scan_table [ i ] ;
memcpy ( & ssid_bssid - > ssid , & bss_desc - > ssid ,
sizeof ( struct mwifiex_802_11_ssid ) ) ;
} else if ( ssid_bssid - > ssid . ssid_len ) {
i = mwifiex_find_ssid_in_list ( priv , & ssid_bssid - > ssid , NULL ,
priv - > bss_mode ) ;
if ( i < 0 ) {
dev_err ( adapter - > dev , " cannot find ssid %s \n " ,
ssid_bssid - > ssid . ssid ) ;
return - 1 ;
}
bss_desc = & adapter - > scan_table [ i ] ;
memcpy ( ssid_bssid - > bssid , bss_desc - > mac_address , ETH_ALEN ) ;
} else {
return mwifiex_find_best_network ( priv , ssid_bssid ) ;
}
return 0 ;
}
/*
* IOCTL request handler to change Ad - Hoc channel .
*
@ -641,6 +649,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
struct mwifiex_bss_info bss_info ;
struct mwifiex_ssid_bssid ssid_bssid ;
u16 curr_chan = 0 ;
struct cfg80211_bss * bss = NULL ;
struct ieee80211_channel * chan ;
memset ( & bss_info , 0 , sizeof ( bss_info ) ) ;
@ -676,12 +686,20 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
ret = - 1 ;
goto done ;
}
/* Start/Join Adhoc network */
memset ( & ssid_bssid , 0 , sizeof ( struct mwifiex_ssid_bssid ) ) ;
memcpy ( & ssid_bssid . ssid , & bss_info . ssid ,
sizeof ( struct mwifiex_802_11_ssid ) ) ;
ret = mwifiex_bss_start ( priv , & ssid_bssid ) ;
chan = __ieee80211_get_channel ( priv - > wdev - > wiphy ,
ieee80211_channel_to_frequency ( channel ,
priv - > curr_bss_params . band ) ) ;
/* Find the BSS we want using available scan results */
bss = cfg80211_get_bss ( priv - > wdev - > wiphy , chan , bss_info . bssid ,
bss_info . ssid . ssid , bss_info . ssid . ssid_len ,
WLAN_CAPABILITY_ESS , WLAN_CAPABILITY_ESS ) ;
if ( ! bss )
wiphy_warn ( priv - > wdev - > wiphy , " assoc: bss %pM not in scan results \n " ,
bss_info . bssid ) ;
ret = mwifiex_bss_start ( priv , bss , & bss_info . ssid ) ;
done :
return ret ;
}