RTL88x2B Driver from Realtek. Version: 5.3.1

This commit is contained in:
Rin Cat
2018-11-23 15:19:44 -05:00
commit 95374e485a
599 changed files with 660947 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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.
*
*****************************************************************************/
#ifndef _RTL8822BU_H_
#define _RTL8822BU_H_
#include <drv_types.h> /* PADAPTER, basic_types.h, rtw_xmit.h and etc. */
#define USB_AGG_EN_8822B BIT(7)
#ifdef CONFIG_LPS_LCLK
/* for CONFIG_LPS_LCLK setting in rtl8822bu_ops.c */
#define REG_USB_HRPWM_8822B 0xFE58
#define REG_USB_HCPWM_8822B 0xFE57
#endif /* CONFIG_LPS_LCLK */
/* rtl8822bu_halinit.c */
u32 rtl8822bu_init(PADAPTER);
u32 rtl8822bu_deinit(PADAPTER);
u32 rtl8822bu_inirp_init(PADAPTER);
u32 rtl8822bu_inirp_deinit(PADAPTER);
void rtl8822bu_interface_configure(PADAPTER);
/* rtl8822bu_halmac.c */
int rtl8822bu_halmac_init_adapter(PADAPTER);
/* rtl8822bu_io.c */
#ifdef CONFIG_RTW_SW_LED
/* rtl8822bu_led.c */
void rtl8822bu_initswleds(PADAPTER);
void rtl8822bu_deinitswleds(PADAPTER);
#endif
/* rtl8822bu_xmit.c */
#define OFFSET_SZ 0
#define MAX_TX_AGG_PACKET_NUMBER_8822B 0xff
s32 rtl8822bu_init_xmit_priv(PADAPTER);
void rtl8822bu_free_xmit_priv(PADAPTER);
s32 rtl8822bu_mgnt_xmit(PADAPTER, struct xmit_frame *);
s32 rtl8822bu_hal_xmit(PADAPTER, struct xmit_frame *);
s32 rtl8822bu_hal_xmitframe_enqueue(PADAPTER, struct xmit_frame *);
s32 rtl8822bu_hostap_mgnt_xmit_entry(PADAPTER, _pkt *);
#ifdef CONFIG_XMIT_THREAD_MODE
s32 rtl8822bu_xmit_buf_handler(PADAPTER);
#endif /* CONFIG_XMIT_THREAD_MODE */
/* rtl8822bu_recv.c */
int rtl8822bu_init_recv_priv(PADAPTER);
void rtl8822bu_free_recv_priv(PADAPTER);
#endif /* _RTL8822BU_H_ */

View File

@@ -0,0 +1,436 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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 _RTL8822BU_HALINIT_C_
#include <hal_data.h> /* HAL DATA */
#include "../../hal_halmac.h" /* HALMAC API */
#include "../rtl8822b.h" /* rtl8822b hal common define */
#include "rtl8822bu.h"
#ifndef CONFIG_USB_HCI
#error "CONFIG_USB_HCI shall be on!\n"
#endif
static void _dbg_dump_macreg(PADAPTER padapter)
{
u32 offset = 0;
u32 val32 = 0;
u32 index = 0;
for (index = 0; index < 64; index++) {
offset = index * 4;
val32 = rtw_read32(padapter, offset);
RTW_INFO("offset : 0x%02x ,val:0x%08x\n", offset, val32);
}
}
#ifdef CONFIG_FWLPS_IN_IPS
u8 rtl8822bu_fw_ips_init(_adapter *padapter)
{
struct sreset_priv *psrtpriv = &GET_HAL_DATA(padapter)->srestpriv;
struct debug_priv *pdbgpriv = &adapter_to_dvobj(padapter)->drv_dbg;
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
if (pwrctl->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE
&& GET_HAL_DATA(padapter)->bFWReady == _TRUE && pwrctl->pre_ips_type == 0) {
systime start_time;
u8 cpwm_orig, cpwm_now, rpwm;
u8 bMacPwrCtrlOn = _TRUE;
RTW_INFO("%s: Leaving FW_IPS\n", __func__);
#ifdef CONFIG_LPS_LCLK
/* for polling cpwm */
cpwm_orig = 0;
rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
/* set rpwm */
rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &rpwm);
rpwm += 0x80;
rpwm |= PS_ACK;
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
RTW_INFO("%s: write rpwm=%02x\n", __func__, rpwm);
pwrctl->tog = (rpwm + 0x80) & 0x80;
/* do polling cpwm */
start_time = rtw_get_current_time();
do {
rtw_mdelay_os(1);
rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
if ((cpwm_orig ^ cpwm_now) & 0x80) {
#ifdef DBG_CHECK_FW_PS_STATE
RTW_INFO("%s: polling cpwm ok when leaving IPS in FWLPS state, cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x\n"
, __func__, cpwm_orig, cpwm_now, rtw_read8(padapter, REG_CR));
#endif /* DBG_CHECK_FW_PS_STATE */
break;
}
if (rtw_get_passing_time_ms(start_time) > 100) {
RTW_INFO("%s: polling cpwm timeout when leaving IPS in FWLPS state, cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x\n",
__func__, cpwm_orig, cpwm_now, rtw_read8(padapter, REG_CR));
break;
}
} while (1);
#endif /* CONFIG_LPS_LCLK */
rtl8822b_set_FwPwrModeInIPS_cmd(padapter, 0);
rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
#ifdef CONFIG_LPS_LCLK
#ifdef DBG_CHECK_FW_PS_STATE
if (rtw_fw_ps_state(padapter) == _FAIL) {
RTW_INFO("after hal init, fw ps state in 32k\n");
pdbgpriv->dbg_ips_drvopen_fail_cnt++;
}
#endif /* DBG_CHECK_FW_PS_STATE */
#endif /* CONFIG_LPS_LCLK */
return _SUCCESS;
}
return _FAIL;
}
u8 rtl8822bu_fw_ips_deinit(_adapter *padapter)
{
struct sreset_priv *psrtpriv = &GET_HAL_DATA(padapter)->srestpriv;
struct debug_priv *pdbgpriv = &adapter_to_dvobj(padapter)->drv_dbg;
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
if (pwrctl->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE
&& GET_HAL_DATA(padapter)->bFWReady == _TRUE && padapter->netif_up == _TRUE) {
int cnt = 0;
u8 val8 = 0, rpwm;
RTW_INFO("%s: issue H2C to FW when entering IPS\n", __func__);
rtl8822b_set_FwPwrModeInIPS_cmd(padapter, 0x1);
#ifdef CONFIG_LPS_LCLK
/* poll 0x1cc to make sure H2C command already finished by FW; MAC_0x1cc=0 means H2C done by FW. */
do {
val8 = rtw_read8(padapter, REG_HMETFR);
cnt++;
RTW_INFO("%s polling REG_HMETFR=0x%x, cnt=%d\n", __func__, val8, cnt);
rtw_mdelay_os(10);
} while (cnt < 100 && (val8 != 0));
/* H2C done, enter 32k */
if (val8 == 0) {
/* set rpwm to enter 32k */
rtw_hal_get_hwreg(padapter, HW_VAR_RPWM_TOG, &rpwm);
rpwm += 0x80;
rpwm |= BIT_SYS_CLK_8822B;
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
RTW_INFO("%s: write rpwm=%02x\n", __func__, rpwm);
pwrctl->tog = (val8 + 0x80) & 0x80;
cnt = val8 = 0;
do {
val8 = rtw_read8(padapter, REG_CR);
cnt++;
RTW_INFO("%s polling 0x100=0x%x, cnt=%d\n", __func__, val8, cnt);
rtw_mdelay_os(10);
} while (cnt < 100 && (val8 != 0xEA));
#ifdef DBG_CHECK_FW_PS_STATE
if (val8 != 0xEA)
RTW_INFO("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n"
, rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, REG_HMETFR));
#endif /* DBG_CHECK_FW_PS_STATE */
} else {
RTW_INFO("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n"
, rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
, rtw_read32(padapter, 0x1c8), rtw_read32(padapter, REG_HMETFR));
}
RTW_INFO("polling done when entering IPS, check result : 0x100=0x%x, cnt=%d, MAC_1cc=0x%02x\n"
, rtw_read8(padapter, REG_CR), cnt, rtw_read8(padapter, REG_HMETFR));
pwrctl->pre_ips_type = 0;
#endif /* CONFIG_LPS_LCLK */
return _SUCCESS;
}
pdbgpriv->dbg_carddisable_cnt++;
pwrctl->pre_ips_type = 1;
return _FAIL;
}
#endif
static void init_hwled(PADAPTER adapter, u8 enable)
{
u8 mode = 0;
struct led_priv *ledpriv = adapter_to_led(adapter);
if (ledpriv->LedStrategy != HW_LED)
return;
rtw_halmac_led_cfg(adapter_to_dvobj(adapter), enable, mode);
}
static void hal_init_misc(PADAPTER adapter)
{
#ifdef CONFIG_RTW_LED
init_hwled(adapter, 1);
#endif /* CONFIG_RTW_LED */
}
u32 rtl8822bu_init(PADAPTER padapter)
{
u8 status = _SUCCESS;
systime init_start_time = rtw_get_current_time();
#ifdef CONFIG_FWLPS_IN_IPS
if (_SUCCESS == rtl8822bu_fw_ips_init(padapter))
goto exit;
#endif
rtl8822b_init(padapter);
hal_init_misc(padapter);
exit:
RTW_INFO("%s in %dms\n", __func__, rtw_get_passing_time_ms(init_start_time));
return status;
}
static void hal_deinit_misc(PADAPTER adapter)
{
#ifdef CONFIG_RTW_LED
init_hwled(adapter, 0);
#endif /* CONFIG_RTW_LED */
}
u32 rtl8822bu_deinit(PADAPTER padapter)
{
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct dvobj_priv *pobj_priv = adapter_to_dvobj(padapter);
u8 status = _TRUE;
RTW_INFO("==> %s\n", __func__);
#ifdef CONFIG_FWLPS_IN_IPS
if (_SUCCESS == rtl8822bu_fw_ips_deinit(padapter))
goto exit;
#endif
hal_deinit_misc(padapter);
status = rtl8822b_deinit(padapter);
if (status == _FALSE) {
RTW_INFO("%s: rtl8822b_hal_deinit fail\n", __func__);
return _FAIL;
}
exit:
RTW_INFO("%s <==\n", __func__);
return _SUCCESS;
}
u32 rtl8822bu_inirp_init(PADAPTER padapter)
{
u8 i, status;
struct recv_buf *precvbuf;
struct dvobj_priv *pdev = adapter_to_dvobj(padapter);
struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
struct recv_priv *precvpriv = &(padapter->recvpriv);
u32(*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u32(*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr);
#endif
#ifdef CONFIG_FWLPS_IN_IPS
/* Do not sumbit urb repeat */
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
if (pwrctl->bips_processing == _TRUE) {
status = _SUCCESS;
goto exit;
}
#endif /* CONFIG_FWLPS_IN_IPS */
_read_port = pintfhdl->io_ops._read_port;
status = _SUCCESS;
precvpriv->ff_hwaddr = RECV_BULK_IN_ADDR;
/* issue Rx irp to receive data */
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF; i++) {
if (_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (u8 *)precvbuf) == _FALSE) {
status = _FAIL;
goto exit;
}
precvbuf++;
precvpriv->free_recv_buf_queue_cnt--;
}
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
if (pdev->RtInPipe[REALTEK_USB_IN_INT_EP_IDX] != 0x05) {
status = _FAIL;
RTW_INFO("%s =>Warning !! Have not USB Int-IN pipe, RtIntInPipe(%d)!!!\n", __func__, pdev->RtInPipe[REALTEK_USB_IN_INT_EP_IDX]);
goto exit;
}
_read_interrupt = pintfhdl->io_ops._read_interrupt;
if (_read_interrupt(pintfhdl, RECV_INT_IN_ADDR) == _FALSE) {
status = _FAIL;
}
#endif
exit:
return status;
}
u32 rtl8822bu_inirp_deinit(PADAPTER padapter)
{
rtw_read_port_cancel(padapter);
return _SUCCESS;
}
void rtl8822bu_update_interrupt_mask(PADAPTER padapter, u8 bHIMR0 , u32 AddMSR, u32 RemoveMSR)
{
HAL_DATA_TYPE *pHalData;
u32 *himr;
pHalData = GET_HAL_DATA(padapter);
if (bHIMR0)
himr = &(pHalData->IntrMask[0]);
else
himr = &(pHalData->IntrMask[1]);
if (AddMSR)
*himr |= AddMSR;
if (RemoveMSR)
*himr &= (~RemoveMSR);
if (bHIMR0)
rtw_write32(padapter, REG_HIMR0_8822B, *himr);
else
rtw_write32(padapter, REG_HIMR1_8822B, *himr);
}
static void config_chip_out_EP(PADAPTER padapter, u8 NumOutPipe)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->OutEpQueueSel = 0;
pHalData->OutEpNumber = 0;
switch (NumOutPipe) {
case 4:
pHalData->OutEpQueueSel = TX_SELE_HQ | TX_SELE_LQ | TX_SELE_NQ;
pHalData->OutEpNumber = 4;
break;
case 3:
pHalData->OutEpQueueSel = TX_SELE_HQ | TX_SELE_LQ | TX_SELE_NQ;
pHalData->OutEpNumber = 3;
break;
case 2:
pHalData->OutEpQueueSel = TX_SELE_HQ | TX_SELE_NQ;
pHalData->OutEpNumber = 2;
break;
case 1:
pHalData->OutEpQueueSel = TX_SELE_HQ;
pHalData->OutEpNumber = 1;
break;
default:
break;
}
RTW_INFO("%s OutEpQueueSel(0x%02x), OutEpNumber(%d)\n", __func__, pHalData->OutEpQueueSel, pHalData->OutEpNumber);
}
static u8 usb_set_queue_pipe_mapping(PADAPTER padapter, u8 NumInPipe, u8 NumOutPipe)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u8 result = _FALSE;
config_chip_out_EP(padapter, NumOutPipe);
/* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
if (1 == pHalData->OutEpNumber) {
if (1 != NumInPipe)
return result;
}
result = Hal_MappingOutPipe(padapter, NumOutPipe);
return result;
}
void rtl8822bu_interface_configure(PADAPTER padapter)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
if (IS_SUPER_SPEED_USB(padapter))
pHalData->UsbBulkOutSize = USB_SUPER_SPEED_BULK_SIZE;
else if (IS_HIGH_SPEED_USB(padapter))
pHalData->UsbBulkOutSize = USB_HIGH_SPEED_BULK_SIZE;
else
pHalData->UsbBulkOutSize = USB_FULL_SPEED_BULK_SIZE;
pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber;
#ifdef CONFIG_USB_TX_AGGREGATION
/* according to value defined by halmac */
pHalData->UsbTxAggMode = 1;
rtw_halmac_usb_get_txagg_desc_num(pdvobjpriv, &pHalData->UsbTxAggDescNum);
#endif /* CONFIG_USB_TX_AGGREGATION */
#ifdef CONFIG_USB_RX_AGGREGATION
/* according to value defined by halmac */
pHalData->rxagg_mode = RX_AGG_USB;
#ifdef CONFIG_PLATFORM_NOVATEK_NT72668
pHalData->rxagg_usb_size = 0x03;
pHalData->rxagg_usb_timeout = 0x20;
#elif defined(CONFIG_PLATFORM_HISILICON)
/* use 16k to workaround for HISILICON platform */
pHalData->rxagg_usb_size = 3;
pHalData->rxagg_usb_timeout = 8;
#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
#endif /* CONFIG_USB_RX_AGGREGATION */
usb_set_queue_pipe_mapping(padapter,
pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes);
}

View File

@@ -0,0 +1,320 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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 _RTL8822BU_HALMAC_C_
#include <drv_types.h> /* struct dvobj_priv and etc. */
#include "../../hal_halmac.h"
#include "../rtl8822b.h" /* rtl8822b_cal_txdesc_chksum() and etc. */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
#define usb_write_port_complete_not_xmitframe(purb, regs) usb_write_port_complete_not_xmitframe(purb)
#endif
static void usb_write_port_complete_not_xmitframe(struct urb *purb, struct pt_regs *regs)
{
if (purb->status == 0) {
;
} else {
RTW_INFO("###=> urb_write_port_complete status(%d)\n", purb->status);
if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) {
;
} else if (purb->status == -EINPROGRESS) {
goto check_completion;
} else if (purb->status == -ENOENT) {
RTW_INFO("%s: -ENOENT\n", __func__);
goto check_completion;
} else if (purb->status == -ECONNRESET) {
RTW_INFO("%s: -ECONNRESET\n", __func__);
goto check_completion;
} else if (purb->status == -ESHUTDOWN) {
RTW_INFO("%s: -ESHUTDOWN\n", __func__);
goto check_completion;
} else {
goto check_completion;
}
}
check_completion:
rtw_mfree(purb->transfer_buffer, purb->transfer_buffer_length);
usb_free_urb(purb);
}
static u32 usb_write_port_not_xmitframe(struct dvobj_priv *d, u8 addr, u32 cnt, u8 *wmem)
{
struct dvobj_priv *pobj = (struct dvobj_priv *)d;
PADAPTER padapter = dvobj_get_primary_adapter(pobj);
unsigned int pipe;
int status;
u32 ret = _FAIL, bwritezero = _FALSE;
PURB purb = NULL;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
struct usb_device *pusbd = pdvobj->pusbdev;
purb = usb_alloc_urb(0, GFP_KERNEL);
if (purb == NULL) {
RTW_ERR("purb == NULL\n");
return _FAIL;
}
/* translate DMA FIFO addr to pipehandle */
pipe = ffaddr2pipehdl(pdvobj, addr);
usb_fill_bulk_urb(purb, pusbd, pipe,
wmem,
cnt,
usb_write_port_complete_not_xmitframe,
padapter);
#ifdef USB_PACKET_OFFSET_SZ
#if (USB_PACKET_OFFSET_SZ == 0)
purb->transfer_flags |= URB_ZERO_PACKET;
#endif
#endif
#if 0
if (bwritezero)
purb->transfer_flags |= URB_ZERO_PACKET;
#endif
status = usb_submit_urb(purb, GFP_ATOMIC);
if (!status) {
#ifdef DBG_CONFIG_ERROR_DETECT
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.last_tx_time = rtw_get_current_time();
}
#endif
} else {
RTW_INFO("usb_write_port, status=%d\n", status);
switch (status) {
case -ENODEV:
break;
default:
break;
}
goto exit;
}
ret = _SUCCESS;
exit:
if (ret != _SUCCESS)
usb_free_urb(purb);
return ret;
}
static u8 usb_write_data_not_xmitframe(void *d, u8 *pBuf, u32 size, u8 qsel)
{
struct dvobj_priv *pobj = (struct dvobj_priv *)d;
PADAPTER padapter = dvobj_get_primary_adapter(pobj);
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u32 desclen, len;
u8 *buf;
u8 ret;
u8 addr;
u8 add_pkt_offset = 0;
desclen = rtl8822b_get_tx_desc_size(padapter);
len = desclen + size;
if (qsel == HALMAC_TXDESC_QSEL_BEACON) {
if (len % pHalData->UsbBulkOutSize == 0)
add_pkt_offset = 1;
if (add_pkt_offset == 1)
len = len + PACKET_OFFSET_SZ;
buf = rtw_zmalloc(len);
if (!buf)
return _FALSE;
if (add_pkt_offset == 1)
_rtw_memcpy(buf + desclen + PACKET_OFFSET_SZ , pBuf, size);
else
_rtw_memcpy(buf + desclen, pBuf, size);
SET_TX_DESC_TXPKTSIZE_8822B(buf, size);
if (add_pkt_offset == 1) {
SET_TX_DESC_OFFSET_8822B(buf, desclen + PACKET_OFFSET_SZ);
SET_TX_DESC_PKT_OFFSET_8822B(buf, 1);
} else
SET_TX_DESC_OFFSET_8822B(buf, desclen);
} else if (qsel == HALMAC_TXDESC_QSEL_H2C_CMD){
buf = rtw_zmalloc(len);
if (!buf)
return _FALSE;
_rtw_memcpy(buf + desclen, pBuf, size);
SET_TX_DESC_TXPKTSIZE_8822B(buf, size);
} else {
RTW_ERR("%s: qsel may be error(%d)\n", __func__, qsel);
return _FALSE;
}
SET_TX_DESC_QSEL_8822B(buf, qsel);
rtl8822b_cal_txdesc_chksum(padapter, buf);
addr = rtw_halmac_usb_get_bulkout_id(d, buf, len);
ret = usb_write_port_not_xmitframe(d, addr, len , buf);
if (_SUCCESS == ret) {
ret = _TRUE;
} else {
RTW_ERR("%s , rtl8822bu_simple_write_port fail\n", __func__);
rtw_mfree(buf , len);
ret = _FALSE;
}
return ret;
}
static u8 usb_write_data_rsvd_page_normal(void *d, u8 *pBuf, u32 size)
{
struct dvobj_priv *pobj = (struct dvobj_priv *)d;
PADAPTER padapter = dvobj_get_primary_adapter(pobj);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct xmit_frame *pcmdframe = NULL;
struct pkt_attrib *pattrib = NULL;
u8 txdesoffset = 0;
u8 *buf = NULL;
if (size + TXDESC_OFFSET > MAX_CMDBUF_SZ) {
RTW_INFO("%s: total buffer size(%d) > MAX_CMDSZE(%d)\n"
, __func__, size + TXDESC_OFFSET, MAX_CMDSZ);
return _FALSE;
}
pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
if (pcmdframe == NULL) {
RTW_INFO("%s: alloc cmd frame fail!\n", __func__);
return _FALSE;
}
txdesoffset = TXDESC_OFFSET;
buf = pcmdframe->buf_addr;
_rtw_memcpy((buf + txdesoffset), pBuf, size); /* shift desclen */
/* update attribute */
pattrib = &pcmdframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
pattrib->qsel = HALMAC_TXDESC_QSEL_BEACON;
pattrib->pktlen = size;
pattrib->last_txcmdsz = size;
/* fill tx desc in dump_mgntframe */
dump_mgntframe(padapter, pcmdframe);
return _TRUE;
}
static u8 usb_write_data_h2c_normal(void *d, u8 *pBuf, u32 size)
{
struct dvobj_priv *pobj = (struct dvobj_priv *)d;
PADAPTER padapter = dvobj_get_primary_adapter(pobj);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct xmit_frame *pcmdframe = NULL;
struct pkt_attrib *pattrib = NULL;
u8 txdesoffset = 0;
u8 *buf = NULL;
if (size + TXDESC_OFFSET > MAX_XMIT_EXTBUF_SZ) {
RTW_INFO("%s: total buffer size(%d) > MAX_XMIT_EXTBUF_SZ(%d)\n"
, __func__, size + TXDESC_OFFSET, MAX_XMIT_EXTBUF_SZ);
return _FALSE;
}
pcmdframe = alloc_mgtxmitframe(pxmitpriv);
if (pcmdframe == NULL) {
RTW_INFO("%s: alloc cmd frame fail!\n", __func__);
return _FALSE;
}
txdesoffset = TXDESC_SIZE;
buf = pcmdframe->buf_addr;
_rtw_memcpy(buf + txdesoffset, pBuf, size); /* shift desclen */
/* update attribute */
pattrib = &pcmdframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
pattrib->qsel = HALMAC_TXDESC_QSEL_H2C_CMD;
pattrib->pktlen = size;
pattrib->last_txcmdsz = size;
/* fill tx desc in dump_mgntframe */
dump_mgntframe(padapter, pcmdframe);
return _TRUE;
}
static u8 usb_write_data_rsvd_page(void *d, u8 *pBuf, u32 size)
{
struct dvobj_priv *pobj = (struct dvobj_priv *)d;
PADAPTER padapter = dvobj_get_primary_adapter(pobj);
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
if (pHalData->not_xmitframe_fw_dl)
return usb_write_data_not_xmitframe(d , pBuf , size, HALMAC_TXDESC_QSEL_BEACON);
else
return usb_write_data_rsvd_page_normal(d , pBuf , size);
}
static u8 usb_write_data_h2c(void *d, u8 *pBuf, u32 size)
{
struct dvobj_priv *pobj = (struct dvobj_priv *)d;
PADAPTER padapter = dvobj_get_primary_adapter(pobj);
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
if (pHalData->not_xmitframe_fw_dl)
return usb_write_data_not_xmitframe(d , pBuf , size, HALMAC_TXDESC_QSEL_H2C_CMD);
else
return usb_write_data_h2c_normal(d , pBuf , size);
}
int rtl8822bu_halmac_init_adapter(PADAPTER padapter)
{
struct dvobj_priv *d;
struct halmac_platform_api *api;
int err;
d = adapter_to_dvobj(padapter);
api = &rtw_halmac_platform_api;
api->SEND_RSVD_PAGE = usb_write_data_rsvd_page;
api->SEND_H2C_PKT = usb_write_data_h2c;
err = rtw_halmac_init_adapter(d, api);
return err;
}

View File

@@ -0,0 +1,51 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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 _RTL8822BU_IO_C_
#include <drv_types.h> /* PADAPTER and etc. */
void rtl8822bu_set_intf_ops(struct _io_ops *pops)
{
_rtw_memset((u8 *)pops, 0, sizeof(struct _io_ops));
pops->_read8 = &usb_read8;
pops->_read16 = &usb_read16;
pops->_read32 = &usb_read32;
pops->_read_mem = &usb_read_mem;
pops->_read_port = &usb_read_port;
pops->_write8 = &usb_write8;
pops->_write16 = &usb_write16;
pops->_write32 = &usb_write32;
pops->_writeN = &usb_writeN;
#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
pops->_write8_async = &usb_async_write8;
pops->_write16_async = &usb_async_write16;
pops->_write32_async = &usb_async_write32;
#endif
pops->_write_mem = &usb_write_mem;
pops->_write_port = &usb_write_port;
pops->_read_port_cancel = &usb_read_port_cancel;
pops->_write_port_cancel = &usb_write_port_cancel;
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
pops->_read_interrupt = &usb_read_interrupt;
#endif
}

View File

@@ -0,0 +1,142 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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 _RTL8822BU_LED_C_
#include <drv_types.h> /* PADAPTER */
#include <hal_data.h> /* PHAL_DATA_TYPE */
#include <hal_com_led.h> /* PLED_USB */
#include "../../hal_halmac.h" /* HALMAC API */
#ifdef CONFIG_RTW_SW_LED
/*
* =============================================================================
* LED object.
* =============================================================================
*/
/*
* =============================================================================
* Prototype of protected function.
* =============================================================================
*/
/*
* =============================================================================
* LED routines.
* =============================================================================
*/
/*
* Description:
* Turn on LED according to LedPin specified.
*/
static void swledon(PADAPTER padapter, PLED_USB led)
{
PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter);
if (RTW_CANNOT_RUN(padapter))
return;
switch (led->LedPin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
case LED_PIN_LED1:
case LED_PIN_LED2:
default:
rtw_halmac_led_switch(adapter_to_dvobj(padapter), 1);
break;
}
led->bLedOn = _TRUE;
}
/*
* Description:
* Turn off LED according to LedPin specified.
*/
static void swledoff(PADAPTER padapter, PLED_USB led)
{
PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter);
if (RTW_CANNOT_RUN(padapter))
return;
switch (led->LedPin) {
case LED_PIN_GPIO0:
break;
case LED_PIN_LED0:
case LED_PIN_LED1:
case LED_PIN_LED2:
default:
rtw_halmac_led_switch(adapter_to_dvobj(padapter), 0);
break;
}
led->bLedOn = _FALSE;
}
/*
* =============================================================================
* Interface to manipulate LED objects.
* =============================================================================
*/
/*
* =============================================================================
* Default LED behavior.
* =============================================================================
*/
/*
* Description:
* Initialize all LED_871x objects.
*/
void rtl8822bu_initswleds(PADAPTER padapter)
{
struct led_priv *ledpriv = adapter_to_led(padapter);
u8 enable = 1;
u8 mode = 3;
ledpriv->LedControlHandler = LedControlUSB;
ledpriv->SwLedOn = swledon;
ledpriv->SwLedOff = swledoff;
InitLed(padapter, &(ledpriv->SwLed0), LED_PIN_LED0);
InitLed(padapter, &(ledpriv->SwLed1), LED_PIN_LED1);
InitLed(padapter, &(ledpriv->SwLed2), LED_PIN_LED2);
rtw_halmac_led_cfg(adapter_to_dvobj(padapter), enable, mode);
}
/*
* Description:
* DeInitialize all LED_819xUsb objects.
*/
void rtl8822bu_deinitswleds(PADAPTER padapter)
{
struct led_priv *ledpriv = adapter_to_led(padapter);
u8 enable = 0;
u8 mode = 3;
DeInitLed(&(ledpriv->SwLed0));
DeInitLed(&(ledpriv->SwLed1));
DeInitLed(&(ledpriv->SwLed2));
rtw_halmac_led_cfg(adapter_to_dvobj(padapter), enable, mode);
}
#endif

View File

@@ -0,0 +1,355 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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 _RTL8822BU_OPS_C_
#include <drv_types.h> /* PADAPTER, basic_types.h and etc. */
#include <hal_intf.h> /* struct hal_ops */
#include <hal_data.h> /* HAL_DATA_TYPE */
#include "../../hal_halmac.h" /* register define */
#include "../rtl8822b.h" /* 8822b hal common define. rtl8822bu_init_default_value ...*/
#include "rtl8822bu.h" /* 8822bu functions */
#ifdef CONFIG_SUPPORT_USB_INT
static void rtl8822bu_interrupt_handler(PADAPTER padapter, u16 pkt_len, u8 *pbuf)
{
}
#endif /* CONFIG_SUPPORT_USB_INT */
void rtl8822bu_set_hw_type(struct dvobj_priv *pdvobj)
{
pdvobj->HardwareType = HARDWARE_TYPE_RTL8822BU;
RTW_INFO("CHIP TYPE: RTL8822B\n");
}
static u8 sethwreg(PADAPTER padapter, u8 variable, u8 *val)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
struct registry_priv *registry_par = &padapter->registrypriv;
int status = 0;
u8 ret = _SUCCESS;
switch (variable) {
case HW_VAR_RXDMA_AGG_PG_TH:
#ifdef CONFIG_USB_RX_AGGREGATION
if (pdvobjpriv->traffic_stat.cur_tx_tp < 1 && pdvobjpriv->traffic_stat.cur_rx_tp < 1) {
/* for low traffic, do not usb AGGREGATION */
pHalData->rxagg_usb_timeout = 0x01;
pHalData->rxagg_usb_size = 0x01;
} else {
#ifdef CONFIG_PLATFORM_NOVATEK_NT72668
pHalData->rxagg_usb_timeout = 0x20;
pHalData->rxagg_usb_size = 0x03;
#elif defined(CONFIG_PLATFORM_HISILICON)
/* use 16k to workaround for HISILICON platform */
pHalData->rxagg_usb_timeout = 8;
pHalData->rxagg_usb_size = 3;
#else
/* default setting */
pHalData->rxagg_usb_timeout = 0x20;
pHalData->rxagg_usb_size = 0x05;
#endif
}
rtw_halmac_rx_agg_switch(pdvobjpriv, _TRUE);
#if 0
RTW_INFO("\n==========RAFFIC_STATISTIC==============\n");
RTW_INFO("cur_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_tx_bytes);
RTW_INFO("cur_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_rx_bytes);
RTW_INFO("last_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_tx_bytes);
RTW_INFO("last_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_rx_bytes);
RTW_INFO("cur_tx_tp:%d\n", pdvobjpriv->traffic_stat.cur_tx_tp);
RTW_INFO("cur_rx_tp:%d\n", pdvobjpriv->traffic_stat.cur_rx_tp);
RTW_INFO("\n========================\n");
#endif
#endif
break;
case HW_VAR_SET_RPWM:
#ifdef CONFIG_LPS_LCLK
{
u8 ps_state = *((u8 *)val);
/*rpwm value only use BIT0(clock bit) ,BIT6(Ack bit), and BIT7(Toggle bit) for 88e.
BIT0 value - 1: 32k, 0:40MHz.
BIT6 value - 1: report cpwm value after success set, 0:do not report.
BIT7 value - Toggle bit change.
modify by Thomas. 2012/4/2.*/
ps_state = ps_state & 0xC1;
/* RTW_INFO("##### Change RPWM value to = %x for switch clk #####\n", ps_state); */
rtw_write8(padapter, REG_USB_HRPWM_8822B, ps_state);
}
#endif
break;
case HW_VAR_AMPDU_MAX_TIME:
rtw_write8(padapter, REG_AMPDU_MAX_TIME_V1_8822B, 0x70);
break;
case HW_VAR_USB_MODE:
/* U2 to U3 */
if (registry_par->switch_usb_mode == 1) {
if (IS_HIGH_SPEED_USB(padapter)) {
status = rtw_halmac_switch_usb_mode(adapter_to_dvobj(padapter), RTW_USB_SPEED_3);
if (status)
*val = _TRUE;
}
} else if (registry_par->switch_usb_mode == 2) {
/* U3 to U2 */
if (IS_SUPER_SPEED_USB(padapter)) {
status = rtw_halmac_switch_usb_mode(adapter_to_dvobj(padapter), RTW_USB_SPEED_2);
if (status)
*val = _TRUE;
}
}
break;
case HW_VAR_SET_REQ_FW_PS:
{
/*
* 1. driver write 0x8f[4]=1
* request fw ps state (only can write bit4)
*/
u8 req_fw_ps = 0;
req_fw_ps = rtw_read8(padapter, 0x8f);
req_fw_ps |= 0x10;
rtw_write8(padapter, 0x8f, req_fw_ps);
}
break;
default:
ret = rtl8822b_sethwreg(padapter, variable, val);
break;
}
return ret;
}
static void gethwreg(PADAPTER padapter, u8 variable, u8 *val)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
switch (variable) {
case HW_VAR_CPWM:
#ifdef CONFIG_LPS_LCLK
*val = rtw_read8(padapter, REG_USB_HCPWM_8822B);
/* RTW_INFO("##### REG_USB_HCPWM(0x%02x) = 0x%02x #####\n", REG_USB_HCPWM_8822B, *val); */
#endif /* CONFIG_LPS_LCLK */
break;
case HW_VAR_RPWM_TOG:
#ifdef CONFIG_LPS_LCLK
*val = rtw_read8(padapter, REG_USB_HRPWM_8822B);
*val &= BIT_TOGGLE_8822B;
#endif /* CONFIG_LPS_LCLK */
break;
case HW_VAR_FW_PS_STATE:
/* driver read dword 0x88 to get fw ps state */
*((u16 *)val) = rtw_read16(padapter, 0x88);
break;
default:
rtl8822b_gethwreg(padapter, variable, val);
break;
}
}
/*
Description:
Change default setting of specified variable.
*/
static u8 sethaldefvar(PADAPTER padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u8 bResult = _SUCCESS;
switch (eVariable) {
default:
rtl8822b_sethaldefvar(padapter, eVariable, pValue);
break;
}
return bResult;
}
/*
Description:
Query setting of specified variable.
*/
static u8 gethaldefvar(PADAPTER padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
u8 bResult = _SUCCESS;
switch (eVariable) {
case HW_VAR_MAX_RX_AMPDU_FACTOR:
*(HT_CAP_AMPDU_FACTOR *)pValue = MAX_AMPDU_FACTOR_64K;
break;
default:
bResult = rtl8822b_gethaldefvar(padapter, eVariable, pValue);
break;
}
return bResult;
}
static void rtl8822bu_init_default_value(PADAPTER padapter)
{
rtl8822b_init_default_value(padapter);
}
static u8 rtl8822bu_ps_func(PADAPTER padapter, HAL_INTF_PS_FUNC efunc_id, u8 *val)
{
u8 bResult = _TRUE;
switch (efunc_id) {
#if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED)
case HAL_USB_SELECT_SUSPEND:
break;
#endif /* CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED */
default:
break;
}
return bResult;
}
#ifdef CONFIG_RTW_LED
static void read_ledsetting(PADAPTER adapter)
{
struct led_priv *ledpriv = adapter_to_led(adapter);
#ifdef CONFIG_RTW_SW_LED
PHAL_DATA_TYPE hal;
hal = GET_HAL_DATA(adapter);
ledpriv->bRegUseLed = _TRUE;
switch (hal->EEPROMCustomerID) {
default:
hal->CustomerID = RT_CID_DEFAULT;
break;
}
switch (hal->CustomerID) {
case RT_CID_DEFAULT:
default:
ledpriv->LedStrategy = SW_LED_MODE9;
break;
}
#else /* HW LED */
ledpriv->LedStrategy = HW_LED;
#endif /* CONFIG_RTW_SW_LED */
}
#endif /* CONFIG_RTW_LED */
/*
* Description:
* Collect all hardware information, fill "HAL_DATA_TYPE".
* Sometimes this would be used to read MAC address.
* This function will do
* 1. Read Efuse/EEPROM to initialize
* 2. Read registers to initialize
* 3. Other vaiables initialization
*/
static u8 read_adapter_info(PADAPTER padapter)
{
u8 ret = _FAIL;
/*
* 1. Read Efuse/EEPROM to initialize
*/
if (rtl8822b_read_efuse(padapter) != _SUCCESS)
goto exit;
/*
* 2. Read registers to initialize
*/
/*
* 3. Other Initialization
*/
#ifdef CONFIG_RTW_LED
read_ledsetting(padapter);
#endif /* CONFIG_RTW_LED */
ret = _SUCCESS;
exit:
return ret;
}
void rtl8822bu_set_hal_ops(PADAPTER padapter)
{
struct hal_ops *ops;
int err;
err = rtl8822bu_halmac_init_adapter(padapter);
if (err) {
RTW_INFO("%s: [ERROR]HALMAC initialize FAIL!\n", __func__);
return;
}
rtl8822b_set_hal_ops(padapter);
ops = &padapter->hal_func;
ops->hal_init = rtl8822bu_init;
ops->hal_deinit = rtl8822bu_deinit;
ops->inirp_init = rtl8822bu_inirp_init;
ops->inirp_deinit = rtl8822bu_inirp_deinit;
ops->init_xmit_priv = rtl8822bu_init_xmit_priv;
ops->free_xmit_priv = rtl8822bu_free_xmit_priv;
ops->init_recv_priv = rtl8822bu_init_recv_priv;
ops->free_recv_priv = rtl8822bu_free_recv_priv;
#ifdef CONFIG_RTW_SW_LED
ops->InitSwLeds = rtl8822bu_initswleds;
ops->DeInitSwLeds = rtl8822bu_deinitswleds;
#endif
ops->init_default_value = rtl8822bu_init_default_value;
ops->intf_chip_configure = rtl8822bu_interface_configure;
ops->read_adapter_info = read_adapter_info;
ops->set_hw_reg_handler = sethwreg;
ops->GetHwRegHandler = gethwreg;
ops->get_hal_def_var_handler = gethaldefvar;
ops->SetHalDefVarHandler = sethaldefvar;
ops->hal_xmit = rtl8822bu_hal_xmit;
ops->mgnt_xmit = rtl8822bu_mgnt_xmit;
ops->hal_xmitframe_enqueue = rtl8822bu_hal_xmitframe_enqueue;
#ifdef CONFIG_HOSTAPD_MLME
ops->hostap_mgnt_xmit_entry = rtl8822bu_hostap_mgnt_xmit_entry;
#endif
ops->interface_ps_func = rtl8822bu_ps_func;
#ifdef CONFIG_XMIT_THREAD_MODE
ops->xmit_thread_handler = rtl8822bu_xmit_buf_handler;
#endif
#ifdef CONFIG_SUPPORT_USB_INT
ops->interrupt_handler = rtl8822bu_interrupt_handler;
#endif
}

View File

@@ -0,0 +1,171 @@
/******************************************************************************
*
* Copyright(c) 2015 - 2017 Realtek Corporation.
*
* 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 _RTL8822BU_RECV_C_
#include <drv_types.h> /* PADAPTER, rtw_xmit.h and etc. */
#include <hal_data.h> /* HAL_DATA_TYPE */
#include "../../hal_halmac.h" /* RX desc */
#include "../rtl8822b.h" /* rtl8822b_query_rx_desc, rtl8822b_c2h_handler_no_io() */
int rtl8822bu_init_recv_priv(PADAPTER padapter)
{
return usb_init_recv_priv(padapter, INTERRUPT_MSG_FORMAT_LEN);
}
void rtl8822bu_free_recv_priv(PADAPTER padapter)
{
usb_free_recv_priv(padapter, INTERRUPT_MSG_FORMAT_LEN);
}
static u8 recvbuf2recvframe_proccess_c2h(PADAPTER padapter, u8 *pbuf, s32 transfer_len)
{
u8 ret = _SUCCESS;
/* send rx desc + c2h content to halmac */
rtl8822b_c2h_handler_no_io(padapter, pbuf, transfer_len);
exit:
return ret;
}
static u8 recvbuf2recvframe_proccess_normal_rx
(PADAPTER padapter, u8 *pbuf, struct rx_pkt_attrib *pattrib, union recv_frame *precvframe, _pkt *pskb)
{
u8 ret = _SUCCESS;
struct recv_priv *precvpriv = &padapter->recvpriv;
_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
#ifdef CONFIG_RX_PACKET_APPEND_FCS
if (check_fwstate(&padapter->mlmepriv, WIFI_MONITOR_STATE) == _FALSE) {
if (rtl8822b_rx_fcs_appended(padapter))
pattrib->pkt_len -= IEEE80211_FCS_LEN;
}
#endif
if (rtw_os_alloc_recvframe(padapter, precvframe,
(pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), pskb) == _FAIL) {
rtw_free_recvframe(precvframe, pfree_recv_queue);
ret = _FAIL;
goto exit;
}
recvframe_put(precvframe, pattrib->pkt_len);
pre_recv_entry(precvframe, pattrib->physt ? (pbuf + RXDESC_OFFSET) : NULL);
exit:
return ret;
}
int recvbuf2recvframe(PADAPTER padapter, void *ptr)
{
u8 *pbuf;
u8 pkt_cnt = 0;
u32 pkt_offset;
s32 transfer_len;
u8 *pphy_status = NULL;
union recv_frame *precvframe = NULL;
struct rx_pkt_attrib *pattrib = NULL;
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct recv_priv *precvpriv = &padapter->recvpriv;
_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
_pkt *pskb;
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
pskb = NULL;
transfer_len = (s32)((struct recv_buf *)ptr)->transfer_len;
pbuf = ((struct recv_buf *)ptr)->pbuf;
#else /* !CONFIG_USE_USB_BUFFER_ALLOC_RX */
pskb = (_pkt *)ptr;
transfer_len = (s32)pskb->len;
pbuf = pskb->data;
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
#ifdef CONFIG_USB_RX_AGGREGATION
pkt_cnt = GET_RX_DESC_DMA_AGG_NUM_8822B(pbuf);
#endif
do {
precvframe = rtw_alloc_recvframe(pfree_recv_queue);
if (precvframe == NULL) {
RTW_INFO("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__);
goto _exit_recvbuf2recvframe;
}
_rtw_init_listhead(&precvframe->u.hdr.list);
precvframe->u.hdr.precvbuf = NULL; /* can't access the precvbuf for new arch */
precvframe->u.hdr.len = 0;
rtl8822b_query_rx_desc(precvframe, pbuf);
pattrib = &precvframe->u.hdr.attrib;
if ((padapter->registrypriv.mp_mode == 0) && ((pattrib->crc_err) || (pattrib->icv_err))) {
RTW_INFO("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err);
rtw_free_recvframe(precvframe, pfree_recv_queue);
goto _exit_recvbuf2recvframe;
}
pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
RTW_INFO("%s()-%d: RX Warning!,pkt_len<=0(%d) or pkt_offset(%d)> transfer_len(%d)\n"
, __func__, __LINE__, pattrib->pkt_len, pkt_offset, transfer_len);
if (pkt_offset > transfer_len)
RTW_INFO("%s()-%d: RX Warning!,RXDESC_SIZE(%d), drvinfo_sz(%d), shift_sz(%d),pkt_len(%d)\n"
, __func__, __LINE__, RXDESC_SIZE, pattrib->drvinfo_sz, pattrib->shift_sz, pattrib->pkt_len);
rtw_free_recvframe(precvframe, pfree_recv_queue);
goto _exit_recvbuf2recvframe;
}
switch (pattrib->pkt_rpt_type) {
case C2H_PACKET:
/* C2H_PACKET doesn't use recvframe, so free it */
rtw_free_recvframe(precvframe, pfree_recv_queue);
if (recvbuf2recvframe_proccess_c2h(padapter, pbuf, transfer_len) == _FAIL)
goto _exit_recvbuf2recvframe;
break;
case TX_REPORT1:
case TX_REPORT2:
case HIS_REPORT:
RTW_INFO("%s: [WARNNING] RX type(%d) not be handled!\n", __func__, pattrib->pkt_rpt_type);
rtw_free_recvframe(precvframe, pfree_recv_queue);
break;
case NORMAL_RX:
default:
if (recvbuf2recvframe_proccess_normal_rx(padapter, pbuf, pattrib, precvframe, pskb) == _FAIL)
goto _exit_recvbuf2recvframe;
break;
}
#ifdef CONFIG_USB_RX_AGGREGATION
/* jaguar 8-byte alignment */
pkt_offset = (u16)_RND8(pkt_offset);
pkt_cnt--;
pbuf += pkt_offset;
#endif
transfer_len -= pkt_offset;
precvframe = NULL;
} while (transfer_len > 0);
_exit_recvbuf2recvframe:
return _SUCCESS;
}

File diff suppressed because it is too large Load Diff