private void StartRxQueue(int queueId) { Log.Notice("Starting RX queue {0}", queueId); var queue = (IxgbeRxQueue)RxQueues[queueId]; //Mempool should be >= number of rx and tx descriptors uint mempoolSize = NumRxQueueEntries + NumTxQueueEntries; queue.Mempool = MemoryHelper.AllocateMempool(mempoolSize < 4096 ? 4096 : mempoolSize, 2048); if ((queue.EntriesCount & (queue.EntriesCount - 1)) != 0) { Log.Error("FATAL: number of queue entries must be a power of 2"); Environment.Exit(1); } for (ushort ei = 0; ei < queue.EntriesCount; ei++) { var descrAddr = queue.GetDescriptorAddress(ei); Log.Notice("Setting up descriptor at index #{0}", ei); //Allocate packet buffer var packetBuffer = queue.Mempool.GetPacketBufferFast(); if (packetBuffer.IsNull) { Log.Error("Fatal: Could not allocate packet buffer"); Environment.Exit(1); } queue.WriteBufferAddress(descrAddr, packetBuffer.PhysicalAddress + PacketBuffer.DataOffset); queue.WriteHeaderBufferAddress(descrAddr, 0); queue.VirtualAddresses[ei] = packetBuffer.VirtualAddress; } //Enable queue and wait if necessary SetFlags(IxgbeDefs.RXDCTL((uint)queueId), IxgbeDefs.RXDCTL_ENABLE); WaitSetReg(IxgbeDefs.RXDCTL((uint)queueId), IxgbeDefs.RXDCTL_ENABLE); //Rx queue starts out full SetReg(IxgbeDefs.RDH((uint)queueId), 0); //Was set to 0 before in the init function SetReg(IxgbeDefs.RDT((uint)queueId), (uint)(queue.EntriesCount - 1)); }
private void InitMempool() { _mempool = MemoryHelper.AllocateMempool(BuffersCount); //Pre-fill all our packet buffers with some templates that can be modified later var buffers = new PacketBuffer[BuffersCount]; for (int i = 0; i < BuffersCount; i++) { var buffer = _mempool.GetPacketBuffer(); buffer.Size = (uint)PacketData.Length; buffer.WriteData(0, PacketData); var ipData = buffer.CopyData(14, 20); buffer.WriteData(24, (short)CalcIpChecksum(ipData)); buffers[i] = buffer; } //Return them all to the mempool, all future allocations will return buffers with the data set above foreach (var buffer in buffers) { _mempool.FreeBuffer(buffer); } }