1 /******************************************************************************
3 * Copyright(c) 2016 - 2017 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 *****************************************************************************/
16 #define _RTL8821CE_HALINIT_C_
17 #include <drv_types.h> /* PADAPTER, basic_types.h and etc. */
18 #include <hal_data.h> /* HAL_DATA_TYPE */
19 #include "../rtl8821c.h"
20 #include "rtl8821ce.h"
22 u32 InitMAC_TRXBD_8821CE(PADAPTER Adapter)
28 struct recv_priv *precvpriv = &Adapter->recvpriv;
29 struct xmit_priv *pxmitpriv = &Adapter->xmitpriv;
30 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
32 RTW_INFO("=======>InitMAC_TXBD_8821CE()\n");
35 * Set CMD TX BD (buffer descriptor) physical address(from OS API).
37 rtw_write32(Adapter, REG_H2CQ_TXBD_DESA_8821C,
38 (u64)pxmitpriv->tx_ring[TXCMD_QUEUE_INX].dma &
40 rtw_write32(Adapter, REG_H2CQ_TXBD_NUM_8821C,
41 TX_BD_NUM_8821CE_CMD | ((RTL8821CE_SEG_NUM << 12) &
44 #ifdef CONFIG_64BIT_DMA
45 rtw_write32(Adapter, REG_H2CQ_TXBD_DESA_8821C + 4,
46 ((u64)pxmitpriv->tx_ring[TXCMD_QUEUE_INX].dma) >> 32);
49 * Set TX/RX BD (buffer descriptor) physical address(from OS API).
51 rtw_write32(Adapter, REG_BCNQ_TXBD_DESA_8821C,
52 (u64)pxmitpriv->tx_ring[BCN_QUEUE_INX].dma &
54 rtw_write32(Adapter, REG_MGQ_TXBD_DESA_8821C,
55 (u64)pxmitpriv->tx_ring[MGT_QUEUE_INX].dma &
57 rtw_write32(Adapter, REG_VOQ_TXBD_DESA_8821C,
58 (u64)pxmitpriv->tx_ring[VO_QUEUE_INX].dma &
60 rtw_write32(Adapter, REG_VIQ_TXBD_DESA_8821C,
61 (u64)pxmitpriv->tx_ring[VI_QUEUE_INX].dma &
63 rtw_write32(Adapter, REG_BEQ_TXBD_DESA_8821C,
64 (u64)pxmitpriv->tx_ring[BE_QUEUE_INX].dma &
67 /* vincent sync windows */
68 tmpU4b = rtw_read32(Adapter, REG_BEQ_TXBD_DESA_8821C);
70 rtw_write32(Adapter, REG_BKQ_TXBD_DESA_8821C,
71 (u64)pxmitpriv->tx_ring[BK_QUEUE_INX].dma &
73 rtw_write32(Adapter, REG_HI0Q_TXBD_DESA_8821C,
74 (u64)pxmitpriv->tx_ring[HIGH_QUEUE_INX].dma &
76 rtw_write32(Adapter, REG_RXQ_RXBD_DESA_8821C,
77 (u64)precvpriv->rx_ring[RX_MPDU_QUEUE].dma &
80 #ifdef CONFIG_64BIT_DMA
82 * 2009/10/28 MH For DMA 64 bits. We need to assign the high
83 * 32 bit address for NIC HW to transmit data to correct path.
85 rtw_write32(Adapter, REG_BCNQ_TXBD_DESA_8821C + 4,
86 ((u64)pxmitpriv->tx_ring[BCN_QUEUE_INX].dma) >> 32);
87 rtw_write32(Adapter, REG_MGQ_TXBD_DESA_8821C + 4,
88 ((u64)pxmitpriv->tx_ring[MGT_QUEUE_INX].dma) >> 32);
89 rtw_write32(Adapter, REG_VOQ_TXBD_DESA_8821C + 4,
90 ((u64)pxmitpriv->tx_ring[VO_QUEUE_INX].dma) >> 32);
91 rtw_write32(Adapter, REG_VIQ_TXBD_DESA_8821C + 4,
92 ((u64)pxmitpriv->tx_ring[VI_QUEUE_INX].dma) >> 32);
93 rtw_write32(Adapter, REG_BEQ_TXBD_DESA_8821C + 4,
94 ((u64)pxmitpriv->tx_ring[BE_QUEUE_INX].dma) >> 32);
95 rtw_write32(Adapter, REG_BKQ_TXBD_DESA_8821C + 4,
96 ((u64)pxmitpriv->tx_ring[BK_QUEUE_INX].dma) >> 32);
97 rtw_write32(Adapter, REG_HI0Q_TXBD_DESA_8821C + 4,
98 ((u64)pxmitpriv->tx_ring[HIGH_QUEUE_INX].dma) >> 32);
99 rtw_write32(Adapter, REG_RXQ_RXBD_DESA_8821C + 4,
100 ((u64)precvpriv->rx_ring[RX_MPDU_QUEUE].dma) >> 32);
103 /* 2009/10/28 MH If RX descriptor address is not equal to zero.
104 * We will enable DMA 64 bit functuion.
105 * Note: We never saw thd consition which the descripto address are
106 * divided into 4G down and 4G upper separate area.
108 if (((u64)precvpriv->rx_ring[RX_MPDU_QUEUE].dma) >> 32 != 0) {
109 RTW_INFO("Enable DMA64 bit\n");
111 /* Check if other descriptor address is zero and
112 * abnormally be in 4G lower area.
114 if (((u64)pxmitpriv->tx_ring[MGT_QUEUE_INX].dma) >> 32)
115 RTW_INFO("MGNT_QUEUE HA=0\n");
118 RTW_INFO("Enable DMA32 bit\n");
120 if (adapter_to_dvobj(Adapter)->bdma64)
121 PlatformEnableDMA64(Adapter);
124 /* pci buffer descriptor mode: Reset the Read/Write point to 0 */
125 PlatformEFIOWrite4Byte(Adapter, REG_TSFTIMER_HCI_8821C, 0x3fffffff);
127 /* Reset the H2CQ R/W point index to 0 */
128 tmpU4b = rtw_read32(Adapter, REG_H2CQ_CSR_8821C);
129 rtw_write32(Adapter, REG_H2CQ_CSR_8821C, (tmpU4b | BIT8 | BIT16));
131 tmpU1b = rtw_read8(Adapter, REG_PCIE_CTRL + 3);
132 rtw_write8(Adapter, REG_PCIE_CTRL + 3, (tmpU1b | 0xF7));
134 /* 20100318 Joseph: Reset interrupt migration setting
135 * when initialization. Suggested by SD1
138 rtw_write32(Adapter, REG_INT_MIG, 0);
139 pHalData->bInterruptMigration = _FALSE;
141 /* 2009.10.19. Reset H2C protection register. by tynli. */
142 rtw_write32(Adapter, REG_MCUTST_I_8821C, 0x0);
145 if (Adapter->registrypriv.mp_mode == 1) {
146 rtw_write32(Adapter, REG_MACID, 0x87654321);
147 rtw_write32(Adapter, 0x0700, 0x87654321);
151 /* pic buffer descriptor mode: */
153 rtw_write16(Adapter, REG_MGQ_TXBD_NUM_8821C,
154 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
155 rtw_write16(Adapter, REG_VOQ_TXBD_NUM_8821C,
156 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
157 rtw_write16(Adapter, REG_VIQ_TXBD_NUM_8821C,
158 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
159 rtw_write16(Adapter, REG_BEQ_TXBD_NUM_8821C,
160 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
161 rtw_write16(Adapter, REG_BKQ_TXBD_NUM_8821C,
162 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
163 rtw_write16(Adapter, REG_HI0Q_TXBD_NUM_8821C,
164 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
165 rtw_write16(Adapter, REG_HI1Q_TXBD_NUM_8821C,
166 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
167 rtw_write16(Adapter, REG_HI2Q_TXBD_NUM_8821C,
168 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
169 rtw_write16(Adapter, REG_HI3Q_TXBD_NUM_8821C,
170 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
171 rtw_write16(Adapter, REG_HI4Q_TXBD_NUM_8821C,
172 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
173 rtw_write16(Adapter, REG_HI5Q_TXBD_NUM_8821C,
174 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
175 rtw_write16(Adapter, REG_HI6Q_TXBD_NUM_8821C,
176 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
177 rtw_write16(Adapter, REG_HI7Q_TXBD_NUM_8821C,
178 TX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 12) & 0x3000));
181 /* rx. support 32 bits in linux */
183 #ifdef CONFIG_64BIT_DMA
185 rtw_write16(Adapter, REG_RX_RXBD_NUM_8821C,
186 RX_BD_NUM_8821CE |((RTL8821CE_SEG_NUM<<13 ) & 0x6000) |0x8000);
189 rtw_write16(Adapter, REG_RX_RXBD_NUM_8821C,
190 RX_BD_NUM_8821CE | ((RTL8821CE_SEG_NUM << 13) & 0x6000));
193 /* reset read/write point */
194 rtw_write32(Adapter, REG_TSFTIMER_HCI_8821C, 0XFFFFFFFF);
196 #if 1 /* vincent windows */
197 /* Start debug mode */
201 reg0x3f3 = rtw_read8(Adapter, 0x3f3);
202 rtw_write8(Adapter, 0x3f3, reg0x3f3 | BIT2);
206 /* Need to disable BT coex to let MP tool Tx, this would be done in FW
207 * in the future, suggest by ChunChu, 2015.05.19
214 tmp2Byte = rtw_read16(Adapter, REG_SYS_FUNC_EN_8821C);
215 rtw_write16(Adapter, REG_SYS_FUNC_EN_8821C, tmp2Byte | BIT10);
216 tmp1Byte = rtw_read8(Adapter, REG_DIS_TXREQ_CLR_8821C);
217 rtw_write8(Adapter, REG_DIS_TXREQ_CLR_8821C, tmp1Byte | BIT7);
218 tmp4Byte = rtw_read32(Adapter, 0x1080);
219 rtw_write32(Adapter, 0x1080, tmp4Byte | BIT16);
223 RTW_INFO("InitMAC_TXBD_8821CE() <====\n");
228 u32 rtl8821ce_hal_init(PADAPTER padapter)
233 struct registry_priv *registry_par;
235 hal = GET_HAL_DATA(padapter);
236 registry_par = &padapter->registrypriv;
238 InitMAC_TRXBD_8821CE(padapter);
240 ok = rtl8821c_hal_init(padapter);
244 #if defined(USING_RX_TAG)
245 /* have to init after halmac init */
246 val8 = rtw_read8(padapter, REG_PCIE_CTRL_8821C + 2);
247 rtw_write8(padapter, REG_PCIE_CTRL_8821C + 2, (val8 | BIT4));
248 rtw_write16(padapter, REG_PCIE_CTRL_8821C, 0x8000);
250 rtw_write16(padapter, REG_PCIE_CTRL_8821C, 0x0000);
253 rtw_write8(padapter, REG_RX_DRVINFO_SZ_8821C, 0x4);
255 /* MAX AMPDU Number = 43, Reg0x4C8[21:16] = 0x2B */
256 rtw_write16(padapter, REG_PROT_MODE_CTRL_8821C + 2, 0x2B2B);
258 hal->pci_backdoor_ctrl = registry_par->pci_aspm_config;
260 rtw_pci_aspm_config(padapter);
265 void rtl8821ce_init_default_value(PADAPTER padapter)
267 PHAL_DATA_TYPE pHalData;
270 pHalData = GET_HAL_DATA(padapter);
272 rtl8821c_init_default_value(padapter);
274 /* interface related variable */
275 pHalData->CurrentWirelessMode = WIRELESS_MODE_AUTO;
276 pHalData->bDefaultAntenna = 1;
277 pHalData->TransmitConfig = BIT_CFEND_FORMAT | BIT_WMAC_TCR_ERRSTEN_3;
279 /* Set RCR-Receive Control Register .
280 * The value is set in InitializeAdapter8190Pci().
282 pHalData->ReceiveConfig = (
283 #ifdef CONFIG_RX_PACKET_APPEND_FCS
295 /* BIT_ADF | PS-Poll filter */
302 * Set default value of Interrupt Mask Register0
304 pHalData->IntrMaskDefault[0] = (u32)(
305 BIT(29) | /* BIT_PSTIMEOUT */
306 BIT(27) | /* BIT_GTINT3 */
310 BIT_HSISR_IND_ON_INT_MSK |
312 #ifdef CONFIG_LPS_LCLK
326 * Set default value of Interrupt Mask Register1
328 pHalData->IntrMaskDefault[1] = (u32)(
329 BIT(9) | /* TXFOVW */
331 BIT_PRETXERR_HANDLE_IMR |
335 * Set default value of Interrupt Mask Register3
337 pHalData->IntrMaskDefault[3] = (u32)(
338 BIT_SETH2CDOK_MASK | /* H2C_TX_OK */
341 /* 2012/03/27 hpfan Add for win8 DTM DPC ISR test */
342 pHalData->IntrMaskReg[0] = (u32)(
344 BIT(29) | /* BIT_PSTIMEOUT */
347 pHalData->IntrMaskReg[1] = (u32)(
351 pHalData->IntrMask[0] = pHalData->IntrMaskDefault[0];
352 pHalData->IntrMask[1] = pHalData->IntrMaskDefault[1];
353 pHalData->IntrMask[3] = pHalData->IntrMaskDefault[3];
357 static void hal_deinit_misc(PADAPTER padapter)
362 u32 rtl8821ce_hal_deinit(PADAPTER padapter)
364 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
365 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
366 struct dvobj_priv *pobj_priv = adapter_to_dvobj(padapter);
369 RTW_INFO("==> %s\n", __func__);
372 hal_deinit_misc(padapter);
373 status = rtl8821c_hal_deinit(padapter);
374 if (status == _FALSE) {
375 RTW_INFO("%s: rtl8821c_hal_deinit fail\n", __func__);
379 RTW_INFO("%s <==\n", __func__);