2007-02-10 12:25:27 -02:00
/**
* This file contains the handling of command .
* It prepares command and sends it to firmware when it is ready .
*/
# include <net/iw_handler.h>
# include "host.h"
# include "hostcmd.h"
# include "decl.h"
# include "defs.h"
# include "dev.h"
# include "join.h"
# include "wext.h"
static void cleanup_cmdnode ( struct cmd_ctrl_node * ptempnode ) ;
2007-12-05 17:58:06 +01:00
struct cmd_ctrl_node * lbs_get_cmd_ctrl_node ( struct lbs_private * priv ) ;
void lbs_set_cmd_ctrl_node ( struct lbs_private * priv ,
struct cmd_ctrl_node * ptempnode ,
u16 wait_option , void * pdata_buf ) ;
2007-02-10 12:25:27 -02:00
static u16 commands_allowed_in_ps [ ] = {
2007-08-02 11:31:18 -04:00
CMD_802_11_RSSI ,
2007-02-10 12:25:27 -02:00
} ;
/**
* @ brief This function checks if the commans is allowed
* in PS mode not .
*
* @ param command the command ID
* @ return TRUE or FALSE
*/
2007-05-25 23:36:54 -04:00
static u8 is_command_allowed_in_ps ( __le16 command )
2007-02-10 12:25:27 -02:00
{
int i ;
2007-05-25 23:36:54 -04:00
for ( i = 0 ; i < ARRAY_SIZE ( commands_allowed_in_ps ) ; i + + ) {
2007-02-10 12:25:27 -02:00
if ( command = = cpu_to_le16 ( commands_allowed_in_ps [ i ] ) )
return 1 ;
}
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_hw_spec ( struct lbs_private * priv , struct cmd_ds_command * cmd )
2007-02-10 12:25:27 -02:00
{
struct cmd_ds_get_hw_spec * hwspec = & cmd - > params . hwspec ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_GET_HW_SPEC ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_get_hw_spec ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
memcpy ( hwspec - > permanentaddr , priv - > adapter - > current_addr , ETH_ALEN ) ;
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_ps_mode ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
struct cmd_ds_802_11_ps_mode * psm = & cmd - > params . psmode ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_PS_MODE ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_ps_mode ) +
S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
psm - > action = cpu_to_le16 ( cmd_action ) ;
psm - > multipledtim = 0 ;
2007-05-25 23:36:54 -04:00
switch ( cmd_action ) {
2007-08-02 11:31:18 -04:00
case CMD_SUBCMD_ENTER_PS :
2007-05-25 11:27:16 -04:00
lbs_deb_cmd ( " PS command: " " SubCode- Enter PS \n " ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 13:09:34 -04:00
psm - > locallisteninterval = 0 ;
2007-08-02 13:09:15 -04:00
psm - > nullpktinterval = 0 ;
2007-02-10 12:25:27 -02:00
psm - > multipledtim =
2007-08-02 13:09:49 -04:00
cpu_to_le16 ( MRVDRV_DEFAULT_MULTIPLE_DTIM ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_SUBCMD_EXIT_PS :
2007-05-25 11:27:16 -04:00
lbs_deb_cmd ( " PS command: " " SubCode- Exit PS \n " ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_SUBCMD_SLEEP_CONFIRMED :
2007-05-25 11:27:16 -04:00
lbs_deb_cmd ( " PS command: SubCode- sleep confirm \n " ) ;
2007-02-10 12:25:27 -02:00
break ;
default :
break ;
}
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_inactivity_timeout ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action , void * pdata_buf )
{
u16 * timeout = pdata_buf ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_INACTIVITY_TIMEOUT ) ;
2007-02-10 12:25:27 -02:00
cmd - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_inactivity_timeout )
+ S_DS_GEN ) ;
cmd - > params . inactivity_timeout . action = cpu_to_le16 ( cmd_action ) ;
if ( cmd_action )
2007-05-25 23:36:54 -04:00
cmd - > params . inactivity_timeout . timeout = cpu_to_le16 ( * timeout ) ;
2007-02-10 12:25:27 -02:00
else
cmd - > params . inactivity_timeout . timeout = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_sleep_params ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
struct cmd_ds_802_11_sleep_params * sp = & cmd - > params . sleep_params ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( ( sizeof ( struct cmd_ds_802_11_sleep_params ) ) +
S_DS_GEN ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_SLEEP_PARAMS ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_GET ) {
2007-02-10 12:25:27 -02:00
memset ( & adapter - > sp , 0 , sizeof ( struct sleep_params ) ) ;
memset ( sp , 0 , sizeof ( struct cmd_ds_802_11_sleep_params ) ) ;
sp - > action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:31:18 -04:00
} else if ( cmd_action = = CMD_ACT_SET ) {
2007-02-10 12:25:27 -02:00
sp - > action = cpu_to_le16 ( cmd_action ) ;
sp - > error = cpu_to_le16 ( adapter - > sp . sp_error ) ;
sp - > offset = cpu_to_le16 ( adapter - > sp . sp_offset ) ;
sp - > stabletime = cpu_to_le16 ( adapter - > sp . sp_stabletime ) ;
sp - > calcontrol = ( u8 ) adapter - > sp . sp_calcontrol ;
sp - > externalsleepclk = ( u8 ) adapter - > sp . sp_extsleepclk ;
sp - > reserved = cpu_to_le16 ( adapter - > sp . sp_reserved ) ;
}
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_set_wep ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u32 cmd_act ,
void * pdata_buf )
{
struct cmd_ds_802_11_set_wep * wep = & cmd - > params . wep ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
int ret = 0 ;
struct assoc_request * assoc_req = pdata_buf ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_SET_WEP ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( * wep ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( cmd_act = = CMD_ACT_ADD ) {
2007-02-10 12:25:27 -02:00
int i ;
if ( ! assoc_req ) {
2007-05-25 11:27:16 -04:00
lbs_deb_cmd ( " Invalid association request! " ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
2007-08-02 11:31:18 -04:00
wep - > action = cpu_to_le16 ( CMD_ACT_ADD ) ;
2007-02-10 12:25:27 -02:00
/* default tx key index */
2007-05-25 23:36:54 -04:00
wep - > keyindex = cpu_to_le16 ( ( u16 ) ( assoc_req - > wep_tx_keyidx &
2007-08-02 11:31:18 -04:00
( u32 ) CMD_WEP_KEY_INDEX_MASK ) ) ;
2007-02-10 12:25:27 -02:00
/* Copy key types and material to host command structure */
for ( i = 0 ; i < 4 ; i + + ) {
2007-08-02 10:45:55 -04:00
struct enc_key * pkey = & assoc_req - > wep_keys [ i ] ;
2007-02-10 12:25:27 -02:00
switch ( pkey - > len ) {
case KEY_LEN_WEP_40 :
2007-10-08 11:07:27 +02:00
wep - > keytype [ i ] = CMD_TYPE_WEP_40_BIT ;
2007-02-10 12:25:27 -02:00
memmove ( & wep - > keymaterial [ i ] , pkey - > key ,
pkey - > len ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " SET_WEP: add key %d (40 bit) \n " , i ) ;
2007-02-10 12:25:27 -02:00
break ;
case KEY_LEN_WEP_104 :
2007-10-08 11:07:27 +02:00
wep - > keytype [ i ] = CMD_TYPE_WEP_104_BIT ;
2007-02-10 12:25:27 -02:00
memmove ( & wep - > keymaterial [ i ] , pkey - > key ,
pkey - > len ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " SET_WEP: add key %d (104 bit) \n " , i ) ;
2007-02-10 12:25:27 -02:00
break ;
case 0 :
break ;
default :
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " SET_WEP: invalid key %d, length %d \n " ,
2007-02-10 12:25:27 -02:00
i , pkey - > len ) ;
ret = - 1 ;
goto done ;
break ;
}
}
2007-08-02 11:31:18 -04:00
} else if ( cmd_act = = CMD_ACT_REMOVE ) {
2007-02-10 12:25:27 -02:00
/* ACT_REMOVE clears _all_ WEP keys */
2007-08-02 11:31:18 -04:00
wep - > action = cpu_to_le16 ( CMD_ACT_REMOVE ) ;
2007-02-10 12:25:27 -02:00
/* default tx key index */
2007-05-25 23:36:54 -04:00
wep - > keyindex = cpu_to_le16 ( ( u16 ) ( adapter - > wep_tx_keyidx &
2007-08-02 11:31:18 -04:00
( u32 ) CMD_WEP_KEY_INDEX_MASK ) ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " SET_WEP: remove key %d \n " , adapter - > wep_tx_keyidx ) ;
2007-02-10 12:25:27 -02:00
}
ret = 0 ;
done :
2007-05-25 11:27:16 -04:00
lbs_deb_leave_args ( LBS_DEB_CMD , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_enable_rsn ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
2007-05-25 23:01:24 -04:00
u16 cmd_action ,
void * pdata_buf )
2007-02-10 12:25:27 -02:00
{
struct cmd_ds_802_11_enable_rsn * penableRSN = & cmd - > params . enbrsn ;
2007-06-18 12:01:12 -04:00
u32 * enable = pdata_buf ;
2007-05-25 23:01:24 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_ENABLE_RSN ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( * penableRSN ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
penableRSN - > action = cpu_to_le16 ( cmd_action ) ;
2007-06-18 12:01:12 -04:00
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_SET ) {
2007-06-18 12:01:12 -04:00
if ( * enable )
2007-08-02 11:31:18 -04:00
penableRSN - > enable = cpu_to_le16 ( CMD_ENABLE_RSN ) ;
2007-06-18 12:01:12 -04:00
else
2007-08-02 11:31:18 -04:00
penableRSN - > enable = cpu_to_le16 ( CMD_DISABLE_RSN ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " ENABLE_RSN: %d \n " , * enable ) ;
2007-02-10 12:25:27 -02:00
}
2007-05-25 23:01:24 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-26 10:07:14 +01:00
static ssize_t lbs_tlv_size ( const u8 * tlv , u16 size )
{
ssize_t pos = 0 ;
struct mrvlietypesheader * tlv_h ;
while ( pos < size ) {
u16 length ;
tlv_h = ( struct mrvlietypesheader * ) tlv ;
if ( tlv_h - > len = = 0 )
return pos ;
length = le16_to_cpu ( tlv_h - > len ) +
sizeof ( struct mrvlietypesheader ) ;
pos + = length ;
tlv + = length ;
}
return pos ;
}
static void lbs_cmd_802_11_subscribe_event ( struct lbs_private * priv ,
struct cmd_ds_command * cmd , u16 cmd_action ,
void * pdata_buf )
{
struct cmd_ds_802_11_subscribe_event * events =
( struct cmd_ds_802_11_subscribe_event * ) pdata_buf ;
/* pdata_buf points to a struct cmd_ds_802_11_subscribe_event and room
* for various Marvell TLVs */
lbs_deb_enter ( LBS_DEB_CMD ) ;
cmd - > size = cpu_to_le16 ( sizeof ( * events )
- sizeof ( events - > tlv )
+ S_DS_GEN ) ;
cmd - > params . subscribe_event . action = cpu_to_le16 ( cmd_action ) ;
if ( cmd_action = = CMD_ACT_GET ) {
cmd - > params . subscribe_event . events = 0 ;
} else {
ssize_t sz = lbs_tlv_size ( events - > tlv , sizeof ( events - > tlv ) ) ;
cmd - > size = cpu_to_le16 ( le16_to_cpu ( cmd - > size ) + sz ) ;
cmd - > params . subscribe_event . events = events - > events ;
memcpy ( cmd - > params . subscribe_event . tlv , events - > tlv , sz ) ;
}
lbs_deb_leave ( LBS_DEB_CMD ) ;
}
2007-02-10 12:25:27 -02:00
static void set_one_wpa_key ( struct MrvlIEtype_keyParamSet * pkeyparamset ,
2007-08-02 10:45:55 -04:00
struct enc_key * pkey )
2007-02-10 12:25:27 -02:00
{
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
if ( pkey - > flags & KEY_INFO_WPA_ENABLED ) {
2007-05-25 23:01:24 -04:00
pkeyparamset - > keyinfo | = cpu_to_le16 ( KEY_INFO_WPA_ENABLED ) ;
2007-02-10 12:25:27 -02:00
}
if ( pkey - > flags & KEY_INFO_WPA_UNICAST ) {
pkeyparamset - > keyinfo | = cpu_to_le16 ( KEY_INFO_WPA_UNICAST ) ;
2007-05-25 23:01:24 -04:00
}
if ( pkey - > flags & KEY_INFO_WPA_MCAST ) {
2007-02-10 12:25:27 -02:00
pkeyparamset - > keyinfo | = cpu_to_le16 ( KEY_INFO_WPA_MCAST ) ;
}
pkeyparamset - > type = cpu_to_le16 ( TLV_TYPE_KEY_MATERIAL ) ;
2007-08-02 10:45:55 -04:00
pkeyparamset - > keytypeid = cpu_to_le16 ( pkey - > type ) ;
2007-02-10 12:25:27 -02:00
pkeyparamset - > keylen = cpu_to_le16 ( pkey - > len ) ;
memcpy ( pkeyparamset - > key , pkey - > key , pkey - > len ) ;
pkeyparamset - > length = cpu_to_le16 ( sizeof ( pkeyparamset - > keytypeid )
+ sizeof ( pkeyparamset - > keyinfo )
+ sizeof ( pkeyparamset - > keylen )
+ sizeof ( pkeyparamset - > key ) ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_key_material ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action ,
u32 cmd_oid , void * pdata_buf )
{
struct cmd_ds_802_11_key_material * pkeymaterial =
& cmd - > params . keymaterial ;
2007-05-25 23:01:24 -04:00
struct assoc_request * assoc_req = pdata_buf ;
2007-02-10 12:25:27 -02:00
int ret = 0 ;
int index = 0 ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_KEY_MATERIAL ) ;
2007-02-10 12:25:27 -02:00
pkeymaterial - > action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_GET ) {
2007-05-25 23:01:24 -04:00
cmd - > size = cpu_to_le16 ( S_DS_GEN + sizeof ( pkeymaterial - > action ) ) ;
2007-02-10 12:25:27 -02:00
ret = 0 ;
goto done ;
}
memset ( & pkeymaterial - > keyParamSet , 0 , sizeof ( pkeymaterial - > keyParamSet ) ) ;
2007-05-25 23:01:24 -04:00
if ( test_bit ( ASSOC_FLAG_WPA_UCAST_KEY , & assoc_req - > flags ) ) {
2007-02-10 12:25:27 -02:00
set_one_wpa_key ( & pkeymaterial - > keyParamSet [ index ] ,
2007-05-25 23:01:24 -04:00
& assoc_req - > wpa_unicast_key ) ;
2007-02-10 12:25:27 -02:00
index + + ;
}
2007-05-25 23:01:24 -04:00
if ( test_bit ( ASSOC_FLAG_WPA_MCAST_KEY , & assoc_req - > flags ) ) {
2007-02-10 12:25:27 -02:00
set_one_wpa_key ( & pkeymaterial - > keyParamSet [ index ] ,
2007-05-25 23:01:24 -04:00
& assoc_req - > wpa_mcast_key ) ;
2007-02-10 12:25:27 -02:00
index + + ;
}
cmd - > size = cpu_to_le16 ( S_DS_GEN
2007-05-25 23:01:24 -04:00
+ sizeof ( pkeymaterial - > action )
+ ( index * sizeof ( struct MrvlIEtype_keyParamSet ) ) ) ;
2007-02-10 12:25:27 -02:00
ret = 0 ;
done :
2007-05-25 11:27:16 -04:00
lbs_deb_leave_args ( LBS_DEB_CMD , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_reset ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd , int cmd_action )
{
struct cmd_ds_802_11_reset * reset = & cmd - > params . reset ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_RESET ) ;
2007-02-10 12:25:27 -02:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_reset ) + S_DS_GEN ) ;
reset - > action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_get_log ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd )
{
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_GET_LOG ) ;
2007-02-10 12:25:27 -02:00
cmd - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_get_log ) + S_DS_GEN ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_get_stat ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd )
{
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_GET_STAT ) ;
2007-02-10 12:25:27 -02:00
cmd - > size =
2007-05-25 23:36:54 -04:00
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_get_stat ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_snmp_mib ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
int cmd_action ,
int cmd_oid , void * pdata_buf )
{
struct cmd_ds_802_11_snmp_mib * pSNMPMIB = & cmd - > params . smib ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
u8 ucTemp ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_cmd ( " SNMP_CMD: cmd_oid = 0x%x \n " , cmd_oid ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_SNMP_MIB ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( * pSNMPMIB ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
switch ( cmd_oid ) {
case OID_802_11_INFRASTRUCTURE_MODE :
{
2007-05-10 22:58:02 -04:00
u8 mode = ( u8 ) ( size_t ) pdata_buf ;
2007-08-02 11:31:18 -04:00
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_SET ) ;
pSNMPMIB - > oid = cpu_to_le16 ( ( u16 ) DESIRED_BSSTYPE_I ) ;
2007-12-07 15:30:44 +00:00
pSNMPMIB - > bufsize = cpu_to_le16 ( sizeof ( u8 ) ) ;
2007-05-10 22:58:02 -04:00
if ( mode = = IW_MODE_ADHOC ) {
2007-02-10 12:25:27 -02:00
ucTemp = SNMP_MIB_VALUE_ADHOC ;
2007-05-10 22:58:02 -04:00
} else {
/* Infra and Auto modes */
ucTemp = SNMP_MIB_VALUE_INFRA ;
}
2007-02-10 12:25:27 -02:00
memmove ( pSNMPMIB - > value , & ucTemp , sizeof ( u8 ) ) ;
break ;
}
case OID_802_11D_ENABLE :
{
u32 ulTemp ;
2007-08-02 11:31:18 -04:00
pSNMPMIB - > oid = cpu_to_le16 ( ( u16 ) DOT11D_I ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_SET ) {
2007-12-07 15:30:44 +00:00
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_SET ) ;
pSNMPMIB - > bufsize = cpu_to_le16 ( sizeof ( u16 ) ) ;
2007-02-10 12:25:27 -02:00
ulTemp = * ( u32 * ) pdata_buf ;
2007-05-25 23:36:54 -04:00
* ( ( __le16 * ) ( pSNMPMIB - > value ) ) =
2007-02-10 12:25:27 -02:00
cpu_to_le16 ( ( u16 ) ulTemp ) ;
}
break ;
}
case OID_802_11_FRAGMENTATION_THRESHOLD :
{
u32 ulTemp ;
2007-08-02 11:31:18 -04:00
pSNMPMIB - > oid = cpu_to_le16 ( ( u16 ) FRAGTHRESH_I ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_GET ) {
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_GET ) ;
} else if ( cmd_action = = CMD_ACT_SET ) {
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_SET ) ;
2007-05-25 23:36:54 -04:00
pSNMPMIB - > bufsize = cpu_to_le16 ( sizeof ( u16 ) ) ;
2007-02-10 12:25:27 -02:00
ulTemp = * ( ( u32 * ) pdata_buf ) ;
2007-05-25 23:36:54 -04:00
* ( ( __le16 * ) ( pSNMPMIB - > value ) ) =
2007-02-10 12:25:27 -02:00
cpu_to_le16 ( ( u16 ) ulTemp ) ;
}
break ;
}
case OID_802_11_RTS_THRESHOLD :
{
u32 ulTemp ;
2007-12-07 15:30:44 +00:00
pSNMPMIB - > oid = cpu_to_le16 ( RTSTHRESH_I ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_GET ) {
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_GET ) ;
} else if ( cmd_action = = CMD_ACT_SET ) {
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_SET ) ;
2007-05-25 23:36:54 -04:00
pSNMPMIB - > bufsize = cpu_to_le16 ( sizeof ( u16 ) ) ;
ulTemp = * ( ( u32 * ) pdata_buf ) ;
* ( __le16 * ) ( pSNMPMIB - > value ) =
2007-02-10 12:25:27 -02:00
cpu_to_le16 ( ( u16 ) ulTemp ) ;
}
break ;
}
case OID_802_11_TX_RETRYCOUNT :
2007-08-02 11:31:18 -04:00
pSNMPMIB - > oid = cpu_to_le16 ( ( u16 ) SHORT_RETRYLIM_I ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_GET ) {
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_GET ) ;
} else if ( cmd_action = = CMD_ACT_SET ) {
pSNMPMIB - > querytype = cpu_to_le16 ( CMD_ACT_SET ) ;
2007-02-10 12:25:27 -02:00
pSNMPMIB - > bufsize = cpu_to_le16 ( sizeof ( u16 ) ) ;
2007-05-25 23:36:54 -04:00
* ( ( __le16 * ) ( pSNMPMIB - > value ) ) =
2007-02-10 12:25:27 -02:00
cpu_to_le16 ( ( u16 ) adapter - > txretrycount ) ;
}
break ;
default :
break ;
}
2007-05-25 11:27:16 -04:00
lbs_deb_cmd (
2007-02-10 12:25:27 -02:00
" SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( cmd - > command ) , le16_to_cpu ( cmd - > size ) ,
le16_to_cpu ( cmd - > seqnum ) , le16_to_cpu ( cmd - > result ) ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_cmd (
2007-08-02 11:54:31 -04:00
" SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( pSNMPMIB - > querytype ) , le16_to_cpu ( pSNMPMIB - > oid ) ,
le16_to_cpu ( pSNMPMIB - > bufsize ) ,
le16_to_cpu ( * ( __le16 * ) pSNMPMIB - > value ) ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_radio_control ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
int cmd_action )
{
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-05-25 23:36:54 -04:00
struct cmd_ds_802_11_radio_control * pradiocontrol = & cmd - > params . radio ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
cmd - > size =
cpu_to_le16 ( ( sizeof ( struct cmd_ds_802_11_radio_control ) ) +
S_DS_GEN ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_RADIO_CONTROL ) ;
2007-02-10 12:25:27 -02:00
pradiocontrol - > action = cpu_to_le16 ( cmd_action ) ;
switch ( adapter - > preamble ) {
2007-08-02 11:31:18 -04:00
case CMD_TYPE_SHORT_PREAMBLE :
2007-02-10 12:25:27 -02:00
pradiocontrol - > control = cpu_to_le16 ( SET_SHORT_PREAMBLE ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_TYPE_LONG_PREAMBLE :
2007-02-10 12:25:27 -02:00
pradiocontrol - > control = cpu_to_le16 ( SET_LONG_PREAMBLE ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_TYPE_AUTO_PREAMBLE :
2007-02-10 12:25:27 -02:00
default :
pradiocontrol - > control = cpu_to_le16 ( SET_AUTO_PREAMBLE ) ;
break ;
}
if ( adapter - > radioon )
pradiocontrol - > control | = cpu_to_le16 ( TURN_ON_RF ) ;
else
pradiocontrol - > control & = cpu_to_le16 ( ~ TURN_ON_RF ) ;
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_rf_tx_power ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action , void * pdata_buf )
{
struct cmd_ds_802_11_rf_tx_power * prtp = & cmd - > params . txp ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
cmd - > size =
2007-05-25 23:36:54 -04:00
cpu_to_le16 ( ( sizeof ( struct cmd_ds_802_11_rf_tx_power ) ) + S_DS_GEN ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_RF_TX_POWER ) ;
2007-05-25 23:36:54 -04:00
prtp - > action = cpu_to_le16 ( cmd_action ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 23:36:54 -04:00
lbs_deb_cmd ( " RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d \n " ,
le16_to_cpu ( cmd - > size ) , le16_to_cpu ( cmd - > command ) ,
le16_to_cpu ( prtp - > action ) ) ;
2007-02-10 12:25:27 -02:00
switch ( cmd_action ) {
2007-08-02 11:31:18 -04:00
case CMD_ACT_TX_POWER_OPT_GET :
prtp - > action = cpu_to_le16 ( CMD_ACT_GET ) ;
2007-02-10 12:25:27 -02:00
prtp - > currentlevel = 0 ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_TX_POWER_OPT_SET_HIGH :
prtp - > action = cpu_to_le16 ( CMD_ACT_SET ) ;
prtp - > currentlevel = cpu_to_le16 ( CMD_ACT_TX_POWER_INDEX_HIGH ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_TX_POWER_OPT_SET_MID :
prtp - > action = cpu_to_le16 ( CMD_ACT_SET ) ;
prtp - > currentlevel = cpu_to_le16 ( CMD_ACT_TX_POWER_INDEX_MID ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_TX_POWER_OPT_SET_LOW :
prtp - > action = cpu_to_le16 ( CMD_ACT_SET ) ;
2007-02-10 12:25:27 -02:00
prtp - > currentlevel = cpu_to_le16 ( * ( ( u16 * ) pdata_buf ) ) ;
break ;
}
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_monitor_mode ( struct lbs_private * priv ,
2007-08-02 13:16:55 -04:00
struct cmd_ds_command * cmd ,
u16 cmd_action , void * pdata_buf )
{
struct cmd_ds_802_11_monitor_mode * monitor = & cmd - > params . monitor ;
cmd - > command = cpu_to_le16 ( CMD_802_11_MONITOR_MODE ) ;
cmd - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_monitor_mode ) +
S_DS_GEN ) ;
monitor - > action = cpu_to_le16 ( cmd_action ) ;
if ( cmd_action = = CMD_ACT_SET ) {
monitor - > mode =
cpu_to_le16 ( ( u16 ) ( * ( u32 * ) pdata_buf ) ) ;
}
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_rate_adapt_rateset ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
struct cmd_ds_802_11_rate_adapt_rateset
* rateadapt = & cmd - > params . rateset ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
cmd - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_rate_adapt_rateset )
+ S_DS_GEN ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_RATE_ADAPT_RATESET ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 23:36:54 -04:00
rateadapt - > action = cpu_to_le16 ( cmd_action ) ;
rateadapt - > enablehwauto = cpu_to_le16 ( adapter - > enablehwauto ) ;
rateadapt - > bitmap = cpu_to_le16 ( adapter - > ratebitmap ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_data_rate ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
struct cmd_ds_802_11_data_rate * pdatarate = & cmd - > params . drate ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_data_rate ) +
2007-02-10 12:25:27 -02:00
S_DS_GEN ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_DATA_RATE ) ;
2007-02-10 12:25:27 -02:00
memset ( pdatarate , 0 , sizeof ( struct cmd_ds_802_11_data_rate ) ) ;
pdatarate - > action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:35:46 -04:00
if ( cmd_action = = CMD_ACT_SET_TX_FIX_RATE ) {
2007-11-15 18:05:47 -05:00
pdatarate - > rates [ 0 ] = lbs_data_rate_to_fw_index ( adapter - > cur_rate ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " DATA_RATE: set fixed 0x%02X \n " ,
2007-08-02 11:40:45 -04:00
adapter - > cur_rate ) ;
2007-08-02 11:35:46 -04:00
} else if ( cmd_action = = CMD_ACT_SET_TX_AUTO ) {
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " DATA_RATE: setting auto \n " ) ;
2007-02-10 12:25:27 -02:00
}
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_mac_multicast_adr ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
struct cmd_ds_mac_multicast_adr * pMCastAdr = & cmd - > params . madr ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_mac_multicast_adr ) +
2007-02-10 12:25:27 -02:00
S_DS_GEN ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_MAC_MULTICAST_ADR ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " MULTICAST_ADR: setting %d addresses \n " , pMCastAdr - > nr_of_adrs ) ;
2007-02-10 12:25:27 -02:00
pMCastAdr - > action = cpu_to_le16 ( cmd_action ) ;
pMCastAdr - > nr_of_adrs =
cpu_to_le16 ( ( u16 ) adapter - > nr_of_multicastmacaddr ) ;
memcpy ( pMCastAdr - > maclist , adapter - > multicastlist ,
adapter - > nr_of_multicastmacaddr * ETH_ALEN ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_rf_channel ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
int option , void * pdata_buf )
{
struct cmd_ds_802_11_rf_channel * rfchan = & cmd - > params . rfchannel ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_RF_CHANNEL ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_rf_channel ) +
S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( option = = CMD_OPT_802_11_RF_CHANNEL_SET ) {
2007-02-10 12:25:27 -02:00
rfchan - > currentchannel = cpu_to_le16 ( * ( ( u16 * ) pdata_buf ) ) ;
}
rfchan - > action = cpu_to_le16 ( option ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_rssi ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd )
{
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_RSSI ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_rssi ) + S_DS_GEN ) ;
2007-08-02 13:08:24 -04:00
cmd - > params . rssi . N = cpu_to_le16 ( DEFAULT_BCN_AVG_FACTOR ) ;
2007-02-10 12:25:27 -02:00
/* reset Beacon SNR/NF/RSSI values */
adapter - > SNR [ TYPE_BEACON ] [ TYPE_NOAVG ] = 0 ;
adapter - > SNR [ TYPE_BEACON ] [ TYPE_AVG ] = 0 ;
adapter - > NF [ TYPE_BEACON ] [ TYPE_NOAVG ] = 0 ;
adapter - > NF [ TYPE_BEACON ] [ TYPE_AVG ] = 0 ;
adapter - > RSSI [ TYPE_BEACON ] [ TYPE_NOAVG ] = 0 ;
adapter - > RSSI [ TYPE_BEACON ] [ TYPE_AVG ] = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_reg_access ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmdptr ,
u8 cmd_action , void * pdata_buf )
{
2007-11-15 18:05:47 -05:00
struct lbs_offset_value * offval ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-11-15 18:05:47 -05:00
offval = ( struct lbs_offset_value * ) pdata_buf ;
2007-02-10 12:25:27 -02:00
2007-12-07 15:30:44 +00:00
switch ( le16_to_cpu ( cmdptr - > command ) ) {
2007-08-02 11:31:18 -04:00
case CMD_MAC_REG_ACCESS :
2007-02-10 12:25:27 -02:00
{
struct cmd_ds_mac_reg_access * macreg ;
cmdptr - > size =
2007-05-25 23:36:54 -04:00
cpu_to_le16 ( sizeof ( struct cmd_ds_mac_reg_access )
+ S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
macreg =
( struct cmd_ds_mac_reg_access * ) & cmdptr - > params .
macreg ;
macreg - > action = cpu_to_le16 ( cmd_action ) ;
macreg - > offset = cpu_to_le16 ( ( u16 ) offval - > offset ) ;
macreg - > value = cpu_to_le32 ( offval - > value ) ;
break ;
}
2007-08-02 11:31:18 -04:00
case CMD_BBP_REG_ACCESS :
2007-02-10 12:25:27 -02:00
{
struct cmd_ds_bbp_reg_access * bbpreg ;
cmdptr - > size =
cpu_to_le16 ( sizeof
( struct cmd_ds_bbp_reg_access )
+ S_DS_GEN ) ;
bbpreg =
( struct cmd_ds_bbp_reg_access * ) & cmdptr - > params .
bbpreg ;
bbpreg - > action = cpu_to_le16 ( cmd_action ) ;
bbpreg - > offset = cpu_to_le16 ( ( u16 ) offval - > offset ) ;
bbpreg - > value = ( u8 ) offval - > value ;
break ;
}
2007-08-02 11:31:18 -04:00
case CMD_RF_REG_ACCESS :
2007-02-10 12:25:27 -02:00
{
struct cmd_ds_rf_reg_access * rfreg ;
cmdptr - > size =
cpu_to_le16 ( sizeof
( struct cmd_ds_rf_reg_access ) +
S_DS_GEN ) ;
rfreg =
( struct cmd_ds_rf_reg_access * ) & cmdptr - > params .
rfreg ;
rfreg - > action = cpu_to_le16 ( cmd_action ) ;
rfreg - > offset = cpu_to_le16 ( ( u16 ) offval - > offset ) ;
rfreg - > value = ( u8 ) offval - > value ;
break ;
}
default :
break ;
}
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_mac_address ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_MAC_ADDRESS ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_mac_address ) +
2007-02-10 12:25:27 -02:00
S_DS_GEN ) ;
cmd - > result = 0 ;
cmd - > params . macadd . action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:31:18 -04:00
if ( cmd_action = = CMD_ACT_SET ) {
2007-02-10 12:25:27 -02:00
memcpy ( cmd - > params . macadd . macadd ,
adapter - > current_addr , ETH_ALEN ) ;
2007-08-02 11:53:06 -04:00
lbs_deb_hex ( LBS_DEB_CMD , " SET_CMD: MAC addr " , adapter - > current_addr , 6 ) ;
2007-02-10 12:25:27 -02:00
}
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_802_11_eeprom_access ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
int cmd_action , void * pdata_buf )
{
2007-11-15 18:05:47 -05:00
struct lbs_ioctl_regrdwr * ea = pdata_buf ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_802_11_EEPROM_ACCESS ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_eeprom_access ) +
S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
cmd - > result = 0 ;
cmd - > params . rdeeprom . action = cpu_to_le16 ( ea - > action ) ;
cmd - > params . rdeeprom . offset = cpu_to_le16 ( ea - > offset ) ;
cmd - > params . rdeeprom . bytecount = cpu_to_le16 ( ea - > NOB ) ;
cmd - > params . rdeeprom . value = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_bt_access ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action , void * pdata_buf )
{
struct cmd_ds_bt_access * bt_access = & cmd - > params . bt ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter_args ( LBS_DEB_CMD , " action %d " , cmd_action ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_BT_ACCESS ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_bt_access ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
cmd - > result = 0 ;
bt_access - > action = cpu_to_le16 ( cmd_action ) ;
switch ( cmd_action ) {
2007-08-02 11:31:18 -04:00
case CMD_ACT_BT_ACCESS_ADD :
2007-02-10 12:25:27 -02:00
memcpy ( bt_access - > addr1 , pdata_buf , 2 * ETH_ALEN ) ;
2007-08-02 11:53:06 -04:00
lbs_deb_hex ( LBS_DEB_MESH , " BT_ADD: blinded MAC addr " , bt_access - > addr1 , 6 ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_BT_ACCESS_DEL :
2007-02-10 12:25:27 -02:00
memcpy ( bt_access - > addr1 , pdata_buf , 1 * ETH_ALEN ) ;
2007-08-02 11:53:06 -04:00
lbs_deb_hex ( LBS_DEB_MESH , " BT_DEL: blinded MAC addr " , bt_access - > addr1 , 6 ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_BT_ACCESS_LIST :
2007-02-10 12:25:27 -02:00
bt_access - > id = cpu_to_le32 ( * ( u32 * ) pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_BT_ACCESS_RESET :
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_BT_ACCESS_SET_INVERT :
2007-05-25 13:53:26 -04:00
bt_access - > id = cpu_to_le32 ( * ( u32 * ) pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_ACT_BT_ACCESS_GET_INVERT :
2007-05-25 13:53:26 -04:00
break ;
2007-02-10 12:25:27 -02:00
default :
break ;
}
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_fwt_access ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action , void * pdata_buf )
{
struct cmd_ds_fwt_access * fwt_access = & cmd - > params . fwt ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter_args ( LBS_DEB_CMD , " action %d " , cmd_action ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_FWT_ACCESS ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_fwt_access ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
cmd - > result = 0 ;
if ( pdata_buf )
memcpy ( fwt_access , pdata_buf , sizeof ( * fwt_access ) ) ;
else
memset ( fwt_access , 0 , sizeof ( * fwt_access ) ) ;
fwt_access - > action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_mesh_access ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd ,
u16 cmd_action , void * pdata_buf )
{
struct cmd_ds_mesh_access * mesh_access = & cmd - > params . mesh ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter_args ( LBS_DEB_CMD , " action %d " , cmd_action ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_MESH_ACCESS ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_mesh_access ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
cmd - > result = 0 ;
if ( pdata_buf )
memcpy ( mesh_access , pdata_buf , sizeof ( * mesh_access ) ) ;
else
memset ( mesh_access , 0 , sizeof ( * mesh_access ) ) ;
mesh_access - > action = cpu_to_le16 ( cmd_action ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
2007-11-20 17:44:28 -05:00
static int lbs_cmd_bcn_ctrl ( struct lbs_private * priv ,
struct cmd_ds_command * cmd ,
u16 cmd_action )
{
struct cmd_ds_802_11_beacon_control
* bcn_ctrl = & cmd - > params . bcn_ctrl ;
struct lbs_adapter * adapter = priv - > adapter ;
lbs_deb_enter ( LBS_DEB_CMD ) ;
cmd - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_beacon_control )
+ S_DS_GEN ) ;
cmd - > command = cpu_to_le16 ( CMD_802_11_BEACON_CTRL ) ;
bcn_ctrl - > action = cpu_to_le16 ( cmd_action ) ;
bcn_ctrl - > beacon_enable = cpu_to_le16 ( adapter - > beacon_enable ) ;
bcn_ctrl - > beacon_period = cpu_to_le16 ( adapter - > beacon_period ) ;
lbs_deb_leave ( LBS_DEB_CMD ) ;
return 0 ;
}
2007-10-30 10:52:46 -04:00
/*
2007-11-15 18:05:47 -05:00
* Note : NEVER use lbs_queue_cmd ( ) with addtail = = 0 other than for
2007-10-30 10:52:46 -04:00
* the command timer , because it does not account for queued commands .
*/
2007-11-23 15:43:44 +01:00
void lbs_queue_cmd ( struct lbs_adapter * adapter ,
struct cmd_ctrl_node * cmdnode ,
u8 addtail )
2007-02-10 12:25:27 -02:00
{
unsigned long flags ;
struct cmd_ds_command * cmdptr ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
if ( ! cmdnode ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " QUEUE_CMD: cmdnode is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
goto done ;
}
cmdptr = ( struct cmd_ds_command * ) cmdnode - > bufvirtualaddr ;
if ( ! cmdptr ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " QUEUE_CMD: cmdptr is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
goto done ;
}
/* Exit_PS command needs to be queued in the header always. */
2007-12-07 15:30:44 +00:00
if ( le16_to_cpu ( cmdptr - > command ) = = CMD_802_11_PS_MODE ) {
2007-02-10 12:25:27 -02:00
struct cmd_ds_802_11_ps_mode * psm = & cmdptr - > params . psmode ;
2007-08-02 11:31:18 -04:00
if ( psm - > action = = cpu_to_le16 ( CMD_SUBCMD_EXIT_PS ) ) {
2007-02-10 12:25:27 -02:00
if ( adapter - > psstate ! = PS_STATE_FULL_POWER )
addtail = 0 ;
}
}
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
2007-12-08 00:35:00 +00:00
if ( addtail )
2007-12-06 13:01:21 +01:00
list_add_tail ( & cmdnode - > list , & adapter - > cmdpendingq ) ;
2007-12-08 00:35:00 +00:00
else
2007-12-06 13:01:21 +01:00
list_add ( & cmdnode - > list , & adapter - > cmdpendingq ) ;
2007-02-10 12:25:27 -02:00
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " QUEUE_CMD: inserted command 0x%04x into cmdpendingq \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( ( ( struct cmd_ds_gen * ) cmdnode - > bufvirtualaddr ) - > command ) ) ;
2007-02-10 12:25:27 -02:00
done :
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
}
/*
* TODO : Fix the issue when DownloadcommandToStation is being called the
2007-08-02 11:54:31 -04:00
* second time when the command times out . All the cmdptr - > xxx are in little
2007-02-10 12:25:27 -02:00
* endian and therefore all the comparissions will fail .
* For now - we are not performing the endian conversion the second time - but
* for PS and DEEP_SLEEP we need to worry
*/
2007-11-23 15:43:44 +01:00
static int DownloadcommandToStation ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ctrl_node * cmdnode )
{
unsigned long flags ;
struct cmd_ds_command * cmdptr ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-08-02 13:18:07 -04:00
int ret = - 1 ;
2007-02-10 12:25:27 -02:00
u16 cmdsize ;
u16 command ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
if ( ! adapter | | ! cmdnode ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " DNLD_CMD: adapter or cmdmode is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
goto done ;
}
cmdptr = ( struct cmd_ds_command * ) cmdnode - > bufvirtualaddr ;
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( ! cmdptr | | ! cmdptr - > size ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " DNLD_CMD: cmdptr is NULL or zero \n " ) ;
2007-11-15 18:05:47 -05:00
__lbs_cleanup_and_insert_cmd ( priv , cmdnode ) ;
2007-02-10 12:25:27 -02:00
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
goto done ;
}
adapter - > cur_cmd = cmdnode ;
adapter - > cur_cmd_retcode = 0 ;
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
2007-12-07 15:30:44 +00:00
cmdsize = le16_to_cpu ( cmdptr - > size ) ;
command = le16_to_cpu ( cmdptr - > command ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " DNLD_CMD: command 0x%04x, size %d, jiffies %lu \n " ,
2007-12-07 15:30:44 +00:00
command , cmdsize , jiffies ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_hex ( LBS_DEB_HOST , " DNLD_CMD " , cmdnode - > bufvirtualaddr , cmdsize ) ;
2007-02-10 12:25:27 -02:00
cmdnode - > cmdwaitqwoken = 0 ;
2007-05-25 12:17:06 -04:00
ret = priv - > hw_host_to_card ( priv , MVMS_CMD , ( u8 * ) cmdptr , cmdsize ) ;
2007-02-10 12:25:27 -02:00
if ( ret ! = 0 ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " DNLD_CMD: hw_host_to_card failed \n " ) ;
2007-02-10 12:25:27 -02:00
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
2007-08-20 12:24:42 -04:00
adapter - > cur_cmd_retcode = ret ;
2007-11-15 18:05:47 -05:00
__lbs_cleanup_and_insert_cmd ( priv , adapter - > cur_cmd ) ;
2007-02-10 12:25:27 -02:00
adapter - > cur_cmd = NULL ;
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
goto done ;
}
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " DNLD_CMD: sent command 0x%04x, jiffies %lu \n " , command , jiffies ) ;
2007-02-10 12:25:27 -02:00
/* Setup the timer after transmit command */
2007-08-02 11:31:18 -04:00
if ( command = = CMD_802_11_SCAN | | command = = CMD_802_11_AUTHENTICATE
| | command = = CMD_802_11_ASSOCIATE )
2007-02-10 12:25:27 -02:00
mod_timer ( & adapter - > command_timer , jiffies + ( 10 * HZ ) ) ;
else
mod_timer ( & adapter - > command_timer , jiffies + ( 5 * HZ ) ) ;
ret = 0 ;
2007-05-25 11:27:16 -04:00
done :
2007-08-02 11:54:31 -04:00
lbs_deb_leave_args ( LBS_DEB_HOST , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-23 15:43:44 +01:00
static int lbs_cmd_mac_control ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ds_command * cmd )
{
struct cmd_ds_mac_control * mac = & cmd - > params . macctrl ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
cmd - > command = cpu_to_le16 ( CMD_MAC_CONTROL ) ;
2007-05-25 23:36:54 -04:00
cmd - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_mac_control ) + S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
mac - > action = cpu_to_le16 ( priv - > adapter - > currentpacketfilter ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " MAC_CONTROL: action 0x%x, size %d \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( mac - > action ) , le16_to_cpu ( cmd - > size ) ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_leave ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
/**
* This function inserts command node to cmdfreeq
* after cleans it . Requires adapter - > driver_lock held .
*/
2007-11-23 15:43:44 +01:00
void __lbs_cleanup_and_insert_cmd ( struct lbs_private * priv ,
struct cmd_ctrl_node * ptempcmd )
2007-02-10 12:25:27 -02:00
{
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
if ( ! ptempcmd )
2007-08-02 11:54:31 -04:00
return ;
2007-02-10 12:25:27 -02:00
cleanup_cmdnode ( ptempcmd ) ;
2007-12-06 13:01:21 +01:00
list_add_tail ( & ptempcmd - > list , & adapter - > cmdfreeq ) ;
2007-02-10 12:25:27 -02:00
}
2007-11-23 15:43:44 +01:00
static void lbs_cleanup_and_insert_cmd ( struct lbs_private * priv ,
struct cmd_ctrl_node * ptempcmd )
2007-02-10 12:25:27 -02:00
{
unsigned long flags ;
spin_lock_irqsave ( & priv - > adapter - > driver_lock , flags ) ;
2007-11-15 18:05:47 -05:00
__lbs_cleanup_and_insert_cmd ( priv , ptempcmd ) ;
2007-02-10 12:25:27 -02:00
spin_unlock_irqrestore ( & priv - > adapter - > driver_lock , flags ) ;
}
2007-11-23 15:43:44 +01:00
int lbs_set_radio_control ( struct lbs_private * priv )
2007-02-10 12:25:27 -02:00
{
int ret = 0 ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
2007-11-15 18:05:47 -05:00
ret = lbs_prepare_and_send_command ( priv ,
2007-08-02 11:31:18 -04:00
CMD_802_11_RADIO_CONTROL ,
CMD_ACT_SET ,
CMD_OPTION_WAITFORRSP , 0 , NULL ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_cmd ( " RADIO_SET: radio %d, preamble %d \n " ,
2007-02-10 12:25:27 -02:00
priv - > adapter - > radioon , priv - > adapter - > preamble ) ;
2007-05-25 11:27:16 -04:00
lbs_deb_leave_args ( LBS_DEB_CMD , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-23 15:43:44 +01:00
int lbs_set_mac_packet_filter ( struct lbs_private * priv )
2007-02-10 12:25:27 -02:00
{
int ret = 0 ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_CMD ) ;
2007-02-10 12:25:27 -02:00
/* Send MAC control command to station */
2007-11-15 18:05:47 -05:00
ret = lbs_prepare_and_send_command ( priv ,
2007-08-02 11:31:18 -04:00
CMD_MAC_CONTROL , 0 , 0 , 0 , NULL ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_leave_args ( LBS_DEB_CMD , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
/**
* @ brief This function prepare the command before send to firmware .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ param cmd_no command number
* @ param cmd_action command action : GET or SET
* @ param wait_option wait option : wait response or not
* @ param cmd_oid cmd oid : treated as sub command
* @ param pdata_buf A pointer to informaion buffer
* @ return 0 or - 1
*/
2007-11-23 15:43:44 +01:00
int lbs_prepare_and_send_command ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
u16 cmd_no ,
u16 cmd_action ,
u16 wait_option , u32 cmd_oid , void * pdata_buf )
{
int ret = 0 ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
struct cmd_ctrl_node * cmdnode ;
struct cmd_ds_command * cmdptr ;
unsigned long flags ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
if ( ! adapter ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: adapter is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
if ( adapter - > surpriseremoved ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: card removed \n " ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
2007-12-05 17:58:06 +01:00
cmdnode = lbs_get_cmd_ctrl_node ( priv ) ;
2007-02-10 12:25:27 -02:00
if ( cmdnode = = NULL ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: cmdnode is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
/* Wake up main thread to execute next command */
2007-08-02 11:32:25 -04:00
wake_up_interruptible ( & priv - > waitq ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
2007-12-01 15:15:41 +00:00
lbs_set_cmd_ctrl_node ( priv , cmdnode , wait_option , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
cmdptr = ( struct cmd_ds_command * ) cmdnode - > bufvirtualaddr ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: command 0x%04x \n " , cmd_no ) ;
2007-02-10 12:25:27 -02:00
if ( ! cmdptr ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: cmdptr is NULL \n " ) ;
2007-11-15 18:05:47 -05:00
lbs_cleanup_and_insert_cmd ( priv , cmdnode ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
/* Set sequence number, command and INT option */
adapter - > seqnum + + ;
cmdptr - > seqnum = cpu_to_le16 ( adapter - > seqnum ) ;
2007-05-25 23:36:54 -04:00
cmdptr - > command = cpu_to_le16 ( cmd_no ) ;
2007-02-10 12:25:27 -02:00
cmdptr - > result = 0 ;
switch ( cmd_no ) {
2007-08-02 11:31:18 -04:00
case CMD_GET_HW_SPEC :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_hw_spec ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_PS_MODE :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_ps_mode ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_SCAN :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_scan ( priv , cmdptr , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_MAC_CONTROL :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_mac_control ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_ASSOCIATE :
case CMD_802_11_REASSOCIATE :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_associate ( priv , cmdptr , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_DEAUTHENTICATE :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_deauthenticate ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_SET_WEP :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_set_wep ( priv , cmdptr , cmd_action , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_AD_HOC_START :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_ad_hoc_start ( priv , cmdptr , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_CODE_DNLD :
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_RESET :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_reset ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_GET_LOG :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_get_log ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_AUTHENTICATE :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_authenticate ( priv , cmdptr , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_GET_STAT :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_get_stat ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_SNMP_MIB :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_snmp_mib ( priv , cmdptr ,
2007-02-10 12:25:27 -02:00
cmd_action , cmd_oid , pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_MAC_REG_ACCESS :
case CMD_BBP_REG_ACCESS :
case CMD_RF_REG_ACCESS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_reg_access ( priv , cmdptr , cmd_action , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_RF_CHANNEL :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_rf_channel ( priv , cmdptr ,
2007-02-10 12:25:27 -02:00
cmd_action , pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_RF_TX_POWER :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_rf_tx_power ( priv , cmdptr ,
2007-02-10 12:25:27 -02:00
cmd_action , pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_RADIO_CONTROL :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_radio_control ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_DATA_RATE :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_data_rate ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_RATE_ADAPT_RATESET :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_rate_adapt_rateset ( priv ,
2007-02-10 12:25:27 -02:00
cmdptr , cmd_action ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_MAC_MULTICAST_ADR :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_mac_multicast_adr ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 13:16:55 -04:00
case CMD_802_11_MONITOR_MODE :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_monitor_mode ( priv , cmdptr ,
2007-08-02 13:16:55 -04:00
cmd_action , pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_AD_HOC_JOIN :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_ad_hoc_join ( priv , cmdptr , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_RSSI :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_rssi ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_AD_HOC_STOP :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_80211_ad_hoc_stop ( priv , cmdptr ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_ENABLE_RSN :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_enable_rsn ( priv , cmdptr , cmd_action ,
2007-05-25 23:01:24 -04:00
pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_KEY_MATERIAL :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_key_material ( priv , cmdptr , cmd_action ,
2007-05-25 23:01:24 -04:00
cmd_oid , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_PAIRWISE_TSC :
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_GROUP_TSC :
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_MAC_ADDRESS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_mac_address ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_EEPROM_ACCESS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_eeprom_access ( priv , cmdptr ,
2007-02-10 12:25:27 -02:00
cmd_action , pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_SET_AFC :
case CMD_802_11_GET_AFC :
2007-02-10 12:25:27 -02:00
cmdptr - > command = cpu_to_le16 ( cmd_no ) ;
2007-05-25 23:36:54 -04:00
cmdptr - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_afc ) +
S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
memmove ( & cmdptr - > params . afc ,
pdata_buf , sizeof ( struct cmd_ds_802_11_afc ) ) ;
ret = 0 ;
goto done ;
2007-08-02 11:31:18 -04:00
case CMD_802_11D_DOMAIN_INFO :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11d_domain_info ( priv , cmdptr ,
2007-02-10 12:25:27 -02:00
cmd_no , cmd_action ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_SLEEP_PARAMS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_sleep_params ( priv , cmdptr , cmd_action ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_INACTIVITY_TIMEOUT :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_802_11_inactivity_timeout ( priv , cmdptr ,
2007-02-10 12:25:27 -02:00
cmd_action , pdata_buf ) ;
2007-12-01 15:15:41 +00:00
lbs_set_cmd_ctrl_node ( priv , cmdnode , 0 , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_TPC_CFG :
cmdptr - > command = cpu_to_le16 ( CMD_802_11_TPC_CFG ) ;
2007-02-10 12:25:27 -02:00
cmdptr - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_tpc_cfg ) +
S_DS_GEN ) ;
memmove ( & cmdptr - > params . tpccfg ,
pdata_buf , sizeof ( struct cmd_ds_802_11_tpc_cfg ) ) ;
ret = 0 ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_LED_GPIO_CTRL :
2007-02-10 12:25:27 -02:00
{
struct mrvlietypes_ledgpio * gpio =
( struct mrvlietypes_ledgpio * )
cmdptr - > params . ledgpio . data ;
memmove ( & cmdptr - > params . ledgpio ,
pdata_buf ,
sizeof ( struct cmd_ds_802_11_led_ctrl ) ) ;
cmdptr - > command =
2007-08-02 11:31:18 -04:00
cpu_to_le16 ( CMD_802_11_LED_GPIO_CTRL ) ;
2007-02-10 12:25:27 -02:00
# define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
cmdptr - > size =
2007-12-07 15:30:44 +00:00
cpu_to_le16 ( le16_to_cpu ( gpio - > header . len )
+ S_DS_GEN
+ ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN ) ;
gpio - > header . len = gpio - > header . len ;
2007-02-10 12:25:27 -02:00
ret = 0 ;
break ;
}
2007-11-26 10:07:14 +01:00
case CMD_802_11_SUBSCRIBE_EVENT :
lbs_cmd_802_11_subscribe_event ( priv , cmdptr ,
cmd_action , pdata_buf ) ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_802_11_PWR_CFG :
cmdptr - > command = cpu_to_le16 ( CMD_802_11_PWR_CFG ) ;
2007-02-10 12:25:27 -02:00
cmdptr - > size =
cpu_to_le16 ( sizeof ( struct cmd_ds_802_11_pwr_cfg ) +
S_DS_GEN ) ;
memmove ( & cmdptr - > params . pwrcfg , pdata_buf ,
sizeof ( struct cmd_ds_802_11_pwr_cfg ) ) ;
ret = 0 ;
break ;
2007-08-02 11:31:18 -04:00
case CMD_BT_ACCESS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_bt_access ( priv , cmdptr , cmd_action , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_FWT_ACCESS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_fwt_access ( priv , cmdptr , cmd_action , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_MESH_ACCESS :
2007-11-15 18:05:47 -05:00
ret = lbs_cmd_mesh_access ( priv , cmdptr , cmd_action , pdata_buf ) ;
2007-02-10 12:25:27 -02:00
break ;
2007-08-02 11:31:18 -04:00
case CMD_GET_TSF :
cmdptr - > command = cpu_to_le16 ( CMD_GET_TSF ) ;
2007-05-25 23:36:54 -04:00
cmdptr - > size = cpu_to_le16 ( sizeof ( struct cmd_ds_get_tsf ) +
S_DS_GEN ) ;
2007-02-10 12:25:27 -02:00
ret = 0 ;
break ;
2007-11-20 17:44:28 -05:00
case CMD_802_11_BEACON_CTRL :
ret = lbs_cmd_bcn_ctrl ( priv , cmdptr , cmd_action ) ;
break ;
2007-02-10 12:25:27 -02:00
default :
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: unknown command 0x%04x \n " , cmd_no ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
break ;
}
/* return error, since the command preparation failed */
if ( ret ! = 0 ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: command preparation failed \n " ) ;
2007-11-15 18:05:47 -05:00
lbs_cleanup_and_insert_cmd ( priv , cmdnode ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
cmdnode - > cmdwaitqwoken = 0 ;
2007-11-15 18:05:47 -05:00
lbs_queue_cmd ( adapter , cmdnode , 1 ) ;
2007-08-02 11:32:25 -04:00
wake_up_interruptible ( & priv - > waitq ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:31:18 -04:00
if ( wait_option & CMD_OPTION_WAITFORRSP ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: wait for response \n " ) ;
2007-02-10 12:25:27 -02:00
might_sleep ( ) ;
wait_event_interruptible ( cmdnode - > cmdwait_q ,
cmdnode - > cmdwaitqwoken ) ;
}
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( adapter - > cur_cmd_retcode ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " PREP_CMD: command failed with return code %d \n " ,
2007-02-10 12:25:27 -02:00
adapter - > cur_cmd_retcode ) ;
adapter - > cur_cmd_retcode = 0 ;
ret = - 1 ;
}
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
done :
2007-08-02 11:54:31 -04:00
lbs_deb_leave_args ( LBS_DEB_HOST , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-15 18:05:47 -05:00
EXPORT_SYMBOL_GPL ( lbs_prepare_and_send_command ) ;
2007-02-10 12:25:27 -02:00
/**
* @ brief This function allocates the command buffer and link
* it to command free queue .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ return 0 or - 1
*/
2007-11-23 15:43:44 +01:00
int lbs_allocate_cmd_buffer ( struct lbs_private * priv )
2007-02-10 12:25:27 -02:00
{
int ret = 0 ;
u32 ulbufsize ;
u32 i ;
struct cmd_ctrl_node * tempcmd_array ;
u8 * ptempvirtualaddr ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
/* Allocate and initialize cmdCtrlNode */
ulbufsize = sizeof ( struct cmd_ctrl_node ) * MRVDRV_NUM_OF_CMD_BUFFER ;
2007-05-25 11:58:22 -04:00
if ( ! ( tempcmd_array = kzalloc ( ulbufsize , GFP_KERNEL ) ) ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " ALLOC_CMD_BUF: tempcmd_array is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
adapter - > cmd_array = tempcmd_array ;
/* Allocate and initialize command buffers */
ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER ;
for ( i = 0 ; i < MRVDRV_NUM_OF_CMD_BUFFER ; i + + ) {
2007-05-25 11:58:22 -04:00
if ( ! ( ptempvirtualaddr = kzalloc ( ulbufsize , GFP_KERNEL ) ) ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " ALLOC_CMD_BUF: ptempvirtualaddr is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
/* Update command buffer virtual */
tempcmd_array [ i ] . bufvirtualaddr = ptempvirtualaddr ;
}
for ( i = 0 ; i < MRVDRV_NUM_OF_CMD_BUFFER ; i + + ) {
init_waitqueue_head ( & tempcmd_array [ i ] . cmdwait_q ) ;
2007-11-15 18:05:47 -05:00
lbs_cleanup_and_insert_cmd ( priv , & tempcmd_array [ i ] ) ;
2007-02-10 12:25:27 -02:00
}
ret = 0 ;
2007-05-25 11:27:16 -04:00
done :
2007-08-02 11:54:31 -04:00
lbs_deb_leave_args ( LBS_DEB_HOST , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
/**
* @ brief This function frees the command buffer .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ return 0 or - 1
*/
2007-11-23 15:43:44 +01:00
int lbs_free_cmd_buffer ( struct lbs_private * priv )
2007-02-10 12:25:27 -02:00
{
2007-05-25 23:36:54 -04:00
u32 ulbufsize ; /* Someone needs to die for this. Slowly and painfully */
2007-02-10 12:25:27 -02:00
unsigned int i ;
struct cmd_ctrl_node * tempcmd_array ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
/* need to check if cmd array is allocated or not */
if ( adapter - > cmd_array = = NULL ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " FREE_CMD_BUF: cmd_array is NULL \n " ) ;
2007-02-10 12:25:27 -02:00
goto done ;
}
tempcmd_array = adapter - > cmd_array ;
/* Release shared memory buffers */
ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER ;
for ( i = 0 ; i < MRVDRV_NUM_OF_CMD_BUFFER ; i + + ) {
if ( tempcmd_array [ i ] . bufvirtualaddr ) {
kfree ( tempcmd_array [ i ] . bufvirtualaddr ) ;
tempcmd_array [ i ] . bufvirtualaddr = NULL ;
}
}
/* Release cmd_ctrl_node */
if ( adapter - > cmd_array ) {
kfree ( adapter - > cmd_array ) ;
adapter - > cmd_array = NULL ;
}
done :
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
return 0 ;
}
/**
* @ brief This function gets a free command node if available in
* command free queue .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
*/
2007-12-05 17:58:06 +01:00
struct cmd_ctrl_node * lbs_get_cmd_ctrl_node ( struct lbs_private * priv )
2007-02-10 12:25:27 -02:00
{
struct cmd_ctrl_node * tempnode ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
unsigned long flags ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
if ( ! adapter )
return NULL ;
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( ! list_empty ( & adapter - > cmdfreeq ) ) {
2007-12-06 13:01:21 +01:00
tempnode = list_first_entry ( & adapter - > cmdfreeq ,
struct cmd_ctrl_node , list ) ;
list_del ( & tempnode - > list ) ;
2007-02-10 12:25:27 -02:00
} else {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " GET_CMD_NODE: cmd_ctrl_node is not available \n " ) ;
2007-02-10 12:25:27 -02:00
tempnode = NULL ;
}
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
2007-08-02 11:54:31 -04:00
if ( tempnode )
2007-02-10 12:25:27 -02:00
cleanup_cmdnode ( tempnode ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
return tempnode ;
}
/**
* @ brief This function cleans command node .
*
* @ param ptempnode A pointer to cmdCtrlNode structure
* @ return n / a
*/
static void cleanup_cmdnode ( struct cmd_ctrl_node * ptempnode )
{
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
if ( ! ptempnode )
return ;
ptempnode - > cmdwaitqwoken = 1 ;
wake_up_interruptible ( & ptempnode - > cmdwait_q ) ;
ptempnode - > wait_option = 0 ;
ptempnode - > pdata_buf = NULL ;
2007-12-07 15:13:05 +00:00
ptempnode - > callback = NULL ;
2007-02-10 12:25:27 -02:00
if ( ptempnode - > bufvirtualaddr ! = NULL )
memset ( ptempnode - > bufvirtualaddr , 0 , MRVDRV_SIZE_OF_CMD_BUFFER ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
}
/**
* @ brief This function initializes the command node .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ param ptempnode A pointer to cmd_ctrl_node structure
* @ param wait_option wait option : wait response or not
* @ param pdata_buf A pointer to informaion buffer
* @ return 0 or - 1
*/
2007-11-23 15:43:44 +01:00
void lbs_set_cmd_ctrl_node ( struct lbs_private * priv ,
2007-02-10 12:25:27 -02:00
struct cmd_ctrl_node * ptempnode ,
2007-12-01 15:15:41 +00:00
u16 wait_option , void * pdata_buf )
2007-02-10 12:25:27 -02:00
{
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
if ( ! ptempnode )
return ;
ptempnode - > wait_option = wait_option ;
ptempnode - > pdata_buf = pdata_buf ;
2007-12-07 15:13:05 +00:00
ptempnode - > callback = NULL ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
}
/**
* @ brief This function executes next command in command
* pending queue . It will put fimware back to PS mode
* if applicable .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ return 0 or - 1
*/
2007-11-23 15:43:44 +01:00
int lbs_execute_next_command ( struct lbs_private * priv )
2007-02-10 12:25:27 -02:00
{
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
struct cmd_ctrl_node * cmdnode = NULL ;
struct cmd_ds_command * cmdptr ;
unsigned long flags ;
int ret = 0 ;
2007-08-02 11:54:31 -04:00
// Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
2007-11-15 18:05:47 -05:00
// only caller to us is lbs_thread() and we get even when a
2007-08-02 11:54:31 -04:00
// data packet is received
lbs_deb_enter ( LBS_DEB_THREAD ) ;
2007-02-10 12:25:27 -02:00
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( adapter - > cur_cmd ) {
2007-08-02 11:54:31 -04:00
lbs_pr_alert ( " EXEC_NEXT_CMD: already processing command! \n " ) ;
2007-02-10 12:25:27 -02:00
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
ret = - 1 ;
goto done ;
}
if ( ! list_empty ( & adapter - > cmdpendingq ) ) {
2007-12-06 13:01:21 +01:00
cmdnode = list_first_entry ( & adapter - > cmdpendingq ,
struct cmd_ctrl_node , list ) ;
2007-02-10 12:25:27 -02:00
}
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
if ( cmdnode ) {
cmdptr = ( struct cmd_ds_command * ) cmdnode - > bufvirtualaddr ;
if ( is_command_allowed_in_ps ( cmdptr - > command ) ) {
2007-05-25 23:36:54 -04:00
if ( ( adapter - > psstate = = PS_STATE_SLEEP ) | |
( adapter - > psstate = = PS_STATE_PRE_SLEEP ) ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host (
" EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( cmdptr - > command ) ,
adapter - > psstate ) ;
2007-02-10 12:25:27 -02:00
ret = - 1 ;
goto done ;
}
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " EXEC_NEXT_CMD: OK to send command "
" 0x%04x in psstate %d \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( cmdptr - > command ) ,
adapter - > psstate ) ;
2007-02-10 12:25:27 -02:00
} else if ( adapter - > psstate ! = PS_STATE_FULL_POWER ) {
/*
* 1. Non - PS command :
* Queue it . set needtowakeup to TRUE if current state
2007-11-15 18:05:47 -05:00
* is SLEEP , otherwise call lbs_ps_wakeup to send Exit_PS .
2007-02-10 12:25:27 -02:00
* 2. PS command but not Exit_PS :
* Ignore it .
* 3. PS command Exit_PS :
* Set needtowakeup to TRUE if current state is SLEEP ,
* otherwise send this command down to firmware
* immediately .
*/
if ( cmdptr - > command ! =
2007-08-02 11:31:18 -04:00
cpu_to_le16 ( CMD_802_11_PS_MODE ) ) {
2007-02-10 12:25:27 -02:00
/* Prepare to send Exit PS,
* this non PS command will be sent later */
if ( ( adapter - > psstate = = PS_STATE_SLEEP )
| | ( adapter - > psstate = = PS_STATE_PRE_SLEEP )
) {
/* w/ new scheme, it will not reach here.
since it is blocked in main_thread . */
adapter - > needtowakeup = 1 ;
} else
2007-11-15 18:05:47 -05:00
lbs_ps_wakeup ( priv , 0 ) ;
2007-02-10 12:25:27 -02:00
ret = 0 ;
goto done ;
} else {
/*
* PS command . Ignore it if it is not Exit_PS .
* otherwise send it down immediately .
*/
struct cmd_ds_802_11_ps_mode * psm =
& cmdptr - > params . psmode ;
2007-08-02 11:54:31 -04:00
lbs_deb_host (
" EXEC_NEXT_CMD: PS cmd, action 0x%02x \n " ,
2007-02-10 12:25:27 -02:00
psm - > action ) ;
if ( psm - > action ! =
2007-08-02 11:31:18 -04:00
cpu_to_le16 ( CMD_SUBCMD_EXIT_PS ) ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host (
" EXEC_NEXT_CMD: ignore ENTER_PS cmd \n " ) ;
2007-12-06 13:01:21 +01:00
list_del ( & cmdnode - > list ) ;
2007-11-15 18:05:47 -05:00
lbs_cleanup_and_insert_cmd ( priv , cmdnode ) ;
2007-02-10 12:25:27 -02:00
ret = 0 ;
goto done ;
}
2007-05-25 23:36:54 -04:00
if ( ( adapter - > psstate = = PS_STATE_SLEEP ) | |
( adapter - > psstate = = PS_STATE_PRE_SLEEP ) ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host (
" EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep \n " ) ;
2007-12-06 13:01:21 +01:00
list_del ( & cmdnode - > list ) ;
2007-11-15 18:05:47 -05:00
lbs_cleanup_and_insert_cmd ( priv , cmdnode ) ;
2007-02-10 12:25:27 -02:00
adapter - > needtowakeup = 1 ;
ret = 0 ;
goto done ;
}
2007-08-02 11:54:31 -04:00
lbs_deb_host (
" EXEC_NEXT_CMD: sending EXIT_PS \n " ) ;
2007-02-10 12:25:27 -02:00
}
}
2007-12-06 13:01:21 +01:00
list_del ( & cmdnode - > list ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " EXEC_NEXT_CMD: sending command 0x%04x \n " ,
2007-05-25 23:36:54 -04:00
le16_to_cpu ( cmdptr - > command ) ) ;
2007-02-10 12:25:27 -02:00
DownloadcommandToStation ( priv , cmdnode ) ;
} else {
/*
* check if in power save mode , if yes , put the device back
* to PS mode
*/
2007-11-15 18:05:47 -05:00
if ( ( adapter - > psmode ! = LBS802_11POWERMODECAM ) & &
2007-02-10 12:25:27 -02:00
( adapter - > psstate = = PS_STATE_FULL_POWER ) & &
2007-11-20 17:44:14 -05:00
( ( adapter - > connect_status = = LBS_CONNECTED ) | |
( adapter - > mesh_connect_status = = LBS_CONNECTED ) ) ) {
2007-05-25 23:36:54 -04:00
if ( adapter - > secinfo . WPAenabled | |
adapter - > secinfo . WPA2enabled ) {
2007-02-10 12:25:27 -02:00
/* check for valid WPA group keys */
2007-05-25 23:36:54 -04:00
if ( adapter - > wpa_mcast_key . len | |
adapter - > wpa_unicast_key . len ) {
2007-08-02 11:54:31 -04:00
lbs_deb_host (
2007-02-10 12:25:27 -02:00
" EXEC_NEXT_CMD: WPA enabled and GTK_SET "
" go back to PS_SLEEP " ) ;
2007-11-15 18:05:47 -05:00
lbs_ps_sleep ( priv , 0 ) ;
2007-02-10 12:25:27 -02:00
}
} else {
2007-08-02 11:54:31 -04:00
lbs_deb_host (
" EXEC_NEXT_CMD: cmdpendingq empty, "
" go back to PS_SLEEP " ) ;
2007-11-15 18:05:47 -05:00
lbs_ps_sleep ( priv , 0 ) ;
2007-02-10 12:25:27 -02:00
}
}
}
ret = 0 ;
done :
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_THREAD ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-23 15:43:44 +01:00
void lbs_send_iwevcustom_event ( struct lbs_private * priv , s8 * str )
2007-02-10 12:25:27 -02:00
{
union iwreq_data iwrq ;
u8 buf [ 50 ] ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_WEXT ) ;
2007-02-10 12:25:27 -02:00
memset ( & iwrq , 0 , sizeof ( union iwreq_data ) ) ;
memset ( buf , 0 , sizeof ( buf ) ) ;
snprintf ( buf , sizeof ( buf ) - 1 , " %s " , str ) ;
iwrq . data . length = strlen ( buf ) + 1 + IW_EV_LCP_LEN ;
/* Send Event to upper layer */
2007-08-02 11:54:31 -04:00
lbs_deb_wext ( " event indication string %s \n " , ( char * ) buf ) ;
lbs_deb_wext ( " event indication length %d \n " , iwrq . data . length ) ;
lbs_deb_wext ( " sending wireless event IWEVCUSTOM for %s \n " , str ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 13:05:16 -04:00
wireless_send_event ( priv - > dev , IWEVCUSTOM , & iwrq , buf ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_WEXT ) ;
2007-02-10 12:25:27 -02:00
}
2007-11-23 15:43:44 +01:00
static int sendconfirmsleep ( struct lbs_private * priv , u8 * cmdptr , u16 size )
2007-02-10 12:25:27 -02:00
{
unsigned long flags ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
int ret = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " SEND_SLEEPC_CMD: before download, cmd size %d \n " ,
2007-02-10 12:25:27 -02:00
size ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_hex ( LBS_DEB_HOST , " sleep confirm command " , cmdptr , size ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 12:17:06 -04:00
ret = priv - > hw_host_to_card ( priv , MVMS_CMD , cmdptr , size ) ;
2007-05-25 13:05:16 -04:00
priv - > dnld_sent = DNLD_RES_RECEIVED ;
2007-02-10 12:25:27 -02:00
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( adapter - > intcounter | | adapter - > currenttxskb )
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p \n " ,
2007-02-10 12:25:27 -02:00
adapter - > intcounter , adapter - > currenttxskb ) ;
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
if ( ret ) {
lbs_pr_alert (
" SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep \n " ) ;
} else {
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( ! adapter - > intcounter ) {
adapter - > psstate = PS_STATE_SLEEP ;
} else {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " SEND_SLEEPC_CMD: after sent, intcounter %d \n " ,
2007-02-10 12:25:27 -02:00
adapter - > intcounter ) ;
}
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " SEND_SLEEPC_CMD: sent confirm sleep \n " ) ;
2007-02-10 12:25:27 -02:00
}
2007-08-02 11:54:31 -04:00
lbs_deb_leave_args ( LBS_DEB_HOST , " ret %d " , ret ) ;
2007-02-10 12:25:27 -02:00
return ret ;
}
2007-11-23 15:43:44 +01:00
void lbs_ps_sleep ( struct lbs_private * priv , int wait_option )
2007-02-10 12:25:27 -02:00
{
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
/*
* PS is currently supported only in Infrastructure mode
* Remove this check if it is to be supported in IBSS mode also
*/
2007-11-15 18:05:47 -05:00
lbs_prepare_and_send_command ( priv , CMD_802_11_PS_MODE ,
2007-08-02 11:31:18 -04:00
CMD_SUBCMD_ENTER_PS , wait_option , 0 , NULL ) ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
}
/**
2007-08-02 11:54:31 -04:00
* @ brief This function sends Exit_PS command to firmware .
2007-02-10 12:25:27 -02:00
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ param wait_option wait response or not
* @ return n / a
*/
2007-11-23 15:43:44 +01:00
void lbs_ps_wakeup ( struct lbs_private * priv , int wait_option )
2007-02-10 12:25:27 -02:00
{
2007-05-25 23:36:54 -04:00
__le32 Localpsmode ;
2007-02-10 12:25:27 -02:00
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
2007-11-15 18:05:47 -05:00
Localpsmode = cpu_to_le32 ( LBS802_11POWERMODECAM ) ;
2007-02-10 12:25:27 -02:00
2007-11-15 18:05:47 -05:00
lbs_prepare_and_send_command ( priv , CMD_802_11_PS_MODE ,
2007-08-02 11:31:18 -04:00
CMD_SUBCMD_EXIT_PS ,
2007-02-10 12:25:27 -02:00
wait_option , 0 , & Localpsmode ) ;
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
}
/**
* @ brief This function checks condition and prepares to
* send sleep confirm command to firmware if ok .
*
2007-11-23 15:43:44 +01:00
* @ param priv A pointer to struct lbs_private structure
2007-02-10 12:25:27 -02:00
* @ param psmode Power Saving mode
* @ return n / a
*/
2007-11-23 15:43:44 +01:00
void lbs_ps_confirm_sleep ( struct lbs_private * priv , u16 psmode )
2007-02-10 12:25:27 -02:00
{
unsigned long flags = 0 ;
2007-11-23 15:43:44 +01:00
struct lbs_adapter * adapter = priv - > adapter ;
2007-02-10 12:25:27 -02:00
u8 allowed = 1 ;
2007-08-02 11:54:31 -04:00
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
2007-05-25 13:05:16 -04:00
if ( priv - > dnld_sent ) {
2007-02-10 12:25:27 -02:00
allowed = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " dnld_sent was set " ) ;
2007-02-10 12:25:27 -02:00
}
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( adapter - > cur_cmd ) {
allowed = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " cur_cmd was set " ) ;
2007-02-10 12:25:27 -02:00
}
if ( adapter - > intcounter > 0 ) {
allowed = 0 ;
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " intcounter %d " , adapter - > intcounter ) ;
2007-02-10 12:25:27 -02:00
}
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
if ( allowed ) {
2007-11-15 18:05:47 -05:00
lbs_deb_host ( " sending lbs_ps_confirm_sleep \n " ) ;
sendconfirmsleep ( priv , ( u8 * ) & adapter - > lbs_ps_confirm_sleep ,
2007-02-10 12:25:27 -02:00
sizeof ( struct PS_CMD_ConfirmSleep ) ) ;
} else {
2007-08-02 11:54:31 -04:00
lbs_deb_host ( " sleep confirm has been delayed \n " ) ;
2007-02-10 12:25:27 -02:00
}
2007-08-02 11:54:31 -04:00
lbs_deb_leave ( LBS_DEB_HOST ) ;
2007-02-10 12:25:27 -02:00
}
2007-12-05 17:58:11 +01:00
/**
* @ brief Simple way to call firmware functions
*
* @ param priv A pointer to struct lbs_private structure
* @ param psmode one of the many CMD_802_11_xxxx
* @ param cmd pointer to the parameters structure for above command
* ( this should not include the command , size , sequence
* and result fields from struct cmd_ds_gen )
* @ param cmd_size size structure pointed to by cmd
* @ param rsp pointer to an area where the result should be placed
* @ param rsp_size pointer to the size of the rsp area . If the firmware
* returns fewer bytes , then this * rsp_size will be
* changed to the actual size .
* @ return - 1 in case of a higher level error , otherwise
* the result code from the firmware
*/
2007-12-07 15:13:05 +00:00
2007-12-08 00:59:54 +00:00
int lbs_cmd ( struct lbs_private * priv , uint16_t command , void * cmd , int cmd_size ,
int ( * callback ) ( uint16_t , struct cmd_ds_command * , struct lbs_private * ) )
2007-12-05 17:58:11 +01:00
{
struct lbs_adapter * adapter = priv - > adapter ;
struct cmd_ctrl_node * cmdnode ;
struct cmd_ds_gen * cmdptr ;
unsigned long flags ;
int ret = 0 ;
lbs_deb_enter ( LBS_DEB_HOST ) ;
2007-12-08 00:59:54 +00:00
if ( ! adapter ) {
2007-12-05 17:58:11 +01:00
lbs_deb_host ( " PREP_CMD: adapter is NULL \n " ) ;
ret = - 1 ;
goto done ;
}
if ( adapter - > surpriseremoved ) {
lbs_deb_host ( " PREP_CMD: card removed \n " ) ;
ret = - 1 ;
goto done ;
}
cmdnode = lbs_get_cmd_ctrl_node ( priv ) ;
if ( cmdnode = = NULL ) {
lbs_deb_host ( " PREP_CMD: cmdnode is NULL \n " ) ;
/* Wake up main thread to execute next command */
wake_up_interruptible ( & priv - > waitq ) ;
ret = - 1 ;
goto done ;
}
cmdptr = ( struct cmd_ds_gen * ) cmdnode - > bufvirtualaddr ;
cmdnode - > wait_option = CMD_OPTION_WAITFORRSP ;
2007-12-08 00:59:54 +00:00
cmdnode - > callback = callback ;
2007-12-05 17:58:11 +01:00
/* Set sequence number, clean result, move to buffer */
adapter - > seqnum + + ;
cmdptr - > command = cpu_to_le16 ( command ) ;
2007-12-06 12:38:31 +00:00
cmdptr - > size = cpu_to_le16 ( cmd_size + S_DS_GEN ) ;
2007-12-05 17:58:11 +01:00
cmdptr - > seqnum = cpu_to_le16 ( adapter - > seqnum ) ;
cmdptr - > result = 0 ;
memcpy ( cmdptr - > cmdresp , cmd , cmd_size ) ;
lbs_deb_host ( " PREP_CMD: command 0x%04x \n " , command ) ;
/* here was the big old switch() statement, which is now obsolete,
* because the caller of lbs_cmd ( ) sets up all of * cmd for us . */
cmdnode - > cmdwaitqwoken = 0 ;
lbs_queue_cmd ( adapter , cmdnode , 1 ) ;
wake_up_interruptible ( & priv - > waitq ) ;
might_sleep ( ) ;
wait_event_interruptible ( cmdnode - > cmdwait_q , cmdnode - > cmdwaitqwoken ) ;
spin_lock_irqsave ( & adapter - > driver_lock , flags ) ;
if ( adapter - > cur_cmd_retcode ) {
lbs_deb_host ( " PREP_CMD: command failed with return code %d \n " ,
adapter - > cur_cmd_retcode ) ;
adapter - > cur_cmd_retcode = 0 ;
ret = - 1 ;
}
spin_unlock_irqrestore ( & adapter - > driver_lock , flags ) ;
done :
lbs_deb_leave_args ( LBS_DEB_HOST , " ret %d " , ret ) ;
return ret ;
}
EXPORT_SYMBOL_GPL ( lbs_cmd ) ;