mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
fpga/common/tb: Rework driver model to better match C code
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
parent
ec1d7fe904
commit
d06fbaf178
@ -384,16 +384,23 @@ class Packet:
|
|||||||
|
|
||||||
|
|
||||||
class EqRing:
|
class EqRing:
|
||||||
def __init__(self, interface, size, stride, index, hw_regs):
|
def __init__(self, interface, index, hw_regs):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.log = interface.log
|
self.log = interface.log
|
||||||
self.driver = interface.driver
|
self.driver = interface.driver
|
||||||
self.log_size = size.bit_length() - 1
|
self.log_size = 0
|
||||||
self.size = 2**self.log_size
|
self.size = 0
|
||||||
self.size_mask = self.size-1
|
self.size_mask = 0
|
||||||
self.stride = stride
|
self.stride = 0
|
||||||
self.index = index
|
self.index = index
|
||||||
self.interrupt_index = 0
|
self.active = False
|
||||||
|
|
||||||
|
self.buf_size = 0
|
||||||
|
self.buf_region = None
|
||||||
|
self.buf_dma = 0
|
||||||
|
self.buf = None
|
||||||
|
|
||||||
|
self.irq = None
|
||||||
|
|
||||||
self.head_ptr = 0
|
self.head_ptr = 0
|
||||||
self.tail_ptr = 0
|
self.tail_ptr = 0
|
||||||
@ -404,11 +411,27 @@ class EqRing:
|
|||||||
async def init(self):
|
async def init(self):
|
||||||
self.log.info("Init EqRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Init EqRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
|
|
||||||
|
async def alloc(self, size, stride):
|
||||||
|
if self.active:
|
||||||
|
raise Exception("Cannot allocate active ring")
|
||||||
|
if self.buf:
|
||||||
|
raise Exception("Already allocated")
|
||||||
|
|
||||||
|
self.log_size = size.bit_length() - 1
|
||||||
|
self.size = 2**self.log_size
|
||||||
|
self.size_mask = self.size-1
|
||||||
|
self.stride = stride
|
||||||
|
|
||||||
self.buf_size = self.size*self.stride
|
self.buf_size = self.size*self.stride
|
||||||
self.buf_region = self.driver.pool.alloc_region(self.buf_size)
|
self.buf_region = self.driver.pool.alloc_region(self.buf_size)
|
||||||
self.buf_dma = self.buf_region.get_absolute_address(0)
|
self.buf_dma = self.buf_region.get_absolute_address(0)
|
||||||
self.buf = self.buf_region.mem
|
self.buf = self.buf_region.mem
|
||||||
|
|
||||||
|
self.head_ptr = 0
|
||||||
|
self.tail_ptr = 0
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
@ -417,20 +440,37 @@ class EqRing:
|
|||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
||||||
|
|
||||||
async def activate(self, int_index):
|
async def free(self):
|
||||||
|
await self.deactivate()
|
||||||
|
|
||||||
|
if self.buf:
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def activate(self, irq):
|
||||||
self.log.info("Activate EqRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Activate EqRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
self.interrupt_index = int_index
|
await self.deactivate()
|
||||||
|
|
||||||
|
self.irq = irq
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, int_index) # interrupt index
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, irq) # interrupt index
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_EVENT_QUEUE_ACTIVE_MASK) # active, log size
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_EVENT_QUEUE_ACTIVE_MASK) # active, log size
|
||||||
|
|
||||||
|
self.active = True
|
||||||
|
|
||||||
async def deactivate(self):
|
async def deactivate(self):
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index) # interrupt index
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, 0) # interrupt index
|
||||||
|
|
||||||
|
self.irq = None
|
||||||
|
|
||||||
|
self.active = False
|
||||||
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
return self.head_ptr == self.tail_ptr
|
return self.head_ptr == self.tail_ptr
|
||||||
@ -446,9 +486,12 @@ class EqRing:
|
|||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask)
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask)
|
||||||
|
|
||||||
async def arm(self):
|
async def arm(self):
|
||||||
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index | MQNIC_EVENT_QUEUE_ARM_MASK) # interrupt index
|
if not self.active:
|
||||||
|
return
|
||||||
|
|
||||||
async def process(self):
|
await self.hw_regs.write_dword(MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.irq | MQNIC_EVENT_QUEUE_ARM_MASK) # interrupt index
|
||||||
|
|
||||||
|
async def process_eq(self):
|
||||||
if not self.interface.port_up:
|
if not self.interface.port_up:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -469,12 +512,12 @@ class EqRing:
|
|||||||
if event_data[0] == 0:
|
if event_data[0] == 0:
|
||||||
# transmit completion
|
# transmit completion
|
||||||
cq = self.interface.tx_cpl_queues[event_data[1]]
|
cq = self.interface.tx_cpl_queues[event_data[1]]
|
||||||
await self.interface.process_tx_cq(cq)
|
await cq.handler(cq)
|
||||||
await cq.arm()
|
await cq.arm()
|
||||||
elif event_data[0] == 1:
|
elif event_data[0] == 1:
|
||||||
# receive completion
|
# receive completion
|
||||||
cq = self.interface.rx_cpl_queues[event_data[1]]
|
cq = self.interface.rx_cpl_queues[event_data[1]]
|
||||||
await self.interface.process_rx_cq(cq)
|
await cq.handler(cq)
|
||||||
await cq.arm()
|
await cq.arm()
|
||||||
|
|
||||||
eq_tail_ptr += 1
|
eq_tail_ptr += 1
|
||||||
@ -485,17 +528,26 @@ class EqRing:
|
|||||||
|
|
||||||
|
|
||||||
class CqRing:
|
class CqRing:
|
||||||
def __init__(self, interface, size, stride, index, hw_regs):
|
def __init__(self, interface, index, hw_regs):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.log = interface.log
|
self.log = interface.log
|
||||||
self.driver = interface.driver
|
self.driver = interface.driver
|
||||||
self.log_size = size.bit_length() - 1
|
self.log_size = 0
|
||||||
self.size = 2**self.log_size
|
self.size = 0
|
||||||
self.size_mask = self.size-1
|
self.size_mask = 0
|
||||||
self.stride = stride
|
self.stride = 0
|
||||||
self.index = index
|
self.index = index
|
||||||
self.interrupt_index = 0
|
self.active = False
|
||||||
self.ring_index = 0
|
|
||||||
|
self.buf_size = 0
|
||||||
|
self.buf_region = None
|
||||||
|
self.buf_dma = 0
|
||||||
|
self.buf = None
|
||||||
|
|
||||||
|
self.eq = None
|
||||||
|
|
||||||
|
self.src_ring = None
|
||||||
|
self.handler = None
|
||||||
|
|
||||||
self.head_ptr = 0
|
self.head_ptr = 0
|
||||||
self.tail_ptr = 0
|
self.tail_ptr = 0
|
||||||
@ -506,11 +558,27 @@ class CqRing:
|
|||||||
async def init(self):
|
async def init(self):
|
||||||
self.log.info("Init CqRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Init CqRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
|
|
||||||
|
async def alloc(self, size, stride):
|
||||||
|
if self.active:
|
||||||
|
raise Exception("Cannot allocate active ring")
|
||||||
|
if self.buf:
|
||||||
|
raise Exception("Already allocated")
|
||||||
|
|
||||||
|
self.log_size = size.bit_length() - 1
|
||||||
|
self.size = 2**self.log_size
|
||||||
|
self.size_mask = self.size-1
|
||||||
|
self.stride = stride
|
||||||
|
|
||||||
self.buf_size = self.size*self.stride
|
self.buf_size = self.size*self.stride
|
||||||
self.buf_region = self.driver.pool.alloc_region(self.buf_size)
|
self.buf_region = self.driver.pool.alloc_region(self.buf_size)
|
||||||
self.buf_dma = self.buf_region.get_absolute_address(0)
|
self.buf_dma = self.buf_region.get_absolute_address(0)
|
||||||
self.buf = self.buf_region.mem
|
self.buf = self.buf_region.mem
|
||||||
|
|
||||||
|
self.head_ptr = 0
|
||||||
|
self.tail_ptr = 0
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
@ -519,20 +587,37 @@ class CqRing:
|
|||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
||||||
|
|
||||||
async def activate(self, int_index):
|
async def free(self):
|
||||||
|
await self.deactivate()
|
||||||
|
|
||||||
|
if self.buf:
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def activate(self, eq):
|
||||||
self.log.info("Activate CqRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Activate CqRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
self.interrupt_index = int_index
|
await self.deactivate()
|
||||||
|
|
||||||
|
self.eq = eq
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, int_index) # event index
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, eq.index) # event index
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_CPL_QUEUE_ACTIVE_MASK) # active, log size
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_CPL_QUEUE_ACTIVE_MASK) # active, log size
|
||||||
|
|
||||||
|
self.active = True
|
||||||
|
|
||||||
async def deactivate(self):
|
async def deactivate(self):
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index) # event index
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, 0) # event index
|
||||||
|
|
||||||
|
self.eq = None
|
||||||
|
|
||||||
|
self.active = False
|
||||||
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
return self.head_ptr == self.tail_ptr
|
return self.head_ptr == self.tail_ptr
|
||||||
@ -548,23 +633,33 @@ class CqRing:
|
|||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask)
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask)
|
||||||
|
|
||||||
async def arm(self):
|
async def arm(self):
|
||||||
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index | MQNIC_CPL_QUEUE_ARM_MASK) # event index
|
if not self.active:
|
||||||
|
return
|
||||||
|
|
||||||
|
await self.hw_regs.write_dword(MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, self.eq.index | MQNIC_CPL_QUEUE_ARM_MASK) # event index
|
||||||
|
|
||||||
|
|
||||||
class TxRing:
|
class TxRing:
|
||||||
def __init__(self, interface, size, stride, index, hw_regs):
|
def __init__(self, interface, index, hw_regs):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.log = interface.log
|
self.log = interface.log
|
||||||
self.driver = interface.driver
|
self.driver = interface.driver
|
||||||
self.log_queue_size = size.bit_length() - 1
|
self.log_queue_size = 0
|
||||||
self.log_desc_block_size = int(stride/MQNIC_DESC_SIZE).bit_length() - 1
|
self.log_desc_block_size = 0
|
||||||
self.desc_block_size = 2**self.log_desc_block_size
|
self.desc_block_size = 0
|
||||||
self.size = 2**self.log_queue_size
|
self.size = 0
|
||||||
self.size_mask = self.size-1
|
self.size_mask = 0
|
||||||
self.full_size = self.size >> 1
|
self.full_size = 0
|
||||||
self.stride = stride
|
self.stride = 0
|
||||||
self.index = index
|
self.index = index
|
||||||
self.cpl_index = 0
|
self.active = False
|
||||||
|
|
||||||
|
self.buf_size = 0
|
||||||
|
self.buf_region = None
|
||||||
|
self.buf_dma = 0
|
||||||
|
self.buf = None
|
||||||
|
|
||||||
|
self.cq = None
|
||||||
|
|
||||||
self.head_ptr = 0
|
self.head_ptr = 0
|
||||||
self.tail_ptr = 0
|
self.tail_ptr = 0
|
||||||
@ -581,6 +676,22 @@ class TxRing:
|
|||||||
async def init(self):
|
async def init(self):
|
||||||
self.log.info("Init TxRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Init TxRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
|
|
||||||
|
async def alloc(self, size, stride):
|
||||||
|
if self.active:
|
||||||
|
raise Exception("Cannot allocate active ring")
|
||||||
|
if self.buf:
|
||||||
|
raise Exception("Already allocated")
|
||||||
|
|
||||||
|
self.log_queue_size = size.bit_length() - 1
|
||||||
|
self.log_desc_block_size = int(stride/MQNIC_DESC_SIZE).bit_length() - 1
|
||||||
|
self.desc_block_size = 2**self.log_desc_block_size
|
||||||
|
self.size = 2**self.log_queue_size
|
||||||
|
self.size_mask = self.size-1
|
||||||
|
self.full_size = self.size >> 1
|
||||||
|
self.stride = stride
|
||||||
|
|
||||||
self.tx_info = [None]*self.size
|
self.tx_info = [None]*self.size
|
||||||
|
|
||||||
self.buf_size = self.size*self.stride
|
self.buf_size = self.size*self.stride
|
||||||
@ -588,6 +699,9 @@ class TxRing:
|
|||||||
self.buf_dma = self.buf_region.get_absolute_address(0)
|
self.buf_dma = self.buf_region.get_absolute_address(0)
|
||||||
self.buf = self.buf_region.mem
|
self.buf = self.buf_region.mem
|
||||||
|
|
||||||
|
self.head_ptr = 0
|
||||||
|
self.tail_ptr = 0
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
@ -596,20 +710,43 @@ class TxRing:
|
|||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
||||||
|
|
||||||
async def activate(self, cpl_index):
|
async def free(self):
|
||||||
|
await self.deactivate()
|
||||||
|
|
||||||
|
if self.buf:
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def activate(self, cq):
|
||||||
self.log.info("Activate TxRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Activate TxRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
self.cpl_index = cpl_index
|
await self.deactivate()
|
||||||
|
|
||||||
|
self.cq = cq
|
||||||
|
self.cq.src_ring = self
|
||||||
|
self.cq.handler = TxRing.process_tx_cq
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cpl_index) # completion queue index
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cq.index) # completion queue index
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
await self.hw_regs.write_dword(MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size
|
||||||
|
|
||||||
|
self.active = True
|
||||||
|
|
||||||
async def deactivate(self):
|
async def deactivate(self):
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
||||||
|
|
||||||
|
if self.cq:
|
||||||
|
self.cq.src_ring = None
|
||||||
|
self.cq.handler = None
|
||||||
|
|
||||||
|
self.cq = None
|
||||||
|
|
||||||
|
self.active = False
|
||||||
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
return self.head_ptr == self.clean_tail_ptr
|
return self.head_ptr == self.clean_tail_ptr
|
||||||
|
|
||||||
@ -634,21 +771,78 @@ class TxRing:
|
|||||||
self.free_desc(index)
|
self.free_desc(index)
|
||||||
self.clean_tail_ptr += 1
|
self.clean_tail_ptr += 1
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def process_tx_cq(cq):
|
||||||
|
interface = cq.interface
|
||||||
|
|
||||||
|
interface.log.info("Process TX CQ %d for TX queue %d (interface %d)", cq.index, cq.src_ring.index, interface.index)
|
||||||
|
|
||||||
|
ring = cq.src_ring
|
||||||
|
|
||||||
|
if not interface.port_up:
|
||||||
|
return
|
||||||
|
|
||||||
|
# process completion queue
|
||||||
|
await cq.read_head_ptr()
|
||||||
|
|
||||||
|
cq_tail_ptr = cq.tail_ptr
|
||||||
|
cq_index = cq_tail_ptr & cq.size_mask
|
||||||
|
|
||||||
|
while (cq.head_ptr != cq_tail_ptr):
|
||||||
|
cpl_data = struct.unpack_from("<HHHxxQ", cq.buf, cq_index*cq.stride)
|
||||||
|
ring_index = cpl_data[1] & ring.size_mask
|
||||||
|
|
||||||
|
interface.log.info("CPL data: %s", cpl_data)
|
||||||
|
|
||||||
|
interface.log.info("Ring index: %d", ring_index)
|
||||||
|
|
||||||
|
ring.free_desc(ring_index)
|
||||||
|
|
||||||
|
cq_tail_ptr += 1
|
||||||
|
cq_index = cq_tail_ptr & cq.size_mask
|
||||||
|
|
||||||
|
cq.tail_ptr = cq_tail_ptr
|
||||||
|
await cq.write_tail_ptr()
|
||||||
|
|
||||||
|
# process ring
|
||||||
|
await ring.read_tail_ptr()
|
||||||
|
|
||||||
|
ring_clean_tail_ptr = ring.clean_tail_ptr
|
||||||
|
ring_index = ring_clean_tail_ptr & ring.size_mask
|
||||||
|
|
||||||
|
while (ring_clean_tail_ptr != ring.tail_ptr):
|
||||||
|
if ring.tx_info[ring_index]:
|
||||||
|
break
|
||||||
|
|
||||||
|
ring_clean_tail_ptr += 1
|
||||||
|
ring_index = ring_clean_tail_ptr & ring.size_mask
|
||||||
|
|
||||||
|
ring.clean_tail_ptr = ring_clean_tail_ptr
|
||||||
|
|
||||||
|
ring.clean_event.set()
|
||||||
|
|
||||||
|
|
||||||
class RxRing:
|
class RxRing:
|
||||||
def __init__(self, interface, size, stride, index, hw_regs):
|
def __init__(self, interface, index, hw_regs):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.log = interface.log
|
self.log = interface.log
|
||||||
self.driver = interface.driver
|
self.driver = interface.driver
|
||||||
self.log_queue_size = size.bit_length() - 1
|
self.log_queue_size = 0
|
||||||
self.log_desc_block_size = int(stride/MQNIC_DESC_SIZE).bit_length() - 1
|
self.log_desc_block_size = 0
|
||||||
self.desc_block_size = 2**self.log_desc_block_size
|
self.desc_block_size = 0
|
||||||
self.size = 2**self.log_queue_size
|
self.size = 0
|
||||||
self.size_mask = self.size-1
|
self.size_mask = 0
|
||||||
self.full_size = self.size >> 1
|
self.full_size = 0
|
||||||
self.stride = stride
|
self.stride = 0
|
||||||
self.index = index
|
self.index = index
|
||||||
self.cpl_index = 0
|
self.active = False
|
||||||
|
|
||||||
|
self.buf_size = 0
|
||||||
|
self.buf_region = None
|
||||||
|
self.buf_dma = 0
|
||||||
|
self.buf = None
|
||||||
|
|
||||||
|
self.cq = None
|
||||||
|
|
||||||
self.head_ptr = 0
|
self.head_ptr = 0
|
||||||
self.tail_ptr = 0
|
self.tail_ptr = 0
|
||||||
@ -663,6 +857,22 @@ class RxRing:
|
|||||||
async def init(self):
|
async def init(self):
|
||||||
self.log.info("Init RxRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Init RxRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
|
|
||||||
|
async def alloc(self, size, stride):
|
||||||
|
if self.active:
|
||||||
|
raise Exception("Cannot allocate active ring")
|
||||||
|
if self.buf:
|
||||||
|
raise Exception("Already allocated")
|
||||||
|
|
||||||
|
self.log_queue_size = size.bit_length() - 1
|
||||||
|
self.log_desc_block_size = int(stride/MQNIC_DESC_SIZE).bit_length() - 1
|
||||||
|
self.desc_block_size = 2**self.log_desc_block_size
|
||||||
|
self.size = 2**self.log_queue_size
|
||||||
|
self.size_mask = self.size-1
|
||||||
|
self.full_size = self.size >> 1
|
||||||
|
self.stride = stride
|
||||||
|
|
||||||
self.rx_info = [None]*self.size
|
self.rx_info = [None]*self.size
|
||||||
|
|
||||||
self.buf_size = self.size*self.stride
|
self.buf_size = self.size*self.stride
|
||||||
@ -670,6 +880,9 @@ class RxRing:
|
|||||||
self.buf_dma = self.buf_region.get_absolute_address(0)
|
self.buf_dma = self.buf_region.get_absolute_address(0)
|
||||||
self.buf = self.buf_region.mem
|
self.buf = self.buf_region.mem
|
||||||
|
|
||||||
|
self.head_ptr = 0
|
||||||
|
self.tail_ptr = 0
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
@ -678,22 +891,45 @@ class RxRing:
|
|||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
||||||
|
|
||||||
async def activate(self, cpl_index):
|
async def free(self):
|
||||||
|
await self.deactivate()
|
||||||
|
|
||||||
|
if self.buf:
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def activate(self, cq):
|
||||||
self.log.info("Activate RxRing %d (interface %d)", self.index, self.interface.index)
|
self.log.info("Activate RxRing %d (interface %d)", self.index, self.interface.index)
|
||||||
|
|
||||||
self.cpl_index = cpl_index
|
await self.deactivate()
|
||||||
|
|
||||||
|
self.cq = cq
|
||||||
|
self.cq.src_ring = self
|
||||||
|
self.cq.handler = RxRing.process_rx_cq
|
||||||
|
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cpl_index) # completion queue index
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address
|
||||||
|
await self.hw_regs.write_dword(MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cq.index) # completion queue index
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
await self.hw_regs.write_dword(MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
await self.hw_regs.write_dword(MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size
|
||||||
|
|
||||||
|
self.active = True
|
||||||
|
|
||||||
await self.refill_buffers()
|
await self.refill_buffers()
|
||||||
|
|
||||||
async def deactivate(self):
|
async def deactivate(self):
|
||||||
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
await self.hw_regs.write_dword(MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size
|
||||||
|
|
||||||
|
if self.cq:
|
||||||
|
self.cq.src_ring = None
|
||||||
|
self.cq.handler = None
|
||||||
|
|
||||||
|
self.cq = None
|
||||||
|
|
||||||
|
self.active = False
|
||||||
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
return self.head_ptr == self.clean_tail_ptr
|
return self.head_ptr == self.clean_tail_ptr
|
||||||
|
|
||||||
@ -744,6 +980,72 @@ class RxRing:
|
|||||||
|
|
||||||
await self.write_head_ptr()
|
await self.write_head_ptr()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def process_rx_cq(cq):
|
||||||
|
interface = cq.interface
|
||||||
|
|
||||||
|
interface.log.info("Process RX CQ %d for RX queue %d (interface %d)", cq.index, cq.src_ring.index, interface.index)
|
||||||
|
|
||||||
|
ring = cq.src_ring
|
||||||
|
|
||||||
|
if not interface.port_up:
|
||||||
|
return
|
||||||
|
|
||||||
|
# process completion queue
|
||||||
|
await cq.read_head_ptr()
|
||||||
|
|
||||||
|
cq_tail_ptr = cq.tail_ptr
|
||||||
|
cq_index = cq_tail_ptr & cq.size_mask
|
||||||
|
|
||||||
|
while (cq.head_ptr != cq_tail_ptr):
|
||||||
|
cpl_data = struct.unpack_from("<HHHxxLHH", cq.buf, cq_index*cq.stride)
|
||||||
|
ring_index = cpl_data[1] & ring.size_mask
|
||||||
|
|
||||||
|
interface.log.info("CPL data: %s", cpl_data)
|
||||||
|
|
||||||
|
interface.log.info("Ring index: %d", ring_index)
|
||||||
|
pkt = ring.rx_info[ring_index]
|
||||||
|
|
||||||
|
length = cpl_data[2]
|
||||||
|
|
||||||
|
skb = Packet()
|
||||||
|
skb.data = pkt[:length]
|
||||||
|
skb.queue = ring.index
|
||||||
|
skb.timestamp_ns = cpl_data[3]
|
||||||
|
skb.timestamp_s = cpl_data[4]
|
||||||
|
skb.rx_checksum = cpl_data[5]
|
||||||
|
|
||||||
|
interface.log.info("Packet: %s", skb)
|
||||||
|
|
||||||
|
interface.pkt_rx_queue.append(skb)
|
||||||
|
interface.pkt_rx_sync.set()
|
||||||
|
|
||||||
|
ring.free_desc(ring_index)
|
||||||
|
|
||||||
|
cq_tail_ptr += 1
|
||||||
|
cq_index = cq_tail_ptr & cq.size_mask
|
||||||
|
|
||||||
|
cq.tail_ptr = cq_tail_ptr
|
||||||
|
await cq.write_tail_ptr()
|
||||||
|
|
||||||
|
# process ring
|
||||||
|
await ring.read_tail_ptr()
|
||||||
|
|
||||||
|
ring_clean_tail_ptr = ring.clean_tail_ptr
|
||||||
|
ring_index = ring_clean_tail_ptr & ring.size_mask
|
||||||
|
|
||||||
|
while (ring_clean_tail_ptr != ring.tail_ptr):
|
||||||
|
if ring.rx_info[ring_index]:
|
||||||
|
break
|
||||||
|
|
||||||
|
ring_clean_tail_ptr += 1
|
||||||
|
ring_index = ring_clean_tail_ptr & ring.size_mask
|
||||||
|
|
||||||
|
ring.clean_tail_ptr = ring_clean_tail_ptr
|
||||||
|
|
||||||
|
# replenish buffers
|
||||||
|
await ring.refill_buffers()
|
||||||
|
|
||||||
|
|
||||||
class BaseScheduler:
|
class BaseScheduler:
|
||||||
def __init__(self, port, index, rb):
|
def __init__(self, port, index, rb):
|
||||||
@ -1005,34 +1307,29 @@ class Interface:
|
|||||||
self.sched_blocks = []
|
self.sched_blocks = []
|
||||||
|
|
||||||
for k in range(self.event_queue_count):
|
for k in range(self.event_queue_count):
|
||||||
q = EqRing(self, 1024, MQNIC_EVENT_SIZE, self.index,
|
eq = EqRing(self, k, self.hw_regs.create_window(self.event_queue_offset + k*self.event_queue_stride, self.event_queue_stride))
|
||||||
self.hw_regs.create_window(self.event_queue_offset + k*self.event_queue_stride, self.event_queue_stride))
|
await eq.init()
|
||||||
await q.init()
|
self.event_queues.append(eq)
|
||||||
self.event_queues.append(q)
|
|
||||||
|
|
||||||
for k in range(self.tx_queue_count):
|
for k in range(self.tx_queue_count):
|
||||||
q = TxRing(self, 1024, MQNIC_DESC_SIZE*4, k,
|
txq = TxRing(self, k, self.hw_regs.create_window(self.tx_queue_offset + k*self.tx_queue_stride, self.tx_queue_stride))
|
||||||
self.hw_regs.create_window(self.tx_queue_offset + k*self.tx_queue_stride, self.tx_queue_stride))
|
await txq.init()
|
||||||
await q.init()
|
self.tx_queues.append(txq)
|
||||||
self.tx_queues.append(q)
|
|
||||||
|
|
||||||
for k in range(self.tx_cpl_queue_count):
|
for k in range(self.tx_cpl_queue_count):
|
||||||
q = CqRing(self, 1024, MQNIC_CPL_SIZE, k,
|
cq = CqRing(self, k, self.hw_regs.create_window(self.tx_cpl_queue_offset + k*self.tx_cpl_queue_stride, self.tx_cpl_queue_stride))
|
||||||
self.hw_regs.create_window(self.tx_cpl_queue_offset + k*self.tx_cpl_queue_stride, self.tx_cpl_queue_stride))
|
await cq.init()
|
||||||
await q.init()
|
self.tx_cpl_queues.append(cq)
|
||||||
self.tx_cpl_queues.append(q)
|
|
||||||
|
|
||||||
for k in range(self.rx_queue_count):
|
for k in range(self.rx_queue_count):
|
||||||
q = RxRing(self, 1024, MQNIC_DESC_SIZE*4, k,
|
rxq = RxRing(self, k, self.hw_regs.create_window(self.rx_queue_offset + k*self.rx_queue_stride, self.rx_queue_stride))
|
||||||
self.hw_regs.create_window(self.rx_queue_offset + k*self.rx_queue_stride, self.rx_queue_stride))
|
await rxq.init()
|
||||||
await q.init()
|
self.rx_queues.append(rxq)
|
||||||
self.rx_queues.append(q)
|
|
||||||
|
|
||||||
for k in range(self.rx_cpl_queue_count):
|
for k in range(self.rx_cpl_queue_count):
|
||||||
q = CqRing(self, 1024, MQNIC_CPL_SIZE, k,
|
cq = CqRing(self, k, self.hw_regs.create_window(self.rx_cpl_queue_offset + k*self.rx_cpl_queue_stride, self.rx_cpl_queue_stride))
|
||||||
self.hw_regs.create_window(self.rx_cpl_queue_offset + k*self.rx_cpl_queue_stride, self.rx_cpl_queue_stride))
|
await cq.init()
|
||||||
await q.init()
|
self.rx_cpl_queues.append(cq)
|
||||||
self.rx_cpl_queues.append(q)
|
|
||||||
|
|
||||||
for k in range(self.port_count):
|
for k in range(self.port_count):
|
||||||
rb = self.reg_blocks.find(MQNIC_RB_PORT_TYPE, MQNIC_RB_PORT_VER, index=k)
|
rb = self.reg_blocks.find(MQNIC_RB_PORT_TYPE, MQNIC_RB_PORT_VER, index=k)
|
||||||
@ -1050,32 +1347,30 @@ class Interface:
|
|||||||
|
|
||||||
assert self.sched_block_count == len(self.sched_blocks)
|
assert self.sched_block_count == len(self.sched_blocks)
|
||||||
|
|
||||||
|
for eq in self.event_queues:
|
||||||
|
await eq.alloc(1024, MQNIC_EVENT_SIZE)
|
||||||
|
await eq.activate(self.index) # TODO?
|
||||||
|
await eq.arm()
|
||||||
|
|
||||||
# wait for all writes to complete
|
# wait for all writes to complete
|
||||||
await self.hw_regs.read_dword(0)
|
await self.hw_regs.read_dword(0)
|
||||||
|
|
||||||
async def open(self):
|
async def open(self):
|
||||||
for q in self.event_queues:
|
for rxq in self.rx_queues:
|
||||||
await q.activate(self.index) # TODO?
|
cq = self.rx_cpl_queues[rxq.index]
|
||||||
q.handler = None # TODO
|
await cq.alloc(1024, MQNIC_CPL_SIZE)
|
||||||
await q.arm()
|
await cq.activate(self.event_queues[cq.index % self.event_queue_count])
|
||||||
|
await cq.arm()
|
||||||
|
await rxq.alloc(1024, MQNIC_DESC_SIZE*4)
|
||||||
|
await rxq.activate(cq)
|
||||||
|
|
||||||
for q in self.rx_cpl_queues:
|
for txq in self.tx_queues:
|
||||||
await q.activate(q.index % self.event_queue_count)
|
cq = self.tx_cpl_queues[txq.index]
|
||||||
q.ring_index = q.index
|
await cq.alloc(1024, MQNIC_CPL_SIZE)
|
||||||
q.handler = None # TODO
|
await cq.activate(self.event_queues[cq.index % self.event_queue_count])
|
||||||
await q.arm()
|
await cq.arm()
|
||||||
|
await txq.alloc(1024, MQNIC_DESC_SIZE*4)
|
||||||
for q in self.rx_queues:
|
await txq.activate(cq)
|
||||||
await q.activate(q.index)
|
|
||||||
|
|
||||||
for q in self.tx_cpl_queues:
|
|
||||||
await q.activate(q.index % self.event_queue_count)
|
|
||||||
q.ring_index = q.index
|
|
||||||
q.handler = None # TODO
|
|
||||||
await q.arm()
|
|
||||||
|
|
||||||
for q in self.tx_queues:
|
|
||||||
await q.activate(q.index)
|
|
||||||
|
|
||||||
# wait for all writes to complete
|
# wait for all writes to complete
|
||||||
await self.hw_regs.read_dword(0)
|
await self.hw_regs.read_dword(0)
|
||||||
@ -1085,20 +1380,13 @@ class Interface:
|
|||||||
async def close(self):
|
async def close(self):
|
||||||
self.port_up = False
|
self.port_up = False
|
||||||
|
|
||||||
for q in self.tx_queues:
|
for txq in self.tx_queues:
|
||||||
await q.deactivate()
|
await txq.deactivate()
|
||||||
|
await txq.cq.deactivate()
|
||||||
|
|
||||||
for q in self.tx_cpl_queues:
|
for rxq in self.rx_queues:
|
||||||
await q.deactivate()
|
await rxq.deactivate()
|
||||||
|
await rxq.cq.deactivate()
|
||||||
for q in self.rx_queues:
|
|
||||||
await q.deactivate()
|
|
||||||
|
|
||||||
for q in self.rx_cpl_queues:
|
|
||||||
await q.deactivate()
|
|
||||||
|
|
||||||
for q in self.event_queues:
|
|
||||||
await q.deactivate()
|
|
||||||
|
|
||||||
# wait for all writes to complete
|
# wait for all writes to complete
|
||||||
await self.hw_regs.read_dword(0)
|
await self.hw_regs.read_dword(0)
|
||||||
@ -1109,116 +1397,6 @@ class Interface:
|
|||||||
for q in self.rx_queues:
|
for q in self.rx_queues:
|
||||||
await q.free_buf()
|
await q.free_buf()
|
||||||
|
|
||||||
async def process_tx_cq(self, cq_ring):
|
|
||||||
self.log.info("Process TX CQ %d (interface %d)", cq_ring.ring_index, self.index)
|
|
||||||
|
|
||||||
ring = self.tx_queues[cq_ring.ring_index]
|
|
||||||
|
|
||||||
if not self.port_up:
|
|
||||||
return
|
|
||||||
|
|
||||||
# process completion queue
|
|
||||||
await cq_ring.read_head_ptr()
|
|
||||||
|
|
||||||
cq_tail_ptr = cq_ring.tail_ptr
|
|
||||||
cq_index = cq_tail_ptr & cq_ring.size_mask
|
|
||||||
|
|
||||||
while (cq_ring.head_ptr != cq_tail_ptr):
|
|
||||||
cpl_data = struct.unpack_from("<HHHxxQ", cq_ring.buf, cq_index*cq_ring.stride)
|
|
||||||
ring_index = cpl_data[1] & ring.size_mask
|
|
||||||
|
|
||||||
self.log.info("CPL data: %s", cpl_data)
|
|
||||||
|
|
||||||
self.log.info("Ring index: %d", ring_index)
|
|
||||||
|
|
||||||
ring.free_desc(ring_index)
|
|
||||||
|
|
||||||
cq_tail_ptr += 1
|
|
||||||
cq_index = cq_tail_ptr & cq_ring.size_mask
|
|
||||||
|
|
||||||
cq_ring.tail_ptr = cq_tail_ptr
|
|
||||||
await cq_ring.write_tail_ptr()
|
|
||||||
|
|
||||||
# process ring
|
|
||||||
await ring.read_tail_ptr()
|
|
||||||
|
|
||||||
ring_clean_tail_ptr = ring.clean_tail_ptr
|
|
||||||
ring_index = ring_clean_tail_ptr & ring.size_mask
|
|
||||||
|
|
||||||
while (ring_clean_tail_ptr != ring.tail_ptr):
|
|
||||||
if ring.tx_info[ring_index]:
|
|
||||||
break
|
|
||||||
|
|
||||||
ring_clean_tail_ptr += 1
|
|
||||||
ring_index = ring_clean_tail_ptr & ring.size_mask
|
|
||||||
|
|
||||||
ring.clean_tail_ptr = ring_clean_tail_ptr
|
|
||||||
|
|
||||||
ring.clean_event.set()
|
|
||||||
|
|
||||||
async def process_rx_cq(self, cq_ring):
|
|
||||||
self.log.info("Process RX CQ %d (interface %d)", cq_ring.ring_index, self.index)
|
|
||||||
|
|
||||||
ring = self.rx_queues[cq_ring.ring_index]
|
|
||||||
|
|
||||||
if not self.port_up:
|
|
||||||
return
|
|
||||||
|
|
||||||
# process completion queue
|
|
||||||
await cq_ring.read_head_ptr()
|
|
||||||
|
|
||||||
cq_tail_ptr = cq_ring.tail_ptr
|
|
||||||
cq_index = cq_tail_ptr & cq_ring.size_mask
|
|
||||||
|
|
||||||
while (cq_ring.head_ptr != cq_tail_ptr):
|
|
||||||
cpl_data = struct.unpack_from("<HHHxxLHH", cq_ring.buf, cq_index*cq_ring.stride)
|
|
||||||
ring_index = cpl_data[1] & ring.size_mask
|
|
||||||
|
|
||||||
self.log.info("CPL data: %s", cpl_data)
|
|
||||||
|
|
||||||
self.log.info("Ring index: %d", ring_index)
|
|
||||||
pkt = ring.rx_info[ring_index]
|
|
||||||
|
|
||||||
length = cpl_data[2]
|
|
||||||
|
|
||||||
skb = Packet()
|
|
||||||
skb.data = pkt[:length]
|
|
||||||
skb.queue = ring.index
|
|
||||||
skb.timestamp_ns = cpl_data[3]
|
|
||||||
skb.timestamp_s = cpl_data[4]
|
|
||||||
skb.rx_checksum = cpl_data[5]
|
|
||||||
|
|
||||||
self.log.info("Packet: %s", skb)
|
|
||||||
|
|
||||||
self.pkt_rx_queue.append(skb)
|
|
||||||
self.pkt_rx_sync.set()
|
|
||||||
|
|
||||||
ring.free_desc(ring_index)
|
|
||||||
|
|
||||||
cq_tail_ptr += 1
|
|
||||||
cq_index = cq_tail_ptr & cq_ring.size_mask
|
|
||||||
|
|
||||||
cq_ring.tail_ptr = cq_tail_ptr
|
|
||||||
await cq_ring.write_tail_ptr()
|
|
||||||
|
|
||||||
# process ring
|
|
||||||
await ring.read_tail_ptr()
|
|
||||||
|
|
||||||
ring_clean_tail_ptr = ring.clean_tail_ptr
|
|
||||||
ring_index = ring_clean_tail_ptr & ring.size_mask
|
|
||||||
|
|
||||||
while (ring_clean_tail_ptr != ring.tail_ptr):
|
|
||||||
if ring.rx_info[ring_index]:
|
|
||||||
break
|
|
||||||
|
|
||||||
ring_clean_tail_ptr += 1
|
|
||||||
ring_index = ring_clean_tail_ptr & ring.size_mask
|
|
||||||
|
|
||||||
ring.clean_tail_ptr = ring_clean_tail_ptr
|
|
||||||
|
|
||||||
# replenish buffers
|
|
||||||
await ring.refill_buffers()
|
|
||||||
|
|
||||||
async def start_xmit(self, skb, tx_ring=None, csum_start=None, csum_offset=None):
|
async def start_xmit(self, skb, tx_ring=None, csum_start=None, csum_offset=None):
|
||||||
if not self.port_up:
|
if not self.port_up:
|
||||||
return
|
return
|
||||||
@ -1514,8 +1692,8 @@ class Driver:
|
|||||||
self.log.info("Interrupt handler start (IRQ %d)", index)
|
self.log.info("Interrupt handler start (IRQ %d)", index)
|
||||||
for i in self.interfaces:
|
for i in self.interfaces:
|
||||||
for eq in i.event_queues:
|
for eq in i.event_queues:
|
||||||
if eq.interrupt_index == index:
|
if eq.irq == index:
|
||||||
await eq.process()
|
await eq.process_eq()
|
||||||
await eq.arm()
|
await eq.arm()
|
||||||
self.log.info("Interrupt handler end (IRQ %d)", index)
|
self.log.info("Interrupt handler end (IRQ %d)", index)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user