Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/ioctl_mp.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#if defined(CONFIG_MP_INCLUDED)1516#include <drv_types.h>17#include <rtw_mp.h>18#include "../../hal/phydm/phydm_precomp.h"192021#if defined(CONFIG_RTL8723B)22#include <rtw_bt_mp.h>23#endif2425/*26* Input Format: %s,%d,%d27* %s is width, could be28* "b" for 1 byte29* "w" for WORD (2 bytes)30* "dw" for DWORD (4 bytes)31* 1st %d is address(offset)32* 2st %d is data to write33*/34int rtw_mp_write_reg(struct net_device *dev,35struct iw_request_info *info,36struct iw_point *wrqu, char *extra)37{38char *pch, *pnext;39char *width_str;40char width;41u32 addr, data;42int ret;43PADAPTER padapter = rtw_netdev_priv(dev);44char input[wrqu->length + 1];4546_rtw_memset(input, 0, sizeof(input));4748if (copy_from_user(input, wrqu->pointer, wrqu->length))49return -EFAULT;5051input[wrqu->length] = '\0';5253_rtw_memset(extra, 0, wrqu->length);5455pch = input;5657pnext = strpbrk(pch, " ,.-");58if (pnext == NULL)59return -EINVAL;60*pnext = 0;61width_str = pch;6263pch = pnext + 1;64pnext = strpbrk(pch, " ,.-");65if (pnext == NULL)66return -EINVAL;67*pnext = 0;68/*addr = simple_strtoul(pch, &ptmp, 16);69_rtw_memset(buf, '\0', sizeof(buf));70_rtw_memcpy(buf, pch, pnext-pch);71ret = kstrtoul(buf, 16, &addr);*/72ret = sscanf(pch, "%x", &addr);73if (addr > 0x3FFF)74return -EINVAL;7576pch = pnext + 1;77pnext = strpbrk(pch, " ,.-");78if ((pch - input) >= wrqu->length)79return -EINVAL;80/*data = simple_strtoul(pch, &ptmp, 16);*/81ret = sscanf(pch, "%x", &data);82RTW_INFO("data=%x,addr=%x\n", (u32)data, (u32)addr);83ret = 0;84width = width_str[0];85switch (width) {86case 'b':87/* 1 byte*/88if (data > 0xFF) {89ret = -EINVAL;90break;91}92rtw_write8(padapter, addr, data);93break;94case 'w':95/* 2 bytes*/96if (data > 0xFFFF) {97ret = -EINVAL;98break;99}100rtw_write16(padapter, addr, data);101break;102case 'd':103/* 4 bytes*/104rtw_write32(padapter, addr, data);105break;106default:107ret = -EINVAL;108break;109}110111return ret;112}113114115/*116* Input Format: %s,%d117* %s is width, could be118* "b" for 1 byte119* "w" for WORD (2 bytes)120* "dw" for DWORD (4 bytes)121* %d is address(offset)122*123* Return:124* %d for data readed125*/126int rtw_mp_read_reg(struct net_device *dev,127struct iw_request_info *info,128struct iw_point *wrqu, char *extra)129{130char input[wrqu->length + 1];131char *pch, *pnext;132char *width_str;133char width;134char data[20], tmp[20];135u32 addr = 0, strtout = 0;136u32 i = 0, j = 0, ret = 0, data32 = 0;137PADAPTER padapter = rtw_netdev_priv(dev);138char *pextra = extra;139140if (wrqu->length > 128)141return -EFAULT;142143_rtw_memset(input, 0, sizeof(input));144if (copy_from_user(input, wrqu->pointer, wrqu->length))145return -EFAULT;146147input[wrqu->length] = '\0';148_rtw_memset(extra, 0, wrqu->length);149_rtw_memset(data, '\0', sizeof(data));150_rtw_memset(tmp, '\0', sizeof(tmp));151pch = input;152pnext = strpbrk(pch, " ,.-");153if (pnext == NULL)154return -EINVAL;155*pnext = 0;156width_str = pch;157158pch = pnext + 1;159160ret = sscanf(pch, "%x", &addr);161if (addr > MP_READ_REG_MAX_OFFSET)162return -EINVAL;163164ret = 0;165width = width_str[0];166167switch (width) {168case 'b':169data32 = rtw_read8(padapter, addr);170RTW_INFO("%x\n", data32);171sprintf(extra, "%d", data32);172wrqu->length = strlen(extra);173break;174case 'w':175/* 2 bytes*/176sprintf(data, "%04x\n", rtw_read16(padapter, addr));177178for (i = 0 ; i <= strlen(data) ; i++) {179if (i % 2 == 0) {180tmp[j] = ' ';181j++;182}183if (data[i] != '\0')184tmp[j] = data[i];185186j++;187}188pch = tmp;189RTW_INFO("pch=%s", pch);190191while (*pch != '\0') {192pnext = strpbrk(pch, " ");193if (!pnext || ((pnext - tmp) > 4))194break;195196pnext++;197if (*pnext != '\0') {198/*strtout = simple_strtoul(pnext , &ptmp, 16);*/199ret = sscanf(pnext, "%x", &strtout);200pextra += sprintf(pextra, " %d", strtout);201} else202break;203pch = pnext;204}205wrqu->length = strlen(extra);206break;207case 'd':208/* 4 bytes */209sprintf(data, "%08x", rtw_read32(padapter, addr));210/*add read data format blank*/211for (i = 0 ; i <= strlen(data) ; i++) {212if (i % 2 == 0) {213tmp[j] = ' ';214j++;215}216if (data[i] != '\0')217tmp[j] = data[i];218219j++;220}221pch = tmp;222RTW_INFO("pch=%s", pch);223224while (*pch != '\0') {225pnext = strpbrk(pch, " ");226if (!pnext)227break;228229pnext++;230if (*pnext != '\0') {231ret = sscanf(pnext, "%x", &strtout);232pextra += sprintf(pextra, " %d", strtout);233} else234break;235pch = pnext;236}237wrqu->length = strlen(extra);238break;239240default:241wrqu->length = 0;242ret = -EINVAL;243break;244}245246return ret;247}248249250/*251* Input Format: %d,%x,%x252* %d is RF path, should be smaller than MAX_RF_PATH_NUMS253* 1st %x is address(offset)254* 2st %x is data to write255*/256int rtw_mp_write_rf(struct net_device *dev,257struct iw_request_info *info,258struct iw_point *wrqu, char *extra)259{260261u32 path, addr, data;262int ret;263PADAPTER padapter = rtw_netdev_priv(dev);264char input[wrqu->length];265266267_rtw_memset(input, 0, wrqu->length);268if (copy_from_user(input, wrqu->pointer, wrqu->length))269return -EFAULT;270271272ret = sscanf(input, "%d,%x,%x", &path, &addr, &data);273if (ret < 3)274return -EINVAL;275276if (path >= GET_HAL_RFPATH_NUM(padapter))277return -EINVAL;278if (addr > 0xFF)279return -EINVAL;280if (data > 0xFFFFF)281return -EINVAL;282283_rtw_memset(extra, 0, wrqu->length);284285write_rfreg(padapter, path, addr, data);286287sprintf(extra, "write_rf completed\n");288wrqu->length = strlen(extra);289290return 0;291}292293294/*295* Input Format: %d,%x296* %d is RF path, should be smaller than MAX_RF_PATH_NUMS297* %x is address(offset)298*299* Return:300* %d for data readed301*/302int rtw_mp_read_rf(struct net_device *dev,303struct iw_request_info *info,304struct iw_point *wrqu, char *extra)305{306char input[wrqu->length];307char *pch, *pnext;308char data[20], tmp[20];309u32 path, addr, strtou;310u32 ret, i = 0 , j = 0;311PADAPTER padapter = rtw_netdev_priv(dev);312char *pextra = extra;313314if (wrqu->length > 128)315return -EFAULT;316_rtw_memset(input, 0, wrqu->length);317if (copy_from_user(input, wrqu->pointer, wrqu->length))318return -EFAULT;319320ret = sscanf(input, "%d,%x", &path, &addr);321if (ret < 2)322return -EINVAL;323324if (path >= GET_HAL_RFPATH_NUM(padapter))325return -EINVAL;326327if (addr > MP_READ_REG_MAX_OFFSET)328return -EINVAL;329330_rtw_memset(extra, 0, wrqu->length);331332sprintf(data, "%08x", read_rfreg(padapter, path, addr));333/*add read data format blank*/334for (i = 0 ; i <= strlen(data) ; i++) {335if (i % 2 == 0) {336tmp[j] = ' ';337j++;338}339tmp[j] = data[i];340j++;341}342pch = tmp;343RTW_INFO("pch=%s", pch);344345while (*pch != '\0') {346pnext = strpbrk(pch, " ");347if (!pnext)348break;349pnext++;350if (*pnext != '\0') {351/*strtou =simple_strtoul(pnext , &ptmp, 16);*/352ret = sscanf(pnext, "%x", &strtou);353pextra += sprintf(pextra, " %d", strtou);354} else355break;356pch = pnext;357}358wrqu->length = strlen(extra);359360return 0;361}362363364int rtw_mp_start(struct net_device *dev,365struct iw_request_info *info,366struct iw_point *wrqu, char *extra)367{368int ret = 0;369PADAPTER padapter = rtw_netdev_priv(dev);370struct mp_priv *pmppriv = &padapter->mppriv;371372rtw_pm_set_ips(padapter, IPS_NONE);373LeaveAllPowerSaveMode(padapter);374375pmppriv->bprocess_mp_mode = _TRUE;376377if (rtw_mi_check_fwstate(padapter, _FW_UNDER_SURVEY)) {378rtw_mi_buddy_set_scan_deny(padapter, 5000);379rtw_mi_scan_abort(padapter, _TRUE);380}381382if (rtw_mp_cmd(padapter, MP_START, RTW_CMDF_WAIT_ACK) != _SUCCESS)383ret = -EPERM;384385_rtw_memset(extra, 0, wrqu->length);386sprintf(extra, "mp_start %s\n", ret == 0 ? "ok" : "fail");387wrqu->length = strlen(extra);388389return ret;390}391392393394int rtw_mp_stop(struct net_device *dev,395struct iw_request_info *info,396struct iw_point *wrqu, char *extra)397{398int ret = 0;399PADAPTER padapter = rtw_netdev_priv(dev);400struct mp_priv *pmppriv = &padapter->mppriv;401402if (rtw_mp_cmd(padapter, MP_STOP, RTW_CMDF_WAIT_ACK) != _SUCCESS)403ret = -EPERM;404405if (pmppriv->mode != MP_ON)406return -EPERM;407408pmppriv->bprocess_mp_mode = _FALSE;409_rtw_memset(extra, 0, wrqu->length);410sprintf(extra, "mp_stop %s\n", ret == 0 ? "ok" : "fail");411wrqu->length = strlen(extra);412413return ret;414}415416417int rtw_mp_rate(struct net_device *dev,418struct iw_request_info *info,419struct iw_point *wrqu, char *extra)420{421u32 rate = MPT_RATE_1M;422u8 input[wrqu->length + 1];423PADAPTER padapter = rtw_netdev_priv(dev);424PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);425426_rtw_memset(input, 0, sizeof(input));427if (copy_from_user(input, wrqu->pointer, wrqu->length))428return -EFAULT;429430input[wrqu->length] = '\0';431rate = rtw_mpRateParseFunc(padapter, input);432padapter->mppriv.rateidx = rate;433434if (rate == 0 && strcmp(input, "1M") != 0) {435rate = rtw_atoi(input);436padapter->mppriv.rateidx = MRateToHwRate(rate);437/*if (rate <= 0x7f)438rate = wifirate2_ratetbl_inx((u8)rate);439else if (rate < 0xC8)440rate = (rate - 0x79 + MPT_RATE_MCS0);441HT rate 0x80(MCS0) ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159442VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179443VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199444else445VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153446rate =(rate - MPT_RATE_VHT1SS_MCS0);447*/448}449_rtw_memset(extra, 0, wrqu->length);450451sprintf(extra, "Set data rate to %s index %d" , input, padapter->mppriv.rateidx);452RTW_INFO("%s: %s rate index=%d\n", __func__, input, padapter->mppriv.rateidx);453454if (padapter->mppriv.rateidx >= DESC_RATEVHTSS4MCS9)455return -EINVAL;456457pMptCtx->mpt_rate_index = HwRateToMPTRate(padapter->mppriv.rateidx);458SetDataRate(padapter);459460wrqu->length = strlen(extra);461return 0;462}463464465int rtw_mp_channel(struct net_device *dev,466struct iw_request_info *info,467struct iw_point *wrqu, char *extra)468{469470PADAPTER padapter = rtw_netdev_priv(dev);471HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);472u8 input[wrqu->length + 1];473u32 channel = 1;474475_rtw_memset(input, 0, sizeof(input));476if (copy_from_user(input, wrqu->pointer, wrqu->length))477return -EFAULT;478479input[wrqu->length] = '\0';480channel = rtw_atoi(input);481/*RTW_INFO("%s: channel=%d\n", __func__, channel);*/482_rtw_memset(extra, 0, wrqu->length);483sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel);484padapter->mppriv.channel = channel;485SetChannel(padapter);486pHalData->current_channel = channel;487488wrqu->length = strlen(extra);489return 0;490}491492493int rtw_mp_ch_offset(struct net_device *dev,494struct iw_request_info *info,495struct iw_point *wrqu, char *extra)496{497498PADAPTER padapter = rtw_netdev_priv(dev);499u8 input[wrqu->length + 1];500u32 ch_offset = 0;501502_rtw_memset(input, 0, sizeof(input));503if (copy_from_user(input, wrqu->pointer, wrqu->length))504return -EFAULT;505506input[wrqu->length] = '\0';507ch_offset = rtw_atoi(input);508/*RTW_INFO("%s: channel=%d\n", __func__, channel);*/509_rtw_memset(extra, 0, wrqu->length);510sprintf(extra, "Change prime channel offset %d to %d", padapter->mppriv.prime_channel_offset , ch_offset);511padapter->mppriv.prime_channel_offset = ch_offset;512SetChannel(padapter);513514wrqu->length = strlen(extra);515return 0;516}517518519int rtw_mp_bandwidth(struct net_device *dev,520struct iw_request_info *info,521struct iw_point *wrqu, char *extra)522{523u32 bandwidth = 0, sg = 0;524PADAPTER padapter = rtw_netdev_priv(dev);525HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);526u8 input[wrqu->length];527528if (copy_from_user(input, wrqu->pointer, wrqu->length))529return -EFAULT;530531if (sscanf(input, "40M=%d,shortGI=%d", &bandwidth, &sg) > 0)532RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth , sg);533534if (bandwidth == 1 && hal_chk_bw_cap(padapter, BW_CAP_40M))535bandwidth = CHANNEL_WIDTH_40;536else if (bandwidth == 2 && hal_chk_bw_cap(padapter, BW_CAP_80M))537bandwidth = CHANNEL_WIDTH_80;538else539bandwidth = CHANNEL_WIDTH_20;540541padapter->mppriv.bandwidth = (u8)bandwidth;542padapter->mppriv.preamble = sg;543_rtw_memset(extra, 0, wrqu->length);544sprintf(extra, "Change BW %d to BW %d\n", pHalData->current_channel_bw , bandwidth);545546SetBandwidth(padapter);547pHalData->current_channel_bw = bandwidth;548549wrqu->length = strlen(extra);550551return 0;552}553554555int rtw_mp_txpower_index(struct net_device *dev,556struct iw_request_info *info,557struct iw_point *wrqu, char *extra)558{559PADAPTER padapter = rtw_netdev_priv(dev);560HAL_DATA_TYPE *phal_data = GET_HAL_DATA(padapter);561char input[wrqu->length + 1];562u32 rfpath;563u32 txpower_inx = 0;564char *pextra = extra;565566if (wrqu->length > 128)567return -EFAULT;568569_rtw_memset(input, 0, sizeof(input));570571if (copy_from_user(input, wrqu->pointer, wrqu->length))572return -EFAULT;573574input[wrqu->length] = '\0';575_rtw_memset(extra, 0, strlen(extra));576577if (wrqu->length == 2) {578if (input[0] != '\0' ) {579rfpath = rtw_atoi(input);580txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);581}582pextra += sprintf(pextra, " %d", txpower_inx);583} else {584txpower_inx = mpt_ProQueryCalTxPower(padapter, 0);585pextra += sprintf(pextra, "patha=%d", txpower_inx);586if (phal_data->rf_type > RF_1T2R) {587txpower_inx = mpt_ProQueryCalTxPower(padapter, 1);588pextra += sprintf(pextra, ",pathb=%d", txpower_inx);589}590if (phal_data->rf_type > RF_2T4R) {591txpower_inx = mpt_ProQueryCalTxPower(padapter, 2);592pextra += sprintf(pextra, ",pathc=%d", txpower_inx);593}594if (phal_data->rf_type > RF_3T4R) {595txpower_inx = mpt_ProQueryCalTxPower(padapter, 3);596pextra += sprintf(pextra, ",pathd=%d", txpower_inx);597}598}599wrqu->length = strlen(extra);600601return 0;602}603604605int rtw_mp_txpower(struct net_device *dev,606struct iw_request_info *info,607struct iw_point *wrqu, char *extra)608{609u32 idx_a = 0, idx_b = 0, idx_c = 0, idx_d = 0;610int MsetPower = 1;611u8 input[wrqu->length];612613PADAPTER padapter = rtw_netdev_priv(dev);614PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);615616if (copy_from_user(input, wrqu->pointer, wrqu->length))617return -EFAULT;618619MsetPower = strncmp(input, "off", 3);620if (MsetPower == 0) {621padapter->mppriv.bSetTxPower = 0;622sprintf(extra, "MP Set power off");623} else {624if (sscanf(input, "patha=%d,pathb=%d,pathc=%d,pathd=%d", &idx_a, &idx_b, &idx_c, &idx_d) < 3)625RTW_INFO("Invalid format on line %s ,patha=%d,pathb=%d,pathc=%d,pathd=%d\n", input , idx_a , idx_b , idx_c , idx_d);626627sprintf(extra, "Set power level path_A:%d path_B:%d path_C:%d path_D:%d", idx_a , idx_b , idx_c , idx_d);628padapter->mppriv.txpoweridx = (u8)idx_a;629630pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)idx_a;631pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)idx_b;632pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)idx_c;633pMptCtx->TxPwrLevel[RF_PATH_D] = (u8)idx_d;634padapter->mppriv.bSetTxPower = 1;635636SetTxPower(padapter);637}638639wrqu->length = strlen(extra);640return 0;641}642643644int rtw_mp_ant_tx(struct net_device *dev,645struct iw_request_info *info,646struct iw_point *wrqu, char *extra)647{648u8 i;649u8 input[wrqu->length + 1];650u16 antenna = 0;651PADAPTER padapter = rtw_netdev_priv(dev);652HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);653654_rtw_memset(input, 0, sizeof(input));655if (copy_from_user(input, wrqu->pointer, wrqu->length))656return -EFAULT;657658input[wrqu->length] = '\0';659sprintf(extra, "switch Tx antenna to %s", input);660661for (i = 0; i < strlen(input); i++) {662switch (input[i]) {663case 'a':664antenna |= ANTENNA_A;665break;666case 'b':667antenna |= ANTENNA_B;668break;669case 'c':670antenna |= ANTENNA_C;671break;672case 'd':673antenna |= ANTENNA_D;674break;675}676}677/*antenna |= BIT(extra[i]-'a');*/678RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);679padapter->mppriv.antenna_tx = antenna;680681/*RTW_INFO("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx);*/682pHalData->antenna_tx_path = antenna;683if (IS_HARDWARE_TYPE_8822C(padapter) && padapter->mppriv.antenna_tx == ANTENNA_B) {684if (padapter->mppriv.antenna_rx == ANTENNA_A || padapter->mppriv.antenna_rx == ANTENNA_B) {685padapter->mppriv.antenna_rx = ANTENNA_AB;686pHalData->AntennaRxPath = ANTENNA_AB;687RTW_INFO("%s:8822C Tx-B Rx Ant to AB\n", __func__);688}689}690SetAntenna(padapter);691692wrqu->length = strlen(extra);693return 0;694}695696697int rtw_mp_ant_rx(struct net_device *dev,698struct iw_request_info *info,699struct iw_point *wrqu, char *extra)700{701u8 i;702u16 antenna = 0;703u8 input[wrqu->length + 1];704PADAPTER padapter = rtw_netdev_priv(dev);705HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);706707_rtw_memset(input, 0, sizeof(input));708if (copy_from_user(input, wrqu->pointer, wrqu->length))709return -EFAULT;710711input[wrqu->length] = '\0';712/*RTW_INFO("%s: input=%s\n", __func__, input);*/713_rtw_memset(extra, 0, wrqu->length);714715sprintf(extra, "switch Rx antenna to %s", input);716717for (i = 0; i < strlen(input); i++) {718switch (input[i]) {719case 'a':720antenna |= ANTENNA_A;721break;722case 'b':723antenna |= ANTENNA_B;724break;725case 'c':726antenna |= ANTENNA_C;727break;728case 'd':729antenna |= ANTENNA_D;730break;731}732}733734RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);735736padapter->mppriv.antenna_rx = antenna;737pHalData->AntennaRxPath = antenna;738/*RTW_INFO("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);*/739SetAntenna(padapter);740wrqu->length = strlen(extra);741742return 0;743}744745746int rtw_set_ctx_destAddr(struct net_device *dev,747struct iw_request_info *info,748struct iw_point *wrqu, char *extra)749{750int jj, kk = 0;751752struct pkt_attrib *pattrib;753struct mp_priv *pmp_priv;754PADAPTER padapter = rtw_netdev_priv(dev);755756pmp_priv = &padapter->mppriv;757pattrib = &pmp_priv->tx.attrib;758759if (strlen(extra) < 5)760return _FAIL;761762RTW_INFO("%s: in=%s\n", __func__, extra);763for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)764pattrib->dst[jj] = key_2char2num(extra[kk], extra[kk + 1]);765766RTW_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]);767return 0;768}769770771772int rtw_mp_ctx(struct net_device *dev,773struct iw_request_info *info,774struct iw_point *wrqu, char *extra)775{776u32 pkTx = 1;777int countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1, payload = 1;778u32 bStartTest = 1;779u32 count = 0, pktinterval = 0, pktlen = 0;780u8 status;781struct mp_priv *pmp_priv;782struct pkt_attrib *pattrib;783PADAPTER padapter = rtw_netdev_priv(dev);784HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);785786pmp_priv = &padapter->mppriv;787pattrib = &pmp_priv->tx.attrib;788789if (padapter->registrypriv.mp_mode != 1 ) {790sprintf(extra, "Error: can't tx ,not in MP mode. \n");791wrqu->length = strlen(extra);792return 0;793}794795if (copy_from_user(extra, wrqu->pointer, wrqu->length))796return -EFAULT;797798*(extra + wrqu->length) = '\0';799RTW_INFO("%s: in=%s\n", __func__, extra);800#ifdef CONFIG_CONCURRENT_MODE801if (!is_primary_adapter(padapter)) {802sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");803wrqu->length = strlen(extra);804return 0;805}806#endif807countPkTx = strncmp(extra, "count=", 5); /* strncmp TRUE is 0*/808cotuTx = strncmp(extra, "background", 20);809CarrSprTx = strncmp(extra, "background,cs", 20);810scTx = strncmp(extra, "background,sc", 20);811sgleTx = strncmp(extra, "background,stone", 20);812pkTx = strncmp(extra, "background,pkt", 20);813stop = strncmp(extra, "stop", 4);814payload = strncmp(extra, "payload=", 8);815816if (sscanf(extra, "count=%d,pkt", &count) > 0)817RTW_INFO("count= %d\n", count);818if (sscanf(extra, "pktinterval=%d", &pktinterval) > 0)819RTW_INFO("pktinterval= %d\n", pktinterval);820if (sscanf(extra, "pktlen=%d", &pktlen) > 0)821RTW_INFO("pktlen= %d\n", pktlen);822823if (payload == 0) {824payload = MP_TX_Payload_default_random;825if (strncmp(extra, "payload=prbs9", 14) == 0) {826payload = MP_TX_Payload_prbs9;827sprintf(extra, "config payload PRBS9\n");828} else {829if (sscanf(extra, "payload=%x", &payload) > 0){830RTW_INFO("payload= %x\n", payload);831sprintf(extra, "config payload setting = %x\n"832"1. input payload=[]:\n "833"[0]: 00, [1]: A5, [2]: 5A, [3]: FF, [4]: PRBS-9, [5]: Random\n"834"2. specified a hex payload: payload=0xee\n", payload);835}836}837pmp_priv->tx.payload = payload;838wrqu->length = strlen(extra);839return 0;840}841842if (_rtw_memcmp(extra, "destmac=", 8)) {843wrqu->length -= 8;844rtw_set_ctx_destAddr(dev, info, wrqu, &extra[8]);845sprintf(extra, "Set dest mac OK !\n");846return 0;847}848/*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);*/849_rtw_memset(extra, '\0', strlen(extra));850851if (pktinterval != 0) {852sprintf(extra, "Pkt Interval = %d", pktinterval);853padapter->mppriv.pktInterval = pktinterval;854wrqu->length = strlen(extra);855return 0;856857} else if (pktlen != 0) {858sprintf(extra, "Pkt len = %d", pktlen);859pattrib->pktlen = pktlen;860wrqu->length = strlen(extra);861return 0;862863} else if (stop == 0) {864bStartTest = 0; /* To set Stop*/865pmp_priv->tx.stop = 1;866sprintf(extra, "Stop continuous Tx");867odm_write_dig(&pHalData->odmpriv, 0x20);868} else {869bStartTest = 1;870odm_write_dig(&pHalData->odmpriv, 0x3f);871if (IS_HARDWARE_TYPE_8822C(padapter) && pmp_priv->antenna_tx == ANTENNA_B) {872if (pmp_priv->antenna_rx == ANTENNA_A || pmp_priv->antenna_rx == ANTENNA_B) {873pmp_priv->antenna_rx = ANTENNA_AB;874pHalData->AntennaRxPath = ANTENNA_AB;875RTW_INFO("%s:8822C Tx-B Rx Ant to AB\n", __func__);876SetAntenna(padapter);877}878}879if (pmp_priv->mode != MP_ON) {880if (pmp_priv->tx.stop != 1) {881RTW_INFO("%s:Error MP_MODE %d != ON\n", __func__, pmp_priv->mode);882return -EFAULT;883}884}885}886887pmp_priv->tx.count = count;888889if (pkTx == 0 || countPkTx == 0)890pmp_priv->mode = MP_PACKET_TX;891if (sgleTx == 0)892pmp_priv->mode = MP_SINGLE_TONE_TX;893if (cotuTx == 0)894pmp_priv->mode = MP_CONTINUOUS_TX;895if (CarrSprTx == 0)896pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;897if (scTx == 0)898pmp_priv->mode = MP_SINGLE_CARRIER_TX;899900status = rtw_mp_pretx_proc(padapter, bStartTest, extra);901902if (stop == 0)903pmp_priv->mode = MP_ON;904905wrqu->length = strlen(extra);906return status;907}908909910911int rtw_mp_disable_bt_coexist(struct net_device *dev,912struct iw_request_info *info,913union iwreq_data *wrqu, char *extra)914{915#ifdef CONFIG_BT_COEXIST916PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);917918#endif919u8 input[wrqu->data.length + 1];920u32 bt_coexist;921922_rtw_memset(input, 0, sizeof(input));923924if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))925return -EFAULT;926927input[wrqu->data.length] = '\0';928929bt_coexist = rtw_atoi(input);930931if (bt_coexist == 0) {932RTW_INFO("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n");933#ifdef CONFIG_BT_COEXIST934rtw_btcoex_HaltNotify(padapter);935rtw_btcoex_SetManualControl(padapter, _TRUE);936/* Force to switch Antenna to WiFi*/937rtw_write16(padapter, 0x870, 0x300);938rtw_write16(padapter, 0x860, 0x110);939#endif940/* CONFIG_BT_COEXIST */941} else {942#ifdef CONFIG_BT_COEXIST943rtw_btcoex_SetManualControl(padapter, _FALSE);944#endif945}946947return 0;948}949950951int rtw_mp_arx(struct net_device *dev,952struct iw_request_info *info,953struct iw_point *wrqu, char *extra)954{955int bStartRx = 0, bStopRx = 0, bQueryPhy = 0, bQueryMac = 0, bSetBssid = 0, bSetRxframe = 0;956int bmac_filter = 0, bmon = 0, bSmpCfg = 0;957u8 input[wrqu->length];958char *pch, *token, *tmp[2] = {0x00, 0x00};959u32 i = 0, jj = 0, kk = 0, cnts = 0, ret;960PADAPTER padapter = rtw_netdev_priv(dev);961struct mp_priv *pmppriv = &padapter->mppriv;962struct dbg_rx_counter rx_counter;963964if (copy_from_user(input, wrqu->pointer, wrqu->length))965return -EFAULT;966967RTW_INFO("%s: %s\n", __func__, input);968#ifdef CONFIG_CONCURRENT_MODE969if (!is_primary_adapter(padapter)) {970sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");971wrqu->length = strlen(extra);972return 0;973}974#endif975bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/976bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/977bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp TRUE is 0*/978bQueryMac = (strncmp(input, "mac", 3) == 0) ? 1 : 0; /* strncmp TRUE is 0*/979bSetBssid = (strncmp(input, "setbssid=", 8) == 0) ? 1 : 0; /* strncmp TRUE is 0*/980bSetRxframe = (strncmp(input, "frametype", 9) == 0) ? 1 : 0;981/*bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;*/982bmac_filter = (strncmp(input, "accept_mac", 10) == 0) ? 1 : 0;983bmon = (strncmp(input, "mon=", 4) == 0) ? 1 : 0;984bSmpCfg = (strncmp(input , "smpcfg=" , 7) == 0) ? 1 : 0;985pmppriv->bloopback = (strncmp(input, "loopbk", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/986987if (bSetBssid == 1) {988pch = input;989while ((token = strsep(&pch, "=")) != NULL) {990if (i > 1)991break;992tmp[i] = token;993i++;994}995if ((tmp[0] != NULL) && (tmp[1] != NULL)) {996cnts = strlen(tmp[1]) / 2;997if (cnts < 1)998return -EFAULT;999RTW_INFO("%s: cnts=%d\n", __func__, cnts);1000RTW_INFO("%s: data=%s\n", __func__, tmp[1]);1001for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) {1002pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);1003RTW_INFO("network_macaddr[%d]=%x\n", jj, pmppriv->network_macaddr[jj]);1004}1005} else1006return -EFAULT;10071008pmppriv->bSetRxBssid = _TRUE;1009}1010if (bSetRxframe) {1011if (strncmp(input, "frametype beacon", 16) == 0)1012pmppriv->brx_filter_beacon = _TRUE;1013else1014pmppriv->brx_filter_beacon = _FALSE;1015}10161017if (bmac_filter) {1018pmppriv->bmac_filter = bmac_filter;1019pch = input;1020while ((token = strsep(&pch, "=")) != NULL) {1021if (i > 1)1022break;1023tmp[i] = token;1024i++;1025}1026if ((tmp[0] != NULL) && (tmp[1] != NULL)) {1027cnts = strlen(tmp[1]) / 2;1028if (cnts < 1)1029return -EFAULT;1030RTW_INFO("%s: cnts=%d\n", __func__, cnts);1031RTW_INFO("%s: data=%s\n", __func__, tmp[1]);1032for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) {1033pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);1034RTW_INFO("%s mac_filter[%d]=%x\n", __func__, jj, pmppriv->mac_filter[jj]);1035}1036} else1037return -EFAULT;10381039}10401041if (bStartRx) {1042sprintf(extra, "start");1043SetPacketRx(padapter, bStartRx, _FALSE);1044} else if (bStopRx) {1045SetPacketRx(padapter, bStartRx, _FALSE);1046pmppriv->bmac_filter = _FALSE;1047pmppriv->bSetRxBssid = _FALSE;1048sprintf(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);1049} else if (bQueryPhy) {1050_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));1051rtw_dump_phy_rx_counters(padapter, &rx_counter);10521053RTW_INFO("%s: OFDM_FA =%d\n", __func__, rx_counter.rx_ofdm_fa);1054RTW_INFO("%s: CCK_FA =%d\n", __func__, rx_counter.rx_cck_fa);1055sprintf(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);105610571058} else if (bQueryMac) {1059_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));1060rtw_dump_mac_rx_counters(padapter, &rx_counter);1061sprintf(extra, "Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d\n",1062rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);10631064}10651066if (bmon == 1) {1067ret = sscanf(input, "mon=%d", &bmon);10681069if (bmon == 1) {1070pmppriv->rx_bindicatePkt = _TRUE;1071sprintf(extra, "Indicating Receive Packet to network start\n");1072} else {1073pmppriv->rx_bindicatePkt = _FALSE;1074sprintf(extra, "Indicating Receive Packet to network Stop\n");1075}1076}1077if (bSmpCfg == 1) {1078ret = sscanf(input, "smpcfg=%d", &bSmpCfg);10791080if (bSmpCfg == 1) {1081pmppriv->bRTWSmbCfg = _TRUE;1082sprintf(extra , "Indicate By Simple Config Format\n");1083SetPacketRx(padapter, _TRUE, _TRUE);1084} else {1085pmppriv->bRTWSmbCfg = _FALSE;1086sprintf(extra , "Indicate By Normal Format\n");1087SetPacketRx(padapter, _TRUE, _FALSE);1088}1089}10901091if (pmppriv->bloopback == _TRUE) {1092sprintf(extra , "Enter MAC LoopBack mode\n");1093#if defined(CONFIG_RTL8814B)1094/* 1. No adhoc, 2. Enable short cut */1095rtw_write32(padapter, 0x100, 0x0B000EFF);1096#else1097rtw_write32(padapter, 0x100, 0x0B0106FF);1098#endif1099RTW_INFO("0x100 :0x%x", rtw_read32(padapter, 0x100));1100rtw_write16(padapter, 0x608, 0x30c);1101RTW_INFO("0x608 :0x%x", rtw_read32(padapter, 0x608));1102}11031104wrqu->length = strlen(extra) + 1;11051106return 0;1107}110811091110int rtw_mp_trx_query(struct net_device *dev,1111struct iw_request_info *info,1112struct iw_point *wrqu, char *extra)1113{1114u32 txok, txfail, rxok, rxfail, rxfilterout;1115PADAPTER padapter = rtw_netdev_priv(dev);1116PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);1117RT_PMAC_TX_INFO PMacTxInfo = pMptCtx->PMacTxInfo;11181119if (PMacTxInfo.bEnPMacTx == TRUE)1120txok = hal_mpt_query_phytxok(padapter);1121else1122txok = padapter->mppriv.tx.sended;11231124txfail = 0;1125rxok = padapter->mppriv.rx_pktcount;1126rxfail = padapter->mppriv.rx_crcerrpktcount;1127rxfilterout = padapter->mppriv.rx_pktcount_filter_out;11281129_rtw_memset(extra, '\0', 128);11301131sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d\n", txok, txfail, rxok, rxfail, rxfilterout);11321133wrqu->length = strlen(extra) + 1;11341135return 0;1136}113711381139int rtw_mp_pwrtrk(struct net_device *dev,1140struct iw_request_info *info,1141struct iw_point *wrqu, char *extra)1142{1143u8 enable;1144u32 thermal;1145s32 ret;1146PADAPTER padapter = rtw_netdev_priv(dev);1147u8 input[wrqu->length];11481149if (copy_from_user(input, wrqu->pointer, wrqu->length))1150return -EFAULT;11511152_rtw_memset(extra, 0, wrqu->length);11531154enable = 1;1155if (wrqu->length > 1) {1156/* not empty string*/1157if (strncmp(input, "stop", 4) == 0) {1158enable = 0;1159sprintf(extra, "mp tx power tracking stop");1160} else if (sscanf(input, "ther=%d", &thermal) == 1) {1161ret = SetThermalMeter(padapter, (u8)thermal);1162if (ret == _FAIL)1163return -EPERM;1164sprintf(extra, "mp tx power tracking start,target value=%d ok", thermal);1165} else1166return -EINVAL;1167}11681169ret = SetPowerTracking(padapter, enable);1170if (ret == _FAIL)1171return -EPERM;11721173wrqu->length = strlen(extra);11741175return 0;1176}1177117811791180int rtw_mp_psd(struct net_device *dev,1181struct iw_request_info *info,1182struct iw_point *wrqu, char *extra)1183{1184PADAPTER padapter = rtw_netdev_priv(dev);1185u8 input[wrqu->length + 1];11861187_rtw_memset(input, 0, sizeof(input));1188if (copy_from_user(input, wrqu->pointer, wrqu->length))1189return -EFAULT;11901191input[wrqu->length] = '\0';1192strcpy(extra, input);11931194wrqu->length = mp_query_psd(padapter, extra);11951196return 0;1197}119811991200int rtw_mp_thermal(struct net_device *dev,1201struct iw_request_info *info,1202struct iw_point *wrqu, char *extra)1203{1204u8 val[4] = {0};1205u8 ret = 0;1206u16 ther_path_addr[4] = {0};1207u16 cnt = 1;1208PADAPTER padapter = rtw_netdev_priv(dev);1209int rfpath = RF_PATH_A;12101211#ifdef CONFIG_RTL8188E1212ther_path_addr[0] = EEPROM_THERMAL_METER_88E;1213#endif1214#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A)1215ther_path_addr[0] = EEPROM_THERMAL_METER_8812;1216#endif1217#ifdef CONFIG_RTL8192E1218ther_path_addr[0] = EEPROM_THERMAL_METER_8192E;1219#endif1220#ifdef CONFIG_RTL8192F1221ther_path_addr[0] = EEPROM_THERMAL_METER_8192F;1222#endif1223#ifdef CONFIG_RTL8723B1224ther_path_addr[0] = EEPROM_THERMAL_METER_8723B;1225#endif1226#ifdef CONFIG_RTL8703B1227ther_path_addr[0] = EEPROM_THERMAL_METER_8703B;1228#endif1229#ifdef CONFIG_RTL8723D1230ther_path_addr[0] = EEPROM_THERMAL_METER_8723D;1231#endif1232#ifdef CONFIG_RTL8188F1233ther_path_addr[0] = EEPROM_THERMAL_METER_8188F;1234#endif1235#ifdef CONFIG_RTL8188GTV1236ther_path_addr[0] = EEPROM_THERMAL_METER_8188GTV;1237#endif1238#ifdef CONFIG_RTL8822B1239ther_path_addr[0] = EEPROM_THERMAL_METER_8822B;1240#endif1241#ifdef CONFIG_RTL8821C1242ther_path_addr[0] = EEPROM_THERMAL_METER_8821C;1243#endif1244#ifdef CONFIG_RTL8710B1245ther_path_addr[0] = EEPROM_THERMAL_METER_8710B;1246#endif1247#ifdef CONFIG_RTL8822C1248ther_path_addr[0] = EEPROM_THERMAL_METER_A_8822C;1249ther_path_addr[1] = EEPROM_THERMAL_METER_B_8822C;1250#endif1251#ifdef CONFIG_RTL8814B1252ther_path_addr[0] = EEPROM_THERMAL_METER_8814B;1253#endif12541255if (copy_from_user(extra, wrqu->pointer, wrqu->length))1256return -EFAULT;12571258if ((strncmp(extra, "write", 6) == 0)) {1259int i;1260u16 raw_cursize = 0, raw_maxsize = 0;1261#ifdef RTW_HALMAC1262raw_maxsize = efuse_GetavailableSize(padapter);1263#else1264efuse_GetCurrentSize(padapter, &raw_cursize);1265raw_maxsize = efuse_GetMaxSize(padapter);1266#endif1267RTW_INFO("[eFuse available raw size]= %d bytes\n", raw_maxsize - raw_cursize);1268if (2 > raw_maxsize - raw_cursize) {1269RTW_INFO("no available efuse!\n");1270return -EFAULT;1271}12721273for (i = 0; i < GET_HAL_RFPATH_NUM(padapter); i++) {1274GetThermalMeter(padapter, i , &val[i]);1275if (ther_path_addr[i] != 0 && val[i] != 0) {1276if (rtw_efuse_map_write(padapter, ther_path_addr[i], cnt, &val[i]) == _FAIL) {1277RTW_INFO("Error efuse write thermal addr 0x%x ,val = 0x%x\n", ther_path_addr[i], val[i]);1278return -EFAULT;1279}1280} else {1281RTW_INFO("Error efuse write thermal Null addr,val \n");1282return -EFAULT;1283}1284}1285_rtw_memset(extra, 0, wrqu->length);1286sprintf(extra, " efuse write ok :%d", val[0]);1287} else {1288ret = sscanf(extra, "%d", &rfpath);1289if (ret < 1) {1290rfpath = RF_PATH_A;1291RTW_INFO("default thermal of path(%d)\n", rfpath);1292}1293if (rfpath >= GET_HAL_RFPATH_NUM(padapter))1294return -EINVAL;12951296RTW_INFO("read thermal of path(%d)\n", rfpath);1297GetThermalMeter(padapter, rfpath, &val[0]);12981299_rtw_memset(extra, 0, wrqu->length);1300sprintf(extra, "%d", val[0]);1301}1302wrqu->length = strlen(extra);13031304return 0;1305}1306130713081309int rtw_mp_reset_stats(struct net_device *dev,1310struct iw_request_info *info,1311struct iw_point *wrqu, char *extra)1312{1313struct mp_priv *pmp_priv;1314PADAPTER padapter = rtw_netdev_priv(dev);13151316pmp_priv = &padapter->mppriv;13171318pmp_priv->tx.sended = 0;1319pmp_priv->tx_pktcount = 0;1320pmp_priv->rx_pktcount = 0;1321pmp_priv->rx_pktcount_filter_out = 0;1322pmp_priv->rx_crcerrpktcount = 0;13231324rtw_reset_phy_rx_counters(padapter);1325rtw_reset_mac_rx_counters(padapter);13261327_rtw_memset(extra, 0, wrqu->length);1328sprintf(extra, "mp_reset_stats ok\n");1329wrqu->length = strlen(extra);13301331return 0;1332}133313341335int rtw_mp_dump(struct net_device *dev,1336struct iw_request_info *info,1337struct iw_point *wrqu, char *extra)1338{1339struct mp_priv *pmp_priv;1340u8 input[wrqu->length];1341PADAPTER padapter = rtw_netdev_priv(dev);13421343pmp_priv = &padapter->mppriv;13441345if (copy_from_user(input, wrqu->pointer, wrqu->length))1346return -EFAULT;13471348if (strncmp(input, "all", 4) == 0) {1349mac_reg_dump(RTW_DBGDUMP, padapter);1350bb_reg_dump(RTW_DBGDUMP, padapter);1351rf_reg_dump(RTW_DBGDUMP, padapter);1352}1353return 0;1354}135513561357int rtw_mp_phypara(struct net_device *dev,1358struct iw_request_info *info,1359struct iw_point *wrqu, char *extra)1360{13611362PADAPTER padapter = rtw_netdev_priv(dev);1363HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1364char input[wrqu->length];1365u32 invalxcap = 0, ret = 0, bwrite_xcap = 0, hwxtaladdr = 0;1366u16 pgval;136713681369if (copy_from_user(input, wrqu->pointer, wrqu->length))1370return -EFAULT;13711372RTW_INFO("%s:priv in=%s\n", __func__, input);1373bwrite_xcap = (strncmp(input, "write_xcap=", 11) == 0) ? 1 : 0;13741375if (bwrite_xcap == 1) {1376ret = sscanf(input, "write_xcap=%d", &invalxcap);1377invalxcap = invalxcap & 0x7f; /* xtal bit 0 ~6 */1378RTW_INFO("get crystal_cap %d\n", invalxcap);13791380if (IS_HARDWARE_TYPE_8822C(padapter) && ret == 1) {1381hwxtaladdr = 0x110;1382pgval = invalxcap | 0x80; /* reserved default bit7 on */1383pgval = pgval | pgval << 8; /* xtal xi/xo efuse 0x110 0x111 */13841385RTW_INFO("Get crystal_cap 0x%x\n", pgval);1386if (rtw_efuse_map_write(padapter, hwxtaladdr, 2, (u8*)&pgval) == _FAIL) {1387RTW_INFO("%s: rtw_efuse_map_write xcap error!!\n", __func__);1388sprintf(extra, "write xcap pgdata fail");1389ret = -EFAULT;1390} else1391sprintf(extra, "write xcap pgdata ok");13921393}1394} else {1395ret = sscanf(input, "xcap=%d", &invalxcap);13961397if (ret == 1) {1398pHalData->crystal_cap = (u8)invalxcap;1399RTW_INFO("%s:crystal_cap=%d\n", __func__, pHalData->crystal_cap);14001401if (rtw_phydm_set_crystal_cap(padapter, pHalData->crystal_cap) == _FALSE) {1402RTW_ERR("set crystal_cap failed\n");1403rtw_warn_on(1);1404}1405sprintf(extra, "Set xcap=%d", invalxcap);1406}1407}14081409wrqu->length = strlen(extra) + 1;1410return ret;1411}141214131414int rtw_mp_SetRFPath(struct net_device *dev,1415struct iw_request_info *info,1416struct iw_point *wrqu, char *extra)1417{1418PADAPTER padapter = rtw_netdev_priv(dev);1419char input[wrqu->length];1420int bMain = 1, bTurnoff = 1;1421#ifdef CONFIG_ANTENNA_DIVERSITY1422u8 ret = _TRUE;1423#endif14241425RTW_INFO("%s:iwpriv in=%s\n", __func__, input);14261427if (copy_from_user(input, wrqu->pointer, wrqu->length))1428return -EFAULT;14291430bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/1431bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/14321433_rtw_memset(extra, 0, wrqu->length);1434#ifdef CONFIG_ANTENNA_DIVERSITY1435if (bMain == 0)1436ret = rtw_mp_set_antdiv(padapter, _TRUE);1437else1438ret = rtw_mp_set_antdiv(padapter, _FALSE);1439if (ret == _FALSE)1440RTW_INFO("%s:ANTENNA_DIVERSITY FAIL\n", __func__);1441#endif14421443if (bMain == 0) {1444MP_PHY_SetRFPathSwitch(padapter, _TRUE);1445RTW_INFO("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);1446sprintf(extra, "mp_setrfpath Main\n");14471448} else if (bTurnoff == 0) {1449MP_PHY_SetRFPathSwitch(padapter, _FALSE);1450RTW_INFO("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);1451sprintf(extra, "mp_setrfpath Aux\n");1452} else {1453bMain = MP_PHY_QueryRFPathSwitch(padapter);1454RTW_INFO("%s:PHY_SetRFPathSwitch = %s\n", __func__, (bMain ? "Main":"Aux"));1455sprintf(extra, "mp_setrfpath %s\n" , (bMain ? "Main":"Aux"));1456}14571458wrqu->length = strlen(extra);14591460return 0;1461}146214631464int rtw_mp_switch_rf_path(struct net_device *dev,1465struct iw_request_info *info,1466struct iw_point *wrqu, char *extra)1467{1468PADAPTER padapter = rtw_netdev_priv(dev);1469struct mp_priv *pmp_priv;1470char input[wrqu->length];1471int bwlg = 1, bwla = 1, btg = 1, bbt=1;1472u8 ret = 0;147314741475if (copy_from_user(input, wrqu->pointer, wrqu->length))1476return -EFAULT;14771478pmp_priv = &padapter->mppriv;14791480RTW_INFO("%s: in=%s\n", __func__, input);14811482bwlg = strncmp(input, "WLG", 3); /* strncmp TRUE is 0*/1483bwla = strncmp(input, "WLA", 3); /* strncmp TRUE is 0*/1484btg = strncmp(input, "BTG", 3); /* strncmp TRUE is 0*/1485bbt = strncmp(input, "BT", 3); /* strncmp TRUE is 0*/14861487_rtw_memset(extra, 0, wrqu->length);1488#ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */1489if (bwlg == 0) {1490pmp_priv->rf_path_cfg = SWITCH_TO_WLG;1491sprintf(extra, "switch rf path WLG\n");1492} else if (bwla == 0) {1493pmp_priv->rf_path_cfg = SWITCH_TO_WLA;1494sprintf(extra, "switch rf path WLA\n");1495} else if (btg == 0) {1496pmp_priv->rf_path_cfg = SWITCH_TO_BTG;1497sprintf(extra, "switch rf path BTG\n");1498} else if (bbt == 0) {1499pmp_priv->rf_path_cfg = SWITCH_TO_BT;1500sprintf(extra, "switch rf path BG\n");1501} else {1502sprintf(extra, "Error set %s\n", __func__);1503return -EFAULT;1504}15051506mp_phy_switch_rf_path_set(padapter, &pmp_priv->rf_path_cfg);1507#endif15081509wrqu->length = strlen(extra);15101511return ret;15121513}1514int rtw_mp_QueryDrv(struct net_device *dev,1515struct iw_request_info *info,1516union iwreq_data *wrqu, char *extra)1517{1518PADAPTER padapter = rtw_netdev_priv(dev);1519char input[wrqu->data.length];1520int qAutoLoad = 1;15211522PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);15231524if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))1525return -EFAULT;1526RTW_INFO("%s:iwpriv in=%s\n", __func__, input);15271528qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/15291530if (qAutoLoad == 0) {1531RTW_INFO("%s:qAutoLoad\n", __func__);15321533if (pHalData->bautoload_fail_flag)1534sprintf(extra, "fail");1535else1536sprintf(extra, "ok");1537}1538wrqu->data.length = strlen(extra) + 1;1539return 0;1540}154115421543int rtw_mp_PwrCtlDM(struct net_device *dev,1544struct iw_request_info *info,1545struct iw_point *wrqu, char *extra)1546{1547PADAPTER padapter = rtw_netdev_priv(dev);1548u8 input[wrqu->length];1549int bstart = 1;15501551if (copy_from_user(input, wrqu->pointer, wrqu->length))1552return -EFAULT;15531554bstart = strncmp(input, "start", 5); /* strncmp TRUE is 0*/1555if (bstart == 0) {1556sprintf(extra, "PwrCtlDM start\n");1557MPT_PwrCtlDM(padapter, 1);1558} else {1559sprintf(extra, "PwrCtlDM stop\n");1560MPT_PwrCtlDM(padapter, 0);1561}1562wrqu->length = strlen(extra);15631564return 0;1565}15661567int rtw_mp_iqk(struct net_device *dev,1568struct iw_request_info *info,1569struct iw_point *wrqu, char *extra)1570{1571PADAPTER padapter = rtw_netdev_priv(dev);15721573rtw_mp_trigger_iqk(padapter);15741575return 0;1576}15771578int rtw_mp_lck(struct net_device *dev,1579struct iw_request_info *info,1580struct iw_point *wrqu, char *extra)1581{1582PADAPTER padapter = rtw_netdev_priv(dev);15831584rtw_mp_trigger_lck(padapter);15851586return 0;1587}15881589int rtw_mp_dpk(struct net_device *dev,1590struct iw_request_info *info,1591union iwreq_data *wrqu, char *extra)1592{1593PADAPTER padapter = rtw_netdev_priv(dev);1594HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1595struct dm_struct *pDM_Odm = &pHalData->odmpriv;1596struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);15971598u8 ips_mode = IPS_NUM; /* init invalid value */1599u8 lps_mode = PS_MODE_NUM; /* init invalid value */16001601if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))1602return -EFAULT;16031604*(extra + wrqu->data.length) = '\0';16051606if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {1607pDM_Odm->dpk_info.is_dpk_enable = 0;1608halrf_dpk_enable_disable(pDM_Odm);1609sprintf(extra, "set dpk off\n");16101611} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {1612pDM_Odm->dpk_info.is_dpk_enable = 1;1613halrf_dpk_enable_disable(pDM_Odm);1614sprintf(extra, "set dpk on\n");1615} else {1616#ifdef CONFIG_LPS1617lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */1618rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);1619#endif1620#ifdef CONFIG_IPS1621ips_mode = pwrctrlpriv->ips_mode;/* keep org value */1622rtw_pm_set_ips(padapter, IPS_NONE);1623#endif1624rtw_mp_trigger_dpk(padapter);1625if (padapter->registrypriv.mp_mode == 0) {1626#ifdef CONFIG_IPS1627rtw_pm_set_ips(padapter, ips_mode);1628#endif /* CONFIG_IPS */16291630#ifdef CONFIG_LPS1631rtw_pm_set_lps(padapter, lps_mode);1632#endif /* CONFIG_LPS */1633}1634sprintf(extra, "set dpk trigger\n");1635}16361637wrqu->data.length = strlen(extra);16381639return 0;1640}16411642int rtw_mp_getver(struct net_device *dev,1643struct iw_request_info *info,1644union iwreq_data *wrqu, char *extra)1645{1646PADAPTER padapter = rtw_netdev_priv(dev);1647struct mp_priv *pmp_priv;16481649pmp_priv = &padapter->mppriv;16501651if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))1652return -EFAULT;16531654sprintf(extra, "rtwpriv=%d\n", RTWPRIV_VER_INFO);1655wrqu->data.length = strlen(extra);1656return 0;1657}165816591660int rtw_mp_mon(struct net_device *dev,1661struct iw_request_info *info,1662union iwreq_data *wrqu, char *extra)1663{1664PADAPTER padapter = rtw_netdev_priv(dev);1665struct mp_priv *pmp_priv = &padapter->mppriv;1666struct mlme_priv *pmlmepriv = &padapter->mlmepriv;1667struct hal_ops *pHalFunc = &padapter->hal_func;1668NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;1669int bstart = 1, bstop = 1;16701671networkType = Ndis802_11Infrastructure;1672if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))1673return -EFAULT;16741675*(extra + wrqu->data.length) = '\0';1676rtw_pm_set_ips(padapter, IPS_NONE);1677LeaveAllPowerSaveMode(padapter);16781679#ifdef CONFIG_MP_INCLUDED1680if (init_mp_priv(padapter) == _FAIL)1681RTW_INFO("%s: initialize MP private data Fail!\n", __func__);1682padapter->mppriv.channel = 6;16831684bstart = strncmp(extra, "start", 5); /* strncmp TRUE is 0*/1685bstop = strncmp(extra, "stop", 4); /* strncmp TRUE is 0*/1686if (bstart == 0) {1687mp_join(padapter, WIFI_FW_ADHOC_STATE);1688SetPacketRx(padapter, _TRUE, _FALSE);1689SetChannel(padapter);1690pmp_priv->rx_bindicatePkt = _TRUE;1691pmp_priv->bRTWSmbCfg = _TRUE;1692sprintf(extra, "monitor mode start\n");1693} else if (bstop == 0) {1694SetPacketRx(padapter, _FALSE, _FALSE);1695pmp_priv->rx_bindicatePkt = _FALSE;1696pmp_priv->bRTWSmbCfg = _FALSE;1697padapter->registrypriv.mp_mode = 1;1698pHalFunc->hal_deinit(padapter);1699padapter->registrypriv.mp_mode = 0;1700pHalFunc->hal_init(padapter);1701/*rtw_disassoc_cmd(padapter, 0, 0);*/1702if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {1703rtw_disassoc_cmd(padapter, 500, 0);1704rtw_indicate_disconnect(padapter, 0, _FALSE);1705/*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/1706}1707rtw_pm_set_ips(padapter, IPS_NORMAL);1708sprintf(extra, "monitor mode Stop\n");1709}1710#endif1711wrqu->data.length = strlen(extra);1712return 0;1713}17141715int rtw_mp_pretx_proc(PADAPTER padapter, u8 bStartTest, char *extra)1716{1717struct mp_priv *pmp_priv = &padapter->mppriv;1718char *pextra = extra;17191720switch (pmp_priv->mode) {17211722case MP_PACKET_TX:1723if (bStartTest == 0) {1724pmp_priv->tx.stop = 1;1725pmp_priv->mode = MP_ON;1726sprintf(extra, "Stop continuous Tx");1727} else if (pmp_priv->tx.stop == 1) {1728pextra = extra + strlen(extra);1729pextra += sprintf(pextra, "\nStart continuous DA=ffffffffffff len=1500 count=%u\n", pmp_priv->tx.count);1730pmp_priv->tx.stop = 0;1731SetPacketTx(padapter);1732} else1733return -EFAULT;1734return 0;1735case MP_SINGLE_TONE_TX:1736if (bStartTest != 0)1737strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");1738SetSingleToneTx(padapter, (u8)bStartTest);1739break;1740case MP_CONTINUOUS_TX:1741if (bStartTest != 0)1742strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");1743SetContinuousTx(padapter, (u8)bStartTest);1744break;1745case MP_CARRIER_SUPPRISSION_TX:1746if (bStartTest != 0) {1747if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_11M)1748strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");1749else1750strcat(extra, "\nSpecify carrier suppression but not CCK rate");1751}1752SetCarrierSuppressionTx(padapter, (u8)bStartTest);1753break;1754case MP_SINGLE_CARRIER_TX:1755if (bStartTest != 0)1756strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");1757SetSingleCarrierTx(padapter, (u8)bStartTest);1758break;17591760default:1761sprintf(extra, "Error! Continuous-Tx is not on-going.");1762return -EFAULT;1763}17641765if (bStartTest == 1 && pmp_priv->mode != MP_ON) {1766struct mp_priv *pmp_priv = &padapter->mppriv;17671768if (pmp_priv->tx.stop == 0) {1769pmp_priv->tx.stop = 1;1770rtw_msleep_os(5);1771}1772#ifdef CONFIG_80211N_HT1773if(padapter->registrypriv.ht_enable &&1774is_supported_ht(padapter->registrypriv.wireless_mode))1775pmp_priv->tx.attrib.ht_en = 1;1776#endif1777pmp_priv->tx.stop = 0;1778pmp_priv->tx.count = 1;1779SetPacketTx(padapter);1780} else1781pmp_priv->mode = MP_ON;17821783#if defined(CONFIG_RTL8812A)1784if (IS_HARDWARE_TYPE_8812AU(padapter)) {1785/* <20130425, Kordan> Turn off OFDM Rx to prevent from CCA causing Tx hang.*/1786if (pmp_priv->mode == MP_PACKET_TX)1787phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 1);1788else1789phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 0);1790}1791#endif17921793return 0;1794}179517961797int rtw_mp_tx(struct net_device *dev,1798struct iw_request_info *info,1799union iwreq_data *wrqu, char *extra)1800{1801PADAPTER padapter = rtw_netdev_priv(dev);1802HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1803struct mp_priv *pmp_priv = &padapter->mppriv;1804PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);1805char *pextra = extra;1806u32 bandwidth = 0, sg = 0, channel = 6, txpower = 40, rate = 108, ant = 0, txmode = 1, count = 0;1807u8 bStartTest = 1, status = 0;1808#ifdef CONFIG_MP_VHT_HW_TX_MODE1809u8 Idx = 0, tmpU1B;1810#endif1811u16 antenna = 0;18121813if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))1814return -EFAULT;1815RTW_INFO("extra = %s\n", extra);1816#ifdef CONFIG_CONCURRENT_MODE1817if (!is_primary_adapter(padapter)) {1818sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");1819wrqu->data.length = strlen(extra);1820return 0;1821}1822#endif18231824if (strncmp(extra, "stop", 3) == 0) {1825bStartTest = 0; /* To set Stop*/1826pmp_priv->tx.stop = 1;1827sprintf(extra, "Stop continuous Tx");1828status = rtw_mp_pretx_proc(padapter, bStartTest, extra);1829wrqu->data.length = strlen(extra);1830return status;1831} else if (strncmp(extra, "count", 5) == 0) {1832if (sscanf(extra, "count=%d", &count) < 1)1833RTW_INFO("Got Count=%d]\n", count);1834pmp_priv->tx.count = count;1835return 0;1836} else if (strncmp(extra, "setting", 7) == 0) {1837_rtw_memset(extra, 0, wrqu->data.length);1838pextra += sprintf(pextra, "Current Setting :\n Channel:%d", pmp_priv->channel);1839pextra += sprintf(pextra, "\n Bandwidth:%d", pmp_priv->bandwidth);1840pextra += sprintf(pextra, "\n Rate index:%d", pmp_priv->rateidx);1841pextra += sprintf(pextra, "\n TxPower index:%d", pmp_priv->txpoweridx);1842pextra += sprintf(pextra, "\n Antenna TxPath:%d", pmp_priv->antenna_tx);1843pextra += sprintf(pextra, "\n Antenna RxPath:%d", pmp_priv->antenna_rx);1844pextra += sprintf(pextra, "\n MP Mode:%d", pmp_priv->mode);1845wrqu->data.length = strlen(extra);1846return 0;1847#ifdef CONFIG_MP_VHT_HW_TX_MODE1848} else if (strncmp(extra, "pmact", 5) == 0) {1849if (strncmp(extra, "pmact=", 6) == 0) {1850_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(pMptCtx->PMacTxInfo));1851if (strncmp(extra, "pmact=start", 11) == 0) {1852pMptCtx->PMacTxInfo.bEnPMacTx = _TRUE;1853sprintf(extra, "Set PMac Tx Mode start\n");1854} else {1855pMptCtx->PMacTxInfo.bEnPMacTx = _FALSE;1856sprintf(extra, "Set PMac Tx Mode Stop\n");1857}1858if (pMptCtx->bldpc == TRUE)1859pMptCtx->PMacTxInfo.bLDPC = _TRUE;18601861if (pMptCtx->bstbc == TRUE)1862pMptCtx->PMacTxInfo.bSTBC = _TRUE;18631864pMptCtx->PMacTxInfo.bSPreamble = pmp_priv->preamble;1865pMptCtx->PMacTxInfo.bSGI = pmp_priv->preamble;1866pMptCtx->PMacTxInfo.BandWidth = pmp_priv->bandwidth;1867pMptCtx->PMacTxInfo.TX_RATE = HwRateToMPTRate(pmp_priv->rateidx);18681869pMptCtx->PMacTxInfo.Mode = pMptCtx->HWTxmode;18701871pMptCtx->PMacTxInfo.NDP_sound = FALSE;/*(Adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/18721873if (padapter->mppriv.pktInterval == 0)1874pMptCtx->PMacTxInfo.PacketPeriod = 100;1875else1876pMptCtx->PMacTxInfo.PacketPeriod = padapter->mppriv.pktInterval;18771878if (padapter->mppriv.pktLength < 1000)1879pMptCtx->PMacTxInfo.PacketLength = 1000;1880else1881pMptCtx->PMacTxInfo.PacketLength = padapter->mppriv.pktLength;18821883pMptCtx->PMacTxInfo.PacketPattern = rtw_random32() % 0xFF;18841885if (padapter->mppriv.tx_pktcount != 0)1886pMptCtx->PMacTxInfo.PacketCount = padapter->mppriv.tx_pktcount;18871888pMptCtx->PMacTxInfo.Ntx = 0;1889for (Idx = 16; Idx < 20; Idx++) {1890tmpU1B = (padapter->mppriv.antenna_tx >> Idx) & 1;1891if (tmpU1B)1892pMptCtx->PMacTxInfo.Ntx++;1893}18941895_rtw_memset(pMptCtx->PMacTxInfo.MacAddress, 0xFF, ETH_ALEN);18961897PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);18981899if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE))19001901CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);1902else {1903PMAC_Nsym_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);1904/* 24 BIT*/1905L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);1906}1907/* 48BIT*/1908if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE))1909HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);1910else if (MPT_IS_VHT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) {1911/* 48BIT*/1912VHT_SIG_A_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);19131914/* 26/27/29 BIT & CRC 8 BIT*/1915VHT_SIG_B_generator(&pMptCtx->PMacTxInfo);19161917/* 32 BIT*/1918VHT_Delimiter_generator(&pMptCtx->PMacTxInfo);1919}19201921mpt_ProSetPMacTx(padapter);19221923} else if (strncmp(extra, "pmact,mode=", 11) == 0) {1924int txmode = 0;19251926if (sscanf(extra, "pmact,mode=%d", &txmode) > 0) {1927if (txmode == 1) {1928pMptCtx->HWTxmode = CONTINUOUS_TX;1929sprintf(extra, "\t Config HW Tx mode = CONTINUOUS_TX\n");1930} else if (txmode == 2) {1931pMptCtx->HWTxmode = OFDM_Single_Tone_TX;1932sprintf(extra, "\t Config HW Tx mode = OFDM_Single_Tone_TX\n");1933} else {1934pMptCtx->HWTxmode = PACKETS_TX;1935sprintf(extra, "\t Config HW Tx mode = PACKETS_TX\n");1936}1937} else {1938pMptCtx->HWTxmode = PACKETS_TX;1939sprintf(extra, "\t Config HW Tx mode=\n 0 = PACKETS_TX\n 1 = CONTINUOUS_TX\n 2 = OFDM_Single_Tone_TX");1940}1941} else if (strncmp(extra, "pmact,", 6) == 0) {1942int PacketPeriod = 0, PacketLength = 0, PacketCout = 0;1943int bldpc = 0, bstbc = 0;19441945if (sscanf(extra, "pmact,period=%d", &PacketPeriod) > 0) {1946padapter->mppriv.pktInterval = PacketPeriod;1947RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktInterval);1948sprintf(extra, "PacketPeriod [1~255]= %d\n", padapter->mppriv.pktInterval);19491950} else if (sscanf(extra, "pmact,length=%d", &PacketLength) > 0) {1951padapter->mppriv.pktLength = PacketLength;1952RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktLength);1953sprintf(extra, "PacketLength[~65535]=%d\n", padapter->mppriv.pktLength);19541955} else if (sscanf(extra, "pmact,count=%d", &PacketCout) > 0) {1956padapter->mppriv.tx_pktcount = PacketCout;1957RTW_INFO("Packet Cout =%d\n", padapter->mppriv.tx_pktcount);1958sprintf(extra, "Packet Cout =%d\n", padapter->mppriv.tx_pktcount);19591960} else if (sscanf(extra, "pmact,ldpc=%d", &bldpc) > 0) {1961pMptCtx->bldpc = bldpc;1962RTW_INFO("Set LDPC =%d\n", pMptCtx->bldpc);1963sprintf(extra, "Set LDPC =%d\n", pMptCtx->bldpc);19641965} else if (sscanf(extra, "pmact,stbc=%d", &bstbc) > 0) {1966pMptCtx->bstbc = bstbc;1967RTW_INFO("Set STBC =%d\n", pMptCtx->bstbc);1968sprintf(extra, "Set STBC =%d\n", pMptCtx->bstbc);1969} else1970sprintf(extra, "\n period={1~255}\n length={1000~65535}\n count={0~}\n ldpc={0/1}\n stbc={0/1}");19711972}19731974wrqu->data.length = strlen(extra);1975return 0;1976#endif1977} else {19781979if (sscanf(extra, "ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d", &channel, &bandwidth, &rate, &txpower, &ant, &txmode) < 6) {1980RTW_INFO("Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);1981_rtw_memset(extra, 0, wrqu->data.length);1982pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");1983pextra += sprintf(pextra, "\t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d\n", channel, bandwidth, rate, txpower, ant, txmode);1984pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");1985pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");1986pextra += sprintf(pextra, "\n [ rate : CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >]");1987pextra += sprintf(pextra, "\n [ OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108>");1988pextra += sprintf(pextra, "\n [ HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 >");1989pextra += sprintf(pextra, "\n [ HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 >");1990pextra += sprintf(pextra, "\n [ VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 >");1991pextra += sprintf(pextra, "\n [ txpower : 1~63 power index");1992pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");1993pextra += sprintf(pextra, "\n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX>\n");1994wrqu->data.length = strlen(extra);1995return status;19961997} else {1998char *pextra = extra;1999RTW_INFO("Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);2000_rtw_memset(extra, 0, wrqu->data.length);2001sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);2002padapter->mppriv.channel = channel;2003SetChannel(padapter);2004pHalData->current_channel = channel;20052006if (bandwidth == 1)2007bandwidth = CHANNEL_WIDTH_40;2008else if (bandwidth == 2)2009bandwidth = CHANNEL_WIDTH_80;2010pextra = extra + strlen(pextra);2011pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);2012padapter->mppriv.bandwidth = (u8)bandwidth;2013padapter->mppriv.preamble = sg;2014SetBandwidth(padapter);2015pHalData->current_channel_bw = bandwidth;20162017pextra += sprintf(pextra, "\nSet power level :%d", txpower);2018padapter->mppriv.txpoweridx = (u8)txpower;2019pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)txpower;2020pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)txpower;2021pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)txpower;2022pMptCtx->TxPwrLevel[RF_PATH_D] = (u8)txpower;2023SetTxPower(padapter);20242025RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth, sg);20262027if (rate <= 0x7f)2028rate = wifirate2_ratetbl_inx((u8)rate);2029else if (rate < 0xC8)2030rate = (rate - 0x80 + MPT_RATE_MCS0);2031/*HT rate 0x80(MCS0) ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~1592032VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~1792033VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~1992034else2035VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~1532036rate =(rate - MPT_RATE_VHT1SS_MCS0);2037*/2038RTW_INFO("%s: rate index=%d\n", __func__, rate);2039if (rate >= MPT_RATE_LAST)2040return -EINVAL;2041pextra += sprintf(pextra, "\nSet data rate to %d index %d", padapter->mppriv.rateidx, rate);20422043padapter->mppriv.rateidx = rate;2044pMptCtx->mpt_rate_index = rate;2045SetDataRate(padapter);20462047pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);2048switch (ant) {2049case 1:2050antenna = ANTENNA_A;2051break;2052case 2:2053antenna = ANTENNA_B;2054break;2055case 4:2056antenna = ANTENNA_C;2057break;2058case 8:2059antenna = ANTENNA_D;2060break;2061case 3:2062antenna = ANTENNA_AB;2063break;2064case 5:2065antenna = ANTENNA_AC;2066break;2067case 9:2068antenna = ANTENNA_AD;2069break;2070case 6:2071antenna = ANTENNA_BC;2072break;2073case 10:2074antenna = ANTENNA_BD;2075break;2076case 12:2077antenna = ANTENNA_CD;2078break;2079case 7:2080antenna = ANTENNA_ABC;2081break;2082case 14:2083antenna = ANTENNA_BCD;2084break;2085case 11:2086antenna = ANTENNA_ABD;2087break;2088case 15:2089antenna = ANTENNA_ABCD;2090break;2091}2092RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);2093padapter->mppriv.antenna_tx = antenna;2094padapter->mppriv.antenna_rx = antenna;2095pHalData->antenna_tx_path = antenna;2096SetAntenna(padapter);20972098if (txmode == 0)2099pmp_priv->mode = MP_CONTINUOUS_TX;2100else if (txmode == 1) {2101pmp_priv->mode = MP_PACKET_TX;2102pmp_priv->tx.count = count;2103} else if (txmode == 2)2104pmp_priv->mode = MP_SINGLE_TONE_TX;2105else if (txmode == 3)2106pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;2107else if (txmode == 4)2108pmp_priv->mode = MP_SINGLE_CARRIER_TX;21092110status = rtw_mp_pretx_proc(padapter, bStartTest, extra);2111}21122113}21142115wrqu->data.length = strlen(extra);2116return status;2117}211821192120int rtw_mp_rx(struct net_device *dev,2121struct iw_request_info *info,2122union iwreq_data *wrqu, char *extra)2123{2124PADAPTER padapter = rtw_netdev_priv(dev);2125HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);2126struct mp_priv *pmp_priv = &padapter->mppriv;2127char *pextra = extra;2128u32 bandwidth = 0, sg = 0, channel = 6, ant = 0;2129u16 antenna = 0;2130u8 bStartRx = 0;21312132if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2133return -EFAULT;21342135#ifdef CONFIG_CONCURRENT_MODE2136if (!is_primary_adapter(padapter)) {2137sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");2138wrqu->data.length = strlen(extra);2139return 0;2140}2141#endif21422143if (strncmp(extra, "stop", 4) == 0) {2144_rtw_memset(extra, 0, wrqu->data.length);2145SetPacketRx(padapter, bStartRx, _FALSE);2146pmp_priv->bmac_filter = _FALSE;2147sprintf(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);2148wrqu->data.length = strlen(extra);2149return 0;21502151} else if (sscanf(extra, "ch=%d,bw=%d,ant=%d", &channel, &bandwidth, &ant) < 3) {2152RTW_INFO("Invalid format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);2153_rtw_memset(extra, 0, wrqu->data.length);2154pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");2155pextra += sprintf(pextra, "\t ch=%d,bw=%d,ant=%d\n", channel, bandwidth, ant);2156pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");2157pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");2158pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");2159wrqu->data.length = strlen(extra);2160return 0;21612162} else {2163char *pextra = extra;2164bStartRx = 1;2165RTW_INFO("Got format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);2166_rtw_memset(extra, 0, wrqu->data.length);2167sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);2168padapter->mppriv.channel = channel;2169SetChannel(padapter);2170pHalData->current_channel = channel;21712172if (bandwidth == 1)2173bandwidth = CHANNEL_WIDTH_40;2174else if (bandwidth == 2)2175bandwidth = CHANNEL_WIDTH_80;2176pextra = extra + strlen(extra);2177pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);2178padapter->mppriv.bandwidth = (u8)bandwidth;2179padapter->mppriv.preamble = sg;2180SetBandwidth(padapter);2181pHalData->current_channel_bw = bandwidth;21822183pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);2184switch (ant) {2185case 1:2186antenna = ANTENNA_A;2187break;2188case 2:2189antenna = ANTENNA_B;2190break;2191case 4:2192antenna = ANTENNA_C;2193break;2194case 8:2195antenna = ANTENNA_D;2196break;2197case 3:2198antenna = ANTENNA_AB;2199break;2200case 5:2201antenna = ANTENNA_AC;2202break;2203case 9:2204antenna = ANTENNA_AD;2205break;2206case 6:2207antenna = ANTENNA_BC;2208break;2209case 10:2210antenna = ANTENNA_BD;2211break;2212case 12:2213antenna = ANTENNA_CD;2214break;2215case 7:2216antenna = ANTENNA_ABC;2217break;2218case 14:2219antenna = ANTENNA_BCD;2220break;2221case 11:2222antenna = ANTENNA_ABD;2223break;2224case 15:2225antenna = ANTENNA_ABCD;2226break;2227}2228RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);2229padapter->mppriv.antenna_tx = antenna;2230padapter->mppriv.antenna_rx = antenna;2231pHalData->antenna_tx_path = antenna;2232SetAntenna(padapter);22332234strcat(extra, "\nstart Rx");2235SetPacketRx(padapter, bStartRx, _FALSE);2236}2237wrqu->data.length = strlen(extra);2238return 0;2239}224022412242int rtw_mp_hwtx(struct net_device *dev,2243struct iw_request_info *info,2244union iwreq_data *wrqu, char *extra)2245{2246PADAPTER padapter = rtw_netdev_priv(dev);2247struct mp_priv *pmp_priv = &padapter->mppriv;2248PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);22492250#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)2251if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2252return -EFAULT;2253*(extra + wrqu->data.length) = '\0';22542255_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(RT_PMAC_TX_INFO));2256_rtw_memcpy((void *)&pMptCtx->PMacTxInfo, (void *)extra, sizeof(RT_PMAC_TX_INFO));2257_rtw_memset(extra, 0, wrqu->data.length);22582259if (pMptCtx->PMacTxInfo.bEnPMacTx == 1 && pmp_priv->mode != MP_ON) {2260sprintf(extra, "MP Tx Running, Please Set PMac Tx Mode Stop\n");2261RTW_INFO("Error !!! MP Tx Running, Please Set PMac Tx Mode Stop\n");2262} else {2263RTW_INFO("To set MAC Tx mode\n");2264mpt_ProSetPMacTx(padapter);2265sprintf(extra, "Set PMac Tx Mode OK\n");2266}2267wrqu->data.length = strlen(extra);2268#endif2269return 0;22702271}22722273int rtw_mp_pwrlmt(struct net_device *dev,2274struct iw_request_info *info,2275union iwreq_data *wrqu, char *extra)2276{2277PADAPTER padapter = rtw_netdev_priv(dev);2278struct registry_priv *registry_par = &padapter->registrypriv;2279u8 pwrlimtstat = 0;22802281if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2282return -EFAULT;22832284*(extra + wrqu->data.length) = '\0';2285#if CONFIG_TXPWR_LIMIT2286pwrlimtstat = registry_par->RegEnableTxPowerLimit;2287if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {2288padapter->registrypriv.RegEnableTxPowerLimit = 0;2289sprintf(extra, "Turn off Power Limit\n");22902291} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {2292padapter->registrypriv.RegEnableTxPowerLimit = 1;2293sprintf(extra, "Turn on Power Limit\n");22942295} else2296#endif2297sprintf(extra, "Get Power Limit Status:%s\n", (pwrlimtstat == 1) ? "ON" : "OFF");229822992300wrqu->data.length = strlen(extra);2301return 0;2302}23032304int rtw_mp_pwrbyrate(struct net_device *dev,2305struct iw_request_info *info,2306union iwreq_data *wrqu, char *extra)2307{2308PADAPTER padapter = rtw_netdev_priv(dev);23092310if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2311return -EFAULT;23122313*(extra + wrqu->data.length) = '\0';2314if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {2315padapter->registrypriv.RegEnableTxPowerByRate = 0;2316sprintf(extra, "Turn off Tx Power by Rate\n");23172318} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {2319padapter->registrypriv.RegEnableTxPowerByRate = 1;2320sprintf(extra, "Turn On Tx Power by Rate\n");23212322} else {2323sprintf(extra, "Get Power by Rate Status:%s\n", (padapter->registrypriv.RegEnableTxPowerByRate == 1) ? "ON" : "OFF");2324}23252326wrqu->data.length = strlen(extra);2327return 0;2328}232923302331int rtw_mp_dpk_track(struct net_device *dev,2332struct iw_request_info *info,2333union iwreq_data *wrqu, char *extra)2334{2335PADAPTER padapter = rtw_netdev_priv(dev);2336HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);2337struct dm_struct *pDM_Odm = &pHalData->odmpriv;233823392340if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2341return -EFAULT;23422343*(extra + wrqu->data.length) = '\0';23442345if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {2346halrf_set_dpk_track(pDM_Odm, FALSE);2347sprintf(extra, "set dpk track off\n");23482349} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {2350halrf_set_dpk_track(pDM_Odm, TRUE);2351sprintf(extra, "set dpk track on\n");2352}23532354wrqu->data.length = strlen(extra);2355return 0;2356}235723582359int rtw_bt_efuse_mask_file(struct net_device *dev,2360struct iw_request_info *info,2361union iwreq_data *wrqu, char *extra)2362{2363char *rtw_efuse_mask_file_path;2364u8 Status;2365PADAPTER padapter = rtw_netdev_priv(dev);23662367_rtw_memset(btmaskfileBuffer, 0x00, sizeof(btmaskfileBuffer));23682369if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2370return -EFAULT;23712372*(extra + wrqu->data.length) = '\0';23732374if (strncmp(extra, "data,", 5) == 0) {2375u8 *pch;2376char *ptmp, tmp;2377u8 count = 0;2378u8 i = 0;23792380ptmp = extra;2381pch = strsep(&ptmp, ",");23822383if ((pch == NULL) || (strlen(pch) == 0)) {2384RTW_INFO("%s: parameter error(no cmd)!\n", __func__);2385return -EFAULT;2386}23872388do {2389pch = strsep(&ptmp, ":");2390if ((pch == NULL) || (strlen(pch) == 0))2391break;2392if (strlen(pch) != 22393|| IsHexDigit(*pch) == _FALSE2394|| IsHexDigit(*(pch + 1)) == _FALSE2395|| sscanf(pch, "%hhx", &tmp) != 12396) {2397RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);2398return -EFAULT;2399}2400btmaskfileBuffer[count++] = tmp;24012402} while (count < 64);24032404_rtw_memset(extra, '\0' , strlen(extra));24052406for (i = 0; i < count; i++)2407ptmp += sprintf(ptmp, "%02x:", btmaskfileBuffer[i]);24082409padapter->registrypriv.bBTFileMaskEfuse = _TRUE;24102411sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count);2412wrqu->data.length = strlen(extra);2413return 0;2414}2415rtw_efuse_mask_file_path = extra;24162417if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {2418RTW_INFO("%s do rtw_is_file_readable = %s! ,sizeof BT maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(btmaskfileBuffer));2419Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, btmaskfileBuffer, sizeof(btmaskfileBuffer));2420if (Status == _TRUE) {2421padapter->registrypriv.bBTFileMaskEfuse = _TRUE;2422sprintf(extra, "BT efuse mask file read OK\n");2423} else {2424padapter->registrypriv.bBTFileMaskEfuse = _FALSE;2425sprintf(extra, "read BT efuse mask file FAIL\n");2426RTW_INFO("%s rtw_efuse_file_read BT mask fail!\n", __func__);2427}2428} else {2429padapter->registrypriv.bBTFileMaskEfuse = _FALSE;2430sprintf(extra, "BT efuse mask file readable FAIL\n");2431RTW_INFO("%s rtw_is_file_readable BT Mask file fail!\n", __func__);2432}2433wrqu->data.length = strlen(extra);2434return 0;2435}243624372438int rtw_efuse_mask_file(struct net_device *dev,2439struct iw_request_info *info,2440union iwreq_data *wrqu, char *extra)2441{2442char *rtw_efuse_mask_file_path;2443u8 Status;2444PADAPTER padapter = rtw_netdev_priv(dev);24452446_rtw_memset(maskfileBuffer, 0x00, sizeof(maskfileBuffer));24472448if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2449return -EFAULT;24502451*(extra + wrqu->data.length) = '\0';2452if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {2453padapter->registrypriv.boffefusemask = 1;2454sprintf(extra, "Turn off Efuse Mask\n");2455wrqu->data.length = strlen(extra);2456return 0;2457}2458if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {2459padapter->registrypriv.boffefusemask = 0;2460sprintf(extra, "Turn on Efuse Mask\n");2461wrqu->data.length = strlen(extra);2462return 0;2463}2464if (strncmp(extra, "data,", 5) == 0) {2465u8 *pch;2466char *ptmp, tmp;2467u8 count = 0;2468u8 i = 0;24692470ptmp = extra;2471pch = strsep(&ptmp, ",");24722473if ((pch == NULL) || (strlen(pch) == 0)) {2474RTW_INFO("%s: parameter error(no cmd)!\n", __func__);2475return -EFAULT;2476}24772478do {2479pch = strsep(&ptmp, ":");2480if ((pch == NULL) || (strlen(pch) == 0))2481break;2482if (strlen(pch) != 22483|| IsHexDigit(*pch) == _FALSE2484|| IsHexDigit(*(pch + 1)) == _FALSE2485|| sscanf(pch, "%hhx", &tmp) != 12486) {2487RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);2488return -EFAULT;2489}2490maskfileBuffer[count++] = tmp;24912492} while (count < 64);24932494_rtw_memset(extra, '\0' , strlen(extra));24952496for (i = 0; i < count; i++)2497ptmp += sprintf(ptmp, "%02x:", maskfileBuffer[i]);24982499padapter->registrypriv.bFileMaskEfuse = _TRUE;25002501sprintf(ptmp, "\nLoad Efuse Mask data %d hex ok\n", count);2502wrqu->data.length = strlen(extra);2503return 0;2504}2505rtw_efuse_mask_file_path = extra;25062507if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {2508RTW_INFO("%s do rtw_efuse_mask_file_read = %s! ,sizeof maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(maskfileBuffer));2509Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, maskfileBuffer, sizeof(maskfileBuffer));2510if (Status == _TRUE) {2511padapter->registrypriv.bFileMaskEfuse = _TRUE;2512sprintf(extra, "efuse mask file read OK\n");2513} else {2514padapter->registrypriv.bFileMaskEfuse = _FALSE;2515sprintf(extra, "read efuse mask file FAIL\n");2516RTW_INFO("%s rtw_efuse_file_read mask fail!\n", __func__);2517}2518} else {2519padapter->registrypriv.bFileMaskEfuse = _FALSE;2520sprintf(extra, "efuse mask file readable FAIL\n");2521RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);2522}2523wrqu->data.length = strlen(extra);2524return 0;2525}252625272528int rtw_efuse_file_map(struct net_device *dev,2529struct iw_request_info *info,2530union iwreq_data *wrqu, char *extra)2531{2532char *rtw_efuse_file_map_path;2533u8 Status;2534PEFUSE_HAL pEfuseHal;2535PADAPTER padapter = rtw_netdev_priv(dev);2536HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);2537struct mp_priv *pmp_priv = &padapter->mppriv;25382539pEfuseHal = &pHalData->EfuseHal;2540if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2541return -EFAULT;25422543rtw_efuse_file_map_path = extra;25442545_rtw_memset(pEfuseHal->fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);25462547if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {2548RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);2549Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, sizeof(pEfuseHal->fakeEfuseModifiedMap));2550if (Status == _TRUE) {2551pmp_priv->bloadefusemap = _TRUE;2552sprintf(extra, "efuse file file_read OK\n");2553} else {2554pmp_priv->bloadefusemap = _FALSE;2555sprintf(extra, "efuse file file_read FAIL\n");2556}2557} else {2558sprintf(extra, "efuse file readable FAIL\n");2559RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);2560}2561wrqu->data.length = strlen(extra);2562return 0;2563}25642565int rtw_bt_efuse_file_map(struct net_device *dev,2566struct iw_request_info *info,2567union iwreq_data *wrqu, char *extra)2568{2569char *rtw_efuse_file_map_path;2570u8 Status;2571PEFUSE_HAL pEfuseHal;2572PADAPTER padapter = rtw_netdev_priv(dev);2573HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);2574struct mp_priv *pmp_priv = &padapter->mppriv;25752576pEfuseHal = &pHalData->EfuseHal;2577if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2578return -EFAULT;25792580rtw_efuse_file_map_path = extra;25812582_rtw_memset(pEfuseHal->fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);25832584if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {2585RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);2586Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeBTEfuseModifiedMap, sizeof(pEfuseHal->fakeBTEfuseModifiedMap));2587if (Status == _TRUE) {2588pmp_priv->bloadBTefusemap = _TRUE;2589sprintf(extra, "BT efuse file file_read OK\n");2590} else {2591pmp_priv->bloadBTefusemap = _FALSE;2592sprintf(extra, "BT efuse file file_read FAIL\n");2593}2594} else {2595sprintf(extra, "BT efuse file readable FAIL\n");2596RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);2597}2598wrqu->data.length = strlen(extra);2599return 0;2600}260126022603static inline void dump_buf(u8 *buf, u32 len)2604{2605u32 i;26062607RTW_INFO("-----------------Len %d----------------\n", len);2608for (i = 0; i < len; i++)2609RTW_INFO("%2.2x-", *(buf + i));2610RTW_INFO("\n");2611}26122613int rtw_mp_link(struct net_device *dev,2614struct iw_request_info *info,2615struct iw_point *wrqu, char *extra)2616{2617PADAPTER padapter = rtw_netdev_priv(dev);2618struct mp_priv *pmp_priv;2619char input[wrqu->length];2620int bgetrxdata = 0, btxdata = 0, bsetbt = 0;2621u8 err = 0;2622u32 i = 0, datalen = 0,jj, kk, waittime = 0;2623u16 val = 0x00, ret = 0;2624char *pextra = NULL;2625u8 *setdata = NULL;2626char *pch, *ptmp, *token, *tmp[4] = {0x00, 0x00, 0x00};26272628pmp_priv = &padapter->mppriv;26292630if (copy_from_user(input, wrqu->pointer, wrqu->length))2631return -EFAULT;26322633_rtw_memset(extra, 0, wrqu->length);26342635RTW_INFO("%s: in=%s\n", __func__, input);26362637bgetrxdata = (strncmp(input, "rxdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/2638btxdata = (strncmp(input, "txdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/2639bsetbt = (strncmp(input, "setbt", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/26402641if (bgetrxdata) {2642RTW_INFO("%s: in= 1 \n", __func__);2643if (pmp_priv->mplink_brx == _TRUE) {26442645while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) {2646if (pmp_priv->mplink_brx == _FALSE)2647rtw_msleep_os(10);2648else2649break;2650waittime++;2651}2652if (pmp_priv->mplink_brx == _TRUE) {2653sprintf(extra, "\n");2654pextra = extra + strlen(extra);2655for (i = 0; i < pmp_priv->mplink_rx_len; i ++) {2656pextra += sprintf(pextra, "%02x:", pmp_priv->mplink_buf[i]);2657}2658_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));2659pmp_priv->mplink_brx = _FALSE;2660}2661}2662} else if (btxdata) {2663struct pkt_attrib *pattrib;26642665pch = input;2666setdata = rtw_zmalloc(1024);2667if (setdata == NULL) {2668err = -ENOMEM;2669goto exit;2670}26712672i = 0;2673while ((token = strsep(&pch, ",")) != NULL) {2674if (i > 2)2675break;2676tmp[i] = token;2677i++;2678}26792680/* tmp[0],[1],[2] */2681/* txdata,00e04c871200........... */2682if (strcmp(tmp[0], "txdata") == 0) {2683if ((tmp[1] == NULL)) {2684err = -EINVAL;2685goto exit;2686}2687}26882689datalen = strlen(tmp[1]);2690if (datalen % 2) {2691err = -EINVAL;2692goto exit;2693}2694datalen /= 2;2695if (datalen == 0) {2696err = -EINVAL;2697goto exit;2698}26992700RTW_INFO("%s: data len=%d\n", __FUNCTION__, datalen);2701RTW_INFO("%s: tx data=%s\n", __FUNCTION__, tmp[1]);27022703for (jj = 0, kk = 0; jj < datalen; jj++, kk += 2)2704setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);27052706dump_buf(setdata, datalen);2707_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));2708_rtw_memcpy(pmp_priv->mplink_buf, setdata, datalen);27092710pattrib = &pmp_priv->tx.attrib;2711pattrib->pktlen = datalen;2712pmp_priv->tx.count = 1;2713pmp_priv->tx.stop = 0;2714pmp_priv->mplink_btx = _TRUE;2715SetPacketTx(padapter);2716pmp_priv->mode = MP_PACKET_TX;27172718} else if (bsetbt) {27192720#ifdef CONFIG_BT_COEXIST2721pch = input;2722i = 0;27232724while ((token = strsep(&pch, ",")) != NULL) {2725if (i > 3)2726break;2727tmp[i] = token;2728i++;2729}27302731if (tmp[1] == NULL) {2732err = -EINVAL;2733goto exit;2734}27352736if (strcmp(tmp[1], "scbd") == 0) {2737u16 org_val = 0x8002, pre_val, read_score_board_val;2738u8 state;27392740pre_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;27412742if (tmp[2] != NULL) {2743state = simple_strtoul(tmp[2], &ptmp, 10);27442745if (state)2746org_val = org_val | BIT6;2747else2748org_val = org_val & (~BIT6);27492750if (org_val != pre_val) {2751pre_val = org_val;2752rtw_write16(padapter, 0xaa, org_val);2753RTW_INFO("%s,setbt scbd write org_val = 0x%x , pre_val = 0x%x\n", __func__, org_val, pre_val);2754} else {2755RTW_INFO("%s,setbt scbd org_val = 0x%x ,pre_val = 0x%x\n", __func__, org_val, pre_val);2756}2757} else {2758read_score_board_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;2759RTW_INFO("%s,read_score_board_val = 0x%x\n", __func__, read_score_board_val);2760}2761goto exit;27622763} else if (strcmp(tmp[1], "testmode") == 0) {27642765if (tmp[2] == NULL) {2766err = -EINVAL;2767goto exit;2768}27692770val = simple_strtoul(tmp[2], &ptmp, 16);2771RTW_INFO("get tmp, type %s, val =0x%x!\n", tmp[1], val);27722773if (tmp[2] != NULL) {2774_rtw_memset(extra, 0, wrqu->length);2775ret = rtw_btcoex_btset_testmode(padapter, val);2776if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) {2777RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val);2778sprintf(extra, "BT_OP fail 0x%x!\n", val);2779} else2780sprintf(extra, "Set BT_OP 0x%x done!\n", val);2781}27822783}2784#endif /* CONFIG_BT_COEXIST */2785}27862787exit:2788if (setdata)2789rtw_mfree(setdata, 1024);27902791wrqu->length = strlen(extra);2792return err;27932794}27952796#if defined(CONFIG_RTL8723B)2797int rtw_mp_SetBT(struct net_device *dev,2798struct iw_request_info *info,2799union iwreq_data *wrqu, char *extra)2800{2801PADAPTER padapter = rtw_netdev_priv(dev);2802struct hal_ops *pHalFunc = &padapter->hal_func;2803HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);28042805BT_REQ_CMD BtReq;2806PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);2807PBT_RSP_CMD pBtRsp = (PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];2808char input[128];2809char *pch, *ptmp, *token, *tmp[2] = {0x00, 0x00};2810u8 setdata[100];2811u8 resetbt = 0x00;2812u8 tempval, BTStatus;2813u8 H2cSetbtmac[6];2814u8 u1H2CBtMpOperParm[4] = {0x01};2815int testmode = 1, ready = 1, trxparam = 1, setgen = 1, getgen = 1, testctrl = 1, testbt = 1, readtherm = 1, setbtmac = 1;2816u32 i = 0, ii = 0, jj = 0, kk = 0, cnts = 0, status = 0;2817PRT_MP_FIRMWARE pBTFirmware = NULL;28182819if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))2820return -EFAULT;28212822*(extra + wrqu->data.length) = '\0';28232824if (strlen(extra) < 1)2825return -EFAULT;28262827RTW_INFO("%s:iwpriv in=%s\n", __func__, extra);2828ready = strncmp(extra, "ready", 5);2829testmode = strncmp(extra, "testmode", 8); /* strncmp TRUE is 0*/2830trxparam = strncmp(extra, "trxparam", 8);2831setgen = strncmp(extra, "setgen", 6);2832getgen = strncmp(extra, "getgen", 6);2833testctrl = strncmp(extra, "testctrl", 8);2834testbt = strncmp(extra, "testbt", 6);2835readtherm = strncmp(extra, "readtherm", 9);2836setbtmac = strncmp(extra, "setbtmac", 8);28372838if (strncmp(extra, "dlbt", 4) == 0) {2839pHalData->LastHMEBoxNum = 0;2840pHalData->bBTFWReady = _FALSE;2841rtw_write8(padapter, 0xa3, 0x05);2842BTStatus = rtw_read8(padapter, 0xa0);2843RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);2844if (BTStatus != 0x04) {2845sprintf(extra, "BT Status not Active DLFW FAIL\n");2846goto exit;2847}28482849tempval = rtw_read8(padapter, 0x6B);2850tempval |= BIT7;2851rtw_write8(padapter, 0x6B, tempval);28522853/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/2854/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/2855rtw_usleep_os(100);2856/* disable BT power cut*/2857/* 0x6A[14] = 0*/2858tempval = rtw_read8(padapter, 0x6B);2859tempval &= ~BIT6;2860rtw_write8(padapter, 0x6B, tempval);2861rtw_usleep_os(100);2862MPT_PwrCtlDM(padapter, 0);2863rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));2864rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));2865rtw_msleep_os(600);2866rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));2867rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));2868rtw_msleep_os(1200);2869pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));2870if (pBTFirmware == NULL)2871goto exit;2872pHalData->bBTFWReady = _FALSE;2873FirmwareDownloadBT(padapter, pBTFirmware);2874if (pBTFirmware)2875rtw_mfree((u8 *)pBTFirmware, sizeof(RT_MP_FIRMWARE));28762877RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");2878rtw_msleep_os(2000);2879_rtw_memset(extra, '\0', wrqu->data.length);2880BtReq.opCodeVer = 1;2881BtReq.OpCode = 0;2882BtReq.paraLength = 0;2883mptbt_BtControlProcess(padapter, &BtReq);2884rtw_msleep_os(100);28852886RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);2887if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {28882889if (padapter->mppriv.bTxBufCkFail == _TRUE)2890sprintf(extra, "check TxBuf Fail.\n");2891else2892sprintf(extra, "download FW Fail.\n");2893} else {2894sprintf(extra, "download FW OK.\n");2895goto exit;2896}2897goto exit;2898}2899if (strncmp(extra, "dlfw", 4) == 0) {2900pHalData->LastHMEBoxNum = 0;2901pHalData->bBTFWReady = _FALSE;2902rtw_write8(padapter, 0xa3, 0x05);2903BTStatus = rtw_read8(padapter, 0xa0);2904RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);2905if (BTStatus != 0x04) {2906sprintf(extra, "BT Status not Active DLFW FAIL\n");2907goto exit;2908}29092910tempval = rtw_read8(padapter, 0x6B);2911tempval |= BIT7;2912rtw_write8(padapter, 0x6B, tempval);29132914/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/2915/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/2916rtw_usleep_os(100);2917/* disable BT power cut*/2918/* 0x6A[14] = 0*/2919tempval = rtw_read8(padapter, 0x6B);2920tempval &= ~BIT6;2921rtw_write8(padapter, 0x6B, tempval);2922rtw_usleep_os(100);29232924MPT_PwrCtlDM(padapter, 0);2925rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));2926rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));2927rtw_msleep_os(600);2928rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));2929rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));2930rtw_msleep_os(1200);29312932#if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)2933/* Pull up BT reset pin.*/2934RTW_INFO("%s: pull up BT reset pin when bt start mp test\n", __func__);2935rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);2936#endif2937RTW_INFO(" FirmwareDownload!\n");29382939#if defined(CONFIG_RTL8723B)2940status = rtl8723b_FirmwareDownload(padapter, _FALSE);2941#endif2942RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");2943rtw_msleep_os(1000);2944#ifdef CONFIG_BT_COEXIST2945rtw_btcoex_HaltNotify(padapter);2946RTW_INFO("SetBT btcoex HaltNotify !\n");2947/*hal_btcoex1ant_SetAntPath(padapter);*/2948rtw_btcoex_SetManualControl(padapter, _TRUE);2949#endif2950_rtw_memset(extra, '\0', wrqu->data.length);2951BtReq.opCodeVer = 1;2952BtReq.OpCode = 0;2953BtReq.paraLength = 0;2954mptbt_BtControlProcess(padapter, &BtReq);2955rtw_msleep_os(200);29562957RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);2958if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {2959if (padapter->mppriv.bTxBufCkFail == _TRUE)2960sprintf(extra, "check TxBuf Fail.\n");2961else2962sprintf(extra, "download FW Fail.\n");2963} else {2964#ifdef CONFIG_BT_COEXIST2965rtw_btcoex_SwitchBtTRxMask(padapter);2966#endif2967rtw_msleep_os(200);2968sprintf(extra, "download FW OK.\n");2969goto exit;2970}2971goto exit;2972}29732974if (strncmp(extra, "down", 4) == 0) {2975RTW_INFO("SetBT down for to hal_init !\n");2976#ifdef CONFIG_BT_COEXIST2977rtw_btcoex_SetManualControl(padapter, _FALSE);2978rtw_btcoex_Initialize(padapter);2979#endif2980pHalFunc->read_adapter_info(padapter);2981pHalFunc->hal_deinit(padapter);2982pHalFunc->hal_init(padapter);2983rtw_pm_set_ips(padapter, IPS_NONE);2984LeaveAllPowerSaveMode(padapter);2985MPT_PwrCtlDM(padapter, 0);2986rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));2987rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));2988rtw_msleep_os(600);2989/*rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));*/2990rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));2991rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));2992rtw_msleep_os(1200);2993goto exit;2994}2995if (strncmp(extra, "disable", 7) == 0) {2996RTW_INFO("SetBT disable !\n");2997rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) & 0xFFFFFFFB));2998rtw_msleep_os(500);2999goto exit;3000}3001if (strncmp(extra, "enable", 6) == 0) {3002RTW_INFO("SetBT enable !\n");3003rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) | 0x00000004));3004rtw_msleep_os(500);3005goto exit;3006}3007if (strncmp(extra, "h2c", 3) == 0) {3008RTW_INFO("SetBT h2c !\n");3009pHalData->bBTFWReady = _TRUE;3010rtw_hal_fill_h2c_cmd(padapter, 0x63, 1, u1H2CBtMpOperParm);3011goto exit;3012}3013if (strncmp(extra, "2ant", 4) == 0) {3014RTW_INFO("Set BT 2ant use!\n");3015phy_set_mac_reg(padapter, 0x67, BIT5, 0x1);3016rtw_write32(padapter, 0x948, 0000);30173018goto exit;3019}30203021if (ready != 0 && testmode != 0 && trxparam != 0 && setgen != 0 && getgen != 0 && testctrl != 0 && testbt != 0 && readtherm != 0 && setbtmac != 0)3022return -EFAULT;30233024if (testbt == 0) {3025BtReq.opCodeVer = 1;3026BtReq.OpCode = 6;3027BtReq.paraLength = cnts / 2;3028goto todo;3029}3030if (ready == 0) {3031BtReq.opCodeVer = 1;3032BtReq.OpCode = 0;3033BtReq.paraLength = 0;3034goto todo;3035}30363037pch = extra;3038i = 0;3039while ((token = strsep(&pch, ",")) != NULL) {3040if (i > 1)3041break;3042tmp[i] = token;3043i++;3044}30453046if ((tmp[0] != NULL) && (tmp[1] != NULL)) {3047cnts = strlen(tmp[1]);3048if (cnts < 1)3049return -EFAULT;30503051RTW_INFO("%s: cnts=%d\n", __func__, cnts);3052RTW_INFO("%s: data=%s\n", __func__, tmp[1]);30533054for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) {3055BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);3056/* RTW_INFO("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);*/3057}3058} else3059return -EFAULT;30603061if (testmode == 0) {3062BtReq.opCodeVer = 1;3063BtReq.OpCode = 1;3064BtReq.paraLength = 1;3065}3066if (trxparam == 0) {3067BtReq.opCodeVer = 1;3068BtReq.OpCode = 2;3069BtReq.paraLength = cnts / 2;3070}3071if (setgen == 0) {3072RTW_INFO("%s: BT_SET_GENERAL\n", __func__);3073BtReq.opCodeVer = 1;3074BtReq.OpCode = 3;/*BT_SET_GENERAL 3*/3075BtReq.paraLength = cnts / 2;3076}3077if (getgen == 0) {3078RTW_INFO("%s: BT_GET_GENERAL\n", __func__);3079BtReq.opCodeVer = 1;3080BtReq.OpCode = 4;/*BT_GET_GENERAL 4*/3081BtReq.paraLength = cnts / 2;3082}3083if (readtherm == 0) {3084RTW_INFO("%s: BT_GET_GENERAL\n", __func__);3085BtReq.opCodeVer = 1;3086BtReq.OpCode = 4;/*BT_GET_GENERAL 4*/3087BtReq.paraLength = cnts / 2;3088}30893090if (testctrl == 0) {3091RTW_INFO("%s: BT_TEST_CTRL\n", __func__);3092BtReq.opCodeVer = 1;3093BtReq.OpCode = 5;/*BT_TEST_CTRL 5*/3094BtReq.paraLength = cnts / 2;3095}30963097RTW_INFO("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",3098__func__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);30993100if (BtReq.paraLength < 1)3101goto todo;3102for (i = 0; i < BtReq.paraLength; i++) {3103RTW_INFO("%s: BtReq.pParamStart[%d] = 0x%02x\n",3104__func__, i, BtReq.pParamStart[i]);3105}31063107todo:3108_rtw_memset(extra, '\0', wrqu->data.length);31093110if (pHalData->bBTFWReady == _FALSE) {3111sprintf(extra, "BTFWReady = FALSE.\n");3112goto exit;3113}31143115mptbt_BtControlProcess(padapter, &BtReq);31163117if (readtherm == 0) {3118sprintf(extra, "BT thermal=");3119for (i = 4; i < pMptCtx->mptOutLen; i++) {3120if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00))3121goto exit;31223123sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i] & 0x1f));3124}3125} else {3126for (i = 4; i < pMptCtx->mptOutLen; i++)3127sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]);3128}31293130exit:3131wrqu->data.length = strlen(extra) + 1;3132RTW_INFO("-%s: output len=%d data=%s\n", __func__, wrqu->data.length, extra);31333134return status;3135}31363137#endif /*#ifdef CONFIG_RTL8723B*/31383139#endif314031413142