10#include "request_ixl.h"
12#include <l4/ixl/device.h>
13#include <l4/ixl/memory.h>
22class Ixl_port :
public Port_iface
25 static constexpr unsigned Tx_batch_size = 32;
26 static constexpr unsigned Num_bufs = 1024;
27 static constexpr unsigned Buf_size = 2048;
28 static constexpr l4_uint64_t Max_mem_size = 1ULL << 28;
30 Ixl_port(Ixl::Ixl_device *dev)
31 : Port_iface(dev->get_driver_name().c_str()),
33 _mempool(*_dev, Num_bufs, Buf_size, Max_mem_size)
35 Ixl::mac_address mac_addr = _dev->get_mac_addr();
36 _mac =
Mac_addr(
reinterpret_cast<char const *
>(mac_addr.addr));
38 _mac.to_array(_stats->mac);
45 void rx_notify_disable_and_remember()
override {}
46 void rx_notify_emit_and_enable()
override {}
47 bool is_gone()
const override {
return false; }
50 bool tx_work_pending()
53 return _tx_batch_idx < _tx_batch_len;
57 std::optional<Ixl_net_request> get_tx_request()
60 if (_tx_batch_idx < _tx_batch_len)
61 return std::make_optional<Ixl_net_request>(_tx_batch[_tx_batch_idx++]);
66 Result handle_request(Port_iface *src_port,
Net_transfer &src,
71 Dbg trace(Dbg::Request, Dbg::Trace,
"REQ-IXL");
72 trace.printf(
"%s: Transfer request %p.\n", _name, src.
req_id());
74 struct Ixl::pkt_buf *buf = _mempool.pkt_buf_alloc();
77 trace.printf(
"\tTransfer failed, out-of-memory, dropping.\n");
78 return Result::Dropped;
86 Buffer dst_buf(
reinterpret_cast<char *
>(buf->data),
87 Buf_size - offsetof(Ixl::pkt_buf, data));
88 unsigned max_size = Buf_size - offsetof(Ixl::pkt_buf, data);
99 trace.printf(
"\tTransfer failed, bad descriptor exception, dropping.\n");
102 Ixl::pkt_buf_free(buf);
109 "\tTransfer failed, exceeds max packet-size, dropping.\n");
110 Ixl::pkt_buf_free(buf);
111 return Result::Dropped;
115 trace.printf(
"\tCopying %p#%p:%u (%x) -> %p#%p:%u (%x)\n",
116 src_port, src_buf.pos, src_buf.left, src_buf.left,
117 static_cast<Port_iface *
>(
this),
118 dst_buf.pos, dst_buf.left, dst_buf.left);
122 buf->size = max_size - dst_buf.left;
123 *bytes_transferred = buf->size;
126 if (_dev->tx_batch(0, &buf, 1) == 1)
128 trace.printf(
"\tTransfer queued at device.\n");
129 return Result::Delivered;
133 trace.printf(
"\tTransfer failed, dropping.\n");
134 Ixl::pkt_buf_free(buf);
135 return Result::Dropped;
139 Ixl::Ixl_device *dev() {
return _dev; }
142 void fetch_tx_requests()
144 if (_tx_batch_idx < _tx_batch_len)
150 _tx_batch_len = _dev->rx_batch(0, _tx_batch, Tx_batch_size);
154 Ixl::Ixl_device *_dev;
155 Ixl::Mempool _mempool;
156 Ixl::pkt_buf *_tx_batch[Tx_batch_size];
157 unsigned _tx_batch_idx = 0;
158 unsigned _tx_batch_len = 0;
A wrapper class around the value of a MAC address.
A network request to only a single destination.
void const * req_id() const
Identifier for the underlying Net_request, used for logging purposes.
virtual bool done()=0
Check whether the transfer has been completed, i.e.
Buffer & cur_buf()
Buffer containing (a part of) the packet data.
Class for VLAN packet rewriting.
l4_uint32_t copy_pkt(Buffer &dst, Buffer &src)
Copy packet from src to dst.
unsigned long long l4_uint64_t
Unsigned 64bit value.
Data buffer used to transfer packets.
Exception used by Queue to indicate descriptor errors.