2017-05-11 18:47:23 +00:00
/******************************************************************************
*
2019-11-09 10:12:08 +00:00
* Copyright ( c ) 2007 - 2017 Realtek Corporation .
2017-05-11 18:47:23 +00:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
2019-11-09 10:12:08 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-05-11 18:47:23 +00:00
# if defined(CONFIG_MP_INCLUDED)
# include <drv_types.h>
# include <rtw_mp.h>
# include <rtw_mp_ioctl.h>
# include "../../hal/phydm/phydm_precomp.h"
# if defined(CONFIG_RTL8723B)
2019-11-09 10:12:08 +00:00
# include <rtw_bt_mp.h>
2017-05-11 18:47:23 +00:00
# endif
2020-10-31 15:54:15 +00:00
# define RTW_IWD_MAX_LEN 128
inline u8 rtw_do_mp_iwdata_len_chk ( const char * caller , u32 len )
{
u8 is_illegal = _FALSE ;
if ( len > = RTW_IWD_MAX_LEN ) {
RTW_ERR ( " %s : iw data len(%u) > RTW_IWD_MAX_LEN(%u) " ,
caller , len , RTW_IWD_MAX_LEN ) ;
is_illegal = _TRUE ;
}
return is_illegal ;
}
2017-05-11 18:47:23 +00:00
/*
* Input Format : % s , % d , % d
* % s is width , could be
* " b " for 1 byte
* " w " for WORD ( 2 bytes )
* " dw " for DWORD ( 4 bytes )
* 1 st % d is address ( offset )
* 2 st % d is data to write
*/
int rtw_mp_write_reg ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
char * pch , * pnext ;
2017-05-11 18:47:23 +00:00
char * width_str ;
2019-11-09 10:12:08 +00:00
char width ;
2017-05-11 18:47:23 +00:00
u32 addr , data ;
int ret ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
pch = input ;
pnext = strpbrk ( pch , " ,.- " ) ;
if ( pnext = = NULL )
return - EINVAL ;
* pnext = 0 ;
width_str = pch ;
pch = pnext + 1 ;
pnext = strpbrk ( pch , " ,.- " ) ;
if ( pnext = = NULL )
return - EINVAL ;
* pnext = 0 ;
/*addr = simple_strtoul(pch, &ptmp, 16);
_rtw_memset ( buf , ' \0 ' , sizeof ( buf ) ) ;
_rtw_memcpy ( buf , pch , pnext - pch ) ;
ret = kstrtoul ( buf , 16 , & addr ) ; */
ret = sscanf ( pch , " %x " , & addr ) ;
if ( addr > 0x3FFF )
return - EINVAL ;
pch = pnext + 1 ;
pnext = strpbrk ( pch , " ,.- " ) ;
if ( ( pch - input ) > = wrqu - > length )
return - EINVAL ;
/*data = simple_strtoul(pch, &ptmp, 16);*/
ret = sscanf ( pch , " %x " , & data ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " data=%x,addr=%x \n " , ( u32 ) data , ( u32 ) addr ) ;
2017-05-11 18:47:23 +00:00
ret = 0 ;
width = width_str [ 0 ] ;
switch ( width ) {
case ' b ' :
/* 1 byte*/
if ( data > 0xFF ) {
ret = - EINVAL ;
break ;
}
rtw_write8 ( padapter , addr , data ) ;
break ;
case ' w ' :
/* 2 bytes*/
if ( data > 0xFFFF ) {
ret = - EINVAL ;
break ;
}
rtw_write16 ( padapter , addr , data ) ;
break ;
case ' d ' :
/* 4 bytes*/
rtw_write32 ( padapter , addr , data ) ;
break ;
default :
ret = - EINVAL ;
break ;
}
return ret ;
}
/*
* Input Format : % s , % d
* % s is width , could be
* " b " for 1 byte
* " w " for WORD ( 2 bytes )
* " dw " for DWORD ( 4 bytes )
* % d is address ( offset )
*
* Return :
* % d for data readed
*/
int rtw_mp_read_reg ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2019-11-09 10:12:08 +00:00
char * pch , * pnext ;
2017-05-11 18:47:23 +00:00
char * width_str ;
char width ;
2019-11-09 10:12:08 +00:00
char data [ 20 ] , tmp [ 20 ] ;
2017-05-11 18:47:23 +00:00
u32 addr = 0 , strtout = 0 ;
u32 i = 0 , j = 0 , ret = 0 , data32 = 0 ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
char * pextra = extra ;
2017-05-11 18:47:23 +00:00
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( wrqu - > length > 128 )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
_rtw_memset ( data , ' \0 ' , sizeof ( data ) ) ;
_rtw_memset ( tmp , ' \0 ' , sizeof ( tmp ) ) ;
pch = input ;
pnext = strpbrk ( pch , " ,.- " ) ;
if ( pnext = = NULL )
return - EINVAL ;
* pnext = 0 ;
width_str = pch ;
pch = pnext + 1 ;
ret = sscanf ( pch , " %x " , & addr ) ;
if ( addr > 0x3FFF )
return - EINVAL ;
ret = 0 ;
width = width_str [ 0 ] ;
switch ( width ) {
case ' b ' :
2019-11-09 10:12:08 +00:00
data32 = rtw_read8 ( padapter , addr ) ;
RTW_INFO ( " %x \n " , data32 ) ;
sprintf ( extra , " %d " , data32 ) ;
wrqu - > length = strlen ( extra ) ;
break ;
2017-05-11 18:47:23 +00:00
case ' w ' :
2019-11-09 10:12:08 +00:00
/* 2 bytes*/
sprintf ( data , " %04x \n " , rtw_read16 ( padapter , addr ) ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
for ( i = 0 ; i < = strlen ( data ) ; i + + ) {
if ( i % 2 = = 0 ) {
tmp [ j ] = ' ' ;
2017-05-11 18:47:23 +00:00
j + + ;
}
2019-11-09 10:12:08 +00:00
if ( data [ i ] ! = ' \0 ' )
tmp [ j ] = data [ i ] ;
j + + ;
}
pch = tmp ;
RTW_INFO ( " pch=%s " , pch ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
while ( * pch ! = ' \0 ' ) {
pnext = strpbrk ( pch , " " ) ;
if ( ! pnext | | ( ( pnext - tmp ) > 4 ) )
break ;
pnext + + ;
if ( * pnext ! = ' \0 ' ) {
/*strtout = simple_strtoul(pnext , &ptmp, 16);*/
ret = sscanf ( pnext , " %x " , & strtout ) ;
pextra + = sprintf ( pextra , " %d " , strtout ) ;
} else
break ;
pch = pnext ;
}
wrqu - > length = strlen ( extra ) ;
break ;
case ' d ' :
/* 4 bytes */
sprintf ( data , " %08x " , rtw_read32 ( padapter , addr ) ) ;
/*add read data format blank*/
for ( i = 0 ; i < = strlen ( data ) ; i + + ) {
if ( i % 2 = = 0 ) {
tmp [ j ] = ' ' ;
2017-05-11 18:47:23 +00:00
j + + ;
}
2019-11-09 10:12:08 +00:00
if ( data [ i ] ! = ' \0 ' )
tmp [ j ] = data [ i ] ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
j + + ;
2017-05-11 18:47:23 +00:00
}
2019-11-09 10:12:08 +00:00
pch = tmp ;
RTW_INFO ( " pch=%s " , pch ) ;
while ( * pch ! = ' \0 ' ) {
pnext = strpbrk ( pch , " " ) ;
if ( ! pnext )
break ;
pnext + + ;
if ( * pnext ! = ' \0 ' ) {
ret = sscanf ( pnext , " %x " , & strtout ) ;
pextra + = sprintf ( pextra , " %d " , strtout ) ;
} else
break ;
pch = pnext ;
}
wrqu - > length = strlen ( extra ) ;
break ;
default :
wrqu - > length = 0 ;
ret = - EINVAL ;
break ;
}
2017-05-11 18:47:23 +00:00
return ret ;
}
/*
* Input Format : % d , % x , % x
* % d is RF path , should be smaller than MAX_RF_PATH_NUMS
* 1 st % x is address ( offset )
* 2 st % x is data to write
*/
int rtw_mp_write_rf ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u32 path , addr , data ;
int ret ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > l ength ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
_rtw_memset ( input , 0 , wrqu - > length ) ;
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
ret = sscanf ( input , " %d,%x,%x " , & path , & addr , & data ) ;
if ( ret < 3 )
return - EINVAL ;
if ( path > = GET_HAL_RFPATH_NUM ( padapter ) )
return - EINVAL ;
if ( addr > 0xFF )
return - EINVAL ;
if ( data > 0xFFFFF )
return - EINVAL ;
_rtw_memset ( extra , 0 , wrqu - > length ) ;
write_rfreg ( padapter , path , addr , data ) ;
sprintf ( extra , " write_rf completed \n " ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
/*
* Input Format : % d , % x
* % d is RF path , should be smaller than MAX_RF_PATH_NUMS
* % x is address ( offset )
*
* Return :
* % d for data readed
*/
int rtw_mp_read_rf ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2019-11-09 10:12:08 +00:00
char * pch , * pnext ;
char data [ 20 ] , tmp [ 20 ] ;
2017-05-11 18:47:23 +00:00
u32 path , addr , strtou ;
u32 ret , i = 0 , j = 0 ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
char * pextra = extra ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( wrqu - > length > 128 )
return - EFAULT ;
_rtw_memset ( input , 0 , wrqu - > length ) ;
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
ret = sscanf ( input , " %d,%x " , & path , & addr ) ;
if ( ret < 2 )
return - EINVAL ;
if ( path > = GET_HAL_RFPATH_NUM ( padapter ) )
return - EINVAL ;
if ( addr > 0xFF )
return - EINVAL ;
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( data , " %08x " , read_rfreg ( padapter , path , addr ) ) ;
/*add read data format blank*/
for ( i = 0 ; i < = strlen ( data ) ; i + + ) {
if ( i % 2 = = 0 ) {
tmp [ j ] = ' ' ;
j + + ;
}
tmp [ j ] = data [ i ] ;
j + + ;
}
pch = tmp ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " pch=%s " , pch ) ;
2017-05-11 18:47:23 +00:00
while ( * pch ! = ' \0 ' ) {
pnext = strpbrk ( pch , " " ) ;
if ( ! pnext )
break ;
pnext + + ;
if ( * pnext ! = ' \0 ' ) {
/*strtou =simple_strtoul(pnext , &ptmp, 16);*/
ret = sscanf ( pnext , " %x " , & strtou ) ;
2019-11-09 10:12:08 +00:00
pextra + = sprintf ( pextra , " %d " , strtou ) ;
2017-05-11 18:47:23 +00:00
} else
break ;
pch = pnext ;
}
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_start ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
int ret = 0 ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
rtw_pm_set_ips ( padapter , IPS_NONE ) ;
LeaveAllPowerSaveMode ( padapter ) ;
2019-11-09 10:12:08 +00:00
if ( rtw_mi_check_fwstate ( padapter , _FW_UNDER_SURVEY ) )
rtw_mi_scan_abort ( padapter , _FALSE ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
if ( rtw_mp_cmd ( padapter , MP_START , RTW_CMDF_WAIT_ACK ) ! = _SUCCESS )
ret = - EPERM ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " mp_start %s \n " , ret = = 0 ? " ok " : " fail " ) ;
wrqu - > length = strlen ( extra ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
return ret ;
2017-05-11 18:47:23 +00:00
}
int rtw_mp_stop ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
int ret = 0 ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
if ( rtw_mp_cmd ( padapter , MP_STOP , RTW_CMDF_WAIT_ACK ) ! = _SUCCESS )
ret = - EPERM ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " mp_stop %s \n " , ret = = 0 ? " ok " : " fail " ) ;
wrqu - > length = strlen ( extra ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
return ret ;
2017-05-11 18:47:23 +00:00
}
int rtw_mp_rate ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u32 rate = MPT_RATE_1M ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
PMPT_CONTEXT pMptCtx = & ( padapter - > mppriv . mpt_ctx ) ;
2017-05-11 18:47:23 +00:00
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
rate = rtw_mpRateParseFunc ( padapter , input ) ;
padapter - > mppriv . rateidx = rate ;
if ( rate = = 0 & & strcmp ( input , " 1M " ) ! = 0 ) {
rate = rtw_atoi ( input ) ;
padapter - > mppriv . rateidx = MRateToHwRate ( rate ) ;
/*if (rate <= 0x7f)
rate = wifirate2_ratetbl_inx ( ( u8 ) rate ) ;
else if ( rate < 0xC8 )
rate = ( rate - 0x79 + MPT_RATE_MCS0 ) ;
HT rate 0x80 ( MCS0 ) ~ 0x8F ( MCS15 ) ~ 0x9F ( MCS31 ) 128 ~ 159
VHT1SS ~ 2 SS rate 0xA0 ( VHT1SS_MCS0 44 ) ~ 0xB3 ( VHT2SS_MCS9 # 63 ) 160 ~ 179
VHT rate 0xB4 ( VHT3SS_MCS0 64 ) ~ 0xC7 ( VHT2SS_MCS9 # 83 ) 180 ~ 199
else
VHT rate 0x90 ( VHT1SS_MCS0 ) ~ 0x99 ( VHT1SS_MCS9 ) 144 ~ 153
rate = ( rate - MPT_RATE_VHT1SS_MCS0 ) ;
*/
}
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " Set data rate to %s index %d " , input , padapter - > mppriv . rateidx ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: %s rate index=%d \n " , __func__ , input , padapter - > mppriv . rateidx ) ;
2017-05-11 18:47:23 +00:00
if ( padapter - > mppriv . rateidx > = DESC_RATEVHTSS4MCS9 )
return - EINVAL ;
2019-11-09 10:12:08 +00:00
pMptCtx - > mpt_rate_index = HwRateToMPTRate ( padapter - > mppriv . rateidx ) ;
2017-05-11 18:47:23 +00:00
SetDataRate ( padapter ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_channel ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
u32 channel = 1 ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
channel = rtw_atoi ( input ) ;
2019-11-09 10:12:08 +00:00
/*RTW_INFO("%s: channel=%d\n", __func__, channel);*/
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " Change channel %d to channel %d " , padapter - > mppriv . channel , channel ) ;
padapter - > mppriv . channel = channel ;
SetChannel ( padapter ) ;
2019-11-09 10:12:08 +00:00
pHalData - > current_channel = channel ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_ch_offset ( struct net_device * dev ,
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2019-11-09 10:12:08 +00:00
u32 ch_offset = 0 ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
input [ wrqu - > length ] = ' \0 ' ;
ch_offset = rtw_atoi ( input ) ;
/*RTW_INFO("%s: channel=%d\n", __func__, channel);*/
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " Change prime channel offset %d to %d " , padapter - > mppriv . prime_channel_offset , ch_offset ) ;
padapter - > mppriv . prime_channel_offset = ch_offset ;
SetChannel ( padapter ) ;
2017-05-11 18:47:23 +00:00
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_bandwidth ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u32 bandwidth = 0 , sg = 0 ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
if ( sscanf ( input , " 40M=%d,shortGI=%d " , & bandwidth , & sg ) > 0 )
RTW_INFO ( " %s: bw=%d sg=%d \n " , __func__ , bandwidth , sg ) ;
2017-05-11 18:47:23 +00:00
if ( bandwidth = = 1 )
bandwidth = CHANNEL_WIDTH_40 ;
else if ( bandwidth = = 2 )
bandwidth = CHANNEL_WIDTH_80 ;
padapter - > mppriv . bandwidth = ( u8 ) bandwidth ;
padapter - > mppriv . preamble = sg ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " Change BW %d to BW %d \n " , pHalData - > current_channel_bw , bandwidth ) ;
2017-05-11 18:47:23 +00:00
SetBandwidth ( padapter ) ;
2019-11-09 10:12:08 +00:00
pHalData - > current_channel_bw = bandwidth ;
wrqu - > length = strlen ( extra ) ;
2017-05-11 18:47:23 +00:00
return 0 ;
}
int rtw_mp_txpower_index ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
HAL_DATA_TYPE * phal_data = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
u32 rfpath ;
u32 txpower_inx ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( wrqu - > length > 128 )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
if ( wrqu - > length = = 2 ) {
rfpath = rtw_atoi ( input ) ;
txpower_inx = mpt_ProQueryCalTxPower ( padapter , rfpath ) ;
sprintf ( extra , " %d " , txpower_inx ) ;
} else {
2021-02-06 10:06:22 +00:00
char * pextra = extra ;
2019-11-09 10:12:08 +00:00
txpower_inx = mpt_ProQueryCalTxPower ( padapter , 0 ) ;
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( extra , " patha=%d " , txpower_inx ) ;
2019-11-09 10:12:08 +00:00
if ( phal_data - > rf_type > RF_1T2R ) {
txpower_inx = mpt_ProQueryCalTxPower ( padapter , 1 ) ;
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " ,pathb=%d " , txpower_inx ) ;
2019-11-09 10:12:08 +00:00
}
if ( phal_data - > rf_type > RF_2T4R ) {
txpower_inx = mpt_ProQueryCalTxPower ( padapter , 2 ) ;
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " ,pathc=%d " , txpower_inx ) ;
2019-11-09 10:12:08 +00:00
}
if ( phal_data - > rf_type > RF_3T4R ) {
txpower_inx = mpt_ProQueryCalTxPower ( padapter , 3 ) ;
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " ,pathd=%d " , txpower_inx ) ;
2019-11-09 10:12:08 +00:00
}
}
2017-05-11 18:47:23 +00:00
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_txpower ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
u32 idx_a = 0 , idx_b = 0 , idx_c = 0 , idx_d = 0 ;
2017-05-11 18:47:23 +00:00
int MsetPower = 1 ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
PMPT_CONTEXT pMptCtx = & ( padapter - > mppriv . mpt_ctx ) ;
2017-05-11 18:47:23 +00:00
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
MsetPower = strncmp ( input , " off " , 3 ) ;
if ( MsetPower = = 0 ) {
padapter - > mppriv . bSetTxPower = 0 ;
sprintf ( extra , " MP Set power off " ) ;
} else {
if ( sscanf ( input , " patha=%d,pathb=%d,pathc=%d,pathd=%d " , & idx_a , & idx_b , & idx_c , & idx_d ) < 3 )
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Invalid format on line %s ,patha=%d,pathb=%d,pathc=%d,pathd=%d \n " , input , idx_a , idx_b , idx_c , idx_d ) ;
2017-05-11 18:47:23 +00:00
sprintf ( extra , " Set power level path_A:%d path_B:%d path_C:%d path_D:%d " , idx_a , idx_b , idx_c , idx_d ) ;
padapter - > mppriv . txpoweridx = ( u8 ) idx_a ;
2019-11-09 10:12:08 +00:00
pMptCtx - > TxPwrLevel [ RF_PATH_A ] = ( u8 ) idx_a ;
pMptCtx - > TxPwrLevel [ RF_PATH_B ] = ( u8 ) idx_b ;
pMptCtx - > TxPwrLevel [ RF_PATH_C ] = ( u8 ) idx_c ;
pMptCtx - > TxPwrLevel [ RF_PATH_D ] = ( u8 ) idx_d ;
2017-05-11 18:47:23 +00:00
padapter - > mppriv . bSetTxPower = 1 ;
SetTxPower ( padapter ) ;
}
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_ant_tx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u8 i ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
u16 antenna = 0 ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
sprintf ( extra , " switch Tx antenna to %s " , input ) ;
for ( i = 0 ; i < strlen ( input ) ; i + + ) {
switch ( input [ i ] ) {
case ' a ' :
antenna | = ANTENNA_A ;
break ;
case ' b ' :
antenna | = ANTENNA_B ;
break ;
case ' c ' :
antenna | = ANTENNA_C ;
break ;
case ' d ' :
antenna | = ANTENNA_D ;
break ;
}
}
/*antenna |= BIT(extra[i]-'a');*/
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: antenna=0x%x \n " , __func__ , antenna ) ;
2017-05-11 18:47:23 +00:00
padapter - > mppriv . antenna_tx = antenna ;
padapter - > mppriv . antenna_rx = antenna ;
2019-11-09 10:12:08 +00:00
/*RTW_INFO("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx);*/
pHalData - > antenna_tx_path = antenna ;
2017-05-11 18:47:23 +00:00
SetAntenna ( padapter ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_ant_rx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u8 i ;
u16 antenna = 0 ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
/*RTW_INFO("%s: input=%s\n", __func__, input);*/
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " switch Rx antenna to %s " , input ) ;
for ( i = 0 ; i < strlen ( input ) ; i + + ) {
switch ( input [ i ] ) {
case ' a ' :
antenna | = ANTENNA_A ;
break ;
case ' b ' :
antenna | = ANTENNA_B ;
break ;
case ' c ' :
antenna | = ANTENNA_C ;
break ;
case ' d ' :
antenna | = ANTENNA_D ;
break ;
}
}
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: antenna=0x%x \n " , __func__ , antenna ) ;
2017-05-11 18:47:23 +00:00
padapter - > mppriv . antenna_tx = antenna ;
padapter - > mppriv . antenna_rx = antenna ;
pHalData - > AntennaRxPath = antenna ;
2019-11-09 10:12:08 +00:00
/*RTW_INFO("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);*/
2017-05-11 18:47:23 +00:00
SetAntenna ( padapter ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_set_ctx_destAddr ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
int jj , kk = 0 ;
struct pkt_attrib * pattrib ;
struct mp_priv * pmp_priv ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
2017-05-11 18:47:23 +00:00
pmp_priv = & padapter - > mppriv ;
pattrib = & pmp_priv - > tx . attrib ;
if ( strlen ( extra ) < 5 )
return _FAIL ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: in=%s \n " , __func__ , extra ) ;
2017-05-11 18:47:23 +00:00
for ( jj = 0 , kk = 0 ; jj < ETH_ALEN ; jj + + , kk + = 3 )
pattrib - > dst [ jj ] = key_2char2num ( extra [ kk ] , extra [ kk + 1 ] ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " pattrib->dst:%x %x %x %x %x %x \n " , pattrib - > dst [ 0 ] , pattrib - > dst [ 1 ] , pattrib - > dst [ 2 ] , pattrib - > dst [ 3 ] , pattrib - > dst [ 4 ] , pattrib - > dst [ 5 ] ) ;
2017-05-11 18:47:23 +00:00
return 0 ;
}
int rtw_mp_ctx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u32 pkTx = 1 ;
int countPkTx = 1 , cotuTx = 1 , CarrSprTx = 1 , scTx = 1 , sgleTx = 1 , stop = 1 ;
u32 bStartTest = 1 ;
u32 count = 0 , pktinterval = 0 , pktlen = 0 ;
u8 status ;
struct mp_priv * pmp_priv ;
struct pkt_attrib * pattrib ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
pmp_priv = & padapter - > mppriv ;
pattrib = & pmp_priv - > tx . attrib ;
if ( copy_from_user ( extra , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
* ( extra + wrqu - > length ) = ' \0 ' ;
RTW_INFO ( " %s: in=%s \n " , __func__ , extra ) ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_CONCURRENT_MODE
2019-11-09 10:12:08 +00:00
if ( ! is_primary_adapter ( padapter ) ) {
2017-05-11 18:47:23 +00:00
sprintf ( extra , " Error: MP mode can't support Virtual Adapter, Please to use main Adapter. \n " ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
# endif
countPkTx = strncmp ( extra , " count= " , 5 ) ; /* strncmp TRUE is 0*/
cotuTx = strncmp ( extra , " background " , 20 ) ;
CarrSprTx = strncmp ( extra , " background,cs " , 20 ) ;
scTx = strncmp ( extra , " background,sc " , 20 ) ;
sgleTx = strncmp ( extra , " background,stone " , 20 ) ;
pkTx = strncmp ( extra , " background,pkt " , 20 ) ;
stop = strncmp ( extra , " stop " , 4 ) ;
if ( sscanf ( extra , " count=%d,pkt " , & count ) > 0 )
2019-11-09 10:12:08 +00:00
RTW_INFO ( " count= %d \n " , count ) ;
2017-05-11 18:47:23 +00:00
if ( sscanf ( extra , " pktinterval=%d " , & pktinterval ) > 0 )
2019-11-09 10:12:08 +00:00
RTW_INFO ( " pktinterval= %d \n " , pktinterval ) ;
2017-05-11 18:47:23 +00:00
if ( sscanf ( extra , " pktlen=%d " , & pktlen ) > 0 )
2019-11-09 10:12:08 +00:00
RTW_INFO ( " pktlen= %d \n " , pktlen ) ;
2017-05-11 18:47:23 +00:00
if ( _rtw_memcmp ( extra , " destmac= " , 8 ) ) {
wrqu - > length - = 8 ;
rtw_set_ctx_destAddr ( dev , info , wrqu , & extra [ 8 ] ) ;
sprintf ( extra , " Set dest mac OK ! \n " ) ;
return 0 ;
}
2019-11-09 10:12:08 +00:00
/*RTW_INFO("%s: count=%d countPkTx=%d cotuTx=%d CarrSprTx=%d scTx=%d sgleTx=%d pkTx=%d stop=%d\n", __func__, count, countPkTx, cotuTx, CarrSprTx, pkTx, sgleTx, scTx, stop);*/
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , ' \0 ' , strlen ( extra ) ) ;
if ( pktinterval ! = 0 ) {
sprintf ( extra , " Pkt Interval = %d " , pktinterval ) ;
padapter - > mppriv . pktInterval = pktinterval ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
if ( pktlen ! = 0 ) {
sprintf ( extra , " Pkt len = %d " , pktlen ) ;
pattrib - > pktlen = pktlen ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
if ( stop = = 0 ) {
bStartTest = 0 ; /* To set Stop*/
pmp_priv - > tx . stop = 1 ;
sprintf ( extra , " Stop continuous Tx " ) ;
2019-11-09 10:12:08 +00:00
odm_write_dig ( & pHalData - > odmpriv , 0x20 ) ;
2017-05-11 18:47:23 +00:00
} else {
bStartTest = 1 ;
2019-11-09 10:12:08 +00:00
odm_write_dig ( & pHalData - > odmpriv , 0x7f ) ;
2017-05-11 18:47:23 +00:00
if ( pmp_priv - > mode ! = MP_ON ) {
if ( pmp_priv - > tx . stop ! = 1 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: MP_MODE != ON %d \n " , __func__ , pmp_priv - > mode ) ;
2017-05-11 18:47:23 +00:00
return - EFAULT ;
}
}
}
pmp_priv - > tx . count = count ;
if ( pkTx = = 0 | | countPkTx = = 0 )
pmp_priv - > mode = MP_PACKET_TX ;
if ( sgleTx = = 0 )
pmp_priv - > mode = MP_SINGLE_TONE_TX ;
if ( cotuTx = = 0 )
pmp_priv - > mode = MP_CONTINUOUS_TX ;
if ( CarrSprTx = = 0 )
pmp_priv - > mode = MP_CARRIER_SUPPRISSION_TX ;
if ( scTx = = 0 )
pmp_priv - > mode = MP_SINGLE_CARRIER_TX ;
status = rtw_mp_pretx_proc ( padapter , bStartTest , extra ) ;
wrqu - > length = strlen ( extra ) ;
return status ;
}
int rtw_mp_disable_bt_coexist ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
# ifdef CONFIG_BT_COEXIST
2017-05-11 18:47:23 +00:00
PADAPTER padapter = ( PADAPTER ) rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
# endif
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
u32 bt_coexist ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > data . length + 1 ) ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > data . length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
bt_coexist = rtw_atoi ( input ) ;
if ( bt_coexist = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST \n " ) ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_BT_COEXIST
rtw_btcoex_HaltNotify ( padapter ) ;
rtw_btcoex_SetManualControl ( padapter , _TRUE ) ;
/* Force to switch Antenna to WiFi*/
rtw_write16 ( padapter , 0x870 , 0x300 ) ;
rtw_write16 ( padapter , 0x860 , 0x110 ) ;
2019-11-09 10:12:08 +00:00
# endif
2017-05-11 18:47:23 +00:00
/* CONFIG_BT_COEXIST */
} else {
# ifdef CONFIG_BT_COEXIST
rtw_btcoex_SetManualControl ( padapter , _FALSE ) ;
# endif
}
return 0 ;
}
int rtw_mp_arx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
int bStartRx = 0 , bStopRx = 0 , bQueryPhy = 0 , bQueryMac = 0 , bSetBssid = 0 , bSetRxframe = 0 ;
int bmac_filter = 0 , bmon = 0 , bSmpCfg = 0 ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2019-11-09 10:12:08 +00:00
char * pch , * token , * tmp [ 2 ] = { 0x00 , 0x00 } ;
u32 i = 0 , jj = 0 , kk = 0 , cnts = 0 , ret ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
struct mp_priv * pmppriv = & padapter - > mppriv ;
struct dbg_rx_counter rx_counter ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: %s \n " , __func__ , input ) ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_CONCURRENT_MODE
2019-11-09 10:12:08 +00:00
if ( ! is_primary_adapter ( padapter ) ) {
2017-05-11 18:47:23 +00:00
sprintf ( extra , " Error: MP mode can't support Virtual Adapter, Please to use main Adapter. \n " ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
# endif
bStartRx = ( strncmp ( input , " start " , 5 ) = = 0 ) ? 1 : 0 ; /* strncmp TRUE is 0*/
bStopRx = ( strncmp ( input , " stop " , 5 ) = = 0 ) ? 1 : 0 ; /* strncmp TRUE is 0*/
bQueryPhy = ( strncmp ( input , " phy " , 3 ) = = 0 ) ? 1 : 0 ; /* strncmp TRUE is 0*/
bQueryMac = ( strncmp ( input , " mac " , 3 ) = = 0 ) ? 1 : 0 ; /* strncmp TRUE is 0*/
bSetBssid = ( strncmp ( input , " setbssid= " , 8 ) = = 0 ) ? 1 : 0 ; /* strncmp TRUE is 0*/
2019-11-09 10:12:08 +00:00
bSetRxframe = ( strncmp ( input , " frametype " , 9 ) = = 0 ) ? 1 : 0 ;
2017-05-11 18:47:23 +00:00
/*bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;*/
bmac_filter = ( strncmp ( input , " accept_mac " , 10 ) = = 0 ) ? 1 : 0 ;
bmon = ( strncmp ( input , " mon= " , 4 ) = = 0 ) ? 1 : 0 ;
bSmpCfg = ( strncmp ( input , " smpcfg= " , 7 ) = = 0 ) ? 1 : 0 ;
pmppriv - > bloopback = ( strncmp ( input , " loopbk " , 6 ) = = 0 ) ? 1 : 0 ; /* strncmp TRUE is 0*/
if ( bSetBssid = = 1 ) {
pch = input ;
while ( ( token = strsep ( & pch , " = " ) ) ! = NULL ) {
if ( i > 1 )
break ;
tmp [ i ] = token ;
i + + ;
}
if ( ( tmp [ 0 ] ! = NULL ) & & ( tmp [ 1 ] ! = NULL ) ) {
cnts = strlen ( tmp [ 1 ] ) / 2 ;
if ( cnts < 1 )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: cnts=%d \n " , __func__ , cnts ) ;
RTW_INFO ( " %s: data=%s \n " , __func__ , tmp [ 1 ] ) ;
2017-05-11 18:47:23 +00:00
for ( jj = 0 , kk = 0 ; jj < cnts ; jj + + , kk + = 2 ) {
pmppriv - > network_macaddr [ jj ] = key_2char2num ( tmp [ 1 ] [ kk ] , tmp [ 1 ] [ kk + 1 ] ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " network_macaddr[%d]=%x \n " , jj , pmppriv - > network_macaddr [ jj ] ) ;
}
2017-05-11 18:47:23 +00:00
} else
return - EFAULT ;
2019-11-09 10:12:08 +00:00
2017-05-11 18:47:23 +00:00
pmppriv - > bSetRxBssid = _TRUE ;
}
2019-11-09 10:12:08 +00:00
if ( bSetRxframe ) {
if ( strncmp ( input , " frametype beacon " , 16 ) = = 0 )
pmppriv - > brx_filter_beacon = _TRUE ;
else
pmppriv - > brx_filter_beacon = _FALSE ;
}
2017-05-11 18:47:23 +00:00
if ( bmac_filter ) {
pmppriv - > bmac_filter = bmac_filter ;
pch = input ;
while ( ( token = strsep ( & pch , " = " ) ) ! = NULL ) {
if ( i > 1 )
break ;
tmp [ i ] = token ;
i + + ;
}
if ( ( tmp [ 0 ] ! = NULL ) & & ( tmp [ 1 ] ! = NULL ) ) {
cnts = strlen ( tmp [ 1 ] ) / 2 ;
if ( cnts < 1 )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: cnts=%d \n " , __func__ , cnts ) ;
RTW_INFO ( " %s: data=%s \n " , __func__ , tmp [ 1 ] ) ;
2017-05-11 18:47:23 +00:00
for ( jj = 0 , kk = 0 ; jj < cnts ; jj + + , kk + = 2 ) {
pmppriv - > mac_filter [ jj ] = key_2char2num ( tmp [ 1 ] [ kk ] , tmp [ 1 ] [ kk + 1 ] ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s mac_filter[%d]=%x \n " , __func__ , jj , pmppriv - > mac_filter [ jj ] ) ;
}
} else
2017-05-11 18:47:23 +00:00
return - EFAULT ;
}
if ( bStartRx ) {
sprintf ( extra , " start " ) ;
SetPacketRx ( padapter , bStartRx , _FALSE ) ;
} else if ( bStopRx ) {
SetPacketRx ( padapter , bStartRx , _FALSE ) ;
pmppriv - > bmac_filter = _FALSE ;
2019-11-09 10:12:08 +00:00
pmppriv - > bSetRxBssid = _FALSE ;
2017-05-11 18:47:23 +00:00
sprintf ( extra , " Received packet OK:%d CRC error:%d ,Filter out:%d " , padapter - > mppriv . rx_pktcount , padapter - > mppriv . rx_crcerrpktcount , padapter - > mppriv . rx_pktcount_filter_out ) ;
} else if ( bQueryPhy ) {
_rtw_memset ( & rx_counter , 0 , sizeof ( struct dbg_rx_counter ) ) ;
rtw_dump_phy_rx_counters ( padapter , & rx_counter ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: OFDM_FA =%d \n " , __func__ , rx_counter . rx_ofdm_fa ) ;
RTW_INFO ( " %s: CCK_FA =%d \n " , __func__ , rx_counter . rx_cck_fa ) ;
2017-05-11 18:47:23 +00:00
sprintf ( extra , " Phy Received packet OK:%d CRC error:%d FA Counter: %d " , rx_counter . rx_pkt_ok , rx_counter . rx_pkt_crc_error , rx_counter . rx_cck_fa + rx_counter . rx_ofdm_fa ) ;
} else if ( bQueryMac ) {
_rtw_memset ( & rx_counter , 0 , sizeof ( struct dbg_rx_counter ) ) ;
rtw_dump_mac_rx_counters ( padapter , & rx_counter ) ;
sprintf ( extra , " Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d \n " ,
2019-11-09 10:12:08 +00:00
rx_counter . rx_pkt_ok , rx_counter . rx_pkt_crc_error , rx_counter . rx_pkt_drop ) ;
2017-05-11 18:47:23 +00:00
}
if ( bmon = = 1 ) {
ret = sscanf ( input , " mon=%d " , & bmon ) ;
if ( bmon = = 1 ) {
pmppriv - > rx_bindicatePkt = _TRUE ;
sprintf ( extra , " Indicating Receive Packet to network start \n " ) ;
} else {
pmppriv - > rx_bindicatePkt = _FALSE ;
sprintf ( extra , " Indicating Receive Packet to network Stop \n " ) ;
}
}
if ( bSmpCfg = = 1 ) {
ret = sscanf ( input , " smpcfg=%d " , & bSmpCfg ) ;
if ( bSmpCfg = = 1 ) {
pmppriv - > bRTWSmbCfg = _TRUE ;
sprintf ( extra , " Indicate By Simple Config Format \n " ) ;
SetPacketRx ( padapter , _TRUE , _TRUE ) ;
} else {
pmppriv - > bRTWSmbCfg = _FALSE ;
sprintf ( extra , " Indicate By Normal Format \n " ) ;
SetPacketRx ( padapter , _TRUE , _FALSE ) ;
}
}
if ( pmppriv - > bloopback = = _TRUE ) {
sprintf ( extra , " Enter MAC LoopBack mode \n " ) ;
_rtw_write32 ( padapter , 0x100 , 0xB0106FF ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " 0x100 :0x%x " , _rtw_read32 ( padapter , 0x100 ) ) ;
2017-05-11 18:47:23 +00:00
_rtw_write16 ( padapter , 0x608 , 0x30c ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " 0x100 :0x%x " , _rtw_read32 ( padapter , 0x608 ) ) ;
2017-05-11 18:47:23 +00:00
}
wrqu - > length = strlen ( extra ) + 1 ;
return 0 ;
}
int rtw_mp_trx_query ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u32 txok , txfail , rxok , rxfail , rxfilterout ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
PMPT_CONTEXT pMptCtx = & ( padapter - > mppriv . mpt_ctx ) ;
2017-05-11 18:47:23 +00:00
RT_PMAC_TX_INFO PMacTxInfo = pMptCtx - > PMacTxInfo ;
if ( PMacTxInfo . bEnPMacTx = = TRUE )
2019-11-09 10:12:08 +00:00
txok = hal_mpt_query_phytxok ( padapter ) ;
2017-05-11 18:47:23 +00:00
else
2019-11-09 10:12:08 +00:00
txok = padapter - > mppriv . tx . sended ;
2017-05-11 18:47:23 +00:00
txfail = 0 ;
rxok = padapter - > mppriv . rx_pktcount ;
rxfail = padapter - > mppriv . rx_crcerrpktcount ;
rxfilterout = padapter - > mppriv . rx_pktcount_filter_out ;
_rtw_memset ( extra , ' \0 ' , 128 ) ;
sprintf ( extra , " Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d \n " , txok , txfail , rxok , rxfail , rxfilterout ) ;
wrqu - > length = strlen ( extra ) + 1 ;
return 0 ;
}
int rtw_mp_pwrtrk ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u8 enable ;
u32 thermal ;
s32 ret ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
_rtw_memset ( extra , 0 , wrqu - > length ) ;
enable = 1 ;
if ( wrqu - > length > 1 ) {
/* not empty string*/
if ( strncmp ( input , " stop " , 4 ) = = 0 ) {
enable = 0 ;
sprintf ( extra , " mp tx power tracking stop " ) ;
} else if ( sscanf ( input , " ther=%d " , & thermal ) = = 1 ) {
ret = SetThermalMeter ( padapter , ( u8 ) thermal ) ;
if ( ret = = _FAIL )
return - EPERM ;
sprintf ( extra , " mp tx power tracking start,target value=%d ok " , thermal ) ;
} else
return - EINVAL ;
}
ret = SetPowerTracking ( padapter , enable ) ;
if ( ret = = _FAIL )
return - EPERM ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_psd ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
if ( rtw_do_mp_iwdata_len_chk ( __func__ , ( wrqu - > length + 1 ) ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
_rtw_memset ( input , 0 , sizeof ( input ) ) ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
input [ wrqu - > length ] = ' \0 ' ;
2017-05-11 18:47:23 +00:00
strcpy ( extra , input ) ;
wrqu - > length = mp_query_psd ( padapter , extra ) ;
return 0 ;
}
int rtw_mp_thermal ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
u8 val ;
int bwrite = 1 ;
# ifdef CONFIG_RTL8188E
u16 addr = EEPROM_THERMAL_METER_88E ;
# endif
# if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A)
u16 addr = EEPROM_THERMAL_METER_8812 ;
# endif
# ifdef CONFIG_RTL8192E
u16 addr = EEPROM_THERMAL_METER_8192E ;
# endif
2019-11-09 10:12:08 +00:00
# ifdef CONFIG_RTL8192F
u16 addr = EEPROM_THERMAL_METER_8192F ;
# endif
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_RTL8723B
u16 addr = EEPROM_THERMAL_METER_8723B ;
# endif
# ifdef CONFIG_RTL8703B
u16 addr = EEPROM_THERMAL_METER_8703B ;
# endif
2019-11-09 10:12:08 +00:00
# ifdef CONFIG_RTL8723D
u16 addr = EEPROM_THERMAL_METER_8723D ;
# endif
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_RTL8188F
u16 addr = EEPROM_THERMAL_METER_8188F ;
2019-11-09 10:12:08 +00:00
# endif
# ifdef CONFIG_RTL8188GTV
u16 addr = EEPROM_THERMAL_METER_8188GTV ;
# endif
# ifdef CONFIG_RTL8822B
u16 addr = EEPROM_THERMAL_METER_8822B ;
# endif
# ifdef CONFIG_RTL8821C
u16 addr = EEPROM_THERMAL_METER_8821C ;
# endif
# ifdef CONFIG_RTL8710B
u16 addr = EEPROM_THERMAL_METER_8710B ;
2017-05-11 18:47:23 +00:00
# endif
u16 cnt = 1 ;
u16 max_available_size = 0 ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
if ( copy_from_user ( extra , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
bwrite = strncmp ( extra , " write " , 6 ) ; /* strncmp TRUE is 0*/
GetThermalMeter ( padapter , & val ) ;
if ( bwrite = = 0 ) {
2019-11-09 10:12:08 +00:00
/*RTW_INFO("to write val:%d",val);*/
2017-05-11 18:47:23 +00:00
EFUSE_GetEfuseDefinition ( padapter , EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL , ( PVOID ) & max_available_size , _FALSE ) ;
if ( 2 > max_available_size ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " no available efuse! \n " ) ;
2017-05-11 18:47:23 +00:00
return - EFAULT ;
}
if ( rtw_efuse_map_write ( padapter , addr , cnt , & val ) = = _FAIL ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " rtw_efuse_map_write error \n " ) ;
2017-05-11 18:47:23 +00:00
return - EFAULT ;
}
sprintf ( extra , " efuse write ok :%d " , val ) ;
} else
sprintf ( extra , " %d " , val ) ;
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_reset_stats ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
struct mp_priv * pmp_priv ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
pmp_priv = & padapter - > mppriv ;
pmp_priv - > tx . sended = 0 ;
pmp_priv - > tx_pktcount = 0 ;
pmp_priv - > rx_pktcount = 0 ;
pmp_priv - > rx_pktcount_filter_out = 0 ;
pmp_priv - > rx_crcerrpktcount = 0 ;
rtw_reset_phy_rx_counters ( padapter ) ;
rtw_reset_mac_rx_counters ( padapter ) ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
sprintf ( extra , " mp_reset_stats ok \n " ) ;
wrqu - > length = strlen ( extra ) ;
2017-05-11 18:47:23 +00:00
return 0 ;
}
int rtw_mp_dump ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
struct mp_priv * pmp_priv ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
pmp_priv = & padapter - > mppriv ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
if ( strncmp ( input , " all " , 4 ) = = 0 ) {
mac_reg_dump ( RTW_DBGDUMP , padapter ) ;
bb_reg_dump ( RTW_DBGDUMP , padapter ) ;
rf_reg_dump ( RTW_DBGDUMP , padapter ) ;
}
return 0 ;
}
int rtw_mp_phypara ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
u32 valxcap , ret ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:iwpriv in=%s \n " , __func__ , input ) ;
2017-05-11 18:47:23 +00:00
ret = sscanf ( input , " xcap=%d " , & valxcap ) ;
2019-11-09 10:12:08 +00:00
pHalData - > crystal_cap = ( u8 ) valxcap ;
2017-05-11 18:47:23 +00:00
hal_set_crystal_cap ( padapter , valxcap ) ;
sprintf ( extra , " Set xcap=%d " , valxcap ) ;
wrqu - > length = strlen ( extra ) + 1 ;
return 0 ;
}
int rtw_mp_SetRFPath ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
int bMain = 1 , bTurnoff = 1 ;
2019-11-09 10:12:08 +00:00
# ifdef CONFIG_ANTENNA_DIVERSITY
u8 ret = _TRUE ;
# endif
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:iwpriv in=%s \n " , __func__ , input ) ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
2017-05-11 18:47:23 +00:00
return - EFAULT ;
bMain = strncmp ( input , " 1 " , 2 ) ; /* strncmp TRUE is 0*/
bTurnoff = strncmp ( input , " 0 " , 3 ) ; /* strncmp TRUE is 0*/
2019-11-09 10:12:08 +00:00
_rtw_memset ( extra , 0 , wrqu - > length ) ;
# ifdef CONFIG_ANTENNA_DIVERSITY
if ( bMain = = 0 )
ret = rtw_mp_set_antdiv ( padapter , _TRUE ) ;
else
ret = rtw_mp_set_antdiv ( padapter , _FALSE ) ;
if ( ret = = _FALSE )
RTW_INFO ( " %s:ANTENNA_DIVERSITY FAIL \n " , __func__ ) ;
# endif
2017-05-11 18:47:23 +00:00
if ( bMain = = 0 ) {
MP_PHY_SetRFPathSwitch ( padapter , _TRUE ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:PHY_SetRFPathSwitch=TRUE \n " , __func__ ) ;
sprintf ( extra , " mp_setrfpath Main \n " ) ;
2017-05-11 18:47:23 +00:00
} else if ( bTurnoff = = 0 ) {
MP_PHY_SetRFPathSwitch ( padapter , _FALSE ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:PHY_SetRFPathSwitch=FALSE \n " , __func__ ) ;
sprintf ( extra , " mp_setrfpath Aux \n " ) ;
} else {
bMain = MP_PHY_QueryRFPathSwitch ( padapter ) ;
RTW_INFO ( " %s:PHY_SetRFPathSwitch = %s \n " , __func__ , ( bMain ? " Main " : " Aux " ) ) ;
sprintf ( extra , " mp_setrfpath %s \n " , ( bMain ? " Main " : " Aux " ) ) ;
2017-05-11 18:47:23 +00:00
}
2019-11-09 10:12:08 +00:00
wrqu - > length = strlen ( extra ) ;
2017-05-11 18:47:23 +00:00
return 0 ;
}
2019-11-09 10:12:08 +00:00
int rtw_mp_switch_rf_path ( struct net_device * dev ,
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
struct mp_priv * pmp_priv ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2019-11-09 10:12:08 +00:00
int bwlg = 1 , bwla = 1 , btg = 1 , bbt = 1 ;
u8 ret = 0 ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
pmp_priv = & padapter - > mppriv ;
RTW_INFO ( " %s: in=%s \n " , __func__ , input ) ;
bwlg = strncmp ( input , " WLG " , 3 ) ; /* strncmp TRUE is 0*/
bwla = strncmp ( input , " WLA " , 3 ) ; /* strncmp TRUE is 0*/
btg = strncmp ( input , " BTG " , 3 ) ; /* strncmp TRUE is 0*/
bbt = strncmp ( input , " BT " , 3 ) ; /* strncmp TRUE is 0*/
_rtw_memset ( extra , 0 , wrqu - > length ) ;
# ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */
if ( bwlg = = 0 ) {
pmp_priv - > rf_path_cfg = SWITCH_TO_WLG ;
sprintf ( extra , " switch rf path WLG \n " ) ;
} else if ( bwla = = 0 ) {
pmp_priv - > rf_path_cfg = SWITCH_TO_WLA ;
sprintf ( extra , " switch rf path WLA \n " ) ;
} else if ( btg = = 0 ) {
pmp_priv - > rf_path_cfg = SWITCH_TO_BTG ;
sprintf ( extra , " switch rf path BTG \n " ) ;
} else if ( bbt = = 0 ) {
pmp_priv - > rf_path_cfg = SWITCH_TO_BT ;
sprintf ( extra , " switch rf path BG \n " ) ;
} else {
sprintf ( extra , " Error set %s \n " , __func__ ) ;
return - EFAULT ;
}
mp_phy_switch_rf_path_set ( padapter , & pmp_priv - > rf_path_cfg ) ;
# endif
wrqu - > length = strlen ( extra ) ;
return ret ;
}
2017-05-11 18:47:23 +00:00
int rtw_mp_QueryDrv ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
char input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
int qAutoLoad = 1 ;
PHAL_DATA_TYPE pHalData = GET_HAL_DATA ( padapter ) ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > data . length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:iwpriv in=%s \n " , __func__ , input ) ;
2017-05-11 18:47:23 +00:00
qAutoLoad = strncmp ( input , " autoload " , 8 ) ; /* strncmp TRUE is 0*/
if ( qAutoLoad = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:qAutoLoad \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
if ( pHalData - > bautoload_fail_flag )
sprintf ( extra , " fail " ) ;
else
sprintf ( extra , " ok " ) ;
}
wrqu - > data . length = strlen ( extra ) + 1 ;
return 0 ;
}
int rtw_mp_PwrCtlDM ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2020-10-31 15:54:15 +00:00
u8 input [ RTW_IWD_MAX_LEN ] ;
2017-05-11 18:47:23 +00:00
int bstart = 1 ;
2020-10-31 15:54:15 +00:00
if ( rtw_do_mp_iwdata_len_chk ( __func__ , wrqu - > length ) )
return - EFAULT ;
2017-05-11 18:47:23 +00:00
if ( copy_from_user ( input , wrqu - > pointer , wrqu - > length ) )
return - EFAULT ;
bstart = strncmp ( input , " start " , 5 ) ; /* strncmp TRUE is 0*/
if ( bstart = = 0 ) {
sprintf ( extra , " PwrCtlDM start \n " ) ;
MPT_PwrCtlDM ( padapter , 1 ) ;
} else {
sprintf ( extra , " PwrCtlDM stop \n " ) ;
MPT_PwrCtlDM ( padapter , 0 ) ;
}
wrqu - > length = strlen ( extra ) ;
return 0 ;
}
2019-11-09 10:12:08 +00:00
int rtw_mp_iqk ( struct net_device * dev ,
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
rtw_mp_trigger_iqk ( padapter ) ;
return 0 ;
}
int rtw_mp_lck ( struct net_device * dev ,
struct iw_request_info * info ,
struct iw_point * wrqu , char * extra )
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
rtw_mp_trigger_lck ( padapter ) ;
return 0 ;
}
2017-05-11 18:47:23 +00:00
int rtw_mp_getver ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
struct mp_priv * pmp_priv ;
pmp_priv = & padapter - > mppriv ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
sprintf ( extra , " rtwpriv=%d \n " , RTWPRIV_VER_INFO ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_mon ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
struct mp_priv * pmp_priv = & padapter - > mppriv ;
struct mlme_priv * pmlmepriv = & padapter - > mlmepriv ;
2019-11-09 10:12:08 +00:00
struct hal_ops * pHalFunc = & padapter - > hal_func ;
2017-05-11 18:47:23 +00:00
NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
int bstart = 1 , bstop = 1 ;
2019-11-09 10:12:08 +00:00
2017-05-11 18:47:23 +00:00
networkType = Ndis802_11Infrastructure ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
* ( extra + wrqu - > data . length ) = ' \0 ' ;
2017-05-11 18:47:23 +00:00
rtw_pm_set_ips ( padapter , IPS_NONE ) ;
LeaveAllPowerSaveMode ( padapter ) ;
# ifdef CONFIG_MP_INCLUDED
if ( init_mp_priv ( padapter ) = = _FAIL )
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: initialize MP private data Fail! \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
padapter - > mppriv . channel = 6 ;
bstart = strncmp ( extra , " start " , 5 ) ; /* strncmp TRUE is 0*/
bstop = strncmp ( extra , " stop " , 4 ) ; /* strncmp TRUE is 0*/
if ( bstart = = 0 ) {
mp_join ( padapter , WIFI_FW_ADHOC_STATE ) ;
SetPacketRx ( padapter , _TRUE , _FALSE ) ;
SetChannel ( padapter ) ;
pmp_priv - > rx_bindicatePkt = _TRUE ;
pmp_priv - > bRTWSmbCfg = _TRUE ;
sprintf ( extra , " monitor mode start \n " ) ;
} else if ( bstop = = 0 ) {
SetPacketRx ( padapter , _FALSE , _FALSE ) ;
pmp_priv - > rx_bindicatePkt = _FALSE ;
pmp_priv - > bRTWSmbCfg = _FALSE ;
padapter - > registrypriv . mp_mode = 1 ;
pHalFunc - > hal_deinit ( padapter ) ;
padapter - > registrypriv . mp_mode = 0 ;
pHalFunc - > hal_init ( padapter ) ;
2019-11-09 10:12:08 +00:00
/*rtw_disassoc_cmd(padapter, 0, 0);*/
2017-05-11 18:47:23 +00:00
if ( check_fwstate ( pmlmepriv , _FW_LINKED ) = = _TRUE ) {
2019-11-09 10:12:08 +00:00
rtw_disassoc_cmd ( padapter , 500 , 0 ) ;
2017-05-11 18:47:23 +00:00
rtw_indicate_disconnect ( padapter , 0 , _FALSE ) ;
2019-11-09 10:12:08 +00:00
/*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/
2017-05-11 18:47:23 +00:00
}
rtw_pm_set_ips ( padapter , IPS_NORMAL ) ;
sprintf ( extra , " monitor mode Stop \n " ) ;
}
# endif
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_pretx_proc ( PADAPTER padapter , u8 bStartTest , char * extra )
{
struct mp_priv * pmp_priv = & padapter - > mppriv ;
2019-11-09 10:12:08 +00:00
char * pextra = extra ;
switch ( pmp_priv - > mode ) {
case MP_PACKET_TX :
if ( bStartTest = = 0 ) {
pmp_priv - > tx . stop = 1 ;
pmp_priv - > mode = MP_ON ;
sprintf ( extra , " Stop continuous Tx " ) ;
} else if ( pmp_priv - > tx . stop = = 1 ) {
pextra = extra + strlen ( extra ) ;
pextra + = sprintf ( pextra , " \n Start continuous DA=ffffffffffff len=1500 count=%u \n " , pmp_priv - > tx . count ) ;
pmp_priv - > tx . stop = 0 ;
SetPacketTx ( padapter ) ;
} else
return - EFAULT ;
return 0 ;
case MP_SINGLE_TONE_TX :
if ( bStartTest ! = 0 )
strcat ( extra , " \n Start continuous DA=ffffffffffff len=1500 \n infinite=yes. " ) ;
SetSingleToneTx ( padapter , ( u8 ) bStartTest ) ;
break ;
case MP_CONTINUOUS_TX :
if ( bStartTest ! = 0 )
strcat ( extra , " \n Start continuous DA=ffffffffffff len=1500 \n infinite=yes. " ) ;
SetContinuousTx ( padapter , ( u8 ) bStartTest ) ;
break ;
case MP_CARRIER_SUPPRISSION_TX :
if ( bStartTest ! = 0 ) {
if ( HwRateToMPTRate ( pmp_priv - > rateidx ) < = MPT_RATE_11M )
strcat ( extra , " \n Start continuous DA=ffffffffffff len=1500 \n infinite=yes. " ) ;
else
strcat ( extra , " \n Specify carrier suppression but not CCK rate " ) ;
2017-05-11 18:47:23 +00:00
}
2019-11-09 10:12:08 +00:00
SetCarrierSuppressionTx ( padapter , ( u8 ) bStartTest ) ;
break ;
case MP_SINGLE_CARRIER_TX :
if ( bStartTest ! = 0 )
strcat ( extra , " \n Start continuous DA=ffffffffffff len=1500 \n infinite=yes. " ) ;
SetSingleCarrierTx ( padapter , ( u8 ) bStartTest ) ;
break ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
default :
sprintf ( extra , " Error! Continuous-Tx is not on-going. " ) ;
return - EFAULT ;
}
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
if ( bStartTest = = 1 & & pmp_priv - > mode ! = MP_ON ) {
struct mp_priv * pmp_priv = & padapter - > mppriv ;
if ( pmp_priv - > tx . stop = = 0 ) {
pmp_priv - > tx . stop = 1 ;
rtw_msleep_os ( 5 ) ;
}
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_80211N_HT
2019-11-09 10:12:08 +00:00
if ( padapter - > registrypriv . ht_enable & &
is_supported_ht ( padapter - > registrypriv . wireless_mode ) )
2017-05-11 18:47:23 +00:00
pmp_priv - > tx . attrib . ht_en = 1 ;
# endif
2019-11-09 10:12:08 +00:00
pmp_priv - > tx . stop = 0 ;
pmp_priv - > tx . count = 1 ;
SetPacketTx ( padapter ) ;
} else
pmp_priv - > mode = MP_ON ;
2017-05-11 18:47:23 +00:00
# if defined(CONFIG_RTL8812A)
2019-11-09 10:12:08 +00:00
if ( IS_HARDWARE_TYPE_8812AU ( padapter ) ) {
/* <20130425, Kordan> Turn off OFDM Rx to prevent from CCA causing Tx hang.*/
if ( pmp_priv - > mode = = MP_PACKET_TX )
phy_set_bb_reg ( padapter , rCCAonSec_Jaguar , BIT3 , 1 ) ;
else
phy_set_bb_reg ( padapter , rCCAonSec_Jaguar , BIT3 , 0 ) ;
}
2017-05-11 18:47:23 +00:00
# endif
return 0 ;
}
int rtw_mp_tx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
2019-11-09 10:12:08 +00:00
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
struct mp_priv * pmp_priv = & padapter - > mppriv ;
PMPT_CONTEXT pMptCtx = & ( padapter - > mppriv . mpt_ctx ) ;
char * pextra = extra ;
u32 bandwidth = 0 , sg = 0 , channel = 6 , txpower = 40 , rate = 108 , ant = 0 , txmode = 1 , count = 0 ;
u8 bStartTest = 1 , status = 0 ;
# ifdef CONFIG_MP_VHT_HW_TX_MODE
u8 Idx = 0 , tmpU1B ;
# endif
u16 antenna = 0 ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
RTW_INFO ( " extra = %s \n " , extra ) ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_CONCURRENT_MODE
2019-11-09 10:12:08 +00:00
if ( ! is_primary_adapter ( padapter ) ) {
sprintf ( extra , " Error: MP mode can't support Virtual Adapter, Please to use main Adapter. \n " ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
2017-05-11 18:47:23 +00:00
# endif
2019-11-09 10:12:08 +00:00
if ( strncmp ( extra , " stop " , 3 ) = = 0 ) {
bStartTest = 0 ; /* To set Stop*/
pmp_priv - > tx . stop = 1 ;
sprintf ( extra , " Stop continuous Tx " ) ;
status = rtw_mp_pretx_proc ( padapter , bStartTest , extra ) ;
wrqu - > data . length = strlen ( extra ) ;
return status ;
} else if ( strncmp ( extra , " count " , 5 ) = = 0 ) {
if ( sscanf ( extra , " count=%d " , & count ) < 1 )
RTW_INFO ( " Got Count=%d] \n " , count ) ;
pmp_priv - > tx . count = count ;
return 0 ;
} else if ( strncmp ( extra , " setting " , 7 ) = = 0 ) {
_rtw_memset ( extra , 0 , wrqu - > data . length ) ;
pextra + = sprintf ( pextra , " Current Setting : \n Channel:%d " , pmp_priv - > channel ) ;
pextra + = sprintf ( pextra , " \n Bandwidth:%d " , pmp_priv - > bandwidth ) ;
pextra + = sprintf ( pextra , " \n Rate index:%d " , pmp_priv - > rateidx ) ;
pextra + = sprintf ( pextra , " \n TxPower index:%d " , pmp_priv - > txpoweridx ) ;
pextra + = sprintf ( pextra , " \n Antenna TxPath:%d " , pmp_priv - > antenna_tx ) ;
pextra + = sprintf ( pextra , " \n Antenna RxPath:%d " , pmp_priv - > antenna_rx ) ;
pextra + = sprintf ( pextra , " \n MP Mode:%d " , pmp_priv - > mode ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_MP_VHT_HW_TX_MODE
2019-11-09 10:12:08 +00:00
} else if ( strncmp ( extra , " pmact " , 5 ) = = 0 ) {
if ( strncmp ( extra , " pmact= " , 6 ) = = 0 ) {
_rtw_memset ( & pMptCtx - > PMacTxInfo , 0 , sizeof ( pMptCtx - > PMacTxInfo ) ) ;
if ( strncmp ( extra , " pmact=start " , 11 ) = = 0 ) {
pMptCtx - > PMacTxInfo . bEnPMacTx = _TRUE ;
sprintf ( extra , " Set PMac Tx Mode start \n " ) ;
} else {
pMptCtx - > PMacTxInfo . bEnPMacTx = _FALSE ;
sprintf ( extra , " Set PMac Tx Mode Stop \n " ) ;
}
if ( pMptCtx - > bldpc = = TRUE )
pMptCtx - > PMacTxInfo . bLDPC = _TRUE ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
if ( pMptCtx - > bstbc = = TRUE )
pMptCtx - > PMacTxInfo . bSTBC = _TRUE ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
pMptCtx - > PMacTxInfo . bSPreamble = pmp_priv - > preamble ;
pMptCtx - > PMacTxInfo . bSGI = pmp_priv - > preamble ;
pMptCtx - > PMacTxInfo . BandWidth = pmp_priv - > bandwidth ;
pMptCtx - > PMacTxInfo . TX_RATE = HwRateToMPTRate ( pmp_priv - > rateidx ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
pMptCtx - > PMacTxInfo . Mode = pMptCtx - > HWTxmode ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
pMptCtx - > PMacTxInfo . NDP_sound = FALSE ; /*(Adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/
if ( padapter - > mppriv . pktInterval = = 0 )
pMptCtx - > PMacTxInfo . PacketPeriod = 100 ;
else
pMptCtx - > PMacTxInfo . PacketPeriod = padapter - > mppriv . pktInterval ;
if ( padapter - > mppriv . pktLength < 1000 )
pMptCtx - > PMacTxInfo . PacketLength = 1000 ;
else
pMptCtx - > PMacTxInfo . PacketLength = padapter - > mppriv . pktLength ;
pMptCtx - > PMacTxInfo . PacketPattern = rtw_random32 ( ) % 0xFF ;
if ( padapter - > mppriv . tx_pktcount ! = 0 )
pMptCtx - > PMacTxInfo . PacketCount = padapter - > mppriv . tx_pktcount ;
pMptCtx - > PMacTxInfo . Ntx = 0 ;
for ( Idx = 16 ; Idx < 20 ; Idx + + ) {
tmpU1B = ( padapter - > mppriv . antenna_tx > > Idx ) & 1 ;
if ( tmpU1B )
pMptCtx - > PMacTxInfo . Ntx + + ;
}
_rtw_memset ( pMptCtx - > PMacTxInfo . MacAddress , 0xFF , ETH_ALEN ) ;
PMAC_Get_Pkt_Param ( & pMptCtx - > PMacTxInfo , & pMptCtx - > PMacPktInfo ) ;
if ( MPT_IS_CCK_RATE ( pMptCtx - > PMacTxInfo . TX_RATE ) )
CCK_generator ( & pMptCtx - > PMacTxInfo , & pMptCtx - > PMacPktInfo ) ;
else {
PMAC_Nsym_generator ( & pMptCtx - > PMacTxInfo , & pMptCtx - > PMacPktInfo ) ;
/* 24 BIT*/
L_SIG_generator ( pMptCtx - > PMacPktInfo . N_sym , & pMptCtx - > PMacTxInfo , & pMptCtx - > PMacPktInfo ) ;
}
/* 48BIT*/
if ( MPT_IS_HT_RATE ( pMptCtx - > PMacTxInfo . TX_RATE ) )
HT_SIG_generator ( & pMptCtx - > PMacTxInfo , & pMptCtx - > PMacPktInfo ) ;
else if ( MPT_IS_VHT_RATE ( pMptCtx - > PMacTxInfo . TX_RATE ) ) {
/* 48BIT*/
VHT_SIG_A_generator ( & pMptCtx - > PMacTxInfo , & pMptCtx - > PMacPktInfo ) ;
/* 26/27/29 BIT & CRC 8 BIT*/
VHT_SIG_B_generator ( & pMptCtx - > PMacTxInfo ) ;
/* 32 BIT*/
VHT_Delimiter_generator ( & pMptCtx - > PMacTxInfo ) ;
}
mpt_ProSetPMacTx ( padapter ) ;
} else if ( strncmp ( extra , " pmact,mode= " , 11 ) = = 0 ) {
int txmode = 0 ;
if ( sscanf ( extra , " pmact,mode=%d " , & txmode ) > 0 ) {
if ( txmode = = 1 ) {
pMptCtx - > HWTxmode = CONTINUOUS_TX ;
sprintf ( extra , " \t Config HW Tx mode = CONTINUOUS_TX \n " ) ;
2017-05-11 18:47:23 +00:00
} else if ( txmode = = 2 ) {
2019-11-09 10:12:08 +00:00
pMptCtx - > HWTxmode = OFDM_Single_Tone_TX ;
sprintf ( extra , " \t Config HW Tx mode = OFDM_Single_Tone_TX \n " ) ;
} else {
pMptCtx - > HWTxmode = PACKETS_TX ;
sprintf ( extra , " \t Config HW Tx mode = PACKETS_TX \n " ) ;
2017-05-11 18:47:23 +00:00
}
2019-11-09 10:12:08 +00:00
} else {
pMptCtx - > HWTxmode = PACKETS_TX ;
sprintf ( extra , " \t Config HW Tx mode= \n 0 = PACKETS_TX \n 1 = CONTINUOUS_TX \n 2 = OFDM_Single_Tone_TX " ) ;
2017-05-11 18:47:23 +00:00
}
2019-11-09 10:12:08 +00:00
} else if ( strncmp ( extra , " pmact, " , 6 ) = = 0 ) {
int PacketPeriod = 0 , PacketLength = 0 , PacketCout = 0 ;
int bldpc = 0 , bstbc = 0 ;
if ( sscanf ( extra , " pmact,period=%d " , & PacketPeriod ) > 0 ) {
padapter - > mppriv . pktInterval = PacketPeriod ;
RTW_INFO ( " PacketPeriod=%d \n " , padapter - > mppriv . pktInterval ) ;
sprintf ( extra , " PacketPeriod [1~255]= %d \n " , padapter - > mppriv . pktInterval ) ;
} else if ( sscanf ( extra , " pmact,length=%d " , & PacketLength ) > 0 ) {
padapter - > mppriv . pktLength = PacketLength ;
RTW_INFO ( " PacketPeriod=%d \n " , padapter - > mppriv . pktLength ) ;
sprintf ( extra , " PacketLength[~65535]=%d \n " , padapter - > mppriv . pktLength ) ;
} else if ( sscanf ( extra , " pmact,count=%d " , & PacketCout ) > 0 ) {
padapter - > mppriv . tx_pktcount = PacketCout ;
RTW_INFO ( " Packet Cout =%d \n " , padapter - > mppriv . tx_pktcount ) ;
sprintf ( extra , " Packet Cout =%d \n " , padapter - > mppriv . tx_pktcount ) ;
} else if ( sscanf ( extra , " pmact,ldpc=%d " , & bldpc ) > 0 ) {
pMptCtx - > bldpc = bldpc ;
RTW_INFO ( " Set LDPC =%d \n " , pMptCtx - > bldpc ) ;
sprintf ( extra , " Set LDPC =%d \n " , pMptCtx - > bldpc ) ;
} else if ( sscanf ( extra , " pmact,stbc=%d " , & bstbc ) > 0 ) {
pMptCtx - > bstbc = bstbc ;
RTW_INFO ( " Set STBC =%d \n " , pMptCtx - > bstbc ) ;
sprintf ( extra , " Set STBC =%d \n " , pMptCtx - > bstbc ) ;
} else
sprintf ( extra , " \n period={1~255} \n length={1000~65535} \n count={0~} \n ldpc={0/1} \n stbc={0/1} " ) ;
2017-05-11 18:47:23 +00:00
}
wrqu - > data . length = strlen ( extra ) ;
2019-11-09 10:12:08 +00:00
return 0 ;
# endif
} else {
if ( sscanf ( extra , " ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d " , & channel , & bandwidth , & rate , & txpower , & ant , & txmode ) < 6 ) {
RTW_INFO ( " Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d] \n " , channel , bandwidth , rate , txpower , ant , txmode ) ;
_rtw_memset ( extra , 0 , wrqu - > data . length ) ;
pextra + = sprintf ( pextra , " \n Please input correct format as bleow: \n " ) ;
pextra + = sprintf ( pextra , " \t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d \n " , channel , bandwidth , rate , txpower , ant , txmode ) ;
pextra + = sprintf ( pextra , " \n [ ch : BGN = <1~14> , A or AC = <36~165> ] " ) ;
pextra + = sprintf ( pextra , " \n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ] " ) ;
pextra + = sprintf ( pextra , " \n [ rate : CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >] " ) ;
pextra + = sprintf ( pextra , " \n [ OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108> " ) ;
pextra + = sprintf ( pextra , " \n [ HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 > " ) ;
pextra + = sprintf ( pextra , " \n [ HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 > " ) ;
pextra + = sprintf ( pextra , " \n [ VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 > " ) ;
pextra + = sprintf ( pextra , " \n [ txpower : 1~63 power index " ) ;
pextra + = sprintf ( pextra , " \n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12 " ) ;
pextra + = sprintf ( pextra , " \n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX> \n " ) ;
wrqu - > data . length = strlen ( extra ) ;
return status ;
} else {
char * pextra = extra ;
RTW_INFO ( " Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d] \n " , channel , bandwidth , rate , txpower , ant , txmode ) ;
_rtw_memset ( extra , 0 , wrqu - > data . length ) ;
sprintf ( extra , " Change Current channel %d to channel %d " , padapter - > mppriv . channel , channel ) ;
padapter - > mppriv . channel = channel ;
SetChannel ( padapter ) ;
pHalData - > current_channel = channel ;
if ( bandwidth = = 1 )
bandwidth = CHANNEL_WIDTH_40 ;
else if ( bandwidth = = 2 )
bandwidth = CHANNEL_WIDTH_80 ;
pextra = extra + strlen ( pextra ) ;
pextra + = sprintf ( pextra , " \n Change Current Bandwidth %d to Bandwidth %d " , padapter - > mppriv . bandwidth , bandwidth ) ;
padapter - > mppriv . bandwidth = ( u8 ) bandwidth ;
padapter - > mppriv . preamble = sg ;
SetBandwidth ( padapter ) ;
pHalData - > current_channel_bw = bandwidth ;
pextra + = sprintf ( pextra , " \n Set power level :%d " , txpower ) ;
padapter - > mppriv . txpoweridx = ( u8 ) txpower ;
pMptCtx - > TxPwrLevel [ RF_PATH_A ] = ( u8 ) txpower ;
pMptCtx - > TxPwrLevel [ RF_PATH_B ] = ( u8 ) txpower ;
pMptCtx - > TxPwrLevel [ RF_PATH_C ] = ( u8 ) txpower ;
pMptCtx - > TxPwrLevel [ RF_PATH_D ] = ( u8 ) txpower ;
SetTxPower ( padapter ) ;
RTW_INFO ( " %s: bw=%d sg=%d \n " , __func__ , bandwidth , sg ) ;
if ( rate < = 0x7f )
rate = wifirate2_ratetbl_inx ( ( u8 ) rate ) ;
else if ( rate < 0xC8 )
rate = ( rate - 0x80 + MPT_RATE_MCS0 ) ;
/*HT rate 0x80(MCS0) ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
VHT1SS ~ 2 SS rate 0xA0 ( VHT1SS_MCS0 44 ) ~ 0xB3 ( VHT2SS_MCS9 # 63 ) 160 ~ 179
VHT rate 0xB4 ( VHT3SS_MCS0 64 ) ~ 0xC7 ( VHT2SS_MCS9 # 83 ) 180 ~ 199
else
VHT rate 0x90 ( VHT1SS_MCS0 ) ~ 0x99 ( VHT1SS_MCS9 ) 144 ~ 153
rate = ( rate - MPT_RATE_VHT1SS_MCS0 ) ;
*/
RTW_INFO ( " %s: rate index=%d \n " , __func__ , rate ) ;
if ( rate > = MPT_RATE_LAST )
return - EINVAL ;
pextra + = sprintf ( pextra , " \n Set data rate to %d index %d " , padapter - > mppriv . rateidx , rate ) ;
padapter - > mppriv . rateidx = rate ;
pMptCtx - > mpt_rate_index = rate ;
SetDataRate ( padapter ) ;
pextra + = sprintf ( pextra , " \n Set Antenna Path :%d " , ant ) ;
switch ( ant ) {
case 1 :
antenna = ANTENNA_A ;
break ;
case 2 :
antenna = ANTENNA_B ;
break ;
case 4 :
antenna = ANTENNA_C ;
break ;
case 8 :
antenna = ANTENNA_D ;
break ;
case 3 :
antenna = ANTENNA_AB ;
break ;
case 5 :
antenna = ANTENNA_AC ;
break ;
case 9 :
antenna = ANTENNA_AD ;
break ;
case 6 :
antenna = ANTENNA_BC ;
break ;
case 10 :
antenna = ANTENNA_BD ;
break ;
case 12 :
antenna = ANTENNA_CD ;
break ;
case 7 :
antenna = ANTENNA_ABC ;
break ;
case 14 :
antenna = ANTENNA_BCD ;
break ;
case 11 :
antenna = ANTENNA_ABD ;
break ;
case 15 :
antenna = ANTENNA_ABCD ;
break ;
}
RTW_INFO ( " %s: antenna=0x%x \n " , __func__ , antenna ) ;
padapter - > mppriv . antenna_tx = antenna ;
padapter - > mppriv . antenna_rx = antenna ;
pHalData - > antenna_tx_path = antenna ;
SetAntenna ( padapter ) ;
if ( txmode = = 0 )
pmp_priv - > mode = MP_CONTINUOUS_TX ;
else if ( txmode = = 1 ) {
pmp_priv - > mode = MP_PACKET_TX ;
pmp_priv - > tx . count = count ;
} else if ( txmode = = 2 )
pmp_priv - > mode = MP_SINGLE_TONE_TX ;
else if ( txmode = = 3 )
pmp_priv - > mode = MP_CARRIER_SUPPRISSION_TX ;
else if ( txmode = = 4 )
pmp_priv - > mode = MP_SINGLE_CARRIER_TX ;
status = rtw_mp_pretx_proc ( padapter , bStartTest , extra ) ;
}
}
wrqu - > data . length = strlen ( extra ) ;
return status ;
2017-05-11 18:47:23 +00:00
}
int rtw_mp_rx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
struct mp_priv * pmp_priv = & padapter - > mppriv ;
2019-11-09 10:12:08 +00:00
char * pextra = extra ;
2017-05-11 18:47:23 +00:00
u32 bandwidth = 0 , sg = 0 , channel = 6 , ant = 0 ;
u16 antenna = 0 ;
u8 bStartRx = 0 ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
2019-11-09 10:12:08 +00:00
return - EFAULT ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_CONCURRENT_MODE
2019-11-09 10:12:08 +00:00
if ( ! is_primary_adapter ( padapter ) ) {
sprintf ( extra , " Error: MP mode can't support Virtual Adapter, Please to use main Adapter. \n " ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
2017-05-11 18:47:23 +00:00
# endif
if ( strncmp ( extra , " stop " , 4 ) = = 0 ) {
_rtw_memset ( extra , 0 , wrqu - > data . length ) ;
SetPacketRx ( padapter , bStartRx , _FALSE ) ;
pmp_priv - > bmac_filter = _FALSE ;
sprintf ( extra , " Received packet OK:%d CRC error:%d ,Filter out:%d " , padapter - > mppriv . rx_pktcount , padapter - > mppriv . rx_crcerrpktcount , padapter - > mppriv . rx_pktcount_filter_out ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
} else if ( sscanf ( extra , " ch=%d,bw=%d,ant=%d " , & channel , & bandwidth , & ant ) < 3 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Invalid format [ch=%d,bw=%d,ant=%d] \n " , channel , bandwidth , ant ) ;
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , 0 , wrqu - > data . length ) ;
2019-11-09 10:12:08 +00:00
pextra + = sprintf ( pextra , " \n Please input correct format as bleow: \n " ) ;
pextra + = sprintf ( pextra , " \t ch=%d,bw=%d,ant=%d \n " , channel , bandwidth , ant ) ;
pextra + = sprintf ( pextra , " \n [ ch : BGN = <1~14> , A or AC = <36~165> ] " ) ;
pextra + = sprintf ( pextra , " \n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ] " ) ;
pextra + = sprintf ( pextra , " \n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12 " ) ;
2017-05-11 18:47:23 +00:00
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
} else {
2019-11-09 10:12:08 +00:00
char * pextra = extra ;
2017-05-11 18:47:23 +00:00
bStartRx = 1 ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Got format [ch=%d,bw=%d,ant=%d] \n " , channel , bandwidth , ant ) ;
2017-05-11 18:47:23 +00:00
_rtw_memset ( extra , 0 , wrqu - > data . length ) ;
sprintf ( extra , " Change Current channel %d to channel %d " , padapter - > mppriv . channel , channel ) ;
padapter - > mppriv . channel = channel ;
SetChannel ( padapter ) ;
2019-11-09 10:12:08 +00:00
pHalData - > current_channel = channel ;
2017-05-11 18:47:23 +00:00
if ( bandwidth = = 1 )
bandwidth = CHANNEL_WIDTH_40 ;
else if ( bandwidth = = 2 )
bandwidth = CHANNEL_WIDTH_80 ;
2019-11-09 10:12:08 +00:00
pextra = extra + strlen ( extra ) ;
pextra + = sprintf ( pextra , " \n Change Current Bandwidth %d to Bandwidth %d " , padapter - > mppriv . bandwidth , bandwidth ) ;
2017-05-11 18:47:23 +00:00
padapter - > mppriv . bandwidth = ( u8 ) bandwidth ;
padapter - > mppriv . preamble = sg ;
SetBandwidth ( padapter ) ;
2019-11-09 10:12:08 +00:00
pHalData - > current_channel_bw = bandwidth ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
pextra + = sprintf ( pextra , " \n Set Antenna Path :%d " , ant ) ;
2017-05-11 18:47:23 +00:00
switch ( ant ) {
case 1 :
antenna = ANTENNA_A ;
break ;
case 2 :
antenna = ANTENNA_B ;
break ;
case 4 :
antenna = ANTENNA_C ;
break ;
case 8 :
antenna = ANTENNA_D ;
break ;
case 3 :
antenna = ANTENNA_AB ;
break ;
case 5 :
antenna = ANTENNA_AC ;
break ;
case 9 :
antenna = ANTENNA_AD ;
break ;
case 6 :
antenna = ANTENNA_BC ;
break ;
case 10 :
antenna = ANTENNA_BD ;
break ;
case 12 :
antenna = ANTENNA_CD ;
break ;
case 7 :
antenna = ANTENNA_ABC ;
break ;
case 14 :
antenna = ANTENNA_BCD ;
break ;
case 11 :
antenna = ANTENNA_ABD ;
break ;
case 15 :
antenna = ANTENNA_ABCD ;
break ;
}
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: antenna=0x%x \n " , __func__ , antenna ) ;
2017-05-11 18:47:23 +00:00
padapter - > mppriv . antenna_tx = antenna ;
padapter - > mppriv . antenna_rx = antenna ;
2019-11-09 10:12:08 +00:00
pHalData - > antenna_tx_path = antenna ;
2017-05-11 18:47:23 +00:00
SetAntenna ( padapter ) ;
2019-11-09 10:12:08 +00:00
strcat ( extra , " \n start Rx " ) ;
2017-05-11 18:47:23 +00:00
SetPacketRx ( padapter , bStartRx , _FALSE ) ;
}
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_hwtx ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
struct mp_priv * pmp_priv = & padapter - > mppriv ;
2019-11-09 10:12:08 +00:00
PMPT_CONTEXT pMptCtx = & ( padapter - > mppriv . mpt_ctx ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
# if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
2017-05-11 18:47:23 +00:00
u8 input [ wrqu - > data . length ] ;
if ( copy_from_user ( input , wrqu - > data . pointer , wrqu - > data . length ) )
2019-11-09 10:12:08 +00:00
return - EFAULT ;
2017-05-11 18:47:23 +00:00
_rtw_memset ( & pMptCtx - > PMacTxInfo , 0 , sizeof ( RT_PMAC_TX_INFO ) ) ;
_rtw_memcpy ( ( void * ) & pMptCtx - > PMacTxInfo , ( void * ) input , sizeof ( RT_PMAC_TX_INFO ) ) ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( wrqu - > data . pointer , 0 , wrqu - > data . length ) ;
2017-05-11 18:47:23 +00:00
2019-11-09 10:12:08 +00:00
if ( pMptCtx - > PMacTxInfo . bEnPMacTx = = 1 & & pmp_priv - > mode ! = MP_ON ) {
sprintf ( extra , " MP Tx Running, Please Set PMac Tx Mode Stop \n " ) ;
RTW_INFO ( " Error !!! MP Tx Running, Please Set PMac Tx Mode Stop \n " ) ;
} else {
RTW_INFO ( " To set MAC Tx mode \n " ) ;
mpt_ProSetPMacTx ( padapter ) ;
sprintf ( extra , " Set PMac Tx Mode OK \n " ) ;
}
2017-05-11 18:47:23 +00:00
wrqu - > data . length = strlen ( extra ) ;
# endif
return 0 ;
}
2019-11-09 10:12:08 +00:00
int rtw_mp_pwrlmt ( struct net_device * dev ,
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
struct registry_priv * registry_par = & padapter - > registrypriv ;
u8 pwrlimtstat = 0 ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
* ( extra + wrqu - > data . length ) = ' \0 ' ;
# if CONFIG_TXPWR_LIMIT
pwrlimtstat = registry_par - > RegEnableTxPowerLimit ;
if ( strncmp ( extra , " off " , 3 ) = = 0 & & strlen ( extra ) < 4 ) {
padapter - > registrypriv . RegEnableTxPowerLimit = 0 ;
sprintf ( extra , " Turn off Power Limit \n " ) ;
} else if ( strncmp ( extra , " on " , 2 ) = = 0 & & strlen ( extra ) < 3 ) {
padapter - > registrypriv . RegEnableTxPowerLimit = 1 ;
sprintf ( extra , " Turn on Power Limit \n " ) ;
} else
# endif
sprintf ( extra , " Get Power Limit Status:%s \n " , ( pwrlimtstat = = 1 ) ? " ON " : " OFF " ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
int rtw_mp_pwrbyrate ( struct net_device * dev ,
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
* ( extra + wrqu - > data . length ) = ' \0 ' ;
if ( strncmp ( extra , " off " , 3 ) = = 0 & & strlen ( extra ) < 4 ) {
padapter - > registrypriv . RegEnableTxPowerByRate = 0 ;
sprintf ( extra , " Turn off Tx Power by Rate \n " ) ;
} else if ( strncmp ( extra , " on " , 2 ) = = 0 & & strlen ( extra ) < 3 ) {
padapter - > registrypriv . RegEnableTxPowerByRate = 1 ;
sprintf ( extra , " Turn On Tx Power by Rate \n " ) ;
} else {
sprintf ( extra , " Get Power by Rate Status:%s \n " , ( padapter - > registrypriv . RegEnableTxPowerByRate = = 1 ) ? " ON " : " OFF " ) ;
}
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
2017-05-11 18:47:23 +00:00
int rtw_efuse_mask_file ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
char * rtw_efuse_mask_file_path ;
u8 Status ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
2017-05-11 18:47:23 +00:00
_rtw_memset ( maskfileBuffer , 0x00 , sizeof ( maskfileBuffer ) ) ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
* ( extra + wrqu - > data . length ) = ' \0 ' ;
2017-05-11 18:47:23 +00:00
if ( strncmp ( extra , " off " , 3 ) = = 0 & & strlen ( extra ) < 4 ) {
padapter - > registrypriv . boffefusemask = 1 ;
sprintf ( extra , " Turn off Efuse Mask \n " ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
if ( strncmp ( extra , " on " , 2 ) = = 0 & & strlen ( extra ) < 3 ) {
padapter - > registrypriv . boffefusemask = 0 ;
sprintf ( extra , " Turn on Efuse Mask \n " ) ;
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
2019-11-09 10:12:08 +00:00
if ( strncmp ( extra , " data, " , 5 ) = = 0 ) {
2021-02-06 10:06:22 +00:00
char * pextra = extra ;
2019-11-09 10:12:08 +00:00
u8 * pch ;
char * ptmp , tmp ;
u8 count = 0 ;
u8 i = 0 ;
ptmp = extra ;
pch = strsep ( & ptmp , " , " ) ;
if ( ( pch = = NULL ) | | ( strlen ( pch ) = = 0 ) ) {
RTW_INFO ( " %s: parameter error(no cmd)! \n " , __func__ ) ;
return - EFAULT ;
}
do {
pch = strsep ( & ptmp , " : " ) ;
if ( ( pch = = NULL ) | | ( strlen ( pch ) = = 0 ) )
break ;
if ( strlen ( pch ) ! = 2
| | IsHexDigit ( * pch ) = = _FALSE
| | IsHexDigit ( * ( pch + 1 ) ) = = _FALSE
| | sscanf ( pch , " %hhx " , & tmp ) ! = 1
) {
RTW_INFO ( " %s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef... \n " , __func__ ) ;
return - EFAULT ;
}
maskfileBuffer [ count + + ] = tmp ;
} while ( count < 64 ) ;
for ( i = 0 ; i < count ; i + + )
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " :%02x " , maskfileBuffer [ i ] ) ;
2019-11-09 10:12:08 +00:00
padapter - > registrypriv . bFileMaskEfuse = _TRUE ;
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " \n Load Efuse Mask data %d hex ok \n " , count ) ;
2019-11-09 10:12:08 +00:00
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
2017-05-11 18:47:23 +00:00
rtw_efuse_mask_file_path = extra ;
if ( rtw_is_file_readable ( rtw_efuse_mask_file_path ) = = _TRUE ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s do rtw_efuse_mask_file_read = %s! ,sizeof maskfileBuffer %zu \n " , __func__ , rtw_efuse_mask_file_path , sizeof ( maskfileBuffer ) ) ;
2017-05-11 18:47:23 +00:00
Status = rtw_efuse_file_read ( padapter , rtw_efuse_mask_file_path , maskfileBuffer , sizeof ( maskfileBuffer ) ) ;
2019-11-09 10:12:08 +00:00
if ( Status = = _TRUE ) {
2017-05-11 18:47:23 +00:00
padapter - > registrypriv . bFileMaskEfuse = _TRUE ;
2019-11-09 10:12:08 +00:00
sprintf ( extra , " efuse mask file read OK \n " ) ;
} else {
padapter - > registrypriv . bFileMaskEfuse = _FALSE ;
sprintf ( extra , " read efuse mask file FAIL \n " ) ;
RTW_INFO ( " %s rtw_efuse_file_read mask fail! \n " , __func__ ) ;
}
2017-05-11 18:47:23 +00:00
} else {
padapter - > registrypriv . bFileMaskEfuse = _FALSE ;
sprintf ( extra , " efuse mask file readable FAIL \n " ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s rtw_is_file_readable fail! \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
}
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
int rtw_efuse_file_map ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
char * rtw_efuse_file_map_path ;
u8 Status ;
PEFUSE_HAL pEfuseHal ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
2019-11-09 10:12:08 +00:00
struct mp_priv * pmp_priv = & padapter - > mppriv ;
2017-05-11 18:47:23 +00:00
pEfuseHal = & pHalData - > EfuseHal ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
rtw_efuse_file_map_path = extra ;
2019-11-09 10:12:08 +00:00
_rtw_memset ( pEfuseHal - > fakeEfuseModifiedMap , 0xFF , EFUSE_MAX_MAP_LEN ) ;
2017-05-11 18:47:23 +00:00
if ( rtw_is_file_readable ( rtw_efuse_file_map_path ) = = _TRUE ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s do rtw_efuse_mask_file_read = %s! \n " , __func__ , rtw_efuse_file_map_path ) ;
2017-05-11 18:47:23 +00:00
Status = rtw_efuse_file_read ( padapter , rtw_efuse_file_map_path , pEfuseHal - > fakeEfuseModifiedMap , sizeof ( pEfuseHal - > fakeEfuseModifiedMap ) ) ;
2019-11-09 10:12:08 +00:00
if ( Status = = _TRUE ) {
pmp_priv - > bloadefusemap = _TRUE ;
2017-05-11 18:47:23 +00:00
sprintf ( extra , " efuse file file_read OK \n " ) ;
2019-11-09 10:12:08 +00:00
} else {
pmp_priv - > bloadefusemap = _FALSE ;
2017-05-11 18:47:23 +00:00
sprintf ( extra , " efuse file file_read FAIL \n " ) ;
2019-11-09 10:12:08 +00:00
}
2017-05-11 18:47:23 +00:00
} else {
sprintf ( extra , " efuse file readable FAIL \n " ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s rtw_is_file_readable fail! \n " , __func__ ) ;
}
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
int rtw_bt_efuse_file_map ( struct net_device * dev ,
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
{
char * rtw_efuse_file_map_path ;
u8 Status ;
PEFUSE_HAL pEfuseHal ;
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
struct mp_priv * pmp_priv = & padapter - > mppriv ;
pEfuseHal = & pHalData - > EfuseHal ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
rtw_efuse_file_map_path = extra ;
_rtw_memset ( pEfuseHal - > fakeBTEfuseModifiedMap , 0xFF , EFUSE_BT_MAX_MAP_LEN ) ;
if ( rtw_is_file_readable ( rtw_efuse_file_map_path ) = = _TRUE ) {
RTW_INFO ( " %s do rtw_efuse_mask_file_read = %s! \n " , __func__ , rtw_efuse_file_map_path ) ;
Status = rtw_efuse_file_read ( padapter , rtw_efuse_file_map_path , pEfuseHal - > fakeBTEfuseModifiedMap , sizeof ( pEfuseHal - > fakeBTEfuseModifiedMap ) ) ;
if ( Status = = _TRUE ) {
pmp_priv - > bloadBTefusemap = _TRUE ;
sprintf ( extra , " BT efuse file file_read OK \n " ) ;
} else {
pmp_priv - > bloadBTefusemap = _FALSE ;
sprintf ( extra , " BT efuse file file_read FAIL \n " ) ;
}
} else {
sprintf ( extra , " BT efuse file readable FAIL \n " ) ;
RTW_INFO ( " %s rtw_is_file_readable fail! \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
}
wrqu - > data . length = strlen ( extra ) ;
return 0 ;
}
# if defined(CONFIG_RTL8723B)
int rtw_mp_SetBT ( struct net_device * dev ,
2019-11-09 10:12:08 +00:00
struct iw_request_info * info ,
union iwreq_data * wrqu , char * extra )
2017-05-11 18:47:23 +00:00
{
PADAPTER padapter = rtw_netdev_priv ( dev ) ;
2019-11-09 10:12:08 +00:00
struct hal_ops * pHalFunc = & padapter - > hal_func ;
2017-05-11 18:47:23 +00:00
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( padapter ) ;
BT_REQ_CMD BtReq ;
2019-11-09 10:12:08 +00:00
PMPT_CONTEXT pMptCtx = & ( padapter - > mppriv . mpt_ctx ) ;
2017-05-11 18:47:23 +00:00
PBT_RSP_CMD pBtRsp = ( PBT_RSP_CMD ) & pMptCtx - > mptOutBuf [ 0 ] ;
char input [ 128 ] ;
char * pch , * ptmp , * token , * tmp [ 2 ] = { 0x00 , 0x00 } ;
u8 setdata [ 100 ] ;
u8 resetbt = 0x00 ;
u8 tempval , BTStatus ;
u8 H2cSetbtmac [ 6 ] ;
u8 u1H2CBtMpOperParm [ 4 ] = { 0x01 } ;
int testmode = 1 , ready = 1 , trxparam = 1 , setgen = 1 , getgen = 1 , testctrl = 1 , testbt = 1 , readtherm = 1 , setbtmac = 1 ;
u32 i = 0 , ii = 0 , jj = 0 , kk = 0 , cnts = 0 , status = 0 ;
PRT_MP_FIRMWARE pBTFirmware = NULL ;
if ( copy_from_user ( extra , wrqu - > data . pointer , wrqu - > data . length ) )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
* ( extra + wrqu - > data . length ) = ' \0 ' ;
2017-05-11 18:47:23 +00:00
if ( strlen ( extra ) < 1 )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s:iwpriv in=%s \n " , __func__ , extra ) ;
2017-05-11 18:47:23 +00:00
ready = strncmp ( extra , " ready " , 5 ) ;
testmode = strncmp ( extra , " testmode " , 8 ) ; /* strncmp TRUE is 0*/
trxparam = strncmp ( extra , " trxparam " , 8 ) ;
setgen = strncmp ( extra , " setgen " , 6 ) ;
getgen = strncmp ( extra , " getgen " , 6 ) ;
testctrl = strncmp ( extra , " testctrl " , 8 ) ;
testbt = strncmp ( extra , " testbt " , 6 ) ;
readtherm = strncmp ( extra , " readtherm " , 9 ) ;
setbtmac = strncmp ( extra , " setbtmac " , 8 ) ;
if ( strncmp ( extra , " dlbt " , 4 ) = = 0 ) {
pHalData - > LastHMEBoxNum = 0 ;
2019-11-09 10:12:08 +00:00
pHalData - > bBTFWReady = _FALSE ;
2017-05-11 18:47:23 +00:00
rtw_write8 ( padapter , 0xa3 , 0x05 ) ;
BTStatus = rtw_read8 ( padapter , 0xa0 ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: btwmap before read 0xa0 BT Status =0x%x \n " , __func__ , BTStatus ) ;
2017-05-11 18:47:23 +00:00
if ( BTStatus ! = 0x04 ) {
sprintf ( extra , " BT Status not Active DLFW FAIL \n " ) ;
goto exit ;
}
tempval = rtw_read8 ( padapter , 0x6B ) ;
tempval | = BIT7 ;
rtw_write8 ( padapter , 0x6B , tempval ) ;
/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
rtw_usleep_os ( 100 ) ;
/* disable BT power cut*/
/* 0x6A[14] = 0*/
tempval = rtw_read8 ( padapter , 0x6B ) ;
tempval & = ~ BIT6 ;
rtw_write8 ( padapter , 0x6B , tempval ) ;
rtw_usleep_os ( 100 ) ;
MPT_PwrCtlDM ( padapter , 0 ) ;
rtw_write32 ( padapter , 0xcc , ( rtw_read32 ( padapter , 0xcc ) | 0x00000004 ) ) ;
rtw_write32 ( padapter , 0x6b , ( rtw_read32 ( padapter , 0x6b ) & 0xFFFFFFEF ) ) ;
rtw_msleep_os ( 600 ) ;
rtw_write32 ( padapter , 0x6b , ( rtw_read32 ( padapter , 0x6b ) | 0x00000010 ) ) ;
rtw_write32 ( padapter , 0xcc , ( rtw_read32 ( padapter , 0xcc ) & 0xFFFFFFFB ) ) ;
rtw_msleep_os ( 1200 ) ;
pBTFirmware = ( PRT_MP_FIRMWARE ) rtw_zmalloc ( sizeof ( RT_MP_FIRMWARE ) ) ;
if ( pBTFirmware = = NULL )
goto exit ;
2019-11-09 10:12:08 +00:00
pHalData - > bBTFWReady = _FALSE ;
2017-05-11 18:47:23 +00:00
FirmwareDownloadBT ( padapter , pBTFirmware ) ;
if ( pBTFirmware )
rtw_mfree ( ( u8 * ) pBTFirmware , sizeof ( RT_MP_FIRMWARE ) ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Wait for FirmwareDownloadBT fw boot! \n " ) ;
2017-05-11 18:47:23 +00:00
rtw_msleep_os ( 2000 ) ;
_rtw_memset ( extra , ' \0 ' , wrqu - > data . length ) ;
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 0 ;
BtReq . paraLength = 0 ;
mptbt_BtControlProcess ( padapter , & BtReq ) ;
rtw_msleep_os ( 100 ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " FirmwareDownloadBT ready = 0x%x 0x%x " , pMptCtx - > mptOutBuf [ 4 ] , pMptCtx - > mptOutBuf [ 5 ] ) ;
2017-05-11 18:47:23 +00:00
if ( ( pMptCtx - > mptOutBuf [ 4 ] = = 0x00 ) & & ( pMptCtx - > mptOutBuf [ 5 ] = = 0x00 ) ) {
if ( padapter - > mppriv . bTxBufCkFail = = _TRUE )
sprintf ( extra , " check TxBuf Fail. \n " ) ;
else
sprintf ( extra , " download FW Fail. \n " ) ;
} else {
sprintf ( extra , " download FW OK. \n " ) ;
goto exit ;
}
goto exit ;
}
if ( strncmp ( extra , " dlfw " , 4 ) = = 0 ) {
pHalData - > LastHMEBoxNum = 0 ;
2019-11-09 10:12:08 +00:00
pHalData - > bBTFWReady = _FALSE ;
2017-05-11 18:47:23 +00:00
rtw_write8 ( padapter , 0xa3 , 0x05 ) ;
BTStatus = rtw_read8 ( padapter , 0xa0 ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: btwmap before read 0xa0 BT Status =0x%x \n " , __func__ , BTStatus ) ;
2017-05-11 18:47:23 +00:00
if ( BTStatus ! = 0x04 ) {
sprintf ( extra , " BT Status not Active DLFW FAIL \n " ) ;
goto exit ;
}
tempval = rtw_read8 ( padapter , 0x6B ) ;
tempval | = BIT7 ;
rtw_write8 ( padapter , 0x6B , tempval ) ;
/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
rtw_usleep_os ( 100 ) ;
/* disable BT power cut*/
/* 0x6A[14] = 0*/
tempval = rtw_read8 ( padapter , 0x6B ) ;
tempval & = ~ BIT6 ;
rtw_write8 ( padapter , 0x6B , tempval ) ;
rtw_usleep_os ( 100 ) ;
MPT_PwrCtlDM ( padapter , 0 ) ;
rtw_write32 ( padapter , 0xcc , ( rtw_read32 ( padapter , 0xcc ) | 0x00000004 ) ) ;
rtw_write32 ( padapter , 0x6b , ( rtw_read32 ( padapter , 0x6b ) & 0xFFFFFFEF ) ) ;
rtw_msleep_os ( 600 ) ;
rtw_write32 ( padapter , 0x6b , ( rtw_read32 ( padapter , 0x6b ) | 0x00000010 ) ) ;
rtw_write32 ( padapter , 0xcc , ( rtw_read32 ( padapter , 0xcc ) & 0xFFFFFFFB ) ) ;
rtw_msleep_os ( 1200 ) ;
# if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
/* Pull up BT reset pin.*/
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: pull up BT reset pin when bt start mp test \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
rtw_wifi_gpio_wlan_ctrl ( WLAN_BT_PWDN_ON ) ;
# endif
2019-11-09 10:12:08 +00:00
RTW_INFO ( " FirmwareDownload! \n " ) ;
2017-05-11 18:47:23 +00:00
# if defined(CONFIG_RTL8723B)
status = rtl8723b_FirmwareDownload ( padapter , _FALSE ) ;
# endif
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Wait for FirmwareDownloadBT fw boot! \n " ) ;
2017-05-11 18:47:23 +00:00
rtw_msleep_os ( 1000 ) ;
# ifdef CONFIG_BT_COEXIST
rtw_btcoex_HaltNotify ( padapter ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " SetBT btcoex HaltNotify ! \n " ) ;
2017-05-11 18:47:23 +00:00
/*hal_btcoex1ant_SetAntPath(padapter);*/
rtw_btcoex_SetManualControl ( padapter , _TRUE ) ;
# endif
_rtw_memset ( extra , ' \0 ' , wrqu - > data . length ) ;
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 0 ;
BtReq . paraLength = 0 ;
mptbt_BtControlProcess ( padapter , & BtReq ) ;
rtw_msleep_os ( 200 ) ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " FirmwareDownloadBT ready = 0x%x 0x%x " , pMptCtx - > mptOutBuf [ 4 ] , pMptCtx - > mptOutBuf [ 5 ] ) ;
2017-05-11 18:47:23 +00:00
if ( ( pMptCtx - > mptOutBuf [ 4 ] = = 0x00 ) & & ( pMptCtx - > mptOutBuf [ 5 ] = = 0x00 ) ) {
if ( padapter - > mppriv . bTxBufCkFail = = _TRUE )
sprintf ( extra , " check TxBuf Fail. \n " ) ;
else
sprintf ( extra , " download FW Fail. \n " ) ;
} else {
# ifdef CONFIG_BT_COEXIST
rtw_btcoex_SwitchBtTRxMask ( padapter ) ;
# endif
rtw_msleep_os ( 200 ) ;
sprintf ( extra , " download FW OK. \n " ) ;
goto exit ;
}
goto exit ;
}
if ( strncmp ( extra , " down " , 4 ) = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " SetBT down for to hal_init ! \n " ) ;
2017-05-11 18:47:23 +00:00
# ifdef CONFIG_BT_COEXIST
rtw_btcoex_SetManualControl ( padapter , _FALSE ) ;
rtw_btcoex_Initialize ( padapter ) ;
# endif
pHalFunc - > read_adapter_info ( padapter ) ;
pHalFunc - > hal_deinit ( padapter ) ;
pHalFunc - > hal_init ( padapter ) ;
rtw_pm_set_ips ( padapter , IPS_NONE ) ;
LeaveAllPowerSaveMode ( padapter ) ;
MPT_PwrCtlDM ( padapter , 0 ) ;
rtw_write32 ( padapter , 0xcc , ( rtw_read32 ( padapter , 0xcc ) | 0x00000004 ) ) ;
rtw_write32 ( padapter , 0x6b , ( rtw_read32 ( padapter , 0x6b ) & 0xFFFFFFEF ) ) ;
rtw_msleep_os ( 600 ) ;
/*rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));*/
rtw_write32 ( padapter , 0x6b , ( rtw_read32 ( padapter , 0x6b ) | 0x00000010 ) ) ;
rtw_write32 ( padapter , 0xcc , ( rtw_read32 ( padapter , 0xcc ) & 0xFFFFFFFB ) ) ;
rtw_msleep_os ( 1200 ) ;
goto exit ;
}
if ( strncmp ( extra , " disable " , 7 ) = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " SetBT disable ! \n " ) ;
2017-05-11 18:47:23 +00:00
rtw_write32 ( padapter , 0x6a , ( rtw_read32 ( padapter , 0x6a ) & 0xFFFFFFFB ) ) ;
rtw_msleep_os ( 500 ) ;
goto exit ;
}
if ( strncmp ( extra , " enable " , 6 ) = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " SetBT enable ! \n " ) ;
2017-05-11 18:47:23 +00:00
rtw_write32 ( padapter , 0x6a , ( rtw_read32 ( padapter , 0x6a ) | 0x00000004 ) ) ;
rtw_msleep_os ( 500 ) ;
goto exit ;
}
if ( strncmp ( extra , " h2c " , 3 ) = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " SetBT h2c ! \n " ) ;
pHalData - > bBTFWReady = _TRUE ;
2017-05-11 18:47:23 +00:00
rtw_hal_fill_h2c_cmd ( padapter , 0x63 , 1 , u1H2CBtMpOperParm ) ;
goto exit ;
}
if ( strncmp ( extra , " 2ant " , 4 ) = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " Set BT 2ant use! \n " ) ;
phy_set_mac_reg ( padapter , 0x67 , BIT5 , 0x1 ) ;
2017-05-11 18:47:23 +00:00
rtw_write32 ( padapter , 0x948 , 0000 ) ;
goto exit ;
}
if ( ready ! = 0 & & testmode ! = 0 & & trxparam ! = 0 & & setgen ! = 0 & & getgen ! = 0 & & testctrl ! = 0 & & testbt ! = 0 & & readtherm ! = 0 & & setbtmac ! = 0 )
return - EFAULT ;
if ( testbt = = 0 ) {
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 6 ;
BtReq . paraLength = cnts / 2 ;
goto todo ;
}
if ( ready = = 0 ) {
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 0 ;
BtReq . paraLength = 0 ;
goto todo ;
}
pch = extra ;
i = 0 ;
while ( ( token = strsep ( & pch , " , " ) ) ! = NULL ) {
if ( i > 1 )
break ;
tmp [ i ] = token ;
i + + ;
}
if ( ( tmp [ 0 ] ! = NULL ) & & ( tmp [ 1 ] ! = NULL ) ) {
cnts = strlen ( tmp [ 1 ] ) ;
if ( cnts < 1 )
return - EFAULT ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: cnts=%d \n " , __func__ , cnts ) ;
RTW_INFO ( " %s: data=%s \n " , __func__ , tmp [ 1 ] ) ;
2017-05-11 18:47:23 +00:00
for ( jj = 0 , kk = 0 ; jj < cnts ; jj + + , kk + = 2 ) {
BtReq . pParamStart [ jj ] = key_2char2num ( tmp [ 1 ] [ kk ] , tmp [ 1 ] [ kk + 1 ] ) ;
2019-11-09 10:12:08 +00:00
/* RTW_INFO("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);*/
2017-05-11 18:47:23 +00:00
}
2019-11-09 10:12:08 +00:00
} else
2017-05-11 18:47:23 +00:00
return - EFAULT ;
2019-11-09 10:12:08 +00:00
2017-05-11 18:47:23 +00:00
if ( testmode = = 0 ) {
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 1 ;
BtReq . paraLength = 1 ;
}
if ( trxparam = = 0 ) {
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 2 ;
BtReq . paraLength = cnts / 2 ;
}
if ( setgen = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: BT_SET_GENERAL \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 3 ; /*BT_SET_GENERAL 3*/
BtReq . paraLength = cnts / 2 ;
}
if ( getgen = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: BT_GET_GENERAL \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 4 ; /*BT_GET_GENERAL 4*/
BtReq . paraLength = cnts / 2 ;
}
if ( readtherm = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: BT_GET_GENERAL \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 4 ; /*BT_GET_GENERAL 4*/
BtReq . paraLength = cnts / 2 ;
}
if ( testctrl = = 0 ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: BT_TEST_CTRL \n " , __func__ ) ;
2017-05-11 18:47:23 +00:00
BtReq . opCodeVer = 1 ;
BtReq . OpCode = 5 ; /*BT_TEST_CTRL 5*/
BtReq . paraLength = cnts / 2 ;
}
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: Req opCodeVer=%d OpCode=%d paraLength=%d \n " ,
__func__ , BtReq . opCodeVer , BtReq . OpCode , BtReq . paraLength ) ;
2017-05-11 18:47:23 +00:00
if ( BtReq . paraLength < 1 )
goto todo ;
for ( i = 0 ; i < BtReq . paraLength ; i + + ) {
2019-11-09 10:12:08 +00:00
RTW_INFO ( " %s: BtReq.pParamStart[%d] = 0x%02x \n " ,
__func__ , i , BtReq . pParamStart [ i ] ) ;
2017-05-11 18:47:23 +00:00
}
todo :
_rtw_memset ( extra , ' \0 ' , wrqu - > data . length ) ;
2019-11-09 10:12:08 +00:00
if ( pHalData - > bBTFWReady = = _FALSE ) {
2017-05-11 18:47:23 +00:00
sprintf ( extra , " BTFWReady = FALSE. \n " ) ;
goto exit ;
}
mptbt_BtControlProcess ( padapter , & BtReq ) ;
if ( readtherm = = 0 ) {
2021-02-06 10:06:22 +00:00
char * pextra = extra ;
pextra + = sprintf ( pextra , " BT thermal= " ) ;
2017-05-11 18:47:23 +00:00
for ( i = 4 ; i < pMptCtx - > mptOutLen ; i + + ) {
if ( ( pMptCtx - > mptOutBuf [ i ] = = 0x00 ) & & ( pMptCtx - > mptOutBuf [ i + 1 ] = = 0x00 ) )
goto exit ;
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " %d " , ( pMptCtx - > mptOutBuf [ i ] & 0x1f ) ) ;
2017-05-11 18:47:23 +00:00
}
} else {
2021-02-06 10:06:22 +00:00
char * pextra = extra + strlen ( extra ) ;
2017-05-11 18:47:23 +00:00
for ( i = 4 ; i < pMptCtx - > mptOutLen ; i + + )
2021-02-06 10:06:22 +00:00
pextra + = sprintf ( pextra , " 0x%x " , pMptCtx - > mptOutBuf [ i ] ) ;
2017-05-11 18:47:23 +00:00
}
exit :
wrqu - > data . length = strlen ( extra ) + 1 ;
2019-11-09 10:12:08 +00:00
RTW_INFO ( " -%s: output len=%d data=%s \n " , __func__ , wrqu - > data . length , extra ) ;
2017-05-11 18:47:23 +00:00
return status ;
}
# endif /*#ifdef CONFIG_RTL8723B*/
# endif