mirror of
https://github.com/morrownr/8821cu-20210916.git
synced 2024-12-23 06:42:50 +00:00
289 lines
7.2 KiB
C
289 lines
7.2 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2016 - 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 _RTL8821CU_HALINIT_C_
|
|
|
|
#include <hal_data.h> /* HAL DATA */
|
|
#include "../../hal_halmac.h" /* HALMAC API */
|
|
#include "../rtl8821c.h" /* rtl8821c hal common define */
|
|
#include "rtl8821cu.h"
|
|
|
|
#ifndef CONFIG_USB_HCI
|
|
|
|
#error "CONFIG_USB_HCI shall be on!\n"
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_RTW_LED
|
|
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);
|
|
}
|
|
#endif /* CONFIG_RTW_LED */
|
|
|
|
static void hal_init_misc(PADAPTER adapter)
|
|
{
|
|
#ifdef CONFIG_RTW_LED
|
|
struct led_priv *ledpriv = adapter_to_led(adapter);
|
|
|
|
init_hwled(adapter, 1);
|
|
#ifdef CONFIG_RTW_SW_LED
|
|
if (ledpriv->bRegUseLed == _TRUE)
|
|
rtw_halmac_led_cfg(adapter_to_dvobj(adapter), _TRUE, 3);
|
|
#endif
|
|
#endif /* CONFIG_RTW_LED */
|
|
|
|
}
|
|
|
|
u32 rtl8821cu_hal_init(PADAPTER padapter)
|
|
{
|
|
u8 status = _SUCCESS;
|
|
systime init_start_time = rtw_get_current_time();
|
|
|
|
if (_FALSE == rtl8821c_hal_init(padapter))
|
|
return _FAIL;
|
|
|
|
hal_init_misc(padapter);
|
|
|
|
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
|
|
struct led_priv *ledpriv = adapter_to_led(adapter);
|
|
|
|
init_hwled(adapter, 0);
|
|
#ifdef CONFIG_RTW_SW_LED
|
|
if (ledpriv->bRegUseLed == _TRUE)
|
|
rtw_halmac_led_cfg(adapter_to_dvobj(adapter), _FALSE, 3);
|
|
#endif
|
|
#endif /* CONFIG_RTW_LED */
|
|
}
|
|
|
|
u32 rtl8821cu_hal_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__);
|
|
|
|
|
|
hal_deinit_misc(padapter);
|
|
status = rtl8821c_hal_deinit(padapter);
|
|
if (status == _FALSE) {
|
|
RTW_INFO("%s: rtl8821c_hal_deinit fail\n", __func__);
|
|
return _FAIL;
|
|
}
|
|
|
|
RTW_INFO("%s <==\n", __func__);
|
|
return _SUCCESS;
|
|
}
|
|
|
|
|
|
u32 rtl8821cu_inirp_init(PADAPTER padapter)
|
|
{
|
|
struct registry_priv *regsty = adapter_to_regsty(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
|
|
|
|
|
|
_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 < regsty->recvbuf_nr; 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]); */
|
|
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 rtl8821cu_inirp_deinit(PADAPTER padapter)
|
|
{
|
|
struct recv_priv *precvpriv = &padapter->recvpriv;
|
|
_pkt *pskb;
|
|
|
|
rtw_read_port_cancel(padapter);
|
|
|
|
while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
|
|
skb_reset_tail_pointer(pskb);
|
|
pskb->len = 0;
|
|
skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
|
|
}
|
|
|
|
/* Clean pending recv buf */
|
|
while (rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue));
|
|
|
|
return _SUCCESS;
|
|
}
|
|
|
|
void rtl8821cu_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_8821C, *himr);
|
|
else
|
|
rtw_write32(padapter, REG_HIMR1_8821C, *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); */
|
|
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 rtl8821cu_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;
|
|
|
|
#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;
|
|
#if 0
|
|
pHalData->rxagg_usb_size = 8;
|
|
pHalData->rxagg_usb_timeout = 0x6;
|
|
pHalData->rxagg_dma_size = 16;
|
|
pHalData->rxagg_dma_timeout = 0x6;
|
|
#endif
|
|
#endif /* CONFIG_USB_RX_AGGREGATION */
|
|
|
|
usb_set_queue_pipe_mapping(padapter,
|
|
pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes);
|
|
}
|