def post_send(self): """ Posts one send WQE to the SQ by doing all the required work such as building the control/data segments, updating and ringing the dbr, updating the producer indexes, etc. """ idx = self.qattr.sq.post_idx if self.qattr.sq.post_idx < self.qattr.sq.wqe_num else 0 buf_offset = self.qattr.sq.offset + (idx << dve.MLX5_SEND_WQE_SHIFT) # Prepare WQE imm_be32 = struct.unpack( "<I", struct.pack(">I", self.imm + self.qattr.sq.post_idx))[0] ctrl_seg = WqeCtrlSeg(imm=imm_be32, fm_ce_se=dve.MLX5_WQE_CTRL_CQ_UPDATE) data_seg = WqeDataSeg(self.mr.length, self.mr.lkey, self.mr.buf) ctrl_seg.opmod_idx_opcode = (self.qattr.sq.post_idx & 0xffff) << 8 | dve.MLX5_OPCODE_SEND_IMM size_in_octowords = int((ctrl_seg.sizeof() + data_seg.sizeof()) / 16) ctrl_seg.qpn_ds = self.qpn << 8 | size_in_octowords Wqe([ctrl_seg, data_seg], self.umems['qp'].umem_addr + buf_offset) self.qattr.sq.post_idx += int( (size_in_octowords * 16 + dve.MLX5_SEND_WQE_BB - 1) / dve.MLX5_SEND_WQE_BB) # Make sure descriptors are written dma.udma_to_dev_barrier() # Update the doorbell record mem.writebe32(self.umems['qp_dbr'].umem_addr, self.qattr.sq.post_idx & 0xffff, dve.MLX5_SND_DBR) dma.udma_to_dev_barrier() # Ring the doorbell and post the WQE dma.mmio_write64_as_be(self.uar['qp'].reg_addr, mem.read64(ctrl_seg.addr))
def init_dveq_buff(self): from tests.mlx5_prm_structs import SwEqe for i in range(self.nent): eqe_bytes = mem.read64(self.eq.vaddr + i * len(SwEqe())) eqe_bytes = eqe_bytes.to_bytes(length=8, byteorder='little') eqe = SwEqe(eqe_bytes) eqe.owner = 0x1 self.update_ci(0)
def get_eqe(self, cc): from tests.mlx5_prm_structs import SwEqe ci = self.cons_index + cc entry = ci & (self.nent - 1) eqe_bytes = mem.read64(self.eq.vaddr + entry * len(SwEqe())) eqe_bytes = eqe_bytes.to_bytes(length=8, byteorder='little') eqe = SwEqe(eqe_bytes) if (eqe.owner & 1) ^ (not(not(ci & self.nent))): eqe = None elif eqe: dma.udma_from_dev_barrier() return eqe