int NoiseFloorLoadWait(int *nfc, int *nfe, int nfn, int timeout) { int ip; unsigned int ready; NoiseFloorLoad(nfc,nfe,nfn); for(ip=0; ip<timeout; ip++) { // // wait for noise floor calibration to finish // FieldRead("BB_agc_control.do_noisefloor",&ready); if(ready==0) { break; } UserPrint("."); } if(ip>=timeout) { UserPrint("timeout."); return -1; } return 0; }
int Ar9287_ChecksumCalculate(void) { ar9287_eeprom_t *peep9287; A_UINT16 sum = 0, *pHalf, i; peep9287 = (ar9287_eeprom_t *)Ar9287EepromStructGet(); peep9287->baseEepHeader.checksum=0; UserPrint("Ar9287_ChecksumSet: checksum init=0x%x\n", peep9287->baseEepHeader.checksum); // prints the Current EEPROM structure // printf("target endian %d\ client endian %d\n", targetEndian, clientEndian); // printf("length %x\n", pEepStruct->baseEepHeader.length); // change endianness of 16 and 32 bit elements pHalf = (A_UINT16 *)peep9287; //apply the endian macro to any fields that we were using // pEepStruct->baseEepHeader.length = host2target16(pEepStruct->baseEepHeader.length); // for (i = 0; i < lengthStruct/2; i++) { for (i = 0; i < sizeof(ar9287_eeprom_t)/2; i++) { sum ^= *pHalf++; } // pEepStruct->baseEepHeader.checksum = host2target16(0xFFFF ^ sum); // Don't need to swap checksum. #if 1 //peep9287->baseEepHeader.checksum = sum; //UserPrint("Ar9287_ChecksumSet: checksum calculated before ^0xffff =0x%x\n", peep9287->baseEepHeader.checksum); peep9287->baseEepHeader.checksum = 0xFFFF ^ sum; UserPrint("Ar9287_ChecksumSet: checksum calculated after ^0xffff =0x%x\n", peep9287->baseEepHeader.checksum); #else UserPrint("Ar9287CalDataCheckSumSet: byte count=0x%x, checksum (calculated)=0x%x\n", i, sum); #endif return 0; }
void LinkRxDump(void *dr, int ndump, int np) { char buffer[MBUFFER]; int datalen; int it; if(ndump>MBUFFER) { ndump=MBUFFER; } RxDescriptorPrint(dr,buffer,MBUFFER); UserPrint("%s\n",buffer); // // fetch the data // datalen=RxDescriptorDataLen(dr); if(ndump>datalen) { ndump=datalen; } MyMemoryRead(LinkRxLoopBuffer[np], (unsigned int *)buffer, ndump); // // print // for(it=0; it<ndump; it++) { UserPrint("%02x ",buffer[it]); } UserPrint("\n"); }
void computeChecksum (QC98XX_EEPROM *pEepStruct) { A_UINT16 sum, *pHalf; UserPrint("--computeChecksum old 0x%x\n", pEepStruct->baseEepHeader.checksum); pEepStruct->baseEepHeader.checksum = 0x0000; pHalf = (A_UINT16 *)pEepStruct; sum = computeChecksumOnly(pHalf, (sizeof(QC98XX_EEPROM))/2); sum = 0xFFFF ^ sum; memcpy(&pEepStruct->baseEepHeader.checksum, &sum, 2); UserPrint("--computeChecksum new 0x%x\n", pEepStruct->baseEepHeader.checksum); }
int NoiseFloorFetchWait(int *nfc, int *nfe, int nfn, int timeout) { unsigned int mask; int it; unsigned int address; int high, low; int ip; unsigned int ready; // // noise floor values are signed. this computes a mask to extend the sign bit // it assumes that all the values are the same length. // mask=0; if(FieldFind("BB_cca_b0.minCCApwr_0", &address, &low, &high)) { for(it=high-low+1; it<32; it++) { mask |= (1<<it); } } for(ip=0; ip<timeout; ip++) { // // wait for noise floor calibration to finish // FieldRead("BB_agc_control.do_noisefloor",&ready); if(ready==0) { NoiseFloorFetch(nfc, nfe, nfn); break; } else { UserPrint("."); MyDelay(1); } } if(ip>=timeout) { UserPrint("timeout."); nfc[0]=0; nfc[1]=0; nfc[2]=0; nfe[0]=0; nfe[1]=0; nfe[2]=0; return -1; } return 0; }
// // Create a loop of rx descriptors. // Return the address of the first one. // int LinkRxLoopCreate(int many) { int it; unsigned int dr[MDESCRIPTOR]; unsigned int descriptorNext; many=LinkRxLoopMany; // we ignore the suggested queue size // MemoryLayout(1024); /* * create a few descriptors linked in a loop * OSPREY requires that the memory buffer directly follow the descriptor. Older chip sets * include a pointer to the buffer in the descriptor. This code does both. */ for(it=0; it<many; it++) { LinkRxLoopDescriptor[it] = MemoryLayout(RxDescriptorSize()+MPACKETSIZEBUFFER); if(LinkRxLoopDescriptor[it]==0) { UserPrint( "Device Number %d:rxDataSetup: unable to allocate memory for %d descriptors\n", 0, many); return -1; } LinkRxLoopBuffer[it]=LinkRxLoopDescriptor[it]+RxDescriptorSize(); } // // fill in the descriptors // for (it = 0; it < many; it++) { // // figure out next pointer, last one loops back to first // if (it == many - 1) { descriptorNext = LinkRxLoopDescriptor[0]; } else { descriptorNext = LinkRxLoopDescriptor[it+1]; //descriptor + RxDescriptorSize(); } // // make the descriptor // // UserPrint("%2d: %8x %8x %8x\n",it,LinkRxLoopDescriptor[it],LinkRxLoopBuffer[it],descriptorNext); RxDescriptorSetup(dr,descriptorNext,LinkRxLoopBuffer[it],MPACKETSIZE); // // copy it to the shared memory // MyMemoryWrite(LinkRxLoopDescriptor[it],dr,RxDescriptorSize()); // memset(dr, 0x55, RxDescriptorSize()); // MyMemoryWrite(LinkRxLoopDescriptor[it]+48,dr,RxDescriptorSize()); } // LinkRxLoopMany=many; return 0; }
int Ar9300TemperatureGetOld(void) { unsigned int temperature=0; unsigned int AnalogTemp=0; unsigned int stuck=0; unsigned int currentTime; unsigned int endTime; int i; currentTime = TimeMillisecond(); endTime = savedTime+5000; if((endTime>savedTime && (currentTime>endTime || currentTime<savedTime)) || (endTime<savedTime && currentTime>endTime && currentTime<savedTime)) { if(TemperatureAddress==0) { Ar9300TemperatureFieldLookup(); } for(i = 0; i<MSTUCK; i++) { MyDelay(1); MyFieldRead(TemperatureAddress,TemperatureLow,TemperatureHigh,&temperature); MyFieldRead(TemperatureDoneAddress,TemperatureDoneLow,TemperatureDoneHigh,&stuck); MyFieldRead(AnalogTempAddress, AnalogTempLow, AnalogTempHigh, &AnalogTemp); UserPrint("Stuck = %d ", stuck); if (stuck == 1){ break; } } //UserPrint("\n"); if((stuck==0)) { TemperatureRestart(); } else { savedTemp = temperature; } UserPrint("\nctemp=%d stemp=%d alogTemp = %d, ctime=%d stime=%d stuck=%d\n", temperature,savedTemp,AnalogTemp,currentTime, savedTime, stuck); savedTime = currentTime; } return (int)savedTemp; }
static int TxStatusCheck() { unsigned int txe; static unsigned int txeLast; DeviceRegisterRead(0x0840,&txe); // if(txe!=txeLast) { if(txe==0) { UserPrint(" OFF"); } else { UserPrint(" ON"); } } txeLast=txe; return txe; }
void SleepModeCommand(int client) { int error; char *name; int np, ip, ngot; int value, selection; // // prepare beginning of error message in case we need to use it // error=0; // //parse arguments and do it // np=CommandParameterMany(); for(ip=0; ip<np; ip++) { name=CommandParameterName(ip); if (strlen(name)==0) continue; // sometime there are tab or space at the end count as np with name as "", skip it selection=ParameterSelect(name,SleepModeParameter,sizeof(SleepModeParameter)/sizeof(SleepModeParameter[0])); switch(selection) { case SleepMode: ngot=SformatInput(CommandParameterValue(ip,0)," %d ",&value); if(ngot != 1 || (value < SleepModeMin || value > SleepModeMax)) { ErrorPrint(ParseBadValue, CommandParameterValue(value, 0),"mode"); error++; } break; default: break; } } if (error == 0) { if (CurrentSleepMode == value) { UserPrint("The device is currently in %s mode.\n", (value == SLEEP_MODE_SLEEP ? "sleep" : (value == SLEEP_MODE_WAKEUP ? "wakeup" : "deep sleep"))); } else { SendOn(client); DeviceSleepMode(value); SendOff(client); CurrentSleepMode = value; } } SendDone(client); }
int Qc98xxRateGroupIndex2Stream (A_UINT16 rateGroupIndex, A_UINT16 neighborRateIndex) { int stream; switch (rateGroupIndex) { case WHAL_VHT_TARGET_POWER_RATES_MCS0_10_20: //not sure what stream these 3 belong to case WHAL_VHT_TARGET_POWER_RATES_MCS1_2_11_12_21_22: case WHAL_VHT_TARGET_POWER_RATES_MCS3_4_13_14_23_24: if (neighborRateIndex <= WHAL_VHT_TARGET_POWER_RATES_MCS9) { stream = 0; } else if (neighborRateIndex <= WHAL_VHT_TARGET_POWER_RATES_MCS19) { stream = 1; } else { stream = 2; } case WHAL_VHT_TARGET_POWER_RATES_MCS5: case WHAL_VHT_TARGET_POWER_RATES_MCS6: case WHAL_VHT_TARGET_POWER_RATES_MCS7: case WHAL_VHT_TARGET_POWER_RATES_MCS8: case WHAL_VHT_TARGET_POWER_RATES_MCS9: stream = 0; break; case WHAL_VHT_TARGET_POWER_RATES_MCS15: case WHAL_VHT_TARGET_POWER_RATES_MCS16: case WHAL_VHT_TARGET_POWER_RATES_MCS17: case WHAL_VHT_TARGET_POWER_RATES_MCS18: case WHAL_VHT_TARGET_POWER_RATES_MCS19: stream = 1; break; case WHAL_VHT_TARGET_POWER_RATES_MCS25: case WHAL_VHT_TARGET_POWER_RATES_MCS26: case WHAL_VHT_TARGET_POWER_RATES_MCS27: case WHAL_VHT_TARGET_POWER_RATES_MCS28: case WHAL_VHT_TARGET_POWER_RATES_MCS29: stream = 2; break; default: stream = -1; UserPrint("Qc98xxRateIndex2Stream - ERROR invalid rate group index\n"); break; } return stream; }
DEVICEDLLSPEC void RfBbTestPointStart(int frequency, int ht40, int bandwidth, int antennapair, unsigned char chainnum, int mbgain, int rfgain, int coex, int sharedrx, int switchtable, unsigned char AnaOutEn, int (*ison)(), int (*done)()) { int it; DeviceRfBbTestPoint(frequency, ht40, bandwidth, antennapair, chainnum, mbgain, rfgain, coex, sharedrx, switchtable, AnaOutEn); if(ison!=0) { (*ison)(); } for(it = 0; ; it++) { // // check for message from cart telling us to stop // this is the normal terminating condition // if(done!=0) { if((*done)()) { UserPrint("Stop message received.\n"); break; } } // // sleep every other time, need to keep up with fast rates // if (it % 100 == 0) { UserPrint("."); } MyDelay(100); } }
static int LinkTxBatchNext(int nd, int queue) { int batch; int check; int it; int end; if(PacketMany<=0 || nd<LinkTxMany) { batch=nd/LinkTxBatchMany; check=nd%LinkTxBatchMany; if(check!=0) { UserPrint("bad request to make batch: nd=%d many=%d batch=%d check=%d\n",nd,LinkTxBatchMany,batch,check); return -1; } else { // UserPrint("make batch: nd=%d many=%d batch=%d check=%d\n",nd,LinkTxBatchMany,batch,check); } // // make the descriptors // end=nd+LinkTxBatchMany; if(PacketMany>0 && end>LinkTxMany) { end=LinkTxMany; } // UserPrint("\nMAKE BATCH %d: %d to %d\n",batch,nd,end-1); for(it=nd; it<end; it++) { LinkTxNextDescriptor(it); } // // if autoqueue is set, do it // if(queue) { LinkTxBatchQueue(nd); } } else { // UserPrint("\nBATCH DONE\n"); } return 0; }
// // start transmission // int DescriptorLinkTxStart() { unsigned int qmask; int queueIndex; // // turn on the reciever so we can get acks // WHY DO WE DO THIS FOR tx99 mode???? // if(!DeafMode && !Broadcast) { DescriptorLinkRxStart(0); } // // enable transmitter // queueIndex=0; qmask=1; DeviceTransmitQueueSetup(0,0); // // enable before because Osprey requires it // if(LinkTxEnableFirst) { DeviceTransmitEnable(1); } TxStatusCheck(); LinkTxBatchQueue(0); LinkTxBatchQueue(LinkTxBatchMany); TxStatusCheck(); // // enable after because Merlin requires it // if(!LinkTxEnableFirst) { DeviceTransmitEnable(1); } TxStatusCheck(); UserPrint("tx start done\n"); TxStatusCheck(); return 0; }
static int LinkTxStatusLoopCreateSplit(int numDesc) { int it; unsigned int dr[MDESCRIPTOR]; LinkTxLoopDescriptorStatus[0] = MemoryLayout(numDesc * TxDescriptorStatusSize()); if(LinkTxLoopDescriptorStatus[0]==0) { UserPrint("txDataSetup: unable to allocate client memory for %d status descriptors\n",numDesc); return -1; } TxDescriptorStatusSetup(dr); for(it=0; it<numDesc; it++) { LinkTxLoopDescriptorStatus[it]=LinkTxLoopDescriptorStatus[0]+it*TxDescriptorStatusSize(); DeviceMemoryWrite(LinkTxLoopDescriptorStatus[it],dr,TxDescriptorStatusSize()); } DeviceTransmitDescriptorStatusPointer(LinkTxLoopDescriptorStatus[0],LinkTxLoopDescriptorStatus[0]+numDesc*TxDescriptorStatusSize()); return 0; }
int Qc98xxRateIndex2Stream (A_UINT16 rateIndex) { int stream; if (IS_1STREAM_RATE_INDEX(rateIndex) || IS_1STREAM_vRATE_INDEX(rateIndex)) { stream = 0; } else if (IS_2STREAM_RATE_INDEX(rateIndex) || IS_2STREAM_vRATE_INDEX(rateIndex)) { stream = 1; } else if (IS_3STREAM_RATE_INDEX(rateIndex) || IS_3STREAM_vRATE_INDEX(rateIndex)) { stream = 2; } else { stream = -1; UserPrint("Qc98xxRateIndex2Stream - ERROR invalid rate group index\n"); } return stream; }
// // interpolates into the stored data structure and returns the value that will be used // void TargetPowerGetCommand(int client) { int np, ip; char *name; char buffer[MBUFFER]; int error; int parseStatus=0, nc=0, lc=0; int index; int code; int it, nfrequency, frequency[MLOOP]; int ir, nrate, rate[MRATE], nvrate, vrate[MRATE]; double tp; int rlegacy,rht20,rht40,rerror,ngot,extra; int nvalue; // // install default parameter values // error=0; // // a bunch of frequencies // nfrequency=1; frequency[0]= 2412; // // all rates // nrate=1; rate[0]=RATE_INDEX_6; // // parse arguments and do it // np=CommandParameterMany(); for(ip=0; ip<np; ip++) { name=CommandParameterName(ip); index=ParameterSelectIndex(name,TargetPowerParameter,sizeof(TargetPowerParameter)/sizeof(TargetPowerParameter[0])); if(index>=0) { code=TargetPowerParameter[index].code; switch(code) { case LinkParameterFrequency: nfrequency=ParseIntegerList(ip,name,frequency,&TargetPowerParameter[index]); if(nfrequency<=0) { error++; } break; case LinkParameterRate: nvalue=CommandParameterValueMany(ip); // // check if it might be the old mask codes // rerror=1; if(nvalue==3) { rerror=0; rlegacy=0; rht20=0; rht40=0; ngot=SformatInput(CommandParameterValue(ip,0)," %x %1c",&rlegacy,&extra); if(ngot!=1) { rerror++; } if(nvalue>=2) { ngot=SformatInput(CommandParameterValue(ip,1)," %x %1c",&rht20,&extra); if(ngot!=1) { rerror++; } } if(nvalue>=3) { ngot=SformatInput(CommandParameterValue(ip,2)," %x %1c",&rht40,&extra); if(ngot!=1) { rerror++; } } if(rerror<=0) { nrate=RateCount(rlegacy,rht20,rht40,rate); UserPrint("Note: Please use rate names as possible. Rate masks will be obsolete in the future.\n"); } } if(rerror!=0) { nrate=ParseIntegerList(ip,name,rate,&TargetPowerParameter[index]); if(nrate<=0) { error++; } else { nrate=RateExpand(rate,nrate); nrate=vRateExpand(rate,nrate); } } break; default: ErrorPrint(ParseBadParameter,name); error++; break; } } else { error++; ErrorPrint(ParseBadParameter,name); } } if(error<=0) { // // check if card is loaded // if(!CardValid()) { ErrorPrint(CardNoneLoaded); } else { ErrorPrint(NartDataHeader,"|tp|frequency|rate||target|"); for(it=0; it<nfrequency; it++) { for(ir=0; ir<nrate; ir++) { DeviceTargetPowerGet(frequency[it],rate[ir],&tp); if (IS_vRate(rate[ir])) SformatOutput(buffer,MBUFFER-1,"|tp|%d|%s||%.1lf|",frequency[it],vRateStrAll[rate[ir]-numRateCodes],tp); else SformatOutput(buffer,MBUFFER-1,"|tp|%d|%s||%.1lf|",frequency[it],rateStrAll[rate[ir]],tp); buffer[MBUFFER-1]=0; ErrorPrint(NartData,buffer); } } } } SendDone(client); }
// // take an existing descriptor and alter it to be the next desciptor: // clear all status fields // alter rate and other control parameters // copy it back to the shared memory // // if this is the last required descriptor, zero the link pointer // so that transmission will terminate // static int LinkTxNextDescriptor(int nd) { int rate; // which rate should we use int packet; // which packet number int agg; int slot; int ht40; int sgi; unsigned int dr[MDESCRIPTOR]; unsigned int dptr, nptr; // unsigned char buffer[MBUFFER]; if(PacketMany<=0 || nd<LinkTxMany) { if(InterleaveRate) { packet=nd/(RateMany*(AggregateMany+AggregateBar)); rate=nd%(RateMany*(AggregateMany+AggregateBar)); agg=rate%(AggregateMany+AggregateBar); rate=rate/(AggregateMany+AggregateBar); } else if(PacketMany>0) { rate=nd/(PacketMany*(AggregateMany+AggregateBar)); packet=nd%(PacketMany*(AggregateMany+AggregateBar)); agg=packet%(AggregateMany+AggregateBar); packet=packet/(AggregateMany+AggregateBar); } else { rate=0; packet=nd; agg=0; } slot=nd%(2*LinkTxBatchMany); dptr=LinkTxLoopDescriptor[slot]; // // set link pointer // we make a loop if the number of required descriptors is greater than MQUEUE // // UserPrint("make %d %d\n",nd,slot); if((slot%LinkTxBatchMany)==LinkTxBatchMany-1 || (LinkTxMany>0 && nd>=LinkTxMany-1)) { // // we're done // nptr=0; // UserPrint("null ptr on %d %d\n",nd,slot); } else { // // point to next descriptor // nptr=LinkTxLoopDescriptor[(slot+1)%(2*LinkTxBatchMany)]; } if(AggregateMany>1 && AggregateBar!=0 && agg==AggregateMany) { // // special bar packet for aggregates // TxDescriptorSetup(dr, nptr, LinkTxBarBuffer(), LinkTxBarBufferSize(), Broadcast, Retry, Rate[32], 0, 0, 1, 0, 0, nd&0xffff); // // keep pointer from expected status descriptor to the control descriptor // LinkTxQueued[LinkTxQueuedLast]=nd; // UserPrint(" c[%d]=%d",LinkTxQueuedLast,nd); LinkTxQueuedLast=(LinkTxQueuedLast+1)%LinkTxDescriptorMany; } else { // // this code figures out if the incoming packets have interleaved rates // this is solely for debug purposes // if(InterleaveRate==0 && Rate[rate]!=RateLastQueue) { UserPrint("(%d)",Rate[rate]); RateLastQueue=Rate[rate]; } // // normal packet // ht40=IS_HT40_RATE_INDEX(Rate[rate]); // support short gi for both ht20/ht40 rates. sgi=ShortGi; // // don't allow aggregates at legacy rates // so just send multiple packets // if(IS_LEGACY_RATE_INDEX(Rate[rate])) { TxDescriptorSetup(dr, nptr, LinkTxLoopBuffer(agg), LinkTxLoopBufferSize(agg), Broadcast, Retry, Rate[rate], 0, 0, TxChain, 0, 0, nd&0xffff); // // keep pointer from expected status descriptor to the control descriptor // LinkTxQueued[LinkTxQueuedLast]=nd; // UserPrint(" c[%d]=%d",LinkTxQueuedLast,nd); LinkTxQueuedLast=(LinkTxQueuedLast+1)%LinkTxDescriptorMany; } else { TxDescriptorSetup(dr, nptr, LinkTxLoopBuffer(agg), LinkTxLoopBufferSize(agg), Broadcast, Retry, Rate[rate], ht40, sgi, TxChain, AggregateMany, (agg!=AggregateMany-1), nd&0xffff); if(LinkTxAggregateStatus || agg==AggregateMany-1) { // // keep pointer from expected status descriptor to the control descriptor // LinkTxQueued[LinkTxQueuedLast]=nd; // UserPrint(" c[%d]=%d",LinkTxQueuedLast,nd); LinkTxQueuedLast=(LinkTxQueuedLast+1)%LinkTxDescriptorMany; } } } // Check if this packet is for PAPD if(PAPDTrainChainNum != -1) { TxDescriptorPAPDSetup(dr, PAPDTrainChainNum); } // // copy it back to the shared memory // DeviceMemoryWrite(dptr,dr,TxDescriptorSize()); return 0; } return -1; }
int papredistortionSingleTable(struct ath_hal *ah, HAL_CHANNEL *chan, int txChainMask) { int chainNum; unsigned int PA_table[24], smallSignalGain; int status = 0, disable_papd=1, chain_fail[3]={0,0,0}; int paprd_retry_count; UserPrint("Run PA predistortion algorithm: txChainMask=0x%X.\n", txChainMask); /* * Before doing PAPRD training, we must disable pal spare of * hw greeen tx function */ ar9300_hwgreentx_set_pal_spare(AH,0);//ar9300_set_pal_spare(AH,0); LinkTransmitPAPDWarmUp(txChainMask); status= ar9300_paprd_init_table(ah, chan); if(status==-1) { ar9300_enable_paprd(ah, AH_FALSE, chan); UserPrint("Warning:: PA predistortion failed in InitTable\n"); return -1; } { struct ath_hal_9300 *ahp = AH9300(ah); UserPrint("Training power_x2 is %d, channel %d\n", ahp->paprd_training_power, chan->channel); } for(chainNum=0; chainNum<3; chainNum++) { unsigned int i, desired_gain, gain_index; if(txChainMask&(1<<chainNum)) { paprd_retry_count = 0; while (paprd_retry_count < 5) { ar9300_paprd_setup_gain_table(ah,chainNum); LinkTransmitPAPD(ah, chainNum); ar9300_paprd_is_done(ah); status = ar9300_paprd_create_curve(ah, chan, chainNum); if (status != HAL_EINPROGRESS) { if(status==0) { ar9300_populate_paprd_single_table(ah, chan, chainNum); if (!AR_SREV_HONEYBEE(ah) && !AR_SREV_DRAGONFLY(ah)) { if (txChainMask == 0x2 || txChainMask == 0x4){ ar9300_populate_paprd_single_table(ah, chan, 0); } } disable_papd = 0; } else { disable_papd = 1; chain_fail[chainNum] = 1; } break; } else { /* need re-train paprd */ paprd_retry_count++; } } if (paprd_retry_count > 5) UserPrint("Warning: ch%d PAPRD re-train fail\n", (1 << chainNum)); } } if(disable_papd==0) { ar9300_enable_paprd(ah, AH_TRUE, chan); /* * restore PAL spare of hw green tx function */ ar9300_hwgreentx_set_pal_spare(AH,1); } else { ar9300_enable_paprd(ah, AH_FALSE, chan); UserPrint("Warning:: PA predistortion failed. chain_fail_flag %d %d %d\n", chain_fail[0], chain_fail[1], chain_fail[2]); /* * restore PAL spare of hw green tx function */ ar9300_hwgreentx_set_pal_spare(AH,1); return -1; } return 0; }
static int LinkTxBatchQueueLinkPtr(int nd) { unsigned int descriptor[MDESCRIPTOR]; // private copy of current descriptor int first,last; int batch; int behind, elapsed, start, end; // UserPrint("batch queue\n"); TxStatusCheck(); if(nd>0) { batch=nd/LinkTxBatchMany; // // Find the first descriptor queued in this batch. // first=(batch%2)*(LinkTxBatchMany); // // Find last descriptor queued from previous batch. // last=((batch+1)%2)*(LinkTxBatchMany)+LinkTxBatchMany-1; // // read the descriptor from the shared memory // DeviceMemoryRead(LinkTxLoopDescriptor[last], descriptor, TxDescriptorSize()); // UserPrint("link %d -> %d\n",last,first); // // check if it is done // if(TxDescriptorDone(descriptor)) { UserPrint("\nBATCH %d to %d: STALL. Previous batch done. Restart transmitter. %d %d\n",nd,nd+LinkTxBatchMany-1,last,first); // // this is where we need to push the descriptor into txdp // and restart the transmitter // DeviceTransmitDescriptorPointer(0, LinkTxLoopDescriptor[first]); DeviceTransmitEnable(1); } else { start=TxDescriptorPointerGet(); TxDescriptorLinkPtrSet(descriptor, LinkTxLoopDescriptor[first]); DeviceMemoryWrite(LinkTxLoopDescriptor[last], descriptor, TxDescriptorSize()); end=TxDescriptorPointerGet(); elapsed=(end-start)/TxDescriptorSize(); behind=(LinkTxLoopDescriptor[last]-end)/TxDescriptorSize(); UserPrint("\nBATCH %d to %d: %08x -> %08x margin=%d\n",nd,nd+LinkTxBatchMany-1,LinkTxLoopDescriptor[last],LinkTxLoopDescriptor[first],behind); // // this is where we need to check that the chip didn't do this descriptor while // we were fooling around. // DeviceMemoryRead(LinkTxLoopDescriptor[last], descriptor, TxDescriptorSize()); // // check if it is done. // if(TxDescriptorDone(descriptor)) { if(TxStatusCheck()==0) { UserPrint("\nBATCH %d to %d: STALL. Previous batch finished while linking. Restart transmitter. %d %d\n",nd,nd+LinkTxBatchMany-1,last,first); // // this is where we need to push the descriptor into txdp // and restart the transmitter // DeviceTransmitDescriptorPointer(0, LinkTxLoopDescriptor[first]); DeviceTransmitEnable(1); } } // // check and take remedial action if necessary, push descriptor into txdp and // restart transmitter // } } else { // // push into hardware, no fifo, so only one at a time // UserPrint("\nBATCH %d to %d\n",0,LinkTxBatchMany-1); DeviceTransmitDescriptorPointer(0, LinkTxLoopDescriptor[0]); // DeviceTransmitEnable(1); // TxStatusCheck(); } return 0; }
static int TemperatureRestart() { unsigned int save; unsigned int reg; unsigned int txReg; unsigned int readbackReg=0; int i; int pass = 1; // //Look for interframe spacing // /* for(i = 0; i<NUM_TX_FRAME_READS;i++) { MyRegisterRead(0x806c, &txReg); if(txReg & 0x200) { break; } // UserPrint("txReg = %d\n", txReg); } */ //read again to cause delay // MyRegisterRead(0x806c, &txReg); // // read and remember value // /////// MyRegisterRead(TemperatureAdc2Address,&save); // UserPrint("save=%x ",save); // // set these two bits // MyRegisterRead(TemperatureLocalAddress,®); reg |= (1<<TemperatureLocalLow); reg |= (1<<TemperatureStartLow); // UserPrint("writing to set bits reg=%x ",reg); MyRegisterWrite(TemperatureLocalAddress, reg); for (i=0;i<20;i++) { // MyDelay(1); MyRegisterRead(TemperatureLocalAddress, &readbackReg); // UserPrint("in local set: resetReg = %x\n", readbackReg); if(readbackReg & ((1<<TemperatureLocalLow) | (1<<TemperatureStartLow)) ) { break; } } if(i == 20) { UserPrint("!!!!!!!local_therm and/or thermStartbit not set, continue anyway reg = %x\n", readbackReg); pass = 0; } /* MyRegisterWrite(TemperatureLocalAddress,(reg | (1<<TemperatureStartLow))); for (i=0;i<10;i++) { // MyDelay(1); MyRegisterRead(TemperatureLocalAddress, &readbackReg); ///// UserPrint("in start set: resetReg = %x\n", readbackReg); if((readbackReg & (1<<TemperatureStartLow))) { break; } } if(i == 10) { UserPrint("!!!!!!!thermstart bit not set, continue anyway reg = %x\n", readbackReg); pass = 0; } */ // // then clear them // reg &= ~(1<<TemperatureLocalLow); reg &= ~(1<<TemperatureStartLow); //UserPrint("writing to clear bits reg-> %x ",reg); MyRegisterWrite(TemperatureLocalAddress,reg); for (i=0;i<10;i++) { // MyDelay(1); MyRegisterRead(TemperatureLocalAddress, &readbackReg); //// UserPrint("in local clear: resetReg = %x\n", readbackReg); if(((readbackReg >> TemperatureLocalLow) & 0x1)==0 ) { break; } } if(i == 10) { UserPrint("!!!!!!!local bits not clear, continue anyway reg = %x\n", readbackReg); pass = 0; } TemperatureStuckCount=0; //// UserPrint("temperature restart\n"); return (pass); }
// Added VSG sync detection void LinkRxComplete_vsgSync(int timeout, int ndump, unsigned char *dataPattern, int dataPatternLength, int (*done)(), int chainMask) { unsigned int startTime, endTime, ctime; int it, ii; int notdone; int stop; int behind; int scount; unsigned int mDescriptor; // address of descriptor in shared memory #ifdef MEMORYREAD unsigned int descriptor[MDESCRIPTOR+30]; // private copy of current descriptor #else unsigned int *descriptor; #endif int pass; int dsize; int isdone; int ss; int rssic[MCHAIN], rssie[MCHAIN], rssi; #define MSPECTRUM 1024 int nspectrum,spectrum[MSPECTRUM]; int ndata; unsigned char data[MBUFFER]; int sscount=0; unsigned int vsgSync = 0; pass=0; dataPatternLength=0; dataPattern=0; scount=0; dsize=RxDescriptorSize(); // // Loop timeout condition. // This number can be large since it is only used for // catastrophic failure of cart. The normal terminating // condition is a message from cart saying STOP. // startTime=TimeMillisecond(); ctime=startTime; if(timeout<=0) { timeout=2*60*1000; // 2 mins } endTime=startTime+timeout; // // set pointer to first descriptor // // mDescriptor = LinkRxLoopFirst(0); // // keep track of how many times we look and the descriptor is not done // this is used to control the sleep interval // notdone=0; stop=0; behind=0; // // loop looking for descriptors with received packets. // for(it = 0; ; it++) { mDescriptor=LinkRxLoopDescriptor[it%LinkRxLoopMany]; #ifdef MEMORYREAD // // read the next descriptor // MyMemoryRead(mDescriptor, descriptor, dsize); #else descriptor=(unsigned int *)MyMemoryPtr(mDescriptor); #endif // // descriptor is ready, we have a new packet // if(RxDescriptorDone(descriptor)) { #ifdef MEMORYREAD // // read the next descriptor // MyMemoryRead(mDescriptor, descriptor, dsize); #endif notdone=0; behind++; scount=0; #ifdef FASTER if((it%SASAMPLINGS)==0) { UserPrint(" %d",it); } #endif if(_LinkRxSpectralScan) { ss=Ar9300RxDescriptorSpectralScan(descriptor); if(ss) { // // extract rssi and evm measurements. we need these for both good and bad packets // rssi=RxDescriptorRssiCombined(descriptor); if(rssi&0x80) { rssi|=0xffffff00; } rssic[0]=RxDescriptorRssiAnt00(descriptor); rssic[1]=RxDescriptorRssiAnt01(descriptor); rssic[2]=RxDescriptorRssiAnt02(descriptor); rssie[0]=RxDescriptorRssiAnt10(descriptor); rssie[1]=RxDescriptorRssiAnt11(descriptor); rssie[2]=RxDescriptorRssiAnt12(descriptor); for(ii=0; ii<3; ii++) { if(rssic[ii]&0x80) { rssic[ii]|=0xffffff00; } if(rssie[ii]&0x80) { rssie[ii]|=0xffffff00; } } ndata=RxDescriptorDataLen(descriptor); MyMemoryRead(LinkRxLoopBuffer[it%LinkRxLoopMany], (unsigned int *)data, ndata); nspectrum=Ar9300SpectralScanProcess(data,ndata,spectrum,MSPECTRUM); if(_LinkRxSpectralScanFunction!=0) { (*_LinkRxSpectralScanFunction)(rssi,rssic,rssie,MCHAIN,spectrum,nspectrum); } // // extract stats if (!vsgSync) { vsgSync = ((rssic[0] >= ISSM80DBM_THRESHOLD) && (chainMask & (1 << 0)) || (rssic[1] >= ISSM80DBM_THRESHOLD) && (chainMask & (1 << 1)) || (rssic[2] >= ISSM80DBM_THRESHOLD) && (chainMask & (1 << 2)) ); } else { LinkRxStatSpectralScanExtract(descriptor,it); sscount++; //UserPrint("ss_cnt:rssic:mask %d, %d, %d, %d\n",sscount, rssic[0], rssic[1], chainMask); } if(sscount >= SASAMPLINGS) { break; } } } else { // dump packet contents // if(ndump>0) { UserPrint("\n"); LinkRxDump(descriptor, ndump, it%LinkRxLoopMany); } // // extract stats // LinkRxStatExtract(descriptor,it); } // // reset the descriptor so that we can use it again // RxDescriptorReset(descriptor); #ifdef MEMORYREAD // // copy it back to the shared memory // MyMemoryWrite(mDescriptor,descriptor,dsize); #endif // // need to queue the descriptor with the hardware // if(LinkRxDescriptorFifo) { DeviceReceiveDescriptorPointer(mDescriptor); } } // // descriptor not ready // else { if(stop) { scount++; if(scount>200) { break; } } it--; // // sleep every other time, need to keep up with fast rates // if(notdone>100) { UserPrint("."); // MyDelay(1); notdone=0; } else { notdone=1; // this makes sure we never sleep } } // // check for message from cart telling us to stop // this is the normal terminating condition // pass++; if(pass>100) { if(done!=0) { isdone=(*done)(); if(isdone!=0) { UserPrint(" %d Stop",it); if(stop==0) { stop=1; scount=0; behind=0; } // // immediate stop // if(isdone==2) { break; } // break; } } pass=0; // // check for timeout // rare terminating condition when cart crashes or disconnects // ctime=TimeMillisecond(); #if 1 if( timeout>0 && ((endTime>startTime && (ctime>endTime || ctime<startTime)) || (endTime<startTime && ctime>endTime && ctime<startTime))) { UserPrint("%d Timeout",it); break; } #endif } } // // cleanup // if(_LinkRxSpectralScan) { //DeviceSpectralScanDisable(); Ar9300SpectralScanDisable(); } DeviceReceiveDisable(); LinkRxLoopDestroy(0); // // do data verify if requested // UserPrint(" %d\n",it); LinkRxStatFinish(); return; }
// // run the transmitter // // (*ison)() is called when the transmitter is guaranteed to be on (first descriptor returned done) // // (*done)() is called to check if this function should stop early // int DescriptorLinkTxComplete(int timeout, int (*ison)(), int (*done)(), int chipTemperature, int calibrate) { int it; unsigned int startTime, endTime, ctime, failTime; int failRetry; int notdone; unsigned int mDescriptor; // address of descriptor in shared memory unsigned int descriptor[MDESCRIPTOR]; // private copy of current descriptor int cindex; // index of the corresponding control descriptor unsigned int *cd,cdescriptor[MDESCRIPTOR]; // private copy of current control descriptor int pass; int dsize; // int behind; int batch, lbatch; int temperature; int doTemp; LinkTxStatClear(); lbatch=0; pass=0; doTemp=0; dsize=TxDescriptorSize(); // // Loop timeout condition. // This number can be large since it is only used for // catastrophic failure of cart. The normal terminating // condition is a message from cart saying STOP. // startTime=TimeMillisecond(); ctime=startTime; // if(timeout<=0) // { // timeout=60*60*1000; // one hour // } endTime=startTime+timeout; if(Tx100Packet) { failTime=endTime; } else { failTime=startTime+(5*1000); // 5 seconds } failRetry=0; // // set pointer to first descriptor // mDescriptor = LinkTxLoopFirst(); // // keep track of how many times we look and the descriptor is not done // this is used to control the sleep interval // notdone=0; // tlast=0; // // if this is the first descriptor, announce that the transmitter is really on // if(ison!=0) { (*ison)(); } // // loop looking for descriptors with transmitted packets. // terminate either when we reach a null pointer (Merlin and prior) or // when we've done the specified number of packets (Osprey) // for(it=0; (LinkTxStatusMany<=0 || it<LinkTxStatusMany); it++) { // // read the next descriptor // mDescriptor=LinkTxLoopDescriptorStatus[it%LinkTxDescriptorMany]; DeviceMemoryRead(mDescriptor, descriptor, dsize); // // skip ahead for aggregates. // if(LinkTxAggregateStatus) { if(TxDescriptorAggregate(descriptor) && TxDescriptorMoreAgg(descriptor)) { // UserPrint("A"); continue; } } // // is it done? // if(TxDescriptorDone(descriptor)) { cindex=LinkTxQueued[it%LinkTxDescriptorMany]; batch=cindex/LinkTxBatchMany; // UserPrint("(%d %d %d)",it,cindex,batch); DeviceMemoryRead(mDescriptor, descriptor, dsize); // // get the control descriptor too // if(LinkTxSplitDescriptor) { DeviceMemoryRead(LinkTxLoopDescriptor[cindex%LinkTxDescriptorMany], cdescriptor, TxDescriptorSize()); cd=cdescriptor; } else { cd=descriptor; } #ifdef UNUSED behind=(TxDescriptorPointerGet()-mDescriptor)/dsize; if(behind>10) { UserPrint(" -%d",behind); } #endif notdone=0; if((it%100)==0) { UserPrint(" %d",it); } LinkTxStatExtract(descriptor,cd,AggregateMany,it); // // clear the status packet // if(LinkTxSplitDescriptor) { TxDescriptorStatusSetup(descriptor); DeviceMemoryWrite(LinkTxLoopDescriptorStatus[it%LinkTxDescriptorMany],descriptor,TxDescriptorStatusSize()); } // // Do we need to queue the next batch of descriptors? // if(batch>lbatch) { // UserPrint("\n%d %d %d %d\n",it,cindex,lbatch,batch); LinkTxBatchNext((batch+1)*LinkTxBatchMany,1); lbatch=batch; } } // // descriptor isn't done // else { it--; // // sleep every other time, need to keep up with fast rates // if(notdone>100) { UserPrint("."); // MyDelay(1); notdone=0; } else { notdone++; } } // // check temperature // if(doTemp>10) { temperature=DeviceTemperatureGet(0); // // are we supposed to terminate on reaching a certain chip temperature? // if(chipTemperature>0) { if(temperature<=chipTemperature) { UserPrint(" %d Temperature %d <= %d",it,temperature,chipTemperature); break; } } doTemp=0; } doTemp++; // // check for message from cart telling us to stop // this is the normal terminating condition // pass++; if(pass>100) { if(done!=0) { if((*done)()) { UserPrint(" %d Stop",it); break; } } pass=0; // // check for timeout // rare terminating condition when cart crashes or disconnects // ctime=TimeMillisecond(); if(timeout>0 && ((endTime>startTime && (ctime>endTime || ctime<startTime)) || (endTime<startTime && ctime>endTime && ctime<startTime))) { UserPrint(" %d Timeout",it); break; } // // check for failure to start // if(it<=0) { if((failTime>startTime && (ctime>failTime || ctime<startTime)) || (failTime<startTime && ctime>failTime && ctime<startTime)) { UserPrint("Failed to start transmit.\n"); if(failRetry==0) { UserPrint("Trying to restart.\n"); DescriptorLinkTxStart(); failTime=startTime+(5*1000); // 5 seconds failRetry++; // // set pointer to first descriptor // mDescriptor = LinkTxLoopFirst(); } else { ResetForce(); break; } } } } } TxStatusCheck(); DeviceTransmitDisable(0xffff); DeviceReceiveDisable(); LinkTxLoopDestroy(); DescriptorLinkRxLoopDestroy(); // // finish throughput calculation // LinkTxStatFinish(); TxStatusCheck(); UserPrint(" %d Done\n",it); return 0; }
A_BOOL readCalDataFromFile(char *fileName, QC98XX_EEPROM *eepromData, A_UINT32 *bytes) { FILE *fp; A_BOOL rc=1, recomputeChksum=0; size_t numBytes; A_UINT32 i, dataWord; A_UINT32 *pDataWord; char fullFileName[MAX_FILE_LENGTH]; strcpy (fullFileName, configSetup.boardDataPath); strcat (fullFileName, fileName); UserPrint("readCalDataFromFile - reading EEPROM file %s\n",fullFileName); if( (fp = fopen(fullFileName, "rb")) == NULL) { UserPrint("Could not open %s to read\n", fullFileName); if( (fp = fopen(fileName, "rb")) == NULL) { UserPrint("Could not open %s to read\n", fileName); return 0; } } if (QC98XX_EEPROM_SIZE_LARGEST == (numBytes = fread((A_UCHAR *)eepromData, 1, QC98XX_EEPROM_SIZE_LARGEST, fp))) { UserPrint("Read %d from %s\n", numBytes, fileName); if (eepromData->baseEepHeader.eeprom_version < QC98XX_EEP_VER1) { UserPrint("Error - This eeprom bin file v%d is not supported by this NART\n", eepromData->baseEepHeader.eeprom_version); rc = 0; } else { rc = 1; } } else { if (feof(fp)) { UserPrint("Read %d from %s\n", numBytes, fileName); rc = 1; } else if (ferror(fp)) { UserPrint("Error reading %s\n", fileName); rc = 0; } else { UserPrint("Unknown fread rc\n"); rc = 0; } } if (fp) fclose(fp); #ifdef AP_BUILD Qc98xx_swap_eeprom(eepromData); #endif if (numBytes != eepromData->baseEepHeader.length) { UserPrint("WARNING - file size of %d NOT match eepromData->baseEepHeader.length %d\n", numBytes, eepromData->baseEepHeader.length); } if (rc) { for (i = 0; i < WHAL_NUM_CHAINS; ++i) { rc = deriveNumCalChans(eepromData, &numPier5G[i], &numPier2G[i], i); } if (recomputeChksum) { eepromData->baseEepHeader.checksum = 0x0000; computeChecksum(eepromData); } *bytes = (A_UINT32)numBytes; } pDataWord = (A_UINT32 *)eepromData; #define MAX_BLOCK_SIZE 512 { int blockSize; #ifdef AP_BUILD Qc98xx_swap_eeprom(eepromData); #endif QC98XX_EEPROM tempEep; memcpy(&tempEep, eepromData, sizeof(QC98XX_EEPROM)); pDataWord = (A_UINT32 *)&tempEep; for(i=0; i<sizeof(QC98XX_EEPROM); i=i+MAX_BLOCK_SIZE) { if((i+MAX_BLOCK_SIZE)> sizeof(QC98XX_EEPROM)) { blockSize = sizeof(QC98XX_EEPROM) - i; } else { blockSize = MAX_BLOCK_SIZE; } if (Qc9KMemoryWrite(fwBoardDataAddress+i, &pDataWord[i/4], blockSize) != 0) { UserPrint("ERROR - loading golden caldata file into FW memory\n"); } } #ifdef AP_BUILD Qc98xx_swap_eeprom(eepromData); #endif } return rc; }
void LinkRxComplete(int timeout, int ndump, unsigned char *dataPattern, int dataPatternLength, int (*done)()) { unsigned int startTime, endTime, ctime; int it; int notdone; int stop; int behind; int scount; unsigned int mDescriptor; // address of descriptor in shared memory #ifdef MEMORYREAD unsigned int descriptor[MDESCRIPTOR+30]; // private copy of current descriptor #else unsigned int *descriptor; #endif int pass; int dsize; int isdone; pass=0; dataPatternLength=0; dataPattern=0; scount=0; dsize=RxDescriptorSize(); // // Loop timeout condition. // This number can be large since it is only used for // catastrophic failure of cart. The normal terminating // condition is a message from cart saying STOP. // startTime=TimeMillisecond(); ctime=startTime; // if(timeout<=0) // { // timeout=60*60*1000; // one hour // } endTime=startTime+timeout; // // set pointer to first descriptor // // mDescriptor = LinkRxLoopFirst(0); // // keep track of how many times we look and the descriptor is not done // this is used to control the sleep interval // notdone=0; stop=0; behind=0; // // loop looking for descriptors with received packets. // for(it = 0; ; it++) { mDescriptor=LinkRxLoopDescriptor[it%LinkRxLoopMany]; #ifdef MEMORYREAD // // read the next descriptor // MyMemoryRead(mDescriptor, descriptor, dsize); #else descriptor=(unsigned int *)MyMemoryPtr(mDescriptor); #endif // // descriptor is ready, we have a new packet // if(RxDescriptorDone(descriptor)) { #ifdef MEMORYREAD // // read the next descriptor // MyMemoryRead(mDescriptor, descriptor, dsize); #endif notdone=0; behind++; scount=0; #ifdef FASTER if((it%100)==0) { UserPrint(" %d",it); } #endif // // dump packet contents // if(ndump>0) { UserPrint("\n"); LinkRxDump(descriptor, ndump, it%LinkRxLoopMany); } // // extract stats // LinkRxStatExtract(descriptor,it); // // reset the descriptor so that we can use it again // RxDescriptorReset(descriptor); #ifdef MEMORYREAD // // copy it back to the shared memory // MyMemoryWrite(mDescriptor,descriptor,dsize); #endif // // need to queue the descriptor with the hardware // if(LinkRxDescriptorFifo) { DeviceReceiveDescriptorPointer(mDescriptor); } } // // descriptor not ready // else { if(stop) { scount++; if(scount>200) { break; } } it--; // // sleep every other time, need to keep up with fast rates // if(notdone>100) { UserPrint("."); // MyDelay(1); notdone=0; } else { notdone=1; // this makes sure we never sleep } } // // check for message from cart telling us to stop // this is the normal terminating condition // pass++; if(pass>100) { if(done!=0) { isdone=(*done)(); if(isdone!=0) { UserPrint(" %d Stop",it); if(stop==0) { stop=1; scount=0; behind=0; } // // immediate stop // if(isdone==2) { break; } // break; } } pass=0; // // check for timeout // rare terminating condition when cart crashes or disconnects // ctime=TimeMillisecond(); if(timeout>0 && ((endTime>startTime && (ctime>endTime || ctime<startTime)) || (endTime<startTime && ctime>endTime && ctime<startTime))) { UserPrint("%d Timeout",it); break; } } } // // cleanup // DeviceReceiveDisable(); LinkRxLoopDestroy(0); // // do data verify if requested // UserPrint(" %d\n",it); LinkRxStatFinish(); return; }
// // creates a block acknowledgement request (BAR) 802.11 message. // return the size of the message // int LinkTxBarCreate(unsigned char *source, unsigned char *destination) { // int it; // int nwrite; // unsigned int pPktAddr; unsigned int pPkt[24]; WLAN_BAR_CONTROL_MAC_HEADER *pPktHeader; // unsigned char *pBody; // int pPktSize; // // how big is the packet? // pPktHeader=(WLAN_BAR_CONTROL_MAC_HEADER *)pPkt; _LinkTxBarBufferSize = sizeof(WLAN_BAR_CONTROL_MAC_HEADER); // should be 20; // // create the packet Header, all fields are listed here to enable easy changing // pPktHeader->frameControl.protoVer = 0; pPktHeader->frameControl.fType = FRAME_CTRL; pPktHeader->frameControl.fSubtype = SUBT_QOS; pPktHeader->frameControl.ToDS = 0; pPktHeader->frameControl.FromDS = 0; pPktHeader->frameControl.moreFrag = 0; pPktHeader->frameControl.retry = 0; pPktHeader->frameControl.pwrMgt = 0; pPktHeader->frameControl.moreData = 0; pPktHeader->frameControl.wep = 0; pPktHeader->frameControl.order = 0; // Swap the bytes of the frameControl #if 0 //#ifdef ARCH_BIG_ENDIAN { unsigned short* ptr; ptr = (unsigned short *)(&(pPktHeader->frameControl)); *ptr = btol_s(*ptr); } #endif // pPktHeader->durationNav.clearBit = 0; // pPktHeader->durationNav.duration = 0; pPktHeader->durationNav = 0; // aman redefined the struct to be just unsigned short // Swap the bytes of the durationNav #if 0 //#ifdef ARCH_BIG_ENDIAN { unsigned short* ptr; ptr = (unsigned short *)(&(pPktHeader->durationNav)); *ptr = btol_s(*ptr); } #endif // // set the address fields // memcpy(pPktHeader->address1.octets, destination, WLAN_MAC_ADDR_SIZE); memcpy(pPktHeader->address2.octets, source, WLAN_MAC_ADDR_SIZE); // // set the bar control // should define the fields in a bit map // pPktHeader->barControl = 0x7ff00005; // // reserve a block in the shared memory // _LinkTxBarBuffer = MemoryLayout(_LinkTxBarBufferSize); if(_LinkTxBarBuffer==0) { UserPrint("createTransmitPacket: unable to allocate memory for BAR buffer\n"); return 0; } // // write the packet to physical memory // MyMemoryWrite(_LinkTxBarBuffer, pPkt, _LinkTxBarBufferSize); // UserPrint("bar = %x %d\n",_LinkTxBarBuffer,_LinkTxBarBufferSize); // for(it=0; it<_LinkTxBarBufferSize; it++) // { // UserPrint("02x ",pPkt[it]); // } // UserPrint("\n"); return _LinkTxBarBufferSize; }
int LinkTxParameterCheck(unsigned int rateMask, unsigned int rateMaskMcs20, unsigned int rateMaskMcs40, int ir, int numDescPerRate, int dataBodyLength, int broadcast, int ifs, unsigned int txchain, int naggregate) { // // remember some parameters for later use when we queue packets // TxChain=txchain; Broadcast=broadcast; PacketMany= numDescPerRate; // // adjust aggregate parameters to the range [1,MAGGREGATE] // if(naggregate<=1) { AggregateMany=1; AggregateBar=0; } else { AggregateMany=naggregate; if(AggregateMany>MAGGREGATE) { AggregateMany=MAGGREGATE; } // // determine if we should do special block acknowledgement request (BAR) packet // if(Broadcast) { AggregateBar=0; } else { AggregateBar=0; // never do this } // // treat the incoming number of packets as the total // but we treat it internally as the number of aggregate groups, so divide // if(PacketMany>0) { PacketMany/=AggregateMany; if(PacketMany<=0) { PacketMany=1; } } // // enforce maximun aggregate size of 64K // if(AggregateMany*dataBodyLength>65535) { AggregateMany=65535/dataBodyLength; UserPrint("reducing AggregateMany from %d to %d=65535/%d\n",naggregate,AggregateMany,dataBodyLength); } } // // Count rates and make the internal rate arrays. // RateMany = RateCount(rateMask, rateMaskMcs20, rateMaskMcs40, Rate); // // Remember other parameters, for descriptor queueing. // if(PacketMany>0) { InterleaveRate=ir; } else { InterleaveRate=1; } // // If the user asked for an infinite number of packets, set to a million // and force interleave rates on. // if(PacketMany<=0) { // PacketMany=1000000; InterleaveRate=1; } // // if in tx100 mode, we only do one packet at the first rate // if(ifs==0) { // // tx100 // RateMany=1; PacketMany=1; Broadcast=1; } else if(ifs>0) { // // tx99 // Broadcast=1; } else { // // regular // } return 0; }
int DescriptorLinkTxSetup(int *rate, int nrate, int ir, unsigned char *bssid, unsigned char *source, unsigned char *destination, int numDescPerRate, int dataBodyLength, int retries, int antenna, int broadcast, int ifs, int shortGi, unsigned int txchain, int naggregate, unsigned char *pattern, int npattern) { int it; unsigned int antMode = 0; int queueIndex; int dcuIndex; int wepEnable; static unsigned char bcast[]={0xff,0xff,0xff,0xff,0xff,0xff}; unsigned char *duse; unsigned char *ptr; DescriptorLinkRxOptions(); DescriptorLinkTxOptions(); TxStatusCheck(); DeviceTransmitDisable(0xffff); DeviceReceiveDisable(); TxStatusCheck(); // // do we still need these? // wepEnable=0; queueIndex=0; dcuIndex=0; // // Cleanup any descriptors and memory used in previous iteration // Make sure you do these first, since they actually destroy everything. // LinkTxLoopDestroy(); DescriptorLinkRxLoopDestroy(); // // remember some parameters for later use when we queue packets // TxChain=txchain; ShortGi=shortGi; Broadcast=broadcast; Retry=retries; PacketMany= numDescPerRate; // // adjust aggregate parameters to the range [1,MAGGREGATE] // if(naggregate<=1) { AggregateMany=1; AggregateBar=0; } else { AggregateMany=naggregate; if(AggregateMany>MAGGREGATE) { AggregateMany=MAGGREGATE; } // // determine if we should do special block acknowledgement request (BAR) packet // if(Broadcast) { AggregateBar=0; } else { AggregateBar=0; // never do this } // // treat the incoming number of packets as the total // but we treat it internally as the number of aggregate groups, so divide // if(PacketMany>0) { PacketMany/=AggregateMany; if(PacketMany<=0) { PacketMany=1; } } // // enforce maximun aggregate size of 64K // if(AggregateMany*dataBodyLength>65535) { AggregateMany=65535/dataBodyLength; UserPrint("reducing AggregateMany from %d to %d=65535/%d\n",naggregate,AggregateMany,dataBodyLength); } } // // Count rates and make the internal rate arrays. // RateMany = nrate; for(it=0; it<RateMany; it++) { Rate[it]=rate[it]; } //RateCount(rateMask, rateMaskMcs20, rateMaskMcs40, Rate); // // Remember other parameters, for descriptor queueing. // if(PacketMany>0) { InterleaveRate=ir; } else { InterleaveRate=1; } // // If the user asked for an infinite number of packets, set to a million // and force interleave rates on. // if(PacketMany<=0) { // PacketMany=1000000; LinkTxMany= -1; InterleaveRate=1; } // // if in tx100 mode, we only do one packet at the first rate // if(ifs==0) { // // tx100 // RateMany=1; PacketMany=1; Tx100Packet = 1; Broadcast=1; } else if(ifs>0) { // // tx99 // Tx100Packet = 0; Broadcast=1; } else { // // regular // Tx100Packet = 0; } // // If broadcast use the special broadcast address. otherwise, use the specified receiver // if(Broadcast) { duse=bcast; } else { duse=destination; } if(!Broadcast && !DeafMode) { // // Make rx descriptor // DescriptorLinkRxLoopCreate(MQUEUE); } // // calculate the total number of packets we expect to send. // and then figure out how many we should do in each batch. // if the number of packets is small, we may be able to do them in one batch. // if(PacketMany>0) { LinkTxMany=PacketMany*RateMany*(AggregateMany+AggregateBar); if(PacketMany>0 && LinkTxMany<=MQUEUE) { LinkTxBatchMany=LinkTxMany; // do in one batch LinkTxDescriptorMany=LinkTxMany; } else { LinkTxBatchMany=MQUEUE/2; // do in two or more batches LinkTxBatchMany/=(AggregateMany+AggregateBar); // force complete Aggregate into a batch LinkTxBatchMany*=(AggregateMany+AggregateBar); LinkTxDescriptorMany=2*LinkTxBatchMany; } } else { LinkTxBatchMany=MQUEUE/2; // do in two or more batches LinkTxBatchMany/=(AggregateMany+AggregateBar); // force complete Aggregate into a batch LinkTxBatchMany*=(AggregateMany+AggregateBar); LinkTxDescriptorMany=2*LinkTxBatchMany; } // // now calculate the number of tx responses we expect // // Merlin and before return a response for every queued descriptor but only // the terminating descriptor for an aggregate has the done bit set. Skip the others in LinkTxComplete(). // // Osprey only returns status for the terminating packet of aggregates, so there are // fewer status descriptors than control descriptors. // if(LinkTxAggregateStatus || AggregateMany<=1 || PacketMany<=0) { LinkTxStatusMany=LinkTxMany; } else { LinkTxStatusMany=0; for(it=0; it<RateMany; it++) { if(IS_LEGACY_RATE_INDEX(Rate[it])) { // // legacy rates don't support aggrgegates // LinkTxStatusMany+=(PacketMany*(AggregateMany+AggregateBar)); } else { // // only 1 status message is returned for aggregates // LinkTxStatusMany+=(PacketMany*(1+AggregateBar)); } } } UserPrint("TxMany=%d TxStatusMany=%d TxBatchMany=%d TxDescriptorMany=%d\n",LinkTxMany,LinkTxStatusMany,LinkTxBatchMany,LinkTxDescriptorMany); // // create the required number of descriptors // LinkTxLoopDescriptor[0] = MemoryLayout(LinkTxDescriptorMany * TxDescriptorSize()); if(LinkTxLoopDescriptor[0]==0) { UserPrint("txDataSetup: unable to allocate client memory for %d control descriptors\n",LinkTxDescriptorMany); return -1; } for(it=0; it<LinkTxDescriptorMany; it++) { LinkTxLoopDescriptor[it]=LinkTxLoopDescriptor[0]+it*TxDescriptorSize(); } // // make status descriptors // // for pre-Osprey chips, these pointers point to the regular tx descriptor // if(LinkTxStatusLoopCreate(LinkTxDescriptorMany)) { return -1; } // // use PN9 data if no pattern is specified // UserPrint("npattern=%d pattern=%x\n",npattern,pattern); if(npattern<=0) { pattern=PN9Data; npattern=sizeof(PN9Data); } UserPrint("npattern=%d pattern=%x\n",npattern,pattern); ptr=(unsigned char *)pattern; if(ptr!=0) { UserPrint("pattern: "); for(it=0; it<npattern; it++) { UserPrint("%2x ",ptr[it]); } UserPrint("\n"); } // // setup the transmit packets // if(AggregateMany>1) { for(it=0; it<AggregateMany; it++) { LinkTxAggregatePacketCreate(dataBodyLength, pattern, npattern, bssid, source, duse, Tx100Packet, wepEnable, it, AggregateBar); if(LinkTxLoopBuffer(it)==0) { UserPrint("txDataSetup: unable to allocate memory for packet %d\n",it); return -1; } } // // setup the BAR packet // if(AggregateBar>0) { LinkTxBarCreate(source, duse); if(LinkTxBarBuffer==0) { UserPrint("txDataSetup: unable to allocate memory for bar packet\n"); return -1; } } } else { LinkTxPacketCreate(dataBodyLength,pattern,npattern, bssid, source, duse, Tx100Packet,wepEnable); if(LinkTxLoopBuffer(0)==0) { UserPrint("txDataSetup: unable to allocate memory for packet\n"); return -1; } } DeviceTransmitRetryLimit(dcuIndex,retries); // // regular mode // if(ifs<0) { DeviceTransmitRegularData(); DeafMode=0; } // // tx99 mode // else if(ifs>0) { DeviceTransmitFrameData(ifs); DeafMode=1; } // // tx100 mode // else { DeviceTransmitContinuousData(); DeafMode=1; } //#ifdef BADBADBAD // i don't think this works DeviceReceiveDeafMode(DeafMode); //#endif DeviceBssIdSet(bssid); DeviceStationIdSet(source); // // make the first batch of transmit control descriptors, but don't queue them yet // LinkTxBatchNext(0,0); LinkTxBatchNext(LinkTxBatchMany,0); return 0; }
int NoiseFloorDo(int frequency, int *tnf, int tnfmany, int margin, int attempt, int timeout, int (*done)(), int *nfc, int *nfe, int nfmax) { int nf[2*MCHAIN][MATTEMPT],diff[2*MCHAIN],nfuse[2*MCHAIN],nfverify[2*MCHAIN]; int sort[MATTEMPT],esort[MATTEMPT]; int bad; int it; int ich; char buffer[MBUFFER]; char *cetext[2]={"c","e"}; SformatOutput(buffer,MBUFFER-1,"|nf|frequency|chain|minimum|maximum|median|used|delta|status|eminimum|emaximum|emedian|eused|edelta|estatus|"); ErrorPrint(NartDataHeader,buffer); // // try to calculate the noise floor // if(attempt>0 && margin>0) { bad=0; if(attempt<0 || attempt>MATTEMPT) { attempt=MATTEMPT; } for(it=0; it<attempt; it++) { UserPrint(" %d",it); for(ich=0; ich<2*MCHAIN; ich++) { nfuse[ich]= -50; } NoiseFloorLoadWait(nfuse,&nfuse[MCHAIN],MCHAIN,timeout); FieldWrite("BB_agc_control.enable_noisefloor",1); FieldWrite("BB_agc_control.no_update_noisefloor",1); FieldWrite("BB_agc_control.do_noisefloor",1); NoiseFloorFetchWait(nfuse,&nfuse[MCHAIN],MCHAIN,timeout); for(ich=0; ich<2*MCHAIN; ich++) { nf[ich][it]=nfuse[ich]; } } // // compute median // UserPrint("\n"); for(ich=0; ich<MCHAIN; ich++) { UserPrint("%d: ",ich); for(it=0; it<attempt; it++) { UserPrint("%5d",nf[ich][it]); } UserPrint("\n "); Sort(nf[ich],sort,attempt); for(it=0; it<attempt; it++) { UserPrint("%5d",nf[ich][sort[it]]); } nfuse[ich]=nf[ich][sort[attempt/2]]; UserPrint(" -> %5d",nfuse[ich]); // // compare to target // diff[ich]=nfuse[ich]-tnf[ich%tnfmany]; if(diff[ich]>margin) { UserPrint(" BAD , changing to %d\n",tnf[ich%tnfmany]+margin); nfuse[ich]=tnf[ich%tnfmany]+margin; bad++; } else if(diff[ich]< -margin) { UserPrint(" BAD , changing to %d\n",tnf[ich%tnfmany]-margin); nfuse[ich]=tnf[ich%tnfmany]-margin; bad++; } else { UserPrint(" GOOD \n"); } UserPrint("extension %d: ",ich); for(it=0; it<attempt; it++) { UserPrint("%5d",nf[ich+MCHAIN][it]); } UserPrint("\n "); Sort(nf[ich+MCHAIN],esort,attempt); for(it=0; it<attempt; it++) { UserPrint("%5d",nf[ich+MCHAIN][esort[it]]); } nfuse[ich+MCHAIN]=nf[ich+MCHAIN][esort[attempt/2]]; UserPrint(" -> %5d",nfuse[ich+MCHAIN]); // // compare to target // diff[ich+MCHAIN]=nfuse[ich+MCHAIN]-tnf[(ich+MCHAIN)%tnfmany]; if(diff[ich+MCHAIN]>margin) { UserPrint(" BAD , changing to %d\n",tnf[(ich+MCHAIN)%tnfmany]+margin); nfuse[ich+MCHAIN]=tnf[(ich+MCHAIN)%tnfmany]+margin; bad++; } else if(diff[ich+MCHAIN]< -margin) { UserPrint(" BAD , changing to %d\n",tnf[(ich+MCHAIN)%tnfmany]-margin); nfuse[ich+MCHAIN]=tnf[(ich+MCHAIN)%tnfmany]-margin; bad++; } else { UserPrint(" GOOD \n"); } SformatOutput(buffer,MBUFFER-1,"|nf|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|", frequency,ich%MCHAIN, nf[ich][sort[0]],nf[ich][sort[attempt-1]],nf[ich][sort[attempt/2]],nfuse[ich],diff[ich],diff[ich]>= -margin && diff[ich]<=margin, nf[ich+MCHAIN][esort[0]],nf[ich+MCHAIN][esort[attempt-1]],nf[ich+MCHAIN][esort[attempt/2]],nfuse[ich+MCHAIN],diff[ich+MCHAIN],diff[ich+MCHAIN]>= -margin && diff[ich+MCHAIN]<=margin); ErrorPrint(NartData,buffer); } } // // just load the user specified values // else { bad=0; for(ich=0; ich<MCHAIN; ich++) { nfuse[ich]=tnf[ich%tnfmany]; UserPrint("%d: %d",ich,nfuse[ich]); SformatOutput(buffer,MBUFFER-1,"|nf|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|", frequency,ich%MCHAIN, 0,0,0,nfuse[ich],0,0, 0,0,0,nfuse[ich+MCHAIN],0,0); ErrorPrint(NartData,buffer); } } NoiseFloorLoadWait(nfuse,&nfuse[MCHAIN],MCHAIN,timeout); NoiseFloorFetchWait(nfverify,&nfverify[MCHAIN],MCHAIN,timeout); for(ich=0; ich<MCHAIN; ich++) { if(nfuse[ich]!=nfverify[ich]) { UserPrint("NF load problem, ich=%d, %d != %d\n",ich,nfuse[ich],nfverify[ich]); } } for(it=0; it<nfmax; it++) { nfc[it]=nfuse[it]; nfe[it]=nfuse[MCHAIN+it]; } return -bad; }
/************************************************************************** * createTransmitPacket - create packet for transmission * */ int LinkTxPacketCreate( unsigned int dataBodyLength, unsigned char *dataPattern, unsigned int dataPatternLength, unsigned char *bssid, unsigned char *source, unsigned char *destination, int specialTx100Pkt, int wepEnable) { int it; unsigned char pPkt[MPACKET]; WLAN_DATA_MAC_HEADER3 *pPktHeader; unsigned char *pBody; int agg; agg=0; // // how big is the packet? // // 802.11 header (not for tx100) // IV (only if WEP enabled) // packet body // pPktHeader=(WLAN_DATA_MAC_HEADER3 *)pPkt; _LinkTxLoopBufferSize[agg] = dataBodyLength; pBody=pPkt; if(!specialTx100Pkt) { _LinkTxLoopBuffer[agg] += sizeof(WLAN_DATA_MAC_HEADER3); pBody += sizeof(WLAN_DATA_MAC_HEADER3); dataBodyLength-=sizeof(WLAN_DATA_MAC_HEADER); } #ifdef UNUSED if(wepEnable) { _LinkTxLoopBuffer[agg] += (WEP_IV_FIELD + 2); pBody += (WEP_IV_FIELD + 2); } #else wepEnable=0; #endif // // fill in the 802.11 packet header (including the IV field if wep enabled) // LinkTxPacketHeader(pPktHeader, wepEnable, bssid, source, destination, agg); // // fill in the packet body with the specified pattern // LinkTxPacketBody(pBody,dataBodyLength,dataPattern,dataPatternLength); // // reserve a block in the shared memory // _LinkTxLoopBuffer[agg] = MemoryLayout(_LinkTxLoopBufferSize[agg]); if(_LinkTxLoopBuffer[agg]==0) { UserPrint("createTransmitPacket: unable to allocate memory for transmit buffer\n"); return 0; } // // write the packet to physical memory // MyMemoryWrite(_LinkTxLoopBuffer[agg], (unsigned int *)pPkt, _LinkTxLoopBufferSize[agg]); // UserPrint("buffer[%d] = %x %d\n",agg,_LinkTxLoopBuffer[agg],_LinkTxLoopBufferSize[agg]); UserPrint("Packet: "); for(it=0; it<60; it++) { UserPrint("%2x ",pPkt[it]); } UserPrint("\n"); return _LinkTxLoopBufferSize[agg]; }