mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
staging: r8723au: Add source files for new driver - part 1
The Realtek USB device RTL8723AU is found in Lenovo Yoga 13 tablets. A driver for it has been available in a GitHub repo for several months. This commit contains the first part of the source files. The source is arbitrarily split to avoid E-mail files that are too large. Jes Sorensen at RedHat has made many improvements to the vendor code, and he has been doing the testing. I do not have access to this device. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: Jes Sorensen <Jes.Sorensen@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8e0c083234
commit
5e93f35209
2087
drivers/staging/rtl8723au/core/rtw_ap.c
Normal file
2087
drivers/staging/rtl8723au/core/rtw_ap.c
Normal file
File diff suppressed because it is too large
Load Diff
1874
drivers/staging/rtl8723au/core/rtw_cmd.c
Normal file
1874
drivers/staging/rtl8723au/core/rtw_cmd.c
Normal file
File diff suppressed because it is too large
Load Diff
718
drivers/staging/rtl8723au/core/rtw_efuse.c
Normal file
718
drivers/staging/rtl8723au/core/rtw_efuse.c
Normal file
@ -0,0 +1,718 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RTW_EFUSE_C_
|
||||
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
|
||||
#include <rtw_efuse.h>
|
||||
|
||||
/*------------------------Define local variable------------------------------*/
|
||||
|
||||
/* */
|
||||
#define REG_EFUSE_CTRL 0x0030
|
||||
#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
|
||||
/* */
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: Efuse_PowerSwitch23a
|
||||
*
|
||||
* Overview: When we want to enable write operation, we should change to
|
||||
* pwr on state. When we stop write, we should switch to 500k mode
|
||||
* and disable LDO 2.5V.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/17/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
Efuse_PowerSwitch23a(
|
||||
struct rtw_adapter * pAdapter,
|
||||
u8 bWrite,
|
||||
u8 PwrState)
|
||||
{
|
||||
pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: efuse_GetCurrentSize23a
|
||||
*
|
||||
* Overview: Get current efuse size!!!
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/16/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
u16
|
||||
Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType)
|
||||
{
|
||||
u16 ret = 0;
|
||||
|
||||
ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
|
||||
u8
|
||||
Efuse_CalculateWordCnts23a(u8 word_en)
|
||||
{
|
||||
u8 word_cnts = 0;
|
||||
if (!(word_en & BIT(0))) word_cnts++; /* 0 : write enable */
|
||||
if (!(word_en & BIT(1))) word_cnts++;
|
||||
if (!(word_en & BIT(2))) word_cnts++;
|
||||
if (!(word_en & BIT(3))) word_cnts++;
|
||||
return word_cnts;
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Description: */
|
||||
/* Execute E-Fuse read byte operation. */
|
||||
/* Refered from SD1 Richard. */
|
||||
/* */
|
||||
/* Assumption: */
|
||||
/* 1. Boot from E-Fuse and successfully auto-load. */
|
||||
/* 2. PASSIVE_LEVEL (USB interface) */
|
||||
/* */
|
||||
/* Created by Roger, 2008.10.21. */
|
||||
/* */
|
||||
void
|
||||
ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf)
|
||||
{
|
||||
u32 value32;
|
||||
u8 readbyte;
|
||||
u16 retry;
|
||||
/* u32 start = rtw_get_current_time(); */
|
||||
|
||||
/* Write Address */
|
||||
rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
|
||||
readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
|
||||
rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
|
||||
|
||||
/* Write bit 32 0 */
|
||||
readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));
|
||||
|
||||
/* Check bit 32 read-ready */
|
||||
retry = 0;
|
||||
value32 = rtw_read32(Adapter, EFUSE_CTRL);
|
||||
/* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */
|
||||
while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000))
|
||||
{
|
||||
value32 = rtw_read32(Adapter, EFUSE_CTRL);
|
||||
retry++;
|
||||
}
|
||||
|
||||
/* 20100205 Joseph: Add delay suggested by SD1 Victor. */
|
||||
/* This fix the problem that Efuse read error in high temperature condition. */
|
||||
/* Designer says that there shall be some delay after ready bit is set, or the */
|
||||
/* result will always stay on last data we read. */
|
||||
udelay(50);
|
||||
value32 = rtw_read32(Adapter, EFUSE_CTRL);
|
||||
|
||||
*pbuf = (u8)(value32 & 0xff);
|
||||
/* DBG_8723A("ReadEFuseByte23a _offset:%08u, in %d ms\n", _offset , rtw_get_passing_time_ms23a(start)); */
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Description: */
|
||||
/* 1. Execute E-Fuse read byte operation according as map offset and */
|
||||
/* save to E-Fuse table. */
|
||||
/* 2. Refered from SD1 Richard. */
|
||||
/* */
|
||||
/* Assumption: */
|
||||
/* 1. Boot from E-Fuse and successfully auto-load. */
|
||||
/* 2. PASSIVE_LEVEL (USB interface) */
|
||||
/* */
|
||||
/* Created by Roger, 2008.10.21. */
|
||||
/* */
|
||||
/* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */
|
||||
/* 2. Add efuse utilization collect. */
|
||||
/* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */
|
||||
/* write addr must be after sec5. */
|
||||
/* */
|
||||
|
||||
void
|
||||
efuse_ReadEFuse(struct rtw_adapter *Adapter, u8 efuseType,
|
||||
u16 _offset, u16 _size_byte, u8 *pbuf);
|
||||
void
|
||||
efuse_ReadEFuse(struct rtw_adapter *Adapter, u8 efuseType,
|
||||
u16 _offset, u16 _size_byte, u8 *pbuf)
|
||||
{
|
||||
Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset,
|
||||
_size_byte, pbuf);
|
||||
}
|
||||
|
||||
void
|
||||
EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType,
|
||||
u8 type, void *pOut)
|
||||
{
|
||||
pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType,
|
||||
type, pOut);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: EFUSE_Read1Byte23a
|
||||
*
|
||||
* Overview: Copy from WMAC fot EFUSE read 1 byte.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 09/23/2008 MHC Copy from WMAC.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
u8
|
||||
EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
|
||||
{
|
||||
u8 data;
|
||||
u8 Bytetemp = {0x00};
|
||||
u8 temp = {0x00};
|
||||
u32 k = 0;
|
||||
u16 contentLen = 0;
|
||||
|
||||
EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
|
||||
TYPE_EFUSE_REAL_CONTENT_LEN,
|
||||
(void *)&contentLen);
|
||||
|
||||
if (Address < contentLen) /* E-fuse 512Byte */
|
||||
{
|
||||
/* Write E-fuse Register address bit0~7 */
|
||||
temp = Address & 0xFF;
|
||||
rtw_write8(Adapter, EFUSE_CTRL+1, temp);
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
|
||||
/* Write E-fuse Register address bit8~9 */
|
||||
temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
|
||||
rtw_write8(Adapter, EFUSE_CTRL+2, temp);
|
||||
|
||||
/* Write 0x30[31]= 0 */
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
temp = Bytetemp & 0x7F;
|
||||
rtw_write8(Adapter, EFUSE_CTRL+3, temp);
|
||||
|
||||
/* Wait Write-ready (0x30[31]= 1) */
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
while(!(Bytetemp & 0x80))
|
||||
{
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
k++;
|
||||
if (k == 1000)
|
||||
{
|
||||
k = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data = rtw_read8(Adapter, EFUSE_CTRL);
|
||||
return data;
|
||||
}
|
||||
else
|
||||
return 0xFF;
|
||||
}/* EFUSE_Read1Byte23a */
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: EFUSE_Write1Byte
|
||||
*
|
||||
* Overview: Copy from WMAC fot EFUSE write 1 byte.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 09/23/2008 MHC Copy from WMAC.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
EFUSE_Write1Byte(
|
||||
struct rtw_adapter * Adapter,
|
||||
u16 Address,
|
||||
u8 Value);
|
||||
void
|
||||
EFUSE_Write1Byte(
|
||||
struct rtw_adapter * Adapter,
|
||||
u16 Address,
|
||||
u8 Value)
|
||||
{
|
||||
u8 Bytetemp = {0x00};
|
||||
u8 temp = {0x00};
|
||||
u32 k = 0;
|
||||
u16 contentLen = 0;
|
||||
|
||||
/* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr =%x Data =%x\n", Address, Value)); */
|
||||
EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
|
||||
TYPE_EFUSE_REAL_CONTENT_LEN,
|
||||
(void *)&contentLen);
|
||||
|
||||
if (Address < contentLen) /* E-fuse 512Byte */
|
||||
{
|
||||
rtw_write8(Adapter, EFUSE_CTRL, Value);
|
||||
|
||||
/* Write E-fuse Register address bit0~7 */
|
||||
temp = Address & 0xFF;
|
||||
rtw_write8(Adapter, EFUSE_CTRL+1, temp);
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
|
||||
|
||||
/* Write E-fuse Register address bit8~9 */
|
||||
temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
|
||||
rtw_write8(Adapter, EFUSE_CTRL+2, temp);
|
||||
|
||||
/* Write 0x30[31]= 1 */
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
temp = Bytetemp | 0x80;
|
||||
rtw_write8(Adapter, EFUSE_CTRL+3, temp);
|
||||
|
||||
/* Wait Write-ready (0x30[31]= 0) */
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
while(Bytetemp & 0x80)
|
||||
{
|
||||
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
|
||||
k++;
|
||||
if (k == 100)
|
||||
{
|
||||
k = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}/* EFUSE_Write1Byte */
|
||||
|
||||
/* 11/16/2008 MH Read one byte from real Efuse. */
|
||||
u8
|
||||
efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data)
|
||||
{
|
||||
u8 tmpidx = 0;
|
||||
u8 bResult;
|
||||
|
||||
/* -----------------e-fuse reg ctrl --------------------------------- */
|
||||
/* address */
|
||||
rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
|
||||
rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03)) |
|
||||
(rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC));
|
||||
|
||||
rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */
|
||||
|
||||
while(!(0x80 &rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100))
|
||||
tmpidx++;
|
||||
if (tmpidx < 100) {
|
||||
*data = rtw_read8(pAdapter, EFUSE_CTRL);
|
||||
bResult = true;
|
||||
} else {
|
||||
*data = 0xff;
|
||||
bResult = false;
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/* 11/16/2008 MH Write one byte to reald Efuse. */
|
||||
u8
|
||||
efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data)
|
||||
{
|
||||
u8 tmpidx = 0;
|
||||
u8 bResult;
|
||||
|
||||
/* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr = %x Data =%x\n", addr, data)); */
|
||||
|
||||
/* return 0; */
|
||||
|
||||
/* -----------------e-fuse reg ctrl --------------------------------- */
|
||||
/* address */
|
||||
rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
|
||||
rtw_write8(pAdapter, EFUSE_CTRL+2,
|
||||
(rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC)|(u8)((addr>>8)&0x03));
|
||||
rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
|
||||
|
||||
rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
|
||||
|
||||
while((0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100)) {
|
||||
tmpidx++;
|
||||
}
|
||||
|
||||
if (tmpidx<100)
|
||||
{
|
||||
bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bResult = false;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
int
|
||||
Efuse_PgPacketRead23a(struct rtw_adapter *pAdapter, u8 offset, u8 *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = pAdapter->HalFunc.Efuse_PgPacketRead23a(pAdapter, offset, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
Efuse_PgPacketWrite23a(struct rtw_adapter *pAdapter, u8 offset,
|
||||
u8 word_en, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pAdapter->HalFunc.Efuse_PgPacketWrite23a(pAdapter, offset,
|
||||
word_en, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: efuse_WordEnableDataRead23a
|
||||
*
|
||||
* Overview: Read allowed word in current efuse section data.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/16/2008 MHC Create Version 0.
|
||||
* 11/21/2008 MHC Fix Write bug when we only enable late word.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
efuse_WordEnableDataRead23a(u8 word_en,
|
||||
u8 *sourdata,
|
||||
u8 *targetdata)
|
||||
{
|
||||
if (!(word_en&BIT(0)))
|
||||
{
|
||||
targetdata[0] = sourdata[0];
|
||||
targetdata[1] = sourdata[1];
|
||||
}
|
||||
if (!(word_en&BIT(1)))
|
||||
{
|
||||
targetdata[2] = sourdata[2];
|
||||
targetdata[3] = sourdata[3];
|
||||
}
|
||||
if (!(word_en&BIT(2)))
|
||||
{
|
||||
targetdata[4] = sourdata[4];
|
||||
targetdata[5] = sourdata[5];
|
||||
}
|
||||
if (!(word_en&BIT(3)))
|
||||
{
|
||||
targetdata[6] = sourdata[6];
|
||||
targetdata[7] = sourdata[7];
|
||||
}
|
||||
}
|
||||
|
||||
u8
|
||||
Efuse_WordEnableDataWrite23a(struct rtw_adapter *pAdapter, u16 efuse_addr,
|
||||
u8 word_en, u8 *data)
|
||||
{
|
||||
u8 ret = 0;
|
||||
|
||||
ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite23a(pAdapter, efuse_addr,
|
||||
word_en, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 efuse_read8(struct rtw_adapter *padapter, u16 address, u8 *value)
|
||||
{
|
||||
return efuse_OneByteRead23a(padapter, address, value);
|
||||
}
|
||||
|
||||
static u8 efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value)
|
||||
{
|
||||
return efuse_OneByteWrite23a(padapter, address, *value);
|
||||
}
|
||||
|
||||
/*
|
||||
* read/wirte raw efuse data
|
||||
*/
|
||||
u8 rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr,
|
||||
u16 cnts, u8 *data)
|
||||
{
|
||||
int i = 0;
|
||||
u16 real_content_len = 0, max_available_size = 0;
|
||||
u8 res = _FAIL ;
|
||||
u8 (*rw8)(struct rtw_adapter *, u16, u8*);
|
||||
|
||||
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
|
||||
TYPE_EFUSE_REAL_CONTENT_LEN,
|
||||
(void *)&real_content_len);
|
||||
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
|
||||
TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
|
||||
(void *)&max_available_size);
|
||||
|
||||
if (start_addr > real_content_len)
|
||||
return _FAIL;
|
||||
|
||||
if (true == bWrite) {
|
||||
if ((start_addr + cnts) > max_available_size)
|
||||
return _FAIL;
|
||||
rw8 = &efuse_write8;
|
||||
} else
|
||||
rw8 = &efuse_read8;
|
||||
|
||||
Efuse_PowerSwitch23a(padapter, bWrite, true);
|
||||
|
||||
/* e-fuse one byte read / write */
|
||||
for (i = 0; i < cnts; i++) {
|
||||
if (start_addr >= real_content_len) {
|
||||
res = _FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
res = rw8(padapter, start_addr++, data++);
|
||||
if (_FAIL == res) break;
|
||||
}
|
||||
|
||||
Efuse_PowerSwitch23a(padapter, bWrite, false);
|
||||
|
||||
return res;
|
||||
}
|
||||
/* */
|
||||
u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
u16 max_size;
|
||||
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
|
||||
TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
|
||||
(void *)&max_size);
|
||||
return max_size;
|
||||
}
|
||||
/* */
|
||||
u8 efuse_GetCurrentSize23a(struct rtw_adapter *padapter, u16 *size)
|
||||
{
|
||||
Efuse_PowerSwitch23a(padapter, false, true);
|
||||
*size = Efuse_GetCurrentSize23a(padapter, EFUSE_WIFI);
|
||||
Efuse_PowerSwitch23a(padapter, false, false);
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
/* */
|
||||
u8 rtw_efuse_map_read23a(struct rtw_adapter *padapter, u16 addr, u16 cnts, u8 *data)
|
||||
{
|
||||
u16 mapLen = 0;
|
||||
|
||||
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
|
||||
TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
|
||||
|
||||
if ((addr + cnts) > mapLen)
|
||||
return _FAIL;
|
||||
|
||||
Efuse_PowerSwitch23a(padapter, false, true);
|
||||
|
||||
efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data);
|
||||
|
||||
Efuse_PowerSwitch23a(padapter, false, false);
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
u8 rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter, u16 addr, u16 cnts, u8 *data)
|
||||
{
|
||||
u16 mapLen = 0;
|
||||
|
||||
EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
|
||||
TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
|
||||
|
||||
if ((addr + cnts) > mapLen)
|
||||
return _FAIL;
|
||||
|
||||
Efuse_PowerSwitch23a(padapter, false, true);
|
||||
|
||||
efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data);
|
||||
|
||||
Efuse_PowerSwitch23a(padapter, false, false);
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: Efuse_ReadAllMap
|
||||
*
|
||||
* Overview: Read All Efuse content
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/11/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse);
|
||||
void
|
||||
Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse)
|
||||
{
|
||||
u16 mapLen = 0;
|
||||
|
||||
Efuse_PowerSwitch23a(pAdapter, false, true);
|
||||
|
||||
EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN,
|
||||
(void *)&mapLen);
|
||||
|
||||
efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse);
|
||||
|
||||
Efuse_PowerSwitch23a(pAdapter, false, false);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: efuse_ShadowRead1Byte
|
||||
* efuse_ShadowRead2Byte
|
||||
* efuse_ShadowRead4Byte
|
||||
*
|
||||
* Overview: Read from efuse init map by one/two/four bytes !!!!!
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/12/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
efuse_ShadowRead1Byte(
|
||||
struct rtw_adapter * pAdapter,
|
||||
u16 Offset,
|
||||
u8 *Value)
|
||||
{
|
||||
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
|
||||
|
||||
*Value = pEEPROM->efuse_eeprom_data[Offset];
|
||||
} /* EFUSE_ShadowRead23a1Byte */
|
||||
|
||||
/* Read Two Bytes */
|
||||
static void
|
||||
efuse_ShadowRead2Byte(
|
||||
struct rtw_adapter * pAdapter,
|
||||
u16 Offset,
|
||||
u16 *Value)
|
||||
{
|
||||
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
|
||||
|
||||
*Value = pEEPROM->efuse_eeprom_data[Offset];
|
||||
*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
|
||||
} /* EFUSE_ShadowRead23a2Byte */
|
||||
|
||||
/* Read Four Bytes */
|
||||
static void
|
||||
efuse_ShadowRead4Byte(
|
||||
struct rtw_adapter * pAdapter,
|
||||
u16 Offset,
|
||||
u32 *Value)
|
||||
{
|
||||
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
|
||||
|
||||
*Value = pEEPROM->efuse_eeprom_data[Offset];
|
||||
*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
|
||||
*Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
|
||||
*Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
|
||||
} /* efuse_ShadowRead4Byte */
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: EFUSE_ShadowMapUpdate23a
|
||||
*
|
||||
* Overview: Transfer current EFUSE content to shadow init and modify map.
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/13/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType)
|
||||
{
|
||||
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
|
||||
u16 mapLen = 0;
|
||||
|
||||
EFUSE_GetEfuseDefinition23a(pAdapter, efuseType,
|
||||
TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
|
||||
|
||||
if (pEEPROM->bautoload_fail_flag == true)
|
||||
memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
|
||||
else
|
||||
Efuse_ReadAllMap(pAdapter, efuseType,
|
||||
pEEPROM->efuse_eeprom_data);
|
||||
|
||||
}/* EFUSE_ShadowMapUpdate23a */
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: EFUSE_ShadowRead23a
|
||||
*
|
||||
* Overview: Read from efuse init map !!!!!
|
||||
*
|
||||
* Input: NONE
|
||||
*
|
||||
* Output: NONE
|
||||
*
|
||||
* Return: NONE
|
||||
*
|
||||
* Revised History:
|
||||
* When Who Remark
|
||||
* 11/12/2008 MHC Create Version 0.
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
void
|
||||
EFUSE_ShadowRead23a(
|
||||
struct rtw_adapter * pAdapter,
|
||||
u8 Type,
|
||||
u16 Offset,
|
||||
u32 *Value )
|
||||
{
|
||||
if (Type == 1)
|
||||
efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
|
||||
else if (Type == 2)
|
||||
efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
|
||||
else if (Type == 4)
|
||||
efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
|
||||
} /* EFUSE_ShadowRead23a */
|
1861
drivers/staging/rtl8723au/core/rtw_ieee80211.c
Normal file
1861
drivers/staging/rtl8723au/core/rtw_ieee80211.c
Normal file
File diff suppressed because it is too large
Load Diff
266
drivers/staging/rtl8723au/core/rtw_io.c
Normal file
266
drivers/staging/rtl8723au/core/rtw_io.c
Normal file
@ -0,0 +1,266 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
|
||||
The purpose of rtw_io.c
|
||||
|
||||
a. provides the API
|
||||
|
||||
b. provides the protocol engine
|
||||
|
||||
c. provides the software interface between caller and the hardware interface
|
||||
|
||||
Compiler Flag Option:
|
||||
|
||||
1. For USB:
|
||||
a. USE_ASYNC_IRP: Both sync/async operations are provided.
|
||||
|
||||
Only sync read/rtw_write_mem operations are provided.
|
||||
|
||||
jackson@realtek.com.tw
|
||||
|
||||
*/
|
||||
|
||||
#define _RTW_IO_C_
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
#include <rtw_io.h>
|
||||
#include <osdep_intf.h>
|
||||
|
||||
#include <usb_ops.h>
|
||||
|
||||
u8 _rtw_read823a(struct rtw_adapter *adapter, u32 addr)
|
||||
{
|
||||
u8 r_val;
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
r_val = pintfhdl->io_ops._read8(pintfhdl, addr);
|
||||
|
||||
return r_val;
|
||||
}
|
||||
|
||||
u16 _rtw_read1623a(struct rtw_adapter *adapter, u32 addr)
|
||||
{
|
||||
u16 r_val;
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
r_val = pintfhdl->io_ops._read16(pintfhdl, addr);
|
||||
|
||||
return le16_to_cpu(r_val);
|
||||
}
|
||||
|
||||
u32 _rtw_read3223a(struct rtw_adapter *adapter, u32 addr)
|
||||
{
|
||||
u32 r_val;
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
r_val = pintfhdl->io_ops._read32(pintfhdl, addr);
|
||||
|
||||
return le32_to_cpu(r_val);
|
||||
}
|
||||
|
||||
int _rtw_write823a(struct rtw_adapter *adapter, u32 addr, u8 val)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
ret = pintfhdl->io_ops._write8(pintfhdl, addr, val);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
|
||||
int _rtw_write1623a(struct rtw_adapter *adapter, u32 addr, u16 val)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
val = cpu_to_le16(val);
|
||||
ret = pintfhdl->io_ops._write16(pintfhdl, addr, val);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
int _rtw_write3223a(struct rtw_adapter *adapter, u32 addr, u32 val)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
val = cpu_to_le32(val);
|
||||
ret = pintfhdl->io_ops._write32(pintfhdl, addr, val);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
|
||||
int _rtw_writeN23a(struct rtw_adapter *adapter, u32 addr , u32 length , u8 *pdata)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = (struct intf_hdl*)&pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
ret = pintfhdl->io_ops._writeN(pintfhdl, addr, length, pdata);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
int _rtw_write823a_async23a(struct rtw_adapter *adapter, u32 addr, u8 val)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
ret = pintfhdl->io_ops._write8_async(pintfhdl, addr, val);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
int _rtw_write1623a_async(struct rtw_adapter *adapter, u32 addr, u16 val)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
val = cpu_to_le16(val);
|
||||
ret = pintfhdl->io_ops._write16_async(pintfhdl, addr, val);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
int _rtw_write3223a_async23a(struct rtw_adapter *adapter, u32 addr, u32 val)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
int ret;
|
||||
|
||||
val = cpu_to_le32(val);
|
||||
ret = pintfhdl->io_ops._write32_async(pintfhdl, addr, val);
|
||||
|
||||
return RTW_STATUS_CODE23a(ret);
|
||||
}
|
||||
|
||||
void _rtw_read_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
if ((adapter->bDriverStopped == true) ||
|
||||
(adapter->bSurpriseRemoved == true)) {
|
||||
RT_TRACE(_module_rtl871x_io_c_, _drv_info_,
|
||||
("rtw_read_mem:bDriverStopped(%d) OR "
|
||||
"bSurpriseRemoved(%d)", adapter->bDriverStopped,
|
||||
adapter->bSurpriseRemoved));
|
||||
return;
|
||||
}
|
||||
|
||||
pintfhdl->io_ops._read_mem(pintfhdl, addr, cnt, pmem);
|
||||
}
|
||||
|
||||
void _rtw_write_mem23a(struct rtw_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
pintfhdl->io_ops._write_mem(pintfhdl, addr, cnt, pmem);
|
||||
}
|
||||
|
||||
void _rtw_read_port23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
|
||||
struct recv_buf *rbuf)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
if ((adapter->bDriverStopped == true) ||
|
||||
(adapter->bSurpriseRemoved == true)) {
|
||||
RT_TRACE(_module_rtl871x_io_c_, _drv_info_,
|
||||
("rtw_read_port:bDriverStopped(%d) OR "
|
||||
"bSurpriseRemoved(%d)", adapter->bDriverStopped,
|
||||
adapter->bSurpriseRemoved));
|
||||
return;
|
||||
}
|
||||
|
||||
pintfhdl->io_ops._read_port(pintfhdl, addr, cnt, rbuf);
|
||||
}
|
||||
|
||||
void _rtw_read_port23a_cancel(struct rtw_adapter *adapter)
|
||||
{
|
||||
void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
|
||||
|
||||
if (_read_port_cancel)
|
||||
_read_port_cancel(pintfhdl);
|
||||
}
|
||||
|
||||
u32 _rtw_write_port23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
|
||||
struct xmit_buf *xbuf)
|
||||
{
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
u32 ret = _SUCCESS;
|
||||
|
||||
ret = pintfhdl->io_ops._write_port(pintfhdl, addr, cnt, xbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 _rtw_write_port23a_and_wait23a(struct rtw_adapter *adapter, u32 addr, u32 cnt,
|
||||
struct xmit_buf *pxmitbuf, int timeout_ms)
|
||||
{
|
||||
int ret = _SUCCESS;
|
||||
struct submit_ctx sctx;
|
||||
|
||||
rtw_sctx_init23a(&sctx, timeout_ms);
|
||||
pxmitbuf->sctx = &sctx;
|
||||
|
||||
ret = _rtw_write_port23a(adapter, addr, cnt, pxmitbuf);
|
||||
|
||||
if (ret == _SUCCESS)
|
||||
ret = rtw_sctx_wait23a(&sctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _rtw_write_port23a_cancel(struct rtw_adapter *adapter)
|
||||
{
|
||||
void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
|
||||
struct io_priv *pio_priv = &adapter->iopriv;
|
||||
struct intf_hdl *pintfhdl = &pio_priv->intf;
|
||||
|
||||
_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
|
||||
|
||||
if (_write_port_cancel)
|
||||
_write_port_cancel(pintfhdl);
|
||||
}
|
||||
|
||||
int rtw_init_io_priv23a(struct rtw_adapter *padapter,
|
||||
void (*set_intf_ops)(struct _io_ops *pops))
|
||||
{
|
||||
struct io_priv *piopriv = &padapter->iopriv;
|
||||
struct intf_hdl *pintf = &piopriv->intf;
|
||||
|
||||
if (set_intf_ops == NULL)
|
||||
return _FAIL;
|
||||
|
||||
piopriv->padapter = padapter;
|
||||
pintf->padapter = padapter;
|
||||
pintf->pintf_dev = adapter_to_dvobj(padapter);
|
||||
|
||||
set_intf_ops(&pintf->io_ops);
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
601
drivers/staging/rtl8723au/core/rtw_ioctl_set.c
Normal file
601
drivers/staging/rtl8723au/core/rtw_ioctl_set.c
Normal file
@ -0,0 +1,601 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RTW_IOCTL_SET_C_
|
||||
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
#include <rtw_ioctl_set.h>
|
||||
#include <hal_intf.h>
|
||||
|
||||
#include <usb_osintf.h>
|
||||
#include <usb_ops.h>
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
u8 rtw_do_join23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct list_head *plist, *phead;
|
||||
u8* pibss = NULL;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct rtw_queue *queue = &pmlmepriv->scanned_queue;
|
||||
u8 ret = _SUCCESS;
|
||||
|
||||
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
|
||||
phead = get_list_head(queue);
|
||||
plist = phead->next;
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("\n rtw_do_join23a: phead = %p; plist = %p\n\n\n",
|
||||
phead, plist));
|
||||
|
||||
pmlmepriv->cur_network.join_res = -2;
|
||||
|
||||
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
|
||||
|
||||
pmlmepriv->to_join = true;
|
||||
|
||||
if (_rtw_queue_empty23a(queue) == true) {
|
||||
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
|
||||
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
|
||||
|
||||
/* when set_ssid/set_bssid for rtw_do_join23a(), but
|
||||
scanning queue is empty */
|
||||
/* we try to issue sitesurvey firstly */
|
||||
|
||||
if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false ||
|
||||
rtw_to_roaming(padapter) > 0) {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("rtw_do_join23a(): site survey if scanned_queue "
|
||||
"is empty\n."));
|
||||
/* submit site_survey23a_cmd */
|
||||
ret = rtw_sitesurvey_cmd23a(padapter,
|
||||
&pmlmepriv->assoc_ssid, 1,
|
||||
NULL, 0);
|
||||
if (ret != _SUCCESS) {
|
||||
pmlmepriv->to_join = false;
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("rtw_do_join23a(): site survey return "
|
||||
"error\n."));
|
||||
}
|
||||
} else {
|
||||
pmlmepriv->to_join = false;
|
||||
ret = _FAIL;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
} else {
|
||||
int select_ret;
|
||||
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
|
||||
select_ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
|
||||
if (select_ret == _SUCCESS) {
|
||||
pmlmepriv->to_join = false;
|
||||
mod_timer(&pmlmepriv->assoc_timer,
|
||||
jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
|
||||
} else {
|
||||
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
|
||||
struct wlan_bssid_ex *pdev_network;
|
||||
/* submit createbss_cmd to change to a
|
||||
ADHOC_MASTER */
|
||||
|
||||
/* pmlmepriv->lock has been acquired by
|
||||
caller... */
|
||||
pdev_network =
|
||||
&padapter->registrypriv.dev_network;
|
||||
|
||||
pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
|
||||
|
||||
pibss = padapter->registrypriv.dev_network.MacAddress;
|
||||
|
||||
memcpy(&pdev_network->Ssid,
|
||||
&pmlmepriv->assoc_ssid,
|
||||
sizeof(struct cfg80211_ssid));
|
||||
|
||||
rtw_update_registrypriv_dev_network23a(padapter);
|
||||
|
||||
rtw_generate_random_ibss23a(pibss);
|
||||
|
||||
if (rtw_createbss_cmd23a(padapter) != _SUCCESS) {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_,
|
||||
_drv_err_,
|
||||
("***Error =>do_goin: rtw_creat"
|
||||
"ebss_cmd status FAIL***\n"));
|
||||
ret = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pmlmepriv->to_join = false;
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_,
|
||||
_drv_info_,
|
||||
("***Error => rtw_select_and_join_from"
|
||||
"_scanned_queue FAIL under STA_Mode"
|
||||
"***\n "));
|
||||
} else {
|
||||
/* can't associate ; reset under-linking */
|
||||
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
|
||||
|
||||
/* when set_ssid/set_bssid for rtw_do_join23a(),
|
||||
but there are no desired bss in scanning
|
||||
queue */
|
||||
/* we try to issue sitesurvey firstly */
|
||||
if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==
|
||||
false || rtw_to_roaming(padapter) > 0) {
|
||||
/* DBG_8723A("rtw_do_join23a() when no "
|
||||
"desired bss in scanning queue\n");
|
||||
*/
|
||||
ret = rtw_sitesurvey_cmd23a(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
|
||||
if (ret != _SUCCESS) {
|
||||
pmlmepriv->to_join = false;
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
|
||||
}
|
||||
} else {
|
||||
ret = _FAIL;
|
||||
pmlmepriv->to_join = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtw_set_802_11_ssid23a(struct rtw_adapter* padapter, struct cfg80211_ssid *ssid)
|
||||
{
|
||||
u8 status = _SUCCESS;
|
||||
u32 cur_time = 0;
|
||||
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct wlan_network *pnetwork = &pmlmepriv->cur_network;
|
||||
|
||||
|
||||
|
||||
DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
|
||||
ssid->ssid, get_fwstate(pmlmepriv));
|
||||
|
||||
if (padapter->hw_init_completed == false) {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("set_ssid: hw_init_completed == false =>exit!!!\n"));
|
||||
status = _FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
spin_lock_bh(&pmlmepriv->lock);
|
||||
|
||||
DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
|
||||
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
|
||||
goto handle_tkip_countermeasure;
|
||||
} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
|
||||
goto release_mlme_lock;
|
||||
}
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true)
|
||||
{
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
|
||||
|
||||
if ((pmlmepriv->assoc_ssid.ssid_len == ssid->ssid_len) &&
|
||||
!memcmp(&pmlmepriv->assoc_ssid.ssid, ssid->ssid,
|
||||
ssid->ssid_len)) {
|
||||
if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false))
|
||||
{
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("Set SSID is the same ssid, fw_state = 0x%08x\n",
|
||||
get_fwstate(pmlmepriv)));
|
||||
|
||||
if (rtw_is_same_ibss23a(padapter, pnetwork) == false)
|
||||
{
|
||||
/* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
|
||||
rtw_disassoc_cmd23a(padapter, 0, true);
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
|
||||
rtw_indicate_disconnect23a(padapter);
|
||||
|
||||
rtw_free_assoc_resources23a(padapter, 1);
|
||||
|
||||
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
|
||||
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
|
||||
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
|
||||
}
|
||||
} else {
|
||||
goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
|
||||
}
|
||||
} else {
|
||||
rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_JOINBSS, 1);
|
||||
}
|
||||
} else {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("Set SSID not the same ssid\n"));
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("set_ssid =[%s] len = 0x%x\n", ssid->ssid,
|
||||
(unsigned int)ssid->ssid_len));
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("assoc_ssid =[%s] len = 0x%x\n",
|
||||
pmlmepriv->assoc_ssid.ssid,
|
||||
(unsigned int)pmlmepriv->assoc_ssid.ssid_len));
|
||||
|
||||
rtw_disassoc_cmd23a(padapter, 0, true);
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
|
||||
rtw_indicate_disconnect23a(padapter);
|
||||
|
||||
rtw_free_assoc_resources23a(padapter, 1);
|
||||
|
||||
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
|
||||
_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
|
||||
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle_tkip_countermeasure:
|
||||
|
||||
if (padapter->securitypriv.btkip_countermeasure == true) {
|
||||
cur_time = jiffies;
|
||||
|
||||
if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ)
|
||||
{
|
||||
padapter->securitypriv.btkip_countermeasure = false;
|
||||
padapter->securitypriv.btkip_countermeasure_time = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = _FAIL;
|
||||
goto release_mlme_lock;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct cfg80211_ssid));
|
||||
pmlmepriv->assoc_by_bssid = false;
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
|
||||
pmlmepriv->to_join = true;
|
||||
}
|
||||
else {
|
||||
status = rtw_do_join23a(padapter);
|
||||
}
|
||||
|
||||
release_mlme_lock:
|
||||
spin_unlock_bh(&pmlmepriv->lock);
|
||||
|
||||
exit:
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("-rtw_set_802_11_ssid23a: status =%d\n", status));
|
||||
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
u8 rtw_set_802_11_infrastructure_mode23a(struct rtw_adapter* padapter,
|
||||
enum ndis_802_11_net_infra networktype)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct wlan_network *cur_network = &pmlmepriv->cur_network;
|
||||
enum ndis_802_11_net_infra* pold_state = &cur_network->network.InfrastructureMode;
|
||||
|
||||
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
|
||||
("+rtw_set_802_11_infrastructure_mode23a: old =%d new =%d fw_state = 0x%08x\n",
|
||||
*pold_state, networktype, get_fwstate(pmlmepriv)));
|
||||
|
||||
if (*pold_state != networktype)
|
||||
{
|
||||
spin_lock_bh(&pmlmepriv->lock);
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
|
||||
/* DBG_8723A("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
|
||||
|
||||
if (*pold_state == Ndis802_11APMode)
|
||||
{
|
||||
/* change to other mode from Ndis802_11APMode */
|
||||
cur_network->join_res = -1;
|
||||
|
||||
#ifdef CONFIG_8723AU_AP_MODE
|
||||
stop_ap_mode23a(padapter);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||(*pold_state == Ndis802_11IBSS))
|
||||
rtw_disassoc_cmd23a(padapter, 0, true);
|
||||
|
||||
if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
|
||||
rtw_free_assoc_resources23a(padapter, 1);
|
||||
|
||||
if ((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS))
|
||||
{
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
|
||||
{
|
||||
rtw_indicate_disconnect23a(padapter); /* will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not */
|
||||
}
|
||||
}
|
||||
|
||||
*pold_state = networktype;
|
||||
|
||||
_clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
|
||||
|
||||
switch (networktype)
|
||||
{
|
||||
case Ndis802_11IBSS:
|
||||
set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
|
||||
break;
|
||||
|
||||
case Ndis802_11Infrastructure:
|
||||
set_fwstate(pmlmepriv, WIFI_STATION_STATE);
|
||||
break;
|
||||
|
||||
case Ndis802_11APMode:
|
||||
set_fwstate(pmlmepriv, WIFI_AP_STATE);
|
||||
#ifdef CONFIG_8723AU_AP_MODE
|
||||
start_ap_mode23a(padapter);
|
||||
/* rtw_indicate_connect23a(padapter); */
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case Ndis802_11AutoUnknown:
|
||||
case Ndis802_11InfrastructureMax:
|
||||
break;
|
||||
}
|
||||
|
||||
/* SecClearAllKeys(adapter); */
|
||||
|
||||
/* RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", */
|
||||
/* get_fwstate(pmlmepriv))); */
|
||||
|
||||
spin_unlock_bh(&pmlmepriv->lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u8 rtw_set_802_11_bssid23a_list_scan(struct rtw_adapter *padapter,
|
||||
struct cfg80211_ssid *pssid, int ssid_max_num)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
u8 res = true;
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("+rtw_set_802_11_bssid23a_list_scan(), fw_state =%x\n",
|
||||
get_fwstate(pmlmepriv)));
|
||||
|
||||
if (!padapter) {
|
||||
res = false;
|
||||
goto exit;
|
||||
}
|
||||
if (padapter->hw_init_completed == false) {
|
||||
res = false;
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("\n === rtw_set_802_11_bssid23a_list_scan:"
|
||||
"hw_init_completed == false ===\n"));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ||
|
||||
(pmlmepriv->LinkDetectInfo.bBusyTraffic == true)) {
|
||||
/* Scan or linking is in progress, do nothing. */
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("rtw_set_802_11_bssid23a_list_scan fail since fw_state "
|
||||
"= %x\n", get_fwstate(pmlmepriv)));
|
||||
res = true;
|
||||
|
||||
if (check_fwstate(pmlmepriv,
|
||||
(_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n"));
|
||||
} else {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("\n###pmlmepriv->sitesurveyctrl.traffic_"
|
||||
"busy == true\n"));
|
||||
}
|
||||
} else {
|
||||
if (rtw_is_scan_deny(padapter)) {
|
||||
DBG_8723A(FUNC_ADPT_FMT": scan deny\n",
|
||||
FUNC_ADPT_ARG(padapter));
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
spin_lock_bh(&pmlmepriv->lock);
|
||||
|
||||
res = rtw_sitesurvey_cmd23a(padapter, pssid, ssid_max_num,
|
||||
NULL, 0);
|
||||
|
||||
spin_unlock_bh(&pmlmepriv->lock);
|
||||
}
|
||||
exit:
|
||||
return res;
|
||||
}
|
||||
|
||||
u8 rtw_set_802_11_authentication_mode23a(struct rtw_adapter* padapter,
|
||||
enum ndis_802_11_auth_mode authmode)
|
||||
{
|
||||
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||
int res;
|
||||
u8 ret;
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("set_802_11_auth.mode(): mode =%x\n", authmode));
|
||||
|
||||
psecuritypriv->ndisauthtype = authmode;
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("rtw_set_802_11_authentication_mode23a:"
|
||||
"psecuritypriv->ndisauthtype =%d",
|
||||
psecuritypriv->ndisauthtype));
|
||||
|
||||
if (psecuritypriv->ndisauthtype > 3)
|
||||
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
|
||||
|
||||
res = rtw_set_auth23a(padapter, psecuritypriv);
|
||||
|
||||
if (res == _SUCCESS)
|
||||
ret = true;
|
||||
else
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtw_set_802_11_add_wep23a(struct rtw_adapter* padapter,
|
||||
struct ndis_802_11_wep *wep)
|
||||
{
|
||||
u8 bdefaultkey;
|
||||
u8 btransmitkey;
|
||||
int keyid, res;
|
||||
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||
u8 ret = _SUCCESS;
|
||||
|
||||
bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? false : true;
|
||||
btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? true : false;
|
||||
keyid = wep->KeyIndex & 0x3fffffff;
|
||||
|
||||
if (keyid >= 4) {
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
|
||||
("MgntActrtw_set_802_11_add_wep23a:keyid>4 =>fail\n"));
|
||||
ret = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (wep->KeyLength)
|
||||
{
|
||||
case 5:
|
||||
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("MgntActrtw_set_802_11_add_wep23a:wep->KeyLength = 5\n"));
|
||||
break;
|
||||
case 13:
|
||||
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("MgntActrtw_set_802_11_add_wep23a:wep->KeyLength = 13\n"));
|
||||
break;
|
||||
default:
|
||||
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("MgntActrtw_set_802_11_add_wep23a:wep->KeyLength!= 5 "
|
||||
"or 13\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("rtw_set_802_11_add_wep23a:befor memcpy, wep->KeyLength = 0x%x "
|
||||
"wep->KeyIndex = 0x%x keyid =%x\n",
|
||||
wep->KeyLength, wep->KeyIndex, keyid));
|
||||
|
||||
memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0],
|
||||
&wep->KeyMaterial, wep->KeyLength);
|
||||
|
||||
psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
|
||||
|
||||
psecuritypriv->dot11PrivacyKeyIndex = keyid;
|
||||
|
||||
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
|
||||
("rtw_set_802_11_add_wep23a:security key material : %x %x %x %x "
|
||||
"%x %x %x %x %x %x %x %x %x\n",
|
||||
psecuritypriv->dot11DefKey[keyid].skey[0],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[1],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[2],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[3],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[4],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[5],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[6],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[7],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[8],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[9],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[10],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[11],
|
||||
psecuritypriv->dot11DefKey[keyid].skey[12]));
|
||||
|
||||
res = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
|
||||
|
||||
if (res == _FAIL)
|
||||
ret = false;
|
||||
exit:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* rtw_get_cur_max_rate23a -
|
||||
* @adapter: pointer to _adapter structure
|
||||
*
|
||||
* Return 0 or 100Kbps
|
||||
*/
|
||||
u16 rtw_get_cur_max_rate23a(struct rtw_adapter *adapter)
|
||||
{
|
||||
int i = 0;
|
||||
u8 *p;
|
||||
u16 rate = 0, max_rate = 0;
|
||||
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
|
||||
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
|
||||
struct registry_priv *pregistrypriv = &adapter->registrypriv;
|
||||
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
|
||||
struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
|
||||
struct ieee80211_ht_cap *pht_capie;
|
||||
u8 rf_type = 0;
|
||||
u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
|
||||
u16 mcs_rate = 0;
|
||||
u32 ht_ielen = 0;
|
||||
|
||||
if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
|
||||
!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
|
||||
return 0;
|
||||
|
||||
if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
|
||||
p = rtw_get_ie23a(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
|
||||
&ht_ielen, pcur_bss->IELength - 12);
|
||||
if (p && ht_ielen > 0) {
|
||||
pht_capie = (struct ieee80211_ht_cap *)(p + 2);
|
||||
|
||||
memcpy(&mcs_rate, &pht_capie->mcs, 2);
|
||||
|
||||
/* bw_40MHz = (pht_capie->cap_info&
|
||||
IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0; */
|
||||
/* cur_bwmod is updated by beacon, pmlmeinfo is
|
||||
updated by association response */
|
||||
bw_40MHz = (pmlmeext->cur_bwmode &&
|
||||
(HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH &
|
||||
pmlmeinfo->HT_info.infos[0])) ? 1:0;
|
||||
|
||||
/* short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP
|
||||
_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; */
|
||||
short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0;
|
||||
short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0;
|
||||
|
||||
rtw23a_hal_get_hwreg(adapter, HW_VAR_RF_TYPE,
|
||||
(u8 *)(&rf_type));
|
||||
max_rate = rtw_mcs_rate23a(rf_type, bw_40MHz &
|
||||
pregistrypriv->cbw40_enable,
|
||||
short_GI_20, short_GI_40,
|
||||
pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
|
||||
);
|
||||
}
|
||||
} else {
|
||||
while ((pcur_bss->SupportedRates[i] != 0) &&
|
||||
(pcur_bss->SupportedRates[i] != 0xFF)) {
|
||||
rate = pcur_bss->SupportedRates[i] & 0x7F;
|
||||
if (rate>max_rate)
|
||||
max_rate = rate;
|
||||
i++;
|
||||
}
|
||||
|
||||
max_rate = max_rate * 10 / 2;
|
||||
}
|
||||
|
||||
return max_rate;
|
||||
}
|
1899
drivers/staging/rtl8723au/core/rtw_led.c
Normal file
1899
drivers/staging/rtl8723au/core/rtw_led.c
Normal file
File diff suppressed because it is too large
Load Diff
2499
drivers/staging/rtl8723au/core/rtw_mlme.c
Normal file
2499
drivers/staging/rtl8723au/core/rtw_mlme.c
Normal file
File diff suppressed because it is too large
Load Diff
9988
drivers/staging/rtl8723au/core/rtw_mlme_ext.c
Normal file
9988
drivers/staging/rtl8723au/core/rtw_mlme_ext.c
Normal file
File diff suppressed because it is too large
Load Diff
3963
drivers/staging/rtl8723au/core/rtw_p2p.c
Normal file
3963
drivers/staging/rtl8723au/core/rtw_p2p.c
Normal file
File diff suppressed because it is too large
Load Diff
686
drivers/staging/rtl8723au/core/rtw_pwrctrl.c
Normal file
686
drivers/staging/rtl8723au/core/rtw_pwrctrl.c
Normal file
@ -0,0 +1,686 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RTW_PWRCTRL_C_
|
||||
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
#include <osdep_intf.h>
|
||||
|
||||
#ifdef CONFIG_8723AU_BT_COEXIST
|
||||
#include <rtl8723a_hal.h>
|
||||
#endif
|
||||
|
||||
void ips_enter23a(struct rtw_adapter * padapter)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
down(&pwrpriv->lock);
|
||||
|
||||
pwrpriv->bips_processing = true;
|
||||
|
||||
/* syn ips_mode with request */
|
||||
pwrpriv->ips_mode = pwrpriv->ips_mode_req;
|
||||
|
||||
pwrpriv->ips_enter23a_cnts++;
|
||||
DBG_8723A("==>ips_enter23a cnts:%d\n", pwrpriv->ips_enter23a_cnts);
|
||||
#ifdef CONFIG_8723AU_BT_COEXIST
|
||||
BTDM_TurnOffBtCoexistBeforeEnterIPS(padapter);
|
||||
#endif
|
||||
if (rf_off == pwrpriv->change_rfpwrstate)
|
||||
{
|
||||
pwrpriv->bpower_saving = true;
|
||||
DBG_8723A_LEVEL(_drv_always_, "nolinked power save enter\n");
|
||||
|
||||
if (pwrpriv->ips_mode == IPS_LEVEL_2)
|
||||
pwrpriv->bkeepfwalive = true;
|
||||
|
||||
rtw_ips_pwr_down23a(padapter);
|
||||
pwrpriv->rf_pwrstate = rf_off;
|
||||
}
|
||||
pwrpriv->bips_processing = false;
|
||||
|
||||
up(&pwrpriv->lock);
|
||||
}
|
||||
|
||||
int ips_leave23a(struct rtw_adapter * padapter)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
int result = _SUCCESS;
|
||||
int keyid;
|
||||
|
||||
down(&pwrpriv->lock);
|
||||
|
||||
if ((pwrpriv->rf_pwrstate == rf_off) &&!pwrpriv->bips_processing)
|
||||
{
|
||||
pwrpriv->bips_processing = true;
|
||||
pwrpriv->change_rfpwrstate = rf_on;
|
||||
pwrpriv->ips_leave23a_cnts++;
|
||||
DBG_8723A("==>ips_leave23a cnts:%d\n", pwrpriv->ips_leave23a_cnts);
|
||||
|
||||
if ((result = rtw_ips_pwr_up23a(padapter)) == _SUCCESS) {
|
||||
pwrpriv->rf_pwrstate = rf_on;
|
||||
}
|
||||
DBG_8723A_LEVEL(_drv_always_, "nolinked power save leave\n");
|
||||
|
||||
if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) ||(_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm))
|
||||
{
|
||||
DBG_8723A("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing);
|
||||
set_channel_bwmode23a(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
|
||||
for (keyid = 0;keyid<4;keyid++) {
|
||||
if (pmlmepriv->key_mask & CHKBIT(keyid)) {
|
||||
if (keyid == psecuritypriv->dot11PrivacyKeyIndex)
|
||||
result = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
|
||||
else
|
||||
result = rtw_set_key23a(padapter, psecuritypriv, keyid, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBG_8723A("==> ips_leave23a.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
|
||||
pwrpriv->bips_processing = false;
|
||||
|
||||
pwrpriv->bkeepfwalive = false;
|
||||
pwrpriv->bpower_saving = false;
|
||||
}
|
||||
|
||||
up(&pwrpriv->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static bool rtw_pwr_unassociated_idle(struct rtw_adapter *adapter)
|
||||
{
|
||||
struct rtw_adapter *buddy = adapter->pbuddy_adapter;
|
||||
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
|
||||
struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
|
||||
#ifdef CONFIG_8723AU_P2P
|
||||
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
|
||||
#endif
|
||||
|
||||
bool ret = false;
|
||||
|
||||
if (adapter->pwrctrlpriv.ips_deny_time >= rtw_get_current_time())
|
||||
goto exit;
|
||||
|
||||
if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
|
||||
|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
|
||||
|| check_fwstate(pmlmepriv, WIFI_AP_STATE)
|
||||
|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
|
||||
|| !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
|
||||
) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* consider buddy, if exist */
|
||||
if (buddy) {
|
||||
struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv;
|
||||
#ifdef CONFIG_8723AU_P2P
|
||||
struct wifidirect_info *b_pwdinfo = &buddy->wdinfo;
|
||||
#endif
|
||||
|
||||
if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)
|
||||
|| check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS)
|
||||
|| check_fwstate(b_pmlmepriv, WIFI_AP_STATE)
|
||||
|| check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)
|
||||
|| !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE)
|
||||
) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
|
||||
pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
|
||||
DBG_8723A_LEVEL(_drv_always_, "There are some pkts to transmit\n");
|
||||
DBG_8723A_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
|
||||
pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rtw_ps_processor23a(struct rtw_adapter*padapter)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
enum rt_rf_power_state rfpwrstate;
|
||||
|
||||
pwrpriv->ps_processing = true;
|
||||
|
||||
if (pwrpriv->bips_processing == true)
|
||||
goto exit;
|
||||
|
||||
if (padapter->pwrctrlpriv.bHWPwrPindetect) {
|
||||
rfpwrstate = RfOnOffDetect23a(padapter);
|
||||
DBG_8723A("@@@@- #2 %s ==> rfstate:%s\n", __func__, (rfpwrstate == rf_on)?"rf_on":"rf_off");
|
||||
|
||||
if (rfpwrstate!= pwrpriv->rf_pwrstate) {
|
||||
if (rfpwrstate == rf_off) {
|
||||
pwrpriv->change_rfpwrstate = rf_off;
|
||||
pwrpriv->brfoffbyhw = true;
|
||||
padapter->bCardDisableWOHSM = true;
|
||||
rtw_hw_suspend23a(padapter);
|
||||
} else {
|
||||
pwrpriv->change_rfpwrstate = rf_on;
|
||||
rtw_hw_resume23a(padapter);
|
||||
}
|
||||
DBG_8723A("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off)?"rf_off":"rf_on");
|
||||
}
|
||||
pwrpriv->pwr_state_check_cnts ++;
|
||||
}
|
||||
|
||||
if (pwrpriv->ips_mode_req == IPS_NONE)
|
||||
goto exit;
|
||||
|
||||
if (rtw_pwr_unassociated_idle(padapter) == false)
|
||||
goto exit;
|
||||
|
||||
if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0))
|
||||
{
|
||||
DBG_8723A("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv));
|
||||
pwrpriv->change_rfpwrstate = rf_off;
|
||||
ips_enter23a(padapter);
|
||||
}
|
||||
exit:
|
||||
rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
|
||||
pwrpriv->ps_processing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
static void pwr_state_check_handler(unsigned long data)
|
||||
{
|
||||
struct rtw_adapter *padapter = (struct rtw_adapter *)data;
|
||||
rtw_ps_cmd23a(padapter);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Parameters
|
||||
* padapter
|
||||
* pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
|
||||
*
|
||||
*/
|
||||
void rtw_set_rpwm23a(struct rtw_adapter *padapter, u8 pslv)
|
||||
{
|
||||
u8 rpwm;
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
|
||||
|
||||
pslv = PS_STATE(pslv);
|
||||
|
||||
if (true == pwrpriv->btcoex_rfon)
|
||||
{
|
||||
if (pslv < PS_STATE_S4)
|
||||
pslv = PS_STATE_S3;
|
||||
}
|
||||
|
||||
if (pwrpriv->rpwm == pslv) {
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
|
||||
("%s: Already set rpwm[0x%02X], new = 0x%02X!\n", __func__, pwrpriv->rpwm, pslv));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((padapter->bSurpriseRemoved == true) ||
|
||||
(padapter->hw_init_completed == false)) {
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
|
||||
("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
|
||||
__func__, padapter->bSurpriseRemoved, padapter->hw_init_completed));
|
||||
|
||||
pwrpriv->cpwm = PS_STATE_S4;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (padapter->bDriverStopped == true) {
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
|
||||
("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv));
|
||||
|
||||
if (pslv < PS_STATE_S2) {
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
|
||||
("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __func__, pslv));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rpwm = pslv | pwrpriv->tog;
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
|
||||
("rtw_set_rpwm23a: rpwm = 0x%02x cpwm = 0x%02x\n", rpwm, pwrpriv->cpwm));
|
||||
|
||||
pwrpriv->rpwm = pslv;
|
||||
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
|
||||
|
||||
pwrpriv->tog += 0x80;
|
||||
pwrpriv->cpwm = pslv;
|
||||
|
||||
|
||||
}
|
||||
|
||||
u8 PS_RDY_CHECK(struct rtw_adapter * padapter)
|
||||
{
|
||||
unsigned long delta_time;
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
delta_time = jiffies - pwrpriv->DelayLPSLastTimeStamp;
|
||||
|
||||
if (delta_time < LPS_DELAY_TIME)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) ||
|
||||
(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true))
|
||||
return false;
|
||||
if (true == pwrpriv->bInSuspend)
|
||||
return false;
|
||||
if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false))
|
||||
{
|
||||
DBG_8723A("Group handshake still in progress !!!\n");
|
||||
return false;
|
||||
}
|
||||
if (!rtw_cfg80211_pwr_mgmt(padapter))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void rtw_set_ps_mode23a(struct rtw_adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
#ifdef CONFIG_8723AU_P2P
|
||||
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
|
||||
#endif /* CONFIG_8723AU_P2P */
|
||||
|
||||
|
||||
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
|
||||
("%s: PowerMode =%d Smart_PS =%d\n",
|
||||
__func__, ps_mode, smart_ps));
|
||||
|
||||
if (ps_mode > PM_Card_Disable) {
|
||||
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pwrpriv->pwr_mode == ps_mode)
|
||||
{
|
||||
if (PS_MODE_ACTIVE == ps_mode) return;
|
||||
|
||||
if ((pwrpriv->smart_ps == smart_ps) &&
|
||||
(pwrpriv->bcn_ant_mode == bcn_ant_mode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ps_mode == PS_MODE_ACTIVE) {
|
||||
#ifdef CONFIG_8723AU_P2P
|
||||
if (pwdinfo->opp_ps == 0)
|
||||
#endif /* CONFIG_8723AU_P2P */
|
||||
{
|
||||
DBG_8723A("rtw_set_ps_mode23a: Leave 802.11 power save\n");
|
||||
|
||||
pwrpriv->pwr_mode = ps_mode;
|
||||
rtw_set_rpwm23a(padapter, PS_STATE_S4);
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
|
||||
pwrpriv->bFwCurrentInPSMode = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PS_RDY_CHECK(padapter)
|
||||
#ifdef CONFIG_8723AU_BT_COEXIST
|
||||
|| (BT_1Ant(padapter) == true)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
DBG_8723A("%s: Enter 802.11 power save\n", __func__);
|
||||
|
||||
pwrpriv->bFwCurrentInPSMode = true;
|
||||
pwrpriv->pwr_mode = ps_mode;
|
||||
pwrpriv->smart_ps = smart_ps;
|
||||
pwrpriv->bcn_ant_mode = bcn_ant_mode;
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
|
||||
|
||||
#ifdef CONFIG_8723AU_P2P
|
||||
/* Set CTWindow after LPS */
|
||||
if (pwdinfo->opp_ps == 1)
|
||||
p2p_ps_wk_cmd23a(padapter, P2P_PS_ENABLE, 0);
|
||||
#endif /* CONFIG_8723AU_P2P */
|
||||
|
||||
rtw_set_rpwm23a(padapter, PS_STATE_S2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Return:
|
||||
* 0: Leave OK
|
||||
* -1: Timeout
|
||||
* -2: Other error
|
||||
*/
|
||||
s32 LPS_RF_ON_check23a(struct rtw_adapter *padapter, u32 delay_ms)
|
||||
{
|
||||
u32 start_time;
|
||||
u8 bAwake = false;
|
||||
s32 err = 0;
|
||||
|
||||
start_time = rtw_get_current_time();
|
||||
while (1)
|
||||
{
|
||||
rtw23a_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
|
||||
if (true == bAwake)
|
||||
break;
|
||||
|
||||
if (true == padapter->bSurpriseRemoved)
|
||||
{
|
||||
err = -2;
|
||||
DBG_8723A("%s: device surprise removed!!\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rtw_get_passing_time_ms23a(start_time) > delay_ms)
|
||||
{
|
||||
err = -1;
|
||||
DBG_8723A("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms);
|
||||
break;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Description: */
|
||||
/* Enter the leisure power save mode. */
|
||||
void LPS_Enter23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
if (!PS_RDY_CHECK(padapter))
|
||||
return;
|
||||
|
||||
if (pwrpriv->bLeisurePs) {
|
||||
/* Idle for a while if we connect to AP a while ago. */
|
||||
if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
|
||||
if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
|
||||
pwrpriv->bpower_saving = true;
|
||||
DBG_8723A("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps);
|
||||
/* For Tenda W311R IOT issue */
|
||||
rtw_set_ps_mode23a(padapter, pwrpriv->power_mgnt, pwrpriv->smart_ps, 0);
|
||||
}
|
||||
} else {
|
||||
pwrpriv->LpsIdleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Description: */
|
||||
/* Leave the leisure power save mode. */
|
||||
void LPS_Leave23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
#define LPS_LEAVE_TIMEOUT_MS 100
|
||||
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
if (pwrpriv->bLeisurePs) {
|
||||
if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
|
||||
rtw_set_ps_mode23a(padapter, PS_MODE_ACTIVE, 0, 0);
|
||||
|
||||
if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
|
||||
LPS_RF_ON_check23a(padapter, LPS_LEAVE_TIMEOUT_MS);
|
||||
}
|
||||
}
|
||||
|
||||
pwrpriv->bpower_saving = false;
|
||||
}
|
||||
|
||||
/* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
|
||||
/* Move code to function by tynli. 2010.03.26. */
|
||||
void LeaveAllPowerSaveMode23a(struct rtw_adapter *Adapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
|
||||
u8 enqueue = 0;
|
||||
|
||||
|
||||
|
||||
/* DBG_8723A("%s.....\n", __func__); */
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
|
||||
{ /* connect */
|
||||
#ifdef CONFIG_8723AU_P2P
|
||||
p2p_ps_wk_cmd23a(Adapter, P2P_PS_DISABLE, enqueue);
|
||||
#endif /* CONFIG_8723AU_P2P */
|
||||
|
||||
rtw_lps_ctrl_wk_cmd23a(Adapter, LPS_CTRL_LEAVE, enqueue);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void rtw_init_pwrctrl_priv23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
sema_init(&pwrctrlpriv->lock, 1);
|
||||
pwrctrlpriv->rf_pwrstate = rf_on;
|
||||
pwrctrlpriv->ips_enter23a_cnts = 0;
|
||||
pwrctrlpriv->ips_leave23a_cnts = 0;
|
||||
pwrctrlpriv->bips_processing = false;
|
||||
|
||||
pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
|
||||
pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
|
||||
|
||||
pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
|
||||
pwrctrlpriv->pwr_state_check_cnts = 0;
|
||||
pwrctrlpriv->bInternalAutoSuspend = false;
|
||||
pwrctrlpriv->bInSuspend = false;
|
||||
pwrctrlpriv->bkeepfwalive = false;
|
||||
|
||||
pwrctrlpriv->LpsIdleCount = 0;
|
||||
pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */
|
||||
pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?true:false;
|
||||
|
||||
pwrctrlpriv->bFwCurrentInPSMode = false;
|
||||
|
||||
pwrctrlpriv->rpwm = 0;
|
||||
pwrctrlpriv->cpwm = PS_STATE_S4;
|
||||
|
||||
pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
|
||||
pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
|
||||
pwrctrlpriv->bcn_ant_mode = 0;
|
||||
|
||||
pwrctrlpriv->tog = 0x80;
|
||||
|
||||
pwrctrlpriv->btcoex_rfon = false;
|
||||
|
||||
setup_timer(&pwrctrlpriv->pwr_state_check_timer,
|
||||
pwr_state_check_handler, (unsigned long)padapter);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void rtw_free_pwrctrl_priv(struct rtw_adapter *adapter)
|
||||
{
|
||||
}
|
||||
|
||||
u8 rtw_interface_ps_func23a(struct rtw_adapter *padapter, enum hal_intf_ps_func efunc_id, u8* val)
|
||||
{
|
||||
u8 bResult = true;
|
||||
rtw_hal_intf_ps_func23a(padapter, efunc_id, val);
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime23a(ms);
|
||||
}
|
||||
|
||||
/*
|
||||
* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
|
||||
* @adapter: pointer to _adapter structure
|
||||
* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup
|
||||
* Return _SUCCESS or _FAIL
|
||||
*/
|
||||
|
||||
int _rtw_pwr_wakeup23a(struct rtw_adapter *padapter, u32 ips_deffer_ms, const char *caller)
|
||||
{
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
int ret = _SUCCESS;
|
||||
u32 start = rtw_get_current_time();
|
||||
|
||||
if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime23a(ips_deffer_ms))
|
||||
pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime23a(ips_deffer_ms);
|
||||
|
||||
if (pwrpriv->ps_processing) {
|
||||
DBG_8723A("%s wait ps_processing...\n", __func__);
|
||||
while (pwrpriv->ps_processing && rtw_get_passing_time_ms23a(start) <= 3000)
|
||||
msleep(10);
|
||||
if (pwrpriv->ps_processing)
|
||||
DBG_8723A("%s wait ps_processing timeout\n", __func__);
|
||||
else
|
||||
DBG_8723A("%s wait ps_processing done\n", __func__);
|
||||
}
|
||||
|
||||
if (rtw_hal_sreset_inprogress(padapter)) {
|
||||
DBG_8723A("%s wait sreset_inprogress...\n", __func__);
|
||||
while (rtw_hal_sreset_inprogress(padapter) && rtw_get_passing_time_ms23a(start) <= 4000)
|
||||
msleep(10);
|
||||
if (rtw_hal_sreset_inprogress(padapter))
|
||||
DBG_8723A("%s wait sreset_inprogress timeout\n", __func__);
|
||||
else
|
||||
DBG_8723A("%s wait sreset_inprogress done\n", __func__);
|
||||
}
|
||||
|
||||
if (pwrpriv->bInternalAutoSuspend == false && pwrpriv->bInSuspend) {
|
||||
DBG_8723A("%s wait bInSuspend...\n", __func__);
|
||||
while (pwrpriv->bInSuspend &&
|
||||
(rtw_get_passing_time_ms23a(start) <= 3000)) {
|
||||
msleep(10);
|
||||
}
|
||||
if (pwrpriv->bInSuspend)
|
||||
DBG_8723A("%s wait bInSuspend timeout\n", __func__);
|
||||
else
|
||||
DBG_8723A("%s wait bInSuspend done\n", __func__);
|
||||
}
|
||||
|
||||
/* System suspend is not allowed to wakeup */
|
||||
if ((pwrpriv->bInternalAutoSuspend == false) && (true == pwrpriv->bInSuspend)) {
|
||||
ret = _FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* block??? */
|
||||
if ((pwrpriv->bInternalAutoSuspend == true) && (padapter->net_closed == true)) {
|
||||
ret = _FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* I think this should be check in IPS, LPS, autosuspend functions... */
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
|
||||
{
|
||||
ret = _SUCCESS;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (rf_off == pwrpriv->rf_pwrstate) {
|
||||
DBG_8723A("%s call ips_leave23a....\n", __func__);
|
||||
if (_FAIL == ips_leave23a(padapter)) {
|
||||
DBG_8723A("======> ips_leave23a fail.............\n");
|
||||
ret = _FAIL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: the following checking need to be merged... */
|
||||
if (padapter->bDriverStopped || !padapter->bup ||
|
||||
!padapter->hw_init_completed) {
|
||||
DBG_8723A("%s: bDriverStopped =%d, bup =%d, hw_init_completed "
|
||||
"=%u\n", caller, padapter->bDriverStopped,
|
||||
padapter->bup, padapter->hw_init_completed);
|
||||
ret = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime23a(ips_deffer_ms))
|
||||
pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime23a(ips_deffer_ms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw_pm_set_lps23a(struct rtw_adapter *padapter, u8 mode)
|
||||
{
|
||||
int ret = 0;
|
||||
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
if (mode < PS_MODE_NUM)
|
||||
{
|
||||
if (pwrctrlpriv->power_mgnt != mode)
|
||||
{
|
||||
if (PS_MODE_ACTIVE == mode)
|
||||
{
|
||||
LeaveAllPowerSaveMode23a(padapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
pwrctrlpriv->LpsIdleCount = 2;
|
||||
}
|
||||
pwrctrlpriv->power_mgnt = mode;
|
||||
pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?true:false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtw_pm_set_ips23a(struct rtw_adapter *padapter, u8 mode)
|
||||
{
|
||||
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
|
||||
|
||||
if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
|
||||
rtw_ips_mode_req(pwrctrlpriv, mode);
|
||||
DBG_8723A("%s %s\n", __func__, mode == IPS_NORMAL?"IPS_NORMAL":"IPS_LEVEL_2");
|
||||
return 0;
|
||||
}
|
||||
else if (mode == IPS_NONE) {
|
||||
rtw_ips_mode_req(pwrctrlpriv, mode);
|
||||
DBG_8723A("%s %s\n", __func__, "IPS_NONE");
|
||||
if ((padapter->bSurpriseRemoved == 0)&&_FAIL == rtw_pwr_wakeup(padapter))
|
||||
return -EFAULT;
|
||||
}
|
||||
else {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
2471
drivers/staging/rtl8723au/core/rtw_recv.c
Normal file
2471
drivers/staging/rtl8723au/core/rtw_recv.c
Normal file
File diff suppressed because it is too large
Load Diff
1653
drivers/staging/rtl8723au/core/rtw_security.c
Normal file
1653
drivers/staging/rtl8723au/core/rtw_security.c
Normal file
File diff suppressed because it is too large
Load Diff
253
drivers/staging/rtl8723au/core/rtw_sreset.c
Normal file
253
drivers/staging/rtl8723au/core/rtw_sreset.c
Normal file
@ -0,0 +1,253 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include<rtw_sreset.h>
|
||||
|
||||
void sreset_init_value23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
|
||||
|
||||
mutex_init(&psrtpriv->silentreset_mutex);
|
||||
psrtpriv->silent_reset_inprogress = false;
|
||||
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
|
||||
psrtpriv->last_tx_time = 0;
|
||||
psrtpriv->last_tx_complete_time = 0;
|
||||
}
|
||||
void sreset_reset_value23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
|
||||
|
||||
psrtpriv->silent_reset_inprogress = false;
|
||||
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
|
||||
psrtpriv->last_tx_time = 0;
|
||||
psrtpriv->last_tx_complete_time = 0;
|
||||
}
|
||||
|
||||
u8 sreset_get_wifi_status23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
|
||||
u8 status = WIFI_STATUS_SUCCESS;
|
||||
u32 val32 = 0;
|
||||
|
||||
if (psrtpriv->silent_reset_inprogress)
|
||||
return status;
|
||||
val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
|
||||
if (val32 == 0xeaeaeaea) {
|
||||
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
|
||||
} else if (val32 != 0) {
|
||||
DBG_8723A("txdmastatu(%x)\n", val32);
|
||||
psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
|
||||
}
|
||||
|
||||
if (WIFI_STATUS_SUCCESS != psrtpriv->Wifi_Error_Status) {
|
||||
DBG_8723A("==>%s error_status(0x%x)\n", __func__, psrtpriv->Wifi_Error_Status);
|
||||
status = (psrtpriv->Wifi_Error_Status &~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL));
|
||||
}
|
||||
DBG_8723A("==> %s wifi_status(0x%x)\n", __func__, status);
|
||||
|
||||
/* status restore */
|
||||
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void sreset_set_wifi_error_status23a(struct rtw_adapter *padapter, u32 status)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
|
||||
pHalData->srestpriv.Wifi_Error_Status = status;
|
||||
}
|
||||
|
||||
void sreset_set_trigger_point(struct rtw_adapter *padapter, s32 tgp)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
|
||||
pHalData->srestpriv.dbg_trigger_point = tgp;
|
||||
}
|
||||
|
||||
bool sreset_inprogress(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
|
||||
return pHalData->srestpriv.silent_reset_inprogress;
|
||||
}
|
||||
|
||||
static void sreset_restore_security_station(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct sta_info *psta;
|
||||
struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
|
||||
u8 val8;
|
||||
|
||||
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)
|
||||
val8 = 0xcc;
|
||||
else
|
||||
val8 = 0xcf;
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
|
||||
|
||||
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
|
||||
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
|
||||
psta = rtw_get_stainfo23a(pstapriv, get_bssid(mlmepriv));
|
||||
if (psta == NULL) {
|
||||
/* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
|
||||
} else {
|
||||
/* pairwise key */
|
||||
rtw_setstakey_cmd23a(padapter, (unsigned char *)psta, true);
|
||||
/* group key */
|
||||
rtw_set_key23a(padapter,&padapter->securitypriv, padapter->securitypriv.dot118021XGrpKeyid, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sreset_restore_network_station(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
|
||||
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
|
||||
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
|
||||
u8 threshold;
|
||||
|
||||
rtw_setopmode_cmd23a(padapter, Ndis802_11Infrastructure);
|
||||
|
||||
/* TH = 1 => means that invalidate usb rx aggregation */
|
||||
/* TH = 0 => means that validate usb rx aggregation, use init value. */
|
||||
if (mlmepriv->htpriv.ht_option) {
|
||||
if (padapter->registrypriv.wifi_spec == 1)
|
||||
threshold = 1;
|
||||
else
|
||||
threshold = 0;
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
|
||||
} else {
|
||||
threshold = 1;
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
|
||||
}
|
||||
|
||||
set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
|
||||
|
||||
/* disable dynamic functions, such as high power, DIG */
|
||||
/* Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false); */
|
||||
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
|
||||
|
||||
{
|
||||
u8 join_type = 0;
|
||||
rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
|
||||
}
|
||||
|
||||
Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
|
||||
|
||||
mlmeext_joinbss_event_callback23a(padapter, 1);
|
||||
/* restore Sequence No. */
|
||||
rtw_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn);
|
||||
|
||||
sreset_restore_security_station(padapter);
|
||||
}
|
||||
|
||||
static void sreset_restore_network_status(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
|
||||
|
||||
if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
|
||||
DBG_8723A(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
|
||||
sreset_restore_network_station(padapter);
|
||||
} else if (check_fwstate(mlmepriv, WIFI_AP_STATE)) {
|
||||
DBG_8723A(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
|
||||
rtw_ap_restore_network(padapter);
|
||||
} else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) {
|
||||
DBG_8723A(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
|
||||
} else {
|
||||
DBG_8723A(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
|
||||
}
|
||||
}
|
||||
|
||||
static void sreset_stop_adapter(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
if (padapter == NULL)
|
||||
return;
|
||||
|
||||
DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
|
||||
|
||||
if (!rtw_netif_queue_stopped(padapter->pnetdev))
|
||||
netif_tx_stop_all_queues(padapter->pnetdev);
|
||||
|
||||
rtw_cancel_all_timer23a(padapter);
|
||||
|
||||
/* TODO: OS and HCI independent */
|
||||
tasklet_kill(&pxmitpriv->xmit_tasklet);
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
|
||||
rtw_scan_abort23a(padapter);
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
|
||||
rtw23a_join_to_handler((unsigned long)padapter);
|
||||
}
|
||||
|
||||
static void sreset_start_adapter(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
if (padapter == NULL)
|
||||
return;
|
||||
|
||||
DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
|
||||
sreset_restore_network_status(padapter);
|
||||
}
|
||||
|
||||
/* TODO: OS and HCI independent */
|
||||
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
|
||||
|
||||
mod_timer(&padapter->mlmepriv.dynamic_chk_timer,
|
||||
jiffies + msecs_to_jiffies(2000));
|
||||
|
||||
if (rtw_netif_queue_stopped(padapter->pnetdev))
|
||||
netif_tx_wake_all_queues(padapter->pnetdev);
|
||||
}
|
||||
|
||||
void sreset_reset(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
|
||||
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
|
||||
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
|
||||
unsigned long start = jiffies;
|
||||
|
||||
DBG_8723A("%s\n", __func__);
|
||||
|
||||
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
|
||||
|
||||
mutex_lock(&psrtpriv->silentreset_mutex);
|
||||
psrtpriv->silent_reset_inprogress = true;
|
||||
pwrpriv->change_rfpwrstate = rf_off;
|
||||
|
||||
sreset_stop_adapter(padapter);
|
||||
|
||||
ips_enter23a(padapter);
|
||||
ips_leave23a(padapter);
|
||||
|
||||
sreset_start_adapter(padapter);
|
||||
psrtpriv->silent_reset_inprogress = false;
|
||||
mutex_unlock(&psrtpriv->silentreset_mutex);
|
||||
|
||||
DBG_8723A("%s done in %d ms\n", __func__,
|
||||
jiffies_to_msecs(jiffies - start));
|
||||
}
|
509
drivers/staging/rtl8723au/core/rtw_sta_mgt.c
Normal file
509
drivers/staging/rtl8723au/core/rtw_sta_mgt.c
Normal file
@ -0,0 +1,509 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RTW_STA_MGT_C_
|
||||
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
#include <recv_osdep.h>
|
||||
#include <xmit_osdep.h>
|
||||
#include <mlme_osdep.h>
|
||||
#include <sta_info.h>
|
||||
|
||||
void _rtw_init_stainfo(struct sta_info *psta)
|
||||
{
|
||||
memset((u8 *)psta, 0, sizeof (struct sta_info));
|
||||
spin_lock_init(&psta->lock);
|
||||
INIT_LIST_HEAD(&psta->list);
|
||||
INIT_LIST_HEAD(&psta->hash_list);
|
||||
_rtw_init_queue23a(&psta->sleep_q);
|
||||
psta->sleepq_len = 0;
|
||||
_rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv);
|
||||
_rtw_init_sta_recv_priv23a(&psta->sta_recvpriv);
|
||||
#ifdef CONFIG_8723AU_AP_MODE
|
||||
INIT_LIST_HEAD(&psta->asoc_list);
|
||||
INIT_LIST_HEAD(&psta->auth_list);
|
||||
psta->expire_to = 0;
|
||||
psta->flags = 0;
|
||||
psta->capability = 0;
|
||||
psta->bpairwise_key_installed = false;
|
||||
psta->nonerp_set = 0;
|
||||
psta->no_short_slot_time_set = 0;
|
||||
psta->no_short_preamble_set = 0;
|
||||
psta->no_ht_gf_set = 0;
|
||||
psta->no_ht_set = 0;
|
||||
psta->ht_20mhz_set = 0;
|
||||
psta->keep_alive_trycnt = 0;
|
||||
#endif /* CONFIG_8723AU_AP_MODE */
|
||||
}
|
||||
|
||||
u32 _rtw_init_sta_priv23a(struct sta_priv *pstapriv)
|
||||
{
|
||||
struct sta_info *psta;
|
||||
s32 i;
|
||||
|
||||
pstapriv->pallocated_stainfo_buf = rtw_zvmalloc(sizeof(struct sta_info) * NUM_STA+ 4);
|
||||
|
||||
if (!pstapriv->pallocated_stainfo_buf)
|
||||
return _FAIL;
|
||||
|
||||
pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
|
||||
((unsigned long)(pstapriv->pallocated_stainfo_buf) & 3);
|
||||
_rtw_init_queue23a(&pstapriv->free_sta_queue);
|
||||
spin_lock_init(&pstapriv->sta_hash_lock);
|
||||
pstapriv->asoc_sta_count = 0;
|
||||
_rtw_init_queue23a(&pstapriv->sleep_q);
|
||||
_rtw_init_queue23a(&pstapriv->wakeup_q);
|
||||
psta = (struct sta_info *)(pstapriv->pstainfo_buf);
|
||||
|
||||
for (i = 0; i < NUM_STA; i++) {
|
||||
_rtw_init_stainfo(psta);
|
||||
INIT_LIST_HEAD(&pstapriv->sta_hash[i]);
|
||||
list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
|
||||
psta++;
|
||||
}
|
||||
#ifdef CONFIG_8723AU_AP_MODE
|
||||
pstapriv->sta_dz_bitmap = 0;
|
||||
pstapriv->tim_bitmap = 0;
|
||||
INIT_LIST_HEAD(&pstapriv->asoc_list);
|
||||
INIT_LIST_HEAD(&pstapriv->auth_list);
|
||||
spin_lock_init(&pstapriv->asoc_list_lock);
|
||||
spin_lock_init(&pstapriv->auth_list_lock);
|
||||
pstapriv->asoc_list_cnt = 0;
|
||||
pstapriv->auth_list_cnt = 0;
|
||||
pstapriv->auth_to = 3; /* 3*2 = 6 sec */
|
||||
pstapriv->assoc_to = 3;
|
||||
/* pstapriv->expire_to = 900; 900*2 = 1800 sec = 30 min, expire after no any traffic. */
|
||||
/* pstapriv->expire_to = 30; 30*2 = 60 sec = 1 min, expire after no any traffic. */
|
||||
pstapriv->expire_to = 3; /* 3*2 = 6 sec */
|
||||
pstapriv->max_num_sta = NUM_STA;
|
||||
#endif
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
inline int rtw_stainfo_offset23a(struct sta_priv *stapriv, struct sta_info *sta)
|
||||
{
|
||||
int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
|
||||
|
||||
if (!stainfo_offset_valid(offset))
|
||||
DBG_8723A("%s invalid offset(%d), out of range!!!", __func__, offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
inline struct sta_info *rtw_get_stainfo23a_by_offset23a(struct sta_priv *stapriv, int offset)
|
||||
{
|
||||
if (!stainfo_offset_valid(offset))
|
||||
DBG_8723A("%s invalid offset(%d), out of range!!!", __func__, offset);
|
||||
return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
|
||||
}
|
||||
|
||||
/* this function is used to free the memory of lock || sema for all stainfos */
|
||||
void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
|
||||
{
|
||||
struct list_head *plist, *phead;
|
||||
struct sta_info *psta;
|
||||
|
||||
spin_lock_bh(&pstapriv->sta_hash_lock);
|
||||
|
||||
phead = get_list_head(&pstapriv->free_sta_queue);
|
||||
|
||||
/* we really achieve a lot in this loop .... */
|
||||
list_for_each(plist, phead)
|
||||
psta = container_of(plist, struct sta_info, list);
|
||||
spin_unlock_bh(&pstapriv->sta_hash_lock);
|
||||
}
|
||||
|
||||
void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
|
||||
{
|
||||
rtw_mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
|
||||
}
|
||||
|
||||
u32 _rtw_free_sta_priv23a(struct sta_priv *pstapriv)
|
||||
{
|
||||
struct list_head *phead, *plist, *ptmp;
|
||||
struct sta_info *psta;
|
||||
struct recv_reorder_ctrl *preorder_ctrl;
|
||||
int index;
|
||||
|
||||
if (pstapriv) {
|
||||
/* delete all reordering_ctrl_timer */
|
||||
spin_lock_bh(&pstapriv->sta_hash_lock);
|
||||
for (index = 0; index < NUM_STA; index++) {
|
||||
phead = &pstapriv->sta_hash[index];
|
||||
|
||||
list_for_each_safe(plist, ptmp, phead) {
|
||||
int i;
|
||||
psta = container_of(plist, struct sta_info,
|
||||
hash_list);
|
||||
for (i = 0; i < 16 ; i++) {
|
||||
preorder_ctrl = &psta->recvreorder_ctrl[i];
|
||||
del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&pstapriv->sta_hash_lock);
|
||||
/*===============================*/
|
||||
|
||||
rtw_mfree_sta_priv_lock(pstapriv);
|
||||
|
||||
if (pstapriv->pallocated_stainfo_buf)
|
||||
rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4);
|
||||
}
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
struct sta_info *rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr)
|
||||
{
|
||||
struct list_head *phash_list;
|
||||
struct sta_info *psta;
|
||||
struct rtw_queue *pfree_sta_queue;
|
||||
struct recv_reorder_ctrl *preorder_ctrl;
|
||||
uint tmp_aid;
|
||||
s32 index;
|
||||
int i = 0;
|
||||
u16 wRxSeqInitialValue = 0xffff;
|
||||
|
||||
pfree_sta_queue = &pstapriv->free_sta_queue;
|
||||
|
||||
spin_lock_bh(&pstapriv->sta_hash_lock);
|
||||
|
||||
if (_rtw_queue_empty23a(pfree_sta_queue)) {
|
||||
spin_unlock_bh(&pstapriv->sta_hash_lock);
|
||||
return NULL;
|
||||
}
|
||||
psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
|
||||
|
||||
list_del_init(&psta->list);
|
||||
|
||||
tmp_aid = psta->aid;
|
||||
|
||||
_rtw_init_stainfo(psta);
|
||||
|
||||
psta->padapter = pstapriv->padapter;
|
||||
|
||||
memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
|
||||
|
||||
index = wifi_mac_hash(hwaddr);
|
||||
|
||||
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
|
||||
("rtw_alloc_stainfo23a: index = %x", index));
|
||||
if (index >= NUM_STA) {
|
||||
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
|
||||
("ERROR => rtw_alloc_stainfo23a: index >= NUM_STA"));
|
||||
psta = NULL;
|
||||
goto exit;
|
||||
}
|
||||
phash_list = &pstapriv->sta_hash[index];
|
||||
|
||||
list_add_tail(&psta->hash_list, phash_list);
|
||||
|
||||
pstapriv->asoc_sta_count ++ ;
|
||||
|
||||
/* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
|
||||
/* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */
|
||||
/* So, we initialize the tid_rxseq variable as the 0xffff. */
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
|
||||
|
||||
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
|
||||
("alloc number_%d stainfo with hwaddr = %pM\n",
|
||||
pstapriv->asoc_sta_count, hwaddr));
|
||||
|
||||
init_addba_retry_timer23a(psta);
|
||||
|
||||
/* for A-MPDU Rx reordering buffer control */
|
||||
for (i = 0; i < 16; i++) {
|
||||
preorder_ctrl = &psta->recvreorder_ctrl[i];
|
||||
|
||||
preorder_ctrl->padapter = pstapriv->padapter;
|
||||
|
||||
preorder_ctrl->enable = false;
|
||||
|
||||
preorder_ctrl->indicate_seq = 0xffff;
|
||||
preorder_ctrl->wend_b = 0xffff;
|
||||
/* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */
|
||||
preorder_ctrl->wsize_b = 64;/* 64; */
|
||||
|
||||
_rtw_init_queue23a(&preorder_ctrl->pending_recvframe_queue);
|
||||
|
||||
rtw_init_recv_timer23a(preorder_ctrl);
|
||||
}
|
||||
/* init for DM */
|
||||
psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
|
||||
psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
|
||||
|
||||
/* init for the sequence number of received management frame */
|
||||
psta->RxMgmtFrameSeqNum = 0xffff;
|
||||
exit:
|
||||
spin_unlock_bh(&pstapriv->sta_hash_lock);
|
||||
return psta;
|
||||
}
|
||||
|
||||
/* using pstapriv->sta_hash_lock to protect */
|
||||
u32 rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
struct rtw_queue *pfree_sta_queue;
|
||||
struct recv_reorder_ctrl *preorder_ctrl;
|
||||
struct sta_xmit_priv *pstaxmitpriv;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct hw_xmit *phwxmit;
|
||||
int i;
|
||||
|
||||
if (psta == NULL)
|
||||
goto exit;
|
||||
|
||||
spin_lock_bh(&psta->lock);
|
||||
psta->state &= ~_FW_LINKED;
|
||||
spin_unlock_bh(&psta->lock);
|
||||
|
||||
pfree_sta_queue = &pstapriv->free_sta_queue;
|
||||
|
||||
pstaxmitpriv = &psta->sta_xmitpriv;
|
||||
|
||||
spin_lock_bh(&pxmitpriv->lock);
|
||||
|
||||
rtw_free_xmitframe_queue23a(pxmitpriv, &psta->sleep_q);
|
||||
psta->sleepq_len = 0;
|
||||
|
||||
/* vo */
|
||||
rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
|
||||
list_del_init(&pstaxmitpriv->vo_q.tx_pending);
|
||||
phwxmit = pxmitpriv->hwxmits;
|
||||
phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
|
||||
pstaxmitpriv->vo_q.qcnt = 0;
|
||||
|
||||
/* vi */
|
||||
rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
|
||||
list_del_init(&pstaxmitpriv->vi_q.tx_pending);
|
||||
phwxmit = pxmitpriv->hwxmits+1;
|
||||
phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
|
||||
pstaxmitpriv->vi_q.qcnt = 0;
|
||||
|
||||
/* be */
|
||||
rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
|
||||
list_del_init(&pstaxmitpriv->be_q.tx_pending);
|
||||
phwxmit = pxmitpriv->hwxmits+2;
|
||||
phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
|
||||
pstaxmitpriv->be_q.qcnt = 0;
|
||||
|
||||
/* bk */
|
||||
rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
|
||||
list_del_init(&pstaxmitpriv->bk_q.tx_pending);
|
||||
phwxmit = pxmitpriv->hwxmits+3;
|
||||
phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
|
||||
pstaxmitpriv->bk_q.qcnt = 0;
|
||||
|
||||
spin_unlock_bh(&pxmitpriv->lock);
|
||||
|
||||
list_del_init(&psta->hash_list);
|
||||
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n", pstapriv->asoc_sta_count, psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4], psta->hwaddr[5]));
|
||||
pstapriv->asoc_sta_count --;
|
||||
|
||||
/* re-init sta_info; 20061114 will be init in alloc_stainfo */
|
||||
/* _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv); */
|
||||
/* _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv); */
|
||||
|
||||
del_timer_sync(&psta->addba_retry_timer);
|
||||
|
||||
/* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
|
||||
for (i = 0; i < 16; i++) {
|
||||
struct list_head *phead, *plist;
|
||||
struct recv_frame *prframe;
|
||||
struct rtw_queue *ppending_recvframe_queue;
|
||||
struct rtw_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
|
||||
|
||||
preorder_ctrl = &psta->recvreorder_ctrl[i];
|
||||
|
||||
del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
|
||||
|
||||
ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
|
||||
|
||||
spin_lock_bh(&ppending_recvframe_queue->lock);
|
||||
phead = get_list_head(ppending_recvframe_queue);
|
||||
plist = phead->next;
|
||||
|
||||
while (!list_empty(phead)) {
|
||||
prframe = container_of(plist, struct recv_frame, list);
|
||||
plist = plist->next;
|
||||
list_del_init(&prframe->list);
|
||||
rtw_free_recvframe23a(prframe, pfree_recv_queue);
|
||||
}
|
||||
spin_unlock_bh(&ppending_recvframe_queue->lock);
|
||||
}
|
||||
if (!(psta->state & WIFI_AP_STATE))
|
||||
rtw_hal_set_odm_var23a(padapter, HAL_ODM_STA_INFO, psta, false);
|
||||
#ifdef CONFIG_8723AU_AP_MODE
|
||||
spin_lock_bh(&pstapriv->auth_list_lock);
|
||||
if (!list_empty(&psta->auth_list)) {
|
||||
list_del_init(&psta->auth_list);
|
||||
pstapriv->auth_list_cnt--;
|
||||
}
|
||||
spin_unlock_bh(&pstapriv->auth_list_lock);
|
||||
|
||||
psta->expire_to = 0;
|
||||
|
||||
psta->sleepq_ac_len = 0;
|
||||
psta->qos_info = 0;
|
||||
|
||||
psta->max_sp_len = 0;
|
||||
psta->uapsd_bk = 0;
|
||||
psta->uapsd_be = 0;
|
||||
psta->uapsd_vi = 0;
|
||||
psta->uapsd_vo = 0;
|
||||
|
||||
psta->has_legacy_ac = 0;
|
||||
|
||||
pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
|
||||
pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
|
||||
|
||||
if ((psta->aid >0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
|
||||
pstapriv->sta_aid[psta->aid - 1] = NULL;
|
||||
psta->aid = 0;
|
||||
}
|
||||
#endif /* CONFIG_8723AU_AP_MODE */
|
||||
list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
|
||||
exit:
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
/* free all stainfo which in sta_hash[all] */
|
||||
void rtw_free_all_stainfo23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct list_head *plist, *phead, *ptmp;
|
||||
struct sta_info *psta;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct sta_info* pbcmc_stainfo = rtw_get_bcmc_stainfo23a(padapter);
|
||||
s32 index; if (pstapriv->asoc_sta_count == 1)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&pstapriv->sta_hash_lock);
|
||||
|
||||
for (index = 0; index < NUM_STA; index++) {
|
||||
phead = &pstapriv->sta_hash[index];
|
||||
|
||||
list_for_each_safe(plist, ptmp, phead) {
|
||||
psta = container_of(plist, struct sta_info, hash_list);
|
||||
|
||||
if (pbcmc_stainfo!= psta)
|
||||
rtw_free_stainfo23a(padapter, psta);
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&pstapriv->sta_hash_lock);
|
||||
}
|
||||
|
||||
/* any station allocated can be searched by hash list */
|
||||
struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr)
|
||||
{
|
||||
struct list_head *plist, *phead;
|
||||
struct sta_info *psta = NULL;
|
||||
u32 index;
|
||||
u8 *addr;
|
||||
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
if (hwaddr == NULL)
|
||||
return NULL;
|
||||
|
||||
if (is_multicast_ether_addr(hwaddr))
|
||||
addr = bc_addr;
|
||||
else
|
||||
addr = hwaddr;
|
||||
|
||||
index = wifi_mac_hash(addr);
|
||||
|
||||
spin_lock_bh(&pstapriv->sta_hash_lock);
|
||||
|
||||
phead = &pstapriv->sta_hash[index];
|
||||
|
||||
list_for_each(plist, phead) {
|
||||
psta = container_of(plist, struct sta_info, hash_list);
|
||||
|
||||
if (!memcmp(psta->hwaddr, addr, ETH_ALEN)) {
|
||||
/* if found the matched address */
|
||||
break;
|
||||
}
|
||||
psta = NULL;
|
||||
}
|
||||
spin_unlock_bh(&pstapriv->sta_hash_lock);
|
||||
return psta;
|
||||
}
|
||||
|
||||
u32 rtw_init_bcmc_stainfo23a(struct rtw_adapter* padapter)
|
||||
{
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct sta_info *psta;
|
||||
struct tx_servq *ptxservq;
|
||||
u32 res = _SUCCESS;
|
||||
unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
psta = rtw_alloc_stainfo23a(pstapriv, bcast_addr);
|
||||
if (psta == NULL) {
|
||||
res = _FAIL;
|
||||
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
|
||||
("rtw_alloc_stainfo23a fail"));
|
||||
return res;
|
||||
}
|
||||
/* default broadcast & multicast use macid 1 */
|
||||
psta->mac_id = 1;
|
||||
|
||||
ptxservq = &psta->sta_xmitpriv.be_q;
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter)
|
||||
{
|
||||
struct sta_info *psta;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
psta = rtw_get_stainfo23a(pstapriv, bc_addr);
|
||||
return psta;
|
||||
}
|
||||
|
||||
u8 rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr)
|
||||
{
|
||||
u8 res = true;
|
||||
#ifdef CONFIG_8723AU_AP_MODE
|
||||
struct list_head *plist, *phead;
|
||||
struct rtw_wlan_acl_node *paclnode;
|
||||
u8 match = false;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
|
||||
struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
|
||||
|
||||
spin_lock_bh(&pacl_node_q->lock);
|
||||
phead = get_list_head(pacl_node_q);
|
||||
|
||||
list_for_each(plist, phead) {
|
||||
paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
|
||||
|
||||
if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
|
||||
if (paclnode->valid) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&pacl_node_q->lock);
|
||||
|
||||
if (pacl_list->mode == 1)/* accept unless in deny list */
|
||||
res = (match) ? false : true;
|
||||
else if (pacl_list->mode == 2)/* deny unless in accept list */
|
||||
res = (match) ? true : false;
|
||||
else
|
||||
res = true;
|
||||
#endif
|
||||
return res;
|
||||
}
|
1760
drivers/staging/rtl8723au/core/rtw_wlan_util.c
Normal file
1760
drivers/staging/rtl8723au/core/rtw_wlan_util.c
Normal file
File diff suppressed because it is too large
Load Diff
2463
drivers/staging/rtl8723au/core/rtw_xmit.c
Normal file
2463
drivers/staging/rtl8723au/core/rtw_xmit.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user