// // 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; }
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 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; }
// // 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; }
/************************************************************************** * 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]; }