|
| | 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") |
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.
| 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
-
| netvsc | NetVSC device |
| xrid | Relative transaction ID |
| data | Data |
| len | Length of data |
- Return values
-
Definition at line 53 of file netvsc.c.
54 {
56 unsigned int i;
58
59
61 DBGC ( netvsc,
"NETVSC %s could not send control message: %s\n",
64 }
65
66
68
69
71
72
75
76
78
79
81 }
82
83 DBGC ( netvsc,
"NETVSC %s timed out waiting for XRID %d\n",
87}
struct arbelprm_rc_send_wqe rc
unsigned long long uint64_t
uint8_t data[48]
Additional event data.
#define ETIMEDOUT
Connection timed out.
#define NETVSC_BASE_XID
Base transaction ID.
#define NETVSC_MAX_WAIT_MS
Maximum time to wait for a transaction to complete.
char * strerror(int errno)
Retrieve string representation of error number.
int wait_rc
Return status code for current blocking transaction.
struct vmbus_device * vmdev
VMBus device.
unsigned int wait_xrid
Relative transaction ID for current blocking transaction.
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
int vmbus_send_control(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send control packet via ring buffer.
void vmbus_dump_channel(struct vmbus_device *vmdev)
Dump channel status (for debugging)
int vmbus_poll(struct vmbus_device *vmdev)
Poll ring buffer.
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().
Initialise communication.
- Parameters
-
- Return values
-
Definition at line 108 of file netvsc.c.
108 {
111
112
117
118
120 sizeof (
msg ) ) ) != 0 ) {
121 DBGC ( netvsc,
"NETVSC %s could not initialise: %s\n",
124 }
125
126 return 0;
127}
#define cpu_to_le32(value)
void * memset(void *dest, int character, size_t len) __nonnull
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
static int netvsc_control(struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
Send control message and wait for completion.
@ NETVSC_INIT_XRID
Initialisation.
#define NETVSC_INIT_MSG
NetVSC initialisation message.
#define NETVSC_VERSION_1
Oldest known NetVSC protocol version.
NetVSC initialisation message.
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().
Handle initialisation completion.
- Parameters
-
| netvsc | NetVSC device |
| data | Data |
| len | Length of data |
- Return values
-
Definition at line 138 of file netvsc.c.
139 {
141
142
143 if (
len <
sizeof ( *cmplt ) ) {
144 DBGC ( netvsc,
"NETVSC %s underlength initialisation "
145 "completion (%zd bytes)\n", netvsc->
name,
len );
147 }
149 DBGC ( netvsc,
"NETVSC %s unexpected initialisation completion "
150 "type %d\n", netvsc->
name,
153 }
155 DBGC ( netvsc,
"NETVSC %s initialisation failure status %d\n",
158 }
159
160 return 0;
161}
#define EINVAL
Invalid argument.
#define EPROTO
Protocol error.
#define le32_to_cpu(value)
#define NETVSC_INIT_CMPLT
NetVSC initialisation completion.
NetVSC initialisation completion.
struct netvsc_header header
Message header.
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().
| int netvsc_rx_established_buffer |
( |
struct netvsc_device * | netvsc, |
|
|
const void * | data, |
|
|
size_t | len ) |
|
static |
Handle establish receive data buffer completion.
- Parameters
-
| netvsc | NetVSC device |
| data | Data |
| len | Length of data |
- Return values
-
Definition at line 227 of file netvsc.c.
228 {
230
231
232 if (
len <
sizeof ( *cmplt ) ) {
233 DBGC ( netvsc,
"NETVSC %s underlength buffer completion (%zd "
234 "bytes)\n", netvsc->
name,
len );
236 }
238 DBGC ( netvsc,
"NETVSC %s unexpected buffer completion type "
241 }
243 DBGC ( netvsc,
"NETVSC %s buffer failure status %d\n",
246 }
247
248 return 0;
249}
#define NETVSC_RX_ESTABLISH_CMPLT
NetVSC establish receive data buffer completion.
NetVSC establish receive data buffer completion.
struct netvsc_header header
Message header.
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().
Handle received data packet.
- Parameters
-
| vmdev | VMBus device |
| xid | Transaction ID |
| data | Data |
| len | Length of data |
| list | List of I/O buffers |
- Return values
-
Definition at line 318 of file netvsc.c.
320 {
327
328
329 if (
len <
sizeof ( *
msg ) ) {
330 DBGC ( netvsc,
"NETVSC %s received underlength RNDIS packet "
331 "(%zd bytes)\n", netvsc->
name,
len );
333 goto err_sanity;
334 }
336 DBGC ( netvsc,
"NETVSC %s received unexpected RNDIS packet "
337 "type %d\n", netvsc->
name,
340 goto err_sanity;
341 }
342
343
345 DBGC ( netvsc,
"NETVSC %s could not send completion: %s\n",
347 goto err_completion;
348 }
349
350
354 }
355
356 return 0;
357
358 err_completion:
359 err_sanity:
363 }
365}
#define NULL
NULL pointer (VOID *)
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
#define iob_disown(iobuf)
Disown an I/O buffer.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
#define list_del(list)
Delete an entry from a list.
#define NETVSC_RNDIS_MSG
NetVSC RNDIS message.
void rndis_rx(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive packet from underlying transport layer.
struct list_head list
List of which this buffer is a member.
int vmbus_send_completion(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send completion packet via ring buffer.
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().
Handle received completion packet.
- Parameters
-
| vmdev | VMBus device |
| xid | Transaction ID |
| data | Data |
| len | Length of data |
- Return values
-
Definition at line 376 of file netvsc.c.
377 {
382 const void *
data,
size_t len );
384 unsigned int tx_id;
386
387
391
392
395 ( netvsc->
tx.
count - 1 ) ] = tx_id;
396
397
399 return 0;
400 }
401
402
407 }
else if ( ( netvsc->
wait_xrid != 0 ) &&
410 } else {
411 DBGC ( netvsc,
"NETVSC %s received unexpected completion "
412 "(%08llx)\n", netvsc->
name, xid );
414 }
415
416
418
419
423 }
424
426}
pseudo_bit_t completion[0x00001]
#define EPIPE
Broken pipe.
static int netvsc_initialised(struct netvsc_device *netvsc, const void *data, size_t len)
Handle initialisation completion.
static int netvsc_completed(struct netvsc_device *netvsc __unused, const void *data __unused, size_t len __unused)
Handle generic completion.
static int netvsc_rx_established_buffer(struct netvsc_device *netvsc, const void *data, size_t len)
Handle establish receive data buffer completion.
@ NETVSC_RX_ESTABLISH_XRID
Establish receive buffer.
@ NETVSC_TX_BASE_XRID
Transmit descriptors (one per transmit buffer ID)
#define NETVSC_TX_NUM_DESC
Number of transmit ring entries.
static void rndis_tx_complete(struct rndis_device *rndis, struct io_buffer *iobuf)
Complete message transmission.
struct netvsc_ring tx
Transmit ring.
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
unsigned int id_cons
Buffer ID consumer counter.
uint8_t * ids
Buffer ID ring.
unsigned int count
Number of descriptors.
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.
Transmit packet.
- Parameters
-
| rndis | RNDIS device |
| iobuf | I/O buffer |
- Return values
-
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 {
482 unsigned int tx_id;
483 unsigned int xrid;
486
487
488
489
490
491
492 if ( netvsc_is_obsolete ( netvsc ) )
494
495
498
499
500 if ( netvsc_ring_is_full ( &netvsc->
tx ) )
502
503
508
509
515
516
518 iobuf ) ) != 0 ) {
519 DBGC ( netvsc,
"NETVSC %s could not send RNDIS message: %s\n",
522 }
523
524
527
528 return 0;
529}
#define assert(condition)
Assert a condition at run-time.
struct ena_llq_option header
Header locations.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define NETVSC_RNDIS_CONTROL
RNDIS control channel (for all other RNDIS messages)
#define NETVSC_RNDIS_NO_BUFFER
"No buffer used" index
#define NETVSC_RNDIS_DATA
RNDIS data channel (for RNDIS_PACKET_MSG only)
int rndis_tx_defer(struct rndis_device *rndis, struct io_buffer *iobuf)
Defer transmitted packet.
#define RNDIS_PACKET_MSG
RNDIS packet message.
void * data
Start of data.
unsigned int id_prod
Buffer ID producer counter.
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.
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.
Create data buffer.
- Parameters
-
| netvsc | NetVSC device |
| buffer | Data buffer |
- Return values
-
Definition at line 643 of file netvsc.c.
644 {
648
649
652 DBGC ( netvsc,
"NETVSC %s could not allocate %zd-byte buffer\n",
655 goto err_alloc;
656 }
657
658
662 DBGC ( netvsc,
"NETVSC %s could not establish GPADL: %s\n",
664 goto err_establish_gpadl;
665 }
667
668
670 DBGC ( netvsc,
"NETVSC %s could not register transfer pages: "
672 goto err_register_pages;
673 }
674
675 return 0;
676
678 err_register_pages:
680 err_establish_gpadl:
682 err_alloc:
684}
#define ENOMEM
Not enough space.
static __always_inline void * umalloc(size_t size)
Allocate external memory.
static __always_inline void ufree(void *ptr)
Free external memory.
int vmbus_establish_gpadl(struct vmbus_device *vmdev, void *data, size_t len)
Establish GPA descriptor list.
int vmbus_gpadl_teardown(struct vmbus_device *vmdev, unsigned int gpadl)
Tear down GPA descriptor list.
static void vmbus_unregister_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Unregister transfer page set.
static int vmbus_register_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Register transfer page set.
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().
Open device.
- Parameters
-
- Return values
-
Definition at line 722 of file netvsc.c.
722 {
725
726
728 goto err_create_rx;
729
730
733 DBGC ( netvsc,
"NETVSC %s could not open VMBus: %s\n",
735 goto err_vmbus_open;
736 }
737
738
740 goto err_initialise;
742 goto err_ndis_version;
743
744
746 goto err_create_tx;
747
748
750 goto err_establish_rx;
751
752 return 0;
753
755 err_establish_rx:
757 err_create_tx:
758 err_ndis_version:
759 err_initialise:
761 err_vmbus_open:
763 err_create_rx:
765}
#define PAGE_SIZE
Page size.
static int netvsc_revoke_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Revoke data buffer.
static int netvsc_establish_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Establish data buffer.
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_ndis_version(struct netvsc_device *netvsc)
Set NDIS version.
static int netvsc_create_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Create data buffer.
static struct vmbus_channel_operations netvsc_channel_operations
VMBus channel operations.
static int netvsc_create_ring(struct netvsc_device *netvsc __unused, struct netvsc_ring *ring)
Create descriptor ring.
static int netvsc_initialise(struct netvsc_device *netvsc)
Initialise communication.
static void netvsc_destroy_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Destroy data buffer.
#define NETVSC_MTU
Maximum supported NetVSC message length.
struct netvsc_buffer rx
Receive buffer.
void vmbus_close(struct vmbus_device *vmdev)
Close VMBus channel.
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.
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.
Probe device.
- Parameters
-
- Return values
-
Definition at line 802 of file netvsc.c.
802 {
806
807
809 if ( ! rndis ) {
811 goto err_alloc;
812 }
815 netvsc = rndis->
priv;
816 netvsc->
vmdev = vmdev;
817 netvsc->
rndis = rndis;
827
828
830 DBGC ( netvsc,
"NETVSC %s could not register: %s\n",
832 goto err_register;
833 }
834
835 return 0;
836
838 err_register:
840 err_alloc:
842}
static struct rndis_operations netvsc_operations
RNDIS operations.
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
Transfer page set operations.
#define NETVSC_RX_REVOKE_MSG
NetVSC revoke receive data buffer message.
@ NETVSC_RX_REVOKE_XRID
Revoke receive buffer.
#define NETVSC_RX_BUF_LEN
RX data buffer length.
#define NETVSC_RX_ESTABLISH_MSG
NetVSC establish receive data buffer message.
#define NETVSC_RX_BUF_PAGESET
RX data buffer page set ID.
int register_rndis(struct rndis_device *rndis)
Register RNDIS device.
void unregister_rndis(struct rndis_device *rndis)
Unregister RNDIS device.
void free_rndis(struct rndis_device *rndis)
Free RNDIS device.
struct rndis_device * alloc_rndis(size_t priv_len)
Allocate RNDIS device.
static void rndis_init(struct rndis_device *rndis, struct rndis_operations *op)
Initialise an RNDIS device.
struct device * dev
Underlying hardware device.
struct io_buffer * tx_iobufs[NETVSC_TX_NUM_DESC]
Transmit I/O buffers.
uint8_t tx_ids[NETVSC_TX_NUM_DESC]
Transmit buffer IDs.
struct net_device * netdev
Network device.
struct device dev
Generic iPXE device.
static void vmbus_set_drvdata(struct vmbus_device *vmdev, void *priv)
Set VMBus device driver-private data.
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.