void LinkRxSetup(unsigned char *bssid, unsigned char *macaddr) { DeviceReceiveDisable(); // // cleanup descriptors created last time // LinkRxLoopDestroy(0); /* * create a few descriptors linked in a loop */ LinkRxLoopCreate(MQUEUE); #ifdef UNUSED this should always be turned on ar5kInitData[pLibDev->ar5kInitIndex].pMacAPI->setPPM(0, enablePPM); pLibDev->rx.rxEnable = 1; #endif DeviceStationIdSet(macaddr); DeviceBssIdSet(bssid); DeviceReceiveDeafMode(0); return; }
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; }