| /* |
| * Copyright (c) 2007-2008 Atheros Communications Inc. |
| * |
| * Permission to use, copy, modify, and/or distribute this software for any |
| * purpose with or without fee is hereby granted, provided that the above |
| * copyright notice and this permission notice appear in all copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| */ |
| #include "../80211core/cprecomp.h" |
| #include "hpani.h" |
| #include "hpusb.h" |
| #include "otus.ini" |
| |
| extern const u32_t zcFwImage[]; |
| extern const u32_t zcFwImageSize; |
| extern const u32_t zcDKFwImage[]; |
| extern const u32_t zcDKFwImageSize; |
| extern const u32_t zcFwImageSPI[]; |
| extern const u32_t zcFwImageSPISize; |
| |
| #ifdef ZM_OTUS_LINUX_PHASE_2 |
| extern const u32_t zcFwBufImage[]; |
| extern const u32_t zcFwBufImageSize; |
| extern const u32_t zcP2FwImage[]; |
| extern const u32_t zcP2FwImageSize; |
| #endif |
| extern void zfInitCmdQueue(zdev_t* dev); |
| extern u16_t zfIssueCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, |
| u16_t src, u8_t* buf); |
| extern void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen); |
| extern u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val); |
| extern u16_t zfFlushDelayWrite(zdev_t* dev); |
| extern void zfUsbInit(zdev_t* dev); |
| extern u16_t zfFirmwareDownload(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset); |
| extern u16_t zfFirmwareDownloadNotJump(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset); |
| extern void zfUsbFree(zdev_t* dev); |
| extern u16_t zfCwmIsExtChanBusy(u32_t ctlBusy, u32_t extBusy); |
| extern void zfCoreCwmBusy(zdev_t* dev, u16_t busy); |
| |
| /* Prototypes */ |
| void zfInitRf(zdev_t* dev, u32_t frequency); |
| void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40); |
| void zfInitMac(zdev_t* dev); |
| |
| void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset); |
| void zfInitPowerCal(zdev_t* dev); |
| |
| #ifdef ZM_DRV_INIT_USB_MODE |
| void zfInitUsbMode(zdev_t* dev); |
| u16_t zfHpUsbReset(zdev_t* dev); |
| #endif |
| |
| /* Bank 0 1 2 3 5 6 7 */ |
| void zfSetRfRegs(zdev_t* dev, u32_t frequency); |
| /* Bank 4 */ |
| void zfSetBank4AndPowerTable(zdev_t* dev, u32_t frequency, u8_t bw40, |
| u8_t extOffset); |
| /* Get param for turnoffdyn */ |
| void zfGetHwTurnOffdynParam(zdev_t* dev, |
| u32_t frequency, u8_t bw40, u8_t extOffset, |
| int* delta_slope_coeff_exp, |
| int* delta_slope_coeff_man, |
| int* delta_slope_coeff_exp_shgi, |
| int* delta_slope_coeff_man_shgi); |
| |
| void zfSelAdcClk(zdev_t* dev, u8_t bw40, u32_t frequency); |
| u32_t zfHpEchoCommand(zdev_t* dev, u32_t value); |
| |
| |
| |
| #define zm_hp_priv(x) (((struct zsHpPriv*)wd->hpPrivate)->x) |
| static struct zsHpPriv zgHpPriv; |
| |
| #define ZM_FIRMWARE_WLAN_ADDR 0x200000 |
| #define ZM_FIRMWARE_SPI_ADDR 0x114000 |
| /* 0: real chip 1: FPGA test */ |
| #define ZM_FPGA_PHY 0 |
| |
| #define reg_write(addr, val) zfDelayWriteInternalReg(dev, addr+0x1bc000, val) |
| #define zm_min(A, B) ((A>B)? B:A) |
| |
| |
| /******************** Intialization ********************/ |
| u16_t zfHpInit(zdev_t* dev, u32_t frequency) |
| { |
| u16_t ret; |
| zmw_get_wlan_dev(dev); |
| |
| /* Initializa HAL Plus private variables */ |
| wd->hpPrivate = &zgHpPriv; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->halCapability = ZM_HP_CAP_11N; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->hwFrequency = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->hwBw40 = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->hwExtOffset = 0; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->disableDfsCh = 0; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->ledMode[0] = 1; |
| ((struct zsHpPriv*)wd->hpPrivate)->ledMode[1] = 1; |
| ((struct zsHpPriv*)wd->hpPrivate)->strongRSSI = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->rxStrongRSSI = 0; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->slotType = 1; |
| ((struct zsHpPriv*)wd->hpPrivate)->aggPktNum = 0x10000a; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->eepromImageIndex = 0; |
| |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->eepromImageRdReq = 0; |
| #ifdef ZM_OTUS_RX_STREAM_MODE |
| ((struct zsHpPriv*)wd->hpPrivate)->remainBuf = NULL; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxRemainLen = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxPktLen = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxPadLen = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxTransferLen = 0; |
| #endif |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->enableBBHeavyClip = 1; |
| ((struct zsHpPriv*)wd->hpPrivate)->hwBBHeavyClip = 1; // force enable 8107 |
| ((struct zsHpPriv*)wd->hpPrivate)->doBBHeavyClip = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->setValueHeavyClip = 0; |
| |
| |
| /* Initialize driver core */ |
| zfInitCmdQueue(dev); |
| |
| /* Initialize USB */ |
| zfUsbInit(dev); |
| |
| #if ZM_SW_LOOP_BACK != 1 |
| |
| /* TODO : [Download FW] */ |
| if (wd->modeMDKEnable) |
| { |
| /* download the MDK firmware */ |
| if ((ret = zfFirmwareDownload(dev, (u32_t*)zcDKFwImage, |
| (u32_t)zcDKFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) |
| { |
| /* TODO : exception handling */ |
| //return 1; |
| } |
| } |
| else |
| { |
| #ifndef ZM_OTUS_LINUX_PHASE_2 |
| /* download the normal firmware */ |
| if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, |
| (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) |
| { |
| /* TODO : exception handling */ |
| //return 1; |
| } |
| #else |
| |
| // 1-PH fw: ReadMac() store some global variable |
| if ((ret = zfFirmwareDownloadNotJump(dev, (u32_t*)zcFwBufImage, |
| (u32_t)zcFwBufImageSize, 0x102800)) != ZM_SUCCESS) |
| { |
| DbgPrint("Dl zcFwBufImage failed!"); |
| } |
| |
| zfwSleep(dev, 1000); |
| |
| if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, |
| (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) |
| { |
| DbgPrint("Dl zcFwBufImage failed!"); |
| } |
| #endif |
| } |
| #endif |
| |
| #ifdef ZM_DRV_INIT_USB_MODE |
| /* Init USB Mode */ |
| zfInitUsbMode(dev); |
| |
| /* Do the USB Reset */ |
| zfHpUsbReset(dev); |
| #endif |
| |
| /* Register setting */ |
| /* ZM_DRIVER_MODEL_TYPE_MDK |
| * 1=>for MDK, disable init RF, PHY, and MAC, |
| * 0=>normal init |
| */ |
| //#if ((ZM_SW_LOOP_BACK != 1) && (ZM_DRIVER_MODEL_TYPE_MDK !=1)) |
| #if ZM_SW_LOOP_BACK != 1 |
| if(!wd->modeMDKEnable) |
| { |
| /* Init MAC */ |
| zfInitMac(dev); |
| |
| #if ZM_FW_LOOP_BACK != 1 |
| /* Init PHY */ |
| zfInitPhy(dev, frequency, 0); |
| |
| /* Init RF */ |
| zfInitRf(dev, frequency); |
| |
| #if ZM_FPGA_PHY == 0 |
| /* BringUp issue */ |
| //zfDelayWriteInternalReg(dev, 0x9800+0x1bc000, 0x10000007); |
| //zfFlushDelayWrite(dev); |
| #endif |
| |
| #endif /* end of ZM_FW_LOOP_BACK != 1 */ |
| } |
| #endif /* end of ((ZM_SW_LOOP_BACK != 1) && (ZM_DRIVER_MODEL_TYPE_MDK !=1)) */ |
| |
| zfHpEchoCommand(dev, 0xAABBCCDD); |
| |
| return 0; |
| } |
| |
| |
| u16_t zfHpReinit(zdev_t* dev, u32_t frequency) |
| { |
| u16_t ret; |
| zmw_get_wlan_dev(dev); |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->halReInit = 1; |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->strongRSSI = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->rxStrongRSSI = 0; |
| |
| #ifdef ZM_OTUS_RX_STREAM_MODE |
| if (((struct zsHpPriv*)wd->hpPrivate)->remainBuf != NULL) |
| { |
| zfwBufFree(dev, ((struct zsHpPriv*)wd->hpPrivate)->remainBuf, 0); |
| } |
| ((struct zsHpPriv*)wd->hpPrivate)->remainBuf = NULL; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxRemainLen = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxPktLen = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxPadLen = 0; |
| ((struct zsHpPriv*)wd->hpPrivate)->usbRxTransferLen = 0; |
| #endif |
| |
| zfInitCmdQueue(dev); |
| zfCoreReinit(dev); |
| |
| #ifndef ZM_OTUS_LINUX_PHASE_2 |
| /* Download firmware */ |
| if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, |
| (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) |
| { |
| /* TODO : exception handling */ |
| //return 1; |
| } |
| #else |
| if ((ret = zfFirmwareDownload(dev, (u32_t*)zcP2FwImage, |
| (u32_t)zcP2FwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) |
| { |
| /* TODO : exception handling */ |
| //return 1; |
| } |
| #endif |
| |
| #ifdef ZM_DRV_INIT_USB_MODE |
| /* Init USB Mode */ |
| zfInitUsbMode(dev); |
| |
| /* Do the USB Reset */ |
| zfHpUsbReset(dev); |
| #endif |
| |
| /* Init MAC */ |
| zfInitMac(dev); |
| |
| /* Init PHY */ |
| zfInitPhy(dev, frequency, 0); |
| /* Init RF */ |
| zfInitRf(dev, frequency); |
| |
| #if ZM_FPGA_PHY == 0 |
| /* BringUp issue */ |
| //zfDelayWriteInternalReg(dev, 0x9800+0x1bc000, 0x10000007); |
| //zfFlushDelayWrite(dev); |
| #endif |
| |
| zfHpEchoCommand(dev, 0xAABBCCDD); |
| |
| return 0; |
| } |
| |
| |
| u16_t zfHpRelease(zdev_t* dev) |
| { |
| /* Free USB resource */ |
| zfUsbFree(dev); |
| |
| return 0; |
| } |
| |
| /* MDK mode setting for dontRetransmit */ |
| void zfHpConfigFM(zdev_t* dev, u32_t RxMaxSize, u32_t DontRetransmit) |
| { |
| u32_t cmd[3]; |
| u16_t ret; |
| |
| cmd[0] = 8 | (ZM_CMD_CONFIG << 8); |
| cmd[1] = RxMaxSize; /* zgRxMaxSize */ |
| cmd[2] = DontRetransmit; /* zgDontRetransmit */ |
| |
| ret = zfIssueCmd(dev, cmd, 12, ZM_OID_INTERNAL_WRITE, 0); |
| } |
| |
| const u8_t zcXpdToPd[16] = |
| { |
| /* 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF */ |
| 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2 |
| }; |
| |
| /******************** RF and PHY ********************/ |
| |
| void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40) |
| { |
| u16_t i, j, k; |
| u16_t entries; |
| u16_t modesIndex = 0; |
| u16_t freqIndex = 0; |
| u32_t tmp, tmp1; |
| struct zsHpPriv* hpPriv; |
| |
| u32_t eepromBoardData[15][6] = { |
| /* Register A-20 A-20/40 G-20/40 G-20 G-Turbo */ |
| {0x9964, 0, 0, 0, 0, 0}, |
| {0x9960, 0, 0, 0, 0, 0}, |
| {0xb960, 0, 0, 0, 0, 0}, |
| {0x9844, 0, 0, 0, 0, 0}, |
| {0x9850, 0, 0, 0, 0, 0}, |
| {0x9834, 0, 0, 0, 0, 0}, |
| {0x9828, 0, 0, 0, 0, 0}, |
| {0xc864, 0, 0, 0, 0, 0}, |
| {0x9848, 0, 0, 0, 0, 0}, |
| {0xb848, 0, 0, 0, 0, 0}, |
| {0xa20c, 0, 0, 0, 0, 0}, |
| {0xc20c, 0, 0, 0, 0, 0}, |
| {0x9920, 0, 0, 0, 0, 0}, |
| {0xb920, 0, 0, 0, 0, 0}, |
| {0xa258, 0, 0, 0, 0, 0}, |
| }; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv=wd->hpPrivate; |
| |
| /* #1 Save the initial value of the related RIFS register settings */ |
| //((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy++; |
| |
| /* |
| * Setup the indices for the next set of register array writes |
| * PHY mode is static20 / 2040 |
| * Frequency is 2.4GHz (B) / 5GHz (A) |
| */ |
| if ( frequency > ZM_CH_G_14 ) |
| { |
| /* 5GHz */ |
| freqIndex = 1; |
| if (bw40) |
| { |
| modesIndex = 2; |
| zm_debug_msg0("init ar5416Modes in 2: A-20/40"); |
| } |
| else |
| { |
| modesIndex = 1; |
| zm_debug_msg0("init ar5416Modes in 1: A-20"); |
| } |
| } |
| else |
| { |
| /* 2.4GHz */ |
| freqIndex = 2; |
| if (bw40) |
| { |
| modesIndex = 3; |
| zm_debug_msg0("init ar5416Modes in 3: G-20/40"); |
| } |
| else |
| { |
| modesIndex = 4; |
| zm_debug_msg0("init ar5416Modes in 4: G-20"); |
| } |
| } |
| |
| |
| #if ZM_FPGA_PHY == 1 |
| /* Starting External Hainan Register Initialization */ |
| /* TODO: */ |
| |
| zfwSleep(dev, 10); |
| #endif |
| |
| /* |
| *Set correct Baseband to analog shift setting to access analog chips. |
| */ |
| //reg_write(PHY_BASE, 0x00000007); |
| // reg_write(0x9800, 0x00000007); |
| |
| /* |
| * Write addac shifts |
| */ |
| // do this in firmware |
| |
| |
| |
| /* Zeroize board data */ |
| for (j=0; j<15; j++) |
| { |
| for (k=1; k<=4; k++) |
| { |
| eepromBoardData[j][k] = 0; |
| } |
| } |
| /* |
| * Register setting by mode |
| */ |
| |
| entries = sizeof(ar5416Modes) / sizeof(*ar5416Modes); |
| zm_msg1_scan(ZM_LV_2, "Modes register setting entries=", entries); |
| for (i=0; i<entries; i++) |
| { |
| #if 0 |
| if ( ((struct zsHpPriv*)wd->hpPrivate)->hwNotFirstInit && (ar5416Modes[i][0] == 0xa27c) ) |
| { |
| /* Force disable CR671 bit20 / 7823 */ |
| /* The bug has to do with the polarity of the pdadc offset calibration. There */ |
| /* is an initial calibration that is OK, and there is a continuous */ |
| /* calibration that updates the pddac with the wrong polarity. Fortunately */ |
| /* the second loop can be disabled with a bit called en_pd_dc_offset_thr. */ |
| |
| reg_write(ar5416Modes[i][0], (ar5416Modes[i][modesIndex]& 0xffefffff) ); |
| ((struct zsHpPriv*)wd->hpPrivate)->hwNotFirstInit = 1; |
| } |
| else |
| { |
| #endif |
| /* FirstTime Init or not 0xa27c(CR671) */ |
| reg_write(ar5416Modes[i][0], ar5416Modes[i][modesIndex]); |
| // } |
| /* Initialize board data */ |
| for (j=0; j<15; j++) |
| { |
| if (ar5416Modes[i][0] == eepromBoardData[j][0]) |
| { |
| for (k=1; k<=4; k++) |
| { |
| eepromBoardData[j][k] = ar5416Modes[i][k]; |
| } |
| } |
| } |
| /* #1 Save the initial value of the related RIFS register settings */ |
| //if( ((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy == 1 ) |
| { |
| switch(ar5416Modes[i][0]) |
| { |
| case 0x9850 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initDesiredSigSize = ar5416Modes[i][modesIndex]; |
| break; |
| case 0x985c : |
| ((struct zsHpPriv*)wd->hpPrivate)->initAGC = ar5416Modes[i][modesIndex]; |
| break; |
| case 0x9860 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initAgcControl = ar5416Modes[i][modesIndex]; |
| break; |
| case 0x9918 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initSearchStartDelay = ar5416Modes[i][modesIndex]; |
| break; |
| case 0x99ec : |
| ((struct zsHpPriv*)wd->hpPrivate)->initRIFSSearchParams = ar5416Modes[i][modesIndex]; |
| break; |
| case 0xa388 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initFastChannelChangeControl = ar5416Modes[i][modesIndex]; |
| default : |
| break; |
| } |
| } |
| } |
| #if 0 |
| zfFlushDelayWrite(dev); |
| |
| /* |
| * Common Register setting |
| */ |
| entries = sizeof(ar5416Common) / sizeof(*ar5416Common); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Common[i][0], ar5416Common[i][1]); |
| } |
| zfFlushDelayWrite(dev); |
| |
| /* |
| * RF Gain setting by freqIndex |
| */ |
| entries = sizeof(ar5416BB_RfGain) / sizeof(*ar5416BB_RfGain); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416BB_RfGain[i][0], ar5416BB_RfGain[i][freqIndex]); |
| } |
| zfFlushDelayWrite(dev); |
| |
| /* |
| * Moved ar5416InitChainMask() here to ensure the swap bit is set before |
| * the pdadc table is written. Swap must occur before any radio dependent |
| * replicated register access. The pdadc curve addressing in particular |
| * depends on the consistent setting of the swap bit. |
| */ |
| //ar5416InitChainMask(pDev); |
| |
| /* Setup the transmit power values. */ |
| // TODO |
| #endif |
| |
| /* Update 5G board data */ |
| //Ant control common |
| tmp = hpPriv->eepromImage[0x100+0x144*2/4]; |
| eepromBoardData[0][1] = tmp; |
| eepromBoardData[0][2] = tmp; |
| //Ant control chain 0 |
| tmp = hpPriv->eepromImage[0x100+0x140*2/4]; |
| eepromBoardData[1][1] = tmp; |
| eepromBoardData[1][2] = tmp; |
| //Ant control chain 2 |
| tmp = hpPriv->eepromImage[0x100+0x142*2/4]; |
| eepromBoardData[2][1] = tmp; |
| eepromBoardData[2][2] = tmp; |
| //SwSettle |
| tmp = hpPriv->eepromImage[0x100+0x146*2/4]; |
| tmp = (tmp >> 16) & 0x7f; |
| eepromBoardData[3][1] &= (~((u32_t)0x3f80)); |
| eepromBoardData[3][1] |= (tmp << 7); |
| #if 0 |
| //swSettleHt40 |
| tmp = hpPriv->eepromImage[0x100+0x158*2/4]; |
| tmp = (tmp) & 0x7f; |
| eepromBoardData[3][2] &= (~((u32_t)0x3f80)); |
| eepromBoardData[3][2] |= (tmp << 7); |
| #endif |
| //adcDesired, pdaDesired |
| tmp = hpPriv->eepromImage[0x100+0x148*2/4]; |
| tmp = (tmp >> 24); |
| tmp1 = hpPriv->eepromImage[0x100+0x14a*2/4]; |
| tmp1 = tmp1 & 0xff; |
| tmp = tmp + (tmp1<<8); |
| eepromBoardData[4][1] &= (~((u32_t)0xffff)); |
| eepromBoardData[4][1] |= tmp; |
| eepromBoardData[4][2] &= (~((u32_t)0xffff)); |
| eepromBoardData[4][2] |= tmp; |
| //TxEndToXpaOff, TxFrameToXpaOn |
| tmp = hpPriv->eepromImage[0x100+0x14a*2/4]; |
| tmp = (tmp >> 24) & 0xff; |
| tmp1 = hpPriv->eepromImage[0x100+0x14c*2/4]; |
| tmp1 = (tmp1 >> 8) & 0xff; |
| tmp = (tmp<<24) + (tmp<<16) + (tmp1<<8) + tmp1; |
| eepromBoardData[5][1] = tmp; |
| eepromBoardData[5][2] = tmp; |
| //TxEnaToRxOm |
| tmp = hpPriv->eepromImage[0x100+0x14c*2/4] & 0xff; |
| eepromBoardData[6][1] &= (~((u32_t)0xff0000)); |
| eepromBoardData[6][1] |= (tmp<<16); |
| eepromBoardData[6][2] &= (~((u32_t)0xff0000)); |
| eepromBoardData[6][2] |= (tmp<<16); |
| //Thresh62 |
| tmp = hpPriv->eepromImage[0x100+0x14c*2/4]; |
| tmp = (tmp >> 16) & 0x7f; |
| eepromBoardData[7][1] &= (~((u32_t)0x7f000)); |
| eepromBoardData[7][1] |= (tmp<<12); |
| eepromBoardData[7][2] &= (~((u32_t)0x7f000)); |
| eepromBoardData[7][2] |= (tmp<<12); |
| //TxRxAtten chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x146*2/4]; |
| tmp = (tmp >> 24) & 0x3f; |
| eepromBoardData[8][1] &= (~((u32_t)0x3f000)); |
| eepromBoardData[8][1] |= (tmp<<12); |
| eepromBoardData[8][2] &= (~((u32_t)0x3f000)); |
| eepromBoardData[8][2] |= (tmp<<12); |
| //TxRxAtten chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x148*2/4] & 0x3f; |
| eepromBoardData[9][1] &= (~((u32_t)0x3f000)); |
| eepromBoardData[9][1] |= (tmp<<12); |
| eepromBoardData[9][2] &= (~((u32_t)0x3f000)); |
| eepromBoardData[9][2] |= (tmp<<12); |
| //TxRxMargin chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x148*2/4]; |
| tmp = (tmp >> 8) & 0x3f; |
| eepromBoardData[10][1] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[10][1] |= (tmp<<18); |
| eepromBoardData[10][2] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[10][2] |= (tmp<<18); |
| //TxRxMargin chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x148*2/4]; |
| tmp = (tmp >> 16) & 0x3f; |
| eepromBoardData[11][1] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[11][1] |= (tmp<<18); |
| eepromBoardData[11][2] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[11][2] |= (tmp<<18); |
| //iqCall chain_0, iqCallQ chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x14e*2/4]; |
| tmp = (tmp >> 24) & 0x3f; |
| tmp1 = hpPriv->eepromImage[0x100+0x150*2/4]; |
| tmp1 = (tmp1 >> 8) & 0x1f; |
| tmp = (tmp<<5) + tmp1; |
| eepromBoardData[12][1] &= (~((u32_t)0x7ff)); |
| eepromBoardData[12][1] |= (tmp); |
| eepromBoardData[12][2] &= (~((u32_t)0x7ff)); |
| eepromBoardData[12][2] |= (tmp); |
| //iqCall chain_2, iqCallQ chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x150*2/4]; |
| tmp = tmp & 0x3f; |
| tmp1 = hpPriv->eepromImage[0x100+0x150*2/4]; |
| tmp1 = (tmp1 >> 16) & 0x1f; |
| tmp = (tmp<<5) + tmp1; |
| eepromBoardData[13][1] &= (~((u32_t)0x7ff)); |
| eepromBoardData[13][1] |= (tmp); |
| eepromBoardData[13][2] &= (~((u32_t)0x7ff)); |
| eepromBoardData[13][2] |= (tmp); |
| //bsw_Margin chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x156*2/4]; |
| tmp = (tmp >> 16) & 0xf; |
| eepromBoardData[10][1] &= (~((u32_t)0x3c00)); |
| eepromBoardData[10][1] |= (tmp << 10); |
| eepromBoardData[10][2] &= (~((u32_t)0x3c00)); |
| eepromBoardData[10][2] |= (tmp << 10); |
| //xpd gain mask |
| tmp = hpPriv->eepromImage[0x100+0x14e*2/4]; |
| tmp = (tmp >> 8) & 0xf; |
| eepromBoardData[14][1] &= (~((u32_t)0xf0000)); |
| eepromBoardData[14][1] |= (zcXpdToPd[tmp] << 16); |
| eepromBoardData[14][2] &= (~((u32_t)0xf0000)); |
| eepromBoardData[14][2] |= (zcXpdToPd[tmp] << 16); |
| #if 0 |
| //bsw_Atten chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x156*2/4]; |
| tmp = (tmp) & 0x1f; |
| eepromBoardData[10][1] &= (~((u32_t)0x1f)); |
| eepromBoardData[10][1] |= (tmp); |
| eepromBoardData[10][2] &= (~((u32_t)0x1f)); |
| eepromBoardData[10][2] |= (tmp); |
| //bsw_Margin chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x156*2/4]; |
| tmp = (tmp >> 24) & 0xf; |
| eepromBoardData[11][1] &= (~((u32_t)0x3c00)); |
| eepromBoardData[11][1] |= (tmp << 10); |
| eepromBoardData[11][2] &= (~((u32_t)0x3c00)); |
| eepromBoardData[11][2] |= (tmp << 10); |
| //bsw_Atten chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x156*2/4]; |
| tmp = (tmp >> 8) & 0x1f; |
| eepromBoardData[11][1] &= (~((u32_t)0x1f)); |
| eepromBoardData[11][1] |= (tmp); |
| eepromBoardData[11][2] &= (~((u32_t)0x1f)); |
| eepromBoardData[11][2] |= (tmp); |
| #endif |
| |
| /* Update 2.4G board data */ |
| //Ant control common |
| tmp = hpPriv->eepromImage[0x100+0x170*2/4]; |
| tmp = tmp >> 24; |
| tmp1 = hpPriv->eepromImage[0x100+0x172*2/4]; |
| tmp = tmp + (tmp1 << 8); |
| eepromBoardData[0][3] = tmp; |
| eepromBoardData[0][4] = tmp; |
| //Ant control chain 0 |
| tmp = hpPriv->eepromImage[0x100+0x16c*2/4]; |
| tmp = tmp >> 24; |
| tmp1 = hpPriv->eepromImage[0x100+0x16e*2/4]; |
| tmp = tmp + (tmp1 << 8); |
| eepromBoardData[1][3] = tmp; |
| eepromBoardData[1][4] = tmp; |
| //Ant control chain 2 |
| tmp = hpPriv->eepromImage[0x100+0x16e*2/4]; |
| tmp = tmp >> 24; |
| tmp1 = hpPriv->eepromImage[0x100+0x170*2/4]; |
| tmp = tmp + (tmp1 << 8); |
| eepromBoardData[2][3] = tmp; |
| eepromBoardData[2][4] = tmp; |
| //SwSettle |
| tmp = hpPriv->eepromImage[0x100+0x174*2/4]; |
| tmp = (tmp >> 8) & 0x7f; |
| eepromBoardData[3][4] &= (~((u32_t)0x3f80)); |
| eepromBoardData[3][4] |= (tmp << 7); |
| #if 0 |
| //swSettleHt40 |
| tmp = hpPriv->eepromImage[0x100+0x184*2/4]; |
| tmp = (tmp >> 24) & 0x7f; |
| eepromBoardData[3][3] &= (~((u32_t)0x3f80)); |
| eepromBoardData[3][3] |= (tmp << 7); |
| #endif |
| //adcDesired, pdaDesired |
| tmp = hpPriv->eepromImage[0x100+0x176*2/4]; |
| tmp = (tmp >> 16) & 0xff; |
| tmp1 = hpPriv->eepromImage[0x100+0x176*2/4]; |
| tmp1 = tmp1 >> 24; |
| tmp = tmp + (tmp1<<8); |
| eepromBoardData[4][3] &= (~((u32_t)0xffff)); |
| eepromBoardData[4][3] |= tmp; |
| eepromBoardData[4][4] &= (~((u32_t)0xffff)); |
| eepromBoardData[4][4] |= tmp; |
| //TxEndToXpaOff, TxFrameToXpaOn |
| tmp = hpPriv->eepromImage[0x100+0x178*2/4]; |
| tmp = (tmp >> 16) & 0xff; |
| tmp1 = hpPriv->eepromImage[0x100+0x17a*2/4]; |
| tmp1 = tmp1 & 0xff; |
| tmp = (tmp << 24) + (tmp << 16) + (tmp1 << 8) + tmp1; |
| eepromBoardData[5][3] = tmp; |
| eepromBoardData[5][4] = tmp; |
| //TxEnaToRxOm |
| tmp = hpPriv->eepromImage[0x100+0x178*2/4]; |
| tmp = (tmp >> 24); |
| eepromBoardData[6][3] &= (~((u32_t)0xff0000)); |
| eepromBoardData[6][3] |= (tmp<<16); |
| eepromBoardData[6][4] &= (~((u32_t)0xff0000)); |
| eepromBoardData[6][4] |= (tmp<<16); |
| //Thresh62 |
| tmp = hpPriv->eepromImage[0x100+0x17a*2/4]; |
| tmp = (tmp >> 8) & 0x7f; |
| eepromBoardData[7][3] &= (~((u32_t)0x7f000)); |
| eepromBoardData[7][3] |= (tmp<<12); |
| eepromBoardData[7][4] &= (~((u32_t)0x7f000)); |
| eepromBoardData[7][4] |= (tmp<<12); |
| //TxRxAtten chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x174*2/4]; |
| tmp = (tmp >> 16) & 0x3f; |
| eepromBoardData[8][3] &= (~((u32_t)0x3f000)); |
| eepromBoardData[8][3] |= (tmp<<12); |
| eepromBoardData[8][4] &= (~((u32_t)0x3f000)); |
| eepromBoardData[8][4] |= (tmp<<12); |
| //TxRxAtten chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x174*2/4]; |
| tmp = (tmp >> 24) & 0x3f; |
| eepromBoardData[9][3] &= (~((u32_t)0x3f000)); |
| eepromBoardData[9][3] |= (tmp<<12); |
| eepromBoardData[9][4] &= (~((u32_t)0x3f000)); |
| eepromBoardData[9][4] |= (tmp<<12); |
| //TxRxMargin chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x176*2/4]; |
| tmp = (tmp) & 0x3f; |
| eepromBoardData[10][3] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[10][3] |= (tmp<<18); |
| eepromBoardData[10][4] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[10][4] |= (tmp<<18); |
| //TxRxMargin chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x176*2/4]; |
| tmp = (tmp >> 8) & 0x3f; |
| eepromBoardData[11][3] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[11][3] |= (tmp<<18); |
| eepromBoardData[11][4] &= (~((u32_t)0xfc0000)); |
| eepromBoardData[11][4] |= (tmp<<18); |
| //iqCall chain_0, iqCallQ chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x17c*2/4]; |
| tmp = (tmp >> 16) & 0x3f; |
| tmp1 = hpPriv->eepromImage[0x100+0x17e*2/4]; |
| tmp1 = (tmp1) & 0x1f; |
| tmp = (tmp<<5) + tmp1; |
| eepromBoardData[12][3] &= (~((u32_t)0x7ff)); |
| eepromBoardData[12][3] |= (tmp); |
| eepromBoardData[12][4] &= (~((u32_t)0x7ff)); |
| eepromBoardData[12][4] |= (tmp); |
| //iqCall chain_2, iqCallQ chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x17c*2/4]; |
| tmp = (tmp>>24) & 0x3f; |
| tmp1 = hpPriv->eepromImage[0x100+0x17e*2/4]; |
| tmp1 = (tmp1 >> 8) & 0x1f; |
| tmp = (tmp<<5) + tmp1; |
| eepromBoardData[13][3] &= (~((u32_t)0x7ff)); |
| eepromBoardData[13][3] |= (tmp); |
| eepromBoardData[13][4] &= (~((u32_t)0x7ff)); |
| eepromBoardData[13][4] |= (tmp); |
| //xpd gain mask |
| tmp = hpPriv->eepromImage[0x100+0x17c*2/4]; |
| tmp = tmp & 0xf; |
| DbgPrint("xpd=0x%x, pd=0x%x\n", tmp, zcXpdToPd[tmp]); |
| eepromBoardData[14][3] &= (~((u32_t)0xf0000)); |
| eepromBoardData[14][3] |= (zcXpdToPd[tmp] << 16); |
| eepromBoardData[14][4] &= (~((u32_t)0xf0000)); |
| eepromBoardData[14][4] |= (zcXpdToPd[tmp] << 16); |
| #if 0 |
| //bsw_Margin chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x184*2/4]; |
| tmp = (tmp >> 8) & 0xf; |
| eepromBoardData[10][3] &= (~((u32_t)0x3c00)); |
| eepromBoardData[10][3] |= (tmp << 10); |
| eepromBoardData[10][4] &= (~((u32_t)0x3c00)); |
| eepromBoardData[10][4] |= (tmp << 10); |
| //bsw_Atten chain_0 |
| tmp = hpPriv->eepromImage[0x100+0x182*2/4]; |
| tmp = (tmp>>24) & 0x1f; |
| eepromBoardData[10][3] &= (~((u32_t)0x1f)); |
| eepromBoardData[10][3] |= (tmp); |
| eepromBoardData[10][4] &= (~((u32_t)0x1f)); |
| eepromBoardData[10][4] |= (tmp); |
| //bsw_Margin chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x184*2/4]; |
| tmp = (tmp >> 16) & 0xf; |
| eepromBoardData[11][3] &= (~((u32_t)0x3c00)); |
| eepromBoardData[11][3] |= (tmp << 10); |
| eepromBoardData[11][4] &= (~((u32_t)0x3c00)); |
| eepromBoardData[11][4] |= (tmp << 10); |
| //bsw_Atten chain_2 |
| tmp = hpPriv->eepromImage[0x100+0x184*2/4]; |
| tmp = (tmp) & 0x1f; |
| eepromBoardData[11][3] &= (~((u32_t)0x1f)); |
| eepromBoardData[11][3] |= (tmp); |
| eepromBoardData[11][4] &= (~((u32_t)0x1f)); |
| eepromBoardData[11][4] |= (tmp); |
| #endif |
| |
| #if 0 |
| for (j=0; j<14; j++) |
| { |
| DbgPrint("%04x, %08x, %08x, %08x, %08x\n", eepromBoardData[j][0], eepromBoardData[j][1], eepromBoardData[j][2], eepromBoardData[j][3], eepromBoardData[j][4]); |
| } |
| #endif |
| |
| if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE |
| { |
| /* Update board data to registers */ |
| for (j=0; j<15; j++) |
| { |
| reg_write(eepromBoardData[j][0], eepromBoardData[j][modesIndex]); |
| |
| /* #1 Save the initial value of the related RIFS register settings */ |
| //if( ((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy == 1 ) |
| { |
| switch(eepromBoardData[j][0]) |
| { |
| case 0x9850 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initDesiredSigSize = eepromBoardData[j][modesIndex]; |
| break; |
| case 0x985c : |
| ((struct zsHpPriv*)wd->hpPrivate)->initAGC = eepromBoardData[j][modesIndex]; |
| break; |
| case 0x9860 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initAgcControl = eepromBoardData[j][modesIndex]; |
| break; |
| case 0x9918 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initSearchStartDelay = eepromBoardData[j][modesIndex]; |
| break; |
| case 0x99ec : |
| ((struct zsHpPriv*)wd->hpPrivate)->initRIFSSearchParams = eepromBoardData[j][modesIndex]; |
| break; |
| case 0xa388 : |
| ((struct zsHpPriv*)wd->hpPrivate)->initFastChannelChangeControl = eepromBoardData[j][modesIndex]; |
| default : |
| break; |
| } |
| } |
| } |
| } /* if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE */ |
| |
| |
| /* Bringup issue : force tx gain */ |
| //reg_write(0xa258, 0x0cc65381); |
| //reg_write(0xa274, 0x0a1a7c15); |
| zfInitPowerCal(dev); |
| |
| if(frequency > ZM_CH_G_14) |
| { |
| zfDelayWriteInternalReg(dev, 0x1d4014, 0x5143); |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, 0x1d4014, 0x5163); |
| } |
| |
| zfFlushDelayWrite(dev); |
| } |
| |
| |
| void zfInitRf(zdev_t* dev, u32_t frequency) |
| { |
| u32_t cmd[8]; |
| u16_t ret; |
| int delta_slope_coeff_exp; |
| int delta_slope_coeff_man; |
| int delta_slope_coeff_exp_shgi; |
| int delta_slope_coeff_man_shgi; |
| |
| zmw_get_wlan_dev(dev); |
| |
| zm_debug_msg1(" initRf frequency = ", frequency); |
| |
| if (frequency == 0) |
| { |
| frequency = 2412; |
| } |
| |
| /* Bank 0 1 2 3 5 6 7 */ |
| zfSetRfRegs(dev, frequency); |
| /* Bank 4 */ |
| zfSetBank4AndPowerTable(dev, frequency, 0, 0); |
| |
| /* stroe frequency */ |
| ((struct zsHpPriv*)wd->hpPrivate)->hwFrequency = (u16_t)frequency; |
| |
| zfGetHwTurnOffdynParam(dev, |
| frequency, 0, 0, |
| &delta_slope_coeff_exp, |
| &delta_slope_coeff_man, |
| &delta_slope_coeff_exp_shgi, |
| &delta_slope_coeff_man_shgi); |
| |
| /* related functions */ |
| frequency = frequency*1000; |
| cmd[0] = 28 | (ZM_CMD_RF_INIT << 8); |
| cmd[1] = frequency; |
| cmd[2] = 0;//((struct zsHpPriv*)wd->hpPrivate)->hw_DYNAMIC_HT2040_EN; |
| cmd[3] = 1;//((wd->ExtOffset << 2) | ((struct zsHpPriv*)wd->hpPrivate)->hw_HT_ENABLE); |
| cmd[4] = delta_slope_coeff_exp; |
| cmd[5] = delta_slope_coeff_man; |
| cmd[6] = delta_slope_coeff_exp_shgi; |
| cmd[7] = delta_slope_coeff_man_shgi; |
| |
| ret = zfIssueCmd(dev, cmd, 32, ZM_OID_INTERNAL_WRITE, 0); |
| |
| // delay temporarily, wait for new PHY and RF |
| zfwSleep(dev, 1000); |
| } |
| |
| int tn(int exp) |
| { |
| int i; |
| int tmp = 1; |
| for(i=0; i<exp; i++) |
| tmp = tmp*2; |
| |
| return tmp; |
| } |
| |
| /*int zfFloor(double indata) |
| { |
| if(indata<0) |
| return (int)indata-1; |
| else |
| return (int)indata; |
| } |
| */ |
| u32_t reverse_bits(u32_t chan_sel) |
| { |
| /* reverse_bits */ |
| u32_t chansel = 0; |
| u8_t i; |
| |
| for (i=0; i<8; i++) |
| chansel |= ((chan_sel>>(7-i) & 0x1) << i); |
| return chansel; |
| } |
| |
| /* Bank 0 1 2 3 5 6 7 */ |
| void zfSetRfRegs(zdev_t* dev, u32_t frequency) |
| { |
| u16_t entries; |
| u16_t freqIndex = 0; |
| u16_t i; |
| |
| //zmw_get_wlan_dev(dev); |
| |
| if ( frequency > ZM_CH_G_14 ) |
| { |
| /* 5G */ |
| freqIndex = 1; |
| zm_msg0_scan(ZM_LV_2, "Set to 5GHz"); |
| |
| } |
| else |
| { |
| /* 2.4G */ |
| freqIndex = 2; |
| zm_msg0_scan(ZM_LV_2, "Set to 2.4GHz"); |
| } |
| |
| #if 1 |
| entries = sizeof(otusBank) / sizeof(*otusBank); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(otusBank[i][0], otusBank[i][freqIndex]); |
| } |
| #else |
| /* Bank0 */ |
| entries = sizeof(ar5416Bank0) / sizeof(*ar5416Bank0); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Bank0[i][0], ar5416Bank0[i][1]); |
| } |
| /* Bank1 */ |
| entries = sizeof(ar5416Bank1) / sizeof(*ar5416Bank1); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Bank1[i][0], ar5416Bank1[i][1]); |
| } |
| /* Bank2 */ |
| entries = sizeof(ar5416Bank2) / sizeof(*ar5416Bank2); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Bank2[i][0], ar5416Bank2[i][1]); |
| } |
| /* Bank3 */ |
| entries = sizeof(ar5416Bank3) / sizeof(*ar5416Bank3); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Bank3[i][0], ar5416Bank3[i][freqIndex]); |
| } |
| /* Bank5 */ |
| reg_write (0x98b0, 0x00000013); |
| reg_write (0x98e4, 0x00000002); |
| /* Bank6 */ |
| entries = sizeof(ar5416Bank6) / sizeof(*ar5416Bank6); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Bank6[i][0], ar5416Bank6[i][freqIndex]); |
| } |
| /* Bank7 */ |
| entries = sizeof(ar5416Bank7) / sizeof(*ar5416Bank7); |
| for (i=0; i<entries; i++) |
| { |
| reg_write(ar5416Bank7[i][0], ar5416Bank7[i][1]); |
| } |
| #endif |
| |
| zfFlushDelayWrite(dev); |
| } |
| |
| /* Bank 4 */ |
| void zfSetBank4AndPowerTable(zdev_t* dev, u32_t frequency, u8_t bw40, |
| u8_t extOffset) |
| { |
| u32_t chup = 1; |
| u32_t bmode_LF_synth_freq = 0; |
| u32_t amode_refsel_1 = 0; |
| u32_t amode_refsel_0 = 1; |
| u32_t addr2 = 1; |
| u32_t addr1 = 0; |
| u32_t addr0 = 0; |
| |
| u32_t d1; |
| u32_t d0; |
| u32_t tmp_0; |
| u32_t tmp_1; |
| u32_t data0; |
| u32_t data1; |
| |
| u8_t chansel; |
| u8_t chan_sel; |
| u32_t temp_chan_sel; |
| |
| u16_t i; |
| |
| zmw_get_wlan_dev(dev); |
| |
| |
| /* if enable 802.11h, need to record curent channel index in channel array */ |
| if (wd->sta.DFSEnable) |
| { |
| for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) |
| { |
| if (wd->regulationTable.allowChannel[i].channel == frequency) |
| break; |
| } |
| wd->regulationTable.CurChIndex = i; |
| } |
| |
| if (bw40 == 1) |
| { |
| if (extOffset == 1) |
| { |
| frequency += 10; |
| } |
| else |
| { |
| frequency -= 10; |
| } |
| |
| } |
| |
| |
| if ( frequency > 3000 ) |
| { |
| if ( frequency % 10 ) |
| { |
| /* 5M */ |
| chan_sel = (u8_t)((frequency - 4800)/5); |
| chan_sel = (u8_t)(chan_sel & 0xff); |
| chansel = (u8_t)reverse_bits(chan_sel); |
| } |
| else |
| { |
| /* 10M : improve Tx EVM */ |
| chan_sel = (u8_t)((frequency - 4800)/10); |
| chan_sel = (u8_t)(chan_sel & 0xff)<<1; |
| chansel = (u8_t)reverse_bits(chan_sel); |
| |
| amode_refsel_1 = 1; |
| amode_refsel_0 = 0; |
| } |
| } |
| else |
| { |
| //temp_chan_sel = (((frequency - 672)*2) - 3040)/10; |
| if (frequency == 2484) |
| { |
| temp_chan_sel = 10 + (frequency - 2274)/5 ; |
| bmode_LF_synth_freq = 1; |
| } |
| else |
| { |
| temp_chan_sel = 16 + (frequency - 2272)/5 ; |
| bmode_LF_synth_freq = 0; |
| } |
| chan_sel = (u8_t)(temp_chan_sel << 2) & 0xff; |
| chansel = (u8_t)reverse_bits(chan_sel); |
| } |
| |
| d1 = chansel; //# 8 bits of chan |
| d0 = addr0<<7 | addr1<<6 | addr2<<5 |
| | amode_refsel_0<<3 | amode_refsel_1<<2 |
| | bmode_LF_synth_freq<<1 | chup; |
| |
| tmp_0 = d0 & 0x1f; //# 5-1 |
| tmp_1 = d1 & 0x1f; //# 5-1 |
| data0 = tmp_1<<5 | tmp_0; |
| |
| tmp_0 = d0>>5 & 0x7; //# 8-6 |
| tmp_1 = d1>>5 & 0x7; //# 8-6 |
| data1 = tmp_1<<5 | tmp_0; |
| |
| /* Bank4 */ |
| reg_write (0x9800+(0x2c<<2), data0); |
| reg_write (0x9800+(0x3a<<2), data1); |
| //zm_debug_msg1("0x9800+(0x2c<<2 = ", data0); |
| //zm_debug_msg1("0x9800+(0x3a<<2 = ", data1); |
| |
| |
| zfFlushDelayWrite(dev); |
| |
| zfwSleep(dev, 10); |
| |
| return; |
| } |
| |
| |
| struct zsPhyFreqPara |
| { |
| u32_t coeff_exp; |
| u32_t coeff_man; |
| u32_t coeff_exp_shgi; |
| u32_t coeff_man_shgi; |
| }; |
| |
| struct zsPhyFreqTable |
| { |
| u32_t frequency; |
| struct zsPhyFreqPara FpgaDynamicHT; |
| struct zsPhyFreqPara FpgaStaticHT; |
| struct zsPhyFreqPara ChipST20Mhz; |
| struct zsPhyFreqPara Chip2040Mhz; |
| struct zsPhyFreqPara Chip2040ExtAbove; |
| }; |
| |
| const struct zsPhyFreqTable zgPhyFreqCoeff[] = |
| { |
| /*Index freq FPGA DYNAMIC_HT2040_EN FPGA STATIC_HT20 Real Chip static20MHz Real Chip 2040MHz Real Chip 2040Mhz */ |
| /* fclk = 10.8 21.6 40 ext below 40 ext above 40 */ |
| /* 0 */ {2412, {5, 23476, 5, 21128}, {4, 23476, 4, 21128}, {3, 21737, 3, 19563}, {3, 21827, 3, 19644}, {3, 21647, 3, 19482}}, |
| /* 1 */ {2417, {5, 23427, 5, 21084}, {4, 23427, 4, 21084}, {3, 21692, 3, 19523}, {3, 21782, 3, 19604}, {3, 21602, 3, 19442}}, |
| /* 2 */ {2422, {5, 23379, 5, 21041}, {4, 23379, 4, 21041}, {3, 21647, 3, 19482}, {3, 21737, 3, 19563}, {3, 21558, 3, 19402}}, |
| /* 3 */ {2427, {5, 23330, 5, 20997}, {4, 23330, 4, 20997}, {3, 21602, 3, 19442}, {3, 21692, 3, 19523}, {3, 21514, 3, 19362}}, |
| /* 4 */ {2432, {5, 23283, 5, 20954}, {4, 23283, 4, 20954}, {3, 21558, 3, 19402}, {3, 21647, 3, 19482}, {3, 21470, 3, 19323}}, |
| /* 5 */ {2437, {5, 23235, 5, 20911}, {4, 23235, 4, 20911}, {3, 21514, 3, 19362}, {3, 21602, 3, 19442}, {3, 21426, 3, 19283}}, |
| /* 6 */ {2442, {5, 23187, 5, 20868}, {4, 23187, 4, 20868}, {3, 21470, 3, 19323}, {3, 21558, 3, 19402}, {3, 21382, 3, 19244}}, |
| /* 7 */ {2447, {5, 23140, 5, 20826}, {4, 23140, 4, 20826}, {3, 21426, 3, 19283}, {3, 21514, 3, 19362}, {3, 21339, 3, 19205}}, |
| /* 8 */ {2452, {5, 23093, 5, 20783}, {4, 23093, 4, 20783}, {3, 21382, 3, 19244}, {3, 21470, 3, 19323}, {3, 21295, 3, 19166}}, |
| /* 9 */ {2457, {5, 23046, 5, 20741}, {4, 23046, 4, 20741}, {3, 21339, 3, 19205}, {3, 21426, 3, 19283}, {3, 21252, 3, 19127}}, |
| /* 10 */ {2462, {5, 22999, 5, 20699}, {4, 22999, 4, 20699}, {3, 21295, 3, 19166}, {3, 21382, 3, 19244}, {3, 21209, 3, 19088}}, |
| /* 11 */ {2467, {5, 22952, 5, 20657}, {4, 22952, 4, 20657}, {3, 21252, 3, 19127}, {3, 21339, 3, 19205}, {3, 21166, 3, 19050}}, |
| /* 12 */ {2472, {5, 22906, 5, 20615}, {4, 22906, 4, 20615}, {3, 21209, 3, 19088}, {3, 21295, 3, 19166}, {3, 21124, 3, 19011}}, |
| /* 13 */ {2484, {5, 22795, 5, 20516}, {4, 22795, 4, 20516}, {3, 21107, 3, 18996}, {3, 21192, 3, 19073}, {3, 21022, 3, 18920}}, |
| /* 14 */ {4920, {6, 23018, 6, 20716}, {5, 23018, 5, 20716}, {4, 21313, 4, 19181}, {4, 21356, 4, 19220}, {4, 21269, 4, 19142}}, |
| /* 15 */ {4940, {6, 22924, 6, 20632}, {5, 22924, 5, 20632}, {4, 21226, 4, 19104}, {4, 21269, 4, 19142}, {4, 21183, 4, 19065}}, |
| /* 16 */ {4960, {6, 22832, 6, 20549}, {5, 22832, 5, 20549}, {4, 21141, 4, 19027}, {4, 21183, 4, 19065}, {4, 21098, 4, 18988}}, |
| /* 17 */ {4980, {6, 22740, 6, 20466}, {5, 22740, 5, 20466}, {4, 21056, 4, 18950}, {4, 21098, 4, 18988}, {4, 21014, 4, 18912}}, |
| /* 18 */ {5040, {6, 22469, 6, 20223}, {5, 22469, 5, 20223}, {4, 20805, 4, 18725}, {4, 20846, 4, 18762}, {4, 20764, 4, 18687}}, |
| /* 19 */ {5060, {6, 22381, 6, 20143}, {5, 22381, 5, 20143}, {4, 20723, 4, 18651}, {4, 20764, 4, 18687}, {4, 20682, 4, 18614}}, |
| /* 20 */ {5080, {6, 22293, 6, 20063}, {5, 22293, 5, 20063}, {4, 20641, 4, 18577}, {4, 20682, 4, 18614}, {4, 20601, 4, 18541}}, |
| /* 21 */ {5180, {6, 21862, 6, 19676}, {5, 21862, 5, 19676}, {4, 20243, 4, 18219}, {4, 20282, 4, 18254}, {4, 20204, 4, 18183}}, |
| /* 22 */ {5200, {6, 21778, 6, 19600}, {5, 21778, 5, 19600}, {4, 20165, 4, 18148}, {4, 20204, 4, 18183}, {4, 20126, 4, 18114}}, |
| /* 23 */ {5220, {6, 21695, 6, 19525}, {5, 21695, 5, 19525}, {4, 20088, 4, 18079}, {4, 20126, 4, 18114}, {4, 20049, 4, 18044}}, |
| /* 24 */ {5240, {6, 21612, 6, 19451}, {5, 21612, 5, 19451}, {4, 20011, 4, 18010}, {4, 20049, 4, 18044}, {4, 19973, 4, 17976}}, |
| /* 25 */ {5260, {6, 21530, 6, 19377}, {5, 21530, 5, 19377}, {4, 19935, 4, 17941}, {4, 19973, 4, 17976}, {4, 19897, 4, 17907}}, |
| /* 26 */ {5280, {6, 21448, 6, 19303}, {5, 21448, 5, 19303}, {4, 19859, 4, 17873}, {4, 19897, 4, 17907}, {4, 19822, 4, 17840}}, |
| /* 27 */ {5300, {6, 21367, 6, 19230}, {5, 21367, 5, 19230}, {4, 19784, 4, 17806}, {4, 19822, 4, 17840}, {4, 19747, 4, 17772}}, |
| /* 28 */ {5320, {6, 21287, 6, 19158}, {5, 21287, 5, 19158}, {4, 19710, 4, 17739}, {4, 19747, 4, 17772}, {4, 19673, 4, 17706}}, |
| /* 29 */ {5500, {6, 20590, 6, 18531}, {5, 20590, 5, 18531}, {4, 19065, 4, 17159}, {4, 19100, 4, 17190}, {4, 19030, 4, 17127}}, |
| /* 30 */ {5520, {6, 20516, 6, 18464}, {5, 20516, 5, 18464}, {4, 18996, 4, 17096}, {4, 19030, 4, 17127}, {4, 18962, 4, 17065}}, |
| /* 31 */ {5540, {6, 20442, 6, 18397}, {5, 20442, 5, 18397}, {4, 18927, 4, 17035}, {4, 18962, 4, 17065}, {4, 18893, 4, 17004}}, |
| /* 32 */ {5560, {6, 20368, 6, 18331}, {5, 20368, 5, 18331}, {4, 18859, 4, 16973}, {4, 18893, 4, 17004}, {4, 18825, 4, 16943}}, |
| /* 33 */ {5580, {6, 20295, 6, 18266}, {5, 20295, 5, 18266}, {4, 18792, 4, 16913}, {4, 18825, 4, 16943}, {4, 18758, 4, 16882}}, |
| /* 34 */ {5600, {6, 20223, 6, 18200}, {5, 20223, 5, 18200}, {4, 18725, 4, 16852}, {4, 18758, 4, 16882}, {4, 18691, 4, 16822}}, |
| /* 35 */ {5620, {6, 20151, 6, 18136}, {5, 20151, 5, 18136}, {4, 18658, 4, 16792}, {4, 18691, 4, 16822}, {4, 18625, 4, 16762}}, |
| /* 36 */ {5640, {6, 20079, 6, 18071}, {5, 20079, 5, 18071}, {4, 18592, 4, 16733}, {4, 18625, 4, 16762}, {4, 18559, 4, 16703}}, |
| /* 37 */ {5660, {6, 20008, 6, 18007}, {5, 20008, 5, 18007}, {4, 18526, 4, 16673}, {4, 18559, 4, 16703}, {4, 18493, 4, 16644}}, |
| /* 38 */ {5680, {6, 19938, 6, 17944}, {5, 19938, 5, 17944}, {4, 18461, 4, 16615}, {4, 18493, 4, 16644}, {4, 18428, 4, 16586}}, |
| /* 39 */ {5700, {6, 19868, 6, 17881}, {5, 19868, 5, 17881}, {4, 18396, 4, 16556}, {4, 18428, 4, 16586}, {4, 18364, 4, 16527}}, |
| /* 40 */ {5745, {6, 19712, 6, 17741}, {5, 19712, 5, 17741}, {4, 18252, 4, 16427}, {4, 18284, 4, 16455}, {4, 18220, 4, 16398}}, |
| /* 41 */ {5765, {6, 19644, 6, 17679}, {5, 19644, 5, 17679}, {4, 18189, 5, 32740}, {4, 18220, 4, 16398}, {4, 18157, 5, 32683}}, |
| /* 42 */ {5785, {6, 19576, 6, 17618}, {5, 19576, 5, 17618}, {4, 18126, 5, 32626}, {4, 18157, 5, 32683}, {4, 18094, 5, 32570}}, |
| /* 43 */ {5805, {6, 19508, 6, 17558}, {5, 19508, 5, 17558}, {4, 18063, 5, 32514}, {4, 18094, 5, 32570}, {4, 18032, 5, 32458}}, |
| /* 44 */ {5825, {6, 19441, 6, 17497}, {5, 19441, 5, 17497}, {4, 18001, 5, 32402}, {4, 18032, 5, 32458}, {4, 17970, 5, 32347}}, |
| /* 45 */ {5170, {6, 21904, 6, 19714}, {5, 21904, 5, 19714}, {4, 20282, 4, 18254}, {4, 20321, 4, 18289}, {4, 20243, 4, 18219}}, |
| /* 46 */ {5190, {6, 21820, 6, 19638}, {5, 21820, 5, 19638}, {4, 20204, 4, 18183}, {4, 20243, 4, 18219}, {4, 20165, 4, 18148}}, |
| /* 47 */ {5210, {6, 21736, 6, 19563}, {5, 21736, 5, 19563}, {4, 20126, 4, 18114}, {4, 20165, 4, 18148}, {4, 20088, 4, 18079}}, |
| /* 48 */ {5230, {6, 21653, 6, 19488}, {5, 21653, 5, 19488}, {4, 20049, 4, 18044}, {4, 20088, 4, 18079}, {4, 20011, 4, 18010}} |
| }; |
| /* to reduce search time, please modify this define if you add or delete channel in table */ |
| #define First5GChannelIndex 14 |
| |
| void zfGetHwTurnOffdynParam(zdev_t* dev, |
| u32_t frequency, u8_t bw40, u8_t extOffset, |
| int* delta_slope_coeff_exp, |
| int* delta_slope_coeff_man, |
| int* delta_slope_coeff_exp_shgi, |
| int* delta_slope_coeff_man_shgi) |
| { |
| /* Get param for turnoffdyn */ |
| u16_t i, arraySize; |
| |
| //zmw_get_wlan_dev(dev); |
| |
| arraySize = sizeof(zgPhyFreqCoeff)/sizeof(struct zsPhyFreqTable); |
| if (frequency < 3000) |
| { |
| /* 2.4GHz Channel */ |
| for (i = 0; i < First5GChannelIndex; i++) |
| { |
| if (frequency == zgPhyFreqCoeff[i].frequency) |
| break; |
| } |
| |
| if (i < First5GChannelIndex) |
| { |
| } |
| else |
| { |
| zm_msg1_scan(ZM_LV_0, "Unsupported 2.4G frequency = ", frequency); |
| return; |
| } |
| } |
| else |
| { |
| /* 5GHz Channel */ |
| for (i = First5GChannelIndex; i < arraySize; i++) |
| { |
| if (frequency == zgPhyFreqCoeff[i].frequency) |
| break; |
| } |
| |
| if (i < arraySize) |
| { |
| } |
| else |
| { |
| zm_msg1_scan(ZM_LV_0, "Unsupported 5G frequency = ", frequency); |
| return; |
| } |
| } |
| |
| /* FPGA DYNAMIC_HT2040_EN fclk = 10.8 */ |
| /* FPGA STATIC_HT20_ fclk = 21.6 */ |
| /* Real Chip fclk = 40 */ |
| #if ZM_FPGA_PHY == 1 |
| //fclk = 10.8; |
| *delta_slope_coeff_exp = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_exp; |
| *delta_slope_coeff_man = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_man; |
| *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_exp_shgi; |
| *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_man_shgi; |
| #else |
| //fclk = 40; |
| if (bw40) |
| { |
| /* ht2040 */ |
| if (extOffset == 1) { |
| *delta_slope_coeff_exp = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_exp; |
| *delta_slope_coeff_man = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_man; |
| *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_exp_shgi; |
| *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_man_shgi; |
| } |
| else { |
| *delta_slope_coeff_exp = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_exp; |
| *delta_slope_coeff_man = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_man; |
| *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_exp_shgi; |
| *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_man_shgi; |
| } |
| } |
| else |
| { |
| /* static 20 */ |
| *delta_slope_coeff_exp = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_exp; |
| *delta_slope_coeff_man = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_man; |
| *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_exp_shgi; |
| *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_man_shgi; |
| } |
| #endif |
| } |
| |
| /* Main routin frequency setting function */ |
| /* If 2.4G/5G switch, PHY need resetting BB and RF for band switch */ |
| /* Do the setting switch in zfSendFrequencyCmd() */ |
| void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40, |
| u8_t extOffset, u8_t initRF) |
| { |
| u32_t cmd[9]; |
| u32_t cmdB[3]; |
| u16_t ret; |
| u8_t old_band; |
| u8_t new_band; |
| u32_t checkLoopCount; |
| u32_t tmpValue; |
| |
| int delta_slope_coeff_exp; |
| int delta_slope_coeff_man; |
| int delta_slope_coeff_exp_shgi; |
| int delta_slope_coeff_man_shgi; |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| zm_msg1_scan(ZM_LV_1, "Frequency = ", frequency); |
| zm_msg1_scan(ZM_LV_1, "bw40 = ", bw40); |
| zm_msg1_scan(ZM_LV_1, "extOffset = ", extOffset); |
| |
| if ( hpPriv->coldResetNeedFreq ) |
| { |
| hpPriv->coldResetNeedFreq = 0; |
| initRF = 2; |
| zm_debug_msg0("zfHpSetFrequencyEx: Do ColdReset "); |
| } |
| if ( hpPriv->isSiteSurvey == 2 ) |
| { |
| /* wait time for AGC and noise calibration : not in sitesurvey and connected */ |
| checkLoopCount = 2000; /* 2000*100 = 200ms */ |
| } |
| else |
| { |
| /* wait time for AGC and noise calibration : in sitesurvey */ |
| checkLoopCount = 1000; /* 1000*100 = 100ms */ |
| } |
| |
| hpPriv->latestFrequency = frequency; |
| hpPriv->latestBw40 = bw40; |
| hpPriv->latestExtOffset = extOffset; |
| |
| if ((hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_GENERAL) || |
| (hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK)) |
| { |
| if ( frequency <= ZM_CH_G_14 ) |
| { |
| /* workaround for 11g Ad Hoc beacon distribution */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, 0x7f0007); |
| //zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_AIFS, 0x1c04901c); |
| } |
| } |
| |
| /* AHB, DAC, ADC clock selection by static20/ht2040 */ |
| zfSelAdcClk(dev, bw40, frequency); |
| |
| /* clear bb_heavy_clip_enable */ |
| reg_write(0x99e0, 0x200); |
| zfFlushDelayWrite(dev); |
| |
| /* Set CTS/RTS rate */ |
| if ( frequency > ZM_CH_G_14 ) |
| { |
| //zfHpSetRTSCTSRate(dev, 0x10b010b); /* OFDM 6M */ |
| new_band = 1; |
| } |
| else |
| { |
| //zfHpSetRTSCTSRate(dev, 0x30003); /* CCK 11M */ |
| new_band = 0; |
| } |
| |
| if (((struct zsHpPriv*)wd->hpPrivate)->hwFrequency > ZM_CH_G_14) |
| old_band = 1; |
| else |
| old_band = 0; |
| |
| //Workaround for 2.4GHz only device |
| if ((hpPriv->OpFlags & 0x1) == 0) |
| { |
| if ((((struct zsHpPriv*)wd->hpPrivate)->hwFrequency == ZM_CH_G_1) && (frequency == ZM_CH_G_2)) |
| { |
| /* Force to do band switching */ |
| old_band = 1; |
| } |
| } |
| |
| /* Notify channel switch to firmware */ |
| /* TX/RX must be stopped by now */ |
| cmd[0] = 0 | (ZM_CMD_FREQ_STRAT << 8); |
| ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, 0); |
| |
| if ((initRF != 0) || (new_band != old_band) |
| || (((struct zsHpPriv*)wd->hpPrivate)->hwBw40 != bw40)) |
| { |
| /* band switch */ |
| zm_msg0_scan(ZM_LV_1, "=====band switch====="); |
| |
| if (initRF == 2 ) |
| { |
| //Cold reset BB/ADDA |
| zfDelayWriteInternalReg(dev, 0x1d4004, 0x800); |
| zfFlushDelayWrite(dev); |
| zm_msg0_scan(ZM_LV_1, "Do cold reset BB/ADDA"); |
| } |
| else |
| { |
| //Warm reset BB/ADDA |
| zfDelayWriteInternalReg(dev, 0x1d4004, 0x400); |
| zfFlushDelayWrite(dev); |
| } |
| |
| /* reset workaround state to default */ |
| hpPriv->rxStrongRSSI = 0; |
| hpPriv->strongRSSI = 0; |
| |
| zfDelayWriteInternalReg(dev, 0x1d4004, 0x0); |
| zfFlushDelayWrite(dev); |
| |
| zfInitPhy(dev, frequency, bw40); |
| |
| // zfiCheckRifs(dev); |
| |
| /* Bank 0 1 2 3 5 6 7 */ |
| zfSetRfRegs(dev, frequency); |
| /* Bank 4 */ |
| zfSetBank4AndPowerTable(dev, frequency, bw40, extOffset); |
| |
| cmd[0] = 32 | (ZM_CMD_RF_INIT << 8); |
| } |
| else //((new_band == old_band) && !initRF) |
| { |
| /* same band */ |
| |
| /* Force disable CR671 bit20 / 7823 */ |
| /* The bug has to do with the polarity of the pdadc offset calibration. There */ |
| /* is an initial calibration that is OK, and there is a continuous */ |
| /* calibration that updates the pddac with the wrong polarity. Fortunately */ |
| /* the second loop can be disabled with a bit called en_pd_dc_offset_thr. */ |
| #if 0 |
| cmdB[0] = 8 | (ZM_CMD_BITAND << 8);; |
| cmdB[1] = (0xa27c + 0x1bc000); |
| cmdB[2] = 0xffefffff; |
| ret = zfIssueCmd(dev, cmdB, 12, ZM_OID_INTERNAL_WRITE, 0); |
| #endif |
| |
| /* Bank 4 */ |
| zfSetBank4AndPowerTable(dev, frequency, bw40, extOffset); |
| |
| |
| cmd[0] = 32 | (ZM_CMD_FREQUENCY << 8); |
| } |
| |
| /* Compatibility for new layout UB83 */ |
| /* Setting code at CR1 here move from the func:zfHwHTEnable() in firmware */ |
| if (((struct zsHpPriv*)wd->hpPrivate)->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) |
| { |
| /* UB83 : one stream */ |
| tmpValue = 0; |
| } |
| else |
| { |
| /* UB81, UB82 : two stream */ |
| tmpValue = 0x100; |
| } |
| |
| if (1) //if (((struct zsHpPriv*)wd->hpPrivate)->hw_HT_ENABLE == 1) |
| { |
| if (bw40 == 1) |
| { |
| if (extOffset == 1) { |
| reg_write(0x9804, tmpValue | 0x2d4); //3d4 for real |
| } |
| else { |
| reg_write(0x9804, tmpValue | 0x2c4); //3c4 for real |
| } |
| //# Dyn HT2040.Refer to Reg 1. |
| //#[3]:single length (4us) 1st HT long training symbol; use Walsh spatial spreading for 2 chains 2 streams TX |
| //#[c]:allow short GI for HT40 packets; enable HT detection. |
| //#[4]:enable 20/40 MHz channel detection. |
| } |
| else |
| { |
| reg_write(0x9804, tmpValue | 0x240); |
| //# Static HT20 |
| //#[3]:single length (4us) 1st HT long training symbol; use Walsh spatial spreading for 2 chains 2 streams TX |
| //#[4]:Otus don't allow short GI for HT20 packets yet; enable HT detection. |
| //#[0]:disable 20/40 MHz channel detection. |
| } |
| } |
| else |
| { |
| reg_write(0x9804, 0x0); |
| //# Legacy;# Direct Mapping for each chain. |
| //#Be modified by Oligo to add dynanic for legacy. |
| if (bw40 == 1) |
| { |
| reg_write(0x9804, 0x4); //# Dyn Legacy .Refer to reg 1. |
| } |
| else |
| { |
| reg_write(0x9804, 0x0); //# Static Legacy |
| } |
| } |
| zfFlushDelayWrite(dev); |
| /* end of ub83 compatibility */ |
| |
| /* Set Power, TPC, Gain table... */ |
| zfSetPowerCalTable(dev, frequency, bw40, extOffset); |
| |
| |
| /* store frequency */ |
| ((struct zsHpPriv*)wd->hpPrivate)->hwFrequency = (u16_t)frequency; |
| ((struct zsHpPriv*)wd->hpPrivate)->hwBw40 = bw40; |
| ((struct zsHpPriv*)wd->hpPrivate)->hwExtOffset = extOffset; |
| |
| zfGetHwTurnOffdynParam(dev, |
| frequency, bw40, extOffset, |
| &delta_slope_coeff_exp, |
| &delta_slope_coeff_man, |
| &delta_slope_coeff_exp_shgi, |
| &delta_slope_coeff_man_shgi); |
| |
| /* related functions */ |
| frequency = frequency*1000; |
| /* len[36] : type[0x30] : seq[?] */ |
| // cmd[0] = 28 | (ZM_CMD_FREQUENCY << 8); |
| cmd[1] = frequency; |
| cmd[2] = bw40;//((struct zsHpPriv*)wd->hpPrivate)->hw_DYNAMIC_HT2040_EN; |
| cmd[3] = (extOffset<<2)|0x1;//((wd->ExtOffset << 2) | ((struct zsHpPriv*)wd->hpPrivate)->hw_HT_ENABLE); |
| cmd[4] = delta_slope_coeff_exp; |
| cmd[5] = delta_slope_coeff_man; |
| cmd[6] = delta_slope_coeff_exp_shgi; |
| cmd[7] = delta_slope_coeff_man_shgi; |
| cmd[8] = checkLoopCount; |
| |
| ret = zfIssueCmd(dev, cmd, 36, ZM_CMD_SET_FREQUENCY, 0); |
| |
| // delay temporarily, wait for new PHY and RF |
| //zfwSleep(dev, 1000); |
| } |
| |
| |
| /******************** Key ********************/ |
| |
| u16_t zfHpResetKeyCache(zdev_t* dev) |
| { |
| u8_t i; |
| u32_t key[4] = {0, 0, 0, 0}; |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv=wd->hpPrivate; |
| |
| for(i=0;i<4;i++) |
| { |
| zfHpSetDefaultKey(dev, i, ZM_WEP64, key, NULL); |
| } |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_ROLL_CALL_TBL_L, 0x00); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_ROLL_CALL_TBL_H, 0x00); |
| zfFlushDelayWrite(dev); |
| |
| hpPriv->camRollCallTable = (u64_t) 0; |
| |
| return 0; |
| } |
| |
| |
| /************************************************************************/ |
| /* */ |
| /* FUNCTION DESCRIPTION zfSetKey */ |
| /* Set key. */ |
| /* */ |
| /* INPUTS */ |
| /* dev : device pointer */ |
| /* */ |
| /* OUTPUTS */ |
| /* 0 : success */ |
| /* other : fail */ |
| /* */ |
| /* AUTHOR */ |
| /* Stephen Chen ZyDAS Technology Corporation 2006.1 */ |
| /* */ |
| /************************************************************************/ |
| /* ! please use zfCoreSetKey() in 80211Core for SetKey */ |
| u32_t zfHpSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type, |
| u16_t* mac, u32_t* key) |
| { |
| u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; |
| u16_t ret; |
| u16_t i; |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv=wd->hpPrivate; |
| |
| #if 0 /* remove to zfCoreSetKey() */ |
| zmw_declare_for_critical_section(); |
| |
| zmw_enter_critical_section(dev); |
| wd->sta.flagKeyChanging++; |
| zm_debug_msg1(" zfHpSetKey++++ ", wd->sta.flagKeyChanging); |
| zmw_leave_critical_section(dev); |
| #endif |
| |
| cmd[0] = 0x0000281C; |
| cmd[1] = ((u32_t)keyId<<16) + (u32_t)user; |
| cmd[2] = ((u32_t)mac[0]<<16) + (u32_t)type; |
| cmd[3] = ((u32_t)mac[2]<<16) + ((u32_t)mac[1]); |
| |
| for (i=0; i<4; i++) |
| { |
| cmd[4+i] = key[i]; |
| } |
| |
| if (user < 64) |
| { |
| hpPriv->camRollCallTable |= ((u64_t) 1) << user; |
| } |
| |
| //ret = zfIssueCmd(dev, cmd, 32, ZM_OID_INTERNAL_WRITE, NULL); |
| ret = zfIssueCmd(dev, cmd, 32, ZM_CMD_SET_KEY, NULL); |
| return ret; |
| } |
| |
| |
| u32_t zfHpSetApPairwiseKey(zdev_t* dev, u16_t* staMacAddr, u8_t type, |
| u32_t* key, u32_t* micKey, u16_t staAid) |
| { |
| if ((staAid!=0) && (staAid<64)) |
| { |
| zfHpSetKey(dev, (staAid-1), 0, type, staMacAddr, key); |
| if ((type == ZM_TKIP) |
| #ifdef ZM_ENABLE_CENC |
| || (type == ZM_CENC) |
| #endif //ZM_ENABLE_CENC |
| ) |
| zfHpSetKey(dev, (staAid-1), 1, type, staMacAddr, micKey); |
| return 0; |
| } |
| return 1; |
| } |
| |
| u32_t zfHpSetApGroupKey(zdev_t* dev, u16_t* apMacAddr, u8_t type, |
| u32_t* key, u32_t* micKey, u16_t vapId) |
| { |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT - 1 - vapId, 0, type, apMacAddr, key); // 6D18 modify from 0 to 1 ?? |
| if ((type == ZM_TKIP) |
| #ifdef ZM_ENABLE_CENC |
| || (type == ZM_CENC) |
| #endif //ZM_ENABLE_CENC |
| ) |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT - 1 - vapId, 1, type, apMacAddr, micKey); |
| return 0; |
| } |
| |
| u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* micKey) |
| { |
| u16_t macAddr[3] = {0, 0, 0}; |
| |
| #ifdef ZM_ENABLE_IBSS_WPA2PSK |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK ) |
| { /* If not wpa2psk , use traditional */ |
| /* Because the bug of chip , defaultkey should follow the key map rule in register 700 */ |
| if ( keyId == 0 ) |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, type, macAddr, key); |
| else |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 1, type, macAddr, key); |
| } |
| else |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, type, macAddr, key); |
| #else |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, type, macAddr, key); |
| #endif |
| if ((type == ZM_TKIP) |
| |
| #ifdef ZM_ENABLE_CENC |
| || (type == ZM_CENC) |
| #endif //ZM_ENABLE_CENC |
| ) |
| { |
| zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 1, type, macAddr, micKey); |
| } |
| |
| return 0; |
| } |
| |
| u32_t zfHpSetPerUserKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t* mac, u8_t type, u32_t* key, u32_t* micKey) |
| { |
| #ifdef ZM_ENABLE_IBSS_WPA2PSK |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK ) |
| { /* If not wpa2psk , use traditional */ |
| if(keyId) |
| { /* Set Group Key */ |
| zfHpSetKey(dev, user, 1, type, (u16_t *)mac, key); |
| } |
| else if(keyId == 0) |
| { /* Set Pairwise Key */ |
| zfHpSetKey(dev, user, 0, type, (u16_t *)mac, key); |
| } |
| } |
| else |
| { |
| zfHpSetKey(dev, user, keyId, type, (u16_t *)mac, key); |
| } |
| #else |
| zfHpSetKey(dev, user, keyId, type, (u16_t *)mac, key); |
| #endif |
| |
| if ((type == ZM_TKIP) |
| #ifdef ZM_ENABLE_CENC |
| || (type == ZM_CENC) |
| #endif //ZM_ENABLE_CENC |
| ) |
| { |
| zfHpSetKey(dev, user, keyId + 1, type, (u16_t *)mac, micKey); |
| } |
| return 0; |
| } |
| |
| /************************************************************************/ |
| /* */ |
| /* FUNCTION DESCRIPTION zfHpRemoveKey */ |
| /* Remove key. */ |
| /* */ |
| /* INPUTS */ |
| /* dev : device pointer */ |
| /* */ |
| /* OUTPUTS */ |
| /* 0 : success */ |
| /* other : fail */ |
| /* */ |
| /* AUTHOR */ |
| /* Yuan-Gu Wei ZyDAS Technology Corporation 2006.6 */ |
| /* */ |
| /************************************************************************/ |
| u16_t zfHpRemoveKey(zdev_t* dev, u16_t user) |
| { |
| u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; |
| u16_t ret = 0; |
| |
| cmd[0] = 0x00002904; |
| cmd[1] = (u32_t)user; |
| |
| ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, NULL); |
| return ret; |
| } |
| |
| |
| |
| /******************** DMA ********************/ |
| u16_t zfHpStartRecv(zdev_t* dev) |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3d30, 0x100); |
| zfFlushDelayWrite(dev); |
| |
| return 0; |
| } |
| |
| u16_t zfHpStopRecv(zdev_t* dev) |
| { |
| return 0; |
| } |
| |
| |
| /******************** MAC ********************/ |
| void zfInitMac(zdev_t* dev) |
| { |
| /* ACK extension register */ |
| // jhlee temp : change value 0x2c -> 0x40 |
| // honda resolve short preamble problem : 0x40 -> 0x75 |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_ACK_EXTENSION, 0x40); // 0x28 -> 0x2c 6522:yflee |
| |
| /* TxQ0/1/2/3 Retry MAX=2 => transmit 3 times and degrade rate for retry */ |
| /* PB42 AP crash issue: */ |
| /* Workaround the crash issue by CTS/RTS, set retry max to zero for */ |
| /* workaround tx underrun which enable CTS/RTS */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RETRY_MAX, 0); // 0x11111 => 0 |
| |
| /* use hardware MIC check */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_SNIFFER, 0x2000000); |
| |
| /* Set Rx threshold to 1600 */ |
| #if ZM_LARGEPAYLOAD_TEST == 1 |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_THRESHOLD, 0xc4000); |
| #else |
| #ifndef ZM_DISABLE_AMSDU8K_SUPPORT |
| /* The maximum A-MSDU length is 3839/7935 */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_THRESHOLD, 0xc1f80); |
| #else |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_THRESHOLD, 0xc0f80); |
| #endif |
| #endif |
| |
| //zfDelayWriteInternalReg(dev, ZM_MAC_REG_DYNAMIC_SIFS_ACK, 0x10A); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_PE_DELAY, 0x70); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_SLOT_TIME, 9<<10); |
| |
| /* CF-END mode */ |
| zfDelayWriteInternalReg(dev, 0x1c3b2c, 0x19000000); |
| |
| //NAV protects ACK only (in TXOP) |
| zfDelayWriteInternalReg(dev, 0x1c3b38, 0x201); |
| |
| |
| /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ |
| /* OTUS set AM to 0x1 */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_HT1, 0x8000170); |
| |
| /* TODO : wep backoff protection 0x63c */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BACKOFF_PROTECT, 0x105); |
| |
| /* AGG test code*/ |
| /* Aggregation MAX number and timeout */ |
| zfDelayWriteInternalReg(dev, 0x1c3b9c, 0x10000a); |
| /* Filter any control frames, BAR is bit 24 */ |
| zfDelayWriteInternalReg(dev, 0x1c368c, 0x0500ffff); |
| /* Enable deaggregator */ |
| zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); |
| |
| /* Basic rate */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BASIC_RATE, 0x150f); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_MANDATORY_RATE, 0x150f); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RTS_CTS_RATE, 0x10b01bb); |
| |
| /* MIMO resposne control */ |
| zfDelayWriteInternalReg(dev, 0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */ |
| |
| /* Enable LED0 and LED1 */ |
| zfDelayWriteInternalReg(dev, 0x1d0100, 0x3); |
| zfDelayWriteInternalReg(dev, 0x1d0104, 0x3); |
| |
| /* switch MAC to OTUS interface */ |
| zfDelayWriteInternalReg(dev, 0x1c3600, 0x3); |
| |
| /* RXMAC A-MPDU length threshold */ |
| zfDelayWriteInternalReg(dev, 0x1c3c50, 0xffff); |
| |
| /* Phy register read timeout */ |
| zfDelayWriteInternalReg(dev, 0x1c3680, 0xf00008); |
| |
| /* Disable Rx TimeOut : workaround for BB. |
| * OTUS would interrupt the rx frame that sent by OWL TxUnderRun |
| * because OTUS rx timeout behavior, then OTUS would not ack the BA for |
| * this AMPDU from OWL. |
| * Fix by Perry Hwang. 2007/05/10. |
| * 0x1c362c : Rx timeout value : bit 27~16 |
| */ |
| zfDelayWriteInternalReg(dev, 0x1c362c, 0x0); |
| |
| //Set USB Rx stream mode MAX packet number to 2 |
| // Max packet number = *0x1e1110 + 1 |
| zfDelayWriteInternalReg(dev, 0x1e1110, 0x4); |
| //Set USB Rx stream mode timeout to 10us |
| zfDelayWriteInternalReg(dev, 0x1e1114, 0x80); |
| |
| //Set CPU clock frequency to 88/80MHz |
| zfDelayWriteInternalReg(dev, 0x1D4008, 0x73); |
| |
| //Set WLAN DMA interrupt mode : generate int per packet |
| zfDelayWriteInternalReg(dev, 0x1c3d7c, 0x110011); |
| |
| /* 7807 */ |
| /* enable func : Reset FIFO1 and FIFO2 when queue-gnt is low */ |
| /* 0x1c3bb0 Bit2 */ |
| /* Disable SwReset in firmware for TxHang, enable reset FIFO func. */ |
| zfDelayWriteInternalReg(dev, 0x1c3bb0, 0x4); |
| |
| /* Disables the CF_END frame */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141E0F48); |
| |
| /* Disable the SW Decrypt*/ |
| zfDelayWriteInternalReg(dev, 0x1c3678, 0x70); |
| zfFlushDelayWrite(dev); |
| //--------------------- |
| |
| /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */ |
| zfUpdateDefaultQosParameter(dev, 0); |
| |
| //zfSelAdcClk(dev, 0); |
| |
| return; |
| } |
| |
| |
| u16_t zfHpSetSnifferMode(zdev_t* dev, u16_t on) |
| { |
| if (on != 0) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_SNIFFER, 0x2000001); |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_SNIFFER, 0x2000000); |
| } |
| zfFlushDelayWrite(dev); |
| return 0; |
| } |
| |
| |
| u16_t zfHpSetApStaMode(zdev_t* dev, u8_t mode) |
| { |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| hpPriv->dot11Mode = mode; |
| |
| switch(mode) |
| { |
| case ZM_HAL_80211_MODE_AP: |
| zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f0000a1); |
| zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); |
| break; |
| |
| case ZM_HAL_80211_MODE_STA: |
| zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f000002); |
| zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); |
| break; |
| |
| case ZM_HAL_80211_MODE_IBSS_GENERAL: |
| zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f000000); |
| zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); |
| break; |
| |
| case ZM_HAL_80211_MODE_IBSS_WPA2PSK: |
| zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f0000e0); |
| zfDelayWriteInternalReg(dev, 0x1c3c40, 0x41); // for multiple ( > 2 ) stations IBSS network |
| break; |
| |
| default: |
| goto skip; |
| } |
| |
| zfFlushDelayWrite(dev); |
| |
| skip: |
| return 0; |
| } |
| |
| |
| u16_t zfHpSetBssid(zdev_t* dev, u8_t* bssidSrc) |
| { |
| u32_t address; |
| u16_t *bssid = (u16_t *)bssidSrc; |
| |
| address = bssid[0] + (((u32_t)bssid[1]) << 16); |
| zfDelayWriteInternalReg(dev, 0x1c3618, address); |
| |
| address = (u32_t)bssid[2]; |
| zfDelayWriteInternalReg(dev, 0x1c361C, address); |
| zfFlushDelayWrite(dev); |
| return 0; |
| } |
| |
| |
| /************************************************************************/ |
| /* */ |
| /* FUNCTION DESCRIPTION zfHpUpdateQosParameter */ |
| /* Update TxQs CWMIN, CWMAX, AIFS and TXOP. */ |
| /* */ |
| /* INPUTS */ |
| /* dev : device pointer */ |
| /* cwminTbl : CWMIN parameter for TxQs */ |
| /* cwmaxTbl : CWMAX parameter for TxQs */ |
| /* aifsTbl: AIFS parameter for TxQs */ |
| /* txopTbl : TXOP parameter for TxQs */ |
| /* */ |
| /* OUTPUTS */ |
| /* none */ |
| /* */ |
| /* AUTHOR */ |
| /* Stephen ZyDAS Technology Corporation 2006.6 */ |
| /* */ |
| /************************************************************************/ |
| u8_t zfHpUpdateQosParameter(zdev_t* dev, u16_t* cwminTbl, u16_t* cwmaxTbl, |
| u16_t* aifsTbl, u16_t* txopTbl) |
| { |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| zm_msg0_mm(ZM_LV_0, "zfHalUpdateQosParameter()"); |
| |
| /* Note : Do not change cwmin for Q0 in Ad Hoc mode */ |
| /* otherwise driver will fail in Wifi beacon distribution */ |
| if (hpPriv->dot11Mode == ZM_HAL_80211_MODE_STA) |
| { |
| #if 0 //Restore CWmin to improve down link throughput |
| //cheating in BE traffic |
| if (wd->sta.EnableHT == 1) |
| { |
| //cheating in BE traffic |
| cwminTbl[0] = 7;//15; |
| } |
| #endif |
| cwmaxTbl[0] = 127;//1023; |
| aifsTbl[0] = 2*9+10;//3 * 9 + 10; |
| } |
| |
| /* CWMIN and CWMAX */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, cwminTbl[0] |
| + ((u32_t)cwmaxTbl[0]<<16)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_CW, cwminTbl[1] |
| + ((u32_t)cwmaxTbl[1]<<16)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC2_CW, cwminTbl[2] |
| + ((u32_t)cwmaxTbl[2]<<16)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC3_CW, cwminTbl[3] |
| + ((u32_t)cwmaxTbl[3]<<16)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC4_CW, cwminTbl[4] |
| + ((u32_t)cwmaxTbl[4]<<16)); |
| |
| /* AIFS */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_AIFS, aifsTbl[0] |
| +((u32_t)aifsTbl[0]<<12)+((u32_t)aifsTbl[0]<<24)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC3_AC2_AIFS, (aifsTbl[0]>>8) |
| +((u32_t)aifsTbl[0]<<4)+((u32_t)aifsTbl[0]<<16)); |
| |
| /* TXOP */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_TXOP, txopTbl[0] |
| + ((u32_t)txopTbl[1]<<16)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC3_AC2_TXOP, txopTbl[2] |
| + ((u32_t)txopTbl[3]<<16)); |
| |
| zfFlushDelayWrite(dev); |
| |
| hpPriv->txop[0] = txopTbl[0]; |
| hpPriv->txop[1] = txopTbl[1]; |
| hpPriv->txop[2] = txopTbl[2]; |
| hpPriv->txop[3] = txopTbl[3]; |
| hpPriv->cwmin[0] = cwminTbl[0]; |
| hpPriv->cwmax[0] = cwmaxTbl[0]; |
| hpPriv->cwmin[1] = cwminTbl[1]; |
| hpPriv->cwmax[1] = cwmaxTbl[1]; |
| |
| return 0; |
| } |
| |
| |
| void zfHpSetAtimWindow(zdev_t* dev, u16_t atimWin) |
| { |
| zm_msg1_mm(ZM_LV_0, "Set ATIM window to ", atimWin); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_ATIM_WINDOW, atimWin); |
| zfFlushDelayWrite(dev); |
| } |
| |
| |
| void zfHpSetBasicRateSet(zdev_t* dev, u16_t bRateBasic, u16_t gRateBasic) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BASIC_RATE, bRateBasic |
| | ((u16_t)gRateBasic<<8)); |
| zfFlushDelayWrite(dev); |
| } |
| |
| |
| /* HT40 send by OFDM 6M */ |
| /* otherwise use reg 0x638 */ |
| void zfHpSetRTSCTSRate(zdev_t* dev, u32_t rate) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_RTS_CTS_RATE, rate); |
| zfFlushDelayWrite(dev); |
| } |
| |
| void zfHpSetMacAddress(zdev_t* dev, u16_t* macAddr, u16_t macAddrId) |
| { |
| if (macAddrId == 0) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_L, |
| (((u32_t)macAddr[1])<<16) | macAddr[0]); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_H, macAddr[2]); |
| } |
| else if (macAddrId <= 7) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_ACK_TABLE+((macAddrId-1)*8), |
| macAddr[0] + ((u32_t)macAddr[1]<<16)); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_ACK_TABLE+((macAddrId-1)*8)+4, |
| macAddr[2]); |
| } |
| zfFlushDelayWrite(dev); |
| } |
| |
| void zfHpSetMulticastList(zdev_t* dev, u8_t size, u8_t* pList, u8_t bAllMulticast) |
| { |
| struct zsMulticastAddr* pMacList = (struct zsMulticastAddr*) pList; |
| u8_t i; |
| u32_t value; |
| u32_t swRegMulHashValueH, swRegMulHashValueL; |
| |
| swRegMulHashValueH = 0x80000000; |
| swRegMulHashValueL = 0; |
| |
| if ( bAllMulticast ) |
| { |
| swRegMulHashValueH = swRegMulHashValueL = ~0; |
| } |
| else |
| { |
| for(i=0; i<size; i++) |
| { |
| value = pMacList[i].addr[5] >> 2; |
| |
| if ( value < 32 ) |
| { |
| swRegMulHashValueL |= (1 << value); |
| } |
| else |
| { |
| swRegMulHashValueH |= (1 << (value-32)); |
| } |
| } |
| } |
| |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_GROUP_HASH_TBL_L, |
| swRegMulHashValueL); |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_GROUP_HASH_TBL_H, |
| swRegMulHashValueH); |
| zfFlushDelayWrite(dev); |
| return; |
| } |
| |
| /******************** Beacon ********************/ |
| void zfHpEnableBeacon(zdev_t* dev, u16_t mode, u16_t bcnInterval, u16_t dtim, u8_t enableAtim) |
| { |
| u32_t value; |
| |
| zmw_get_wlan_dev(dev); |
| |
| /* Beacon Ready */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_CTRL, 0); |
| /* Beacon DMA buffer address */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_ADDR, ZM_BEACON_BUFFER_ADDRESS); |
| |
| value = bcnInterval; |
| |
| value |= (((u32_t) dtim) << 16); |
| |
| if (mode == ZM_MODE_AP) |
| { |
| |
| value |= 0x1000000; |
| } |
| else if (mode == ZM_MODE_IBSS) |
| { |
| value |= 0x2000000; |
| |
| if ( enableAtim ) |
| { |
| value |= 0x4000000; |
| } |
| ((struct zsHpPriv*)wd->hpPrivate)->ibssBcnEnabled = 1; |
| ((struct zsHpPriv*)wd->hpPrivate)->ibssBcnInterval = value; |
| } |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_PRETBTT, (bcnInterval-6)<<16); |
| |
| /* Beacon period and beacon enable */ |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, value); |
| zfFlushDelayWrite(dev); |
| } |
| |
| void zfHpDisableBeacon(zdev_t* dev) |
| { |
| zmw_get_wlan_dev(dev); |
| |
| ((struct zsHpPriv*)wd->hpPrivate)->ibssBcnEnabled = 0; |
| |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, 0); |
| zfFlushDelayWrite(dev); |
| } |
| |
| void zfHpLedCtrl(zdev_t* dev, u16_t ledId, u8_t mode) |
| { |
| u16_t state; |
| zmw_get_wlan_dev(dev); |
| |
| //zm_debug_msg1("LED ID=", ledId); |
| //zm_debug_msg1("LED mode=", mode); |
| if (ledId < 2) |
| { |
| if (((struct zsHpPriv*)wd->hpPrivate)->ledMode[ledId] != mode) |
| { |
| ((struct zsHpPriv*)wd->hpPrivate)->ledMode[ledId] = mode; |
| |
| state = ((struct zsHpPriv*)wd->hpPrivate)->ledMode[0] |
| | (((struct zsHpPriv*)wd->hpPrivate)->ledMode[1]<<1); |
| zfDelayWriteInternalReg(dev, 0x1d0104, state); |
| zfFlushDelayWrite(dev); |
| //zm_debug_msg0("Update LED"); |
| } |
| } |
| } |
| |
| /************************************************************************/ |
| /* */ |
| /* FUNCTION DESCRIPTION zfHpResetTxRx */ |
| /* Reset Tx and Rx Desc. */ |
| /* */ |
| /* INPUTS */ |
| /* dev : device pointer */ |
| /* */ |
| /* OUTPUTS */ |
| /* 0 : success */ |
| /* other : fail */ |
| /* */ |
| /* AUTHOR */ |
| /* Chao-Wen Yang ZyDAS Technology Corporation 2007.3 */ |
| /* */ |
| /************************************************************************/ |
| u16_t zfHpUsbReset(zdev_t* dev) |
| { |
| u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; |
| u16_t ret = 0; |
| |
| //zm_debug_msg0("CWY - Reset Tx and Rx"); |
| |
| cmd[0] = 0 | (ZM_CMD_RESET << 8); |
| |
| ret = zfIssueCmd(dev, cmd, 4, ZM_OID_INTERNAL_WRITE, NULL); |
| return ret; |
| } |
| |
| u16_t zfHpDKReset(zdev_t* dev, u8_t flag) |
| { |
| u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; |
| u16_t ret = 0; |
| |
| //zm_debug_msg0("CWY - Reset Tx and Rx"); |
| |
| cmd[0] = 4 | (ZM_CMD_DKRESET << 8); |
| cmd[1] = flag; |
| |
| ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, NULL); |
| return ret; |
| } |
| |
| u32_t zfHpCwmUpdate(zdev_t* dev) |
| { |
| //u32_t cmd[3]; |
| //u16_t ret; |
| // |
| //cmd[0] = 0x00000008; |
| //cmd[1] = 0x1c36e8; |
| //cmd[2] = 0x1c36ec; |
| // |
| //ret = zfIssueCmd(dev, cmd, 12, ZM_CWM_READ, 0); |
| //return ret; |
| |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv=wd->hpPrivate; |
| |
| zfCoreCwmBusy(dev, zfCwmIsExtChanBusy(hpPriv->ctlBusy, hpPriv->extBusy)); |
| |
| hpPriv->ctlBusy = 0; |
| hpPriv->extBusy = 0; |
| |
| return 0; |
| } |
| |
| u32_t zfHpAniUpdate(zdev_t* dev) |
| { |
| u32_t cmd[5]; |
| u16_t ret; |
| |
| cmd[0] = 0x00000010; |
| cmd[1] = 0x1c36e8; |
| cmd[2] = 0x1c36ec; |
| cmd[3] = 0x1c3cb4; |
| cmd[4] = 0x1c3cb8; |
| |
| ret = zfIssueCmd(dev, cmd, 20, ZM_ANI_READ, 0); |
| return ret; |
| } |
| |
| /* |
| * Update Beacon RSSI in ANI |
| */ |
| u32_t zfHpAniUpdateRssi(zdev_t* dev, u8_t rssi) |
| { |
| struct zsHpPriv* hpPriv; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv=wd->hpPrivate; |
| |
| hpPriv->stats.ast_nodestats.ns_avgbrssi = rssi; |
| |
| return 0; |
| } |
| |
| #define ZM_SEEPROM_MAC_ADDRESS_OFFSET (0x1400 + (0x106<<1)) |
| #define ZM_SEEPROM_REGDOMAIN_OFFSET (0x1400 + (0x104<<1)) |
| #define ZM_SEEPROM_VERISON_OFFSET (0x1400 + (0x102<<1)) |
| #define ZM_SEEPROM_HARDWARE_TYPE_OFFSET (0x1374) |
| #define ZM_SEEPROM_HW_HEAVY_CLIP (0x161c) |
| |
| u32_t zfHpGetMacAddress(zdev_t* dev) |
| { |
| u32_t cmd[7]; |
| u16_t ret; |
| |
| cmd[0] = 0x00000000 | 24; |
| cmd[1] = ZM_SEEPROM_MAC_ADDRESS_OFFSET; |
| cmd[2] = ZM_SEEPROM_MAC_ADDRESS_OFFSET+4; |
| cmd[3] = ZM_SEEPROM_REGDOMAIN_OFFSET; |
| cmd[4] = ZM_SEEPROM_VERISON_OFFSET; |
| cmd[5] = ZM_SEEPROM_HARDWARE_TYPE_OFFSET; |
| cmd[6] = ZM_SEEPROM_HW_HEAVY_CLIP; |
| |
| ret = zfIssueCmd(dev, cmd, 28, ZM_MAC_READ, 0); |
| return ret; |
| } |
| |
| u32_t zfHpGetTransmitPower(zdev_t* dev) |
| { |
| struct zsHpPriv* hpPriv; |
| u16_t tpc = 0; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| if (hpPriv->hwFrequency < 3000) { |
| tpc = hpPriv->tPow2x2g[0] & 0x3f; |
| wd->maxTxPower2 &= 0x3f; |
| tpc = (tpc > wd->maxTxPower2)? wd->maxTxPower2 : tpc; |
| } else { |
| tpc = hpPriv->tPow2x5g[0] & 0x3f; |
| wd->maxTxPower5 &= 0x3f; |
| tpc = (tpc > wd->maxTxPower5)? wd->maxTxPower5 : tpc; |
| } |
| |
| return tpc; |
| } |
| |
| u8_t zfHpGetMinTxPower(zdev_t* dev) |
| { |
| struct zsHpPriv* hpPriv; |
| u8_t tpc = 0; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| if (hpPriv->hwFrequency < 3000) |
| { |
| if(wd->BandWidth40) |
| { |
| //40M |
| tpc = (hpPriv->tPow2x2gHt40[7]&0x3f); |
| } |
| else |
| { |
| //20M |
| tpc = (hpPriv->tPow2x2gHt20[7]&0x3f); |
| } |
| } |
| else |
| { |
| if(wd->BandWidth40) |
| { |
| //40M |
| tpc = (hpPriv->tPow2x5gHt40[7]&0x3f); |
| } |
| else |
| { |
| //20M |
| tpc = (hpPriv->tPow2x5gHt20[7]&0x3f); |
| } |
| } |
| |
| return tpc; |
| } |
| |
| u8_t zfHpGetMaxTxPower(zdev_t* dev) |
| { |
| struct zsHpPriv* hpPriv; |
| u8_t tpc = 0; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv = wd->hpPrivate; |
| |
| if (hpPriv->hwFrequency < 3000) |
| { |
| tpc = (hpPriv->tPow2xCck[0]&0x3f); |
| } |
| else |
| { |
| tpc =(hpPriv->tPow2x5g[0]&0x3f); |
| } |
| |
| return tpc; |
| } |
| |
| u32_t zfHpLoadEEPROMFromFW(zdev_t* dev) |
| { |
| u32_t cmd[16]; |
| u32_t ret=0, i, j; |
| zmw_get_wlan_dev(dev); |
| |
| i = ((struct zsHpPriv*)wd->hpPrivate)->eepromImageRdReq; |
| |
| cmd[0] = ZM_HAL_MAX_EEPROM_PRQ*4; |
| |
| for (j=0; j<ZM_HAL_MAX_EEPROM_PRQ; j++) |
| { |
| cmd[j+1] = 0x1000 + (((i*ZM_HAL_MAX_EEPROM_PRQ) + j)*4); |
| } |
| |
| ret = zfIssueCmd(dev, cmd, (ZM_HAL_MAX_EEPROM_PRQ+1)*4, ZM_EEPROM_READ, 0); |
| |
| return ret; |
| } |
| |
| void zfHpHeartBeat(zdev_t* dev) |
| { |
| struct zsHpPriv* hpPriv; |
| u8_t polluted = 0; |
| u8_t ackTpc; |
| |
| zmw_get_wlan_dev(dev); |
| hpPriv=wd->hpPrivate; |
| |
| /* Workaround : Make OTUS fire more beacon in ad hoc mode in 2.4GHz */ |
| if (hpPriv->ibssBcnEnabled != 0) |
| { |
| if (hpPriv->hwFrequency <= ZM_CH_G_14) |
| { |
| if ((wd->tick % 10) == 0) |
| { |
| if ((wd->tick % 40) == 0) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, hpPriv->ibssBcnInterval-1); |
| polluted = 1; |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, hpPriv->ibssBcnInterval); |
| polluted = 1; |
| } |
| } |
| } |
| } |
| |
| if ((wd->tick & 0x3f) == 0x25) |
| { |
| /* Workaround for beacon stuck after SW reset */ |
| if (hpPriv->ibssBcnEnabled != 0) |
| { |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_ADDR, ZM_BEACON_BUFFER_ADDRESS); |
| polluted = 1; |
| } |
| |
| //DbgPrint("hpPriv->aggMaxDurationBE=%d", hpPriv->aggMaxDurationBE); |
| //DbgPrint("wd->sta.avgSizeOfReceivePackets=%d", wd->sta.avgSizeOfReceivePackets); |
| if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) |
| && (zfStaIsConnected(dev)) |
| && (wd->sta.EnableHT == 1) //11n mode |
| && (wd->BandWidth40 == 1) //40MHz mode |
| && (wd->sta.enableDrvBA ==0) //Marvel AP |
| && (hpPriv->aggMaxDurationBE > 2000) //BE TXOP > 2ms |
| && (wd->sta.avgSizeOfReceivePackets > 1420)) |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3b9c, 0x8000a); |
| polluted = 1; |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3b9c, hpPriv->aggPktNum); |
| polluted = 1; |
| } |
| |
| if (wd->dynamicSIFSEnable == 0) |
| { |
| if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) |
| && (zfStaIsConnected(dev)) |
| && (wd->sta.EnableHT == 1) //11n mode |
| && (wd->BandWidth40 == 0) //20MHz mode |
| && (wd->sta.enableDrvBA ==0)) //Marvel AP |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3698, 0x5144000); |
| polluted = 1; |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3698, 0xA144000); |
| polluted = 1; |
| } |
| } |
| else |
| { |
| if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) |
| && (zfStaIsConnected(dev)) |
| && (wd->sta.EnableHT == 1) //11n mode |
| && (wd->sta.athOwlAp == 1)) //Atheros AP |
| { |
| if (hpPriv->retransmissionEvent) |
| { |
| switch(hpPriv->latestSIFS) |
| { |
| case 0: |
| hpPriv->latestSIFS = 1; |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0x8144000); |
| break; |
| case 1: |
| hpPriv->latestSIFS = 2; |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); |
| break; |
| case 2: |
| hpPriv->latestSIFS = 3; |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xc144000); |
| break; |
| case 3: |
| hpPriv->latestSIFS = 0; |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); |
| break; |
| default: |
| hpPriv->latestSIFS = 0; |
| zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); |
| break; |
| } |
| polluted = 1; |
| zm_debug_msg1("##### Correct Tx retransmission issue #####, ", hpPriv->latestSIFS); |
| hpPriv->retransmissionEvent = 0; |
| } |
| } |
| else |
| { |
| hpPriv->latestSIFS = 0; |
| hpPriv->retransmissionEvent = 0; |
| zfDelayWriteInternalReg(dev, 0x1c3698, 0xA144000); |
| polluted = 1; |
| } |
| } |
| |
| if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE)) |
| { |
| #define ZM_SIGNAL_THRESHOLD 66 |
| if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) |
| && (zfStaIsConnected(dev)) |
| && (wd->SignalStrength > ZM_SIGNAL_THRESHOLD)) |
| { |
| /* remove state handle, always rewrite register setting */ |
| //if (hpPriv->strongRSSI == 0) |
| { |
| hpPriv->strongRSSI = 1; |
| /* Strong RSSI, set ACK to one Tx stream and lower Tx power 7dbm */ |
| if (hpPriv->currentAckRtsTpc > (14+10)) |
| { |
| ackTpc = hpPriv->currentAckRtsTpc - 14; |
| } |
| else |
| { |
| ackTpc = 10; |
| } |
| zfDelayWriteInternalReg(dev, 0x1c3694, ((ackTpc) << 20) | (0x1<<26)); |
| zfDelayWriteInternalReg(dev, 0x1c3bb4, ((ackTpc) << 5 ) | (0x1<<11) | |
| ((ackTpc) << 21) | (0x1<<27) ); |
| polluted = 1; |
| } |
| } |
| else |
| { |
| /* remove state handle, always rewrite register setting */ |
| //if (hpPriv->strongRSSI == 1) |
| { |
| hpPriv->strongRSSI = 0; |
| if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->currentAckRtsTpc&0x3f) << 20) | (0x1<<26)); |
| zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->currentAckRtsTpc&0x3f) << 5 ) | (0x1<<11) | |
| ((hpPriv->currentAckRtsTpc&0x3f) << 21) | (0x1<<27) ); |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->currentAckRtsTpc&0x3f) << 20) | (0x5<<26)); |
| zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->currentAckRtsTpc&0x3f) << 5 ) | (0x5<<11) | |
| ((hpPriv->currentAckRtsTpc&0x3f) << 21) | (0x5<<27) ); |
| } |
| polluted = 1; |
| } |
| } |
| #undef ZM_SIGNAL_THRESHOLD |
| } |
| |
| if ((hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) == 0) |
| { |
| if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE)) |
| { |
| #define ZM_RX_SIGNAL_THRESHOLD_H 71 |
| #define ZM_RX_SIGNAL_THRESHOLD_L 66 |
| u8_t rxSignalThresholdH = ZM_RX_SIGNAL_THRESHOLD_H; |
| u8_t rxSignalThresholdL = ZM_RX_SIGNAL_THRESHOLD_L; |
| #undef ZM_RX_SIGNAL_THRESHOLD_H |
| #undef ZM_RX_SIGNAL_THRESHOLD_L |
| |
| if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) |
| && (zfStaIsConnected(dev)) |
| && (wd->SignalStrength > rxSignalThresholdH) |
| )//&& (hpPriv->rxStrongRSSI == 0)) |
| { |
| hpPriv->rxStrongRSSI = 1; |
| //zfDelayWriteInternalReg(dev, 0x1c5964, 0x1220); |
| //zfDelayWriteInternalReg(dev, 0x1c5960, 0x900); |
| //zfDelayWriteInternalReg(dev, 0x1c6960, 0x900); |
| //zfDelayWriteInternalReg(dev, 0x1c7960, 0x900); |
| if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE |
| { |
| if (hpPriv->hwFrequency <= ZM_CH_G_14) |
| { |
| zfDelayWriteInternalReg(dev, 0x1c8960, 0x900); |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, 0x1c8960, 0x9b49); |
| } |
| } |
| else |
| { |
| zfDelayWriteInternalReg(dev, 0x1c8960, 0x0900); |
| } |
| polluted = 1; |
| } |
| else if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) |
| && (zfStaIsConnected(dev))
|