Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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];
}