Commit 13423166 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-6.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver fixes and removal from Greg KH:
 "Here are four small staging driver fixes, and one big staging driver
  deletion for 6.3-rc2.

  The fixes are:

   - rtl8192e driver fixes for where the driver was attempting to
     execute various programs directly from the disk for unknown reasons

   - rtl8723bs driver fixes for issues found by Hans in testing

  The deleted driver is the removal of the r8188eu wireless driver as
  now in 6.3-rc1 we have a "real" wifi driver for one that includes
  support for many many more devices than this old driver did. So it's
  time to remove it as it is no longer needed. The maintainers of this
  driver all have acked its removal. Many thanks to them over the years
  for working to clean it up and keep it working while the real driver
  was being developed.

  All of these have been in linux-next this week with no reported
  problems"

* tag 'staging-6.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: r8188eu: delete driver
  staging: rtl8723bs: Pass correct parameters to cfg80211_get_bss()
  staging: rtl8723bs: Fix key-store index handling
  staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh
  staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script
parents d3d0cac6 fdf6c230
......@@ -19864,13 +19864,6 @@ S: Maintained
W: http://wiki.laptop.org/go/DCON
F: drivers/staging/olpc_dcon/
STAGING - REALTEK RTL8188EU DRIVERS
M: Larry Finger <Larry.Finger@lwfinger.net>
M: Phillip Potter <phil@philpotter.co.uk>
R: Pavel Skripkin <paskripkin@gmail.com>
S: Supported
F: drivers/staging/r8188eu/
STAGING - REALTEK RTL8712U DRIVERS
M: Larry Finger <Larry.Finger@lwfinger.net>
M: Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
......
......@@ -36,8 +36,6 @@ source "drivers/staging/rtl8723bs/Kconfig"
source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/r8188eu/Kconfig"
source "drivers/staging/rts5208/Kconfig"
source "drivers/staging/octeon/Kconfig"
......
......@@ -8,7 +8,6 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_RTL8723BS) += rtl8723bs/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_R8188EU) += r8188eu/
obj-$(CONFIG_RTS5208) += rts5208/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VT6655) += vt6655/
......
# SPDX-License-Identifier: GPL-2.0
config R8188EU
tristate "Realtek RTL8188EU Wireless LAN NIC driver"
depends on WLAN && USB && CFG80211
depends on m
select WIRELESS_EXT
select WEXT_PRIV
select LIB80211
select LIB80211_CRYPT_WEP
select LIB80211_CRYPT_CCMP
help
This option adds support for the Realtek RTL8188EU chipset, used in USB
devices such as the ASUS USB-N10 Nano. This newer driver is based on GitHub
sources for version v4.1.4_6773.20130222, and contains modifications for
newer kernel features. If built as a module, it will be called r8188eu.
r8188eu-y = \
hal/HalHWImg8188E_MAC.o \
hal/HalHWImg8188E_BB.o \
hal/HalHWImg8188E_RF.o \
hal/HalPhyRf_8188e.o \
hal/HalPwrSeqCmd.o \
hal/Hal8188ERateAdaptive.o \
hal/hal_intf.o \
hal/hal_com.o \
hal/odm.o \
hal/odm_HWConfig.o \
hal/odm_RTL8188E.o \
hal/rtl8188e_cmd.o \
hal/rtl8188e_dm.o \
hal/rtl8188e_hal_init.o \
hal/rtl8188e_phycfg.o \
hal/rtl8188e_rf6052.o \
hal/rtl8188e_rxdesc.o \
hal/rtl8188eu_xmit.o \
hal/usb_halinit.o \
hal/usb_ops_linux.o \
os_dep/ioctl_linux.o \
os_dep/os_intfs.o \
os_dep/osdep_service.o \
os_dep/usb_intf.o \
os_dep/usb_ops_linux.o \
core/rtw_ap.o \
core/rtw_br_ext.o \
core/rtw_cmd.o \
core/rtw_efuse.o \
core/rtw_fw.o \
core/rtw_ieee80211.o \
core/rtw_ioctl_set.o \
core/rtw_iol.o \
core/rtw_led.o \
core/rtw_mlme.o \
core/rtw_mlme_ext.o \
core/rtw_pwrctrl.o \
core/rtw_p2p.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
obj-$(CONFIG_R8188EU) := r8188eu.o
To-do list:
* Correct the coding style according to Linux guidelines; please read the document
at https://www.kernel.org/doc/html/latest/process/coding-style.html.
* Remove unnecessary debugging/printing macros; for those that are still needed
use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()).
* Remove dead code such as unusued functions, variables, fields, etc..
* Use in-kernel API and remove unnecessary wrappers where possible.
* Fix bugs due to code that sleeps in atomic context.
* Remove the HAL layer and migrate its functionality into the relevant parts of
the driver.
* Switch to use LIB80211.
* Switch to use MAC80211.
* Switch to use CFG80211.
* Improve the error handling of various functions, particularly those that use
existing kernel APIs.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#define _RTW_EFUSE_C_
#include "../include/osdep_service.h"
#include "../include/drv_types.h"
#include "../include/rtw_efuse.h"
#include "../include/rtl8188e_hal.h"
/* */
/* Description: */
/* Execute E-Fuse read byte operation. */
/* Referred 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
ReadEFuseByte(
struct adapter *Adapter,
u16 _offset,
u8 *pbuf)
{
u32 value32;
u8 readbyte;
u16 retry;
int res;
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
res = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
if (res)
return;
rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
/* Write bit 32 0 */
res = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
if (res)
return;
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
/* Check bit 32 read-ready */
res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (res)
return;
for (retry = 0; retry < 10000; retry++) {
res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (res)
continue;
if (((value32 >> 24) & 0xff) & 0x80)
break;
}
/* 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);
res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
if (res)
return;
*pbuf = (u8)(value32 & 0xff);
/* FIXME: return an error to caller */
}
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include <linux/firmware.h>
#include "../include/rtw_fw.h"
#define MAX_REG_BLOCK_SIZE 196
#define FW_8188E_START_ADDRESS 0x1000
#define MAX_PAGE_SIZE 4096
#define IS_FW_HEADER_EXIST(_fwhdr) \
((le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x92C0 || \
(le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x88C0 || \
(le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x2300 || \
(le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x88E0)
struct rt_firmware_hdr {
__le16 signature; /* 92C0: test chip; 92C,
* 88C0: test chip; 88C1: MP A-cut;
* 92C1: MP A-cut */
u8 category; /* AP/NIC and USB/PCI */
u8 function; /* Reserved for different FW function
* indcation, for further use when
* driver needs to download different
* FW for different conditions */
__le16 version; /* FW Version */
u8 subversion; /* FW Subversion, default 0x00 */
u8 rsvd1;
u8 month; /* Release time Month field */
u8 date; /* Release time Date field */
u8 hour; /* Release time Hour field */
u8 minute; /* Release time Minute field */
__le16 ramcodesize; /* The size of RAM code */
u8 foundry;
u8 rsvd2;
__le32 svnidx; /* The SVN entry index */
__le32 rsvd3;
__le32 rsvd4;
__le32 rsvd5;
};
static_assert(sizeof(struct rt_firmware_hdr) == 32);
static void fw_download_enable(struct adapter *padapter, bool enable)
{
u8 tmp;
int res;
if (enable) {
/* MCU firmware download enable. */
res = rtw_read8(padapter, REG_MCUFWDL, &tmp);
if (res)
return;
rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
res = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
if (res)
return;
rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
/* MCU firmware download disable. */
res = rtw_read8(padapter, REG_MCUFWDL, &tmp);
if (res)
return;
rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension. */
rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
}
}
static int block_write(struct adapter *padapter, u8 *buffer, u32 size)
{
int ret = _SUCCESS;
u32 blocks, block_size, remain;
u32 i, offset, addr;
u8 *data;
block_size = MAX_REG_BLOCK_SIZE;
blocks = size / block_size;
remain = size % block_size;
for (i = 0; i < blocks; i++) {
addr = FW_8188E_START_ADDRESS + i * block_size;
data = buffer + i * block_size;
if (rtw_writeN(padapter, addr, block_size, data))
return _FAIL;
}
if (remain) {
offset = blocks * block_size;
block_size = 8;
blocks = remain / block_size;
remain = remain % block_size;
for (i = 0; i < blocks; i++) {
addr = FW_8188E_START_ADDRESS + offset + i * block_size;
data = buffer + offset + i * block_size;
if (rtw_writeN(padapter, addr, block_size, data))
return _FAIL;
}
}
if (remain) {
offset += blocks * block_size;
/* block size 1 */
blocks = remain;
for (i = 0; i < blocks; i++) {
addr = FW_8188E_START_ADDRESS + offset + i;
data = buffer + offset + i;
ret = rtw_write8(padapter, addr, *data);
if (ret == _FAIL)
goto exit;
}
}
exit:
return ret;
}
static int page_write(struct adapter *padapter, u32 page, u8 *buffer, u32 size)
{
u8 value8;
u8 u8Page = (u8)(page & 0x07);
int res;
res = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
if (res)
return _FAIL;
value8 = (value8 & 0xF8) | u8Page;
rtw_write8(padapter, REG_MCUFWDL + 2, value8);
return block_write(padapter, buffer, size);
}
static int write_fw(struct adapter *padapter, u8 *buffer, u32 size)
{
/* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
/* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
int ret = _SUCCESS;
u32 pageNums, remainSize;
u32 page, offset;
pageNums = size / MAX_PAGE_SIZE;
remainSize = size % MAX_PAGE_SIZE;
for (page = 0; page < pageNums; page++) {
offset = page * MAX_PAGE_SIZE;
ret = page_write(padapter, page, buffer + offset, MAX_PAGE_SIZE);
if (ret == _FAIL)
goto exit;
}
if (remainSize) {
offset = pageNums * MAX_PAGE_SIZE;
page = pageNums;
ret = page_write(padapter, page, buffer + offset, remainSize);
if (ret == _FAIL)
goto exit;
}
exit:
return ret;
}
void rtw_reset_8051(struct adapter *padapter)
{
u8 val8;
int res;
res = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &val8);
if (res)
return;
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 & (~BIT(2)));
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 | (BIT(2)));
}
static int fw_free_to_go(struct adapter *padapter)
{
u32 counter = 0;
u32 value32;
int res;
/* polling CheckSum report */
do {
res = rtw_read32(padapter, REG_MCUFWDL, &value32);
if (res)
continue;
if (value32 & FWDL_CHKSUM_RPT)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
if (counter >= POLLING_READY_TIMEOUT_COUNT)
return _FAIL;
res = rtw_read32(padapter, REG_MCUFWDL, &value32);
if (res)
return _FAIL;
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtw_write32(padapter, REG_MCUFWDL, value32);
rtw_reset_8051(padapter);
/* polling for FW ready */
counter = 0;
do {
res = rtw_read32(padapter, REG_MCUFWDL, &value32);
if (!res && value32 & WINTINI_RDY)
return _SUCCESS;
udelay(5);
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
return _FAIL;
}
static int load_firmware(struct rt_firmware *rtfw, struct device *device)
{
int ret = _SUCCESS;
const struct firmware *fw;
const char *fw_name = FW_RTL8188EU;
int err = request_firmware(&fw, fw_name, device);
if (err) {
pr_err("Request firmware failed with error 0x%x\n", err);
ret = _FAIL;
goto exit;
}
if (!fw) {
pr_err("Firmware %s not available\n", fw_name);
ret = _FAIL;
goto exit;
}
rtfw->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!rtfw->data) {
pr_err("Failed to allocate rtfw->data\n");
ret = _FAIL;
goto exit;
}
rtfw->size = fw->size;
exit:
release_firmware(fw);
return ret;
}
int rtl8188e_firmware_download(struct adapter *padapter)
{
int ret = _SUCCESS;
u8 reg;
unsigned long fwdl_timeout;
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
struct device *device = dvobj_to_dev(dvobj);
struct rt_firmware_hdr *fwhdr = NULL;
u8 *fw_data;
u32 fw_size;
if (!dvobj->firmware.data)
ret = load_firmware(&dvobj->firmware, device);
if (ret == _FAIL) {
dvobj->firmware.data = NULL;
goto exit;
}
fw_data = dvobj->firmware.data;
fw_size = dvobj->firmware.size;
fwhdr = (struct rt_firmware_hdr *)dvobj->firmware.data;
if (IS_FW_HEADER_EXIST(fwhdr)) {
dev_info_once(device, "Firmware Version %d, SubVersion %d, Signature 0x%x\n",
le16_to_cpu(fwhdr->version), fwhdr->subversion,
le16_to_cpu(fwhdr->signature));
fw_data = fw_data + sizeof(struct rt_firmware_hdr);
fw_size = fw_size - sizeof(struct rt_firmware_hdr);
}
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
ret = rtw_read8(padapter, REG_MCUFWDL, &reg);
if (ret) {
ret = _FAIL;
goto exit;
}
if (reg & RAM_DL_SEL) { /* 8051 RAM code */
rtw_write8(padapter, REG_MCUFWDL, 0x00);
rtw_reset_8051(padapter);
}
fw_download_enable(padapter, true);
fwdl_timeout = jiffies + msecs_to_jiffies(500);
do {
/* reset the FWDL chksum */
ret = rtw_read8(padapter, REG_MCUFWDL, &reg);
if (ret) {
ret = _FAIL;
continue;
}
rtw_write8(padapter, REG_MCUFWDL, reg | FWDL_CHKSUM_RPT);
ret = write_fw(padapter, fw_data, fw_size);
if (ret == _SUCCESS)
break;
} while (!time_after(jiffies, fwdl_timeout));
fw_download_enable(padapter, false);
if (ret != _SUCCESS)
goto exit;
ret = fw_free_to_go(padapter);
if (ret != _SUCCESS)
goto exit;
exit:
return ret;
}
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include "../include/rtw_iol.h"
struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter)
{
struct xmit_frame *xmit_frame;
struct xmit_buf *xmitbuf;
struct pkt_attrib *pattrib;
struct xmit_priv *pxmitpriv = &adapter->xmitpriv;
xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
if (!xmit_frame)
return NULL;
xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
if (!xmitbuf) {
rtw_free_xmitframe(pxmitpriv, xmit_frame);
return NULL;
}
xmit_frame->frame_tag = MGNT_FRAMETAG;
xmit_frame->pxmitbuf = xmitbuf;
xmit_frame->buf_addr = xmitbuf->pbuf;
xmitbuf->priv_data = xmit_frame;
pattrib = &xmit_frame->attrib;
update_mgntframe_attrib(adapter, pattrib);
pattrib->qsel = 0x10;/* Beacon */
pattrib->subtype = WIFI_BEACON;
pattrib->pktlen = 0;
pattrib->last_txcmdsz = 0;
return xmit_frame;
}
int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
{
struct pkt_attrib *pattrib = &xmit_frame->attrib;
u16 buf_offset;
u32 ori_len;
buf_offset = TXDESC_OFFSET;
ori_len = buf_offset + pattrib->pktlen;
/* check if the io_buf can accommodate new cmds */
if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ)
return _FAIL;
memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
pattrib->pktlen += cmd_len;
pattrib->last_txcmdsz += cmd_len;
return _SUCCESS;
}
bool rtw_IOL_applied(struct adapter *adapter)
{
if (adapter->registrypriv.fw_iol == 1)
return true;
if ((adapter->registrypriv.fw_iol == 2) &&
(adapter_to_dvobj(adapter)->pusbdev->speed != USB_SPEED_HIGH))
return true;
return false;
}
int rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFF) {
cmd.length = 12;
cmd.mask = cpu_to_le32(mask);
}
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFFFF) {
cmd.length = 12;
cmd.mask = cpu_to_le32(mask);
}
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16(addr);
cmd.data = cpu_to_le32(value);
if (mask != 0xFFFFFFFF) {
cmd.length = 12;
cmd.mask = cpu_to_le32(mask);
}
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF));
cmd.data = cpu_to_le32(value);
if (mask != 0x000FFFFF) {
cmd.length = 12;
cmd.mask = cpu_to_le32(mask);
}
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16(us);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16(ms);
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
{
struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0};
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
}
u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
{
u8 is_cmd_bndy = false;
if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
rtw_IOL_append_END_cmd(pxmit_frame);
pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
is_cmd_bndy = true;
}
return is_cmd_bndy;
}
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2012 Realtek Corporation. */
#include "../include/drv_types.h"
#include "../include/rtw_led.h"
#include "../include/rtl8188e_spec.h"
#define LED_BLINK_NO_LINK_INTVL msecs_to_jiffies(1000)
#define LED_BLINK_LINK_INTVL msecs_to_jiffies(500)
#define LED_BLINK_SCAN_INTVL msecs_to_jiffies(180)
#define LED_BLINK_FASTER_INTVL msecs_to_jiffies(50)
#define LED_BLINK_WPS_SUCESS_INTVL msecs_to_jiffies(5000)
#define IS_LED_WPS_BLINKING(l) \
((l)->CurrLedState == LED_BLINK_WPS || \
(l)->CurrLedState == LED_BLINK_WPS_STOP || \
(l)->bLedWPSBlinkInProgress)
static void ResetLedStatus(struct led_priv *pLed)
{
pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */
pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */
pLed->bLedBlinkInProgress = false; /* true if it is blinking, false o.w.. */
pLed->bLedWPSBlinkInProgress = false;
pLed->BlinkTimes = 0; /* Number of times to toggle led state for blinking. */
pLed->bLedScanBlinkInProgress = false;
}
static void SwLedOn(struct led_priv *pLed)
{
struct adapter *padapter = container_of(pLed, struct adapter, ledpriv);
if (padapter->bDriverStopped)
return;
if (rtw_write8(padapter, REG_LEDCFG2, BIT(5)) != _SUCCESS)
return;
pLed->bLedOn = true;
}
static void SwLedOff(struct led_priv *pLed)
{
struct adapter *padapter = container_of(pLed, struct adapter, ledpriv);
if (padapter->bDriverStopped)
return;
if (rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3)) != _SUCCESS)
return;
pLed->bLedOn = false;
}
static void blink_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct led_priv *pLed = container_of(dwork, struct led_priv, blink_work);
struct adapter *padapter = container_of(pLed, struct adapter, ledpriv);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
SwLedOff(pLed);
ResetLedStatus(pLed);
return;
}
if (pLed->bLedOn)
SwLedOff(pLed);
else
SwLedOn(pLed);
switch (pLed->CurrLedState) {
case LED_BLINK_SLOWLY:
schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
break;
case LED_BLINK_NORMAL:
schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
break;
case LED_BLINK_SCAN:
case LED_BLINK_TXRX:
pLed->BlinkTimes--;
if (pLed->BlinkTimes == 0) {
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
pLed->CurrLedState = LED_BLINK_NORMAL;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
} else {
pLed->CurrLedState = LED_BLINK_SLOWLY;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
}
pLed->bLedBlinkInProgress = false;
pLed->bLedScanBlinkInProgress = false;
} else {
schedule_delayed_work(&pLed->blink_work,
pLed->CurrLedState == LED_BLINK_SCAN ?
LED_BLINK_SCAN_INTVL : LED_BLINK_FASTER_INTVL);
}
break;
case LED_BLINK_WPS:
schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
break;
case LED_BLINK_WPS_STOP: /* WPS success */
if (!pLed->bLedOn) {
pLed->CurrLedState = LED_BLINK_NORMAL;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
pLed->bLedWPSBlinkInProgress = false;
} else {
schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL);
}
break;
default:
break;
}
}
void rtl8188eu_InitSwLeds(struct adapter *padapter)
{
struct led_priv *pledpriv = &padapter->ledpriv;
ResetLedStatus(pledpriv);
INIT_DELAYED_WORK(&pledpriv->blink_work, blink_work);
}
void rtl8188eu_DeInitSwLeds(struct adapter *padapter)
{
struct led_priv *ledpriv = &padapter->ledpriv;
cancel_delayed_work_sync(&ledpriv->blink_work);
ResetLedStatus(ledpriv);
SwLedOff(ledpriv);
}
void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction)
{
struct led_priv *pLed = &padapter->ledpriv;
struct registry_priv *registry_par;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
if (!padapter->hw_init_completed)
return;
if (!pLed->bRegUseLed)
return;
registry_par = &padapter->registrypriv;
if (!registry_par->led_enable)
return;
switch (LedAction) {
case LED_CTL_START_TO_LINK:
case LED_CTL_NO_LINK:
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
cancel_delayed_work(&pLed->blink_work);
pLed->bLedBlinkInProgress = false;
pLed->CurrLedState = LED_BLINK_SLOWLY;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
break;
case LED_CTL_LINK:
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
cancel_delayed_work(&pLed->blink_work);
pLed->bLedBlinkInProgress = false;
pLed->CurrLedState = LED_BLINK_NORMAL;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL);
break;
case LED_CTL_SITE_SURVEY:
if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)))
return;
if (pLed->bLedScanBlinkInProgress)
return;
if (IS_LED_WPS_BLINKING(pLed))
return;
cancel_delayed_work(&pLed->blink_work);
pLed->bLedBlinkInProgress = false;
pLed->bLedScanBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SCAN;
pLed->BlinkTimes = 24;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
break;
case LED_CTL_TX:
case LED_CTL_RX:
if (pLed->bLedBlinkInProgress)
return;
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
cancel_delayed_work(&pLed->blink_work);
pLed->bLedBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_TXRX;
pLed->BlinkTimes = 2;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL);
break;
case LED_CTL_START_WPS: /* wait until xinpin finish */
if (pLed->bLedWPSBlinkInProgress)
return;
cancel_delayed_work(&pLed->blink_work);
pLed->bLedBlinkInProgress = false;
pLed->bLedScanBlinkInProgress = false;
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL);
break;
case LED_CTL_STOP_WPS:
cancel_delayed_work(&pLed->blink_work);
pLed->bLedBlinkInProgress = false;
pLed->bLedScanBlinkInProgress = false;
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS_STOP;
if (pLed->bLedOn) {
schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL);
} else {
schedule_delayed_work(&pLed->blink_work, 0);
}
break;
case LED_CTL_STOP_WPS_FAIL:
cancel_delayed_work(&pLed->blink_work);
pLed->bLedWPSBlinkInProgress = false;
pLed->CurrLedState = LED_BLINK_SLOWLY;
schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL);
break;
case LED_CTL_POWER_OFF:
pLed->CurrLedState = RTW_LED_OFF;
pLed->bLedBlinkInProgress = false;
pLed->bLedWPSBlinkInProgress = false;
pLed->bLedScanBlinkInProgress = false;
cancel_delayed_work(&pLed->blink_work);
SwLedOff(pLed);
break;
default:
break;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include "../include/drv_types.h"
static const u32 ch_freq_map[] = {
2412,
2417,
2422,
2427,
2432,
2437,
2442,
2447,
2452,
2457,
2462,
2467,
2472,
2484
};
u32 rtw_ch2freq(u32 channel)
{
if (channel == 0 || channel > ARRAY_SIZE(ch_freq_map))
return 2412;
return ch_freq_map[channel - 1];
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include "../include/HalPwrSeqCmd.h"
#define PWR_CMD_WRITE 0x01
/* offset: the read register offset */
/* msk: the mask of the write bits */
/* value: write value */
/* note: driver shall implement this cmd by read & msk after write */
#define PWR_CMD_POLLING 0x02
/* offset: the read register offset */
/* msk: the mask of the polled value */
/* value: the value to be polled, masked by the msd field. */
/* note: driver shall implement this cmd by */
/* do{ */
/* if ( (Read(offset) & msk) == (value & msk) ) */
/* break; */
/* } while (not timeout); */
#define PWR_CMD_DELAY 0x03
/* offset: the value to delay (in us) */
/* msk: N/A */
/* value: N/A */
struct wl_pwr_cfg {
u16 offset;
u8 cmd:4;
u8 msk;
u8 value;
};
#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
static struct wl_pwr_cfg rtl8188E_power_on_flow[] = {
{ 0x0006, PWR_CMD_POLLING, BIT(1), BIT(1) },
{ 0x0002, PWR_CMD_WRITE, BIT(0) | BIT(1), 0 }, /* reset BB */
{ 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
{ 0x0005, PWR_CMD_WRITE, BIT(7), 0 }, /* disable HWPDN (control by DRV)*/
{ 0x0005, PWR_CMD_WRITE, BIT(4) | BIT(3), 0 }, /* disable WL suspend*/
{ 0x0005, PWR_CMD_WRITE, BIT(0), BIT(0) },
{ 0x0005, PWR_CMD_POLLING, BIT(0), 0 },
{ 0x0023, PWR_CMD_WRITE, BIT(4), 0 },
};
static struct wl_pwr_cfg rtl8188E_card_disable_flow[] = {
{ 0x001F, PWR_CMD_WRITE, 0xFF, 0 }, /* turn off RF */
{ 0x0023, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* LDO Sleep mode */
{ 0x0005, PWR_CMD_WRITE, BIT(1), BIT(1) }, /* turn off MAC by HW state machine */
{ 0x0005, PWR_CMD_POLLING, BIT(1), 0 },
{ 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
{ 0x0005, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) }, /* enable WL suspend */
{ 0x0007, PWR_CMD_WRITE, 0xFF, 0 }, /* enable bandgap mbias in suspend */
{ 0x0041, PWR_CMD_WRITE, BIT(4), 0 }, /* Clear SIC_EN register */
{ 0xfe10, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* Set USB suspend enable local register */
};
/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */
static struct wl_pwr_cfg rtl8188E_enter_lps_flow[] = {
{ 0x0522, PWR_CMD_WRITE, 0xFF, 0x7F },/* Tx Pause */
{ 0x05F8, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
{ 0x05F9, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
{ 0x05FA, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
{ 0x05FB, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
{ 0x0002, PWR_CMD_WRITE, BIT(0), 0 }, /* CCK and OFDM are disabled, clocks are gated */
{ 0x0002, PWR_CMD_DELAY, 0, 0 },
{ 0x0100, PWR_CMD_WRITE, 0xFF, 0x3F }, /* Reset MAC TRX */
{ 0x0101, PWR_CMD_WRITE, BIT(1), 0 }, /* check if removed later */
{ 0x0553, PWR_CMD_WRITE, BIT(5), BIT(5) }, /* Respond TxOK to scheduler */
};
u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq)
{
struct wl_pwr_cfg pwrcfgcmd = {0};
struct wl_pwr_cfg *pwrseqcmd;
u8 poll_bit = false;
u8 idx, num_steps;
u8 value = 0;
u32 offset = 0;
u32 poll_count = 0; /* polling autoload done. */
u32 max_poll_count = 5000;
int res;
switch (seq) {
case PWR_ON_FLOW:
pwrseqcmd = rtl8188E_power_on_flow;
num_steps = ARRAY_SIZE(rtl8188E_power_on_flow);
break;
case DISABLE_FLOW:
pwrseqcmd = rtl8188E_card_disable_flow;
num_steps = ARRAY_SIZE(rtl8188E_card_disable_flow);
break;
case LPS_ENTER_FLOW:
pwrseqcmd = rtl8188E_enter_lps_flow;
num_steps = ARRAY_SIZE(rtl8188E_enter_lps_flow);
break;
default:
return false;
}
for (idx = 0; idx < num_steps; idx++) {
pwrcfgcmd = pwrseqcmd[idx];
switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
case PWR_CMD_WRITE:
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
/* Read the value from system register */
res = rtw_read8(padapter, offset, &value);
if (res)
return false;
value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
/* Write the value back to system register */
rtw_write8(padapter, offset, value);
break;
case PWR_CMD_POLLING:
poll_bit = false;
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
do {
res = rtw_read8(padapter, offset, &value);
if (res)
return false;
value &= GET_PWR_CFG_MASK(pwrcfgcmd);
if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
poll_bit = true;
else
udelay(10);
if (poll_count++ > max_poll_count)
return false;
} while (!poll_bit);
break;
case PWR_CMD_DELAY:
udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
break;
default:
break;
}
}
return true;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#ifndef __INC_BB_8188E_HW_IMG_H
#define __INC_BB_8188E_HW_IMG_H
/* static bool CheckCondition(const u32 Condition, const u32 Hex); */
/******************************************************************************
* AGC_TAB_1T.TXT
******************************************************************************/
int ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *odm);
/******************************************************************************
* PHY_REG_1T.TXT
******************************************************************************/
int ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *odm);
/******************************************************************************
* PHY_REG_PG.TXT
******************************************************************************/
void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm);
#endif
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#ifndef __INC_MAC_8188E_HW_IMG_H
#define __INC_MAC_8188E_HW_IMG_H
/******************************************************************************
* MAC_REG.TXT
******************************************************************************/
int ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *pDM_Odm);
#endif /* end of HWIMG_SUPPORT */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment