Commit 554c0a3a authored by Hans de Goede's avatar Hans de Goede Committed by Greg Kroah-Hartman
Browse files

staging: Add rtl8723bs sdio wifi driver



The rtl8723bs is found on quite a few systems used by Linux users,
such as on Atom systems (Intel Computestick and various other
Atom based devices) and on many (budget) ARM boards such as
the CHIP.

The plan moving forward with this is for the new clean,
written from scratch, rtl8xxxu driver to eventually gain
support for sdio devices. But there is no clear timeline
for that, so lets add this driver included in staging for now.

Cc: Bastien Nocera <hadess@hadess.net>
Cc: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Jes Sorensen <jes.sorensen@gmail.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 38ca74e5
......@@ -34,6 +34,8 @@ source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
source "drivers/staging/rtl8723bs/Kconfig"
source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/rtl8188eu/Kconfig"
......
......@@ -6,6 +6,7 @@ obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_R8188EU) += rtl8188eu/
obj-$(CONFIG_RTS5208) += rts5208/
......
config RTL8723BS
tristate "Realtek RTL8723BS SDIO Wireless LAN NIC driver"
depends on WLAN && MMC && CFG80211
select WIRELESS_EXT
select WEXT_PRIV
---help---
This option enables support for RTL8723BS SDIO drivers, such as
the wifi found on the 1st gen Intel Compute Stick, the CHIP
and many other Intel Atom and ARM based devices.
If built as a module, it will be called r8723bs.
r8723bs-y = \
core/rtw_ap.o \
core/rtw_btcoex.o \
core/rtw_cmd.o \
core/rtw_debug.o \
core/rtw_efuse.o \
core/rtw_io.o \
core/rtw_ioctl_set.o \
core/rtw_ieee80211.o \
core/rtw_mlme.o \
core/rtw_mlme_ext.o \
core/rtw_odm.o \
core/rtw_pwrctrl.o \
core/rtw_recv.o \
core/rtw_rf.o \
core/rtw_security.o \
core/rtw_sta_mgt.o \
core/rtw_wlan_util.o \
core/rtw_xmit.o \
hal/hal_intf.o \
hal/hal_com.o \
hal/hal_com_phycfg.o \
hal/hal_btcoex.o \
hal/hal_sdio.o \
hal/Hal8723BPwrSeq.o \
hal/HalPhyRf.o \
hal/HalPwrSeqCmd.o \
hal/odm.o \
hal/odm_CfoTracking.o \
hal/odm_debug.o \
hal/odm_DIG.o \
hal/odm_DynamicBBPowerSaving.o \
hal/odm_DynamicTxPower.o \
hal/odm_EdcaTurboCheck.o \
hal/odm_HWConfig.o \
hal/odm_NoiseMonitor.o \
hal/odm_PathDiv.o \
hal/odm_RegConfig8723B.o \
hal/odm_RTL8723B.o \
hal/rtl8723b_cmd.o \
hal/rtl8723b_dm.o \
hal/rtl8723b_hal_init.o \
hal/rtl8723b_phycfg.o \
hal/rtl8723b_rf6052.o \
hal/rtl8723b_rxdesc.o \
hal/rtl8723bs_recv.o \
hal/rtl8723bs_xmit.o \
hal/sdio_halinit.o \
hal/sdio_ops.o \
hal/HalBtc8723b1Ant.o \
hal/HalBtc8723b2Ant.o \
hal/HalHWImg8723B_BB.o \
hal/HalHWImg8723B_MAC.o \
hal/HalHWImg8723B_RF.o \
hal/HalPhyRf_8723B.o \
os_dep/ioctl_cfg80211.o \
os_dep/ioctl_linux.o \
os_dep/mlme_linux.o \
os_dep/osdep_service.o \
os_dep/os_intfs.o \
os_dep/recv_linux.o \
os_dep/rtw_proc.o \
os_dep/sdio_intf.o \
os_dep/sdio_ops_linux.o \
os_dep/wifi_regd.o \
os_dep/xmit_linux.o
obj-$(CONFIG_RTL8723BS) := r8723bs.o
ccflags-y += -I$(srctree)/$(src)/include -I$(srctree)/$(src)/hal
TODO:
- find and remove code blocks guarded by never set CONFIG_FOO defines
- find and remove remaining code valid only for 5 HGz. Most of the obvious
ones have been removed, but things like channel > 14 still exist.
- find and remove any code for other chips that is left over
- convert any remaining unusual variable types
- find codes that can use %pM and %Nph formatting
- checkpatch.pl fixes - most of the remaining ones are lines too long. Many
of them will require refactoring
- merge Realtek's bugfixes and new features into the driver
- switch to use LIB80211
- switch to use MAC80211
Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Bastien Nocera <hadess@hadess.net>, Hans de Goede <hdegoede@redhat.com>
and Larry Finger <Larry.Finger@lwfinger.net>.
This diff is collapsed.
/******************************************************************************
*
* Copyright(c) 2013 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 <drv_types.h>
#include <rtw_debug.h>
#include <rtw_btcoex.h>
#include <hal_btcoex.h>
void rtw_btcoex_Initialize(struct adapter *padapter)
{
hal_btcoex_Initialize(padapter);
}
void rtw_btcoex_PowerOnSetting(struct adapter *padapter)
{
hal_btcoex_PowerOnSetting(padapter);
}
void rtw_btcoex_HAL_Initialize(struct adapter *padapter, u8 bWifiOnly)
{
hal_btcoex_InitHwConfig(padapter, bWifiOnly);
}
void rtw_btcoex_IpsNotify(struct adapter *padapter, u8 type)
{
hal_btcoex_IpsNotify(padapter, type);
}
void rtw_btcoex_LpsNotify(struct adapter *padapter, u8 type)
{
hal_btcoex_LpsNotify(padapter, type);
}
void rtw_btcoex_ScanNotify(struct adapter *padapter, u8 type)
{
hal_btcoex_ScanNotify(padapter, type);
}
void rtw_btcoex_ConnectNotify(struct adapter *padapter, u8 action)
{
hal_btcoex_ConnectNotify(padapter, action);
}
void rtw_btcoex_MediaStatusNotify(struct adapter *padapter, u8 mediaStatus)
{
if ((RT_MEDIA_CONNECT == mediaStatus)
&& (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) {
rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL);
}
hal_btcoex_MediaStatusNotify(padapter, mediaStatus);
}
void rtw_btcoex_SpecialPacketNotify(struct adapter *padapter, u8 pktType)
{
hal_btcoex_SpecialPacketNotify(padapter, pktType);
}
void rtw_btcoex_IQKNotify(struct adapter *padapter, u8 state)
{
hal_btcoex_IQKNotify(padapter, state);
}
void rtw_btcoex_BtInfoNotify(struct adapter *padapter, u8 length, u8 *tmpBuf)
{
hal_btcoex_BtInfoNotify(padapter, length, tmpBuf);
}
void rtw_btcoex_SuspendNotify(struct adapter *padapter, u8 state)
{
hal_btcoex_SuspendNotify(padapter, state);
}
void rtw_btcoex_HaltNotify(struct adapter *padapter)
{
if (false == padapter->bup) {
DBG_871X(FUNC_ADPT_FMT ": bup =%d Skip!\n",
FUNC_ADPT_ARG(padapter), padapter->bup);
return;
}
if (true == padapter->bSurpriseRemoved) {
DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved =%d Skip!\n",
FUNC_ADPT_ARG(padapter), padapter->bSurpriseRemoved);
return;
}
hal_btcoex_HaltNotify(padapter);
}
u8 rtw_btcoex_IsBtDisabled(struct adapter *padapter)
{
return hal_btcoex_IsBtDisabled(padapter);
}
void rtw_btcoex_Handler(struct adapter *padapter)
{
hal_btcoex_Hanlder(padapter);
}
s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(struct adapter *padapter)
{
s32 coexctrl;
coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter);
return coexctrl;
}
void rtw_btcoex_SetManualControl(struct adapter *padapter, u8 manual)
{
if (true == manual) {
hal_btcoex_SetManualControl(padapter, true);
} else{
hal_btcoex_SetManualControl(padapter, false);
}
}
u8 rtw_btcoex_IsBtControlLps(struct adapter *padapter)
{
return hal_btcoex_IsBtControlLps(padapter);
}
u8 rtw_btcoex_IsLpsOn(struct adapter *padapter)
{
return hal_btcoex_IsLpsOn(padapter);
}
u8 rtw_btcoex_RpwmVal(struct adapter *padapter)
{
return hal_btcoex_RpwmVal(padapter);
}
u8 rtw_btcoex_LpsVal(struct adapter *padapter)
{
return hal_btcoex_LpsVal(padapter);
}
void rtw_btcoex_SetBTCoexist(struct adapter *padapter, u8 bBtExist)
{
hal_btcoex_SetBTCoexist(padapter, bBtExist);
}
void rtw_btcoex_SetChipType(struct adapter *padapter, u8 chipType)
{
hal_btcoex_SetChipType(padapter, chipType);
}
void rtw_btcoex_SetPGAntNum(struct adapter *padapter, u8 antNum)
{
hal_btcoex_SetPgAntNum(padapter, antNum);
}
void rtw_btcoex_SetSingleAntPath(struct adapter *padapter, u8 singleAntPath)
{
hal_btcoex_SetSingleAntPath(padapter, singleAntPath);
}
u32 rtw_btcoex_GetRaMask(struct adapter *padapter)
{
return hal_btcoex_GetRaMask(padapter);
}
void rtw_btcoex_RecordPwrMode(struct adapter *padapter, u8 *pCmdBuf, u8 cmdLen)
{
hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen);
}
void rtw_btcoex_DisplayBtCoexInfo(struct adapter *padapter, u8 *pbuf, u32 bufsize)
{
hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize);
}
void rtw_btcoex_SetDBG(struct adapter *padapter, u32 *pDbgModule)
{
hal_btcoex_SetDBG(padapter, pDbgModule);
}
u32 rtw_btcoex_GetDBG(struct adapter *padapter, u8 *pStrBuf, u32 bufSize)
{
return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize);
}
/* ================================================== */
/* Below Functions are called by BT-Coex */
/* ================================================== */
void rtw_btcoex_RejectApAggregatedPacket(struct adapter *padapter, u8 enable)
{
struct mlme_ext_info *pmlmeinfo;
struct sta_info *psta;
pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
if (true == enable) {
pmlmeinfo->bAcceptAddbaReq = false;
if (psta)
send_delba(padapter, 0, psta->hwaddr);
} else{
pmlmeinfo->bAcceptAddbaReq = true;
}
}
void rtw_btcoex_LPS_Enter(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv;
u8 lpsVal;
pwrpriv = adapter_to_pwrctl(padapter);
pwrpriv->bpower_saving = true;
lpsVal = rtw_btcoex_LpsVal(padapter);
rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX");
}
void rtw_btcoex_LPS_Leave(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv;
pwrpriv = adapter_to_pwrctl(padapter);
if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "BTCOEX");
LPS_RF_ON_check(padapter, 100);
pwrpriv->bpower_saving = false;
}
}
This diff is collapsed.
This diff is collapsed.
/******************************************************************************
*
* 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_EEPROM_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
void up_clk(_adapter *padapter, u16 *x)
{
_func_enter_;
*x = *x | _EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
udelay(CLOCK_RATE);
_func_exit_;
}
void down_clk(_adapter *padapter, u16 *x)
{
_func_enter_;
*x = *x & ~_EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
udelay(CLOCK_RATE);
_func_exit_;
}
void shift_out_bits(_adapter *padapter, u16 data, u16 count)
{
u16 x, mask;
_func_enter_;
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
mask = 0x01 << (count - 1);
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
do {
x &= ~_EEDI;
if (data & mask)
x |= _EEDI;
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
rtw_write8(padapter, EE_9346CR, (u8)x);
udelay(CLOCK_RATE);
up_clk(padapter, &x);
down_clk(padapter, &x);
mask = mask >> 1;
} while (mask);
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
x &= ~_EEDI;
rtw_write8(padapter, EE_9346CR, (u8)x);
out:
_func_exit_;
}
u16 shift_in_bits(_adapter *padapter)
{
u16 x, d = 0, i;
_func_enter_;
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
d = 0;
for (i = 0; i < 16; i++) {
d = d << 1;
up_clk(padapter, &x);
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI);
if (x & _EEDO)
d |= 1;
down_clk(padapter, &x);
}
out:
_func_exit_;
return d;
}
void standby(_adapter *padapter)
{
u8 x;
_func_enter_;
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EECS | _EESK);
rtw_write8(padapter, EE_9346CR, x);
udelay(CLOCK_RATE);
x |= _EECS;
rtw_write8(padapter, EE_9346CR, x);
udelay(CLOCK_RATE);
_func_exit_;
}
u16 wait_eeprom_cmd_done(_adapter *padapter)
{
u8 x;
u16 i, res = false;
_func_enter_;
standby(padapter);
for (i = 0; i < 200; i++) {
x = rtw_read8(padapter, EE_9346CR);
if (x & _EEDO) {
res = true;
goto exit;
}
udelay(CLOCK_RATE);
}
exit:
_func_exit_;
return res;
}
void eeprom_clean(_adapter *padapter)
{
u16 x;
_func_enter_;
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
x &= ~(_EECS | _EEDI);
rtw_write8(padapter, EE_9346CR, (u8)x);
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
up_clk(padapter, &x);
if (padapter->bSurpriseRemoved == true) {
RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==true"));
goto out;
}
down_clk(padapter, &x);
out:
_func_exit_;
}
void eeprom_write16(_adapter *padapter, u16 reg, u16 data)
{
u8 x;
_func_enter_;
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, x);
shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
if (padapter->EepromAddressSize == 8) /*CF+ and SDIO*/
shift_out_bits(padapter, 0, 6);
else /*USB*/
shift_out_bits(padapter, 0, 4);
standby(padapter);
/* Commented out by rcnjko, 2004.0
* Erase this particular word. Write the erase opcode and register
* number in that order. The opcode is 3bits in length; reg is 6 bits long.
* shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3);
* shift_out_bits(Adapter, reg, Adapter->EepromAddressSize);
*
* if (wait_eeprom_cmd_done(Adapter ) == false)
* {
* return;
* }
*/
standby(padapter);
/* write the new word to the EEPROM*/
/* send the write opcode the EEPORM*/
shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);