2011-03-21 18:00:50 -07:00
/*
* Marvell Wireless LAN device driver : station command handling
*
* Copyright ( C ) 2011 , Marvell International Ltd .
*
* 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-03-18 20:06:03 -07:00
# include "11ac.h"
2011-03-21 18:00:50 -07:00
/*
* This function prepares command to set / get RSSI information .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting data / beacon average factors
* - Resetting SNR / NF / RSSI values in private structure
* - Ensuring correct endian - ness
*/
static int
mwifiex_cmd_802_11_rssi_info ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd , u16 cmd_action )
{
cmd - > command = cpu_to_le16 ( HostCmd_CMD_RSSI_INFO ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_rssi_info ) +
S_DS_GEN ) ;
cmd - > params . rssi_info . action = cpu_to_le16 ( cmd_action ) ;
cmd - > params . rssi_info . ndata = cpu_to_le16 ( priv - > data_avg_factor ) ;
cmd - > params . rssi_info . nbcn = cpu_to_le16 ( priv - > bcn_avg_factor ) ;
/* Reset SNR/NF/RSSI values in private structure */
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 ;
return 0 ;
}
/*
* This function prepares command to set MAC control .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Ensuring correct endian - ness
*/
static int mwifiex_cmd_mac_control ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
2011-06-20 15:21:48 -07:00
u16 cmd_action , u16 * action )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_mac_control * mac_ctrl = & cmd - > params . mac_ctrl ;
if ( cmd_action ! = HostCmd_ACT_GEN_SET ) {
dev_err ( priv - > adapter - > dev ,
" mac_control: only support set cmd \n " ) ;
return - 1 ;
}
cmd - > command = cpu_to_le16 ( HostCmd_CMD_MAC_CONTROL ) ;
cmd - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_mac_control ) + S_DS_GEN ) ;
2011-06-20 15:21:48 -07:00
mac_ctrl - > action = cpu_to_le16 ( * action ) ;
2011-03-21 18:00:50 -07:00
return 0 ;
}
/*
* This function prepares command to set / get SNMP MIB .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting SNMP MIB OID number and value
* ( as required )
* - Ensuring correct endian - ness
*
* The following SNMP MIB OIDs are supported -
* - FRAG_THRESH_I : Fragmentation threshold
* - RTS_THRESH_I : RTS threshold
* - SHORT_RETRY_LIM_I : Short retry limit
* - DOT11D_I : 11 d support
*/
static int mwifiex_cmd_802_11_snmp_mib ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action , u32 cmd_oid ,
2012-02-02 20:48:57 -08:00
u16 * ul_temp )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_802_11_snmp_mib * snmp_mib = & cmd - > params . smib ;
dev_dbg ( priv - > adapter - > dev , " cmd: SNMP_CMD: cmd_oid = 0x%x \n " , cmd_oid ) ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_SNMP_MIB ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_snmp_mib )
2012-03-13 19:22:40 -07:00
- 1 + S_DS_GEN ) ;
2011-03-21 18:00:50 -07:00
2012-02-02 20:48:57 -08:00
snmp_mib - > oid = cpu_to_le16 ( ( u16 ) cmd_oid ) ;
2011-03-21 18:00:50 -07:00
if ( cmd_action = = HostCmd_ACT_GEN_GET ) {
snmp_mib - > query_type = cpu_to_le16 ( HostCmd_ACT_GEN_GET ) ;
snmp_mib - > buf_size = cpu_to_le16 ( MAX_SNMP_BUF_SIZE ) ;
2012-02-02 20:48:57 -08:00
le16_add_cpu ( & cmd - > size , MAX_SNMP_BUF_SIZE ) ;
} else if ( cmd_action = = HostCmd_ACT_GEN_SET ) {
snmp_mib - > query_type = cpu_to_le16 ( HostCmd_ACT_GEN_SET ) ;
snmp_mib - > buf_size = cpu_to_le16 ( sizeof ( u16 ) ) ;
* ( ( __le16 * ) ( snmp_mib - > value ) ) = cpu_to_le16 ( * ul_temp ) ;
le16_add_cpu ( & cmd - > size , sizeof ( u16 ) ) ;
2011-03-21 18:00:50 -07:00
}
dev_dbg ( priv - > adapter - > dev ,
" cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x, "
" Value=0x%x \n " ,
2012-03-13 19:22:40 -07:00
cmd_action , cmd_oid , le16_to_cpu ( snmp_mib - > buf_size ) ,
le16_to_cpu ( * ( __le16 * ) snmp_mib - > value ) ) ;
2011-03-21 18:00:50 -07:00
return 0 ;
}
/*
* This function prepares command to get log .
*
* Preparation includes -
* - Setting command ID and proper size
* - Ensuring correct endian - ness
*/
static int
2011-04-13 17:27:08 -07:00
mwifiex_cmd_802_11_get_log ( struct host_cmd_ds_command * cmd )
2011-03-21 18:00:50 -07:00
{
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_GET_LOG ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_get_log ) +
S_DS_GEN ) ;
return 0 ;
}
/*
* This function prepares command to set / get Tx data rate configuration .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting configuration index , rate scope and rate drop pattern
* parameters ( as required )
* - Ensuring correct endian - ness
*/
static int mwifiex_cmd_tx_rate_cfg ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
2011-06-20 15:21:48 -07:00
u16 cmd_action , u16 * pbitmap_rates )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_tx_rate_cfg * rate_cfg = & cmd - > params . tx_rate_cfg ;
struct mwifiex_rate_scope * rate_scope ;
struct mwifiex_rate_drop_pattern * rate_drop ;
u32 i ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_TX_RATE_CFG ) ;
rate_cfg - > action = cpu_to_le16 ( cmd_action ) ;
rate_cfg - > cfg_index = 0 ;
rate_scope = ( struct mwifiex_rate_scope * ) ( ( u8 * ) rate_cfg +
sizeof ( struct host_cmd_ds_tx_rate_cfg ) ) ;
rate_scope - > type = cpu_to_le16 ( TLV_TYPE_RATE_SCOPE ) ;
2012-03-13 19:22:40 -07:00
rate_scope - > length = cpu_to_le16
( sizeof ( * rate_scope ) - sizeof ( struct mwifiex_ie_types_header ) ) ;
2011-03-21 18:00:50 -07:00
if ( pbitmap_rates ! = NULL ) {
rate_scope - > hr_dsss_rate_bitmap = cpu_to_le16 ( pbitmap_rates [ 0 ] ) ;
rate_scope - > ofdm_rate_bitmap = cpu_to_le16 ( pbitmap_rates [ 1 ] ) ;
for ( i = 0 ;
i < sizeof ( rate_scope - > ht_mcs_rate_bitmap ) / sizeof ( u16 ) ;
i + + )
rate_scope - > ht_mcs_rate_bitmap [ i ] =
cpu_to_le16 ( pbitmap_rates [ 2 + i ] ) ;
} else {
rate_scope - > hr_dsss_rate_bitmap =
cpu_to_le16 ( priv - > bitmap_rates [ 0 ] ) ;
rate_scope - > ofdm_rate_bitmap =
cpu_to_le16 ( priv - > bitmap_rates [ 1 ] ) ;
for ( i = 0 ;
i < sizeof ( rate_scope - > ht_mcs_rate_bitmap ) / sizeof ( u16 ) ;
i + + )
rate_scope - > ht_mcs_rate_bitmap [ i ] =
cpu_to_le16 ( priv - > bitmap_rates [ 2 + i ] ) ;
}
rate_drop = ( struct mwifiex_rate_drop_pattern * ) ( ( u8 * ) rate_scope +
2012-03-13 19:22:40 -07:00
sizeof ( struct mwifiex_rate_scope ) ) ;
2011-03-21 18:00:50 -07:00
rate_drop - > type = cpu_to_le16 ( TLV_TYPE_RATE_DROP_CONTROL ) ;
rate_drop - > length = cpu_to_le16 ( sizeof ( rate_drop - > rate_drop_mode ) ) ;
rate_drop - > rate_drop_mode = 0 ;
cmd - > size =
cpu_to_le16 ( S_DS_GEN + sizeof ( struct host_cmd_ds_tx_rate_cfg ) +
sizeof ( struct mwifiex_rate_scope ) +
sizeof ( struct mwifiex_rate_drop_pattern ) ) ;
return 0 ;
}
/*
* This function prepares command to set / get Tx power configuration .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting Tx power mode , power group TLV
* ( as required )
* - Ensuring correct endian - ness
*/
2011-04-13 17:27:08 -07:00
static int mwifiex_cmd_tx_power_cfg ( struct host_cmd_ds_command * cmd ,
2011-06-20 15:21:48 -07:00
u16 cmd_action ,
struct host_cmd_ds_txpwr_cfg * txp )
2011-03-21 18:00:50 -07:00
{
2011-05-03 20:11:46 -07:00
struct mwifiex_types_power_group * pg_tlv ;
2011-03-21 18:00:50 -07:00
struct host_cmd_ds_txpwr_cfg * cmd_txp_cfg = & cmd - > params . txp_cfg ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_TXPWR_CFG ) ;
cmd - > size =
cpu_to_le16 ( S_DS_GEN + sizeof ( struct host_cmd_ds_txpwr_cfg ) ) ;
switch ( cmd_action ) {
case HostCmd_ACT_GEN_SET :
if ( txp - > mode ) {
pg_tlv = ( struct mwifiex_types_power_group
2011-06-20 15:21:48 -07:00
* ) ( ( unsigned long ) txp +
2011-03-21 18:00:50 -07:00
sizeof ( struct host_cmd_ds_txpwr_cfg ) ) ;
2011-06-20 15:21:48 -07:00
memmove ( cmd_txp_cfg , txp ,
2011-03-21 18:00:50 -07:00
sizeof ( struct host_cmd_ds_txpwr_cfg ) +
sizeof ( struct mwifiex_types_power_group ) +
2013-10-22 15:24:43 -07:00
le16_to_cpu ( pg_tlv - > length ) ) ;
2011-03-21 18:00:50 -07:00
pg_tlv = ( struct mwifiex_types_power_group * ) ( ( u8 * )
cmd_txp_cfg +
sizeof ( struct host_cmd_ds_txpwr_cfg ) ) ;
cmd - > size = cpu_to_le16 ( le16_to_cpu ( cmd - > size ) +
sizeof ( struct mwifiex_types_power_group ) +
2013-10-22 15:24:43 -07:00
le16_to_cpu ( pg_tlv - > length ) ) ;
2011-03-21 18:00:50 -07:00
} else {
2011-06-20 15:21:48 -07:00
memmove ( cmd_txp_cfg , txp , sizeof ( * txp ) ) ;
2011-03-21 18:00:50 -07:00
}
cmd_txp_cfg - > action = cpu_to_le16 ( cmd_action ) ;
break ;
case HostCmd_ACT_GEN_GET :
cmd_txp_cfg - > action = cpu_to_le16 ( cmd_action ) ;
break ;
}
return 0 ;
}
2012-06-27 19:57:57 -07:00
/*
* This function prepares command to get RF Tx power .
*/
static int mwifiex_cmd_rf_tx_power ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action , void * data_buf )
{
struct host_cmd_ds_rf_tx_pwr * txp = & cmd - > params . txp ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_rf_tx_pwr )
+ S_DS_GEN ) ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_RF_TX_PWR ) ;
txp - > action = cpu_to_le16 ( cmd_action ) ;
return 0 ;
}
2012-07-02 19:32:33 -07:00
/*
* This function prepares command to set rf antenna .
*/
static int mwifiex_cmd_rf_antenna ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action ,
struct mwifiex_ds_ant_cfg * ant_cfg )
{
struct host_cmd_ds_rf_ant_mimo * ant_mimo = & cmd - > params . ant_mimo ;
struct host_cmd_ds_rf_ant_siso * ant_siso = & cmd - > params . ant_siso ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_RF_ANTENNA ) ;
if ( cmd_action ! = HostCmd_ACT_GEN_SET )
return 0 ;
if ( priv - > adapter - > hw_dev_mcs_support = = HT_STREAM_2X2 ) {
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_rf_ant_mimo ) +
S_DS_GEN ) ;
ant_mimo - > action_tx = cpu_to_le16 ( HostCmd_ACT_SET_TX ) ;
ant_mimo - > tx_ant_mode = cpu_to_le16 ( ( u16 ) ant_cfg - > tx_ant ) ;
ant_mimo - > action_rx = cpu_to_le16 ( HostCmd_ACT_SET_RX ) ;
ant_mimo - > rx_ant_mode = cpu_to_le16 ( ( u16 ) ant_cfg - > rx_ant ) ;
} else {
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_rf_ant_siso ) +
S_DS_GEN ) ;
ant_siso - > action = cpu_to_le16 ( HostCmd_ACT_SET_BOTH ) ;
ant_siso - > ant_mode = cpu_to_le16 ( ( u16 ) ant_cfg - > tx_ant ) ;
}
return 0 ;
}
2011-03-21 18:00:50 -07:00
/*
* This function prepares command to set Host Sleep configuration .
*
* Preparation includes -
* - Setting command ID and proper size
* - Setting Host Sleep action , conditions , ARP filters
* ( as required )
* - Ensuring correct endian - ness
*/
2011-06-20 15:21:48 -07:00
static int
mwifiex_cmd_802_11_hs_cfg ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action ,
struct mwifiex_hs_config_param * hscfg_param )
2011-03-21 18:00:50 -07:00
{
struct mwifiex_adapter * adapter = priv - > adapter ;
struct host_cmd_ds_802_11_hs_cfg_enh * hs_cfg = & cmd - > params . opt_hs_cfg ;
2013-09-22 00:27:43 +02:00
bool hs_activate = false ;
2011-03-21 18:00:50 -07:00
2011-06-20 15:21:48 -07:00
if ( ! hscfg_param )
2011-03-21 18:00:50 -07:00
/* New Activate command */
hs_activate = true ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_HS_CFG_ENH ) ;
if ( ! hs_activate & &
2013-03-04 16:27:57 -08:00
( hscfg_param - > conditions ! = cpu_to_le32 ( HS_CFG_CANCEL ) ) & &
2012-03-13 19:22:40 -07:00
( ( adapter - > arp_filter_size > 0 ) & &
( adapter - > arp_filter_size < = ARP_FILTER_MAX_BUF_SIZE ) ) ) {
2011-03-21 18:00:50 -07:00
dev_dbg ( adapter - > dev ,
" cmd: Attach %d bytes ArpFilter to HSCfg cmd \n " ,
2012-03-13 19:22:40 -07:00
adapter - > arp_filter_size ) ;
2011-03-21 18:00:50 -07:00
memcpy ( ( ( u8 * ) hs_cfg ) +
sizeof ( struct host_cmd_ds_802_11_hs_cfg_enh ) ,
adapter - > arp_filter , adapter - > arp_filter_size ) ;
2012-03-13 19:22:40 -07:00
cmd - > size = cpu_to_le16
( adapter - > arp_filter_size +
sizeof ( struct host_cmd_ds_802_11_hs_cfg_enh )
+ S_DS_GEN ) ;
2011-03-21 18:00:50 -07:00
} else {
cmd - > size = cpu_to_le16 ( S_DS_GEN + sizeof ( struct
2012-03-13 19:22:40 -07:00
host_cmd_ds_802_11_hs_cfg_enh ) ) ;
2011-03-21 18:00:50 -07:00
}
if ( hs_activate ) {
hs_cfg - > action = cpu_to_le16 ( HS_ACTIVATE ) ;
2013-12-02 23:17:48 -08:00
hs_cfg - > params . hs_activate . resp_ctrl = cpu_to_le16 ( RESP_NEEDED ) ;
2011-03-21 18:00:50 -07:00
} else {
hs_cfg - > action = cpu_to_le16 ( HS_CONFIGURE ) ;
2011-06-20 15:21:48 -07:00
hs_cfg - > params . hs_config . conditions = hscfg_param - > conditions ;
hs_cfg - > params . hs_config . gpio = hscfg_param - > gpio ;
hs_cfg - > params . hs_config . gap = hscfg_param - > gap ;
2011-03-21 18:00:50 -07:00
dev_dbg ( adapter - > dev ,
" cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x \n " ,
hs_cfg - > params . hs_config . conditions ,
hs_cfg - > params . hs_config . gpio ,
hs_cfg - > params . hs_config . gap ) ;
}
return 0 ;
}
/*
* This function prepares command to set / get MAC address .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting MAC address ( for SET only )
* - Ensuring correct endian - ness
*/
static int mwifiex_cmd_802_11_mac_address ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action )
{
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_MAC_ADDRESS ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_mac_address ) +
S_DS_GEN ) ;
cmd - > result = 0 ;
cmd - > params . mac_addr . action = cpu_to_le16 ( cmd_action ) ;
if ( cmd_action = = HostCmd_ACT_GEN_SET )
memcpy ( cmd - > params . mac_addr . mac_addr , priv - > curr_addr ,
ETH_ALEN ) ;
return 0 ;
}
/*
* This function prepares command to set MAC multicast address .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting MAC multicast address
* - Ensuring correct endian - ness
*/
2011-06-20 15:21:48 -07:00
static int
mwifiex_cmd_mac_multicast_adr ( struct host_cmd_ds_command * cmd ,
u16 cmd_action ,
struct mwifiex_multicast_list * mcast_list )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_mac_multicast_adr * mcast_addr = & cmd - > params . mc_addr ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_mac_multicast_adr ) +
S_DS_GEN ) ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_MAC_MULTICAST_ADR ) ;
mcast_addr - > action = cpu_to_le16 ( cmd_action ) ;
mcast_addr - > num_of_adrs =
cpu_to_le16 ( ( u16 ) mcast_list - > num_multicast_addr ) ;
memcpy ( mcast_addr - > mac_list , mcast_list - > mac_list ,
mcast_list - > num_multicast_addr * ETH_ALEN ) ;
return 0 ;
}
/*
* This function prepares command to deauthenticate .
*
* Preparation includes -
* - Setting command ID and proper size
* - Setting AP MAC address and reason code
* - Ensuring correct endian - ness
*/
static int mwifiex_cmd_802_11_deauthenticate ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
2011-06-20 15:21:48 -07:00
u8 * mac )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_802_11_deauthenticate * deauth = & cmd - > params . deauth ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_DEAUTHENTICATE ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_deauthenticate )
+ S_DS_GEN ) ;
/* Set AP MAC address */
2011-06-20 15:21:48 -07:00
memcpy ( deauth - > mac_addr , mac , ETH_ALEN ) ;
2011-03-21 18:00:50 -07:00
dev_dbg ( priv - > adapter - > dev , " cmd: Deauth: %pM \n " , deauth - > mac_addr ) ;
deauth - > reason_code = cpu_to_le16 ( WLAN_REASON_DEAUTH_LEAVING ) ;
return 0 ;
}
/*
* This function prepares command to stop Ad - Hoc network .
*
* Preparation includes -
* - Setting command ID and proper size
* - Ensuring correct endian - ness
*/
2011-04-13 17:27:08 -07:00
static int mwifiex_cmd_802_11_ad_hoc_stop ( struct host_cmd_ds_command * cmd )
2011-03-21 18:00:50 -07:00
{
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_AD_HOC_STOP ) ;
cmd - > size = cpu_to_le16 ( S_DS_GEN ) ;
return 0 ;
}
/*
* This function sets WEP key ( s ) to key parameter TLV ( s ) .
*
* Multi - key parameter TLVs are supported , so we can send multiple
* WEP keys in a single buffer .
*/
static int
mwifiex_set_keyparamset_wep ( struct mwifiex_private * priv ,
struct mwifiex_ie_type_key_param_set * key_param_set ,
u16 * key_param_len )
{
2011-05-03 20:11:46 -07:00
int cur_key_param_len ;
2011-03-21 18:00:50 -07:00
u8 i ;
/* Multi-key_param_set TLV is supported */
for ( i = 0 ; i < NUM_WEP_KEYS ; i + + ) {
if ( ( priv - > wep_key [ i ] . key_length = = WLAN_KEY_LEN_WEP40 ) | |
( priv - > wep_key [ i ] . key_length = = WLAN_KEY_LEN_WEP104 ) ) {
key_param_set - > type =
cpu_to_le16 ( TLV_TYPE_KEY_MATERIAL ) ;
/* Key_param_set WEP fixed length */
# define KEYPARAMSET_WEP_FIXED_LEN 8
key_param_set - > length = cpu_to_le16 ( ( u16 )
( priv - > wep_key [ i ] .
key_length +
KEYPARAMSET_WEP_FIXED_LEN ) ) ;
key_param_set - > key_type_id =
cpu_to_le16 ( KEY_TYPE_ID_WEP ) ;
key_param_set - > key_info =
2011-04-06 16:46:56 -07:00
cpu_to_le16 ( KEY_ENABLED | KEY_UNICAST |
KEY_MCAST ) ;
2011-03-21 18:00:50 -07:00
key_param_set - > key_len =
cpu_to_le16 ( priv - > wep_key [ i ] . key_length ) ;
/* Set WEP key index */
key_param_set - > key [ 0 ] = i ;
/* Set default Tx key flag */
if ( i = =
( priv - >
wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK ) )
key_param_set - > key [ 1 ] = 1 ;
else
key_param_set - > key [ 1 ] = 0 ;
memmove ( & key_param_set - > key [ 2 ] ,
priv - > wep_key [ i ] . key_material ,
priv - > wep_key [ i ] . key_length ) ;
cur_key_param_len = priv - > wep_key [ i ] . key_length +
KEYPARAMSET_WEP_FIXED_LEN +
sizeof ( struct mwifiex_ie_types_header ) ;
* key_param_len + = ( u16 ) cur_key_param_len ;
key_param_set =
( struct mwifiex_ie_type_key_param_set * )
( ( u8 * ) key_param_set +
2012-03-13 19:22:40 -07:00
cur_key_param_len ) ;
2011-03-21 18:00:50 -07:00
} else if ( ! priv - > wep_key [ i ] . key_length ) {
continue ;
} else {
dev_err ( priv - > adapter - > dev ,
" key%d Length = %d is incorrect \n " ,
( i + 1 ) , priv - > wep_key [ i ] . key_length ) ;
return - 1 ;
}
}
return 0 ;
}
/*
* This function prepares command to set / get / reset network key ( s ) .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting WEP keys , WAPI keys or WPA keys along with required
* encryption ( TKIP , AES ) ( as required )
* - Ensuring correct endian - ness
*/
2011-06-20 15:21:48 -07:00
static int
mwifiex_cmd_802_11_key_material ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action , u32 cmd_oid ,
struct mwifiex_ds_encrypt_key * enc_key )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_802_11_key_material * key_material =
& cmd - > params . key_material ;
2012-05-08 18:30:18 -07:00
struct host_cmd_tlv_mac_addr * tlv_mac ;
u16 key_param_len = 0 , cmd_size ;
2011-03-21 18:00:50 -07:00
int ret = 0 ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_KEY_MATERIAL ) ;
key_material - > action = cpu_to_le16 ( cmd_action ) ;
if ( cmd_action = = HostCmd_ACT_GEN_GET ) {
cmd - > size =
cpu_to_le16 ( sizeof ( key_material - > action ) + S_DS_GEN ) ;
return ret ;
}
if ( ! enc_key ) {
memset ( & key_material - > key_param_set , 0 ,
( NUM_WEP_KEYS *
sizeof ( struct mwifiex_ie_type_key_param_set ) ) ) ;
ret = mwifiex_set_keyparamset_wep ( priv ,
& key_material - > key_param_set ,
& key_param_len ) ;
cmd - > size = cpu_to_le16 ( key_param_len +
sizeof ( key_material - > action ) + S_DS_GEN ) ;
return ret ;
} else
memset ( & key_material - > key_param_set , 0 ,
sizeof ( struct mwifiex_ie_type_key_param_set ) ) ;
if ( enc_key - > is_wapi_key ) {
dev_dbg ( priv - > adapter - > dev , " info: Set WAPI Key \n " ) ;
key_material - > key_param_set . key_type_id =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_TYPE_ID_WAPI ) ;
2011-03-21 18:00:50 -07:00
if ( cmd_oid = = KEY_INFO_ENABLED )
key_material - > key_param_set . key_info =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_ENABLED ) ;
2011-03-21 18:00:50 -07:00
else
key_material - > key_param_set . key_info =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( ! KEY_ENABLED ) ;
2011-03-21 18:00:50 -07:00
key_material - > key_param_set . key [ 0 ] = enc_key - > key_index ;
if ( ! priv - > sec_info . wapi_key_on )
key_material - > key_param_set . key [ 1 ] = 1 ;
else
/* set 0 when re-key */
key_material - > key_param_set . key [ 1 ] = 0 ;
2012-08-24 13:25:30 +08:00
if ( ! is_broadcast_ether_addr ( enc_key - > mac_addr ) ) {
2011-03-21 18:00:50 -07:00
/* WAPI pairwise key: unicast */
key_material - > key_param_set . key_info | =
2011-04-06 16:46:56 -07:00
cpu_to_le16 ( KEY_UNICAST ) ;
2011-03-21 18:00:50 -07:00
} else { /* WAPI group key: multicast */
key_material - > key_param_set . key_info | =
2011-04-06 16:46:56 -07:00
cpu_to_le16 ( KEY_MCAST ) ;
2011-03-21 18:00:50 -07:00
priv - > sec_info . wapi_key_on = true ;
}
key_material - > key_param_set . type =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( TLV_TYPE_KEY_MATERIAL ) ;
2011-03-21 18:00:50 -07:00
key_material - > key_param_set . key_len =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( WAPI_KEY_LEN ) ;
2011-03-21 18:00:50 -07:00
memcpy ( & key_material - > key_param_set . key [ 2 ] ,
enc_key - > key_material , enc_key - > key_len ) ;
memcpy ( & key_material - > key_param_set . key [ 2 + enc_key - > key_len ] ,
2012-08-03 18:06:12 -07:00
enc_key - > pn , PN_LEN ) ;
2011-03-21 18:00:50 -07:00
key_material - > key_param_set . length =
cpu_to_le16 ( WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN ) ;
key_param_len = ( WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN ) +
sizeof ( struct mwifiex_ie_types_header ) ;
2012-03-13 19:22:40 -07:00
cmd - > size = cpu_to_le16 ( sizeof ( key_material - > action )
+ S_DS_GEN + key_param_len ) ;
2011-03-21 18:00:50 -07:00
return ret ;
}
if ( enc_key - > key_len = = WLAN_KEY_LEN_CCMP ) {
2012-08-03 18:06:14 -07:00
if ( enc_key - > is_igtk_key ) {
dev_dbg ( priv - > adapter - > dev , " cmd: CMAC_AES \n " ) ;
key_material - > key_param_set . key_type_id =
cpu_to_le16 ( KEY_TYPE_ID_AES_CMAC ) ;
if ( cmd_oid = = KEY_INFO_ENABLED )
key_material - > key_param_set . key_info =
cpu_to_le16 ( KEY_ENABLED ) ;
else
key_material - > key_param_set . key_info =
cpu_to_le16 ( ! KEY_ENABLED ) ;
key_material - > key_param_set . key_info | =
cpu_to_le16 ( KEY_IGTK ) ;
} else {
dev_dbg ( priv - > adapter - > dev , " cmd: WPA_AES \n " ) ;
key_material - > key_param_set . key_type_id =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_TYPE_ID_AES ) ;
2012-08-03 18:06:14 -07:00
if ( cmd_oid = = KEY_INFO_ENABLED )
key_material - > key_param_set . key_info =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_ENABLED ) ;
2012-08-03 18:06:14 -07:00
else
key_material - > key_param_set . key_info =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( ! KEY_ENABLED ) ;
2011-03-21 18:00:50 -07:00
2012-08-03 18:06:14 -07:00
if ( enc_key - > key_index & MWIFIEX_KEY_INDEX_UNICAST )
2011-03-21 18:00:50 -07:00
/* AES pairwise key: unicast */
2012-08-03 18:06:14 -07:00
key_material - > key_param_set . key_info | =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_UNICAST ) ;
2012-08-03 18:06:14 -07:00
else /* AES group key: multicast */
key_material - > key_param_set . key_info | =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_MCAST ) ;
2012-08-03 18:06:14 -07:00
}
2011-03-21 18:00:50 -07:00
} else if ( enc_key - > key_len = = WLAN_KEY_LEN_TKIP ) {
dev_dbg ( priv - > adapter - > dev , " cmd: WPA_TKIP \n " ) ;
key_material - > key_param_set . key_type_id =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_TYPE_ID_TKIP ) ;
2011-03-21 18:00:50 -07:00
key_material - > key_param_set . key_info =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_ENABLED ) ;
2011-03-21 18:00:50 -07:00
if ( enc_key - > key_index & MWIFIEX_KEY_INDEX_UNICAST )
/* TKIP pairwise key: unicast */
key_material - > key_param_set . key_info | =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_UNICAST ) ;
2011-03-21 18:00:50 -07:00
else /* TKIP group key: multicast */
key_material - > key_param_set . key_info | =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( KEY_MCAST ) ;
2011-03-21 18:00:50 -07:00
}
if ( key_material - > key_param_set . key_type_id ) {
key_material - > key_param_set . type =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( TLV_TYPE_KEY_MATERIAL ) ;
2011-03-21 18:00:50 -07:00
key_material - > key_param_set . key_len =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( ( u16 ) enc_key - > key_len ) ;
2011-03-21 18:00:50 -07:00
memcpy ( key_material - > key_param_set . key , enc_key - > key_material ,
enc_key - > key_len ) ;
key_material - > key_param_set . length =
cpu_to_le16 ( ( u16 ) enc_key - > key_len +
KEYPARAMSET_FIXED_LEN ) ;
2012-05-08 18:30:18 -07:00
key_param_len = ( u16 ) ( enc_key - > key_len + KEYPARAMSET_FIXED_LEN )
2012-03-13 19:22:40 -07:00
+ sizeof ( struct mwifiex_ie_types_header ) ;
2011-03-21 18:00:50 -07:00
2012-08-03 18:06:14 -07:00
if ( le16_to_cpu ( key_material - > key_param_set . key_type_id ) = =
KEY_TYPE_ID_AES_CMAC ) {
struct mwifiex_cmac_param * param =
( void * ) key_material - > key_param_set . key ;
memcpy ( param - > ipn , enc_key - > pn , IGTK_PN_LEN ) ;
memcpy ( param - > key , enc_key - > key_material ,
2012-08-08 19:01:52 -07:00
WLAN_KEY_LEN_AES_CMAC ) ;
2012-08-03 18:06:14 -07:00
key_param_len = sizeof ( struct mwifiex_cmac_param ) ;
key_material - > key_param_set . key_len =
cpu_to_le16 ( key_param_len ) ;
key_param_len + = KEYPARAMSET_FIXED_LEN ;
key_material - > key_param_set . length =
cpu_to_le16 ( key_param_len ) ;
key_param_len + = sizeof ( struct mwifiex_ie_types_header ) ;
}
2012-03-13 19:22:40 -07:00
cmd - > size = cpu_to_le16 ( sizeof ( key_material - > action ) + S_DS_GEN
+ key_param_len ) ;
2012-05-08 18:30:18 -07:00
if ( priv - > bss_type = = MWIFIEX_BSS_TYPE_UAP ) {
tlv_mac = ( void * ) ( ( u8 * ) & key_material - > key_param_set +
key_param_len ) ;
2013-07-22 19:17:57 -07:00
tlv_mac - > header . type =
cpu_to_le16 ( TLV_TYPE_STA_MAC_ADDR ) ;
tlv_mac - > header . len = cpu_to_le16 ( ETH_ALEN ) ;
2012-05-08 18:30:18 -07:00
memcpy ( tlv_mac - > mac_addr , enc_key - > mac_addr , ETH_ALEN ) ;
cmd_size = key_param_len + S_DS_GEN +
sizeof ( key_material - > action ) +
sizeof ( struct host_cmd_tlv_mac_addr ) ;
} else {
cmd_size = key_param_len + S_DS_GEN +
sizeof ( key_material - > action ) ;
}
cmd - > size = cpu_to_le16 ( cmd_size ) ;
2011-03-21 18:00:50 -07:00
}
return ret ;
}
/*
* This function prepares command to set / get 11 d domain information .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting domain information fields ( for SET only )
* - Ensuring correct endian - ness
*/
static int mwifiex_cmd_802_11d_domain_info ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action )
{
struct mwifiex_adapter * adapter = priv - > adapter ;
struct host_cmd_ds_802_11d_domain_info * domain_info =
& cmd - > params . domain_info ;
struct mwifiex_ietypes_domain_param_set * domain =
& domain_info - > domain ;
u8 no_of_triplet = adapter - > domain_reg . no_of_triplet ;
dev_dbg ( adapter - > dev , " info: 11D: no_of_triplet=0x%x \n " , no_of_triplet ) ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11D_DOMAIN_INFO ) ;
domain_info - > action = cpu_to_le16 ( cmd_action ) ;
if ( cmd_action = = HostCmd_ACT_GEN_GET ) {
cmd - > size = cpu_to_le16 ( sizeof ( domain_info - > action ) + S_DS_GEN ) ;
return 0 ;
}
/* Set domain info fields */
domain - > header . type = cpu_to_le16 ( WLAN_EID_COUNTRY ) ;
memcpy ( domain - > country_code , adapter - > domain_reg . country_code ,
2012-03-13 19:22:40 -07:00
sizeof ( domain - > country_code ) ) ;
2011-03-21 18:00:50 -07:00
2012-03-13 19:22:40 -07:00
domain - > header . len =
cpu_to_le16 ( ( no_of_triplet *
sizeof ( struct ieee80211_country_ie_triplet ) )
+ sizeof ( domain - > country_code ) ) ;
2011-03-21 18:00:50 -07:00
if ( no_of_triplet ) {
memcpy ( domain - > triplet , adapter - > domain_reg . triplet ,
2012-03-13 19:22:40 -07:00
no_of_triplet * sizeof ( struct
ieee80211_country_ie_triplet ) ) ;
2011-03-21 18:00:50 -07:00
cmd - > size = cpu_to_le16 ( sizeof ( domain_info - > action ) +
2012-03-13 19:22:40 -07:00
le16_to_cpu ( domain - > header . len ) +
sizeof ( struct mwifiex_ie_types_header )
+ S_DS_GEN ) ;
2011-03-21 18:00:50 -07:00
} else {
cmd - > size = cpu_to_le16 ( sizeof ( domain_info - > action ) + S_DS_GEN ) ;
}
return 0 ;
}
/*
* This function prepares command to set / get IBSS coalescing status .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting status to enable or disable ( for SET only )
* - Ensuring correct endian - ness
*/
2011-04-13 17:27:08 -07:00
static int mwifiex_cmd_ibss_coalescing_status ( struct host_cmd_ds_command * cmd ,
2011-06-20 15:21:48 -07:00
u16 cmd_action , u16 * enable )
2011-03-21 18:00:50 -07:00
{
struct host_cmd_ds_802_11_ibss_status * ibss_coal =
& ( cmd - > params . ibss_coalescing ) ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_IBSS_COALESCING_STATUS ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_ibss_status ) +
S_DS_GEN ) ;
cmd - > result = 0 ;
ibss_coal - > action = cpu_to_le16 ( cmd_action ) ;
switch ( cmd_action ) {
case HostCmd_ACT_GEN_SET :
2011-06-20 15:21:48 -07:00
if ( enable )
ibss_coal - > enable = cpu_to_le16 ( * enable ) ;
2011-06-24 16:33:35 +03:00
else
ibss_coal - > enable = 0 ;
2011-03-21 18:00:50 -07:00
break ;
/* In other case.. Nothing to do */
case HostCmd_ACT_GEN_GET :
default :
break ;
}
return 0 ;
}
/*
* This function prepares command to set / get register value .
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting register offset ( for both GET and SET ) and
* register value ( for SET only )
* - Ensuring correct endian - ness
*
* The following type of registers can be accessed with this function -
* - MAC register
* - BBP register
* - RF register
* - PMIC register
* - CAU register
* - EEPROM
*/
static int mwifiex_cmd_reg_access ( struct host_cmd_ds_command * cmd ,
u16 cmd_action , void * data_buf )
{
2011-06-20 15:21:48 -07:00
struct mwifiex_ds_reg_rw * reg_rw = data_buf ;
2011-03-21 18:00:50 -07:00
switch ( le16_to_cpu ( cmd - > command ) ) {
case HostCmd_CMD_MAC_REG_ACCESS :
{
struct host_cmd_ds_mac_reg_access * mac_reg ;
cmd - > size = cpu_to_le16 ( sizeof ( * mac_reg ) + S_DS_GEN ) ;
2012-06-04 12:44:17 +00:00
mac_reg = & cmd - > params . mac_reg ;
2011-03-21 18:00:50 -07:00
mac_reg - > action = cpu_to_le16 ( cmd_action ) ;
mac_reg - > offset =
cpu_to_le16 ( ( u16 ) le32_to_cpu ( reg_rw - > offset ) ) ;
mac_reg - > value = reg_rw - > value ;
break ;
}
case HostCmd_CMD_BBP_REG_ACCESS :
{
struct host_cmd_ds_bbp_reg_access * bbp_reg ;
cmd - > size = cpu_to_le16 ( sizeof ( * bbp_reg ) + S_DS_GEN ) ;
2012-06-04 12:44:17 +00:00
bbp_reg = & cmd - > params . bbp_reg ;
2011-03-21 18:00:50 -07:00
bbp_reg - > action = cpu_to_le16 ( cmd_action ) ;
bbp_reg - > offset =
cpu_to_le16 ( ( u16 ) le32_to_cpu ( reg_rw - > offset ) ) ;
bbp_reg - > value = ( u8 ) le32_to_cpu ( reg_rw - > value ) ;
break ;
}
case HostCmd_CMD_RF_REG_ACCESS :
{
struct host_cmd_ds_rf_reg_access * rf_reg ;
cmd - > size = cpu_to_le16 ( sizeof ( * rf_reg ) + S_DS_GEN ) ;
2012-06-04 12:44:17 +00:00
rf_reg = & cmd - > params . rf_reg ;
2011-03-21 18:00:50 -07:00
rf_reg - > action = cpu_to_le16 ( cmd_action ) ;
2012-03-13 19:22:40 -07:00
rf_reg - > offset = cpu_to_le16 ( ( u16 ) le32_to_cpu ( reg_rw - > offset ) ) ;
2011-03-21 18:00:50 -07:00
rf_reg - > value = ( u8 ) le32_to_cpu ( reg_rw - > value ) ;
break ;
}
case HostCmd_CMD_PMIC_REG_ACCESS :
{
struct host_cmd_ds_pmic_reg_access * pmic_reg ;
cmd - > size = cpu_to_le16 ( sizeof ( * pmic_reg ) + S_DS_GEN ) ;
2012-06-04 12:44:17 +00:00
pmic_reg = & cmd - > params . pmic_reg ;
2011-03-21 18:00:50 -07:00
pmic_reg - > action = cpu_to_le16 ( cmd_action ) ;
pmic_reg - > offset =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( ( u16 ) le32_to_cpu ( reg_rw - > offset ) ) ;
2011-03-21 18:00:50 -07:00
pmic_reg - > value = ( u8 ) le32_to_cpu ( reg_rw - > value ) ;
break ;
}
case HostCmd_CMD_CAU_REG_ACCESS :
{
struct host_cmd_ds_rf_reg_access * cau_reg ;
cmd - > size = cpu_to_le16 ( sizeof ( * cau_reg ) + S_DS_GEN ) ;
2012-06-04 12:44:17 +00:00
cau_reg = & cmd - > params . rf_reg ;
2011-03-21 18:00:50 -07:00
cau_reg - > action = cpu_to_le16 ( cmd_action ) ;
cau_reg - > offset =
2012-03-13 19:22:40 -07:00
cpu_to_le16 ( ( u16 ) le32_to_cpu ( reg_rw - > offset ) ) ;
2011-03-21 18:00:50 -07:00
cau_reg - > value = ( u8 ) le32_to_cpu ( reg_rw - > value ) ;
break ;
}
case HostCmd_CMD_802_11_EEPROM_ACCESS :
{
2011-06-20 15:21:48 -07:00
struct mwifiex_ds_read_eeprom * rd_eeprom = data_buf ;
2011-03-21 18:00:50 -07:00
struct host_cmd_ds_802_11_eeprom_access * cmd_eeprom =
& cmd - > params . eeprom ;
cmd - > size = cpu_to_le16 ( sizeof ( * cmd_eeprom ) + S_DS_GEN ) ;
cmd_eeprom - > action = cpu_to_le16 ( cmd_action ) ;
cmd_eeprom - > offset = rd_eeprom - > offset ;
cmd_eeprom - > byte_count = rd_eeprom - > byte_count ;
cmd_eeprom - > value = 0 ;
break ;
}
default :
return - 1 ;
}
return 0 ;
}
2011-10-11 17:41:21 -07:00
/*
* This function prepares command to set PCI - Express
* host buffer configuration
*
* Preparation includes -
* - Setting command ID , action and proper size
* - Setting host buffer configuration
* - Ensuring correct endian - ness
*/
static int
mwifiex_cmd_pcie_host_spec ( struct mwifiex_private * priv ,
2012-03-13 19:22:40 -07:00
struct host_cmd_ds_command * cmd , u16 action )
2011-10-11 17:41:21 -07:00
{
struct host_cmd_ds_pcie_details * host_spec =
& cmd - > params . pcie_host_spec ;
struct pcie_service_card * card = priv - > adapter - > card ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_PCIE_DESC_DETAILS ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct
host_cmd_ds_pcie_details ) + S_DS_GEN ) ;
cmd - > result = 0 ;
memset ( host_spec , 0 , sizeof ( struct host_cmd_ds_pcie_details ) ) ;
2012-03-13 19:22:40 -07:00
if ( action ! = HostCmd_ACT_GEN_SET )
return 0 ;
/* Send the ring base addresses and count to firmware */
host_spec - > txbd_addr_lo = ( u32 ) ( card - > txbd_ring_pbase ) ;
host_spec - > txbd_addr_hi = ( u32 ) ( ( ( u64 ) card - > txbd_ring_pbase ) > > 32 ) ;
host_spec - > txbd_count = MWIFIEX_MAX_TXRX_BD ;
host_spec - > rxbd_addr_lo = ( u32 ) ( card - > rxbd_ring_pbase ) ;
host_spec - > rxbd_addr_hi = ( u32 ) ( ( ( u64 ) card - > rxbd_ring_pbase ) > > 32 ) ;
host_spec - > rxbd_count = MWIFIEX_MAX_TXRX_BD ;
host_spec - > evtbd_addr_lo = ( u32 ) ( card - > evtbd_ring_pbase ) ;
host_spec - > evtbd_addr_hi = ( u32 ) ( ( ( u64 ) card - > evtbd_ring_pbase ) > > 32 ) ;
host_spec - > evtbd_count = MWIFIEX_MAX_EVT_BD ;
2013-01-03 21:21:30 -08:00
if ( card - > sleep_cookie_vbase ) {
host_spec - > sleep_cookie_addr_lo =
( u32 ) ( card - > sleep_cookie_pbase ) ;
host_spec - > sleep_cookie_addr_hi =
( u32 ) ( ( ( u64 ) ( card - > sleep_cookie_pbase ) ) > > 32 ) ;
2012-03-13 19:22:40 -07:00
dev_dbg ( priv - > adapter - > dev , " sleep_cook_lo phy addr: 0x%x \n " ,
host_spec - > sleep_cookie_addr_lo ) ;
2011-10-11 17:41:21 -07:00
}
return 0 ;
}
2012-03-15 20:51:51 -07:00
/*
* This function prepares command for event subscription , configuration
* and query . Events can be subscribed or unsubscribed . Current subscribed
* events can be queried . Also , current subscribed events are reported in
* every FW response .
*/
static int
mwifiex_cmd_802_11_subsc_evt ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
struct mwifiex_ds_misc_subsc_evt * subsc_evt_cfg )
{
struct host_cmd_ds_802_11_subsc_evt * subsc_evt = & cmd - > params . subsc_evt ;
struct mwifiex_ie_types_rssi_threshold * rssi_tlv ;
u16 event_bitmap ;
u8 * pos ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_802_11_SUBSCRIBE_EVENT ) ;
cmd - > size = cpu_to_le16 ( sizeof ( struct host_cmd_ds_802_11_subsc_evt ) +
S_DS_GEN ) ;
subsc_evt - > action = cpu_to_le16 ( subsc_evt_cfg - > action ) ;
dev_dbg ( priv - > adapter - > dev , " cmd: action: %d \n " , subsc_evt_cfg - > action ) ;
/*For query requests, no configuration TLV structures are to be added.*/
if ( subsc_evt_cfg - > action = = HostCmd_ACT_GEN_GET )
return 0 ;
subsc_evt - > events = cpu_to_le16 ( subsc_evt_cfg - > events ) ;
event_bitmap = subsc_evt_cfg - > events ;
dev_dbg ( priv - > adapter - > dev , " cmd: event bitmap : %16x \n " ,
event_bitmap ) ;
if ( ( ( subsc_evt_cfg - > action = = HostCmd_ACT_BITWISE_CLR ) | |
( subsc_evt_cfg - > action = = HostCmd_ACT_BITWISE_SET ) ) & &
( event_bitmap = = 0 ) ) {
dev_dbg ( priv - > adapter - > dev , " Error: No event specified "
" for bitwise action type \n " ) ;
return - EINVAL ;
}
/*
* Append TLV structures for each of the specified events for
* subscribing or re - configuring . This is not required for
* bitwise unsubscribing request .
*/
if ( subsc_evt_cfg - > action = = HostCmd_ACT_BITWISE_CLR )
return 0 ;
pos = ( ( u8 * ) subsc_evt ) +
sizeof ( struct host_cmd_ds_802_11_subsc_evt ) ;
if ( event_bitmap & BITMASK_BCN_RSSI_LOW ) {
rssi_tlv = ( struct mwifiex_ie_types_rssi_threshold * ) pos ;
rssi_tlv - > header . type = cpu_to_le16 ( TLV_TYPE_RSSI_LOW ) ;
rssi_tlv - > header . len =
cpu_to_le16 ( sizeof ( struct mwifiex_ie_types_rssi_threshold ) -
sizeof ( struct mwifiex_ie_types_header ) ) ;
rssi_tlv - > abs_value = subsc_evt_cfg - > bcn_l_rssi_cfg . abs_value ;
rssi_tlv - > evt_freq = subsc_evt_cfg - > bcn_l_rssi_cfg . evt_freq ;
dev_dbg ( priv - > adapter - > dev , " Cfg Beacon Low Rssi event, "
" RSSI:-%d dBm, Freq:%d \n " ,
subsc_evt_cfg - > bcn_l_rssi_cfg . abs_value ,
subsc_evt_cfg - > bcn_l_rssi_cfg . evt_freq ) ;
pos + = sizeof ( struct mwifiex_ie_types_rssi_threshold ) ;
le16_add_cpu ( & cmd - > size ,
sizeof ( struct mwifiex_ie_types_rssi_threshold ) ) ;
}
if ( event_bitmap & BITMASK_BCN_RSSI_HIGH ) {
rssi_tlv = ( struct mwifiex_ie_types_rssi_threshold * ) pos ;
rssi_tlv - > header . type = cpu_to_le16 ( TLV_TYPE_RSSI_HIGH ) ;
rssi_tlv - > header . len =
cpu_to_le16 ( sizeof ( struct mwifiex_ie_types_rssi_threshold ) -
sizeof ( struct mwifiex_ie_types_header ) ) ;
rssi_tlv - > abs_value = subsc_evt_cfg - > bcn_h_rssi_cfg . abs_value ;
rssi_tlv - > evt_freq = subsc_evt_cfg - > bcn_h_rssi_cfg . evt_freq ;
2012-04-09 20:06:53 -07:00
dev_dbg ( priv - > adapter - > dev , " Cfg Beacon High Rssi event, "
2012-03-15 20:51:51 -07:00
" RSSI:-%d dBm, Freq:%d \n " ,
subsc_evt_cfg - > bcn_h_rssi_cfg . abs_value ,
subsc_evt_cfg - > bcn_h_rssi_cfg . evt_freq ) ;
pos + = sizeof ( struct mwifiex_ie_types_rssi_threshold ) ;
le16_add_cpu ( & cmd - > size ,
sizeof ( struct mwifiex_ie_types_rssi_threshold ) ) ;
}
return 0 ;
}
2013-03-04 16:27:59 -08:00
static int
mwifiex_cmd_append_rpn_expression ( struct mwifiex_private * priv ,
struct mwifiex_mef_entry * mef_entry ,
u8 * * buffer )
{
struct mwifiex_mef_filter * filter = mef_entry - > filter ;
int i , byte_len ;
u8 * stack_ptr = * buffer ;
2013-08-05 18:51:57 -07:00
for ( i = 0 ; i < MWIFIEX_MEF_MAX_FILTERS ; i + + ) {
2013-03-04 16:27:59 -08:00
filter = & mef_entry - > filter [ i ] ;
if ( ! filter - > filt_type )
break ;
* ( __le32 * ) stack_ptr = cpu_to_le32 ( ( u32 ) filter - > repeat ) ;
stack_ptr + = 4 ;
* stack_ptr = TYPE_DNUM ;
stack_ptr + = 1 ;
2013-08-05 18:51:57 -07:00
byte_len = filter - > byte_seq [ MWIFIEX_MEF_MAX_BYTESEQ ] ;
2013-03-04 16:27:59 -08:00
memcpy ( stack_ptr , filter - > byte_seq , byte_len ) ;
stack_ptr + = byte_len ;
* stack_ptr = byte_len ;
stack_ptr + = 1 ;
* stack_ptr = TYPE_BYTESEQ ;
stack_ptr + = 1 ;
* ( __le32 * ) stack_ptr = cpu_to_le32 ( ( u32 ) filter - > offset ) ;
stack_ptr + = 4 ;
* stack_ptr = TYPE_DNUM ;
stack_ptr + = 1 ;
* stack_ptr = filter - > filt_type ;
stack_ptr + = 1 ;
if ( filter - > filt_action ) {
* stack_ptr = filter - > filt_action ;
stack_ptr + = 1 ;
}
if ( stack_ptr - * buffer > STACK_NBYTES )
return - 1 ;
}
* buffer = stack_ptr ;
return 0 ;
}
static int
mwifiex_cmd_mef_cfg ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
struct mwifiex_ds_mef_cfg * mef )
{
struct host_cmd_ds_mef_cfg * mef_cfg = & cmd - > params . mef_cfg ;
u8 * pos = ( u8 * ) mef_cfg ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_MEF_CFG ) ;
mef_cfg - > criteria = cpu_to_le32 ( mef - > criteria ) ;
mef_cfg - > num_entries = cpu_to_le16 ( mef - > num_entries ) ;
pos + = sizeof ( * mef_cfg ) ;
mef_cfg - > mef_entry - > mode = mef - > mef_entry - > mode ;
mef_cfg - > mef_entry - > action = mef - > mef_entry - > action ;
pos + = sizeof ( * ( mef_cfg - > mef_entry ) ) ;
if ( mwifiex_cmd_append_rpn_expression ( priv , mef - > mef_entry , & pos ) )
return - 1 ;
mef_cfg - > mef_entry - > exprsize =
cpu_to_le16 ( pos - mef_cfg - > mef_entry - > expr ) ;
cmd - > size = cpu_to_le16 ( ( u16 ) ( pos - ( u8 * ) mef_cfg ) + S_DS_GEN ) ;
return 0 ;
}
2013-05-17 17:50:25 -07:00
/* This function parse cal data from ASCII to hex */
static u32 mwifiex_parse_cal_cfg ( u8 * src , size_t len , u8 * dst )
{
u8 * s = src , * d = dst ;
while ( s - src < len ) {
if ( * s & & ( isspace ( * s ) | | * s = = ' \t ' ) ) {
s + + ;
continue ;
}
if ( isxdigit ( * s ) ) {
* d + + = simple_strtol ( s , NULL , 16 ) ;
s + = 2 ;
} else {
s + + ;
}
}
return d - dst ;
}
2013-12-13 18:33:02 -08:00
int mwifiex_dnld_dt_cfgdata ( struct mwifiex_private * priv ,
struct device_node * node , const char * prefix )
2013-12-13 18:33:01 -08:00
{
# ifdef CONFIG_OF
struct property * prop ;
size_t len = strlen ( prefix ) ;
int ret ;
/* look for all matching property names */
for_each_property_of_node ( node , prop ) {
if ( len > strlen ( prop - > name ) | |
strncmp ( prop - > name , prefix , len ) )
continue ;
2014-01-08 15:45:56 -08:00
/* property header is 6 bytes, data must fit in cmd buffer */
if ( prop & & prop - > value & & prop - > length > 6 & &
prop - > length < = MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN ) {
2013-12-13 18:33:01 -08:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_CFG_DATA ,
HostCmd_ACT_GEN_SET , 0 ,
prop ) ;
if ( ret )
return ret ;
}
}
# endif
return 0 ;
}
2013-05-17 17:50:25 -07:00
/* This function prepares command of set_cfg_data. */
static int mwifiex_cmd_cfg_data ( struct mwifiex_private * priv ,
2013-12-13 18:33:01 -08:00
struct host_cmd_ds_command * cmd , void * data_buf )
2013-05-17 17:50:25 -07:00
{
struct mwifiex_adapter * adapter = priv - > adapter ;
2013-12-13 18:33:01 -08:00
struct property * prop = data_buf ;
2013-12-13 18:33:00 -08:00
u32 len ;
u8 * data = ( u8 * ) cmd + S_DS_GEN ;
2013-12-13 18:33:01 -08:00
int ret ;
2013-05-17 17:50:25 -07:00
2013-12-13 18:33:01 -08:00
if ( prop ) {
len = prop - > length ;
ret = of_property_read_u8_array ( adapter - > dt_node , prop - > name ,
data , len ) ;
if ( ret )
return ret ;
dev_dbg ( adapter - > dev ,
" download cfg_data from device tree: %s \n " , prop - > name ) ;
} else if ( adapter - > cal_data - > data & & adapter - > cal_data - > size > 0 ) {
2013-05-17 17:50:25 -07:00
len = mwifiex_parse_cal_cfg ( ( u8 * ) adapter - > cal_data - > data ,
2013-12-13 18:33:00 -08:00
adapter - > cal_data - > size , data ) ;
2013-12-13 18:33:01 -08:00
dev_dbg ( adapter - > dev , " download cfg_data from config file \n " ) ;
} else {
2013-05-17 17:50:25 -07:00
return - 1 ;
2013-12-13 18:33:01 -08:00
}
2013-05-17 17:50:25 -07:00
cmd - > command = cpu_to_le16 ( HostCmd_CMD_CFG_DATA ) ;
2013-12-13 18:33:00 -08:00
cmd - > size = cpu_to_le16 ( S_DS_GEN + len ) ;
2013-05-17 17:50:25 -07:00
return 0 ;
}
2013-08-05 18:52:00 -07:00
static int
mwifiex_cmd_coalesce_cfg ( struct mwifiex_private * priv ,
struct host_cmd_ds_command * cmd ,
u16 cmd_action , void * data_buf )
{
struct host_cmd_ds_coalesce_cfg * coalesce_cfg =
& cmd - > params . coalesce_cfg ;
struct mwifiex_ds_coalesce_cfg * cfg = data_buf ;
struct coalesce_filt_field_param * param ;
u16 cnt , idx , length ;
struct coalesce_receive_filt_rule * rule ;
cmd - > command = cpu_to_le16 ( HostCmd_CMD_COALESCE_CFG ) ;
cmd - > size = cpu_to_le16 ( S_DS_GEN ) ;
coalesce_cfg - > action = cpu_to_le16 ( cmd_action ) ;
coalesce_cfg - > num_of_rules = cpu_to_le16 ( cfg - > num_of_rules ) ;
rule = coalesce_cfg - > rule ;
for ( cnt = 0 ; cnt < cfg - > num_of_rules ; cnt + + ) {
rule - > header . type = cpu_to_le16 ( TLV_TYPE_COALESCE_RULE ) ;
rule - > max_coalescing_delay =
cpu_to_le16 ( cfg - > rule [ cnt ] . max_coalescing_delay ) ;
rule - > pkt_type = cfg - > rule [ cnt ] . pkt_type ;
rule - > num_of_fields = cfg - > rule [ cnt ] . num_of_fields ;
length = 0 ;
param = rule - > params ;
for ( idx = 0 ; idx < cfg - > rule [ cnt ] . num_of_fields ; idx + + ) {
param - > operation = cfg - > rule [ cnt ] . params [ idx ] . operation ;
param - > operand_len =
cfg - > rule [ cnt ] . params [ idx ] . operand_len ;
param - > offset =
cpu_to_le16 ( cfg - > rule [ cnt ] . params [ idx ] . offset ) ;
memcpy ( param - > operand_byte_stream ,
cfg - > rule [ cnt ] . params [ idx ] . operand_byte_stream ,
param - > operand_len ) ;
length + = sizeof ( struct coalesce_filt_field_param ) ;
param + + ;
}
/* Total rule length is sizeof max_coalescing_delay(u16),
* num_of_fields ( u8 ) , pkt_type ( u8 ) and total length of the all
* params
*/
rule - > header . len = cpu_to_le16 ( length + sizeof ( u16 ) +
sizeof ( u8 ) + sizeof ( u8 ) ) ;
/* Add the rule length to the command size*/
le16_add_cpu ( & cmd - > size , le16_to_cpu ( rule - > header . len ) +
sizeof ( struct mwifiex_ie_types_header ) ) ;
rule = ( void * ) ( ( u8 * ) rule - > params + length ) ;
}
/* Add sizeof action, num_of_rules to total command length */
le16_add_cpu ( & cmd - > size , sizeof ( u16 ) + sizeof ( u16 ) ) ;
return 0 ;
}
2011-03-21 18:00:50 -07:00
/*
* This function prepares the commands before sending them to the firmware .
*
* This is a generic function which calls specific command preparation
* routines based upon the command number .
*/
int mwifiex_sta_prepare_cmd ( struct mwifiex_private * priv , uint16_t cmd_no ,
u16 cmd_action , u32 cmd_oid ,
void * data_buf , void * cmd_buf )
{
2011-06-20 15:21:48 -07:00
struct host_cmd_ds_command * cmd_ptr = cmd_buf ;
2011-03-21 18:00:50 -07:00
int ret = 0 ;
/* Prepare command */
switch ( cmd_no ) {
case HostCmd_CMD_GET_HW_SPEC :
ret = mwifiex_cmd_get_hw_spec ( priv , cmd_ptr ) ;
break ;
2013-05-17 17:50:25 -07:00
case HostCmd_CMD_CFG_DATA :
2013-12-13 18:33:01 -08:00
ret = mwifiex_cmd_cfg_data ( priv , cmd_ptr , data_buf ) ;
2013-05-17 17:50:25 -07:00
break ;
2011-03-21 18:00:50 -07:00
case HostCmd_CMD_MAC_CONTROL :
ret = mwifiex_cmd_mac_control ( priv , cmd_ptr , cmd_action ,
data_buf ) ;
break ;
case HostCmd_CMD_802_11_MAC_ADDRESS :
ret = mwifiex_cmd_802_11_mac_address ( priv , cmd_ptr ,
cmd_action ) ;
break ;
case HostCmd_CMD_MAC_MULTICAST_ADR :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_mac_multicast_adr ( cmd_ptr , cmd_action ,
2011-03-21 18:00:50 -07:00
data_buf ) ;
break ;
case HostCmd_CMD_TX_RATE_CFG :
ret = mwifiex_cmd_tx_rate_cfg ( priv , cmd_ptr , cmd_action ,
data_buf ) ;
break ;
case HostCmd_CMD_TXPWR_CFG :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_tx_power_cfg ( cmd_ptr , cmd_action ,
2011-03-21 18:00:50 -07:00
data_buf ) ;
break ;
2012-06-27 19:57:57 -07:00
case HostCmd_CMD_RF_TX_PWR :
ret = mwifiex_cmd_rf_tx_power ( priv , cmd_ptr , cmd_action ,
data_buf ) ;
break ;
2012-07-02 19:32:33 -07:00
case HostCmd_CMD_RF_ANTENNA :
ret = mwifiex_cmd_rf_antenna ( priv , cmd_ptr , cmd_action ,
data_buf ) ;
break ;
2011-03-21 18:00:50 -07:00
case HostCmd_CMD_802_11_PS_MODE_ENH :
ret = mwifiex_cmd_enh_power_mode ( priv , cmd_ptr , cmd_action ,
( uint16_t ) cmd_oid , data_buf ) ;
break ;
case HostCmd_CMD_802_11_HS_CFG_ENH :
ret = mwifiex_cmd_802_11_hs_cfg ( priv , cmd_ptr , cmd_action ,
( struct mwifiex_hs_config_param * ) data_buf ) ;
break ;
case HostCmd_CMD_802_11_SCAN :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_802_11_scan ( cmd_ptr , data_buf ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_802_11_BG_SCAN_QUERY :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_802_11_bg_scan_query ( cmd_ptr ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_802_11_ASSOCIATE :
ret = mwifiex_cmd_802_11_associate ( priv , cmd_ptr , data_buf ) ;
break ;
case HostCmd_CMD_802_11_DEAUTHENTICATE :
ret = mwifiex_cmd_802_11_deauthenticate ( priv , cmd_ptr ,
data_buf ) ;
break ;
case HostCmd_CMD_802_11_AD_HOC_START :
ret = mwifiex_cmd_802_11_ad_hoc_start ( priv , cmd_ptr ,
data_buf ) ;
break ;
case HostCmd_CMD_802_11_GET_LOG :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_802_11_get_log ( cmd_ptr ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_802_11_AD_HOC_JOIN :
ret = mwifiex_cmd_802_11_ad_hoc_join ( priv , cmd_ptr ,
data_buf ) ;
break ;
case HostCmd_CMD_802_11_AD_HOC_STOP :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_802_11_ad_hoc_stop ( cmd_ptr ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_RSSI_INFO :
ret = mwifiex_cmd_802_11_rssi_info ( priv , cmd_ptr , cmd_action ) ;
break ;
case HostCmd_CMD_802_11_SNMP_MIB :
ret = mwifiex_cmd_802_11_snmp_mib ( priv , cmd_ptr , cmd_action ,
cmd_oid , data_buf ) ;
break ;
case HostCmd_CMD_802_11_TX_RATE_QUERY :
cmd_ptr - > command =
cpu_to_le16 ( HostCmd_CMD_802_11_TX_RATE_QUERY ) ;
cmd_ptr - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_tx_rate_query ) +
S_DS_GEN ) ;
priv - > tx_rate = 0 ;
ret = 0 ;
break ;
case HostCmd_CMD_VERSION_EXT :
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
cmd_ptr - > params . verext . version_str_sel =
( u8 ) ( * ( ( u32 * ) data_buf ) ) ;
memcpy ( & cmd_ptr - > params , data_buf ,
sizeof ( struct host_cmd_ds_version_ext ) ) ;
cmd_ptr - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_version_ext ) +
S_DS_GEN ) ;
ret = 0 ;
break ;
2012-09-25 20:23:34 -07:00
case HostCmd_CMD_MGMT_FRAME_REG :
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
cmd_ptr - > params . reg_mask . action = cpu_to_le16 ( cmd_action ) ;
cmd_ptr - > params . reg_mask . mask = cpu_to_le32 ( * ( u32 * ) data_buf ) ;
cmd_ptr - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_mgmt_frame_reg ) +
S_DS_GEN ) ;
ret = 0 ;
break ;
2012-09-25 20:23:36 -07:00
case HostCmd_CMD_REMAIN_ON_CHAN :
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
memcpy ( & cmd_ptr - > params , data_buf ,
sizeof ( struct host_cmd_ds_remain_on_chan ) ) ;
cmd_ptr - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_remain_on_chan ) +
S_DS_GEN ) ;
break ;
2013-03-18 20:06:03 -07:00
case HostCmd_CMD_11AC_CFG :
ret = mwifiex_cmd_11ac_cfg ( priv , cmd_ptr , cmd_action , data_buf ) ;
break ;
2012-09-25 20:23:41 -07:00
case HostCmd_CMD_P2P_MODE_CFG :
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
cmd_ptr - > params . mode_cfg . action = cpu_to_le16 ( cmd_action ) ;
cmd_ptr - > params . mode_cfg . mode = cpu_to_le16 ( * ( u16 * ) data_buf ) ;
cmd_ptr - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_p2p_mode_cfg ) +
S_DS_GEN ) ;
break ;
2011-03-21 18:00:50 -07:00
case HostCmd_CMD_FUNC_INIT :
if ( priv - > adapter - > hw_status = = MWIFIEX_HW_STATUS_RESET )
priv - > adapter - > hw_status = MWIFIEX_HW_STATUS_READY ;
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
cmd_ptr - > size = cpu_to_le16 ( S_DS_GEN ) ;
break ;
case HostCmd_CMD_FUNC_SHUTDOWN :
priv - > adapter - > hw_status = MWIFIEX_HW_STATUS_RESET ;
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
cmd_ptr - > size = cpu_to_le16 ( S_DS_GEN ) ;
break ;
case HostCmd_CMD_11N_ADDBA_REQ :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_11n_addba_req ( cmd_ptr , data_buf ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_11N_DELBA :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_11n_delba ( cmd_ptr , data_buf ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_11N_ADDBA_RSP :
ret = mwifiex_cmd_11n_addba_rsp_gen ( priv , cmd_ptr , data_buf ) ;
break ;
case HostCmd_CMD_802_11_KEY_MATERIAL :
ret = mwifiex_cmd_802_11_key_material ( priv , cmd_ptr ,
2012-03-13 19:22:40 -07:00
cmd_action , cmd_oid ,
data_buf ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_802_11D_DOMAIN_INFO :
ret = mwifiex_cmd_802_11d_domain_info ( priv , cmd_ptr ,
2012-03-13 19:22:40 -07:00
cmd_action ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_RECONFIGURE_TX_BUFF :
ret = mwifiex_cmd_recfg_tx_buf ( priv , cmd_ptr , cmd_action ,
data_buf ) ;
break ;
case HostCmd_CMD_AMSDU_AGGR_CTRL :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_amsdu_aggr_ctrl ( cmd_ptr , cmd_action ,
2011-03-21 18:00:50 -07:00
data_buf ) ;
break ;
case HostCmd_CMD_11N_CFG :
2013-02-15 21:44:30 -08:00
ret = mwifiex_cmd_11n_cfg ( priv , cmd_ptr , cmd_action , data_buf ) ;
2011-03-21 18:00:50 -07:00
break ;
case HostCmd_CMD_WMM_GET_STATUS :
dev_dbg ( priv - > adapter - > dev ,
" cmd: WMM: WMM_GET_STATUS cmd sent \n " ) ;
cmd_ptr - > command = cpu_to_le16 ( HostCmd_CMD_WMM_GET_STATUS ) ;
cmd_ptr - > size =
cpu_to_le16 ( sizeof ( struct host_cmd_ds_wmm_get_status ) +
S_DS_GEN ) ;
ret = 0 ;
break ;
case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS :
2011-04-13 17:27:08 -07:00
ret = mwifiex_cmd_ibss_coalescing_status ( cmd_ptr , cmd_action ,
data_buf ) ;
2011-03-21 18:00:50 -07:00
break ;
2014-02-11 18:39:56 -08:00
case HostCmd_CMD_802_11_SCAN_EXT :
ret = mwifiex_cmd_802_11_scan_ext ( priv , cmd_ptr , data_buf ) ;
break ;
2011-03-21 18:00:50 -07:00
case HostCmd_CMD_MAC_REG_ACCESS :
case HostCmd_CMD_BBP_REG_ACCESS :
case HostCmd_CMD_RF_REG_ACCESS :
case HostCmd_CMD_PMIC_REG_ACCESS :
case HostCmd_CMD_CAU_REG_ACCESS :
case HostCmd_CMD_802_11_EEPROM_ACCESS :
ret = mwifiex_cmd_reg_access ( cmd_ptr , cmd_action , data_buf ) ;
break ;
case HostCmd_CMD_SET_BSS_MODE :
cmd_ptr - > command = cpu_to_le16 ( cmd_no ) ;
2011-03-28 17:55:41 -07:00
if ( priv - > bss_mode = = NL80211_IFTYPE_ADHOC )
2011-03-21 18:00:50 -07:00
cmd_ptr - > params . bss_mode . con_type =
CONNECTION_TYPE_ADHOC ;
2011-03-28 17:55:41 -07:00
else if ( priv - > bss_mode = = NL80211_IFTYPE_STATION )
2011-03-21 18:00:50 -07:00
cmd_ptr - > params . bss_mode . con_type =
CONNECTION_TYPE_INFRA ;
2012-09-25 20:23:42 -07:00
else if ( priv - > bss_mode = = NL80211_IFTYPE_AP )
cmd_ptr - > params . bss_mode . con_type = CONNECTION_TYPE_AP ;
2011-03-21 18:00:50 -07:00
cmd_ptr - > size = cpu_to_le16 ( sizeof ( struct
host_cmd_ds_set_bss_mode ) + S_DS_GEN ) ;
ret = 0 ;
break ;
2011-10-11 17:41:21 -07:00
case HostCmd_CMD_PCIE_DESC_DETAILS :
ret = mwifiex_cmd_pcie_host_spec ( priv , cmd_ptr , cmd_action ) ;
break ;
2012-03-15 20:51:51 -07:00
case HostCmd_CMD_802_11_SUBSCRIBE_EVENT :
ret = mwifiex_cmd_802_11_subsc_evt ( priv , cmd_ptr , data_buf ) ;
break ;
2013-03-04 16:27:59 -08:00
case HostCmd_CMD_MEF_CFG :
ret = mwifiex_cmd_mef_cfg ( priv , cmd_ptr , data_buf ) ;
break ;
2013-08-05 18:52:00 -07:00
case HostCmd_CMD_COALESCE_CFG :
ret = mwifiex_cmd_coalesce_cfg ( priv , cmd_ptr , cmd_action ,
data_buf ) ;
break ;
2011-03-21 18:00:50 -07:00
default :
dev_err ( priv - > adapter - > dev ,
" PREP_CMD: unknown cmd- %#x \n " , cmd_no ) ;
ret = - 1 ;
break ;
}
return ret ;
}
/*
* This function issues commands to initialize firmware .
*
* This is called after firmware download to bring the card to
* working state .
*
* The following commands are issued sequentially -
2011-10-11 17:41:21 -07:00
* - Set PCI - Express host buffer configuration ( PCIE only )
2011-03-21 18:00:50 -07:00
* - Function init ( for first interface only )
* - Read MAC address ( for first interface only )
* - Reconfigure Tx buffer size ( for first interface only )
* - Enable auto deep sleep ( for first interface only )
* - Get Tx rate
* - Get Tx power
* - Set IBSS coalescing status
* - Set AMSDU aggregation control
* - Set 11 d control
* - Set MAC control ( this must be the last command to initialize firmware )
*/
int mwifiex_sta_init_cmd ( struct mwifiex_private * priv , u8 first_sta )
{
2013-05-17 17:50:25 -07:00
struct mwifiex_adapter * adapter = priv - > adapter ;
2011-05-03 20:11:46 -07:00
int ret ;
2011-03-21 18:00:50 -07:00
u16 enable = true ;
struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl ;
struct mwifiex_ds_auto_ds auto_ds ;
enum state_11d_t state_11d ;
2011-07-08 20:40:30 -07:00
struct mwifiex_ds_11n_tx_cfg tx_cfg ;
2011-03-21 18:00:50 -07:00
if ( first_sta ) {
2011-10-11 17:41:21 -07:00
if ( priv - > adapter - > iface_type = = MWIFIEX_PCIE ) {
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv ,
2012-03-13 19:22:40 -07:00
HostCmd_CMD_PCIE_DESC_DETAILS ,
HostCmd_ACT_GEN_SET , 0 , NULL ) ;
2011-10-11 17:41:21 -07:00
if ( ret )
return - 1 ;
}
2011-03-21 18:00:50 -07:00
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_FUNC_INIT ,
HostCmd_ACT_GEN_SET , 0 , NULL ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
2013-05-17 17:50:25 -07:00
2013-12-13 18:33:01 -08:00
/* Download calibration data to firmware.
* The cal - data can be read from device tree and / or
* a configuration file and downloaded to firmware .
*/
adapter - > dt_node =
of_find_node_by_name ( NULL , " marvell_cfgdata " ) ;
if ( adapter - > dt_node ) {
ret = mwifiex_dnld_dt_cfgdata ( priv , adapter - > dt_node ,
" marvell,caldata " ) ;
if ( ret )
return - 1 ;
}
2013-05-17 17:50:25 -07:00
if ( adapter - > cal_data ) {
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_CFG_DATA ,
HostCmd_ACT_GEN_SET , 0 , NULL ) ;
if ( ret )
return - 1 ;
}
2011-03-21 18:00:50 -07:00
/* Read MAC address from HW */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_GET_HW_SPEC ,
HostCmd_ACT_GEN_GET , 0 , NULL ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
/* Reconfigure tx buf size */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv ,
HostCmd_CMD_RECONFIGURE_TX_BUFF ,
HostCmd_ACT_GEN_SET , 0 ,
& priv - > adapter - > tx_buf_size ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
2012-05-08 18:30:14 -07:00
if ( priv - > bss_type ! = MWIFIEX_BSS_TYPE_UAP ) {
/* Enable IEEE PS by default */
priv - > adapter - > ps_mode = MWIFIEX_802_11_POWER_MODE_PSP ;
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync (
2012-05-08 18:30:14 -07:00
priv , HostCmd_CMD_802_11_PS_MODE_ENH ,
EN_AUTO_PS , BITMAP_STA_PS , NULL ) ;
if ( ret )
return - 1 ;
}
2011-03-21 18:00:50 -07:00
}
/* get tx rate */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_TX_RATE_CFG ,
HostCmd_ACT_GEN_GET , 0 , NULL ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
priv - > data_rate = 0 ;
/* get tx power */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_RF_TX_PWR ,
HostCmd_ACT_GEN_GET , 0 , NULL ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
2012-05-08 18:30:14 -07:00
if ( priv - > bss_type = = MWIFIEX_BSS_TYPE_STA ) {
/* set ibss coalescing_status */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync (
2012-05-08 18:30:14 -07:00
priv , HostCmd_CMD_802_11_IBSS_COALESCING_STATUS ,
HostCmd_ACT_GEN_SET , 0 , & enable ) ;
if ( ret )
return - 1 ;
}
2011-03-21 18:00:50 -07:00
memset ( & amsdu_aggr_ctrl , 0 , sizeof ( amsdu_aggr_ctrl ) ) ;
amsdu_aggr_ctrl . enable = true ;
/* Send request to firmware */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_AMSDU_AGGR_CTRL ,
HostCmd_ACT_GEN_SET , 0 ,
& amsdu_aggr_ctrl ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
/* MAC Control must be the last command in init_fw */
/* set MAC Control */
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_MAC_CONTROL ,
HostCmd_ACT_GEN_SET , 0 ,
& priv - > curr_pkt_filter ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
2012-05-08 18:30:14 -07:00
if ( first_sta & & priv - > adapter - > iface_type ! = MWIFIEX_USB & &
priv - > bss_type ! = MWIFIEX_BSS_TYPE_UAP ) {
2011-03-21 18:00:50 -07:00
/* Enable auto deep sleep */
auto_ds . auto_ds = DEEP_SLEEP_ON ;
auto_ds . idle_time = DEEP_SLEEP_IDLE_TIME ;
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv ,
HostCmd_CMD_802_11_PS_MODE_ENH ,
EN_AUTO_PS , BITMAP_AUTO_DS ,
& auto_ds ) ;
2011-03-21 18:00:50 -07:00
if ( ret )
return - 1 ;
}
2012-05-08 18:30:14 -07:00
if ( priv - > bss_type ! = MWIFIEX_BSS_TYPE_UAP ) {
/* Send cmd to FW to enable/disable 11D function */
state_11d = ENABLE_11D ;
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_802_11_SNMP_MIB ,
HostCmd_ACT_GEN_SET , DOT11D_I ,
& state_11d ) ;
2012-05-08 18:30:14 -07:00
if ( ret )
dev_err ( priv - > adapter - > dev ,
" 11D: failed to enable 11D \n " ) ;
}
2011-03-21 18:00:50 -07:00
2012-09-25 20:23:39 -07:00
/* set last_init_cmd before sending the command */
priv - > adapter - > last_init_cmd = HostCmd_CMD_11N_CFG ;
2011-07-08 20:40:30 -07:00
/* Send cmd to FW to configure 11n specific configuration
* ( Short GI , Channel BW , Green field support etc . ) for transmit
*/
tx_cfg . tx_htcap = MWIFIEX_FW_DEF_HTTXCFG ;
2012-09-25 20:23:39 -07:00
ret = mwifiex_send_cmd_sync ( priv , HostCmd_CMD_11N_CFG ,
HostCmd_ACT_GEN_SET , 0 , & tx_cfg ) ;
2011-07-08 20:40:30 -07:00
2011-03-21 18:00:50 -07:00
ret = - EINPROGRESS ;
return ret ;
}