72 public L4virtio::Svr::Device,
79 CXX_BITFIELD_MEMBER( 0, 0, need_csum, raw);
80 CXX_BITFIELD_MEMBER( 1, 1, data_valid, raw);
94 struct Features : L4virtio::Svr::Dev_config::Features
99 CXX_BITFIELD_MEMBER( 0, 0, csum,
raw);
100 CXX_BITFIELD_MEMBER( 1, 1, guest_csum,
raw);
101 CXX_BITFIELD_MEMBER( 5, 5, mac,
raw);
102 CXX_BITFIELD_MEMBER( 6, 6, gso,
raw);
103 CXX_BITFIELD_MEMBER( 7, 7, guest_tso4,
raw);
104 CXX_BITFIELD_MEMBER( 8, 8, guest_tso6,
raw);
105 CXX_BITFIELD_MEMBER( 9, 9, guest_ecn,
raw);
106 CXX_BITFIELD_MEMBER(10, 10, guest_ufo,
raw);
107 CXX_BITFIELD_MEMBER(11, 11, host_tso4,
raw);
108 CXX_BITFIELD_MEMBER(12, 12, host_tso6,
raw);
109 CXX_BITFIELD_MEMBER(13, 13, host_ecn,
raw);
110 CXX_BITFIELD_MEMBER(14, 14, host_ufo,
raw);
111 CXX_BITFIELD_MEMBER(15, 15, mrg_rxbuf,
raw);
112 CXX_BITFIELD_MEMBER(16, 16, status,
raw);
113 CXX_BITFIELD_MEMBER(17, 17, ctrl_vq,
raw);
114 CXX_BITFIELD_MEMBER(18, 18, ctrl_rx,
raw);
115 CXX_BITFIELD_MEMBER(19, 19, ctrl_vlan,
raw);
116 CXX_BITFIELD_MEMBER(20, 20, ctrl_rx_extra,
raw);
117 CXX_BITFIELD_MEMBER(21, 21, guest_announce,
raw);
118 CXX_BITFIELD_MEMBER(22, 22, mq,
raw);
119 CXX_BITFIELD_MEMBER(23, 23, ctrl_mac_addr,
raw);
128 struct Net_config_space
137 L4virtio::Svr::Dev_config_t<Net_config_space> _dev_config;
139 explicit Virtio_net(
unsigned vq_max)
140 : L4virtio::Svr::Device(&_dev_config,
141 Dbg{Dbg::Virtio, Dbg::Warn},
142 Dbg{Dbg::Virtio, Dbg::Debug}),
148 hf.mrg_rxbuf() =
true;
153 hf.host_tso4() =
true;
154 hf.host_tso6() =
true;
155 hf.host_ufo() =
true;
156 hf.host_ecn() =
true;
158 hf.guest_csum() =
true;
159 hf.guest_tso4() =
true;
160 hf.guest_tso6() =
true;
161 hf.guest_ufo() =
true;
162 hf.guest_ecn() =
true;
165 _dev_config.host_features(0) = hf.
raw;
167 _dev_config.reset_hdr();
180 _dev_config.reset_hdr();
183 template<
typename T,
unsigned N >
184 static unsigned array_length(T (&)[N]) {
return N; }
188 Dbg(Dbg::Virtio, Dbg::Info,
"Virtio")
189 .printf(
"(%p): Reconfigure queue %d (%p): Status: %02x\n",
190 this, index, _q + index, _dev_config.status().raw);
192 if (index >= array_length(_q))
201 void dump_features(Dbg
const &dbg,
const volatile l4_uint32_t *p)
203 dbg.cprintf(
"%08x:%08x:%08x:%08x:%08x:%08x\n",
204 p[0], p[1], p[2], p[3], p[4], p[5]);
209 Dbg info(Dbg::Virtio, Dbg::Info,
"Virtio");
210 if (!info.is_active())
213 auto *hdr = _dev_config.hdr();
215 info.printf(
"Device %p running (%02x)\n\thost features: ",
216 this, _dev_config.status().raw);
217 dump_features(info, hdr->dev_features_map);
218 info.printf(
"\tguest features: ");
219 dump_features(info, hdr->driver_features_map);
224 _negotiated_features = _dev_config.negotiated_features(0);
228 bool device_needs_reset()
const
238 Err().printf(
"failed to start queues\n");
262 _kick_guest_irq->trigger();
275 Virtqueue *q =
static_cast<Virtqueue*
>(queue);
279 _kick_guest_irq->trigger();
283 void kick_emit_and_enable()
285 bool kick_pending =
false;
288 kick_pending |= q.kick_enable_get_pending();
293 _kick_guest_irq->trigger();
297 void kick_disable_and_remember()
300 q.kick_disable_and_remember();
303 Features negotiated_features()
const
304 {
return _negotiated_features; }
307 Virtqueue *
tx_q() {
return &_q[Tx]; }
309 Virtqueue *
rx_q() {
return &_q[Rx]; }
311 Virtqueue
const *
tx_q()
const {
return &_q[Tx]; }
313 Virtqueue
const *
rx_q()
const {
return &_q[Rx]; }
316 Features _negotiated_features;