iPXE
rndis.c File Reference

Remote Network Driver Interface Specification. More...

#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/device.h>
#include <ipxe/rndis.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static struct io_bufferrndis_alloc_iob (size_t len)
 Allocate I/O buffer.
static int rndis_wait (struct rndis_device *rndis, unsigned int wait_id)
 Wait for completion.
static int rndis_tx_message (struct rndis_device *rndis, struct io_buffer *iobuf, unsigned int type)
 Transmit message.
void rndis_tx_complete_err (struct rndis_device *rndis, struct io_buffer *iobuf, int rc)
 Complete message transmission.
static int rndis_tx_data (struct rndis_device *rndis, struct io_buffer *iobuf)
 Transmit data packet.
int rndis_tx_defer (struct rndis_device *rndis, struct io_buffer *iobuf)
 Defer transmitted packet.
static void rndis_rx_data (struct rndis_device *rndis, struct io_buffer *iobuf)
 Receive data packet.
static int rndis_tx_initialise (struct rndis_device *rndis, unsigned int id)
 Transmit initialisation message.
static void rndis_rx_initialise (struct rndis_device *rndis, struct io_buffer *iobuf)
 Receive initialisation completion.
static int rndis_initialise (struct rndis_device *rndis)
 Initialise RNDIS.
static int rndis_tx_halt (struct rndis_device *rndis)
 Transmit halt message.
static int rndis_halt (struct rndis_device *rndis)
 Halt RNDIS.
static int rndis_tx_oid (struct rndis_device *rndis, unsigned int oid, const void *data, size_t len)
 Transmit OID message.
static void rndis_rx_query_oid (struct rndis_device *rndis, struct io_buffer *iobuf)
 Receive query OID completion.
static void rndis_rx_set_oid (struct rndis_device *rndis, struct io_buffer *iobuf)
 Receive set OID completion.
static int rndis_oid (struct rndis_device *rndis, unsigned int oid, const void *data, size_t len)
 Query or set OID.
static int rndis_describe (struct rndis_device *rndis)
 Describe RNDIS device.
static void rndis_rx_status (struct rndis_device *rndis, struct io_buffer *iobuf)
 Receive indicate status message.
static void rndis_rx_message (struct rndis_device *rndis, struct io_buffer *iobuf, unsigned int type)
 Receive RNDIS message.
void rndis_rx (struct rndis_device *rndis, struct io_buffer *iobuf)
 Receive packet from underlying transport layer.
void rndis_rx_err (struct rndis_device *rndis, struct io_buffer *iobuf, int rc)
 Discard packet from underlying transport layer.
static int rndis_filter (struct rndis_device *rndis, unsigned int filter)
 Set receive filter.
static int rndis_open (struct net_device *netdev)
 Open network device.
static void rndis_close (struct net_device *netdev)
 Close network device.
static int rndis_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void rndis_poll (struct net_device *netdev)
 Poll for completed and received packets.
struct rndis_devicealloc_rndis (size_t priv_len)
 Allocate RNDIS device.
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.

Variables

static struct net_device_operations rndis_operations
 Network device operations.

Detailed Description

Remote Network Driver Interface Specification.

Definition in file rndis.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ rndis_alloc_iob()

struct io_buffer * rndis_alloc_iob ( size_t len)
static

Allocate I/O buffer.

Parameters
lenLength
Return values
iobufI/O buffer, or NULL

Definition at line 49 of file rndis.c.

49 {
50 struct rndis_header *header;
51 struct io_buffer *iobuf;
52
53 /* Allocate I/O buffer and reserve space */
54 iobuf = alloc_iob ( sizeof ( *header ) + len );
55 if ( iobuf )
56 iob_reserve ( iobuf, sizeof ( *header ) );
57
58 return iobuf;
59}
ring len
Length.
Definition dwmac.h:226
struct ena_llq_option header
Header locations.
Definition ena.h:5
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
A persistent I/O buffer.
Definition iobuf.h:38
RNDIS message header.
Definition rndis.h:24

References alloc_iob(), header, iob_reserve, and len.

Referenced by rndis_tx_halt(), rndis_tx_initialise(), and rndis_tx_oid().

◆ rndis_wait()

int rndis_wait ( struct rndis_device * rndis,
unsigned int wait_id )
static

Wait for completion.

Parameters
rndisRNDIS device
wait_idRequest ID
Return values
rcReturn status code

Definition at line 68 of file rndis.c.

68 {
69 unsigned int i;
70
71 /* Record query ID */
72 rndis->wait_id = wait_id;
73
74 /* Wait for operation to complete */
75 for ( i = 0 ; i < RNDIS_MAX_WAIT_MS ; i++ ) {
76
77 /* Check for completion */
78 if ( ! rndis->wait_id )
79 return rndis->wait_rc;
80
81 /* Poll RNDIS device */
82 rndis->op->poll ( rndis );
83
84 /* Delay for 1ms */
85 mdelay ( 1 );
86 }
87
88 DBGC ( rndis, "RNDIS %s timed out waiting for ID %#08x\n",
89 rndis->name, wait_id );
90 return -ETIMEDOUT;
91}
#define DBGC(...)
Definition compiler.h:505
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define RNDIS_MAX_WAIT_MS
Maximum time to wait for a transaction to complete.
Definition rndis.h:21
struct rndis_operations * op
RNDIS operations.
Definition rndis.h:324
const char * name
Device name.
Definition rndis.h:322
int wait_rc
Return status code for current blocking request.
Definition rndis.h:331
unsigned int wait_id
Request ID for current blocking request.
Definition rndis.h:329
void(* poll)(struct rndis_device *rndis)
Poll for completed and received packets.
Definition rndis.h:314
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79

References DBGC, ETIMEDOUT, mdelay(), rndis_device::name, rndis_device::op, rndis_operations::poll, RNDIS_MAX_WAIT_MS, rndis_device::wait_id, and rndis_device::wait_rc.

Referenced by rndis_initialise(), and rndis_oid().

◆ rndis_tx_message()

int rndis_tx_message ( struct rndis_device * rndis,
struct io_buffer * iobuf,
unsigned int type )
static

Transmit message.

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

Definition at line 101 of file rndis.c.

102 {
103 struct rndis_header *header;
104 int rc;
105
106 /* Prepend RNDIS header */
107 header = iob_push ( iobuf, sizeof ( *header ) );
108 header->type = cpu_to_le32 ( type );
109 header->len = cpu_to_le32 ( iob_len ( iobuf ) );
110
111 /* Transmit message */
112 if ( ( rc = rndis->op->transmit ( rndis, iobuf ) ) != 0 ) {
113 DBGC ( rndis, "RNDIS %s could not transmit: %s\n",
114 rndis->name, strerror ( rc ) );
115 return rc;
116 }
117
118 return 0;
119}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint32_t type
Operating system type.
Definition ena.h:1
#define cpu_to_le32(value)
Definition byteswap.h:108
#define iob_push(iobuf, len)
Definition iobuf.h:89
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int(* transmit)(struct rndis_device *rndis, struct io_buffer *iobuf)
Transmit packet.
Definition rndis.h:307

References cpu_to_le32, DBGC, header, iob_len(), iob_push, rndis_device::name, rndis_device::op, rc, strerror(), rndis_operations::transmit, and type.

Referenced by rndis_tx_data(), rndis_tx_halt(), rndis_tx_initialise(), and rndis_tx_oid().

◆ rndis_tx_complete_err()

void rndis_tx_complete_err ( struct rndis_device * rndis,
struct io_buffer * iobuf,
int rc )

Complete message transmission.

Parameters
rndisRNDIS device
iobufI/O buffer
rcPacket status code

Definition at line 128 of file rndis.c.

129 {
130 struct net_device *netdev = rndis->netdev;
131 struct rndis_header *header;
132 size_t len = iob_len ( iobuf );
133
134 /* Sanity check */
135 if ( len < sizeof ( *header ) ) {
136 DBGC ( rndis, "RNDIS %s completed underlength transmission:\n",
137 rndis->name );
138 DBGC_HDA ( rndis, 0, iobuf->data, len );
140 return;
141 }
142 header = iobuf->data;
143
144 /* Complete buffer */
145 if ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) {
146 netdev_tx_complete_err ( netdev, iobuf, rc );
147 } else {
148 free_iob ( iobuf );
149 }
150}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
void netdev_tx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard transmitted packet.
Definition netdevice.c:441
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471
#define RNDIS_PACKET_MSG
RNDIS packet message.
Definition rndis.h:220
void * data
Start of data.
Definition iobuf.h:53
A network device.
Definition netdevice.h:353
struct net_device * netdev
Network device.
Definition rndis.h:320

References cpu_to_le32, io_buffer::data, DBGC, DBGC_HDA, EINVAL, free_iob(), header, iob_len(), len, rndis_device::name, netdev, rndis_device::netdev, netdev_tx_complete_err(), netdev_tx_err(), NULL, rc, and RNDIS_PACKET_MSG.

Referenced by acm_out_complete(), netvsc_cancel_transmit(), and rndis_tx_complete().

◆ rndis_tx_data()

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

Transmit data packet.

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

Definition at line 159 of file rndis.c.

160 {
162 size_t len = iob_len ( iobuf );
163 int rc;
164
165 /* Prepend packet message header */
166 msg = iob_push ( iobuf, sizeof ( *msg ) );
167 memset ( msg, 0, sizeof ( *msg ) );
168 msg->data.offset = cpu_to_le32 ( sizeof ( *msg ) );
169 msg->data.len = cpu_to_le32 ( len );
170
171 /* Transmit message */
172 if ( ( rc = rndis_tx_message ( rndis, iobuf, RNDIS_PACKET_MSG ) ) != 0 )
173 return rc;
174
175 return 0;
176}
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 rndis_tx_message(struct rndis_device *rndis, struct io_buffer *iobuf, unsigned int type)
Transmit message.
Definition rndis.c:101
RNDIS packet message.
Definition rndis.h:231

References cpu_to_le32, iob_len(), iob_push, len, memset(), msg(), rc, RNDIS_PACKET_MSG, and rndis_tx_message().

Referenced by rndis_transmit().

◆ rndis_tx_defer()

int rndis_tx_defer ( struct rndis_device * rndis,
struct io_buffer * iobuf )

Defer transmitted packet.

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

As with netdev_tx_defer(), the caller must ensure that space in the transmit descriptor ring is freed up before calling rndis_tx_complete().

Unlike netdev_tx_defer(), this call may fail.

Definition at line 191 of file rndis.c.

191 {
192 struct net_device *netdev = rndis->netdev;
193 struct rndis_header *header;
195
196 /* Fail unless this was a packet message. Only packet
197 * messages correspond to I/O buffers in the network device's
198 * TX queue; other messages cannot be deferred in this way.
199 */
200 assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
201 header = iobuf->data;
202 if ( header->type != cpu_to_le32 ( RNDIS_PACKET_MSG ) )
203 return -ENOTSUP;
204
205 /* Strip RNDIS header and packet message header, to return
206 * this packet to the state in which we received it.
207 */
208 iob_pull ( iobuf, ( sizeof ( *header ) + sizeof ( *msg ) ) );
209
210 /* Defer packet */
211 netdev_tx_defer ( netdev, iobuf );
212
213 return 0;
214}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define iob_pull(iobuf, len)
Definition iobuf.h:107
void netdev_tx_defer(struct net_device *netdev, struct io_buffer *iobuf)
Defer transmitted packet.
Definition netdevice.c:413

References assert, cpu_to_le32, io_buffer::data, ENOTSUP, header, iob_len(), iob_pull, msg(), netdev, rndis_device::netdev, netdev_tx_defer(), and RNDIS_PACKET_MSG.

Referenced by netvsc_transmit().

◆ rndis_rx_data()

void rndis_rx_data ( struct rndis_device * rndis,
struct io_buffer * iobuf )
static

Receive data packet.

Parameters
rndisRNDIS device
iobufI/O buffer

Definition at line 222 of file rndis.c.

223 {
224 struct net_device *netdev = rndis->netdev;
226 size_t len = iob_len ( iobuf );
227 size_t data_offset;
228 size_t data_len;
229 int rc;
230
231 /* Sanity check */
232 if ( len < sizeof ( *msg ) ) {
233 DBGC ( rndis, "RNDIS %s received underlength data packet:\n",
234 rndis->name );
235 DBGC_HDA ( rndis, 0, iobuf->data, len );
236 rc = -EINVAL;
237 goto err_len;
238 }
239 msg = iobuf->data;
240
241 /* Locate and sanity check data buffer */
242 data_offset = le32_to_cpu ( msg->data.offset );
243 data_len = le32_to_cpu ( msg->data.len );
244 if ( ( data_offset > len ) || ( data_len > ( len - data_offset ) ) ) {
245 DBGC ( rndis, "RNDIS %s data packet data exceeds packet:\n",
246 rndis->name );
247 DBGC_HDA ( rndis, 0, iobuf->data, len );
248 rc = -EINVAL;
249 goto err_data;
250 }
251
252 /* Strip non-data portions */
253 iob_pull ( iobuf, data_offset );
254 iob_unput ( iobuf, ( iob_len ( iobuf ) - data_len ) );
255
256 /* Hand off to network stack */
257 netdev_rx ( netdev, iob_disown ( iobuf ) );
258
259 return;
260
261 err_data:
262 err_len:
263 /* Report error to network stack */
264 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
265}
#define le32_to_cpu(value)
Definition byteswap.h:114
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
#define iob_unput(iobuf, len)
Definition iobuf.h:140
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition ucode.h:15

References io_buffer::data, data_len, DBGC, DBGC_HDA, EINVAL, iob_disown, iob_len(), iob_pull, iob_unput, le32_to_cpu, len, msg(), rndis_device::name, netdev, rndis_device::netdev, netdev_rx(), netdev_rx_err(), and rc.

Referenced by rndis_rx_message().

◆ rndis_tx_initialise()

int rndis_tx_initialise ( struct rndis_device * rndis,
unsigned int id )
static

Transmit initialisation message.

Parameters
rndisRNDIS device
idRequest ID
Return values
rcReturn status code

Definition at line 274 of file rndis.c.

274 {
275 struct io_buffer *iobuf;
277 int rc;
278
279 /* Allocate I/O buffer */
280 iobuf = rndis_alloc_iob ( sizeof ( *msg ) );
281 if ( ! iobuf ) {
282 rc = -ENOMEM;
283 goto err_alloc;
284 }
285
286 /* Construct message */
287 msg = iob_put ( iobuf, sizeof ( *msg ) );
288 memset ( msg, 0, sizeof ( *msg ) );
289 msg->id = id; /* Non-endian */
292 msg->mtu = cpu_to_le32 ( RNDIS_MTU );
293
294 /* Transmit message */
295 if ( ( rc = rndis_tx_message ( rndis, iobuf,
296 RNDIS_INITIALISE_MSG ) ) != 0 )
297 goto err_tx;
298
299 return 0;
300
301 err_tx:
302 free_iob ( iobuf );
303 err_alloc:
304 return rc;
305}
uint8_t id
Request identifier.
Definition ena.h:1
#define ENOMEM
Not enough space.
Definition errno.h:535
#define iob_put(iobuf, len)
Definition iobuf.h:125
static struct io_buffer * rndis_alloc_iob(size_t len)
Allocate I/O buffer.
Definition rndis.c:49
#define RNDIS_MTU
RNDIS maximum transfer size.
Definition rndis.h:62
#define RNDIS_INITIALISE_MSG
RNDIS initialise message.
Definition rndis.h:32
#define RNDIS_VERSION_MINOR
RNDIS minor version.
Definition rndis.h:56
#define RNDIS_VERSION_MAJOR
RNDIS major version.
Definition rndis.h:53
RNDIS initialise message.
Definition rndis.h:35

References cpu_to_le32, ENOMEM, free_iob(), id, iob_put, memset(), msg(), rc, rndis_alloc_iob(), RNDIS_INITIALISE_MSG, RNDIS_MTU, rndis_tx_message(), RNDIS_VERSION_MAJOR, and RNDIS_VERSION_MINOR.

Referenced by rndis_initialise().

◆ rndis_rx_initialise()

void rndis_rx_initialise ( struct rndis_device * rndis,
struct io_buffer * iobuf )
static

Receive initialisation completion.

Parameters
rndisRNDIS device
iobufI/O buffer

Definition at line 313 of file rndis.c.

314 {
315 struct rndis_initialise_completion *cmplt;
316 size_t len = iob_len ( iobuf );
317 unsigned int id;
318 int rc;
319
320 /* Sanity check */
321 if ( len < sizeof ( *cmplt ) ) {
322 DBGC ( rndis, "RNDIS %s received underlength initialisation "
323 "completion:\n", rndis->name );
324 DBGC_HDA ( rndis, 0, iobuf->data, len );
325 rc = -EINVAL;
326 goto err_len;
327 }
328 cmplt = iobuf->data;
329
330 /* Extract request ID */
331 id = cmplt->id; /* Non-endian */
332
333 /* Check status */
334 if ( cmplt->status ) {
335 DBGC ( rndis, "RNDIS %s received initialisation completion "
336 "failure %#08x\n", rndis->name,
337 le32_to_cpu ( cmplt->status ) );
338 rc = -EIO;
339 goto err_status;
340 }
341
342 /* Success */
343 rc = 0;
344
345 err_status:
346 /* Record completion result if applicable */
347 if ( id == rndis->wait_id ) {
348 rndis->wait_id = 0;
349 rndis->wait_rc = rc;
350 }
351 err_len:
352 free_iob ( iobuf );
353}
#define EIO
Input/output error.
Definition errno.h:434
RNDIS initialise completion.
Definition rndis.h:68
uint32_t status
Status.
Definition rndis.h:72
uint32_t id
Request ID.
Definition rndis.h:70

References io_buffer::data, DBGC, DBGC_HDA, EINVAL, EIO, free_iob(), id, rndis_initialise_completion::id, iob_len(), le32_to_cpu, len, rndis_device::name, rc, rndis_initialise_completion::status, rndis_device::wait_id, and rndis_device::wait_rc.

Referenced by rndis_rx_message().

◆ rndis_initialise()

int rndis_initialise ( struct rndis_device * rndis)
static

Initialise RNDIS.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Definition at line 361 of file rndis.c.

361 {
362 int rc;
363
364 /* Transmit initialisation message */
365 if ( ( rc = rndis_tx_initialise ( rndis, RNDIS_INIT_ID ) ) != 0 )
366 return rc;
367
368 /* Wait for response */
369 if ( ( rc = rndis_wait ( rndis, RNDIS_INIT_ID ) ) != 0 )
370 return rc;
371
372 return 0;
373}
static int rndis_wait(struct rndis_device *rndis, unsigned int wait_id)
Wait for completion.
Definition rndis.c:68
static int rndis_tx_initialise(struct rndis_device *rndis, unsigned int id)
Transmit initialisation message.
Definition rndis.c:274
#define RNDIS_INIT_ID
Request ID used for initialisation.
Definition rndis.h:50

References rc, RNDIS_INIT_ID, rndis_tx_initialise(), and rndis_wait().

Referenced by rndis_describe(), and rndis_open().

◆ rndis_tx_halt()

int rndis_tx_halt ( struct rndis_device * rndis)
static

Transmit halt message.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Definition at line 381 of file rndis.c.

381 {
382 struct io_buffer *iobuf;
383 struct rndis_halt_message *msg;
384 int rc;
385
386 /* Allocate I/O buffer */
387 iobuf = rndis_alloc_iob ( sizeof ( *msg ) );
388 if ( ! iobuf ) {
389 rc = -ENOMEM;
390 goto err_alloc;
391 }
392
393 /* Construct message */
394 msg = iob_put ( iobuf, sizeof ( *msg ) );
395 memset ( msg, 0, sizeof ( *msg ) );
396
397 /* Transmit message */
398 if ( ( rc = rndis_tx_message ( rndis, iobuf, RNDIS_HALT_MSG ) ) != 0 )
399 goto err_tx;
400
401 return 0;
402
403 err_tx:
404 free_iob ( iobuf );
405 err_alloc:
406 return rc;
407}
#define RNDIS_HALT_MSG
RNDIS halt message.
Definition rndis.h:92
RNDIS halt message.
Definition rndis.h:95

References ENOMEM, free_iob(), iob_put, memset(), msg(), rc, rndis_alloc_iob(), RNDIS_HALT_MSG, and rndis_tx_message().

Referenced by rndis_halt().

◆ rndis_halt()

int rndis_halt ( struct rndis_device * rndis)
static

Halt RNDIS.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Definition at line 415 of file rndis.c.

415 {
416 int rc;
417
418 /* Transmit halt message */
419 if ( ( rc = rndis_tx_halt ( rndis ) ) != 0 )
420 return rc;
421
422 return 0;
423}
static int rndis_tx_halt(struct rndis_device *rndis)
Transmit halt message.
Definition rndis.c:381

References rc, and rndis_tx_halt().

Referenced by rndis_close(), rndis_describe(), and rndis_open().

◆ rndis_tx_oid()

int rndis_tx_oid ( struct rndis_device * rndis,
unsigned int oid,
const void * data,
size_t len )
static

Transmit OID message.

Parameters
rndisRNDIS device
oidObject ID
dataNew OID value (or NULL to query current value)
lenLength of new OID value
Return values
rcReturn status code

Definition at line 434 of file rndis.c.

435 {
436 struct io_buffer *iobuf;
437 struct rndis_oid_message *msg;
438 unsigned int type;
439 int rc;
440
441 /* Allocate I/O buffer */
442 iobuf = rndis_alloc_iob ( sizeof ( *msg ) + len );
443 if ( ! iobuf ) {
444 rc = -ENOMEM;
445 goto err_alloc;
446 }
447
448 /* Construct message. We use the OID as the request ID. */
449 msg = iob_put ( iobuf, sizeof ( *msg ) );
450 memset ( msg, 0, sizeof ( *msg ) );
451 msg->id = oid; /* Non-endian */
452 msg->oid = cpu_to_le32 ( oid );
453 msg->offset = cpu_to_le32 ( sizeof ( *msg ) );
454 msg->len = cpu_to_le32 ( len );
455 memcpy ( iob_put ( iobuf, len ), data, len );
456
457 /* Transmit message */
459 if ( ( rc = rndis_tx_message ( rndis, iobuf, type ) ) != 0 )
460 goto err_tx;
461
462 return 0;
463
464 err_tx:
465 free_iob ( iobuf );
466 err_alloc:
467 return rc;
468}
uint8_t data[48]
Additional event data.
Definition ena.h:11
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define RNDIS_SET_MSG
RNDIS set OID message.
Definition rndis.h:104
#define RNDIS_QUERY_MSG
RNDIS query OID message.
Definition rndis.h:101
RNDIS query or set OID message.
Definition rndis.h:107
uint32_t oid
Object ID.
Definition rndis.h:111

References cpu_to_le32, data, ENOMEM, free_iob(), iob_put, len, memcpy(), memset(), msg(), rndis_oid_message::oid, rc, rndis_alloc_iob(), RNDIS_QUERY_MSG, RNDIS_SET_MSG, rndis_tx_message(), and type.

Referenced by rndis_oid().

◆ rndis_rx_query_oid()

void rndis_rx_query_oid ( struct rndis_device * rndis,
struct io_buffer * iobuf )
static

Receive query OID completion.

Parameters
rndisRNDIS device
iobufI/O buffer

Definition at line 476 of file rndis.c.

477 {
478 struct net_device *netdev = rndis->netdev;
479 struct rndis_query_completion *cmplt;
480 size_t len = iob_len ( iobuf );
481 size_t info_offset;
482 size_t info_len;
483 unsigned int id;
484 void *info;
485 uint32_t *link_status;
486 int rc;
487
488 /* Sanity check */
489 if ( len < sizeof ( *cmplt ) ) {
490 DBGC ( rndis, "RNDIS %s received underlength query "
491 "completion:\n", rndis->name );
492 DBGC_HDA ( rndis, 0, iobuf->data, len );
493 rc = -EINVAL;
494 goto err_len;
495 }
496 cmplt = iobuf->data;
497
498 /* Extract request ID */
499 id = cmplt->id; /* Non-endian */
500
501 /* Check status */
502 if ( cmplt->status ) {
503 DBGC ( rndis, "RNDIS %s received query completion failure "
504 "%#08x\n", rndis->name, le32_to_cpu ( cmplt->status ) );
505 DBGC_HDA ( rndis, 0, iobuf->data, len );
506 rc = -EIO;
507 goto err_status;
508 }
509
510 /* Locate and sanity check information buffer */
511 info_offset = le32_to_cpu ( cmplt->offset );
512 info_len = le32_to_cpu ( cmplt->len );
513 if ( ( info_offset > len ) || ( info_len > ( len - info_offset ) ) ) {
514 DBGC ( rndis, "RNDIS %s query completion information exceeds "
515 "packet:\n", rndis->name );
516 DBGC_HDA ( rndis, 0, iobuf->data, len );
517 rc = -EINVAL;
518 goto err_info;
519 }
520 info = ( ( ( void * ) cmplt ) + info_offset );
521
522 /* Handle OID */
523 switch ( id ) {
524
526 if ( info_len > sizeof ( netdev->hw_addr ) )
527 info_len = sizeof ( netdev->hw_addr );
528 memcpy ( netdev->hw_addr, info, info_len );
529 break;
530
532 if ( info_len > sizeof ( netdev->ll_addr ) )
533 info_len = sizeof ( netdev->ll_addr );
534 memcpy ( netdev->ll_addr, info, info_len );
535 break;
536
538 if ( info_len != sizeof ( *link_status ) ) {
539 DBGC ( rndis, "RNDIS %s invalid link status:\n",
540 rndis->name );
541 DBGC_HDA ( rndis, 0, iobuf->data, len );
542 rc = -EPROTO;
543 goto err_link_status;
544 }
545 link_status = info;
546 if ( *link_status == 0 ) {
547 DBGC ( rndis, "RNDIS %s link is up\n", rndis->name );
549 } else {
550 DBGC ( rndis, "RNDIS %s link is down: %#08x\n",
551 rndis->name, le32_to_cpu ( *link_status ) );
553 }
554 break;
555
556 default:
557 DBGC ( rndis, "RNDIS %s unexpected query completion ID %#08x\n",
558 rndis->name, id );
559 DBGC_HDA ( rndis, 0, iobuf->data, len );
560 rc = -EPROTO;
561 goto err_id;
562 }
563
564 /* Success */
565 rc = 0;
566
567 err_id:
568 err_link_status:
569 err_info:
570 err_status:
571 /* Record completion result if applicable */
572 if ( id == rndis->wait_id ) {
573 rndis->wait_id = 0;
574 rndis->wait_rc = rc;
575 }
576 err_len:
577 /* Free I/O buffer */
578 free_iob ( iobuf );
579}
u32 info
Definition ar9003_mac.h:0
unsigned int uint32_t
Definition stdint.h:12
#define EPROTO
Protocol error.
Definition errno.h:625
uint8_t info_len
Reject information length.
Definition ib_mad.h:7
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS
OID for media status.
Definition rndis.h:272
#define RNDIS_OID_802_3_CURRENT_ADDRESS
OID for current MAC address.
Definition rndis.h:278
#define RNDIS_OID_802_3_PERMANENT_ADDRESS
OID for permanent MAC address.
Definition rndis.h:275
RNDIS query OID completion.
Definition rndis.h:124
uint32_t status
Status.
Definition rndis.h:128
uint32_t id
Request ID.
Definition rndis.h:126
uint32_t offset
Information buffer offset.
Definition rndis.h:132
uint32_t len
Information buffer length.
Definition rndis.h:130

References io_buffer::data, DBGC, DBGC_HDA, EINVAL, EIO, EPROTO, free_iob(), id, rndis_query_completion::id, info, info_len, iob_len(), le32_to_cpu, len, rndis_query_completion::len, memcpy(), rndis_device::name, netdev, rndis_device::netdev, netdev_link_down(), netdev_link_up(), rndis_query_completion::offset, rc, RNDIS_OID_802_3_CURRENT_ADDRESS, RNDIS_OID_802_3_PERMANENT_ADDRESS, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, rndis_query_completion::status, rndis_device::wait_id, and rndis_device::wait_rc.

Referenced by rndis_rx_message().

◆ rndis_rx_set_oid()

void rndis_rx_set_oid ( struct rndis_device * rndis,
struct io_buffer * iobuf )
static

Receive set OID completion.

Parameters
rndisRNDIS device
iobufI/O buffer

Definition at line 587 of file rndis.c.

588 {
589 struct rndis_set_completion *cmplt;
590 size_t len = iob_len ( iobuf );
591 unsigned int id;
592 int rc;
593
594 /* Sanity check */
595 if ( len < sizeof ( *cmplt ) ) {
596 DBGC ( rndis, "RNDIS %s received underlength set completion:\n",
597 rndis->name );
598 DBGC_HDA ( rndis, 0, iobuf->data, len );
599 rc = -EINVAL;
600 goto err_len;
601 }
602 cmplt = iobuf->data;
603
604 /* Extract request ID */
605 id = cmplt->id; /* Non-endian */
606
607 /* Check status */
608 if ( cmplt->status ) {
609 DBGC ( rndis, "RNDIS %s received set completion failure "
610 "%#08x\n", rndis->name, le32_to_cpu ( cmplt->status ) );
611 DBGC_HDA ( rndis, 0, iobuf->data, len );
612 rc = -EIO;
613 goto err_status;
614 }
615
616 /* Success */
617 rc = 0;
618
619 err_status:
620 /* Record completion result if applicable */
621 if ( id == rndis->wait_id ) {
622 rndis->wait_id = 0;
623 rndis->wait_rc = rc;
624 }
625 err_len:
626 /* Free I/O buffer */
627 free_iob ( iobuf );
628}
RNDIS set OID completion.
Definition rndis.h:139
uint32_t status
Status.
Definition rndis.h:143
uint32_t id
Request ID.
Definition rndis.h:141

References io_buffer::data, DBGC, DBGC_HDA, EINVAL, EIO, free_iob(), id, rndis_set_completion::id, iob_len(), le32_to_cpu, len, rndis_device::name, rc, rndis_set_completion::status, rndis_device::wait_id, and rndis_device::wait_rc.

Referenced by rndis_rx_message().

◆ rndis_oid()

int rndis_oid ( struct rndis_device * rndis,
unsigned int oid,
const void * data,
size_t len )
static

Query or set OID.

Parameters
rndisRNDIS device
oidObject ID
dataNew OID value (or NULL to query current value)
lenLength of new OID value
Return values
rcReturn status code

Definition at line 639 of file rndis.c.

640 {
641 int rc;
642
643 /* Transmit query */
644 if ( ( rc = rndis_tx_oid ( rndis, oid, data, len ) ) != 0 )
645 return rc;
646
647 /* Wait for response */
648 if ( ( rc = rndis_wait ( rndis, oid ) ) != 0 )
649 return rc;
650
651 return 0;
652}
static int rndis_tx_oid(struct rndis_device *rndis, unsigned int oid, const void *data, size_t len)
Transmit OID message.
Definition rndis.c:434

References data, len, rc, rndis_tx_oid(), and rndis_wait().

Referenced by rndis_describe(), rndis_filter(), and rndis_open().

◆ rndis_describe()

int rndis_describe ( struct rndis_device * rndis)
static

Describe RNDIS device.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Definition at line 660 of file rndis.c.

660 {
661 struct net_device *netdev = rndis->netdev;
662 int rc;
663
664 /* Assign device name (for debugging) */
665 rndis->name = netdev->dev->name;
666
667 /* Open RNDIS device to read MAC addresses */
668 if ( ( rc = rndis->op->open ( rndis ) ) != 0 ) {
669 DBGC ( rndis, "RNDIS %s could not open: %s\n",
670 rndis->name, strerror ( rc ) );
671 goto err_open;
672 }
673
674 /* Initialise RNDIS */
675 if ( ( rc = rndis_initialise ( rndis ) ) != 0 )
676 goto err_initialise;
677
678 /* Query permanent MAC address */
680 NULL, 0 ) ) != 0 )
681 goto err_query_permanent;
682
683 /* Query current MAC address */
685 NULL, 0 ) ) != 0 )
686 goto err_query_current;
687
688 /* Get link status */
690 NULL, 0 ) ) != 0 )
691 goto err_query_link;
692
693 /* Halt RNDIS device */
694 rndis_halt ( rndis );
695
696 /* Close RNDIS device */
697 rndis->op->close ( rndis );
698
699 return 0;
700
701 err_query_link:
702 err_query_current:
703 err_query_permanent:
704 rndis_halt ( rndis );
705 err_initialise:
706 rndis->op->close ( rndis );
707 err_open:
708 return rc;
709}
static int rndis_halt(struct rndis_device *rndis)
Halt RNDIS.
Definition rndis.c:415
static int rndis_oid(struct rndis_device *rndis, unsigned int oid, const void *data, size_t len)
Query or set OID.
Definition rndis.c:639
static int rndis_initialise(struct rndis_device *rndis)
Initialise RNDIS.
Definition rndis.c:361
int(* open)(struct rndis_device *rndis)
Open RNDIS device.
Definition rndis.h:290
void(* close)(struct rndis_device *rndis)
Close RNDIS device.
Definition rndis.h:296

References rndis_operations::close, DBGC, rndis_device::name, netdev, rndis_device::netdev, NULL, rndis_device::op, rndis_operations::open, rc, rndis_halt(), rndis_initialise(), rndis_oid(), RNDIS_OID_802_3_CURRENT_ADDRESS, RNDIS_OID_802_3_PERMANENT_ADDRESS, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, and strerror().

Referenced by register_rndis().

◆ rndis_rx_status()

void rndis_rx_status ( struct rndis_device * rndis,
struct io_buffer * iobuf )
static

Receive indicate status message.

Parameters
rndisRNDIS device
iobufI/O buffer

Definition at line 717 of file rndis.c.

718 {
719 struct net_device *netdev = rndis->netdev;
721 size_t len = iob_len ( iobuf );
722 unsigned int status;
723 int rc;
724
725 /* Sanity check */
726 if ( len < sizeof ( *msg ) ) {
727 DBGC ( rndis, "RNDIS %s received underlength status message:\n",
728 rndis->name );
729 DBGC_HDA ( rndis, 0, iobuf->data, len );
730 rc = -EINVAL;
731 goto err_len;
732 }
733 msg = iobuf->data;
734
735 /* Extract status */
736 status = le32_to_cpu ( msg->status );
737
738 /* Handle status */
739 switch ( msg->status ) {
740
742 DBGC ( rndis, "RNDIS %s link is up\n", rndis->name );
744 break;
745
747 DBGC ( rndis, "RNDIS %s link is down\n", rndis->name );
749 break;
750
752 /* Ignore */
753 break;
754
755 default:
756 DBGC ( rndis, "RNDIS %s unexpected status %#08x:\n",
757 rndis->name, status );
758 DBGC_HDA ( rndis, 0, iobuf->data, len );
759 rc = -ENOTSUP;
760 goto err_status;
761 }
762
763 /* Free I/O buffer */
764 free_iob ( iobuf );
765
766 return;
767
768 err_status:
769 err_len:
770 /* Report error via network device statistics */
771 netdev_rx_err ( netdev, iobuf, rc );
772}
uint8_t status
Status.
Definition ena.h:5
@ RNDIS_STATUS_WTF_WORLD
Unknown start-of-day status code.
Definition rndis.h:196
@ RNDIS_STATUS_MEDIA_DISCONNECT
Device is disconnected from the medium.
Definition rndis.h:194
@ RNDIS_STATUS_MEDIA_CONNECT
Device is connected to a network medium.
Definition rndis.h:192
RNDIS indicate status message.
Definition rndis.h:178

References io_buffer::data, DBGC, DBGC_HDA, EINVAL, ENOTSUP, free_iob(), iob_len(), le32_to_cpu, len, msg(), rndis_device::name, netdev, rndis_device::netdev, netdev_link_down(), netdev_link_up(), netdev_rx_err(), rc, RNDIS_STATUS_MEDIA_CONNECT, RNDIS_STATUS_MEDIA_DISCONNECT, RNDIS_STATUS_WTF_WORLD, and status.

Referenced by rndis_rx_message().

◆ rndis_rx_message()

void rndis_rx_message ( struct rndis_device * rndis,
struct io_buffer * iobuf,
unsigned int type )
static

Receive RNDIS message.

Parameters
rndisRNDIS device
iobufI/O buffer
typeMessage type

Definition at line 781 of file rndis.c.

782 {
783 struct net_device *netdev = rndis->netdev;
784 int rc;
785
786 /* Handle packet */
787 switch ( type ) {
788
789 case RNDIS_PACKET_MSG:
790 rndis_rx_data ( rndis, iob_disown ( iobuf ) );
791 break;
792
794 rndis_rx_initialise ( rndis, iob_disown ( iobuf ) );
795 break;
796
798 rndis_rx_query_oid ( rndis, iob_disown ( iobuf ) );
799 break;
800
801 case RNDIS_SET_CMPLT:
802 rndis_rx_set_oid ( rndis, iob_disown ( iobuf ) );
803 break;
804
806 rndis_rx_status ( rndis, iob_disown ( iobuf ) );
807 break;
808
809 default:
810 DBGC ( rndis, "RNDIS %s received unexpected type %#08x\n",
811 rndis->name, type );
812 DBGC_HDA ( rndis, 0, iobuf->data, iob_len ( iobuf ) );
813 rc = -EPROTO;
814 goto err_type;
815 }
816
817 return;
818
819 err_type:
820 /* Report error via network device statistics */
821 netdev_rx_err ( netdev, iobuf, rc );
822}
static void rndis_rx_initialise(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive initialisation completion.
Definition rndis.c:313
static void rndis_rx_status(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive indicate status message.
Definition rndis.c:717
static void rndis_rx_data(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive data packet.
Definition rndis.c:222
static void rndis_rx_query_oid(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive query OID completion.
Definition rndis.c:476
static void rndis_rx_set_oid(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive set OID completion.
Definition rndis.c:587
#define RNDIS_SET_CMPLT
RNDIS set OID completion.
Definition rndis.h:136
#define RNDIS_INDICATE_STATUS_MSG
RNDIS indicate status message.
Definition rndis.h:167
#define RNDIS_INITIALISE_CMPLT
RNDIS initialise completion.
Definition rndis.h:65
#define RNDIS_QUERY_CMPLT
RNDIS query OID completion.
Definition rndis.h:121

References io_buffer::data, DBGC, DBGC_HDA, EPROTO, iob_disown, iob_len(), rndis_device::name, netdev, rndis_device::netdev, netdev_rx_err(), rc, RNDIS_INDICATE_STATUS_MSG, RNDIS_INITIALISE_CMPLT, RNDIS_PACKET_MSG, RNDIS_QUERY_CMPLT, rndis_rx_data(), rndis_rx_initialise(), rndis_rx_query_oid(), rndis_rx_set_oid(), rndis_rx_status(), RNDIS_SET_CMPLT, and type.

Referenced by rndis_rx().

◆ rndis_rx()

void rndis_rx ( struct rndis_device * rndis,
struct io_buffer * iobuf )

Receive packet from underlying transport layer.

Parameters
rndisRNDIS device
iobufI/O buffer

Definition at line 830 of file rndis.c.

830 {
831 struct net_device *netdev = rndis->netdev;
832 struct rndis_header *header;
833 unsigned int type;
834 int rc;
835
836 /* Sanity check */
837 if ( iob_len ( iobuf ) < sizeof ( *header ) ) {
838 DBGC ( rndis, "RNDIS %s received underlength packet:\n",
839 rndis->name );
840 DBGC_HDA ( rndis, 0, iobuf->data, iob_len ( iobuf ) );
841 rc = -EINVAL;
842 goto drop;
843 }
844 header = iobuf->data;
845
846 /* Parse and strip header */
847 type = le32_to_cpu ( header->type );
848 iob_pull ( iobuf, sizeof ( *header ) );
849
850 /* Handle message */
851 rndis_rx_message ( rndis, iob_disown ( iobuf ), type );
852
853 return;
854
855 drop:
856 /* Record error */
857 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
858}
static void rndis_rx_message(struct rndis_device *rndis, struct io_buffer *iobuf, unsigned int type)
Receive RNDIS message.
Definition rndis.c:781

References io_buffer::data, DBGC, DBGC_HDA, EINVAL, header, iob_disown, iob_len(), iob_pull, le32_to_cpu, rndis_device::name, netdev, rndis_device::netdev, netdev_rx_err(), rc, rndis_rx_message(), and type.

Referenced by acm_control_receive(), acm_in_complete(), and netvsc_recv_data().

◆ rndis_rx_err()

void rndis_rx_err ( struct rndis_device * rndis,
struct io_buffer * iobuf,
int rc )

Discard packet from underlying transport layer.

Parameters
rndisRNDIS device
iobufI/O buffer
rcPacket status code

Definition at line 867 of file rndis.c.

868 {
869 struct net_device *netdev = rndis->netdev;
870
871 /* Record error */
872 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
873}

References iob_disown, netdev, rndis_device::netdev, netdev_rx_err(), and rc.

Referenced by acm_in_complete(), acm_intr_complete(), and acm_poll().

◆ rndis_filter()

int rndis_filter ( struct rndis_device * rndis,
unsigned int filter )
static

Set receive filter.

Parameters
rndisRNDIS device
filterReceive filter
Return values
rcReturn status code

Definition at line 882 of file rndis.c.

882 {
884 int rc;
885
886 /* Set receive filter */
888 &value, sizeof ( value ) ) ) != 0 ) {
889 DBGC ( rndis, "RNDIS %s could not set receive filter to %#08x: "
890 "%s\n", rndis->name, filter, strerror ( rc ) );
891 return rc;
892 }
893
894 return 0;
895}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
UINT8_t filter
Receive packet filter.
Definition pxe_api.h:11
#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER
OID for packet filter.
Definition rndis.h:255

References cpu_to_le32, DBGC, filter, rndis_device::name, rc, rndis_oid(), RNDIS_OID_GEN_CURRENT_PACKET_FILTER, strerror(), and value.

Referenced by rndis_close(), and rndis_open().

◆ rndis_open()

int rndis_open ( struct net_device * netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 903 of file rndis.c.

903 {
904 struct rndis_device *rndis = netdev->priv;
905 int rc;
906
907 /* Open RNDIS device */
908 if ( ( rc = rndis->op->open ( rndis ) ) != 0 ) {
909 DBGC ( rndis, "RNDIS %s could not open: %s\n",
910 rndis->name, strerror ( rc ) );
911 goto err_open;
912 }
913
914 /* Initialise RNDIS */
915 if ( ( rc = rndis_initialise ( rndis ) ) != 0 )
916 goto err_initialise;
917
918 /* Set receive filter */
919 if ( ( rc = rndis_filter ( rndis, ( RNDIS_FILTER_UNICAST |
923 RNDIS_FILTER_PROMISCUOUS ) ) ) != 0)
924 goto err_set_filter;
925
926 /* Update link status */
928 NULL, 0 ) ) != 0 )
929 goto err_query_link;
930
931 return 0;
932
933 err_query_link:
934 err_set_filter:
935 rndis_halt ( rndis );
936 err_initialise:
937 rndis->op->close ( rndis );
938 err_open:
939 return rc;
940}
static int rndis_filter(struct rndis_device *rndis, unsigned int filter)
Set receive filter.
Definition rndis.c:882
@ RNDIS_FILTER_MULTICAST
Multicast packets.
Definition rndis.h:262
@ RNDIS_FILTER_PROMISCUOUS
All packets.
Definition rndis.h:268
@ RNDIS_FILTER_BROADCAST
Broadcast packets.
Definition rndis.h:266
@ RNDIS_FILTER_ALL_MULTICAST
All multicast packets.
Definition rndis.h:264
@ RNDIS_FILTER_UNICAST
Unicast packets.
Definition rndis.h:260
An RNDIS device.
Definition rndis.h:318

References rndis_operations::close, DBGC, rndis_device::name, netdev, NULL, rndis_device::op, rndis_operations::open, rc, rndis_filter(), RNDIS_FILTER_ALL_MULTICAST, RNDIS_FILTER_BROADCAST, RNDIS_FILTER_MULTICAST, RNDIS_FILTER_PROMISCUOUS, RNDIS_FILTER_UNICAST, rndis_halt(), rndis_initialise(), rndis_oid(), RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, and strerror().

◆ rndis_close()

void rndis_close ( struct net_device * netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 947 of file rndis.c.

947 {
948 struct rndis_device *rndis = netdev->priv;
949
950 /* Clear receive filter */
951 rndis_filter ( rndis, 0 );
952
953 /* Halt RNDIS device */
954 rndis_halt ( rndis );
955
956 /* Close RNDIS device */
957 rndis->op->close ( rndis );
958}

References rndis_operations::close, netdev, rndis_device::op, rndis_filter(), and rndis_halt().

◆ rndis_transmit()

int rndis_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Transmit packet.

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

Definition at line 967 of file rndis.c.

968 {
969 struct rndis_device *rndis = netdev->priv;
970
971 /* Transmit data packet */
972 return rndis_tx_data ( rndis, iobuf );
973}
static int rndis_tx_data(struct rndis_device *rndis, struct io_buffer *iobuf)
Transmit data packet.
Definition rndis.c:159

References netdev, and rndis_tx_data().

◆ rndis_poll()

void rndis_poll ( struct net_device * netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 980 of file rndis.c.

980 {
981 struct rndis_device *rndis = netdev->priv;
982
983 /* Poll RNDIS device */
984 rndis->op->poll ( rndis );
985}

References netdev, rndis_device::op, and rndis_operations::poll.

◆ alloc_rndis()

struct rndis_device * alloc_rndis ( size_t priv_len)

Allocate RNDIS device.

Parameters
priv_lenLength of private data
Return values
rndisRNDIS device, or NULL on allocation failure

Definition at line 1001 of file rndis.c.

1001 {
1002 struct net_device *netdev;
1003 struct rndis_device *rndis;
1004
1005 /* Allocate and initialise structure */
1006 netdev = alloc_etherdev ( sizeof ( *rndis ) + priv_len );
1007 if ( ! netdev )
1008 return NULL;
1010 rndis = netdev->priv;
1011 rndis->netdev = netdev;
1012 rndis->priv = ( ( ( void * ) rndis ) + sizeof ( *rndis ) );
1013
1014 return rndis;
1015}
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
void * priv
Driver private data.
Definition rndis.h:326
RNDIS device operations.
Definition rndis.h:283

References alloc_etherdev(), netdev, rndis_device::netdev, netdev_init(), NULL, and rndis_device::priv.

Referenced by acm_probe(), and netvsc_probe().

◆ register_rndis()

int register_rndis ( struct rndis_device * rndis)

Register RNDIS device.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Note that this routine will open and use the RNDIS device in order to query the MAC address. The device must be immediately ready for use prior to registration.

Definition at line 1027 of file rndis.c.

1027 {
1028 struct net_device *netdev = rndis->netdev;
1029 int rc;
1030
1031 /* Describe RNDIS device */
1032 if ( ( rc = rndis_describe ( rndis ) ) != 0 )
1033 goto err_describe;
1034
1035 /* Register network device */
1036 if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
1037 DBGC ( rndis, "RNDIS %s could not register: %s\n",
1038 rndis->name, strerror ( rc ) );
1039 goto err_register;
1040 }
1041
1042 return 0;
1043
1045 err_register:
1046 err_describe:
1047 return rc;
1048}
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static int rndis_describe(struct rndis_device *rndis)
Describe RNDIS device.
Definition rndis.c:660

References DBGC, rndis_device::name, netdev, rndis_device::netdev, rc, register_netdev(), rndis_describe(), strerror(), and unregister_netdev().

Referenced by acm_probe(), and netvsc_probe().

◆ unregister_rndis()

void unregister_rndis ( struct rndis_device * rndis)

Unregister RNDIS device.

Parameters
rndisRNDIS device

Definition at line 1055 of file rndis.c.

1055 {
1056 struct net_device *netdev = rndis->netdev;
1057
1058 /* Unregister network device */
1060}

References netdev, rndis_device::netdev, and unregister_netdev().

Referenced by acm_probe(), acm_remove(), netvsc_probe(), and netvsc_remove().

◆ free_rndis()

void free_rndis ( struct rndis_device * rndis)

Free RNDIS device.

Parameters
rndisRNDIS device

Definition at line 1067 of file rndis.c.

1067 {
1068 struct net_device *netdev = rndis->netdev;
1069
1070 /* Free network device */
1072 netdev_put ( netdev );
1073}
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576

References netdev, rndis_device::netdev, netdev_nullify(), and netdev_put().

Referenced by acm_probe(), acm_remove(), netvsc_probe(), and netvsc_remove().

Variable Documentation

◆ rndis_operations

struct net_device_operations rndis_operations
static
Initial value:
= {
.open = rndis_open,
.close = rndis_close,
.transmit = rndis_transmit,
.poll = rndis_poll,
}
static int rndis_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition rndis.c:967
static void rndis_close(struct net_device *netdev)
Close network device.
Definition rndis.c:947
static int rndis_open(struct net_device *netdev)
Open network device.
Definition rndis.c:903
static void rndis_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition rndis.c:980

Network device operations.

Definition at line 988 of file rndis.c.

988 {
989 .open = rndis_open,
990 .close = rndis_close,
991 .transmit = rndis_transmit,
992 .poll = rndis_poll,
993};