Lines Matching refs:the
3 # Technical notes for the virtio-net driver.
7 # This program and the accompanying materials are licensed and made available
8 # under the terms and conditions of the BSD License which accompanies this
9 # distribution. The full text of the license may be found at
21 normative. They are made in good faith. Corrections are most welcome on the
24 The following documents have been perused while writing the driver and this
35 The VirtioNetDxe UEFI_DRIVER implements the Simple Network Protocol for
37 of it by the DXE Core / the ConnectController() boot service, enabling for
47 transitions are labeled with the primary function (and its important callees
48 faithfully indented) that implement the transition.
80 The state at the top means "nonexistent" and is hence unnamed on the diagram --
82 functions out of and into that state implement the Driver Binding Protocol.
85 states defined by the Simple Network Protocol. The transition functions between
86 them are member functions of the Simple Network Protocol.
90 from the controller unless it's in EfiSimpleNetworkStopped.
96 In the EfiSimpleNetworkStopped state, the virtio-net device is (has been)
98 address and other device attributes have been retrieved from the device (this
99 is necessary for completing the VirtioNetDriverBindingStart transition).
101 The EfiSimpleNetworkStarted is completely identical to the
102 EfiSimpleNetworkStopped state for virtio-net, in the functional and
103 resource-usage sense. This state is mandated / provided by the Simple Network
104 Protocol for flexibility that the virtio-net driver doesn't exploit.
106 In particular, the EfiSimpleNetworkStarted state is the target of the Shutdown
109 driver could not do that due to the exclusivity of the driver binding that
112 The EfiSimpleNetworkInitialized state is the live state of the virtio NIC / the
114 been allocated, and the following SNP member functions are available (in
115 addition to VirtioNetShutdown which leaves the state):
117 - VirtioNetReceive [SnpReceive.c]: poll the virtio NIC for an Rx packet that
131 filter setting than requested is allowed by the UEFI specification).
135 - VirtioNetReset: reinitialize the virtio NIC without shutting it down (a loop
138 - VirtioNetStationAddress: assign a new MAC address to the virtio NIC,
142 - VirtioNetNvData: access non-volatile data on the virtio NIC.
144 Missing support for these functions is allowed by the UEFI specification and
163 with the Receive member function.) The event is available to clients starting
167 receiving an asynchronous callback (a software interrupt). In the callback
168 function the driver must interrogate the driver instance state, and if it is
169 EfiSimpleNetworkInitialized, access the Rx queue and see if any packets are
170 available for consumption. If so, it must signal the WaitForPacket WAIT type
171 event, waking the client.
173 For simplicity and safety, all parts of the virtio-net driver that access any
174 bit of the driver instance (data or device) run at the TPL_CALLBACK level.
175 This is the highest level allowed for an SNP implementation, and all code
179 The task priority level for the WaitForPacket callback too is set by the
180 driver, the choice is TPL_CALLBACK again. This in effect serializes the
182 parts of the driver.
184 - According to the Driver Writer's Guide, a network driver should install a
185 callback function for the global EXIT_BOOT_SERVICES event (a special NOTIFY
186 type event). When the ExitBootServices() boot service has cleaned up internal
187 firmware state and is about to pass control to the OS, any network driver has
189 reason EXIT_BOOT_SERVICES is emitted and the network driver must abort
192 This callback (VirtioNetExitBoot) is synchronized with the rest of the driver
193 code just the same as explained for WaitForPacket. In
194 EfiSimpleNetworkInitialized state it resets the virtio NIC, halting all data
195 transfer. After the callback returns, no further driver code is expected to
202 Requests (Rx and Tx alike) are always submitted by the guest and processed by
203 the host. For Tx, processing means transmission. For Rx, processing means
204 filling in the request with an incoming packet. Submitted requests exist on the
205 "Available Ring", and answered (processed) requests show up on the "Used Ring".
207 Packet data includes the media (Ethernet) header: destination MAC, source MAC,
211 in the Virtio specification, the only driver-specific trait here is the static
212 pre-configuration of the two-part descriptor chains, in VirtioNetInitRx. The
217 by the host by the guest
237 last processed by the guest by the host
244 In VirtioNetInitRx, the guest allocates the fixed size Receive Destination
245 Area, which accommodates all packets delivered asynchronously by the host. To
253 Furthermore, the guest lays out a static pattern in the Descriptor Table. For
254 each packet that can be in-flight or already arrived from the host,
256 the Nth descriptor chain is set up as follows:
258 - the first (=head) descriptor, with even index, points to the fixed-size
259 sub-slice receiving the virtio-net request header,
261 - the second descriptor (with odd index) points to the fixed (1514 byte) size
262 sub-slice receiving the packet data,
264 - a link from the first (head) descriptor in the chain is established to the
265 second (tail) descriptor in the chain.
267 Finally, the guest populates the Available Ring with the indices of the head
268 descriptors. All descriptor indices on both the Available Ring and the Used
273 - The host consumes a descriptor index off the Available Ring. This index is
274 even (=2*N), and fingers the head descriptor of the chain belonging to packet
277 - The host reads the descriptors D(2*N) and -- following the Next link there
278 --- D(2*N+1), and stores the virtio-net request header at A(2*N), and the
281 - The host places the index of the head descriptor, 2*N, onto the Used Ring,
282 and sets the Len field in the same Used Ring Element to the total number of
283 bytes transferred for the entire descriptor chain. This enables the guest to
284 identify the length of Rx packets.
286 - VirtioNetReceive polls the Used Ring. If a new Used Ring Element shows up, it
287 copies the data out to the caller, and recycles the index of the head
288 descriptor (ie. 2*N) to the Available Ring.
290 - Because the host can process (answer) Rx requests in any order theoretically,
291 the order of head descriptor indices on each of the Available Ring and the
292 Used Ring is virtually random. (Except right after the initial population in
293 VirtioNetInitRx, when the Available Ring is full and increasing, and the Used
296 - If the Available Ring is empty, the host is forced to drop packets. If the
305 in the following:
310 that is shared by all of the head descriptors. This virtio-net request header
311 is never modified by the host.
313 - Each tail descriptor is re-pointed to the caller-supplied packet buffer
314 whenever VirtioNetTransmit places the corresponding head descriptor on the
315 Available Ring. The caller is responsible to hang on to the unmodified buffer
321 chains by keeping the indices of their head descriptors in a stack that is
322 private to the driver instance. All elements of the stack are even.
324 - If the stack is empty (that is, each descriptor chain, in isolation, is
325 either pending transmission, or has been processed by the host but not
329 - Otherwise the index of a free chain's head descriptor is popped from the
331 descriptor's index is pushed on the Available Ring.
333 - The host moves the head descriptor index from the Available Ring to the Used
334 Ring when it transmits the packet.
336 - Client code calls VirtioNetGetStatus. In case the Used Ring is empty, the
338 consumed from the Used Ring and recycled to the private stack. The client
339 code's original packet buffer address is fetched from the tail descriptor
340 (where it has been stored at VirtioNetTransmit time) and returned to the
343 - The Len field of the Used Ring Element is not checked. The host is assumed to
344 have transmitted the entire packet -- VirtioNetTransmit had forced it below
348 VirtioNetGetStatus; EFI_DEVICE_ERROR seems too serious from the specification
352 from the Available Ring to the Used Ring (out of order transmission). Because
353 of this (and the choice of a stack over a list for free descriptor chain
354 tracking) the order of head descriptor indices on either Ring is