iPXE
netvsc.c File Reference

Hyper-V network virtual service client. More...

#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <byteswap.h>
#include <ipxe/umalloc.h>
#include <ipxe/rndis.h>
#include <ipxe/vmbus.h>
#include "netvsc.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int netvsc_control (struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
 Send control message and wait for completion.
static int netvsc_completed (struct netvsc_device *netvsc __unused, const void *data __unused, size_t len __unused)
 Handle generic completion.
static int netvsc_initialise (struct netvsc_device *netvsc)
 Initialise communication.
static int netvsc_initialised (struct netvsc_device *netvsc, const void *data, size_t len)
 Handle initialisation completion.
static int netvsc_ndis_version (struct netvsc_device *netvsc)
 Set NDIS version.
static int netvsc_establish_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Establish data buffer.
static int netvsc_rx_established_buffer (struct netvsc_device *netvsc, const void *data, size_t len)
 Handle establish receive data buffer completion.
static int netvsc_revoke_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Revoke data buffer.
static int netvsc_recv_control (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
 Handle received control packet.
static int netvsc_recv_data (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct list_head *list)
 Handle received data packet.
static int netvsc_recv_completion (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
 Handle received completion packet.
static int netvsc_recv_cancellation (struct vmbus_device *vmdev, uint64_t xid)
 Handle received cancellation packet.
static void netvsc_poll (struct rndis_device *rndis)
 Poll for completed and received packets.
static int netvsc_transmit (struct rndis_device *rndis, struct io_buffer *iobuf)
 Transmit packet.
static void netvsc_cancel_transmit (struct netvsc_device *netvsc, struct io_buffer *iobuf, unsigned int tx_id)
 Cancel transmission.
static int netvsc_create_ring (struct netvsc_device *netvsc __unused, struct netvsc_ring *ring)
 Create descriptor ring.
static void netvsc_destroy_ring (struct netvsc_device *netvsc, struct netvsc_ring *ring, void(*discard)(struct netvsc_device *, struct io_buffer *, unsigned int))
 Destroy descriptor ring.
static int netvsc_buffer_copy (struct vmbus_xfer_pages *pages, void *data, size_t offset, size_t len)
 Copy data from data buffer.
static int netvsc_create_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Create data buffer.
static void netvsc_destroy_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Destroy data buffer.
static int netvsc_open (struct rndis_device *rndis)
 Open device.
static void netvsc_close (struct rndis_device *rndis)
 Close device.
static int netvsc_probe (struct vmbus_device *vmdev)
 Probe device.
static int netvsc_reset (struct vmbus_device *vmdev)
 Reset device.
static void netvsc_remove (struct vmbus_device *vmdev)
 Remove device.
 VMBUS_ROM ("netvsc", "Hyper-V NetVSC RNDIS virtual NIC")

Variables

static struct vmbus_channel_operations netvsc_channel_operations
 VMBus channel operations.
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
 Transfer page set operations.
static struct rndis_operations netvsc_operations
 RNDIS operations.
struct vmbus_driver netvsc_driver __vmbus_driver
 NetVSC driver.

Detailed Description

Hyper-V network virtual service client.

The network virtual service client (NetVSC) connects to the network virtual service provider (NetVSP) via the Hyper-V virtual machine bus (VMBus). It provides a transport layer for RNDIS packets.

Definition in file netvsc.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ netvsc_control()

int netvsc_control ( struct netvsc_device * netvsc,
unsigned int xrid,
const void * data,
size_t len )
static

Send control message and wait for completion.

Parameters
netvscNetVSC device
xridRelative transaction ID
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 53 of file netvsc.c.

54 {
55 uint64_t xid = ( NETVSC_BASE_XID + xrid );
56 unsigned int i;
57 int rc;
58
59 /* Send control message */
60 if ( ( rc = vmbus_send_control ( netvsc->vmdev, xid, data, len ) ) !=0){
61 DBGC ( netvsc, "NETVSC %s could not send control message: %s\n",
62 netvsc->name, strerror ( rc ) );
63 return rc;
64 }
65
66 /* Record transaction ID */
67 netvsc->wait_xrid = xrid;
68
69 /* Wait for operation to complete */
70 for ( i = 0 ; i < NETVSC_MAX_WAIT_MS ; i++ ) {
71
72 /* Check for completion */
73 if ( ! netvsc->wait_xrid )
74 return netvsc->wait_rc;
75
76 /* Poll VMBus device */
77 vmbus_poll ( netvsc->vmdev );
78
79 /* Delay for 1ms */
80 mdelay ( 1 );
81 }
82
83 DBGC ( netvsc, "NETVSC %s timed out waiting for XRID %d\n",
84 netvsc->name, xrid );
85 vmbus_dump_channel ( netvsc->vmdev );
86 return -ETIMEDOUT;
87}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned long long uint64_t
Definition stdint.h:13
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC(...)
Definition compiler.h:505
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define NETVSC_BASE_XID
Base transaction ID.
Definition netvsc.h:45
#define NETVSC_MAX_WAIT_MS
Maximum time to wait for a transaction to complete.
Definition netvsc.h:19
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
const char * name
Name.
Definition netvsc.h:347
int wait_rc
Return status code for current blocking transaction.
Definition netvsc.h:362
struct vmbus_device * vmdev
VMBus device.
Definition netvsc.h:343
unsigned int wait_xrid
Relative transaction ID for current blocking transaction.
Definition netvsc.h:360
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
int vmbus_send_control(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send control packet via ring buffer.
Definition vmbus.c:765
void vmbus_dump_channel(struct vmbus_device *vmdev)
Dump channel status (for debugging)
Definition vmbus.c:1089
int vmbus_poll(struct vmbus_device *vmdev)
Poll ring buffer.
Definition vmbus.c:972

References data, DBGC, ETIMEDOUT, len, mdelay(), netvsc_device::name, NETVSC_BASE_XID, NETVSC_MAX_WAIT_MS, rc, strerror(), vmbus_dump_channel(), vmbus_poll(), vmbus_send_control(), netvsc_device::vmdev, netvsc_device::wait_rc, and netvsc_device::wait_xrid.

Referenced by netvsc_establish_buffer(), netvsc_initialise(), netvsc_ndis_version(), and netvsc_revoke_buffer().

◆ netvsc_completed()

int netvsc_completed ( struct netvsc_device *netvsc __unused,
const void *data __unused,
size_t len __unused )
static

Handle generic completion.

Parameters
netvscNetVSC device
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 97 of file netvsc.c.

98 {
99 return 0;
100}

References __unused, data, and len.

Referenced by netvsc_recv_completion().

◆ netvsc_initialise()

int netvsc_initialise ( struct netvsc_device * netvsc)
static

Initialise communication.

Parameters
netvscNetVSC device
Return values
rcReturn status code

Definition at line 108 of file netvsc.c.

108 {
110 int rc;
111
112 /* Construct message */
113 memset ( &msg, 0, sizeof ( msg ) );
114 msg.header.type = cpu_to_le32 ( NETVSC_INIT_MSG );
117
118 /* Send message and wait for completion */
119 if ( ( rc = netvsc_control ( netvsc, NETVSC_INIT_XRID, &msg,
120 sizeof ( msg ) ) ) != 0 ) {
121 DBGC ( netvsc, "NETVSC %s could not initialise: %s\n",
122 netvsc->name, strerror ( rc ) );
123 return rc;
124 }
125
126 return 0;
127}
#define cpu_to_le32(value)
Definition byteswap.h:108
void * memset(void *dest, int character, size_t len) __nonnull
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition message.c:62
static int netvsc_control(struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
Send control message and wait for completion.
Definition netvsc.c:53
@ NETVSC_INIT_XRID
Initialisation.
Definition netvsc.h:52
#define NETVSC_INIT_MSG
NetVSC initialisation message.
Definition netvsc.h:80
#define NETVSC_VERSION_1
Oldest known NetVSC protocol version.
Definition netvsc.h:95
NetVSC initialisation message.
Definition netvsc.h:83

References cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), NETVSC_INIT_MSG, NETVSC_INIT_XRID, NETVSC_VERSION_1, rc, and strerror().

Referenced by netvsc_open().

◆ netvsc_initialised()

int netvsc_initialised ( struct netvsc_device * netvsc,
const void * data,
size_t len )
static

Handle initialisation completion.

Parameters
netvscNetVSC device
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 138 of file netvsc.c.

139 {
140 const struct netvsc_init_completion *cmplt = data;
141
142 /* Check completion */
143 if ( len < sizeof ( *cmplt ) ) {
144 DBGC ( netvsc, "NETVSC %s underlength initialisation "
145 "completion (%zd bytes)\n", netvsc->name, len );
146 return -EINVAL;
147 }
148 if ( cmplt->header.type != cpu_to_le32 ( NETVSC_INIT_CMPLT ) ) {
149 DBGC ( netvsc, "NETVSC %s unexpected initialisation completion "
150 "type %d\n", netvsc->name,
151 le32_to_cpu ( cmplt->header.type ) );
152 return -EPROTO;
153 }
154 if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
155 DBGC ( netvsc, "NETVSC %s initialisation failure status %d\n",
156 netvsc->name, le32_to_cpu ( cmplt->status ) );
157 return -EPROTO;
158 }
159
160 return 0;
161}
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EPROTO
Protocol error.
Definition errno.h:625
#define le32_to_cpu(value)
Definition byteswap.h:114
@ NETVSC_OK
Definition netvsc.h:64
#define NETVSC_INIT_CMPLT
NetVSC initialisation completion.
Definition netvsc.h:98
uint32_t type
Type.
Definition netvsc.h:76
NetVSC initialisation completion.
Definition netvsc.h:101
struct netvsc_header header
Message header.
Definition netvsc.h:103
uint32_t status
Status.
Definition netvsc.h:109

References cpu_to_le32, data, DBGC, EINVAL, EPROTO, netvsc_init_completion::header, le32_to_cpu, len, netvsc_device::name, NETVSC_INIT_CMPLT, NETVSC_OK, netvsc_init_completion::status, and netvsc_header::type.

Referenced by netvsc_recv_completion().

◆ netvsc_ndis_version()

int netvsc_ndis_version ( struct netvsc_device * netvsc)
static

Set NDIS version.

Parameters
netvscNetVSC device
Return values
rcReturn status code

Definition at line 169 of file netvsc.c.

169 {
171 int rc;
172
173 /* Construct message */
174 memset ( &msg, 0, sizeof ( msg ) );
175 msg.header.type = cpu_to_le32 ( NETVSC_NDIS_VERSION_MSG );
178
179 /* Send message and wait for completion */
180 if ( ( rc = netvsc_control ( netvsc, NETVSC_NDIS_VERSION_XRID,
181 &msg, sizeof ( msg ) ) ) != 0 ) {
182 DBGC ( netvsc, "NETVSC %s could not set NDIS version: %s\n",
183 netvsc->name, strerror ( rc ) );
184 return rc;
185 }
186
187 return 0;
188}
#define NETVSC_NDIS_MAJOR
NetVSC NDIS major version.
Definition netvsc.h:130
@ NETVSC_NDIS_VERSION_XRID
NDIS version.
Definition netvsc.h:54
#define NETVSC_NDIS_MINOR
NetVSC NDIS minor version.
Definition netvsc.h:133
#define NETVSC_NDIS_VERSION_MSG
NetVSC NDIS version message.
Definition netvsc.h:115
NetVSC NDIS version message.
Definition netvsc.h:118

References cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), NETVSC_NDIS_MAJOR, NETVSC_NDIS_MINOR, NETVSC_NDIS_VERSION_MSG, NETVSC_NDIS_VERSION_XRID, rc, and strerror().

Referenced by netvsc_open().

◆ netvsc_establish_buffer()

int netvsc_establish_buffer ( struct netvsc_device * netvsc,
struct netvsc_buffer * buffer )
static

Establish data buffer.

Parameters
netvscNetVSC device
bufferData buffer
Return values
rcReturn status code

Definition at line 197 of file netvsc.c.

198 {
200 int rc;
201
202 /* Construct message */
203 memset ( &msg, 0, sizeof ( msg ) );
204 msg.header.type = cpu_to_le32 ( buffer->establish_type );
205 msg.gpadl = cpu_to_le32 ( buffer->gpadl );
206 msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
207
208 /* Send message and wait for completion */
209 if ( ( rc = netvsc_control ( netvsc, buffer->establish_xrid, &msg,
210 sizeof ( msg ) ) ) != 0 ) {
211 DBGC ( netvsc, "NETVSC %s could not establish buffer: %s\n",
212 netvsc->name, strerror ( rc ) );
213 return rc;
214 }
215
216 return 0;
217}
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
NetVSC establish data buffer message.
Definition netvsc.h:154

References buffer, cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), rc, and strerror().

Referenced by netvsc_open().

◆ netvsc_rx_established_buffer()

int netvsc_rx_established_buffer ( struct netvsc_device * netvsc,
const void * data,
size_t len )
static

Handle establish receive data buffer completion.

Parameters
netvscNetVSC device
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 227 of file netvsc.c.

228 {
229 const struct netvsc_rx_establish_buffer_completion *cmplt = data;
230
231 /* Check completion */
232 if ( len < sizeof ( *cmplt ) ) {
233 DBGC ( netvsc, "NETVSC %s underlength buffer completion (%zd "
234 "bytes)\n", netvsc->name, len );
235 return -EINVAL;
236 }
237 if ( cmplt->header.type != cpu_to_le32 ( NETVSC_RX_ESTABLISH_CMPLT ) ) {
238 DBGC ( netvsc, "NETVSC %s unexpected buffer completion type "
239 "%d\n", netvsc->name, le32_to_cpu ( cmplt->header.type));
240 return -EPROTO;
241 }
242 if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
243 DBGC ( netvsc, "NETVSC %s buffer failure status %d\n",
244 netvsc->name, le32_to_cpu ( cmplt->status ) );
245 return -EPROTO;
246 }
247
248 return 0;
249}
#define NETVSC_RX_ESTABLISH_CMPLT
NetVSC establish receive data buffer completion.
Definition netvsc.h:139
NetVSC establish receive data buffer completion.
Definition netvsc.h:178
struct netvsc_header header
Message header.
Definition netvsc.h:180

References cpu_to_le32, data, DBGC, EINVAL, EPROTO, netvsc_rx_establish_buffer_completion::header, le32_to_cpu, len, netvsc_device::name, NETVSC_OK, NETVSC_RX_ESTABLISH_CMPLT, netvsc_rx_establish_buffer_completion::status, and netvsc_header::type.

Referenced by netvsc_recv_completion().

◆ netvsc_revoke_buffer()

int netvsc_revoke_buffer ( struct netvsc_device * netvsc,
struct netvsc_buffer * buffer )
static

Revoke data buffer.

Parameters
netvscNetVSC device
bufferData buffer
Return values
rcReturn status code

Definition at line 258 of file netvsc.c.

259 {
261 int rc;
262
263 /* If the buffer's GPADL is obsolete (i.e. was created before
264 * the most recent Hyper-V reset), then we will never receive
265 * a response to the revoke message. Since the GPADL is
266 * already destroyed as far as the hypervisor is concerned, no
267 * further action is required.
268 */
269 if ( netvsc_is_obsolete ( netvsc ) )
270 return 0;
271
272 /* Construct message */
273 memset ( &msg, 0, sizeof ( msg ) );
274 msg.header.type = cpu_to_le32 ( buffer->revoke_type );
275 msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
276
277 /* Send message and wait for completion */
278 if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
279 &msg, sizeof ( msg ) ) ) != 0 ) {
280 DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
281 netvsc->name, strerror ( rc ) );
282 return rc;
283 }
284
285 return 0;
286}
NetVSC revoke data buffer message.
Definition netvsc.h:200

References buffer, cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), rc, and strerror().

Referenced by netvsc_close(), and netvsc_open().

◆ netvsc_recv_control()

int netvsc_recv_control ( struct vmbus_device * vmdev,
uint64_t xid,
const void * data,
size_t len )
static

Handle received control packet.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 297 of file netvsc.c.

298 {
299 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
300 struct netvsc_device *netvsc = rndis->priv;
301
302 DBGC ( netvsc, "NETVSC %s received unsupported control packet "
303 "(%08llx):\n", netvsc->name, xid );
304 DBGC_HDA ( netvsc, 0, data, len );
305 return -ENOTSUP;
306}
#define DBGC_HDA(...)
Definition compiler.h:506
#define ENOTSUP
Operation not supported.
Definition errno.h:590
A NetVSC device.
Definition netvsc.h:341
struct rndis_device * rndis
RNDIS device.
Definition netvsc.h:345
An RNDIS device.
Definition rndis.h:318
void * priv
Driver private data.
Definition rndis.h:326
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition vmbus.h:569

References data, DBGC, DBGC_HDA, ENOTSUP, len, netvsc_device::name, rndis_device::priv, netvsc_device::rndis, and vmbus_get_drvdata().

◆ netvsc_recv_data()

int netvsc_recv_data ( struct vmbus_device * vmdev,
uint64_t xid,
const void * data,
size_t len,
struct list_head * list )
static

Handle received data packet.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
listList of I/O buffers
Return values
rcReturn status code

Definition at line 318 of file netvsc.c.

320 {
321 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
322 struct netvsc_device *netvsc = rndis->priv;
323 const struct netvsc_rndis_message *msg = data;
324 struct io_buffer *iobuf;
325 struct io_buffer *tmp;
326 int rc;
327
328 /* Sanity check */
329 if ( len < sizeof ( *msg ) ) {
330 DBGC ( netvsc, "NETVSC %s received underlength RNDIS packet "
331 "(%zd bytes)\n", netvsc->name, len );
332 rc = -EINVAL;
333 goto err_sanity;
334 }
335 if ( msg->header.type != cpu_to_le32 ( NETVSC_RNDIS_MSG ) ) {
336 DBGC ( netvsc, "NETVSC %s received unexpected RNDIS packet "
337 "type %d\n", netvsc->name,
338 le32_to_cpu ( msg->header.type ) );
339 rc = -EINVAL;
340 goto err_sanity;
341 }
342
343 /* Send completion back to host */
344 if ( ( rc = vmbus_send_completion ( vmdev, xid, NULL, 0 ) ) != 0 ) {
345 DBGC ( netvsc, "NETVSC %s could not send completion: %s\n",
346 netvsc->name, strerror ( rc ) );
347 goto err_completion;
348 }
349
350 /* Hand off to RNDIS */
352 list_del ( &iobuf->list );
353 rndis_rx ( rndis, iob_disown ( iobuf ) );
354 }
355
356 return 0;
357
358 err_completion:
359 err_sanity:
361 list_del ( &iobuf->list );
362 free_iob ( iobuf );
363 }
364 return rc;
365}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define NETVSC_RNDIS_MSG
NetVSC RNDIS message.
Definition netvsc.h:210
void rndis_rx(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive packet from underlying transport layer.
Definition rndis.c:830
A persistent I/O buffer.
Definition iobuf.h:38
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
NetVSC RNDIS message.
Definition netvsc.h:213
int vmbus_send_completion(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send completion packet via ring buffer.
Definition vmbus.c:834

References cpu_to_le32, data, DBGC, EINVAL, free_iob(), iob_disown, le32_to_cpu, len, io_buffer::list, list_del, list_for_each_entry_safe, msg(), netvsc_device::name, NETVSC_RNDIS_MSG, NULL, rndis_device::priv, rc, netvsc_device::rndis, rndis_rx(), strerror(), tmp, vmbus_get_drvdata(), and vmbus_send_completion().

◆ netvsc_recv_completion()

int netvsc_recv_completion ( struct vmbus_device * vmdev,
uint64_t xid,
const void * data,
size_t len )
static

Handle received completion packet.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 376 of file netvsc.c.

377 {
378 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
379 struct netvsc_device *netvsc = rndis->priv;
380 struct io_buffer *iobuf;
381 int ( * completion ) ( struct netvsc_device *netvsc,
382 const void *data, size_t len );
383 unsigned int xrid = ( xid - NETVSC_BASE_XID );
384 unsigned int tx_id;
385 int rc;
386
387 /* Handle transmit completion, if applicable */
388 tx_id = ( xrid - NETVSC_TX_BASE_XRID );
389 if ( ( tx_id < NETVSC_TX_NUM_DESC ) &&
390 ( ( iobuf = netvsc->tx.iobufs[tx_id] ) != NULL ) ) {
391
392 /* Free buffer ID */
393 netvsc->tx.iobufs[tx_id] = NULL;
394 netvsc->tx.ids[ ( netvsc->tx.id_cons++ ) &
395 ( netvsc->tx.count - 1 ) ] = tx_id;
396
397 /* Hand back to RNDIS */
398 rndis_tx_complete ( rndis, iobuf );
399 return 0;
400 }
401
402 /* Otherwise determine completion handler */
403 if ( xrid == NETVSC_INIT_XRID ) {
405 } else if ( xrid == NETVSC_RX_ESTABLISH_XRID ) {
407 } else if ( ( netvsc->wait_xrid != 0 ) &&
408 ( xrid == netvsc->wait_xrid ) ) {
410 } else {
411 DBGC ( netvsc, "NETVSC %s received unexpected completion "
412 "(%08llx)\n", netvsc->name, xid );
413 return -EPIPE;
414 }
415
416 /* Hand off to completion handler */
417 rc = completion ( netvsc, data, len );
418
419 /* Record completion handler result if applicable */
420 if ( xrid == netvsc->wait_xrid ) {
421 netvsc->wait_xrid = 0;
422 netvsc->wait_rc = rc;
423 }
424
425 return rc;
426}
pseudo_bit_t completion[0x00001]
Definition arbel.h:2
#define EPIPE
Broken pipe.
Definition errno.h:620
static int netvsc_initialised(struct netvsc_device *netvsc, const void *data, size_t len)
Handle initialisation completion.
Definition netvsc.c:138
static int netvsc_completed(struct netvsc_device *netvsc __unused, const void *data __unused, size_t len __unused)
Handle generic completion.
Definition netvsc.c:97
static int netvsc_rx_established_buffer(struct netvsc_device *netvsc, const void *data, size_t len)
Handle establish receive data buffer completion.
Definition netvsc.c:227
@ NETVSC_RX_ESTABLISH_XRID
Establish receive buffer.
Definition netvsc.h:56
@ NETVSC_TX_BASE_XRID
Transmit descriptors (one per transmit buffer ID)
Definition netvsc.h:50
#define NETVSC_TX_NUM_DESC
Number of transmit ring entries.
Definition netvsc.h:27
static void rndis_tx_complete(struct rndis_device *rndis, struct io_buffer *iobuf)
Complete message transmission.
Definition rndis.h:365
struct netvsc_ring tx
Transmit ring.
Definition netvsc.h:350
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition netvsc.h:240
unsigned int id_cons
Buffer ID consumer counter.
Definition netvsc.h:246
uint8_t * ids
Buffer ID ring.
Definition netvsc.h:242
unsigned int count
Number of descriptors.
Definition netvsc.h:238

References completion, netvsc_ring::count, data, DBGC, EPIPE, netvsc_ring::id_cons, netvsc_ring::ids, netvsc_ring::iobufs, len, netvsc_device::name, NETVSC_BASE_XID, netvsc_completed(), NETVSC_INIT_XRID, netvsc_initialised(), NETVSC_RX_ESTABLISH_XRID, netvsc_rx_established_buffer(), NETVSC_TX_BASE_XRID, NETVSC_TX_NUM_DESC, NULL, rndis_device::priv, rc, netvsc_device::rndis, rndis_tx_complete(), netvsc_device::tx, vmbus_get_drvdata(), netvsc_device::wait_rc, and netvsc_device::wait_xrid.

◆ netvsc_recv_cancellation()

int netvsc_recv_cancellation ( struct vmbus_device * vmdev,
uint64_t xid )
static

Handle received cancellation packet.

Parameters
vmdevVMBus device
xidTransaction ID
Return values
rcReturn status code

Definition at line 435 of file netvsc.c.

436 {
437 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
438 struct netvsc_device *netvsc = rndis->priv;
439
440 DBGC ( netvsc, "NETVSC %s received unsupported cancellation packet "
441 "(%08llx):\n", netvsc->name, xid );
442 return -ENOTSUP;
443}

References DBGC, ENOTSUP, netvsc_device::name, rndis_device::priv, netvsc_device::rndis, and vmbus_get_drvdata().

◆ netvsc_poll()

void netvsc_poll ( struct rndis_device * rndis)
static

Poll for completed and received packets.

Parameters
rndisRNDIS device

Definition at line 458 of file netvsc.c.

458 {
459 struct netvsc_device *netvsc = rndis->priv;
460 struct vmbus_device *vmdev = netvsc->vmdev;
461
462 /* Poll VMBus device */
463 while ( vmbus_has_data ( vmdev ) )
464 vmbus_poll ( vmdev );
465}
A VMBus device.
Definition vmbus.h:475
static int vmbus_has_data(struct vmbus_device *vmdev)
Check if data is present in ring buffer.
Definition vmbus.h:588

References rndis_device::priv, netvsc_device::rndis, vmbus_has_data(), vmbus_poll(), and netvsc_device::vmdev.

◆ netvsc_transmit()

int netvsc_transmit ( struct rndis_device * rndis,
struct io_buffer * iobuf )
static

Transmit packet.

Parameters
rndisRNDIS device
iobufI/O buffer
Return values
rcReturn status code

If this method returns success then the RNDIS device must eventually report completion via rndis_tx_complete().

Definition at line 477 of file netvsc.c.

478 {
479 struct netvsc_device *netvsc = rndis->priv;
480 struct rndis_header *header = iobuf->data;
482 unsigned int tx_id;
483 unsigned int xrid;
484 uint64_t xid;
485 int rc;
486
487 /* If the device is obsolete (i.e. was opened before the most
488 * recent Hyper-V reset), then we will never receive transmit
489 * completions. Fail transmissions immediately to minimise
490 * the delay in closing and reopening the device.
491 */
492 if ( netvsc_is_obsolete ( netvsc ) )
493 return -EPIPE;
494
495 /* Sanity check */
496 assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
497 assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
498
499 /* Check that we have space in the transmit ring */
500 if ( netvsc_ring_is_full ( &netvsc->tx ) )
501 return rndis_tx_defer ( rndis, iobuf );
502
503 /* Allocate buffer ID and calculate transaction ID */
504 tx_id = netvsc->tx.ids[ netvsc->tx.id_prod & ( netvsc->tx.count - 1 ) ];
505 assert ( netvsc->tx.iobufs[tx_id] == NULL );
506 xrid = ( NETVSC_TX_BASE_XRID + tx_id );
507 xid = ( NETVSC_BASE_XID + xrid );
508
509 /* Construct message */
510 memset ( &msg, 0, sizeof ( msg ) );
511 msg.header.type = cpu_to_le32 ( NETVSC_RNDIS_MSG );
512 msg.channel = ( ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) ?
515
516 /* Send message */
517 if ( ( rc = vmbus_send_data ( netvsc->vmdev, xid, &msg, sizeof ( msg ),
518 iobuf ) ) != 0 ) {
519 DBGC ( netvsc, "NETVSC %s could not send RNDIS message: %s\n",
520 netvsc->name, strerror ( rc ) );
521 return rc;
522 }
523
524 /* Store I/O buffer and consume buffer ID */
525 netvsc->tx.iobufs[tx_id] = iobuf;
526 netvsc->tx.id_prod++;
527
528 return 0;
529}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
struct ena_llq_option header
Header locations.
Definition ena.h:5
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define NETVSC_RNDIS_CONTROL
RNDIS control channel (for all other RNDIS messages)
Definition netvsc.h:230
#define NETVSC_RNDIS_NO_BUFFER
"No buffer used" index
Definition netvsc.h:233
#define NETVSC_RNDIS_DATA
RNDIS data channel (for RNDIS_PACKET_MSG only)
Definition netvsc.h:227
int rndis_tx_defer(struct rndis_device *rndis, struct io_buffer *iobuf)
Defer transmitted packet.
Definition rndis.c:191
#define RNDIS_PACKET_MSG
RNDIS packet message.
Definition rndis.h:220
void * data
Start of data.
Definition iobuf.h:53
unsigned int id_prod
Buffer ID producer counter.
Definition netvsc.h:244
RNDIS message header.
Definition rndis.h:24
int vmbus_send_data(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct io_buffer *iobuf)
Send data packet via ring buffer.
Definition vmbus.c:794

References assert, netvsc_ring::count, cpu_to_le32, io_buffer::data, DBGC, EPIPE, header, netvsc_ring::id_prod, netvsc_ring::ids, iob_len(), netvsc_ring::iobufs, le32_to_cpu, memset(), msg(), netvsc_device::name, NETVSC_BASE_XID, NETVSC_RNDIS_CONTROL, NETVSC_RNDIS_DATA, NETVSC_RNDIS_MSG, NETVSC_RNDIS_NO_BUFFER, NETVSC_TX_BASE_XRID, NULL, rndis_device::priv, rc, netvsc_device::rndis, RNDIS_PACKET_MSG, rndis_tx_defer(), strerror(), netvsc_device::tx, vmbus_send_data(), and netvsc_device::vmdev.

◆ netvsc_cancel_transmit()

void netvsc_cancel_transmit ( struct netvsc_device * netvsc,
struct io_buffer * iobuf,
unsigned int tx_id )
static

Cancel transmission.

Parameters
netvscNetVSC device
iobufI/O buffer
tx_idTransmission ID

Definition at line 538 of file netvsc.c.

540 {
541 unsigned int xrid;
542 uint64_t xid;
543
544 /* Send cancellation */
545 xrid = ( NETVSC_TX_BASE_XRID + tx_id );
546 xid = ( NETVSC_BASE_XID + xrid );
547 DBGC ( netvsc, "NETVSC %s cancelling transmission %#x\n",
548 netvsc->name, tx_id );
549 vmbus_send_cancellation ( netvsc->vmdev, xid );
550
551 /* Report back to RNDIS */
552 rndis_tx_complete_err ( netvsc->rndis, iobuf, -ECANCELED );
553}
#define ECANCELED
Operation canceled.
Definition errno.h:344
void rndis_tx_complete_err(struct rndis_device *rndis, struct io_buffer *iobuf, int rc)
Complete message transmission.
Definition rndis.c:128
int vmbus_send_cancellation(struct vmbus_device *vmdev, uint64_t xid)
Send cancellation packet via ring buffer.
Definition vmbus.c:857

References DBGC, ECANCELED, netvsc_device::name, NETVSC_BASE_XID, NETVSC_TX_BASE_XRID, netvsc_device::rndis, rndis_tx_complete_err(), vmbus_send_cancellation(), and netvsc_device::vmdev.

Referenced by netvsc_close().

◆ netvsc_create_ring()

int netvsc_create_ring ( struct netvsc_device *netvsc __unused,
struct netvsc_ring * ring )
static

Create descriptor ring.

Parameters
netvscNetVSC device
ringDescriptor ring
Return values
rcReturn status code

Definition at line 562 of file netvsc.c.

563 {
564 unsigned int i;
565
566 /* Initialise buffer ID ring */
567 for ( i = 0 ; i < ring->count ; i++ ) {
568 ring->ids[i] = i;
569 assert ( ring->iobufs[i] == NULL );
570 }
571 ring->id_prod = 0;
572 ring->id_cons = 0;
573
574 return 0;
575}

References __unused, assert, netvsc_ring::count, netvsc_ring::id_cons, netvsc_ring::id_prod, netvsc_ring::ids, netvsc_ring::iobufs, and NULL.

Referenced by netvsc_open().

◆ netvsc_destroy_ring()

void netvsc_destroy_ring ( struct netvsc_device * netvsc,
struct netvsc_ring * ring,
void(* discard )(struct netvsc_device *, struct io_buffer *, unsigned int) )
static

Destroy descriptor ring.

Parameters
netvscNetVSC device
ringDescriptor ring
discardMethod used to discard outstanding buffer, or NULL

Definition at line 584 of file netvsc.c.

588 {
589 struct io_buffer *iobuf;
590 unsigned int i;
591
592 /* Flush any outstanding buffers */
593 for ( i = 0 ; i < ring->count ; i++ ) {
594 iobuf = ring->iobufs[i];
595 if ( ! iobuf )
596 continue;
597 ring->iobufs[i] = NULL;
598 ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = i;
599 if ( discard )
600 discard ( netvsc, iobuf, i );
601 }
602
603 /* Sanity check */
604 assert ( netvsc_ring_is_empty ( ring ) );
605}

References assert, netvsc_ring::count, netvsc_ring::id_cons, netvsc_ring::ids, netvsc_ring::iobufs, and NULL.

Referenced by netvsc_close(), and netvsc_open().

◆ netvsc_buffer_copy()

int netvsc_buffer_copy ( struct vmbus_xfer_pages * pages,
void * data,
size_t offset,
size_t len )
static

Copy data from data buffer.

Parameters
pagesTransfer page set
dataData buffer
offsetOffset within page set
lenLength within page set
Return values
rcReturn status code

Definition at line 616 of file netvsc.c.

617 {
618 struct netvsc_buffer *buffer =
620
621 /* Sanity check */
622 if ( ( offset > buffer->len ) || ( len > ( buffer->len - offset ) ) )
623 return -ERANGE;
624
625 /* Copy data from buffer */
626 memcpy ( data, ( buffer->data + offset ), len );
627
628 return 0;
629}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define ERANGE
Result too large.
Definition errno.h:640
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A NetVSC data buffer.
Definition netvsc.h:294
struct vmbus_xfer_pages pages
Transfer page set.
Definition netvsc.h:296

References buffer, container_of, data, ERANGE, len, memcpy(), offset, and netvsc_buffer::pages.

◆ netvsc_create_buffer()

int netvsc_create_buffer ( struct netvsc_device * netvsc,
struct netvsc_buffer * buffer )
static

Create data buffer.

Parameters
netvscNetVSC device
bufferData buffer
Return values
rcReturn status code

Definition at line 643 of file netvsc.c.

644 {
645 struct vmbus_device *vmdev = netvsc->vmdev;
646 int gpadl;
647 int rc;
648
649 /* Allocate receive buffer */
650 buffer->data = umalloc ( buffer->len );
651 if ( ! buffer->data ) {
652 DBGC ( netvsc, "NETVSC %s could not allocate %zd-byte buffer\n",
653 netvsc->name, buffer->len );
654 rc = -ENOMEM;
655 goto err_alloc;
656 }
657
658 /* Establish GPA descriptor list */
659 gpadl = vmbus_establish_gpadl ( vmdev, buffer->data, buffer->len );
660 if ( gpadl < 0 ) {
661 rc = gpadl;
662 DBGC ( netvsc, "NETVSC %s could not establish GPADL: %s\n",
663 netvsc->name, strerror ( rc ) );
664 goto err_establish_gpadl;
665 }
666 buffer->gpadl = gpadl;
667
668 /* Register transfer page set */
669 if ( ( rc = vmbus_register_pages ( vmdev, &buffer->pages ) ) != 0 ) {
670 DBGC ( netvsc, "NETVSC %s could not register transfer pages: "
671 "%s\n", netvsc->name, strerror ( rc ) );
672 goto err_register_pages;
673 }
674
675 return 0;
676
677 vmbus_unregister_pages ( vmdev, &buffer->pages );
678 err_register_pages:
679 vmbus_gpadl_teardown ( vmdev, gpadl );
680 err_establish_gpadl:
681 ufree ( buffer->data );
682 err_alloc:
683 return rc;
684}
#define ENOMEM
Not enough space.
Definition errno.h:535
static __always_inline void * umalloc(size_t size)
Allocate external memory.
Definition umalloc.h:57
static __always_inline void ufree(void *ptr)
Free external memory.
Definition umalloc.h:68
uint32_t gpadl
GPADL ID.
Definition netvsc.h:3
int vmbus_establish_gpadl(struct vmbus_device *vmdev, void *data, size_t len)
Establish GPA descriptor list.
Definition vmbus.c:276
int vmbus_gpadl_teardown(struct vmbus_device *vmdev, unsigned int gpadl)
Tear down GPA descriptor list.
Definition vmbus.c:347
static void vmbus_unregister_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Unregister transfer page set.
Definition vmbus.h:615
static int vmbus_register_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Register transfer page set.
Definition vmbus.h:601

References buffer, DBGC, ENOMEM, gpadl, netvsc_device::name, rc, strerror(), ufree(), umalloc(), vmbus_establish_gpadl(), vmbus_gpadl_teardown(), vmbus_register_pages(), vmbus_unregister_pages(), and netvsc_device::vmdev.

Referenced by netvsc_open().

◆ netvsc_destroy_buffer()

void netvsc_destroy_buffer ( struct netvsc_device * netvsc,
struct netvsc_buffer * buffer )
static

Destroy data buffer.

Parameters
netvscNetVSC device
bufferData buffer

Definition at line 692 of file netvsc.c.

693 {
694 struct vmbus_device *vmdev = netvsc->vmdev;
695 int rc;
696
697 /* Unregister transfer pages */
698 vmbus_unregister_pages ( vmdev, &buffer->pages );
699
700 /* Tear down GPA descriptor list */
701 if ( ( rc = vmbus_gpadl_teardown ( vmdev, buffer->gpadl ) ) != 0 ) {
702 DBGC ( netvsc, "NETVSC %s could not tear down GPADL: %s\n",
703 netvsc->name, strerror ( rc ) );
704 /* Death is imminent. The host may well continue to
705 * write to the data buffer. The best we can do is
706 * leak memory for now and hope that the host doesn't
707 * write to this region after we load an OS.
708 */
709 return;
710 }
711
712 /* Free buffer */
713 ufree ( buffer->data );
714}
VMBus "GPADL teardown" message.
Definition vmbus.h:193

References buffer, DBGC, netvsc_device::name, rc, strerror(), ufree(), vmbus_unregister_pages(), and netvsc_device::vmdev.

Referenced by netvsc_close(), and netvsc_open().

◆ netvsc_open()

int netvsc_open ( struct rndis_device * rndis)
static

Open device.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Definition at line 722 of file netvsc.c.

722 {
723 struct netvsc_device *netvsc = rndis->priv;
724 int rc;
725
726 /* Initialise receive buffer */
727 if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
728 goto err_create_rx;
729
730 /* Open channel */
731 if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
732 PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
733 DBGC ( netvsc, "NETVSC %s could not open VMBus: %s\n",
734 netvsc->name, strerror ( rc ) );
735 goto err_vmbus_open;
736 }
737
738 /* Initialise communication with NetVSP */
739 if ( ( rc = netvsc_initialise ( netvsc ) ) != 0 )
740 goto err_initialise;
741 if ( ( rc = netvsc_ndis_version ( netvsc ) ) != 0 )
742 goto err_ndis_version;
743
744 /* Initialise transmit ring */
745 if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
746 goto err_create_tx;
747
748 /* Establish receive buffer */
749 if ( ( rc = netvsc_establish_buffer ( netvsc, &netvsc->rx ) ) != 0 )
750 goto err_establish_rx;
751
752 return 0;
753
754 netvsc_revoke_buffer ( netvsc, &netvsc->rx );
755 err_establish_rx:
756 netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
757 err_create_tx:
758 err_ndis_version:
759 err_initialise:
760 vmbus_close ( netvsc->vmdev );
761 err_vmbus_open:
762 netvsc_destroy_buffer ( netvsc, &netvsc->rx );
763 err_create_rx:
764 return rc;
765}
#define PAGE_SIZE
Page size.
Definition io.h:28
static int netvsc_revoke_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Revoke data buffer.
Definition netvsc.c:258
static int netvsc_establish_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Establish data buffer.
Definition netvsc.c:197
static void netvsc_destroy_ring(struct netvsc_device *netvsc, struct netvsc_ring *ring, void(*discard)(struct netvsc_device *, struct io_buffer *, unsigned int))
Destroy descriptor ring.
Definition netvsc.c:584
static int netvsc_ndis_version(struct netvsc_device *netvsc)
Set NDIS version.
Definition netvsc.c:169
static int netvsc_create_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Create data buffer.
Definition netvsc.c:643
static struct vmbus_channel_operations netvsc_channel_operations
VMBus channel operations.
Definition netvsc.c:446
static int netvsc_create_ring(struct netvsc_device *netvsc __unused, struct netvsc_ring *ring)
Create descriptor ring.
Definition netvsc.c:562
static int netvsc_initialise(struct netvsc_device *netvsc)
Initialise communication.
Definition netvsc.c:108
static void netvsc_destroy_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Destroy data buffer.
Definition netvsc.c:692
#define NETVSC_MTU
Maximum supported NetVSC message length.
Definition netvsc.h:13
struct netvsc_buffer rx
Receive buffer.
Definition netvsc.h:357
void vmbus_close(struct vmbus_device *vmdev)
Close VMBus channel.
Definition vmbus.c:524
int vmbus_open(struct vmbus_device *vmdev, struct vmbus_channel_operations *op, size_t out_len, size_t in_len, size_t mtu)
Open VMBus channel.
Definition vmbus.c:403

References DBGC, netvsc_device::name, netvsc_channel_operations, netvsc_create_buffer(), netvsc_create_ring(), netvsc_destroy_buffer(), netvsc_destroy_ring(), netvsc_establish_buffer(), netvsc_initialise(), NETVSC_MTU, netvsc_ndis_version(), netvsc_revoke_buffer(), NULL, PAGE_SIZE, rndis_device::priv, rc, netvsc_device::rndis, netvsc_device::rx, strerror(), netvsc_device::tx, vmbus_close(), vmbus_open(), and netvsc_device::vmdev.

◆ netvsc_close()

void netvsc_close ( struct rndis_device * rndis)
static

Close device.

Parameters
rndisRNDIS device

Definition at line 772 of file netvsc.c.

772 {
773 struct netvsc_device *netvsc = rndis->priv;
774
775 /* Revoke receive buffer */
776 netvsc_revoke_buffer ( netvsc, &netvsc->rx );
777
778 /* Destroy transmit ring */
779 netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
780
781 /* Close channel */
782 vmbus_close ( netvsc->vmdev );
783
784 /* Destroy receive buffer */
785 netvsc_destroy_buffer ( netvsc, &netvsc->rx );
786}
static void netvsc_cancel_transmit(struct netvsc_device *netvsc, struct io_buffer *iobuf, unsigned int tx_id)
Cancel transmission.
Definition netvsc.c:538

References netvsc_cancel_transmit(), netvsc_destroy_buffer(), netvsc_destroy_ring(), netvsc_revoke_buffer(), rndis_device::priv, netvsc_device::rndis, netvsc_device::rx, netvsc_device::tx, vmbus_close(), and netvsc_device::vmdev.

◆ netvsc_probe()

int netvsc_probe ( struct vmbus_device * vmdev)
static

Probe device.

Parameters
vmdevVMBus device
Return values
rcReturn status code

Definition at line 802 of file netvsc.c.

802 {
803 struct netvsc_device *netvsc;
804 struct rndis_device *rndis;
805 int rc;
806
807 /* Allocate and initialise structure */
808 rndis = alloc_rndis ( sizeof ( *netvsc ) );
809 if ( ! rndis ) {
810 rc = -ENOMEM;
811 goto err_alloc;
812 }
813 rndis_init ( rndis, &netvsc_operations );
814 rndis->netdev->dev = &vmdev->dev;
815 netvsc = rndis->priv;
816 netvsc->vmdev = vmdev;
817 netvsc->rndis = rndis;
818 netvsc->name = vmdev->dev.name;
819 netvsc_init_ring ( &netvsc->tx, NETVSC_TX_NUM_DESC,
820 netvsc->tx_iobufs, netvsc->tx_ids );
821 netvsc_init_buffer ( &netvsc->rx, NETVSC_RX_BUF_PAGESET,
826 vmbus_set_drvdata ( vmdev, rndis );
827
828 /* Register RNDIS device */
829 if ( ( rc = register_rndis ( rndis ) ) != 0 ) {
830 DBGC ( netvsc, "NETVSC %s could not register: %s\n",
831 netvsc->name, strerror ( rc ) );
832 goto err_register;
833 }
834
835 return 0;
836
837 unregister_rndis ( rndis );
838 err_register:
839 free_rndis ( rndis );
840 err_alloc:
841 return rc;
842}
static struct rndis_operations netvsc_operations
RNDIS operations.
Definition netvsc.c:789
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
Transfer page set operations.
Definition netvsc.c:632
#define NETVSC_RX_REVOKE_MSG
NetVSC revoke receive data buffer message.
Definition netvsc.h:142
@ NETVSC_RX_REVOKE_XRID
Revoke receive buffer.
Definition netvsc.h:58
#define NETVSC_RX_BUF_LEN
RX data buffer length.
Definition netvsc.h:39
#define NETVSC_RX_ESTABLISH_MSG
NetVSC establish receive data buffer message.
Definition netvsc.h:136
#define NETVSC_RX_BUF_PAGESET
RX data buffer page set ID.
Definition netvsc.h:33
int register_rndis(struct rndis_device *rndis)
Register RNDIS device.
Definition rndis.c:1027
void unregister_rndis(struct rndis_device *rndis)
Unregister RNDIS device.
Definition rndis.c:1055
void free_rndis(struct rndis_device *rndis)
Free RNDIS device.
Definition rndis.c:1067
struct rndis_device * alloc_rndis(size_t priv_len)
Allocate RNDIS device.
Definition rndis.c:1001
static void rndis_init(struct rndis_device *rndis, struct rndis_operations *op)
Initialise an RNDIS device.
Definition rndis.h:340
char name[40]
Name.
Definition device.h:79
struct device * dev
Underlying hardware device.
Definition netdevice.h:365
struct io_buffer * tx_iobufs[NETVSC_TX_NUM_DESC]
Transmit I/O buffers.
Definition netvsc.h:354
uint8_t tx_ids[NETVSC_TX_NUM_DESC]
Transmit buffer IDs.
Definition netvsc.h:352
struct net_device * netdev
Network device.
Definition rndis.h:320
struct device dev
Generic iPXE device.
Definition vmbus.h:477
static void vmbus_set_drvdata(struct vmbus_device *vmdev, void *priv)
Set VMBus device driver-private data.
Definition vmbus.h:559

References alloc_rndis(), DBGC, net_device::dev, vmbus_device::dev, ENOMEM, free_rndis(), device::name, netvsc_device::name, rndis_device::netdev, netvsc_operations, NETVSC_RX_BUF_LEN, NETVSC_RX_BUF_PAGESET, NETVSC_RX_ESTABLISH_MSG, NETVSC_RX_ESTABLISH_XRID, NETVSC_RX_REVOKE_MSG, NETVSC_RX_REVOKE_XRID, NETVSC_TX_NUM_DESC, netvsc_xfer_pages_operations, rndis_device::priv, rc, register_rndis(), netvsc_device::rndis, rndis_init(), netvsc_device::rx, strerror(), netvsc_device::tx, netvsc_device::tx_ids, netvsc_device::tx_iobufs, unregister_rndis(), vmbus_set_drvdata(), and netvsc_device::vmdev.

◆ netvsc_reset()

int netvsc_reset ( struct vmbus_device * vmdev)
static

Reset device.

Parameters
vmdevVMBus device
Return values
rcReturn status code

Definition at line 850 of file netvsc.c.

850 {
851 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
852 struct netvsc_device *netvsc = rndis->priv;
853 struct net_device *netdev = rndis->netdev;
854 int rc;
855
856 /* A closed device holds no NetVSC (or RNDIS) state, so there
857 * is nothing to reset.
858 */
859 if ( ! netdev_is_open ( netdev ) )
860 return 0;
861
862 /* Close and reopen device to reset any stale state */
864 if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
865 DBGC ( netvsc, "NETVSC %s could not reopen: %s\n",
866 netvsc->name, strerror ( rc ) );
867 return rc;
868 }
869
870 return 0;
871}
static struct net_device * netdev
Definition gdbudp.c:53
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
void netdev_close(struct net_device *netdev)
Close network device.
Definition netdevice.c:896
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
A network device.
Definition netdevice.h:353

References DBGC, netvsc_device::name, netdev, rndis_device::netdev, netdev_close(), netdev_is_open(), netdev_open(), rndis_device::priv, rc, netvsc_device::rndis, strerror(), and vmbus_get_drvdata().

◆ netvsc_remove()

void netvsc_remove ( struct vmbus_device * vmdev)
static

Remove device.

Parameters
vmdevVMBus device

Definition at line 878 of file netvsc.c.

878 {
879 struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
880
881 /* Unregister RNDIS device */
882 unregister_rndis ( rndis );
883
884 /* Free RNDIS device */
885 free_rndis ( rndis );
886}

References free_rndis(), unregister_rndis(), and vmbus_get_drvdata().

◆ VMBUS_ROM()

VMBUS_ROM ( "netvsc" ,
"Hyper-V NetVSC RNDIS virtual NIC"  )

Variable Documentation

◆ netvsc_channel_operations

struct vmbus_channel_operations netvsc_channel_operations
static
Initial value:
= {
.recv_control = netvsc_recv_control,
.recv_data = netvsc_recv_data,
.recv_completion = netvsc_recv_completion,
.recv_cancellation = netvsc_recv_cancellation,
}
static int netvsc_recv_completion(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Handle received completion packet.
Definition netvsc.c:376
static int netvsc_recv_cancellation(struct vmbus_device *vmdev, uint64_t xid)
Handle received cancellation packet.
Definition netvsc.c:435
static int netvsc_recv_data(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct list_head *list)
Handle received data packet.
Definition netvsc.c:318
static int netvsc_recv_control(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Handle received control packet.
Definition netvsc.c:297

VMBus channel operations.

Definition at line 446 of file netvsc.c.

446 {
447 .recv_control = netvsc_recv_control,
448 .recv_data = netvsc_recv_data,
449 .recv_completion = netvsc_recv_completion,
450 .recv_cancellation = netvsc_recv_cancellation,
451};

Referenced by netvsc_open().

◆ netvsc_xfer_pages_operations

struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
static
Initial value:
= {
}
static int netvsc_buffer_copy(struct vmbus_xfer_pages *pages, void *data, size_t offset, size_t len)
Copy data from data buffer.
Definition netvsc.c:616

Transfer page set operations.

Definition at line 632 of file netvsc.c.

632 {
633 .copy = netvsc_buffer_copy,
634};

Referenced by netvsc_probe().

◆ netvsc_operations

struct rndis_operations netvsc_operations
static
Initial value:
= {
.open = netvsc_open,
.close = netvsc_close,
.transmit = netvsc_transmit,
.poll = netvsc_poll,
}
static int netvsc_transmit(struct rndis_device *rndis, struct io_buffer *iobuf)
Transmit packet.
Definition netvsc.c:477
static void netvsc_poll(struct rndis_device *rndis)
Poll for completed and received packets.
Definition netvsc.c:458
static int netvsc_open(struct rndis_device *rndis)
Open device.
Definition netvsc.c:722
static void netvsc_close(struct rndis_device *rndis)
Close device.
Definition netvsc.c:772

RNDIS operations.

Definition at line 789 of file netvsc.c.

789 {
790 .open = netvsc_open,
791 .close = netvsc_close,
792 .transmit = netvsc_transmit,
793 .poll = netvsc_poll,
794};

Referenced by netvsc_probe().

◆ __vmbus_driver

struct vmbus_driver netvsc_driver __vmbus_driver
Initial value:
= {
.name = "netvsc",
.type = VMBUS_TYPE ( 0xf8615163, 0xdf3e, 0x46c5, 0x913f,
0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e ),
.probe = netvsc_probe,
.reset = netvsc_reset,
.remove = netvsc_remove,
}
static int netvsc_reset(struct vmbus_device *vmdev)
Reset device.
Definition netvsc.c:850
static void netvsc_remove(struct vmbus_device *vmdev)
Remove device.
Definition netvsc.c:878
static int netvsc_probe(struct vmbus_device *vmdev)
Probe device.
Definition netvsc.c:802
#define VMBUS_TYPE(a, b, c, d, e0, e1, e2, e3, e4, e5)
Construct VMBus type.
Definition vmbus.h:574

NetVSC driver.

Definition at line 889 of file netvsc.c.

889 {
890 .name = "netvsc",
891 .type = VMBUS_TYPE ( 0xf8615163, 0xdf3e, 0x46c5, 0x913f,
892 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e ),
893 .probe = netvsc_probe,
894 .reset = netvsc_reset,
895 .remove = netvsc_remove,
896};