2011-03-21 18:00:50 -07:00
/*
* Marvell Wireless LAN device driver : association and ad - hoc start / join
*
2014-06-19 21:38:57 -07:00
* Copyright ( C ) 2011 - 2014 , Marvell International Ltd .
2011-03-21 18:00:50 -07:00
*
* This software file ( the " File " ) is distributed by Marvell International
* Ltd . under the terms of the GNU General Public License Version 2 , June 1991
* ( the " License " ) . You may use , redistribute and / or modify this File in
* accordance with the terms and conditions of the License , a copy of which
* is available by writing to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA or on the
* worldwide web at http : //www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* THE FILE IS DISTRIBUTED AS - IS , WITHOUT WARRANTY OF ANY KIND , AND THE
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
* ARE EXPRESSLY DISCLAIMED . The License provides additional details about
* this warranty disclaimer .
*/
# include "decl.h"
# include "ioctl.h"
# include "util.h"
# include "fw.h"
# include "main.h"
# include "wmm.h"
# include "11n.h"
2013-02-15 21:44:30 -08:00
# include "11ac.h"
2011-03-21 18:00:50 -07:00
# define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
/*
* Append a generic IE as a pass through TLV to a TLV buffer .
*
* This function is called from the network join command preparation routine .
*
* If the IE buffer has been setup by the application , this routine appends
* the buffer as a pass through TLV type to the request .
*/
static int
mwifiex_cmd_append_generic_ie ( struct mwifiex_private * priv , u8 * * buffer )
{
int ret_len = 0 ;
struct mwifiex_ie_types_header ie_header ;
/* Null Checks */
if ( ! buffer )
return 0 ;
if ( ! ( * buffer ) )
return 0 ;
/*
* If there is a generic ie buffer setup , append it to the return
* parameter buffer pointer .
*/
if ( priv - > gen_ie_buf_len ) {
2012-03-13 19:22:36 -07:00
dev_dbg ( priv - > adapter - > dev ,
" info: %s: append generic ie len %d to %p \n " ,
__func__ , priv - > gen_ie_buf_len , * buffer ) ;
2011-03-21 18:00:50 -07:00
/* Wrap the generic IE buffer with a pass through TLV type */
ie_header . type = cpu_to_le16 ( TLV_TYPE_PASSTHROUGH ) ;
ie_header . len = cpu_to_le16 ( priv - > gen_ie_buf_len ) ;
memcpy ( * buffer , & ie_header , sizeof ( ie_header ) ) ;
/* Increment the return size and the return buffer pointer
param */
* buffer + = sizeof ( ie_header ) ;
ret_len + = sizeof ( ie_header ) ;
/* Copy the generic IE buffer to the output buffer, advance
pointer */
memcpy ( * buffer , priv - > gen_ie_buf , priv - > gen_ie_buf_len ) ;
/* Increment the return size and the return buffer pointer
param */
* buffer + = priv - > gen_ie_buf_len ;
ret_len + = priv - > gen_ie_buf_len ;
/* Reset the generic IE buffer */
priv - > gen_ie_buf_len = 0 ;
}
/* return the length appended to the buffer */
return ret_len ;
}
/*
* Append TSF tracking info from the scan table for the target AP .
*
* This function is called from the network join command preparation routine .
*
* The TSF table TSF sent to the firmware contains two TSF values :
* - The TSF of the target AP from its previous beacon / probe response
* - The TSF timestamp of our local MAC at the time we observed the
* beacon / probe response .
*
* The firmware uses the timestamp values to set an initial TSF value
* in the MAC for the new association after a reassociation attempt .
*/
static int
mwifiex_cmd_append_tsf_tlv ( struct mwifiex_private * priv , u8 * * buffer ,
struct mwifiex_bssdescriptor * bss_desc )
{
struct mwifiex_ie_types_tsf_timestamp tsf_tlv ;
2011-05-02 11:00:45 -07:00
__le64 tsf_val ;
2011-03-21 18:00:50 -07:00
/* Null Checks */
if ( buffer = = NULL )
return 0 ;
if ( * buffer = = NULL )
return 0 ;
memset ( & tsf_tlv , 0x00 , sizeof ( struct mwifiex_ie_types_tsf_timestamp ) ) ;
tsf_tlv . header . type = cpu_to_le16 ( TLV_TYPE_TSFTIMESTAMP ) ;
tsf_tlv . header . len = cpu_to_le16 ( 2 * sizeof ( tsf_val ) ) ;
memcpy ( * buffer , & tsf_tlv , sizeof ( tsf_tlv . header ) ) ;
* buffer + = sizeof ( tsf_tlv . header ) ;
2011-05-02 11:00:45 -07:00
/* TSF at the time when beacon/probe_response was received */
2012-04-16 21:36:52 -07:00
tsf_val = cpu_to_le64 ( bss_desc - > fw_tsf ) ;
2011-05-02 11:00:45 -07:00
memcpy ( * buffer , & tsf_val , sizeof ( tsf_val ) ) ;
* buffer + = sizeof ( tsf_val ) ;
2012-04-16 21:36:52 -07:00
tsf_val = cpu_to_le64 ( bss_desc - > timestamp ) ;
2011-03-21 18:00:50 -07:00
2012-03-13 19:22:36 -07:00
dev_dbg ( priv - > adapter - > dev ,
" info: %s: TSF offset calc: %016llx - %016llx \n " ,
2012-04-16 21:36:52 -07:00
__func__ , bss_desc - > timestamp , bss_desc - > fw_tsf ) ;
2011-03-21 18:00:50 -07:00
memcpy ( * buffer , & tsf_val , sizeof ( tsf_val ) ) ;
* buffer + = sizeof ( tsf_val ) ;
return sizeof ( tsf_tlv . header ) + ( 2 * sizeof ( tsf_val ) ) ;
}
/*
* This function finds out the common rates between rate1 and rate2 .
*
* It will fill common rates in rate1 as output if found .
*
* NOTE : Setting the MSB of the basic rates needs to be taken
* care of , either before or after calling this function .
*/
static int mwifiex_get_common_rates ( struct mwifiex_private * priv , u8 * rate1 ,
u32 rate1_size , u8 * rate2 , u32 rate2_size )
{
2011-05-03 20:11:46 -07:00
int ret ;
u8 * ptr = rate1 , * tmp ;
2011-03-21 18:00:50 -07:00
u32 i , j ;
2011-08-29 13:21:10 -07:00
tmp = kmemdup ( rate1 , rate1_size , GFP_KERNEL ) ;
2011-03-21 18:00:50 -07:00
if ( ! tmp ) {
dev_err ( priv - > adapter - > dev , " failed to alloc tmp buf \n " ) ;
return - ENOMEM ;
}
memset ( rate1 , 0 , rate1_size ) ;
2013-01-27 23:42:48 +01:00
for ( i = 0 ; i < rate2_size & & rate2 [ i ] ; i + + ) {
for ( j = 0 ; j < rate1_size & & tmp [ j ] ; j + + ) {
2011-03-21 18:00:50 -07:00
/* Check common rate, excluding the bit for
basic rate */
if ( ( rate2 [ i ] & 0x7F ) = = ( tmp [ j ] & 0x7F ) ) {
* rate1 + + = tmp [ j ] ;
break ;
}
}
}
dev_dbg ( priv - > adapter - > dev , " info: Tx data rate set to %#x \n " ,
2012-03-13 19:22:36 -07:00
priv - > data_rate ) ;
2011-03-21 18:00:50 -07:00
if ( ! priv - > is_data_rate_auto ) {
while ( * ptr ) {
if ( ( * ptr & 0x7f ) = = priv - > data_rate ) {
ret = 0 ;
goto done ;
}
ptr + + ;
}
dev_err ( priv - > adapter - > dev , " previously set fixed data rate %#x "
" is not compatible with the network \n " ,
priv - > data_rate ) ;
ret = - 1 ;
goto done ;
}
ret = 0 ;
done :
kfree ( tmp ) ;
return ret ;
}
/*
* This function creates the intersection of the rates supported by a
* target BSS and our adapter settings for use in an assoc / join command .
*/
static int
mwifiex_setup_rates_from_bssdesc ( struct mwifiex_private * priv ,
struct mwifiex_bssdescriptor * bss_desc ,
u8 * out_rates , u32 * out_rates_size )
{
u8 card_rates [ MWIFIEX_SUPPORTED_RATES ] ;
2011-05-03 20:11:46 -07:00
u32 card_rates_size ;
2011-03-21 18:00:50 -07:00
/* Copy AP supported rates */
memcpy ( out_rates , bss_desc - > supported_rates , MWIFIEX_SUPPORTED_RATES ) ;
/* Get the STA supported rates */
card_rates_size = mwifiex_get_active_data_rates ( priv , card_rates ) ;
/* Get the common rates between AP and STA supported rates */
if ( mwifiex_get_common_rates ( priv , out_rates , MWIFIEX_SUPPORTED_RATES ,
card_rates , card_rates_size ) ) {
* out_rates_size = 0 ;
dev_err ( priv - > adapter - > dev , " %s: cannot get common rates \n " ,
2012-03-13 19:22:36 -07:00
__func__ ) ;
2011-03-21 18:00:50 -07:00
return - 1 ;
}
* out_rates_size =
min_t ( size_t , strlen ( out_rates ) , MWIFIEX_SUPPORTED_RATES ) ;
return 0 ;
}
2012-04-09 20:06:56 -07:00
/*
* This function appends a WPS IE . It is called from the network join command
* preparation routine .
*
* If the IE buffer has been setup by the application , this routine appends
* the buffer as a WPS TLV type to the request .
*/
static int
mwifiex_cmd_append_wps_ie ( struct mwifiex_private * priv , u8 * * buffer )
{
int retLen = 0 ;
struct mwifiex_ie_types_header ie_header ;
if ( ! buffer | | ! * buffer )
return 0 ;
/*
* If there is a wps ie buffer setup , append it to the return
* parameter buffer pointer .
*/
if ( priv - > wps_ie_len ) {
dev_dbg ( priv - > adapter - > dev , " cmd: append wps ie %d to %p \n " ,
priv - > wps_ie_len , * buffer ) ;
/* Wrap the generic IE buffer with a pass through TLV type */
ie_header . type = cpu_to_le16 ( TLV_TYPE_MGMT_IE ) ;
ie_header . len = cpu_to_le16 ( priv - > wps_ie_len ) ;
memcpy ( * buffer , & ie_header , sizeof ( ie_header ) ) ;
* buffer + = sizeof ( ie_header ) ;
retLen + = sizeof ( ie_header ) ;
memcpy ( * buffer , priv - > wps_ie , priv - > wps_ie_len ) ;
* buffer + = priv - > wps_ie_len ;
retLen + = priv - > wps_ie_len ;
}
kfree ( priv - > wps_ie ) ;
priv - > wps_ie_len = 0 ;
return retLen ;
}
2011-03-21 18:00:50 -07:00
/*
* This function appends a WAPI IE .
*
* This function is called from the network join command preparation routine .
*
* If the IE buffer has been setup by the application , this routine appends
* the buffer as a WAPI TLV type to the request .
*/
static int
mwifiex_cmd_append_wapi_ie ( struct mwifiex_private * priv , u8 * * buffer )
{
int retLen = 0 ;
struct mwifiex_ie_types_header ie_header ;
/* Null Checks */
if ( buffer = = NULL )
return 0 ;
if ( * buffer = = NULL )
return 0 ;
/*
* If there is a wapi ie buffer setup , append it to the return
* parameter buffer pointer .
*/
if ( priv - > wapi_ie_len ) {
dev_dbg ( priv - > adapter - > dev , " cmd: append wapi ie %d to %p \n " ,
2012-03-13 19:22:36 -07:00
priv - > wapi_ie_len , * buffer ) ;
2011-03-21 18:00:50 -07:00
/* Wrap the generic IE buffer with a pass through TLV type */
ie_header . type = cpu_to_le16 ( TLV_TYPE_WAPI_IE ) ;
ie_header . len = cpu_to_le16 ( priv - > wapi_ie_len ) ;
memcpy ( * buffer , & ie_header , sizeof ( ie_header ) ) ;
/* Increment the return size and the return buffer pointer
param */
* buffer + = sizeof ( ie_header ) ;
retLen + = sizeof ( ie_header ) ;
/* Copy the wapi IE buffer to the output buffer, advance
pointer */
memcpy ( * buffer , priv - > wapi_ie , priv - > wapi_ie_len ) ;
/* Increment the return size and the return buffer pointer
param */
* buffer + = priv - > wapi_ie_len ;
retLen + = priv - > wapi_ie_len ;
}
/* return the length appended to the buffer */
return retLen ;
}
/*
* This function appends rsn ie tlv for wpa / wpa2 security modes .
* It is called from the network join command preparation routine .
*/
static int mwifiex_append_rsn_ie_wpa_wpa2 ( struct mwifiex_private * priv ,
u8 * * buffer )
{
struct mwifiex_ie_types_rsn_param_set * rsn_ie_tlv ;
int rsn_ie_len ;
if ( ! buffer | | ! ( * buffer ) )
return 0 ;
rsn_ie_tlv = ( struct mwifiex_ie_types_rsn_param_set * ) ( * buffer ) ;
rsn_ie_tlv - > header . type = cpu_to_le16 ( ( u16 ) priv - > wpa_ie [ 0 ] ) ;
rsn_ie_tlv - > header . type = cpu_to_le16 (
le16_to_cpu ( rsn_ie_tlv - > header . type ) & 0x00FF ) ;
rsn_ie_tlv - > header . len = cpu_to_le16 ( ( u16 ) priv - > wpa_ie [ 1 ] ) ;
rsn_ie_tlv - > header . len = cpu_to_le16 ( le16_to_cpu ( rsn_ie_tlv - > header . len )
2012-03-13 19:22:36 -07:00
& 0x00FF ) ;
2011-03-21 18:00:50 -07:00
if ( le16_to_cpu ( rsn_ie_tlv - > header . len ) < = ( sizeof ( priv - > wpa_ie ) - 2 ) )
memcpy ( rsn_ie_tlv - > rsn_ie , & priv - > wpa_ie [ 2 ] ,
2012-03-13 19:22:36 -07:00
le16_to_cpu ( rsn_ie_tlv - > header . len ) ) ;
2011-03-21 18:00:50 -07:00
else
return - 1 ;
rsn_ie_len = sizeof ( rsn_ie_tlv - > header ) +
le16_to_cpu ( rsn_ie_tlv - > header . len ) ;
* buffer + = rsn_ie_len ;
return rsn_ie_len ;
}
/*
* This function prepares command for association .
*
* This sets the following parameters -
* - Peer MAC address
* - Listen interval
* - Beacon interval
* - Capability information
*
* . . . and the following TLVs , as required -
* - SSID TLV
* - PHY TLV
* - SS TLV
* - Rates TLV
* - Authentication TLV
* - Channel TLV
* - WPA / WPA2 IE
* - 11 n TLV
* - Vendor specific TLV
* - WMM TLV
* - WAPI IE
* - Generic IE
* - TSF TLV
*
* Preparation also includes -
* - Setting command ID and proper size
* - Ensuring correct endian - ness
*/
int mwifiex_cmd_802_11_associate ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
2011-06-20 15:21:48 -07:00
struct mwifiex_bssdescriptor * bss_desc )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_802_11_associate * assoc = & cmd - > params . associate ;
struct mwifiex_ie_types_ssid_param_set * ssid_tlv ;
struct mwifiex_ie_types_phy_param_set * phy_tlv ;
struct mwifiex_ie_types_ss_param_set * ss_tlv ;
struct mwifiex_ie_types_rates_param_set * rates_tlv ;
struct mwifiex_ie_types_auth_type * auth_tlv ;
struct mwifiex_ie_types_chan_list_param_set * chan_tlv ;
u8 rates [ MWIFIEX_SUPPORTED_RATES ] ;
u32 rates_size ;
u16 tmp_cap ;
u8 * pos ;
int rsn_ie_len = 0 ;
pos = ( u8 * ) assoc ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_ASSOCIATE ) ;
/* Save so we know which BSS Desc to use in the response handler */
priv - > attempted_bss_desc = bss_desc ;
memcpy ( assoc - > peer_sta_addr ,
bss_desc - > mac_address , sizeof ( assoc - > peer_sta_addr ) ) ;
pos + = sizeof ( assoc - > peer_sta_addr ) ;
/* Set the listen interval */
assoc - > listen_interval = cpu_to_le16 ( priv - > listen_interval ) ;
/* Set the beacon period */
assoc - > beacon_period = cpu_to_le16 ( bss_desc - > beacon_period ) ;
pos + = sizeof ( assoc - > cap_info_bitmap ) ;
pos + = sizeof ( assoc - > listen_interval ) ;
pos + = sizeof ( assoc - > beacon_period ) ;
pos + = sizeof ( assoc - > dtim_period ) ;
ssid_tlv = ( struct mwifiex_ie_types_ssid_param_set * ) pos ;
ssid_tlv - > header . type = cpu_to_le16 ( WLAN_EID_SSID ) ;
ssid_tlv - > header . len = cpu_to_le16 ( ( u16 ) bss_desc - > ssid . ssid_len ) ;
memcpy ( ssid_tlv - > ssid , bss_desc - > ssid . ssid ,
2012-03-13 19:22:36 -07:00
le16_to_cpu ( ssid_tlv - > header . len ) ) ;
2011-03-21 18:00:50 -07:00
pos + = sizeof ( ssid_tlv - > header ) + le16_to_cpu ( ssid_tlv - > header . len ) ;
phy_tlv = ( struct mwifiex_ie_types_phy_param_set * ) pos ;
phy_tlv - > header . type = cpu_to_le16 ( WLAN_EID_DS_PARAMS ) ;
phy_tlv - > header . len = cpu_to_le16 ( sizeof ( phy_tlv - > fh_ds . ds_param_set ) ) ;
memcpy ( & phy_tlv - > fh_ds . ds_param_set ,
& bss_desc - > phy_param_set . ds_param_set . current_chan ,
sizeof ( phy_tlv - > fh_ds . ds_param_set ) ) ;
pos + = sizeof ( phy_tlv - > header ) + le16_to_cpu ( phy_tlv - > header . len ) ;
ss_tlv = ( struct mwifiex_ie_types_ss_param_set * ) pos ;
ss_tlv - > header . type = cpu_to_le16 ( WLAN_EID_CF_PARAMS ) ;
ss_tlv - > header . len = cpu_to_le16 ( sizeof ( ss_tlv - > cf_ibss . cf_param_set ) ) ;
pos + = sizeof ( ss_tlv - > header ) + le16_to_cpu ( ss_tlv - > header . len ) ;
/* Get the common rates supported between the driver and the BSS Desc */
if ( mwifiex_setup_rates_from_bssdesc
( priv , bss_desc , rates , & rates_size ) )
return - 1 ;
/* Save the data rates into Current BSS state structure */
priv - > curr_bss_params . num_of_rates = rates_size ;
memcpy ( & priv - > curr_bss_params . data_rates , rates , rates_size ) ;
/* Setup the Rates TLV in the association command */
rates_tlv = ( struct mwifiex_ie_types_rates_param_set * ) pos ;
rates_tlv - > header . type = cpu_to_le16 ( WLAN_EID_SUPP_RATES ) ;
rates_tlv - > header . len = cpu_to_le16 ( ( u16 ) rates_size ) ;
memcpy ( rates_tlv - > rates , rates , rates_size ) ;
pos + = sizeof ( rates_tlv - > header ) + rates_size ;
dev_dbg ( priv - > adapter - > dev , " info: ASSOC_CMD: rates size = %d \n " ,
2012-03-13 19:22:36 -07:00
rates_size ) ;
2011-03-21 18:00:50 -07:00
2011-03-24 20:49:39 -07:00
/* Add the Authentication type to be used for Auth frames */
auth_tlv = ( struct mwifiex_ie_types_auth_type * ) pos ;
auth_tlv - > header . type = cpu_to_le16 ( TLV_TYPE_AUTH_TYPE ) ;
auth_tlv - > header . len = cpu_to_le16 ( sizeof ( auth_tlv - > auth_type ) ) ;
2012-02-24 21:36:04 -08:00
if ( priv - > sec_info . wep_enabled )
2011-03-24 20:49:39 -07:00
auth_tlv - > auth_type = cpu_to_le16 (
( u16 ) priv - > sec_info . authentication_mode ) ;
else
2011-03-28 17:55:42 -07:00
auth_tlv - > auth_type = cpu_to_le16 ( NL80211_AUTHTYPE_OPEN_SYSTEM ) ;
2011-03-24 20:49:39 -07:00
pos + = sizeof ( auth_tlv - > header ) + le16_to_cpu ( auth_tlv - > header . len ) ;
2011-03-21 18:00:50 -07:00
2012-03-13 19:22:36 -07:00
if ( IS_SUPPORT_MULTI_BANDS ( priv - > adapter ) & &
! ( ISSUPP_11NENABLED ( priv - > adapter - > fw_cap_info ) & &
( ! bss_desc - > disable_11n ) & &
( priv - > adapter - > config_bands & BAND_GN | |
priv - > adapter - > config_bands & BAND_AN ) & &
( bss_desc - > bcn_ht_cap )
2011-03-21 18:00:50 -07:00
)
) {
/* Append a channel TLV for the channel the attempted AP was
found on */
chan_tlv = ( struct mwifiex_ie_types_chan_list_param_set * ) pos ;
chan_tlv - > header . type = cpu_to_le16 ( TLV_TYPE_CHANLIST ) ;
chan_tlv - > header . len =
cpu_to_le16 ( sizeof ( struct mwifiex_chan_scan_param_set ) ) ;
memset ( chan_tlv - > chan_scan_param , 0x00 ,
sizeof ( struct mwifiex_chan_scan_param_set ) ) ;
chan_tlv - > chan_scan_param [ 0 ] . chan_number =
( bss_desc - > phy_param_set . ds_param_set . current_chan ) ;
dev_dbg ( priv - > adapter - > dev , " info: Assoc: TLV Chan = %d \n " ,
2012-03-13 19:22:36 -07:00
chan_tlv - > chan_scan_param [ 0 ] . chan_number ) ;
2011-03-21 18:00:50 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type =
mwifiex_band_to_radio_type ( ( u8 ) bss_desc - > bss_band ) ;
dev_dbg ( priv - > adapter - > dev , " info: Assoc: TLV Band = %d \n " ,
2012-03-13 19:22:36 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type ) ;
2011-03-21 18:00:50 -07:00
pos + = sizeof ( chan_tlv - > header ) +
sizeof ( struct mwifiex_chan_scan_param_set ) ;
}
if ( ! priv - > wps . session_enable ) {
if ( priv - > sec_info . wpa_enabled | | priv - > sec_info . wpa2_enabled )
rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2 ( priv , & pos ) ;
if ( rsn_ie_len = = - 1 )
return - 1 ;
}
2012-03-13 19:22:36 -07:00
if ( ISSUPP_11NENABLED ( priv - > adapter - > fw_cap_info ) & &
( ! bss_desc - > disable_11n ) & &
( priv - > adapter - > config_bands & BAND_GN | |
priv - > adapter - > config_bands & BAND_AN ) )
2011-03-21 18:00:50 -07:00
mwifiex_cmd_append_11n_tlv ( priv , bss_desc , & pos ) ;
2013-02-15 21:44:30 -08:00
if ( ISSUPP_11ACENABLED ( priv - > adapter - > fw_cap_info ) & &
! bss_desc - > disable_11n & & ! bss_desc - > disable_11ac & &
2014-02-07 16:21:01 -08:00
priv - > adapter - > config_bands & BAND_AAC )
2013-02-15 21:44:30 -08:00
mwifiex_cmd_append_11ac_tlv ( priv , bss_desc , & pos ) ;
2011-03-21 18:00:50 -07:00
/* Append vendor specific IE TLV */
mwifiex_cmd_append_vsie_tlv ( priv , MWIFIEX_VSIE_MASK_ASSOC , & pos ) ;
mwifiex_wmm_process_association_req ( priv , & pos , & bss_desc - > wmm_ie ,
bss_desc - > bcn_ht_cap ) ;
if ( priv - > sec_info . wapi_enabled & & priv - > wapi_ie_len )
mwifiex_cmd_append_wapi_ie ( priv , & pos ) ;
2012-04-09 20:06:56 -07:00
if ( priv - > wps . session_enable & & priv - > wps_ie_len )
mwifiex_cmd_append_wps_ie ( priv , & pos ) ;
2011-03-21 18:00:50 -07:00
mwifiex_cmd_append_generic_ie ( priv , & pos ) ;
mwifiex_cmd_append_tsf_tlv ( priv , & pos , bss_desc ) ;
2013-06-19 08:49:05 -07:00
mwifiex_11h_process_join ( priv , & pos , bss_desc ) ;
2011-03-21 18:00:50 -07:00
cmd - > size = cpu_to_le16 ( ( u16 ) ( pos - ( u8 * ) assoc ) + S_DS_GEN ) ;
/* Set the Capability info at last */
tmp_cap = bss_desc - > cap_info_bitmap ;
if ( priv - > adapter - > config_bands = = BAND_B )
2011-03-25 19:47:01 -07:00
tmp_cap & = ~ WLAN_CAPABILITY_SHORT_SLOT_TIME ;
2011-03-21 18:00:50 -07:00
tmp_cap & = CAPINFO_MASK ;
dev_dbg ( priv - > adapter - > dev , " info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX \n " ,
2012-03-13 19:22:36 -07:00
tmp_cap , CAPINFO_MASK ) ;
2011-03-21 18:00:50 -07:00
assoc - > cap_info_bitmap = cpu_to_le16 ( tmp_cap ) ;
return 0 ;
}
/*
* Association firmware command response handler
*
* The response buffer for the association command has the following
* memory layout .
*
* For cases where an association response was not received ( indicated
* by the CapInfo and AId field ) :
*
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | Header ( 4 * sizeof ( t_u16 ) ) : Standard command response hdr |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | cap_info / Error Return ( t_u16 ) : |
* | 0xFFFF ( - 1 ) : Internal error |
* | 0xFFFE ( - 2 ) : Authentication unhandled message |
* | 0xFFFD ( - 3 ) : Authentication refused |
* | 0xFFFC ( - 4 ) : Timeout waiting for AP response |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | status_code ( t_u16 ) : |
* | If cap_info is - 1 : |
* | An internal firmware failure prevented the |
* | command from being processed . The status_code |
* | will be set to 1. |
* | |
* | If cap_info is - 2 : |
* | An authentication frame was received but was |
* | not handled by the firmware . IEEE Status |
* | code for the failure is returned . |
* | |
* | If cap_info is - 3 : |
* | An authentication frame was received and the |
* | status_code is the IEEE Status reported in the |
* | response . |
* | |
* | If cap_info is - 4 : |
* | ( 1 ) Association response timeout |
* | ( 2 ) Authentication response timeout |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | a_id ( t_u16 ) : 0xFFFF |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
*
*
* For cases where an association response was received , the IEEE
* standard association response frame is returned :
*
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | Header ( 4 * sizeof ( t_u16 ) ) : Standard command response hdr |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | cap_info ( t_u16 ) : IEEE Capability |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | status_code ( t_u16 ) : IEEE Status Code |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | a_id ( t_u16 ) : IEEE Association ID |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
* | IEEE IEs ( variable ) : Any received IEs comprising the |
* | remaining portion of a received |
* | association response frame . |
* . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
*
* For simplistic handling , the status_code field can be used to determine
* an association success ( 0 ) or failure ( non - zero ) .
*/
int mwifiex_ret_802_11_associate ( struct mwifiex_private * priv ,
2011-04-13 17:27:06 -07:00
struct host_cmd_ds_command * resp )
2011-03-21 18:00:50 -07:00
{
2011-04-13 17:27:06 -07:00
struct mwifiex_adapter * adapter = priv - > adapter ;
2011-03-21 18:00:50 -07:00
int ret = 0 ;
struct ieee_types_assoc_rsp * assoc_rsp ;
struct mwifiex_bssdescriptor * bss_desc ;
2013-09-22 00:27:43 +02:00
bool enable_data = true ;
2013-01-17 17:41:57 -08:00
u16 cap_info , status_code ;
2011-03-21 18:00:50 -07:00
assoc_rsp = ( struct ieee_types_assoc_rsp * ) & resp - > params ;
2013-01-17 17:41:57 -08:00
cap_info = le16_to_cpu ( assoc_rsp - > cap_info_bitmap ) ;
status_code = le16_to_cpu ( assoc_rsp - > status_code ) ;
2011-03-21 18:00:50 -07:00
priv - > assoc_rsp_size = min ( le16_to_cpu ( resp - > size ) - S_DS_GEN ,
2012-03-13 19:22:36 -07:00
sizeof ( priv - > assoc_rsp_buf ) ) ;
2011-03-21 18:00:50 -07:00
memcpy ( priv - > assoc_rsp_buf , & resp - > params , priv - > assoc_rsp_size ) ;
2013-01-17 17:41:57 -08:00
if ( status_code ) {
2011-03-21 18:00:50 -07:00
priv - > adapter - > dbg . num_cmd_assoc_failure + + ;
2012-03-13 19:22:36 -07:00
dev_err ( priv - > adapter - > dev ,
" ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x \n " ,
2013-01-17 17:41:57 -08:00
status_code , cap_info , le16_to_cpu ( assoc_rsp - > a_id ) ) ;
if ( cap_info = = MWIFIEX_TIMEOUT_FOR_AP_RESP ) {
if ( status_code = = MWIFIEX_STATUS_CODE_AUTH_TIMEOUT )
ret = WLAN_STATUS_AUTH_TIMEOUT ;
else
ret = WLAN_STATUS_UNSPECIFIED_FAILURE ;
} else {
ret = status_code ;
}
2011-03-21 18:00:50 -07:00
goto done ;
}
/* Send a Media Connected event, according to the Spec */
priv - > media_connected = true ;
priv - > adapter - > ps_state = PS_STATE_AWAKE ;
priv - > adapter - > pps_uapsd_mode = false ;
priv - > adapter - > tx_lock_flag = false ;
/* Set the attempted BSSID Index to current */
bss_desc = priv - > attempted_bss_desc ;
dev_dbg ( priv - > adapter - > dev , " info: ASSOC_RESP: %s \n " ,
2012-03-13 19:22:36 -07:00
bss_desc - > ssid . ssid ) ;
2011-03-21 18:00:50 -07:00
/* Make a copy of current BSSID descriptor */
memcpy ( & priv - > curr_bss_params . bss_descriptor ,
bss_desc , sizeof ( struct mwifiex_bssdescriptor ) ) ;
/* Update curr_bss_params */
priv - > curr_bss_params . bss_descriptor . channel
= bss_desc - > phy_param_set . ds_param_set . current_chan ;
priv - > curr_bss_params . band = ( u8 ) bss_desc - > bss_band ;
if ( bss_desc - > wmm_ie . vend_hdr . element_id = = WLAN_EID_VENDOR_SPECIFIC )
priv - > curr_bss_params . wmm_enabled = true ;
else
priv - > curr_bss_params . wmm_enabled = false ;
2012-03-13 19:22:36 -07:00
if ( ( priv - > wmm_required | | bss_desc - > bcn_ht_cap ) & &
priv - > curr_bss_params . wmm_enabled )
2011-03-21 18:00:50 -07:00
priv - > wmm_enabled = true ;
else
priv - > wmm_enabled = false ;
priv - > curr_bss_params . wmm_uapsd_enabled = false ;
if ( priv - > wmm_enabled )
priv - > curr_bss_params . wmm_uapsd_enabled
= ( ( bss_desc - > wmm_ie . qos_info_bitmap &
IEEE80211_WMM_IE_AP_QOSINFO_UAPSD ) ? 1 : 0 ) ;
dev_dbg ( priv - > adapter - > dev , " info: ASSOC_RESP: curr_pkt_filter is %#x \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_pkt_filter ) ;
2011-03-21 18:00:50 -07:00
if ( priv - > sec_info . wpa_enabled | | priv - > sec_info . wpa2_enabled )
priv - > wpa_is_gtk_set = false ;
if ( priv - > wmm_enabled ) {
/* Don't re-enable carrier until we get the WMM_GET_STATUS
event */
enable_data = false ;
} else {
/* Since WMM is not enabled, setup the queues with the
defaults */
mwifiex_wmm_setup_queue_priorities ( priv , NULL ) ;
mwifiex_wmm_setup_ac_downgrade ( priv ) ;
}
if ( enable_data )
dev_dbg ( priv - > adapter - > dev ,
" info: post association, re-enabling data flow \n " ) ;
/* Reset SNR/NF/RSSI values */
priv - > data_rssi_last = 0 ;
priv - > data_nf_last = 0 ;
priv - > data_rssi_avg = 0 ;
priv - > data_nf_avg = 0 ;
priv - > bcn_rssi_last = 0 ;
priv - > bcn_nf_last = 0 ;
priv - > bcn_rssi_avg = 0 ;
priv - > bcn_nf_avg = 0 ;
priv - > rxpd_rate = 0 ;
priv - > rxpd_htinfo = 0 ;
mwifiex_save_curr_bcn ( priv ) ;
priv - > adapter - > dbg . num_cmd_assoc_success + + ;
dev_dbg ( priv - > adapter - > dev , " info: ASSOC_RESP: associated \n " ) ;
/* Add the ra_list here for infra mode as there will be only 1 ra
always */
mwifiex_ralist_add ( priv ,
priv - > curr_bss_params . bss_descriptor . mac_address ) ;
if ( ! netif_carrier_ok ( priv - > netdev ) )
netif_carrier_on ( priv - > netdev ) ;
2012-11-01 18:44:16 -07:00
mwifiex_wake_up_net_dev_queue ( priv - > netdev , adapter ) ;
2011-03-21 18:00:50 -07:00
if ( priv - > sec_info . wpa_enabled | | priv - > sec_info . wpa2_enabled )
priv - > scan_block = true ;
done :
/* Need to indicate IOCTL complete */
2011-04-13 17:27:06 -07:00
if ( adapter - > curr_cmd - > wait_q_enabled ) {
if ( ret )
adapter - > cmd_wait_q . status = - 1 ;
else
adapter - > cmd_wait_q . status = 0 ;
2011-03-21 18:00:50 -07:00
}
return ret ;
}
/*
* This function prepares command for ad - hoc start .
*
* Driver will fill up SSID , BSS mode , IBSS parameters , physical
* parameters , probe delay , and capability information . Firmware
* will fill up beacon period , basic rates and operational rates .
*
* In addition , the following TLVs are added -
* - Channel TLV
* - Vendor specific IE
* - WPA / WPA2 IE
* - HT Capabilities IE
* - HT Information IE
*
* Preparation also includes -
* - Setting command ID and proper size
* - Ensuring correct endian - ness
*/
int
mwifiex_cmd_802_11_ad_hoc_start ( struct mwifiex_private * priv ,
2011-06-20 15:21:48 -07:00
struct host_cmd_ds_command * cmd ,
2012-02-27 22:04:14 -08:00
struct cfg80211_ssid * req_ssid )
2011-03-21 18:00:50 -07:00
{
2011-04-15 20:50:40 -07:00
int rsn_ie_len = 0 ;
2011-03-21 18:00:50 -07:00
struct mwifiex_adapter * adapter = priv - > adapter ;
struct host_cmd_ds_802_11_ad_hoc_start * adhoc_start =
& cmd - > params . adhoc_start ;
struct mwifiex_bssdescriptor * bss_desc ;
u32 cmd_append_size = 0 ;
u32 i ;
u16 tmp_cap ;
struct mwifiex_ie_types_chan_list_param_set * chan_tlv ;
2011-11-07 21:41:07 -08:00
u8 radio_type ;
2011-03-21 18:00:50 -07:00
struct mwifiex_ie_types_htcap * ht_cap ;
struct mwifiex_ie_types_htinfo * ht_info ;
u8 * pos = ( u8 * ) adhoc_start +
sizeof ( struct host_cmd_ds_802_11_ad_hoc_start ) ;
if ( ! adapter )
return - 1 ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_AD_HOC_START ) ;
bss_desc = & priv - > curr_bss_params . bss_descriptor ;
priv - > attempted_bss_desc = bss_desc ;
/*
* Fill in the parameters for 2 data structures :
* 1. struct host_cmd_ds_802_11_ad_hoc_start command
* 2. bss_desc
* Driver will fill up SSID , bss_mode , IBSS param , Physical Param ,
* probe delay , and Cap info .
* Firmware will fill up beacon period , Basic rates
* and operational rates .
*/
memset ( adhoc_start - > ssid , 0 , IEEE80211_MAX_SSID_LEN ) ;
2011-06-20 15:21:48 -07:00
memcpy ( adhoc_start - > ssid , req_ssid - > ssid , req_ssid - > ssid_len ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: SSID = %s \n " ,
2012-03-13 19:22:36 -07:00
adhoc_start - > ssid ) ;
2011-03-21 18:00:50 -07:00
memset ( bss_desc - > ssid . ssid , 0 , IEEE80211_MAX_SSID_LEN ) ;
2011-06-20 15:21:48 -07:00
memcpy ( bss_desc - > ssid . ssid , req_ssid - > ssid , req_ssid - > ssid_len ) ;
2011-03-21 18:00:50 -07:00
2011-06-20 15:21:48 -07:00
bss_desc - > ssid . ssid_len = req_ssid - > ssid_len ;
2011-03-21 18:00:50 -07:00
/* Set the BSS mode */
adhoc_start - > bss_mode = HostCmd_BSS_MODE_IBSS ;
2011-03-28 17:55:41 -07:00
bss_desc - > bss_mode = NL80211_IFTYPE_ADHOC ;
2011-03-21 18:00:50 -07:00
adhoc_start - > beacon_period = cpu_to_le16 ( priv - > beacon_period ) ;
bss_desc - > beacon_period = priv - > beacon_period ;
/* Set Physical param set */
/* Parameter IE Id */
# define DS_PARA_IE_ID 3
/* Parameter IE length */
# define DS_PARA_IE_LEN 1
adhoc_start - > phy_param_set . ds_param_set . element_id = DS_PARA_IE_ID ;
adhoc_start - > phy_param_set . ds_param_set . len = DS_PARA_IE_LEN ;
2012-03-12 19:35:10 -07:00
if ( ! mwifiex_get_cfp ( priv , adapter - > adhoc_start_band ,
( u16 ) priv - > adhoc_channel , 0 ) ) {
2011-03-21 18:00:50 -07:00
struct mwifiex_chan_freq_power * cfp ;
2012-03-12 19:35:10 -07:00
cfp = mwifiex_get_cfp ( priv , adapter - > adhoc_start_band ,
FIRST_VALID_CHANNEL , 0 ) ;
2011-03-21 18:00:50 -07:00
if ( cfp )
priv - > adhoc_channel = ( u8 ) cfp - > channel ;
}
if ( ! priv - > adhoc_channel ) {
dev_err ( adapter - > dev , " ADHOC_S_CMD: adhoc_channel cannot be 0 \n " ) ;
return - 1 ;
}
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: creating ADHOC on channel %d \n " ,
2012-03-13 19:22:36 -07:00
priv - > adhoc_channel ) ;
2011-03-21 18:00:50 -07:00
priv - > curr_bss_params . bss_descriptor . channel = priv - > adhoc_channel ;
priv - > curr_bss_params . band = adapter - > adhoc_start_band ;
bss_desc - > channel = priv - > adhoc_channel ;
adhoc_start - > phy_param_set . ds_param_set . current_chan =
priv - > adhoc_channel ;
memcpy ( & bss_desc - > phy_param_set , & adhoc_start - > phy_param_set ,
sizeof ( union ieee_types_phy_param_set ) ) ;
/* Set IBSS param set */
/* IBSS parameter IE Id */
# define IBSS_PARA_IE_ID 6
/* IBSS parameter IE length */
# define IBSS_PARA_IE_LEN 2
adhoc_start - > ss_param_set . ibss_param_set . element_id = IBSS_PARA_IE_ID ;
adhoc_start - > ss_param_set . ibss_param_set . len = IBSS_PARA_IE_LEN ;
adhoc_start - > ss_param_set . ibss_param_set . atim_window
2012-03-13 19:22:36 -07:00
= cpu_to_le16 ( priv - > atim_window ) ;
2011-03-21 18:00:50 -07:00
memcpy ( & bss_desc - > ss_param_set , & adhoc_start - > ss_param_set ,
sizeof ( union ieee_types_ss_param_set ) ) ;
/* Set Capability info */
bss_desc - > cap_info_bitmap | = WLAN_CAPABILITY_IBSS ;
tmp_cap = le16_to_cpu ( adhoc_start - > cap_info_bitmap ) ;
tmp_cap & = ~ WLAN_CAPABILITY_ESS ;
tmp_cap | = WLAN_CAPABILITY_IBSS ;
/* Set up privacy in bss_desc */
2011-04-01 18:36:47 -07:00
if ( priv - > sec_info . encryption_mode ) {
2011-03-21 18:00:50 -07:00
/* Ad-Hoc capability privacy on */
dev_dbg ( adapter - > dev ,
" info: ADHOC_S_CMD: wep_status set privacy to WEP \n " ) ;
bss_desc - > privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP ;
tmp_cap | = WLAN_CAPABILITY_PRIVACY ;
} else {
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: wep_status NOT set, "
" setting privacy to ACCEPT ALL \n " ) ;
bss_desc - > privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL ;
}
2011-11-07 21:41:09 -08:00
memset ( adhoc_start - > data_rate , 0 , sizeof ( adhoc_start - > data_rate ) ) ;
mwifiex_get_active_data_rates ( priv , adhoc_start - > data_rate ) ;
2011-03-21 18:00:50 -07:00
if ( ( adapter - > adhoc_start_band & BAND_G ) & &
( priv - > curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON ) ) {
2014-02-27 19:35:12 -08:00
if ( mwifiex_send_cmd ( priv , HostCmd_CMD_MAC_CONTROL ,
HostCmd_ACT_GEN_SET , 0 ,
& priv - > curr_pkt_filter , false ) ) {
2011-03-21 18:00:50 -07:00
dev_err ( adapter - > dev ,
2012-03-13 19:22:36 -07:00
" ADHOC_S_CMD: G Protection config failed \n " ) ;
2011-03-21 18:00:50 -07:00
return - 1 ;
}
}
/* Find the last non zero */
2011-11-07 21:41:09 -08:00
for ( i = 0 ; i < sizeof ( adhoc_start - > data_rate ) ; i + + )
if ( ! adhoc_start - > data_rate [ i ] )
break ;
2011-03-21 18:00:50 -07:00
priv - > curr_bss_params . num_of_rates = i ;
/* Copy the ad-hoc creating rates into Current BSS rate structure */
memcpy ( & priv - > curr_bss_params . data_rates ,
2011-11-07 21:41:09 -08:00
& adhoc_start - > data_rate , priv - > curr_bss_params . num_of_rates ) ;
2011-03-21 18:00:50 -07:00
2013-05-29 13:04:20 +03:00
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: rates=%4ph \n " ,
adhoc_start - > data_rate ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: AD-HOC Start command is ready \n " ) ;
if ( IS_SUPPORT_MULTI_BANDS ( adapter ) ) {
/* Append a channel TLV */
chan_tlv = ( struct mwifiex_ie_types_chan_list_param_set * ) pos ;
chan_tlv - > header . type = cpu_to_le16 ( TLV_TYPE_CHANLIST ) ;
chan_tlv - > header . len =
cpu_to_le16 ( sizeof ( struct mwifiex_chan_scan_param_set ) ) ;
memset ( chan_tlv - > chan_scan_param , 0x00 ,
sizeof ( struct mwifiex_chan_scan_param_set ) ) ;
chan_tlv - > chan_scan_param [ 0 ] . chan_number =
( u8 ) priv - > curr_bss_params . bss_descriptor . channel ;
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: TLV Chan = %d \n " ,
2012-03-13 19:22:36 -07:00
chan_tlv - > chan_scan_param [ 0 ] . chan_number ) ;
2011-03-21 18:00:50 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type
= mwifiex_band_to_radio_type ( priv - > curr_bss_params . band ) ;
2012-03-13 19:22:36 -07:00
if ( adapter - > adhoc_start_band & BAND_GN | |
adapter - > adhoc_start_band & BAND_AN ) {
2011-12-20 23:47:21 -08:00
if ( adapter - > sec_chan_offset = =
IEEE80211_HT_PARAM_CHA_SEC_ABOVE )
2011-03-21 18:00:50 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type | =
2011-12-20 23:47:21 -08:00
( IEEE80211_HT_PARAM_CHA_SEC_ABOVE < < 4 ) ;
else if ( adapter - > sec_chan_offset = =
2014-07-11 20:54:32 -07:00
IEEE80211_HT_PARAM_CHA_SEC_BELOW )
2011-03-21 18:00:50 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type | =
2011-12-20 23:47:21 -08:00
( IEEE80211_HT_PARAM_CHA_SEC_BELOW < < 4 ) ;
2011-03-21 18:00:50 -07:00
}
dev_dbg ( adapter - > dev , " info: ADHOC_S_CMD: TLV Band = %d \n " ,
2012-03-13 19:22:36 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type ) ;
2011-03-21 18:00:50 -07:00
pos + = sizeof ( chan_tlv - > header ) +
sizeof ( struct mwifiex_chan_scan_param_set ) ;
cmd_append_size + =
sizeof ( chan_tlv - > header ) +
sizeof ( struct mwifiex_chan_scan_param_set ) ;
}
/* Append vendor specific IE TLV */
cmd_append_size + = mwifiex_cmd_append_vsie_tlv ( priv ,
MWIFIEX_VSIE_MASK_ADHOC , & pos ) ;
if ( priv - > sec_info . wpa_enabled ) {
rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2 ( priv , & pos ) ;
if ( rsn_ie_len = = - 1 )
return - 1 ;
cmd_append_size + = rsn_ie_len ;
}
if ( adapter - > adhoc_11n_enabled ) {
2011-11-07 21:41:07 -08:00
/* Fill HT CAPABILITY */
ht_cap = ( struct mwifiex_ie_types_htcap * ) pos ;
memset ( ht_cap , 0 , sizeof ( struct mwifiex_ie_types_htcap ) ) ;
ht_cap - > header . type = cpu_to_le16 ( WLAN_EID_HT_CAPABILITY ) ;
ht_cap - > header . len =
cpu_to_le16 ( sizeof ( struct ieee80211_ht_cap ) ) ;
radio_type = mwifiex_band_to_radio_type (
priv - > adapter - > config_bands ) ;
2014-02-07 16:27:31 -08:00
mwifiex_fill_cap_info ( priv , radio_type , & ht_cap - > ht_cap ) ;
2011-11-07 21:41:07 -08:00
2013-01-02 16:56:00 -08:00
if ( adapter - > sec_chan_offset = =
IEEE80211_HT_PARAM_CHA_SEC_NONE ) {
u16 tmp_ht_cap ;
tmp_ht_cap = le16_to_cpu ( ht_cap - > ht_cap . cap_info ) ;
tmp_ht_cap & = ~ IEEE80211_HT_CAP_SUP_WIDTH_20_40 ;
tmp_ht_cap & = ~ IEEE80211_HT_CAP_SGI_40 ;
ht_cap - > ht_cap . cap_info = cpu_to_le16 ( tmp_ht_cap ) ;
}
2011-11-07 21:41:07 -08:00
pos + = sizeof ( struct mwifiex_ie_types_htcap ) ;
2012-03-13 19:22:36 -07:00
cmd_append_size + = sizeof ( struct mwifiex_ie_types_htcap ) ;
2011-11-07 21:41:07 -08:00
/* Fill HT INFORMATION */
ht_info = ( struct mwifiex_ie_types_htinfo * ) pos ;
memset ( ht_info , 0 , sizeof ( struct mwifiex_ie_types_htinfo ) ) ;
2012-03-15 19:45:16 +01:00
ht_info - > header . type = cpu_to_le16 ( WLAN_EID_HT_OPERATION ) ;
2011-11-07 21:41:07 -08:00
ht_info - > header . len =
2012-03-15 19:45:16 +01:00
cpu_to_le16 ( sizeof ( struct ieee80211_ht_operation ) ) ;
2011-11-07 21:41:07 -08:00
2012-03-15 19:45:16 +01:00
ht_info - > ht_oper . primary_chan =
2011-11-07 21:41:07 -08:00
( u8 ) priv - > curr_bss_params . bss_descriptor . channel ;
2011-12-20 23:47:21 -08:00
if ( adapter - > sec_chan_offset ) {
2012-03-15 19:45:16 +01:00
ht_info - > ht_oper . ht_param = adapter - > sec_chan_offset ;
ht_info - > ht_oper . ht_param | =
2011-03-25 19:47:02 -07:00
IEEE80211_HT_PARAM_CHAN_WIDTH_ANY ;
2011-03-21 18:00:50 -07:00
}
2012-03-15 19:45:16 +01:00
ht_info - > ht_oper . operation_mode =
2011-11-07 21:41:07 -08:00
cpu_to_le16 ( IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT ) ;
2012-03-15 19:45:16 +01:00
ht_info - > ht_oper . basic_set [ 0 ] = 0xff ;
2011-11-07 21:41:07 -08:00
pos + = sizeof ( struct mwifiex_ie_types_htinfo ) ;
cmd_append_size + =
2012-03-13 19:22:36 -07:00
sizeof ( struct mwifiex_ie_types_htinfo ) ;
2011-03-21 18:00:50 -07:00
}
2012-03-13 19:22:36 -07:00
cmd - > size =
cpu_to_le16 ( ( u16 ) ( sizeof ( struct host_cmd_ds_802_11_ad_hoc_start )
+ S_DS_GEN + cmd_append_size ) ) ;
2011-03-21 18:00:50 -07:00
if ( adapter - > adhoc_start_band = = BAND_B )
2011-03-25 19:47:01 -07:00
tmp_cap & = ~ WLAN_CAPABILITY_SHORT_SLOT_TIME ;
2011-03-21 18:00:50 -07:00
else
2011-03-25 19:47:01 -07:00
tmp_cap | = WLAN_CAPABILITY_SHORT_SLOT_TIME ;
2011-03-21 18:00:50 -07:00
adhoc_start - > cap_info_bitmap = cpu_to_le16 ( tmp_cap ) ;
return 0 ;
}
/*
* This function prepares command for ad - hoc join .
*
* Most of the parameters are set up by copying from the target BSS descriptor
* from the scan response .
*
* In addition , the following TLVs are added -
* - Channel TLV
* - Vendor specific IE
* - WPA / WPA2 IE
* - 11 n IE
*
* Preparation also includes -
* - Setting command ID and proper size
* - Ensuring correct endian - ness
*/
int
mwifiex_cmd_802_11_ad_hoc_join ( struct mwifiex_private * priv ,
2011-06-20 15:21:48 -07:00
struct host_cmd_ds_command * cmd ,
struct mwifiex_bssdescriptor * bss_desc )
2011-03-21 18:00:50 -07:00
{
2011-04-15 20:50:40 -07:00
int rsn_ie_len = 0 ;
2011-03-21 18:00:50 -07:00
struct host_cmd_ds_802_11_ad_hoc_join * adhoc_join =
& cmd - > params . adhoc_join ;
struct mwifiex_ie_types_chan_list_param_set * chan_tlv ;
u32 cmd_append_size = 0 ;
u16 tmp_cap ;
u32 i , rates_size = 0 ;
u16 curr_pkt_filter ;
u8 * pos =
( u8 * ) adhoc_join +
sizeof ( struct host_cmd_ds_802_11_ad_hoc_join ) ;
/* Use G protection */
# define USE_G_PROTECTION 0x02
if ( bss_desc - > erp_flags & USE_G_PROTECTION ) {
curr_pkt_filter =
priv - >
curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON ;
2014-02-27 19:35:12 -08:00
if ( mwifiex_send_cmd ( priv , HostCmd_CMD_MAC_CONTROL ,
HostCmd_ACT_GEN_SET , 0 ,
& curr_pkt_filter , false ) ) {
2011-03-21 18:00:50 -07:00
dev_err ( priv - > adapter - > dev ,
2012-03-13 19:22:36 -07:00
" ADHOC_J_CMD: G Protection config failed \n " ) ;
2011-03-21 18:00:50 -07:00
return - 1 ;
}
}
priv - > attempted_bss_desc = bss_desc ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_AD_HOC_JOIN ) ;
adhoc_join - > bss_descriptor . bss_mode = HostCmd_BSS_MODE_IBSS ;
adhoc_join - > bss_descriptor . beacon_period
= cpu_to_le16 ( bss_desc - > beacon_period ) ;
memcpy ( & adhoc_join - > bss_descriptor . bssid ,
& bss_desc - > mac_address , ETH_ALEN ) ;
memcpy ( & adhoc_join - > bss_descriptor . ssid ,
& bss_desc - > ssid . ssid , bss_desc - > ssid . ssid_len ) ;
memcpy ( & adhoc_join - > bss_descriptor . phy_param_set ,
& bss_desc - > phy_param_set ,
sizeof ( union ieee_types_phy_param_set ) ) ;
memcpy ( & adhoc_join - > bss_descriptor . ss_param_set ,
& bss_desc - > ss_param_set , sizeof ( union ieee_types_ss_param_set ) ) ;
tmp_cap = bss_desc - > cap_info_bitmap ;
tmp_cap & = CAPINFO_MASK ;
2012-03-13 19:22:36 -07:00
dev_dbg ( priv - > adapter - > dev ,
" info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX \n " ,
tmp_cap , CAPINFO_MASK ) ;
2011-03-21 18:00:50 -07:00
/* Information on BSSID descriptor passed to FW */
2012-03-13 19:22:36 -07:00
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_J_CMD: BSSID=%pM, SSID='%s' \n " ,
adhoc_join - > bss_descriptor . bssid ,
adhoc_join - > bss_descriptor . ssid ) ;
2011-03-21 18:00:50 -07:00
2013-03-07 20:00:16 -08:00
for ( i = 0 ; i < MWIFIEX_SUPPORTED_RATES & &
bss_desc - > supported_rates [ i ] ; i + + )
;
2011-03-21 18:00:50 -07:00
rates_size = i ;
/* Copy Data Rates from the Rates recorded in scan response */
memset ( adhoc_join - > bss_descriptor . data_rates , 0 ,
sizeof ( adhoc_join - > bss_descriptor . data_rates ) ) ;
memcpy ( adhoc_join - > bss_descriptor . data_rates ,
bss_desc - > supported_rates , rates_size ) ;
/* Copy the adhoc join rates into Current BSS state structure */
priv - > curr_bss_params . num_of_rates = rates_size ;
memcpy ( & priv - > curr_bss_params . data_rates , bss_desc - > supported_rates ,
rates_size ) ;
/* Copy the channel information */
priv - > curr_bss_params . bss_descriptor . channel = bss_desc - > channel ;
priv - > curr_bss_params . band = ( u8 ) bss_desc - > bss_band ;
2012-02-24 21:36:04 -08:00
if ( priv - > sec_info . wep_enabled | | priv - > sec_info . wpa_enabled )
2011-03-21 18:00:50 -07:00
tmp_cap | = WLAN_CAPABILITY_PRIVACY ;
if ( IS_SUPPORT_MULTI_BANDS ( priv - > adapter ) ) {
/* Append a channel TLV */
chan_tlv = ( struct mwifiex_ie_types_chan_list_param_set * ) pos ;
chan_tlv - > header . type = cpu_to_le16 ( TLV_TYPE_CHANLIST ) ;
chan_tlv - > header . len =
cpu_to_le16 ( sizeof ( struct mwifiex_chan_scan_param_set ) ) ;
memset ( chan_tlv - > chan_scan_param , 0x00 ,
sizeof ( struct mwifiex_chan_scan_param_set ) ) ;
chan_tlv - > chan_scan_param [ 0 ] . chan_number =
( bss_desc - > phy_param_set . ds_param_set . current_chan ) ;
2012-03-13 19:22:36 -07:00
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_J_CMD: TLV Chan=%d \n " ,
chan_tlv - > chan_scan_param [ 0 ] . chan_number ) ;
2011-03-21 18:00:50 -07:00
chan_tlv - > chan_scan_param [ 0 ] . radio_type =
mwifiex_band_to_radio_type ( ( u8 ) bss_desc - > bss_band ) ;
2012-03-13 19:22:36 -07:00
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_J_CMD: TLV Band=%d \n " ,
chan_tlv - > chan_scan_param [ 0 ] . radio_type ) ;
2011-03-21 18:00:50 -07:00
pos + = sizeof ( chan_tlv - > header ) +
2012-03-13 19:22:36 -07:00
sizeof ( struct mwifiex_chan_scan_param_set ) ;
2011-03-21 18:00:50 -07:00
cmd_append_size + = sizeof ( chan_tlv - > header ) +
2012-03-13 19:22:36 -07:00
sizeof ( struct mwifiex_chan_scan_param_set ) ;
2011-03-21 18:00:50 -07:00
}
if ( priv - > sec_info . wpa_enabled )
rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2 ( priv , & pos ) ;
if ( rsn_ie_len = = - 1 )
return - 1 ;
cmd_append_size + = rsn_ie_len ;
if ( ISSUPP_11NENABLED ( priv - > adapter - > fw_cap_info ) )
cmd_append_size + = mwifiex_cmd_append_11n_tlv ( priv ,
bss_desc , & pos ) ;
/* Append vendor specific IE TLV */
cmd_append_size + = mwifiex_cmd_append_vsie_tlv ( priv ,
MWIFIEX_VSIE_MASK_ADHOC , & pos ) ;
2012-03-13 19:22:36 -07:00
cmd - > size = cpu_to_le16
( ( u16 ) ( sizeof ( struct host_cmd_ds_802_11_ad_hoc_join )
+ S_DS_GEN + cmd_append_size ) ) ;
2011-03-21 18:00:50 -07:00
adhoc_join - > bss_descriptor . cap_info_bitmap = cpu_to_le16 ( tmp_cap ) ;
2011-04-15 20:50:40 -07:00
return 0 ;
2011-03-21 18:00:50 -07:00
}
/*
* This function handles the command response of ad - hoc start and
* ad - hoc join .
*
* The function generates a device - connected event to notify
* the applications , in case of successful ad - hoc start / join , and
* saves the beacon buffer .
*/
int mwifiex_ret_802_11_ad_hoc ( struct mwifiex_private * priv ,
2011-04-13 17:27:06 -07:00
struct host_cmd_ds_command * resp )
2011-03-21 18:00:50 -07:00
{
int ret = 0 ;
2011-04-13 17:27:06 -07:00
struct mwifiex_adapter * adapter = priv - > adapter ;
2011-03-21 18:00:50 -07:00
struct host_cmd_ds_802_11_ad_hoc_result * adhoc_result ;
struct mwifiex_bssdescriptor * bss_desc ;
2012-10-05 20:21:43 -07:00
u16 reason_code ;
2011-03-21 18:00:50 -07:00
adhoc_result = & resp - > params . adhoc_result ;
bss_desc = priv - > attempted_bss_desc ;
/* Join result code 0 --> SUCCESS */
2012-10-05 20:21:43 -07:00
reason_code = le16_to_cpu ( resp - > result ) ;
if ( reason_code ) {
2011-03-21 18:00:50 -07:00
dev_err ( priv - > adapter - > dev , " ADHOC_RESP: failed \n " ) ;
if ( priv - > media_connected )
2012-10-05 20:21:43 -07:00
mwifiex_reset_connect_state ( priv , reason_code ) ;
2011-03-21 18:00:50 -07:00
memset ( & priv - > curr_bss_params . bss_descriptor ,
0x00 , sizeof ( struct mwifiex_bssdescriptor ) ) ;
ret = - 1 ;
goto done ;
}
/* Send a Media Connected event, according to the Spec */
priv - > media_connected = true ;
2011-04-15 20:50:40 -07:00
if ( le16_to_cpu ( resp - > command ) = = HostCmd_CMD_802_11_AD_HOC_START ) {
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_S_RESP %s \n " ,
2012-03-13 19:22:36 -07:00
bss_desc - > ssid . ssid ) ;
2011-03-21 18:00:50 -07:00
/* Update the created network descriptor with the new BSSID */
memcpy ( bss_desc - > mac_address ,
adhoc_result - > bssid , ETH_ALEN ) ;
priv - > adhoc_state = ADHOC_STARTED ;
} else {
/*
* Now the join cmd should be successful .
* If BSSID has changed use SSID to compare instead of BSSID
*/
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_J_RESP %s \n " ,
2012-03-13 19:22:36 -07:00
bss_desc - > ssid . ssid ) ;
2011-03-21 18:00:50 -07:00
/*
* Make a copy of current BSSID descriptor , only needed for
* join since the current descriptor is already being used
* for adhoc start
*/
memcpy ( & priv - > curr_bss_params . bss_descriptor ,
bss_desc , sizeof ( struct mwifiex_bssdescriptor ) ) ;
priv - > adhoc_state = ADHOC_JOINED ;
}
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_RESP: channel = %d \n " ,
2012-03-13 19:22:36 -07:00
priv - > adhoc_channel ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_RESP: BSSID = %pM \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . bss_descriptor . mac_address ) ;
2011-03-21 18:00:50 -07:00
if ( ! netif_carrier_ok ( priv - > netdev ) )
netif_carrier_on ( priv - > netdev ) ;
2012-11-01 18:44:16 -07:00
mwifiex_wake_up_net_dev_queue ( priv - > netdev , adapter ) ;
2011-03-21 18:00:50 -07:00
mwifiex_save_curr_bcn ( priv ) ;
done :
/* Need to indicate IOCTL complete */
2011-04-13 17:27:06 -07:00
if ( adapter - > curr_cmd - > wait_q_enabled ) {
2011-03-21 18:00:50 -07:00
if ( ret )
2011-04-13 17:27:06 -07:00
adapter - > cmd_wait_q . status = - 1 ;
2011-03-21 18:00:50 -07:00
else
2011-04-13 17:27:06 -07:00
adapter - > cmd_wait_q . status = 0 ;
2011-03-21 18:00:50 -07:00
}
return ret ;
}
/*
* This function associates to a specific BSS discovered in a scan .
*
* It clears any past association response stored for application
* retrieval and calls the command preparation routine to send the
* command to firmware .
*/
int mwifiex_associate ( struct mwifiex_private * priv ,
2011-04-13 17:27:06 -07:00
struct mwifiex_bssdescriptor * bss_desc )
2011-03-21 18:00:50 -07:00
{
2013-07-29 16:32:37 -07:00
/* Return error if the adapter is not STA role or table entry
* is not marked as infra .
*/
if ( ( GET_BSS_ROLE ( priv ) ! = MWIFIEX_BSS_ROLE_STA ) | |
2011-03-28 17:55:41 -07:00
( bss_desc - > bss_mode ! = NL80211_IFTYPE_STATION ) )
2011-03-21 18:00:50 -07:00
return - 1 ;
2013-03-27 19:10:32 -07:00
if ( ISSUPP_11ACENABLED ( priv - > adapter - > fw_cap_info ) & &
! bss_desc - > disable_11n & & ! bss_desc - > disable_11ac & &
2014-02-07 16:21:01 -08:00
priv - > adapter - > config_bands & BAND_AAC )
2013-03-27 19:10:32 -07:00
mwifiex_set_11ac_ba_params ( priv ) ;
else
mwifiex_set_ba_params ( priv ) ;
2011-03-21 18:00:50 -07:00
/* Clear any past association response stored for application
retrieval */
priv - > assoc_rsp_size = 0 ;
2014-02-27 19:35:12 -08:00
return mwifiex_send_cmd ( priv , HostCmd_CMD_802_11_ASSOCIATE ,
HostCmd_ACT_GEN_SET , 0 , bss_desc , true ) ;
2011-03-21 18:00:50 -07:00
}
/*
* This function starts an ad - hoc network .
*
* It calls the command preparation routine to send the command to firmware .
*/
int
mwifiex_adhoc_start ( struct mwifiex_private * priv ,
2012-02-27 22:04:14 -08:00
struct cfg80211_ssid * adhoc_ssid )
2011-03-21 18:00:50 -07:00
{
dev_dbg ( priv - > adapter - > dev , " info: Adhoc Channel = %d \n " ,
priv - > adhoc_channel ) ;
dev_dbg ( priv - > adapter - > dev , " info: curr_bss_params.channel = %d \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . bss_descriptor . channel ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: curr_bss_params.band = %d \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . band ) ;
2011-03-21 18:00:50 -07:00
2013-03-27 19:10:32 -07:00
if ( ISSUPP_11ACENABLED ( priv - > adapter - > fw_cap_info ) & &
2014-02-07 16:21:01 -08:00
priv - > adapter - > config_bands & BAND_AAC )
2013-03-27 19:10:32 -07:00
mwifiex_set_11ac_ba_params ( priv ) ;
else
mwifiex_set_ba_params ( priv ) ;
2014-02-27 19:35:12 -08:00
return mwifiex_send_cmd ( priv , HostCmd_CMD_802_11_AD_HOC_START ,
HostCmd_ACT_GEN_SET , 0 , adhoc_ssid , true ) ;
2011-03-21 18:00:50 -07:00
}
/*
* This function joins an ad - hoc network found in a previous scan .
*
* It calls the command preparation routine to send the command to firmware ,
* if already not connected to the requested SSID .
*/
int mwifiex_adhoc_join ( struct mwifiex_private * priv ,
2011-04-13 17:27:06 -07:00
struct mwifiex_bssdescriptor * bss_desc )
2011-03-21 18:00:50 -07:00
{
dev_dbg ( priv - > adapter - > dev , " info: adhoc join: curr_bss ssid =%s \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . bss_descriptor . ssid . ssid ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: adhoc join: curr_bss ssid_len =%u \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . bss_descriptor . ssid . ssid_len ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: adhoc join: ssid =%s \n " ,
bss_desc - > ssid . ssid ) ;
dev_dbg ( priv - > adapter - > dev , " info: adhoc join: ssid_len =%u \n " ,
2012-03-13 19:22:36 -07:00
bss_desc - > ssid . ssid_len ) ;
2011-03-21 18:00:50 -07:00
/* Check if the requested SSID is already joined */
if ( priv - > curr_bss_params . bss_descriptor . ssid . ssid_len & &
! mwifiex_ssid_cmp ( & bss_desc - > ssid ,
& priv - > curr_bss_params . bss_descriptor . ssid ) & &
( priv - > curr_bss_params . bss_descriptor . bss_mode = =
2011-03-28 17:55:41 -07:00
NL80211_IFTYPE_ADHOC ) ) {
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: ADHOC_J_CMD: new ad-hoc SSID "
" is the same as current; not attempting to re-join \n " ) ;
return - 1 ;
}
2013-03-27 19:10:32 -07:00
if ( ISSUPP_11ACENABLED ( priv - > adapter - > fw_cap_info ) & &
! bss_desc - > disable_11n & & ! bss_desc - > disable_11ac & &
2014-02-07 16:21:01 -08:00
priv - > adapter - > config_bands & BAND_AAC )
2013-03-27 19:10:32 -07:00
mwifiex_set_11ac_ba_params ( priv ) ;
else
mwifiex_set_ba_params ( priv ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: curr_bss_params.channel = %d \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . bss_descriptor . channel ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " info: curr_bss_params.band = %c \n " ,
2012-03-13 19:22:36 -07:00
priv - > curr_bss_params . band ) ;
2011-03-21 18:00:50 -07:00
2014-02-27 19:35:12 -08:00
return mwifiex_send_cmd ( priv , HostCmd_CMD_802_11_AD_HOC_JOIN ,
HostCmd_ACT_GEN_SET , 0 , bss_desc , true ) ;
2011-03-21 18:00:50 -07:00
}
/*
* This function deauthenticates / disconnects from infra network by sending
* deauthentication request .
*/
2011-04-13 17:27:06 -07:00
static int mwifiex_deauthenticate_infra ( struct mwifiex_private * priv , u8 * mac )
2011-03-21 18:00:50 -07:00
{
u8 mac_address [ ETH_ALEN ] ;
2011-05-03 20:11:46 -07:00
int ret ;
2011-03-21 18:00:50 -07:00
2012-06-04 12:44:17 +00:00
if ( ! mac | | is_zero_ether_addr ( mac ) )
memcpy ( mac_address ,
priv - > curr_bss_params . bss_descriptor . mac_address ,
ETH_ALEN ) ;
else
memcpy ( mac_address , mac , ETH_ALEN ) ;
2011-03-21 18:00:50 -07:00
2014-02-27 19:35:12 -08:00
ret = mwifiex_send_cmd ( priv , HostCmd_CMD_802_11_DEAUTHENTICATE ,
HostCmd_ACT_GEN_SET , 0 , mac_address , true ) ;
2011-03-21 18:00:50 -07:00
return ret ;
}
/*
* This function deauthenticates / disconnects from a BSS .
*
* In case of infra made , it sends deauthentication request , and
* in case of ad - hoc mode , a stop network request is sent to the firmware .
2012-05-08 18:30:21 -07:00
* In AP mode , a command to stop bss is sent to firmware .
2011-03-21 18:00:50 -07:00
*/
2011-04-13 17:27:06 -07:00
int mwifiex_deauthenticate ( struct mwifiex_private * priv , u8 * mac )
2011-03-21 18:00:50 -07:00
{
2013-10-11 18:31:31 -07:00
int ret = 0 ;
2012-05-01 19:53:51 -07:00
if ( ! priv - > media_connected )
return 0 ;
2011-03-21 18:00:50 -07:00
2012-05-01 19:53:51 -07:00
switch ( priv - > bss_mode ) {
case NL80211_IFTYPE_STATION :
2013-07-22 19:17:45 -07:00
case NL80211_IFTYPE_P2P_CLIENT :
2013-10-11 18:31:31 -07:00
ret = mwifiex_deauthenticate_infra ( priv , mac ) ;
if ( ret )
cfg80211_disconnected ( priv - > netdev , 0 , NULL , 0 ,
GFP_KERNEL ) ;
break ;
2012-05-01 19:53:51 -07:00
case NL80211_IFTYPE_ADHOC :
2014-02-27 19:35:12 -08:00
return mwifiex_send_cmd ( priv , HostCmd_CMD_802_11_AD_HOC_STOP ,
HostCmd_ACT_GEN_SET , 0 , NULL , true ) ;
2012-05-08 18:30:21 -07:00
case NL80211_IFTYPE_AP :
2014-02-27 19:35:12 -08:00
return mwifiex_send_cmd ( priv , HostCmd_CMD_UAP_BSS_STOP ,
HostCmd_ACT_GEN_SET , 0 , NULL , true ) ;
2012-05-01 19:53:51 -07:00
default :
break ;
2011-03-21 18:00:50 -07:00
}
2013-10-11 18:31:31 -07:00
return ret ;
2011-03-21 18:00:50 -07:00
}
2014-02-27 19:35:17 -08:00
/* This function deauthenticates/disconnects from all BSS. */
void mwifiex_deauthenticate_all ( struct mwifiex_adapter * adapter )
{
struct mwifiex_private * priv ;
int i ;
for ( i = 0 ; i < adapter - > priv_num ; i + + ) {
priv = adapter - > priv [ i ] ;
if ( priv )
mwifiex_deauthenticate ( priv , NULL ) ;
}
}
EXPORT_SYMBOL_GPL ( mwifiex_deauthenticate_all ) ;
2011-03-21 18:00:50 -07:00
/*
* This function converts band to radio type used in channel TLV .
*/
u8
mwifiex_band_to_radio_type ( u8 band )
{
switch ( band ) {
case BAND_A :
case BAND_AN :
case BAND_A | BAND_AN :
2013-02-15 21:44:30 -08:00
case BAND_A | BAND_AN | BAND_AAC :
2011-04-15 20:50:40 -07:00
return HostCmd_SCAN_RADIO_TYPE_A ;
2011-03-21 18:00:50 -07:00
case BAND_B :
case BAND_G :
case BAND_B | BAND_G :
default :
2011-04-15 20:50:40 -07:00
return HostCmd_SCAN_RADIO_TYPE_BG ;
2011-03-21 18:00:50 -07:00
}
}