1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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 ******************************************************************************/
15 #define _HCI_HAL_INIT_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <rtw_efuse.h>
21 #include <rtl8188e_hal.h>
22 #include <rtl8188e_led.h>
27 #define HAL_BB_ENABLE 1
29 static void _ConfigNormalChipOutEP_8188E(struct adapter
*adapt
, u8 NumOutPipe
)
31 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
35 haldata
->OutEpQueueSel
= TX_SELE_HQ
| TX_SELE_LQ
| TX_SELE_NQ
;
36 haldata
->OutEpNumber
= 3;
39 haldata
->OutEpQueueSel
= TX_SELE_HQ
| TX_SELE_NQ
;
40 haldata
->OutEpNumber
= 2;
43 haldata
->OutEpQueueSel
= TX_SELE_HQ
;
44 haldata
->OutEpNumber
= 1;
49 DBG_88E("%s OutEpQueueSel(0x%02x), OutEpNumber(%d)\n", __func__
, haldata
->OutEpQueueSel
, haldata
->OutEpNumber
);
52 static bool HalUsbSetQueuePipeMapping8188EUsb(struct adapter
*adapt
, u8 NumInPipe
, u8 NumOutPipe
)
54 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
57 _ConfigNormalChipOutEP_8188E(adapt
, NumOutPipe
);
59 /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
60 if (haldata
->OutEpNumber
== 1) {
65 /* All config other than above support one Bulk IN and one Interrupt IN. */
67 result
= Hal_MappingOutPipe(adapt
, NumOutPipe
);
72 static void rtl8188eu_interface_configure(struct adapter
*adapt
)
74 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
75 struct dvobj_priv
*pdvobjpriv
= adapter_to_dvobj(adapt
);
77 if (pdvobjpriv
->ishighspeed
)
78 haldata
->UsbBulkOutSize
= USB_HIGH_SPEED_BULK_SIZE
;/* 512 bytes */
80 haldata
->UsbBulkOutSize
= USB_FULL_SPEED_BULK_SIZE
;/* 64 bytes */
82 haldata
->interfaceIndex
= pdvobjpriv
->InterfaceNumber
;
84 haldata
->UsbTxAggMode
= 1;
85 haldata
->UsbTxAggDescNum
= 0x6; /* only 4 bits */
87 haldata
->UsbRxAggMode
= USB_RX_AGG_DMA
;/* USB_RX_AGG_DMA; */
88 haldata
->UsbRxAggBlockCount
= 8; /* unit : 512b */
89 haldata
->UsbRxAggBlockTimeout
= 0x6;
90 haldata
->UsbRxAggPageCount
= 48; /* uint :128 b 0x0A; 10 = MAX_RX_DMA_BUFFER_SIZE/2/haldata->UsbBulkOutSize */
91 haldata
->UsbRxAggPageTimeout
= 0x4; /* 6, absolute time = 34ms/(2^6) */
93 HalUsbSetQueuePipeMapping8188EUsb(adapt
,
94 pdvobjpriv
->RtNumInPipes
, pdvobjpriv
->RtNumOutPipes
);
97 static u32
rtl8188eu_InitPowerOn(struct adapter
*adapt
)
100 /* HW Power on sequence */
101 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
102 if (haldata
->bMacPwrCtrlOn
)
105 if (!rtl88eu_pwrseqcmdparsing(adapt
, PWR_CUT_ALL_MSK
,
106 Rtl8188E_NIC_PWR_ON_FLOW
)) {
107 DBG_88E(KERN_ERR
"%s: run power on flow fail\n", __func__
);
111 /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
112 /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
113 usb_write16(adapt
, REG_CR
, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
115 /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
116 value16
= usb_read16(adapt
, REG_CR
);
117 value16
|= (HCI_TXDMA_EN
| HCI_RXDMA_EN
| TXDMA_EN
| RXDMA_EN
118 | PROTOCOL_EN
| SCHEDULE_EN
| ENSEC
| CALTMR_EN
);
119 /* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
121 usb_write16(adapt
, REG_CR
, value16
);
122 haldata
->bMacPwrCtrlOn
= true;
127 /* Shall USB interface init this? */
128 static void _InitInterrupt(struct adapter
*Adapter
)
132 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
134 /* HISR write one to clear */
135 usb_write32(Adapter
, REG_HISR_88E
, 0xFFFFFFFF);
137 imr
= IMR_PSTIMEOUT_88E
| IMR_TBDER_88E
| IMR_CPWM_88E
| IMR_CPWM2_88E
;
138 usb_write32(Adapter
, REG_HIMR_88E
, imr
);
139 haldata
->IntrMask
[0] = imr
;
141 imr_ex
= IMR_TXERR_88E
| IMR_RXERR_88E
| IMR_TXFOVW_88E
| IMR_RXFOVW_88E
;
142 usb_write32(Adapter
, REG_HIMRE_88E
, imr_ex
);
143 haldata
->IntrMask
[1] = imr_ex
;
145 /* REG_USB_SPECIAL_OPTION - BIT(4) */
146 /* 0; Use interrupt endpoint to upload interrupt pkt */
147 /* 1; Use bulk endpoint to upload interrupt pkt, */
148 usb_opt
= usb_read8(Adapter
, REG_USB_SPECIAL_OPTION
);
150 if (!adapter_to_dvobj(Adapter
)->ishighspeed
)
151 usb_opt
= usb_opt
& (~INT_BULK_SEL
);
153 usb_opt
= usb_opt
| (INT_BULK_SEL
);
155 usb_write8(Adapter
, REG_USB_SPECIAL_OPTION
, usb_opt
);
158 static void _InitQueueReservedPage(struct adapter
*Adapter
)
160 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
161 struct registry_priv
*pregistrypriv
= &Adapter
->registrypriv
;
168 bool bWiFiConfig
= pregistrypriv
->wifi_spec
;
171 if (haldata
->OutEpQueueSel
& TX_SELE_HQ
)
174 if (haldata
->OutEpQueueSel
& TX_SELE_LQ
)
177 /* NOTE: This step shall be proceed before writing REG_RQPN. */
178 if (haldata
->OutEpQueueSel
& TX_SELE_NQ
)
180 value8
= (u8
)_NPQ(numNQ
);
181 usb_write8(Adapter
, REG_RQPN_NPQ
, value8
);
183 numPubQ
= 0xA8 - numHQ
- numLQ
- numNQ
;
186 value32
= _HPQ(numHQ
) | _LPQ(numLQ
) | _PUBQ(numPubQ
) | LD_RQPN
;
187 usb_write32(Adapter
, REG_RQPN
, value32
);
189 usb_write16(Adapter
, REG_RQPN_NPQ
, 0x0000);/* Just follow MP Team,??? Georgia 03/28 */
190 usb_write16(Adapter
, REG_RQPN_NPQ
, 0x0d);
191 usb_write32(Adapter
, REG_RQPN
, 0x808E000d);/* reserve 7 page for LPS */
195 static void _InitTxBufferBoundary(struct adapter
*Adapter
, u8 txpktbuf_bndy
)
197 usb_write8(Adapter
, REG_TXPKTBUF_BCNQ_BDNY
, txpktbuf_bndy
);
198 usb_write8(Adapter
, REG_TXPKTBUF_MGQ_BDNY
, txpktbuf_bndy
);
199 usb_write8(Adapter
, REG_TXPKTBUF_WMAC_LBK_BF_HD
, txpktbuf_bndy
);
200 usb_write8(Adapter
, REG_TRXFF_BNDY
, txpktbuf_bndy
);
201 usb_write8(Adapter
, REG_TDECTRL
+1, txpktbuf_bndy
);
204 static void _InitPageBoundary(struct adapter
*Adapter
)
206 /* RX Page Boundary */
208 u16 rxff_bndy
= MAX_RX_DMA_BUFFER_SIZE_88E
-1
;
210 usb_write16(Adapter
, (REG_TRXFF_BNDY
+ 2), rxff_bndy
);
213 static void _InitNormalChipRegPriority(struct adapter
*Adapter
, u16 beQ
,
214 u16 bkQ
, u16 viQ
, u16 voQ
, u16 mgtQ
,
217 u16 value16
= (usb_read16(Adapter
, REG_TRXDMA_CTRL
) & 0x7);
219 value16
|= _TXDMA_BEQ_MAP(beQ
) | _TXDMA_BKQ_MAP(bkQ
) |
220 _TXDMA_VIQ_MAP(viQ
) | _TXDMA_VOQ_MAP(voQ
) |
221 _TXDMA_MGQ_MAP(mgtQ
) | _TXDMA_HIQ_MAP(hiQ
);
223 usb_write16(Adapter
, REG_TRXDMA_CTRL
, value16
);
226 static void _InitNormalChipOneOutEpPriority(struct adapter
*Adapter
)
228 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
231 switch (haldata
->OutEpQueueSel
) {
239 value
= QUEUE_NORMAL
;
244 _InitNormalChipRegPriority(Adapter
, value
, value
, value
, value
,
248 static void _InitNormalChipTwoOutEpPriority(struct adapter
*Adapter
)
250 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
251 struct registry_priv
*pregistrypriv
= &Adapter
->registrypriv
;
252 u16 beQ
, bkQ
, viQ
, voQ
, mgtQ
, hiQ
;
256 switch (haldata
->OutEpQueueSel
) {
257 case (TX_SELE_HQ
| TX_SELE_LQ
):
258 valueHi
= QUEUE_HIGH
;
259 valueLow
= QUEUE_LOW
;
261 case (TX_SELE_NQ
| TX_SELE_LQ
):
262 valueHi
= QUEUE_NORMAL
;
263 valueLow
= QUEUE_LOW
;
265 case (TX_SELE_HQ
| TX_SELE_NQ
):
266 valueHi
= QUEUE_HIGH
;
267 valueLow
= QUEUE_NORMAL
;
273 if (!pregistrypriv
->wifi_spec
) {
280 } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */
288 _InitNormalChipRegPriority(Adapter
, beQ
, bkQ
, viQ
, voQ
, mgtQ
, hiQ
);
291 static void _InitNormalChipThreeOutEpPriority(struct adapter
*Adapter
)
293 struct registry_priv
*pregistrypriv
= &Adapter
->registrypriv
;
294 u16 beQ
, bkQ
, viQ
, voQ
, mgtQ
, hiQ
;
296 if (!pregistrypriv
->wifi_spec
) {/* typical setting */
303 } else {/* for WMM */
311 _InitNormalChipRegPriority(Adapter
, beQ
, bkQ
, viQ
, voQ
, mgtQ
, hiQ
);
314 static void _InitQueuePriority(struct adapter
*Adapter
)
316 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
318 switch (haldata
->OutEpNumber
) {
320 _InitNormalChipOneOutEpPriority(Adapter
);
323 _InitNormalChipTwoOutEpPriority(Adapter
);
326 _InitNormalChipThreeOutEpPriority(Adapter
);
333 static void _InitNetworkType(struct adapter
*Adapter
)
337 value32
= usb_read32(Adapter
, REG_CR
);
338 /* TODO: use the other function to set network type */
339 value32
= (value32
& ~MASK_NETTYPE
) | _NETTYPE(NT_LINK_AP
);
341 usb_write32(Adapter
, REG_CR
, value32
);
344 static void _InitTransferPageSize(struct adapter
*Adapter
)
346 /* Tx page size is always 128. */
349 value8
= _PSRX(PBP_128
) | _PSTX(PBP_128
);
350 usb_write8(Adapter
, REG_PBP
, value8
);
353 static void _InitDriverInfoSize(struct adapter
*Adapter
, u8 drvInfoSize
)
355 usb_write8(Adapter
, REG_RX_DRVINFO_SZ
, drvInfoSize
);
358 static void _InitWMACSetting(struct adapter
*Adapter
)
360 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
362 haldata
->ReceiveConfig
= RCR_AAP
| RCR_APM
| RCR_AM
| RCR_AB
|
363 RCR_CBSSID_DATA
| RCR_CBSSID_BCN
|
364 RCR_APP_ICV
| RCR_AMF
| RCR_HTC_LOC_CTRL
|
365 RCR_APP_MIC
| RCR_APP_PHYSTS
;
367 /* some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() */
368 usb_write32(Adapter
, REG_RCR
, haldata
->ReceiveConfig
);
370 /* Accept all multicast address */
371 usb_write32(Adapter
, REG_MAR
, 0xFFFFFFFF);
372 usb_write32(Adapter
, REG_MAR
+ 4, 0xFFFFFFFF);
375 static void _InitAdaptiveCtrl(struct adapter
*Adapter
)
380 /* Response Rate Set */
381 value32
= usb_read32(Adapter
, REG_RRSR
);
382 value32
&= ~RATE_BITMAP_ALL
;
383 value32
|= RATE_RRSR_CCK_ONLY_1M
;
384 usb_write32(Adapter
, REG_RRSR
, value32
);
386 /* CF-END Threshold */
388 /* SIFS (used in NAV) */
389 value16
= _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
390 usb_write16(Adapter
, REG_SPEC_SIFS
, value16
);
393 value16
= _LRL(0x30) | _SRL(0x30);
394 usb_write16(Adapter
, REG_RL
, value16
);
397 static void _InitEDCA(struct adapter
*Adapter
)
399 /* Set Spec SIFS (used in NAV) */
400 usb_write16(Adapter
, REG_SPEC_SIFS
, 0x100a);
401 usb_write16(Adapter
, REG_MAC_SPEC_SIFS
, 0x100a);
403 /* Set SIFS for CCK */
404 usb_write16(Adapter
, REG_SIFS_CTX
, 0x100a);
406 /* Set SIFS for OFDM */
407 usb_write16(Adapter
, REG_SIFS_TRX
, 0x100a);
410 usb_write32(Adapter
, REG_EDCA_BE_PARAM
, 0x005EA42B);
411 usb_write32(Adapter
, REG_EDCA_BK_PARAM
, 0x0000A44F);
412 usb_write32(Adapter
, REG_EDCA_VI_PARAM
, 0x005EA324);
413 usb_write32(Adapter
, REG_EDCA_VO_PARAM
, 0x002FA226);
416 static void _InitRDGSetting(struct adapter
*Adapter
)
418 usb_write8(Adapter
, REG_RD_CTRL
, 0xFF);
419 usb_write16(Adapter
, REG_RD_NAV_NXT
, 0x200);
420 usb_write8(Adapter
, REG_RD_RESP_PKT_TH
, 0x05);
423 static void _InitRxSetting(struct adapter
*Adapter
)
425 usb_write32(Adapter
, REG_MACID
, 0x87654321);
426 usb_write32(Adapter
, 0x0700, 0x87654321);
429 static void _InitRetryFunction(struct adapter
*Adapter
)
433 value8
= usb_read8(Adapter
, REG_FWHW_TXQ_CTRL
);
434 value8
|= EN_AMPDU_RTY_NEW
;
435 usb_write8(Adapter
, REG_FWHW_TXQ_CTRL
, value8
);
437 /* Set ACK timeout */
438 usb_write8(Adapter
, REG_ACKTO
, 0x40);
441 /*-----------------------------------------------------------------------------
442 * Function: usb_AggSettingTxUpdate()
444 * Overview: Separate TX/RX parameters update independent for TP detection and
445 * dynamic TX/RX aggreagtion parameters update.
447 * Input: struct adapter *
449 * Output/Return: NONE
453 * 12/10/2010 MHC Separate to smaller function.
455 *---------------------------------------------------------------------------
457 static void usb_AggSettingTxUpdate(struct adapter
*Adapter
)
459 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
462 if (Adapter
->registrypriv
.wifi_spec
)
463 haldata
->UsbTxAggMode
= false;
465 if (haldata
->UsbTxAggMode
) {
466 value32
= usb_read32(Adapter
, REG_TDECTRL
);
467 value32
= value32
& ~(BLK_DESC_NUM_MASK
<< BLK_DESC_NUM_SHIFT
);
468 value32
|= ((haldata
->UsbTxAggDescNum
& BLK_DESC_NUM_MASK
) << BLK_DESC_NUM_SHIFT
);
470 usb_write32(Adapter
, REG_TDECTRL
, value32
);
472 } /* usb_AggSettingTxUpdate */
474 /*-----------------------------------------------------------------------------
475 * Function: usb_AggSettingRxUpdate()
477 * Overview: Separate TX/RX parameters update independent for TP detection and
478 * dynamic TX/RX aggreagtion parameters update.
480 * Input: struct adapter *
482 * Output/Return: NONE
486 * 12/10/2010 MHC Separate to smaller function.
488 *---------------------------------------------------------------------------
491 usb_AggSettingRxUpdate(
492 struct adapter
*Adapter
495 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
499 valueDMA
= usb_read8(Adapter
, REG_TRXDMA_CTRL
);
500 valueUSB
= usb_read8(Adapter
, REG_USB_SPECIAL_OPTION
);
502 switch (haldata
->UsbRxAggMode
) {
504 valueDMA
|= RXDMA_AGG_EN
;
505 valueUSB
&= ~USB_AGG_EN
;
508 valueDMA
&= ~RXDMA_AGG_EN
;
509 valueUSB
|= USB_AGG_EN
;
512 valueDMA
|= RXDMA_AGG_EN
;
513 valueUSB
|= USB_AGG_EN
;
515 case USB_RX_AGG_DISABLE
:
517 valueDMA
&= ~RXDMA_AGG_EN
;
518 valueUSB
&= ~USB_AGG_EN
;
522 usb_write8(Adapter
, REG_TRXDMA_CTRL
, valueDMA
);
523 usb_write8(Adapter
, REG_USB_SPECIAL_OPTION
, valueUSB
);
525 switch (haldata
->UsbRxAggMode
) {
527 usb_write8(Adapter
, REG_RXDMA_AGG_PG_TH
, haldata
->UsbRxAggPageCount
);
528 usb_write8(Adapter
, REG_RXDMA_AGG_PG_TH
+1, haldata
->UsbRxAggPageTimeout
);
531 usb_write8(Adapter
, REG_USB_AGG_TH
, haldata
->UsbRxAggBlockCount
);
532 usb_write8(Adapter
, REG_USB_AGG_TO
, haldata
->UsbRxAggBlockTimeout
);
535 usb_write8(Adapter
, REG_RXDMA_AGG_PG_TH
, haldata
->UsbRxAggPageCount
);
536 usb_write8(Adapter
, REG_RXDMA_AGG_PG_TH
+1, (haldata
->UsbRxAggPageTimeout
& 0x1F));/* 0x280[12:8] */
537 usb_write8(Adapter
, REG_USB_AGG_TH
, haldata
->UsbRxAggBlockCount
);
538 usb_write8(Adapter
, REG_USB_AGG_TO
, haldata
->UsbRxAggBlockTimeout
);
540 case USB_RX_AGG_DISABLE
:
548 haldata
->HwRxPageSize
= 128;
551 haldata
->HwRxPageSize
= 64;
554 haldata
->HwRxPageSize
= 256;
557 haldata
->HwRxPageSize
= 512;
560 haldata
->HwRxPageSize
= 1024;
565 } /* usb_AggSettingRxUpdate */
567 static void InitUsbAggregationSetting(struct adapter
*Adapter
)
569 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
571 /* Tx aggregation setting */
572 usb_AggSettingTxUpdate(Adapter
);
574 /* Rx aggregation setting */
575 usb_AggSettingRxUpdate(Adapter
);
577 /* 201/12/10 MH Add for USB agg mode dynamic switch. */
578 haldata
->UsbRxHighSpeedMode
= false;
581 static void _InitBeaconParameters(struct adapter
*Adapter
)
583 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
585 usb_write16(Adapter
, REG_BCN_CTRL
, 0x1010);
587 /* TODO: Remove these magic number */
588 usb_write16(Adapter
, REG_TBTT_PROHIBIT
, 0x6404);/* ms */
589 usb_write8(Adapter
, REG_DRVERLYINT
, DRIVER_EARLY_INT_TIME
);/* 5ms */
590 usb_write8(Adapter
, REG_BCNDMATIM
, BCN_DMA_ATIME_INT_TIME
); /* 2ms */
592 /* Suggested by designer timchen. Change beacon AIFS to the largest number */
593 /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
594 usb_write16(Adapter
, REG_BCNTCFG
, 0x660F);
596 haldata
->RegBcnCtrlVal
= usb_read8(Adapter
, REG_BCN_CTRL
);
597 haldata
->RegTxPause
= usb_read8(Adapter
, REG_TXPAUSE
);
598 haldata
->RegFwHwTxQCtrl
= usb_read8(Adapter
, REG_FWHW_TXQ_CTRL
+2);
599 haldata
->RegReg542
= usb_read8(Adapter
, REG_TBTT_PROHIBIT
+2);
600 haldata
->RegCR_1
= usb_read8(Adapter
, REG_CR
+1);
603 static void _BeaconFunctionEnable(struct adapter
*Adapter
,
604 bool Enable
, bool Linked
)
606 usb_write8(Adapter
, REG_BCN_CTRL
, (BIT(4) | BIT(3) | BIT(1)));
608 usb_write8(Adapter
, REG_RD_CTRL
+1, 0x6F);
611 /* Set CCK and OFDM Block "ON" */
612 static void _BBTurnOnBlock(struct adapter
*Adapter
)
614 phy_set_bb_reg(Adapter
, rFPGA0_RFMOD
, bCCKEn
, 0x1);
615 phy_set_bb_reg(Adapter
, rFPGA0_RFMOD
, bOFDMEn
, 0x1);
623 static void _InitAntenna_Selection(struct adapter
*Adapter
)
625 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
627 if (haldata
->AntDivCfg
== 0)
629 DBG_88E("==> %s ....\n", __func__
);
631 usb_write32(Adapter
, REG_LEDCFG0
, usb_read32(Adapter
, REG_LEDCFG0
) | BIT(23));
632 phy_set_bb_reg(Adapter
, rFPGA0_XAB_RFParameter
, BIT(13), 0x01);
634 if (phy_query_bb_reg(Adapter
, rFPGA0_XA_RFInterfaceOE
, 0x300) == Antenna_A
)
635 haldata
->CurAntenna
= Antenna_A
;
637 haldata
->CurAntenna
= Antenna_B
;
638 DBG_88E("%s,Cur_ant:(%x)%s\n", __func__
, haldata
->CurAntenna
, (haldata
->CurAntenna
== Antenna_A
) ? "Antenna_A" : "Antenna_B");
641 /*-----------------------------------------------------------------------------
642 * Function: HwSuspendModeEnable92Cu()
644 * Overview: HW suspend mode switch.
654 * 08/23/2010 MHC HW suspend mode switch test..
655 *---------------------------------------------------------------------------
657 enum rt_rf_power_state
RfOnOffDetect(struct adapter
*adapt
)
660 enum rt_rf_power_state rfpowerstate
= rf_off
;
662 if (adapt
->pwrctrlpriv
.bHWPowerdown
) {
663 val8
= usb_read8(adapt
, REG_HSISR
);
664 DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8
);
665 rfpowerstate
= (val8
& BIT(7)) ? rf_off
: rf_on
;
666 } else { /* rf on/off */
667 usb_write8(adapt
, REG_MAC_PINMUX_CFG
, usb_read8(adapt
, REG_MAC_PINMUX_CFG
)&~(BIT(3)));
668 val8
= usb_read8(adapt
, REG_GPIO_IO_SEL
);
669 DBG_88E("GPIO_IN=%02x\n", val8
);
670 rfpowerstate
= (val8
& BIT(3)) ? rf_on
: rf_off
;
673 } /* HalDetectPwrDownMode */
675 static u32
rtl8188eu_hal_init(struct adapter
*Adapter
)
680 u32 status
= _SUCCESS
;
681 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
682 struct pwrctrl_priv
*pwrctrlpriv
= &Adapter
->pwrctrlpriv
;
683 struct registry_priv
*pregistrypriv
= &Adapter
->registrypriv
;
684 unsigned long init_start_time
= jiffies
;
686 #define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
688 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BEGIN
);
690 if (Adapter
->pwrctrlpriv
.bkeepfwalive
) {
691 if (haldata
->odmpriv
.RFCalibrateInfo
.bIQKInitialized
) {
692 rtl88eu_phy_iq_calibrate(Adapter
, true);
694 rtl88eu_phy_iq_calibrate(Adapter
, false);
695 haldata
->odmpriv
.RFCalibrateInfo
.bIQKInitialized
= true;
698 ODM_TXPowerTrackingCheck(&haldata
->odmpriv
);
699 rtl88eu_phy_lc_calibrate(Adapter
);
704 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON
);
705 status
= rtl8188eu_InitPowerOn(Adapter
);
706 if (status
== _FAIL
) {
707 RT_TRACE(_module_hci_hal_init_c_
, _drv_err_
, ("Failed to init power on!\n"));
711 /* Save target channel */
712 haldata
->CurrentChannel
= 6;/* default set to 6 */
714 if (pwrctrlpriv
->reg_rfoff
)
715 pwrctrlpriv
->rf_pwrstate
= rf_off
;
717 /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
718 /* HW GPIO pin. Before PHY_RFConfig8192C. */
719 /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
721 if (!pregistrypriv
->wifi_spec
) {
722 txpktbuf_bndy
= TX_PAGE_BOUNDARY_88E
;
725 txpktbuf_bndy
= WMM_NORMAL_TX_PAGE_BOUNDARY_88E
;
728 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01
);
729 _InitQueueReservedPage(Adapter
);
730 _InitQueuePriority(Adapter
);
731 _InitPageBoundary(Adapter
);
732 _InitTransferPageSize(Adapter
);
734 _InitTxBufferBoundary(Adapter
, 0);
736 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW
);
737 if (Adapter
->registrypriv
.mp_mode
== 1) {
738 _InitRxSetting(Adapter
);
739 Adapter
->bFWReady
= false;
741 status
= rtl88eu_download_fw(Adapter
);
744 DBG_88E("%s: Download Firmware failed!!\n", __func__
);
745 Adapter
->bFWReady
= false;
748 RT_TRACE(_module_hci_hal_init_c_
, _drv_info_
, ("Initializeadapt8192CSdio(): Download Firmware Success!!\n"));
749 Adapter
->bFWReady
= true;
751 rtl8188e_InitializeFirmwareVars(Adapter
);
753 rtl88eu_phy_mac_config(Adapter
);
755 rtl88eu_phy_bb_config(Adapter
);
757 rtl88eu_phy_rf_config(Adapter
);
759 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_EFUSE_PATCH
);
760 status
= rtl8188e_iol_efuse_patch(Adapter
);
761 if (status
== _FAIL
) {
762 DBG_88E("%s rtl8188e_iol_efuse_patch failed\n", __func__
);
766 _InitTxBufferBoundary(Adapter
, txpktbuf_bndy
);
768 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT
);
769 status
= InitLLTTable(Adapter
, txpktbuf_bndy
);
770 if (status
== _FAIL
) {
771 RT_TRACE(_module_hci_hal_init_c_
, _drv_err_
, ("Failed to init LLT table\n"));
775 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02
);
776 /* Get Rx PHY status in order to report RSSI and others. */
777 _InitDriverInfoSize(Adapter
, DRVINFO_SZ
);
779 _InitInterrupt(Adapter
);
780 hal_init_macaddr(Adapter
);/* set mac_address */
781 _InitNetworkType(Adapter
);/* set msr */
782 _InitWMACSetting(Adapter
);
783 _InitAdaptiveCtrl(Adapter
);
785 _InitRetryFunction(Adapter
);
786 InitUsbAggregationSetting(Adapter
);
787 _InitBeaconParameters(Adapter
);
788 /* Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */
789 /* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
790 /* Enable MACTXEN/MACRXEN block */
791 value16
= usb_read16(Adapter
, REG_CR
);
792 value16
|= (MACTXEN
| MACRXEN
);
793 usb_write8(Adapter
, REG_CR
, value16
);
795 if (haldata
->bRDGEnable
)
796 _InitRDGSetting(Adapter
);
798 /* Enable TX Report */
799 /* Enable Tx Report Timer */
800 value8
= usb_read8(Adapter
, REG_TX_RPT_CTRL
);
801 usb_write8(Adapter
, REG_TX_RPT_CTRL
, (value8
| BIT(1) | BIT(0)));
802 /* Set MAX RPT MACID */
803 usb_write8(Adapter
, REG_TX_RPT_CTRL
+1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
804 /* Tx RPT Timer. Unit: 32us */
805 usb_write16(Adapter
, REG_TX_RPT_TIME
, 0xCdf0);
807 usb_write8(Adapter
, REG_EARLY_MODE_CONTROL
, 0);
809 usb_write16(Adapter
, REG_PKT_VO_VI_LIFE_TIME
, 0x0400); /* unit: 256us. 256ms */
810 usb_write16(Adapter
, REG_PKT_BE_BK_LIFE_TIME
, 0x0400); /* unit: 256us. 256ms */
812 /* Keep RfRegChnlVal for later use. */
813 haldata
->RfRegChnlVal
[0] = phy_query_rf_reg(Adapter
, (enum rf_radio_path
)0, RF_CHNLBW
, bRFRegOffsetMask
);
814 haldata
->RfRegChnlVal
[1] = phy_query_rf_reg(Adapter
, (enum rf_radio_path
)1, RF_CHNLBW
, bRFRegOffsetMask
);
816 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK
);
817 _BBTurnOnBlock(Adapter
);
819 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY
);
820 invalidate_cam_all(Adapter
);
822 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11
);
823 /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */
824 phy_set_tx_power_level(Adapter
, haldata
->CurrentChannel
);
826 /* Move by Neo for USB SS to below setp */
827 /* _RfPowerSave(Adapter); */
829 _InitAntenna_Selection(Adapter
);
832 /* Disable BAR, suggested by Scott */
833 /* 2010.04.09 add by hpfan */
835 usb_write32(Adapter
, REG_BAR_MODE_CTRL
, 0x0201ffff);
838 /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
839 usb_write8(Adapter
, REG_HWSEQ_CTRL
, 0xFF);
841 if (pregistrypriv
->wifi_spec
)
842 usb_write16(Adapter
, REG_FAST_EDCA_CTRL
, 0);
844 /* Nav limit , suggest by scott */
845 usb_write8(Adapter
, 0x652, 0x0);
847 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM
);
848 rtl8188e_InitHalDm(Adapter
);
850 /* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
851 /* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
852 /* call initstruct adapter. May cause some problem?? */
853 /* Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */
854 /* in MgntActSet_RF_State() after wake up, because the value of haldata->eRFPowerState */
855 /* is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */
856 /* Added by tynli. 2010.03.30. */
857 pwrctrlpriv
->rf_pwrstate
= rf_on
;
859 /* enable Tx report. */
860 usb_write8(Adapter
, REG_FWHW_TXQ_CTRL
+1, 0x0F);
862 /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */
863 usb_write8(Adapter
, REG_EARLY_MODE_CONTROL
+3, 0x01);/* Pretx_en, for WEP/TKIP SEC */
865 /* tynli_test_tx_report. */
866 usb_write16(Adapter
, REG_TX_RPT_TIME
, 0x3DF0);
868 /* enable tx DMA to drop the redundate data of packet */
869 usb_write16(Adapter
, REG_TXDMA_OFFSET_CHK
, (usb_read16(Adapter
, REG_TXDMA_OFFSET_CHK
) | DROP_DATA_EN
));
871 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK
);
872 /* 2010/08/26 MH Merge from 8192CE. */
873 if (pwrctrlpriv
->rf_pwrstate
== rf_on
) {
874 if (haldata
->odmpriv
.RFCalibrateInfo
.bIQKInitialized
) {
875 rtl88eu_phy_iq_calibrate(Adapter
, true);
877 rtl88eu_phy_iq_calibrate(Adapter
, false);
878 haldata
->odmpriv
.RFCalibrateInfo
.bIQKInitialized
= true;
881 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK
);
883 ODM_TXPowerTrackingCheck(&haldata
->odmpriv
);
885 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK
);
886 rtl88eu_phy_lc_calibrate(Adapter
);
889 /* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); */
890 /* _InitPABias(Adapter); */
891 usb_write8(Adapter
, REG_USB_HRPWM
, 0);
893 /* ack for xmit mgmt frames. */
894 usb_write32(Adapter
, REG_FWHW_TXQ_CTRL
, usb_read32(Adapter
, REG_FWHW_TXQ_CTRL
) | BIT(12));
897 HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END
);
899 DBG_88E("%s in %dms\n", __func__
,
900 jiffies_to_msecs(jiffies
- init_start_time
));
905 static void CardDisableRTL8188EU(struct adapter
*Adapter
)
908 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
910 RT_TRACE(_module_hci_hal_init_c_
, _drv_info_
, ("CardDisableRTL8188EU\n"));
912 /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
913 val8
= usb_read8(Adapter
, REG_TX_RPT_CTRL
);
914 usb_write8(Adapter
, REG_TX_RPT_CTRL
, val8
&(~BIT(1)));
917 usb_write8(Adapter
, REG_CR
, 0x0);
919 /* Run LPS WL RFOFF flow */
920 rtl88eu_pwrseqcmdparsing(Adapter
, PWR_CUT_ALL_MSK
,
921 Rtl8188E_NIC_LPS_ENTER_FLOW
);
923 /* 2. 0x1F[7:0] = 0 turn off RF */
925 val8
= usb_read8(Adapter
, REG_MCUFWDL
);
926 if ((val8
& RAM_DL_SEL
) && Adapter
->bFWReady
) { /* 8051 RAM code */
927 /* Reset MCU 0x2[10]=0. */
928 val8
= usb_read8(Adapter
, REG_SYS_FUNC_EN
+1);
929 val8
&= ~BIT(2); /* 0x2[10], FEN_CPUEN */
930 usb_write8(Adapter
, REG_SYS_FUNC_EN
+1, val8
);
933 /* reset MCU ready status */
934 usb_write8(Adapter
, REG_MCUFWDL
, 0);
938 val8
= usb_read8(Adapter
, REG_32K_CTRL
);
939 usb_write8(Adapter
, REG_32K_CTRL
, val8
&(~BIT(0)));
941 /* Card disable power action flow */
942 rtl88eu_pwrseqcmdparsing(Adapter
, PWR_CUT_ALL_MSK
,
943 Rtl8188E_NIC_DISABLE_FLOW
);
945 /* Reset MCU IO Wrapper */
946 val8
= usb_read8(Adapter
, REG_RSV_CTRL
+1);
947 usb_write8(Adapter
, REG_RSV_CTRL
+1, (val8
&(~BIT(3))));
948 val8
= usb_read8(Adapter
, REG_RSV_CTRL
+1);
949 usb_write8(Adapter
, REG_RSV_CTRL
+1, val8
| BIT(3));
951 /* YJ,test add, 111207. For Power Consumption. */
952 val8
= usb_read8(Adapter
, GPIO_IN
);
953 usb_write8(Adapter
, GPIO_OUT
, val8
);
954 usb_write8(Adapter
, GPIO_IO_SEL
, 0xFF);/* Reg0x46 */
956 val8
= usb_read8(Adapter
, REG_GPIO_IO_SEL
);
957 usb_write8(Adapter
, REG_GPIO_IO_SEL
, (val8
<<4));
958 val8
= usb_read8(Adapter
, REG_GPIO_IO_SEL
+1);
959 usb_write8(Adapter
, REG_GPIO_IO_SEL
+1, val8
|0x0F);/* Reg0x43 */
960 usb_write32(Adapter
, REG_BB_PAD_CTRL
, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
961 haldata
->bMacPwrCtrlOn
= false;
962 Adapter
->bFWReady
= false;
965 static void rtl8192cu_hw_power_down(struct adapter
*adapt
)
967 /* 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c. */
968 /* Then enable power down control bit of register 0x04 BIT4 and BIT15 as 1. */
970 /* Enable register area 0x0-0xc. */
971 usb_write8(adapt
, REG_RSV_CTRL
, 0x0);
972 usb_write16(adapt
, REG_APS_FSMCO
, 0x8812);
975 static u32
rtl8188eu_hal_deinit(struct adapter
*Adapter
)
977 DBG_88E("==> %s\n", __func__
);
979 usb_write32(Adapter
, REG_HIMR_88E
, IMR_DISABLED_88E
);
980 usb_write32(Adapter
, REG_HIMRE_88E
, IMR_DISABLED_88E
);
982 DBG_88E("bkeepfwalive(%x)\n", Adapter
->pwrctrlpriv
.bkeepfwalive
);
983 if (Adapter
->pwrctrlpriv
.bkeepfwalive
) {
984 if ((Adapter
->pwrctrlpriv
.bHWPwrPindetect
) && (Adapter
->pwrctrlpriv
.bHWPowerdown
))
985 rtl8192cu_hw_power_down(Adapter
);
987 if (Adapter
->hw_init_completed
) {
988 CardDisableRTL8188EU(Adapter
);
990 if ((Adapter
->pwrctrlpriv
.bHWPwrPindetect
) && (Adapter
->pwrctrlpriv
.bHWPowerdown
))
991 rtl8192cu_hw_power_down(Adapter
);
997 static unsigned int rtl8188eu_inirp_init(struct adapter
*Adapter
)
1000 struct recv_buf
*precvbuf
;
1002 struct recv_priv
*precvpriv
= &Adapter
->recvpriv
;
1006 RT_TRACE(_module_hci_hal_init_c_
, _drv_info_
,
1007 ("===> usb_inirp_init\n"));
1009 precvpriv
->ff_hwaddr
= RECV_BULK_IN_ADDR
;
1011 /* issue Rx irp to receive data */
1012 precvbuf
= (struct recv_buf
*)precvpriv
->precv_buf
;
1013 for (i
= 0; i
< NR_RECVBUFF
; i
++) {
1014 if (usb_read_port(Adapter
, precvpriv
->ff_hwaddr
, 0, (unsigned char *)precvbuf
) == false) {
1015 RT_TRACE(_module_hci_hal_init_c_
, _drv_err_
, ("usb_rx_init: usb_read_port error\n"));
1021 precvpriv
->free_recv_buf_queue_cnt
--;
1026 RT_TRACE(_module_hci_hal_init_c_
, _drv_info_
, ("<=== usb_inirp_init\n"));
1032 static unsigned int rtl8188eu_inirp_deinit(struct adapter
*Adapter
)
1034 RT_TRACE(_module_hci_hal_init_c_
, _drv_info_
, ("\n ===> usb_rx_deinit\n"));
1036 usb_read_port_cancel(Adapter
);
1038 RT_TRACE(_module_hci_hal_init_c_
, _drv_info_
, ("\n <=== usb_rx_deinit\n"));
1045 /* EEPROM/EFUSE Content Parsing */
1048 static void Hal_EfuseParsePIDVID_8188EU(struct adapter
*adapt
, u8
*hwinfo
, bool AutoLoadFail
)
1050 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
1052 if (!AutoLoadFail
) {
1054 haldata
->EEPROMVID
= EF2BYTE(*(__le16
*)&hwinfo
[EEPROM_VID_88EU
]);
1055 haldata
->EEPROMPID
= EF2BYTE(*(__le16
*)&hwinfo
[EEPROM_PID_88EU
]);
1057 /* Customer ID, 0x00 and 0xff are reserved for Realtek. */
1058 haldata
->EEPROMCustomerID
= *(u8
*)&hwinfo
[EEPROM_CUSTOMERID_88E
];
1059 haldata
->EEPROMSubCustomerID
= EEPROM_Default_SubCustomerID
;
1061 haldata
->EEPROMVID
= EEPROM_Default_VID
;
1062 haldata
->EEPROMPID
= EEPROM_Default_PID
;
1064 /* Customer ID, 0x00 and 0xff are reserved for Realtek. */
1065 haldata
->EEPROMCustomerID
= EEPROM_Default_CustomerID
;
1066 haldata
->EEPROMSubCustomerID
= EEPROM_Default_SubCustomerID
;
1069 DBG_88E("VID = 0x%04X, PID = 0x%04X\n", haldata
->EEPROMVID
, haldata
->EEPROMPID
);
1070 DBG_88E("Customer ID: 0x%02X, SubCustomer ID: 0x%02X\n", haldata
->EEPROMCustomerID
, haldata
->EEPROMSubCustomerID
);
1073 static void Hal_EfuseParseMACAddr_8188EU(struct adapter
*adapt
, u8
*hwinfo
, bool AutoLoadFail
)
1076 u8 sMacAddr
[6] = {0x00, 0xE0, 0x4C, 0x81, 0x88, 0x02};
1077 struct eeprom_priv
*eeprom
= GET_EEPROM_EFUSE_PRIV(adapt
);
1080 for (i
= 0; i
< 6; i
++)
1081 eeprom
->mac_addr
[i
] = sMacAddr
[i
];
1083 /* Read Permanent MAC address */
1084 memcpy(eeprom
->mac_addr
, &hwinfo
[EEPROM_MAC_ADDR_88EU
], ETH_ALEN
);
1086 RT_TRACE(_module_hci_hal_init_c_
, _drv_notice_
,
1087 ("Hal_EfuseParseMACAddr_8188EU: Permanent Address = %pM\n",
1092 readAdapterInfo_8188EU(
1093 struct adapter
*adapt
1096 struct eeprom_priv
*eeprom
= GET_EEPROM_EFUSE_PRIV(adapt
);
1098 /* parse the eeprom/efuse content */
1099 Hal_EfuseParseIDCode88E(adapt
, eeprom
->efuse_eeprom_data
);
1100 Hal_EfuseParsePIDVID_8188EU(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1101 Hal_EfuseParseMACAddr_8188EU(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1103 Hal_ReadPowerSavingMode88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1104 Hal_ReadTxPowerInfo88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1105 Hal_EfuseParseEEPROMVer88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1106 rtl8188e_EfuseParseChnlPlan(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1107 Hal_EfuseParseXtal_8188E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1108 Hal_EfuseParseCustomerID88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1109 Hal_ReadAntennaDiversity88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1110 Hal_EfuseParseBoardType88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1111 Hal_ReadThermalMeter_88E(adapt
, eeprom
->efuse_eeprom_data
, eeprom
->bautoload_fail_flag
);
1114 static void _ReadPROMContent(
1115 struct adapter
*Adapter
1118 struct eeprom_priv
*eeprom
= GET_EEPROM_EFUSE_PRIV(Adapter
);
1121 /* check system boot selection */
1122 eeValue
= usb_read8(Adapter
, REG_9346CR
);
1123 eeprom
->EepromOrEfuse
= (eeValue
& BOOT_FROM_EEPROM
) ? true : false;
1124 eeprom
->bautoload_fail_flag
= (eeValue
& EEPROM_EN
) ? false : true;
1126 DBG_88E("Boot from %s, Autoload %s !\n", (eeprom
->EepromOrEfuse
? "EEPROM" : "EFUSE"),
1127 (eeprom
->bautoload_fail_flag
? "Fail" : "OK"));
1129 Hal_InitPGData88E(Adapter
);
1130 readAdapterInfo_8188EU(Adapter
);
1133 static void _ReadRFType(struct adapter
*Adapter
)
1135 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
1137 haldata
->rf_chip
= RF_6052
;
1140 static void _ReadAdapterInfo8188EU(struct adapter
*Adapter
)
1142 unsigned long start
= jiffies
;
1144 MSG_88E("====> %s\n", __func__
);
1146 _ReadRFType(Adapter
);/* rf_chip -> _InitRFType() */
1147 _ReadPROMContent(Adapter
);
1149 MSG_88E("<==== %s in %d ms\n", __func__
,
1150 jiffies_to_msecs(jiffies
- start
));
1153 #define GPIO_DEBUG_PORT_NUM 0
1154 static void rtl8192cu_trigger_gpio_0(struct adapter
*adapt
)
1158 static void ResumeTxBeacon(struct adapter
*adapt
)
1160 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
1162 /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
1163 /* which should be read from register to a global variable. */
1165 usb_write8(adapt
, REG_FWHW_TXQ_CTRL
+2, (haldata
->RegFwHwTxQCtrl
) | BIT(6));
1166 haldata
->RegFwHwTxQCtrl
|= BIT(6);
1167 usb_write8(adapt
, REG_TBTT_PROHIBIT
+1, 0xff);
1168 haldata
->RegReg542
|= BIT(0);
1169 usb_write8(adapt
, REG_TBTT_PROHIBIT
+2, haldata
->RegReg542
);
1172 static void StopTxBeacon(struct adapter
*adapt
)
1174 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
1176 /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
1177 /* which should be read from register to a global variable. */
1179 usb_write8(adapt
, REG_FWHW_TXQ_CTRL
+2, (haldata
->RegFwHwTxQCtrl
) & (~BIT(6)));
1180 haldata
->RegFwHwTxQCtrl
&= (~BIT(6));
1181 usb_write8(adapt
, REG_TBTT_PROHIBIT
+1, 0x64);
1182 haldata
->RegReg542
&= ~(BIT(0));
1183 usb_write8(adapt
, REG_TBTT_PROHIBIT
+2, haldata
->RegReg542
);
1185 /* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */
1188 static void hw_var_set_opmode(struct adapter
*Adapter
, u8 variable
, u8
*val
)
1191 u8 mode
= *((u8
*)val
);
1193 /* disable Port0 TSF update */
1194 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
) | BIT(4));
1197 val8
= usb_read8(Adapter
, MSR
)&0x0c;
1199 usb_write8(Adapter
, MSR
, val8
);
1201 DBG_88E("%s()-%d mode = %d\n", __func__
, __LINE__
, mode
);
1203 if ((mode
== _HW_STATE_STATION_
) || (mode
== _HW_STATE_NOLINK_
)) {
1204 StopTxBeacon(Adapter
);
1206 usb_write8(Adapter
, REG_BCN_CTRL
, 0x19);/* disable atim wnd */
1207 } else if (mode
== _HW_STATE_ADHOC_
) {
1208 ResumeTxBeacon(Adapter
);
1209 usb_write8(Adapter
, REG_BCN_CTRL
, 0x1a);
1210 } else if (mode
== _HW_STATE_AP_
) {
1211 ResumeTxBeacon(Adapter
);
1213 usb_write8(Adapter
, REG_BCN_CTRL
, 0x12);
1216 usb_write32(Adapter
, REG_RCR
, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
1217 /* enable to rx data frame */
1218 usb_write16(Adapter
, REG_RXFLTMAP2
, 0xFFFF);
1219 /* enable to rx ps-poll */
1220 usb_write16(Adapter
, REG_RXFLTMAP1
, 0x0400);
1222 /* Beacon Control related register for first time */
1223 usb_write8(Adapter
, REG_BCNDMATIM
, 0x02); /* 2ms */
1225 usb_write8(Adapter
, REG_ATIMWND
, 0x0a); /* 10ms */
1226 usb_write16(Adapter
, REG_BCNTCFG
, 0x00);
1227 usb_write16(Adapter
, REG_TBTT_PROHIBIT
, 0xff04);
1228 usb_write16(Adapter
, REG_TSFTR_SYN_OFFSET
, 0x7fff);/* +32767 (~32ms) */
1231 usb_write8(Adapter
, REG_DUAL_TSF_RST
, BIT(0));
1233 /* BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
1234 usb_write8(Adapter
, REG_MBID_NUM
, usb_read8(Adapter
, REG_MBID_NUM
) | BIT(3) | BIT(4));
1236 /* enable BCN0 Function for if1 */
1237 /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
1238 usb_write8(Adapter
, REG_BCN_CTRL
, (DIS_TSF_UDT0_NORMAL_CHIP
|EN_BCN_FUNCTION
| BIT(1)));
1240 /* dis BCN1 ATIM WND if if2 is station */
1241 usb_write8(Adapter
, REG_BCN_CTRL_1
, usb_read8(Adapter
, REG_BCN_CTRL_1
) | BIT(0));
1245 static void hw_var_set_macaddr(struct adapter
*Adapter
, u8 variable
, u8
*val
)
1250 reg_macid
= REG_MACID
;
1252 for (idx
= 0; idx
< 6; idx
++)
1253 usb_write8(Adapter
, (reg_macid
+idx
), val
[idx
]);
1256 static void hw_var_set_bssid(struct adapter
*Adapter
, u8 variable
, u8
*val
)
1261 reg_bssid
= REG_BSSID
;
1263 for (idx
= 0; idx
< 6; idx
++)
1264 usb_write8(Adapter
, (reg_bssid
+idx
), val
[idx
]);
1267 static void hw_var_set_bcn_func(struct adapter
*Adapter
, u8 variable
, u8
*val
)
1271 bcn_ctrl_reg
= REG_BCN_CTRL
;
1274 usb_write8(Adapter
, bcn_ctrl_reg
, (EN_BCN_FUNCTION
| EN_TXBCN_RPT
));
1276 usb_write8(Adapter
, bcn_ctrl_reg
, usb_read8(Adapter
, bcn_ctrl_reg
)&(~(EN_BCN_FUNCTION
| EN_TXBCN_RPT
)));
1279 static void SetHwReg8188EU(struct adapter
*Adapter
, u8 variable
, u8
*val
)
1281 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
1282 struct dm_priv
*pdmpriv
= &haldata
->dmpriv
;
1283 struct odm_dm_struct
*podmpriv
= &haldata
->odmpriv
;
1286 case HW_VAR_MEDIA_STATUS
:
1290 val8
= usb_read8(Adapter
, MSR
)&0x0c;
1291 val8
|= *((u8
*)val
);
1292 usb_write8(Adapter
, MSR
, val8
);
1295 case HW_VAR_MEDIA_STATUS1
:
1299 val8
= usb_read8(Adapter
, MSR
) & 0x03;
1300 val8
|= *((u8
*)val
) << 2;
1301 usb_write8(Adapter
, MSR
, val8
);
1304 case HW_VAR_SET_OPMODE
:
1305 hw_var_set_opmode(Adapter
, variable
, val
);
1307 case HW_VAR_MAC_ADDR
:
1308 hw_var_set_macaddr(Adapter
, variable
, val
);
1311 hw_var_set_bssid(Adapter
, variable
, val
);
1313 case HW_VAR_BASIC_RATE
:
1318 /* 2007.01.16, by Emily */
1319 /* Select RRSR (in Legacy-OFDM and CCK) */
1320 /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
1321 /* We do not use other rates. */
1322 HalSetBrateCfg(Adapter
, val
, &BrateCfg
);
1323 DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg
);
1325 /* 2011.03.30 add by Luke Lee */
1326 /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
1327 /* because CCK 2M has poor TXEVM */
1328 /* CCK 5.5M & 11M ACK should be enabled for better performance */
1330 BrateCfg
= (BrateCfg
| 0xd) & 0x15d;
1331 haldata
->BasicRateSet
= BrateCfg
;
1333 BrateCfg
|= 0x01; /* default enable 1M ACK rate */
1334 /* Set RRSR rate table. */
1335 usb_write8(Adapter
, REG_RRSR
, BrateCfg
& 0xff);
1336 usb_write8(Adapter
, REG_RRSR
+1, (BrateCfg
>> 8) & 0xff);
1337 usb_write8(Adapter
, REG_RRSR
+2, usb_read8(Adapter
, REG_RRSR
+2)&0xf0);
1339 /* Set RTS initial rate */
1340 while (BrateCfg
> 0x1) {
1345 usb_write8(Adapter
, REG_INIRTS_RATE_SEL
, RateIndex
);
1348 case HW_VAR_TXPAUSE
:
1349 usb_write8(Adapter
, REG_TXPAUSE
, *((u8
*)val
));
1351 case HW_VAR_BCN_FUNC
:
1352 hw_var_set_bcn_func(Adapter
, variable
, val
);
1354 case HW_VAR_CORRECT_TSF
:
1357 struct mlme_ext_priv
*pmlmeext
= &Adapter
->mlmeextpriv
;
1358 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1360 tsf
= pmlmeext
->TSFValue
- rtw_modular64(pmlmeext
->TSFValue
, (pmlmeinfo
->bcn_interval
*1024)) - 1024; /* us */
1362 if (((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) || ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
))
1363 StopTxBeacon(Adapter
);
1365 /* disable related TSF function */
1366 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
)&(~BIT(3)));
1368 usb_write32(Adapter
, REG_TSFTR
, tsf
);
1369 usb_write32(Adapter
, REG_TSFTR
+4, tsf
>>32);
1371 /* enable related TSF function */
1372 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
) | BIT(3));
1374 if (((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) || ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
))
1375 ResumeTxBeacon(Adapter
);
1378 case HW_VAR_CHECK_BSSID
:
1380 usb_write32(Adapter
, REG_RCR
, usb_read32(Adapter
, REG_RCR
)|RCR_CBSSID_DATA
|RCR_CBSSID_BCN
);
1384 val32
= usb_read32(Adapter
, REG_RCR
);
1386 val32
&= ~(RCR_CBSSID_DATA
| RCR_CBSSID_BCN
);
1388 usb_write32(Adapter
, REG_RCR
, val32
);
1391 case HW_VAR_MLME_DISCONNECT
:
1392 /* Set RCR to not to receive data frame when NO LINK state */
1393 /* reject all data frames */
1394 usb_write16(Adapter
, REG_RXFLTMAP2
, 0x00);
1397 usb_write8(Adapter
, REG_DUAL_TSF_RST
, (BIT(0) | BIT(1)));
1399 /* disable update TSF */
1400 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
) | BIT(4));
1402 case HW_VAR_MLME_SITESURVEY
:
1403 if (*((u8
*)val
)) { /* under sitesurvey */
1404 /* config RCR to receive different BSSID & not to receive data frame */
1405 u32 v
= usb_read32(Adapter
, REG_RCR
);
1406 v
&= ~(RCR_CBSSID_BCN
);
1407 usb_write32(Adapter
, REG_RCR
, v
);
1408 /* reject all data frame */
1409 usb_write16(Adapter
, REG_RXFLTMAP2
, 0x00);
1411 /* disable update TSF */
1412 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
) | BIT(4));
1413 } else { /* sitesurvey done */
1414 struct mlme_ext_priv
*pmlmeext
= &Adapter
->mlmeextpriv
;
1415 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1417 if ((is_client_associated_to_ap(Adapter
)) ||
1418 ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
)) {
1419 /* enable to rx data frame */
1420 usb_write16(Adapter
, REG_RXFLTMAP2
, 0xFFFF);
1422 /* enable update TSF */
1423 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
)&(~BIT(4)));
1424 } else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
) {
1425 usb_write16(Adapter
, REG_RXFLTMAP2
, 0xFFFF);
1426 /* enable update TSF */
1427 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
)&(~BIT(4)));
1429 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
) {
1430 usb_write32(Adapter
, REG_RCR
, usb_read32(Adapter
, REG_RCR
)|RCR_CBSSID_BCN
);
1432 if (Adapter
->in_cta_test
) {
1433 u32 v
= usb_read32(Adapter
, REG_RCR
);
1434 v
&= ~(RCR_CBSSID_DATA
| RCR_CBSSID_BCN
);/* RCR_ADF */
1435 usb_write32(Adapter
, REG_RCR
, v
);
1437 usb_write32(Adapter
, REG_RCR
, usb_read32(Adapter
, REG_RCR
)|RCR_CBSSID_BCN
);
1442 case HW_VAR_MLME_JOIN
:
1444 u8 RetryLimit
= 0x30;
1445 u8 type
= *((u8
*)val
);
1446 struct mlme_priv
*pmlmepriv
= &Adapter
->mlmepriv
;
1448 if (type
== 0) { /* prepare to join */
1449 /* enable to rx data frame.Accept all data frame */
1450 usb_write16(Adapter
, REG_RXFLTMAP2
, 0xFFFF);
1452 if (Adapter
->in_cta_test
) {
1453 u32 v
= usb_read32(Adapter
, REG_RCR
);
1454 v
&= ~(RCR_CBSSID_DATA
| RCR_CBSSID_BCN
);/* RCR_ADF */
1455 usb_write32(Adapter
, REG_RCR
, v
);
1457 usb_write32(Adapter
, REG_RCR
, usb_read32(Adapter
, REG_RCR
)|RCR_CBSSID_DATA
|RCR_CBSSID_BCN
);
1460 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
1461 RetryLimit
= (haldata
->CustomerID
== RT_CID_CCX
) ? 7 : 48;
1462 else /* Ad-hoc Mode */
1464 } else if (type
== 1) {
1465 /* joinbss_event call back when join res < 0 */
1466 usb_write16(Adapter
, REG_RXFLTMAP2
, 0x00);
1467 } else if (type
== 2) {
1468 /* sta add event call back */
1469 /* enable update TSF */
1470 usb_write8(Adapter
, REG_BCN_CTRL
, usb_read8(Adapter
, REG_BCN_CTRL
)&(~BIT(4)));
1472 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
|WIFI_ADHOC_MASTER_STATE
))
1475 usb_write16(Adapter
, REG_RL
, RetryLimit
<< RETRY_LIMIT_SHORT_SHIFT
| RetryLimit
<< RETRY_LIMIT_LONG_SHIFT
);
1478 case HW_VAR_BEACON_INTERVAL
:
1479 usb_write16(Adapter
, REG_BCN_INTERVAL
, *((u16
*)val
));
1481 case HW_VAR_SLOT_TIME
:
1483 u8 u1bAIFS
, aSifsTime
;
1484 struct mlme_ext_priv
*pmlmeext
= &Adapter
->mlmeextpriv
;
1485 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1487 usb_write8(Adapter
, REG_SLOT
, val
[0]);
1489 if (pmlmeinfo
->WMM_enable
== 0) {
1490 if (pmlmeext
->cur_wireless_mode
== WIRELESS_11B
)
1495 u1bAIFS
= aSifsTime
+ (2 * pmlmeinfo
->slotTime
);
1497 /* <Roger_EXP> Temporary removed, 2008.06.20. */
1498 usb_write8(Adapter
, REG_EDCA_VO_PARAM
, u1bAIFS
);
1499 usb_write8(Adapter
, REG_EDCA_VI_PARAM
, u1bAIFS
);
1500 usb_write8(Adapter
, REG_EDCA_BE_PARAM
, u1bAIFS
);
1501 usb_write8(Adapter
, REG_EDCA_BK_PARAM
, u1bAIFS
);
1505 case HW_VAR_RESP_SIFS
:
1506 /* RESP_SIFS for CCK */
1507 usb_write8(Adapter
, REG_R2T_SIFS
, val
[0]); /* SIFS_T2T_CCK (0x08) */
1508 usb_write8(Adapter
, REG_R2T_SIFS
+1, val
[1]); /* SIFS_R2T_CCK(0x08) */
1509 /* RESP_SIFS for OFDM */
1510 usb_write8(Adapter
, REG_T2T_SIFS
, val
[2]); /* SIFS_T2T_OFDM (0x0a) */
1511 usb_write8(Adapter
, REG_T2T_SIFS
+1, val
[3]); /* SIFS_R2T_OFDM(0x0a) */
1513 case HW_VAR_ACK_PREAMBLE
:
1516 u8 bShortPreamble
= *((bool *)val
);
1517 /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
1518 regTmp
= (haldata
->nCur40MhzPrimeSC
)<<5;
1522 usb_write8(Adapter
, REG_RRSR
+2, regTmp
);
1525 case HW_VAR_SEC_CFG
:
1526 usb_write8(Adapter
, REG_SECCFG
, *((u8
*)val
));
1528 case HW_VAR_DM_FLAG
:
1529 podmpriv
->SupportAbility
= *((u8
*)val
);
1531 case HW_VAR_DM_FUNC_OP
:
1533 podmpriv
->BK_SupportAbility
= podmpriv
->SupportAbility
;
1535 podmpriv
->SupportAbility
= podmpriv
->BK_SupportAbility
;
1537 case HW_VAR_DM_FUNC_SET
:
1538 if (*((u32
*)val
) == DYNAMIC_ALL_FUNC_ENABLE
) {
1539 pdmpriv
->DMFlag
= pdmpriv
->InitDMFlag
;
1540 podmpriv
->SupportAbility
= pdmpriv
->InitODMFlag
;
1542 podmpriv
->SupportAbility
|= *((u32
*)val
);
1545 case HW_VAR_DM_FUNC_CLR
:
1546 podmpriv
->SupportAbility
&= *((u32
*)val
);
1548 case HW_VAR_CAM_EMPTY_ENTRY
:
1550 u8 ucIndex
= *((u8
*)val
);
1554 u32 ulEncAlgo
= CAM_AES
;
1556 for (i
= 0; i
< CAM_CONTENT_COUNT
; i
++) {
1557 /* filled id in CAM config 2 byte */
1559 ulContent
|= (ucIndex
& 0x03) | ((u16
)(ulEncAlgo
)<<2);
1562 /* polling bit, and No Write enable, and address */
1563 ulCommand
= CAM_CONTENT_COUNT
*ucIndex
+i
;
1564 ulCommand
= ulCommand
| CAM_POLLINIG
|CAM_WRITE
;
1565 /* write content 0 is equall to mark invalid */
1566 usb_write32(Adapter
, WCAMI
, ulContent
); /* delay_ms(40); */
1567 usb_write32(Adapter
, RWCAM
, ulCommand
); /* delay_ms(40); */
1571 case HW_VAR_CAM_INVALID_ALL
:
1572 usb_write32(Adapter
, RWCAM
, BIT(31) | BIT(30));
1574 case HW_VAR_CAM_WRITE
:
1577 u32
*cam_val
= (u32
*)val
;
1578 usb_write32(Adapter
, WCAMI
, cam_val
[0]);
1580 cmd
= CAM_POLLINIG
| CAM_WRITE
| cam_val
[1];
1581 usb_write32(Adapter
, RWCAM
, cmd
);
1584 case HW_VAR_AC_PARAM_VO
:
1585 usb_write32(Adapter
, REG_EDCA_VO_PARAM
, ((u32
*)(val
))[0]);
1587 case HW_VAR_AC_PARAM_VI
:
1588 usb_write32(Adapter
, REG_EDCA_VI_PARAM
, ((u32
*)(val
))[0]);
1590 case HW_VAR_AC_PARAM_BE
:
1591 haldata
->AcParam_BE
= ((u32
*)(val
))[0];
1592 usb_write32(Adapter
, REG_EDCA_BE_PARAM
, ((u32
*)(val
))[0]);
1594 case HW_VAR_AC_PARAM_BK
:
1595 usb_write32(Adapter
, REG_EDCA_BK_PARAM
, ((u32
*)(val
))[0]);
1597 case HW_VAR_ACM_CTRL
:
1599 u8 acm_ctrl
= *((u8
*)val
);
1600 u8 AcmCtrl
= usb_read8(Adapter
, REG_ACMHWCTRL
);
1603 AcmCtrl
= AcmCtrl
| 0x1;
1605 if (acm_ctrl
& BIT(3))
1606 AcmCtrl
|= AcmHw_VoqEn
;
1608 AcmCtrl
&= (~AcmHw_VoqEn
);
1610 if (acm_ctrl
& BIT(2))
1611 AcmCtrl
|= AcmHw_ViqEn
;
1613 AcmCtrl
&= (~AcmHw_ViqEn
);
1615 if (acm_ctrl
& BIT(1))
1616 AcmCtrl
|= AcmHw_BeqEn
;
1618 AcmCtrl
&= (~AcmHw_BeqEn
);
1620 DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl
);
1621 usb_write8(Adapter
, REG_ACMHWCTRL
, AcmCtrl
);
1624 case HW_VAR_AMPDU_MIN_SPACE
:
1629 MinSpacingToSet
= *((u8
*)val
);
1630 if (MinSpacingToSet
<= 7) {
1631 switch (Adapter
->securitypriv
.dot11PrivacyAlgrthm
) {
1646 if (MinSpacingToSet
< SecMinSpace
)
1647 MinSpacingToSet
= SecMinSpace
;
1648 usb_write8(Adapter
, REG_AMPDU_MIN_SPACE
, (usb_read8(Adapter
, REG_AMPDU_MIN_SPACE
) & 0xf8) | MinSpacingToSet
);
1652 case HW_VAR_AMPDU_FACTOR
:
1654 u8 RegToSet_Normal
[4] = {0x41, 0xa8, 0x72, 0xb9};
1659 pRegToSet
= RegToSet_Normal
; /* 0xb972a841; */
1660 FactorToSet
= *((u8
*)val
);
1661 if (FactorToSet
<= 3) {
1662 FactorToSet
= 1 << (FactorToSet
+ 2);
1663 if (FactorToSet
> 0xf)
1666 for (index
= 0; index
< 4; index
++) {
1667 if ((pRegToSet
[index
] & 0xf0) > (FactorToSet
<<4))
1668 pRegToSet
[index
] = (pRegToSet
[index
] & 0x0f) | (FactorToSet
<<4);
1670 if ((pRegToSet
[index
] & 0x0f) > FactorToSet
)
1671 pRegToSet
[index
] = (pRegToSet
[index
] & 0xf0) | (FactorToSet
);
1673 usb_write8(Adapter
, (REG_AGGLEN_LMT
+index
), pRegToSet
[index
]);
1678 case HW_VAR_RXDMA_AGG_PG_TH
:
1680 u8 threshold
= *((u8
*)val
);
1682 threshold
= haldata
->UsbRxAggPageCount
;
1683 usb_write8(Adapter
, REG_RXDMA_AGG_PG_TH
, threshold
);
1686 case HW_VAR_SET_RPWM
:
1688 case HW_VAR_H2C_FW_PWRMODE
:
1690 u8 psmode
= (*(u8
*)val
);
1692 /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
1693 /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
1694 if (psmode
!= PS_MODE_ACTIVE
)
1695 ODM_RF_Saving(podmpriv
, true);
1696 rtl8188e_set_FwPwrMode_cmd(Adapter
, psmode
);
1699 case HW_VAR_H2C_FW_JOINBSSRPT
:
1701 u8 mstatus
= (*(u8
*)val
);
1702 rtl8188e_set_FwJoinBssReport_cmd(Adapter
, mstatus
);
1705 case HW_VAR_INITIAL_GAIN
:
1707 struct rtw_dig
*pDigTable
= &podmpriv
->DM_DigTable
;
1708 u32 rx_gain
= ((u32
*)(val
))[0];
1710 if (rx_gain
== 0xff) {/* restore rx gain */
1711 ODM_Write_DIG(podmpriv
, pDigTable
->BackupIGValue
);
1713 pDigTable
->BackupIGValue
= pDigTable
->CurIGValue
;
1714 ODM_Write_DIG(podmpriv
, rx_gain
);
1718 case HW_VAR_TRIGGER_GPIO_0
:
1719 rtl8192cu_trigger_gpio_0(Adapter
);
1721 case HW_VAR_RPT_TIMER_SETTING
:
1723 u16 min_rpt_time
= (*(u16
*)val
);
1724 ODM_RA_Set_TxRPT_Time(podmpriv
, min_rpt_time
);
1727 case HW_VAR_ANTENNA_DIVERSITY_SELECT
:
1729 u8 Optimum_antenna
= (*(u8
*)val
);
1731 /* switch antenna to Optimum_antenna */
1732 if (haldata
->CurAntenna
!= Optimum_antenna
) {
1733 Ant
= (Optimum_antenna
== 2) ? MAIN_ANT
: AUX_ANT
;
1734 rtl88eu_dm_update_rx_idle_ant(&haldata
->odmpriv
, Ant
);
1736 haldata
->CurAntenna
= Optimum_antenna
;
1740 case HW_VAR_EFUSE_BYTES
: /* To set EFUE total used bytes, added by Roger, 2008.12.22. */
1741 haldata
->EfuseUsedBytes
= *((u16
*)val
);
1743 case HW_VAR_FIFO_CLEARN_UP
:
1745 struct pwrctrl_priv
*pwrpriv
= &Adapter
->pwrctrlpriv
;
1749 usb_write8(Adapter
, REG_TXPAUSE
, 0xff);
1752 Adapter
->xmitpriv
.nqos_ssn
= usb_read16(Adapter
, REG_NQOS_SEQ
);
1754 if (!pwrpriv
->bkeepfwalive
) {
1756 usb_write32(Adapter
, REG_RXPKT_NUM
, (usb_read32(Adapter
, REG_RXPKT_NUM
)|RW_RELEASE_EN
));
1758 if (!(usb_read32(Adapter
, REG_RXPKT_NUM
)&RXDMA_IDLE
))
1762 DBG_88E("Stop RX DMA failed......\n");
1765 usb_write16(Adapter
, REG_RQPN_NPQ
, 0x0);
1766 usb_write32(Adapter
, REG_RQPN
, 0x80000000);
1771 case HW_VAR_CHECK_TXBUF
:
1773 case HW_VAR_APFM_ON_MAC
:
1774 haldata
->bMacPwrCtrlOn
= *val
;
1775 DBG_88E("%s: bMacPwrCtrlOn=%d\n", __func__
, haldata
->bMacPwrCtrlOn
);
1777 case HW_VAR_TX_RPT_MAX_MACID
:
1780 DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid
, maxMacid
+1);
1781 usb_write8(Adapter
, REG_TX_RPT_CTRL
+1, maxMacid
+1);
1784 case HW_VAR_H2C_MEDIA_STATUS_RPT
:
1785 rtl8188e_set_FwMediaStatus_cmd(Adapter
, (*(__le16
*)val
));
1787 case HW_VAR_BCN_VALID
:
1788 /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
1789 usb_write8(Adapter
, REG_TDECTRL
+2, usb_read8(Adapter
, REG_TDECTRL
+2) | BIT(0));
1796 static void GetHwReg8188EU(struct adapter
*Adapter
, u8 variable
, u8
*val
)
1798 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
1799 struct odm_dm_struct
*podmpriv
= &haldata
->odmpriv
;
1802 case HW_VAR_BASIC_RATE
:
1803 *((u16
*)(val
)) = haldata
->BasicRateSet
;
1804 case HW_VAR_TXPAUSE
:
1805 val
[0] = usb_read8(Adapter
, REG_TXPAUSE
);
1807 case HW_VAR_BCN_VALID
:
1808 /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
1809 val
[0] = (BIT(0) & usb_read8(Adapter
, REG_TDECTRL
+2)) ? true : false;
1811 case HW_VAR_DM_FLAG
:
1812 val
[0] = podmpriv
->SupportAbility
;
1814 case HW_VAR_RF_TYPE
:
1815 val
[0] = haldata
->rf_type
;
1817 case HW_VAR_FWLPS_RF_ON
:
1819 /* When we halt NIC, we should check if FW LPS is leave. */
1820 if (Adapter
->pwrctrlpriv
.rf_pwrstate
== rf_off
) {
1821 /* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
1822 /* because Fw is unload. */
1826 valRCR
= usb_read32(Adapter
, REG_RCR
);
1827 valRCR
&= 0x00070000;
1835 case HW_VAR_CURRENT_ANTENNA
:
1836 val
[0] = haldata
->CurAntenna
;
1838 case HW_VAR_EFUSE_BYTES
: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */
1839 *((u16
*)(val
)) = haldata
->EfuseUsedBytes
;
1841 case HW_VAR_APFM_ON_MAC
:
1842 *val
= haldata
->bMacPwrCtrlOn
;
1844 case HW_VAR_CHK_HI_QUEUE_EMPTY
:
1845 *val
= ((usb_read32(Adapter
, REG_HGQ_INFORMATION
)&0x0000ff00) == 0) ? true : false;
1854 /* Query setting of specified variable. */
1857 GetHalDefVar8188EUsb(
1858 struct adapter
*Adapter
,
1859 enum hal_def_variable eVariable
,
1863 struct hal_data_8188e
*haldata
= GET_HAL_DATA(Adapter
);
1864 u8 bResult
= _SUCCESS
;
1866 switch (eVariable
) {
1867 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB
:
1869 struct mlme_priv
*pmlmepriv
= &Adapter
->mlmepriv
;
1870 struct sta_priv
*pstapriv
= &Adapter
->stapriv
;
1871 struct sta_info
*psta
;
1872 psta
= rtw_get_stainfo(pstapriv
, pmlmepriv
->cur_network
.network
.MacAddress
);
1874 *((int *)pValue
) = psta
->rssi_stat
.UndecoratedSmoothedPWDB
;
1877 case HAL_DEF_IS_SUPPORT_ANT_DIV
:
1878 *((u8
*)pValue
) = (haldata
->AntDivCfg
== 0) ? false : true;
1880 case HAL_DEF_CURRENT_ANTENNA
:
1881 *((u8
*)pValue
) = haldata
->CurAntenna
;
1883 case HAL_DEF_DRVINFO_SZ
:
1884 *((u32
*)pValue
) = DRVINFO_SZ
;
1886 case HAL_DEF_MAX_RECVBUF_SZ
:
1887 *((u32
*)pValue
) = MAX_RECVBUF_SZ
;
1889 case HAL_DEF_RX_PACKET_OFFSET
:
1890 *((u32
*)pValue
) = RXDESC_SIZE
+ DRVINFO_SZ
;
1892 case HAL_DEF_DBG_DM_FUNC
:
1893 *((u32
*)pValue
) = haldata
->odmpriv
.SupportAbility
;
1895 case HAL_DEF_RA_DECISION_RATE
:
1897 u8 MacID
= *((u8
*)pValue
);
1898 *((u8
*)pValue
) = ODM_RA_GetDecisionRate_8188E(&haldata
->odmpriv
, MacID
);
1901 case HAL_DEF_RA_SGI
:
1903 u8 MacID
= *((u8
*)pValue
);
1904 *((u8
*)pValue
) = ODM_RA_GetShortGI_8188E(&haldata
->odmpriv
, MacID
);
1907 case HAL_DEF_PT_PWR_STATUS
:
1909 u8 MacID
= *((u8
*)pValue
);
1910 *((u8
*)pValue
) = ODM_RA_GetHwPwrStatus_8188E(&haldata
->odmpriv
, MacID
);
1913 case HW_VAR_MAX_RX_AMPDU_FACTOR
:
1914 *((u32
*)pValue
) = MAX_AMPDU_FACTOR_64K
;
1916 case HW_DEF_RA_INFO_DUMP
:
1918 u8 entry_id
= *((u8
*)pValue
);
1919 if (check_fwstate(&Adapter
->mlmepriv
, _FW_LINKED
)) {
1920 DBG_88E("============ RA status check ===================\n");
1921 DBG_88E("Mac_id:%d , RateID = %d, RAUseRate = 0x%08x, RateSGI = %d, DecisionRate = 0x%02x ,PTStage = %d\n",
1923 haldata
->odmpriv
.RAInfo
[entry_id
].RateID
,
1924 haldata
->odmpriv
.RAInfo
[entry_id
].RAUseRate
,
1925 haldata
->odmpriv
.RAInfo
[entry_id
].RateSGI
,
1926 haldata
->odmpriv
.RAInfo
[entry_id
].DecisionRate
,
1927 haldata
->odmpriv
.RAInfo
[entry_id
].PTStage
);
1931 case HW_DEF_ODM_DBG_FLAG
:
1933 struct odm_dm_struct
*dm_ocm
= &haldata
->odmpriv
;
1934 pr_info("dm_ocm->DebugComponents = 0x%llx\n", dm_ocm
->DebugComponents
);
1937 case HAL_DEF_DBG_DUMP_RXPKT
:
1938 *((u8
*)pValue
) = haldata
->bDumpRxPkt
;
1940 case HAL_DEF_DBG_DUMP_TXPKT
:
1941 *((u8
*)pValue
) = haldata
->bDumpTxPkt
;
1951 static void UpdateHalRAMask8188EUsb(struct adapter
*adapt
, u32 mac_id
, u8 rssi_level
)
1954 u8 networkType
, raid
;
1955 u32 mask
, rate_bitmap
;
1956 u8 shortGIrate
= false;
1957 int supportRateNum
= 0;
1958 struct sta_info
*psta
;
1959 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
1960 struct mlme_ext_priv
*pmlmeext
= &adapt
->mlmeextpriv
;
1961 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1962 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
1964 if (mac_id
>= NUM_STA
) /* CAM_SIZE */
1966 psta
= pmlmeinfo
->FW_sta_info
[mac_id
].psta
;
1970 case 0:/* for infra mode */
1971 supportRateNum
= rtw_get_rateset_len(cur_network
->SupportedRates
);
1972 networkType
= judge_network_type(adapt
, cur_network
->SupportedRates
, supportRateNum
) & 0xf;
1973 raid
= networktype_to_raid(networkType
);
1974 mask
= update_supported_rate(cur_network
->SupportedRates
, supportRateNum
);
1975 mask
|= (pmlmeinfo
->HT_enable
) ? update_MSC_rate(&pmlmeinfo
->HT_caps
) : 0;
1976 if (support_short_GI(adapt
, &pmlmeinfo
->HT_caps
))
1979 case 1:/* for broadcast/multicast */
1980 supportRateNum
= rtw_get_rateset_len(pmlmeinfo
->FW_sta_info
[mac_id
].SupportedRates
);
1981 if (pmlmeext
->cur_wireless_mode
& WIRELESS_11B
)
1982 networkType
= WIRELESS_11B
;
1984 networkType
= WIRELESS_11G
;
1985 raid
= networktype_to_raid(networkType
);
1986 mask
= update_basic_rate(cur_network
->SupportedRates
, supportRateNum
);
1988 default: /* for each sta in IBSS */
1989 supportRateNum
= rtw_get_rateset_len(pmlmeinfo
->FW_sta_info
[mac_id
].SupportedRates
);
1990 networkType
= judge_network_type(adapt
, pmlmeinfo
->FW_sta_info
[mac_id
].SupportedRates
, supportRateNum
) & 0xf;
1991 raid
= networktype_to_raid(networkType
);
1992 mask
= update_supported_rate(cur_network
->SupportedRates
, supportRateNum
);
1994 /* todo: support HT in IBSS */
1998 rate_bitmap
= ODM_Get_Rate_Bitmap(&haldata
->odmpriv
, mac_id
, mask
, rssi_level
);
1999 DBG_88E("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
2000 __func__
, mac_id
, networkType
, mask
, rssi_level
, rate_bitmap
);
2002 mask
&= rate_bitmap
;
2004 init_rate
= get_highest_rate_idx(mask
)&0x3f;
2006 ODM_RA_UpdateRateInfo_8188E(&haldata
->odmpriv
, mac_id
,
2007 raid
, mask
, shortGIrate
);
2011 psta
->init_rate
= init_rate
;
2014 static void SetBeaconRelatedRegisters8188EUsb(struct adapter
*adapt
)
2017 struct mlme_ext_priv
*pmlmeext
= &adapt
->mlmeextpriv
;
2018 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2019 u32 bcn_ctrl_reg
= REG_BCN_CTRL
;
2020 /* reset TSF, enable update TSF, correcting TSF On Beacon */
2023 usb_write16(adapt
, REG_BCN_INTERVAL
, pmlmeinfo
->bcn_interval
);
2024 usb_write8(adapt
, REG_ATIMWND
, 0x02);/* 2ms */
2026 _InitBeaconParameters(adapt
);
2028 usb_write8(adapt
, REG_SLOT
, 0x09);
2030 value32
= usb_read32(adapt
, REG_TCR
);
2032 usb_write32(adapt
, REG_TCR
, value32
);
2035 usb_write32(adapt
, REG_TCR
, value32
);
2037 /* NOTE: Fix test chip's bug (about contention windows's randomness) */
2038 usb_write8(adapt
, REG_RXTSF_OFFSET_CCK
, 0x50);
2039 usb_write8(adapt
, REG_RXTSF_OFFSET_OFDM
, 0x50);
2041 _BeaconFunctionEnable(adapt
, true, true);
2043 ResumeTxBeacon(adapt
);
2045 usb_write8(adapt
, bcn_ctrl_reg
, usb_read8(adapt
, bcn_ctrl_reg
) | BIT(1));
2048 static void rtl8188eu_init_default_value(struct adapter
*adapt
)
2050 struct hal_data_8188e
*haldata
;
2051 struct pwrctrl_priv
*pwrctrlpriv
;
2054 haldata
= GET_HAL_DATA(adapt
);
2055 pwrctrlpriv
= &adapt
->pwrctrlpriv
;
2057 /* init default value */
2058 if (!pwrctrlpriv
->bkeepfwalive
)
2059 haldata
->LastHMEBoxNum
= 0;
2061 /* init dm default value */
2062 haldata
->odmpriv
.RFCalibrateInfo
.bIQKInitialized
= false;
2063 haldata
->odmpriv
.RFCalibrateInfo
.TM_Trigger
= 0;/* for IQK */
2064 haldata
->pwrGroupCnt
= 0;
2065 haldata
->PGMaxGroup
= 13;
2066 haldata
->odmpriv
.RFCalibrateInfo
.ThermalValue_HP_index
= 0;
2067 for (i
= 0; i
< HP_THERMAL_NUM
; i
++)
2068 haldata
->odmpriv
.RFCalibrateInfo
.ThermalValue_HP
[i
] = 0;
2071 void rtl8188eu_set_hal_ops(struct adapter
*adapt
)
2073 struct hal_ops
*halfunc
= &adapt
->HalFunc
;
2075 adapt
->HalData
= kzalloc(sizeof(*adapt
->HalData
), GFP_KERNEL
);
2076 if (!adapt
->HalData
)
2077 DBG_88E("cant not alloc memory for HAL DATA\n");
2079 halfunc
->hal_power_on
= rtl8188eu_InitPowerOn
;
2080 halfunc
->hal_init
= &rtl8188eu_hal_init
;
2081 halfunc
->hal_deinit
= &rtl8188eu_hal_deinit
;
2083 halfunc
->inirp_init
= &rtl8188eu_inirp_init
;
2084 halfunc
->inirp_deinit
= &rtl8188eu_inirp_deinit
;
2086 halfunc
->init_xmit_priv
= &rtl8188eu_init_xmit_priv
;
2088 halfunc
->init_recv_priv
= &rtl8188eu_init_recv_priv
;
2089 halfunc
->free_recv_priv
= &rtl8188eu_free_recv_priv
;
2090 halfunc
->InitSwLeds
= &rtl8188eu_InitSwLeds
;
2091 halfunc
->DeInitSwLeds
= &rtl8188eu_DeInitSwLeds
;
2093 halfunc
->init_default_value
= &rtl8188eu_init_default_value
;
2094 halfunc
->intf_chip_configure
= &rtl8188eu_interface_configure
;
2095 halfunc
->read_adapter_info
= &_ReadAdapterInfo8188EU
;
2097 halfunc
->SetHwRegHandler
= &SetHwReg8188EU
;
2098 halfunc
->GetHwRegHandler
= &GetHwReg8188EU
;
2099 halfunc
->GetHalDefVarHandler
= &GetHalDefVar8188EUsb
;
2101 halfunc
->UpdateRAMaskHandler
= &UpdateHalRAMask8188EUsb
;
2102 halfunc
->SetBeaconRelatedRegistersHandler
= &SetBeaconRelatedRegisters8188EUsb
;
2104 halfunc
->hal_xmit
= &rtl8188eu_hal_xmit
;
2105 halfunc
->mgnt_xmit
= &rtl8188eu_mgnt_xmit
;
2107 rtl8188e_set_hal_ops(halfunc
);