~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/drivers/net/netvsc.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of the
 
7
 * License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
17
 * 02110-1301, USA.
 
18
 *
 
19
 * You can also choose to distribute this program under the terms of
 
20
 * the Unmodified Binary Distribution Licence (as given in the file
 
21
 * COPYING.UBDL), provided that you have satisfied its requirements.
 
22
 */
 
23
 
 
24
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
25
 
 
26
/** @file
 
27
 *
 
28
 * Hyper-V network virtual service client
 
29
 *
 
30
 * The network virtual service client (NetVSC) connects to the network
 
31
 * virtual service provider (NetVSP) via the Hyper-V virtual machine
 
32
 * bus (VMBus).  It provides a transport layer for RNDIS packets.
 
33
 */
 
34
 
 
35
#include <errno.h>
 
36
#include <unistd.h>
 
37
#include <byteswap.h>
 
38
#include <ipxe/umalloc.h>
 
39
#include <ipxe/rndis.h>
 
40
#include <ipxe/vmbus.h>
 
41
#include "netvsc.h"
 
42
 
 
43
/**
 
44
 * Send control message and wait for completion
 
45
 *
 
46
 * @v netvsc            NetVSC device
 
47
 * @v xrid              Relative transaction ID
 
48
 * @v data              Data
 
49
 * @v len               Length of data
 
50
 * @ret rc              Return status code
 
51
 */
 
52
static int netvsc_control ( struct netvsc_device *netvsc, unsigned int xrid,
 
53
                            const void *data, size_t len ) {
 
54
        uint64_t xid = ( NETVSC_BASE_XID + xrid );
 
55
        unsigned int i;
 
56
        int rc;
 
57
 
 
58
        /* Send control message */
 
59
        if ( ( rc = vmbus_send_control ( netvsc->vmdev, xid, data, len ) ) !=0){
 
60
                DBGC ( netvsc, "NETVSC %s could not send control message: %s\n",
 
61
                       netvsc->name, strerror ( rc ) );
 
62
                return rc;
 
63
        }
 
64
 
 
65
        /* Record transaction ID */
 
66
        netvsc->wait_xrid = xrid;
 
67
 
 
68
        /* Wait for operation to complete */
 
69
        for ( i = 0 ; i < NETVSC_MAX_WAIT_MS ; i++ ) {
 
70
 
 
71
                /* Check for completion */
 
72
                if ( ! netvsc->wait_xrid )
 
73
                        return netvsc->wait_rc;
 
74
 
 
75
                /* Poll VMBus device */
 
76
                vmbus_poll ( netvsc->vmdev );
 
77
 
 
78
                /* Delay for 1ms */
 
79
                mdelay ( 1 );
 
80
        }
 
81
 
 
82
        DBGC ( netvsc, "NETVSC %s timed out waiting for XRID %d\n",
 
83
               netvsc->name, xrid );
 
84
        vmbus_dump_channel ( netvsc->vmdev );
 
85
        return -ETIMEDOUT;
 
86
}
 
87
 
 
88
/**
 
89
 * Handle generic completion
 
90
 *
 
91
 * @v netvsc            NetVSC device
 
92
 * @v data              Data
 
93
 * @v len               Length of data
 
94
 * @ret rc              Return status code
 
95
 */
 
96
static int netvsc_completed ( struct netvsc_device *netvsc __unused,
 
97
                              const void *data __unused, size_t len __unused ) {
 
98
        return 0;
 
99
}
 
100
 
 
101
/**
 
102
 * Initialise communication
 
103
 *
 
104
 * @v netvsc            NetVSC device
 
105
 * @ret rc              Return status code
 
106
 */
 
107
static int netvsc_initialise ( struct netvsc_device *netvsc ) {
 
108
        struct netvsc_init_message msg;
 
109
        int rc;
 
110
 
 
111
        /* Construct message */
 
112
        memset ( &msg, 0, sizeof ( msg ) );
 
113
        msg.header.type = cpu_to_le32 ( NETVSC_INIT_MSG );
 
114
        msg.min = cpu_to_le32 ( NETVSC_VERSION_1 );
 
115
        msg.max = cpu_to_le32 ( NETVSC_VERSION_1 );
 
116
 
 
117
        /* Send message and wait for completion */
 
118
        if ( ( rc = netvsc_control ( netvsc, NETVSC_INIT_XRID, &msg,
 
119
                                     sizeof ( msg ) ) ) != 0 ) {
 
120
                DBGC ( netvsc, "NETVSC %s could not initialise: %s\n",
 
121
                       netvsc->name, strerror ( rc ) );
 
122
                return rc;
 
123
        }
 
124
 
 
125
        return 0;
 
126
}
 
127
 
 
128
/**
 
129
 * Handle initialisation completion
 
130
 *
 
131
 * @v netvsc            NetVSC device
 
132
 * @v data              Data
 
133
 * @v len               Length of data
 
134
 * @ret rc              Return status code
 
135
 */
 
136
static int
 
137
netvsc_initialised ( struct netvsc_device *netvsc, const void *data,
 
138
                     size_t len ) {
 
139
        const struct netvsc_init_completion *cmplt = data;
 
140
 
 
141
        /* Check completion */
 
142
        if ( len < sizeof ( *cmplt ) ) {
 
143
                DBGC ( netvsc, "NETVSC %s underlength initialisation "
 
144
                       "completion (%zd bytes)\n", netvsc->name, len );
 
145
                return -EINVAL;
 
146
        }
 
147
        if ( cmplt->header.type != cpu_to_le32 ( NETVSC_INIT_CMPLT ) ) {
 
148
                DBGC ( netvsc, "NETVSC %s unexpected initialisation completion "
 
149
                       "type %d\n", netvsc->name,
 
150
                       le32_to_cpu ( cmplt->header.type ) );
 
151
                return -EPROTO;
 
152
        }
 
153
        if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
 
154
                DBGC ( netvsc, "NETVSC %s initialisation failure status %d\n",
 
155
                       netvsc->name, le32_to_cpu ( cmplt->status ) );
 
156
                return -EPROTO;
 
157
        }
 
158
 
 
159
        return 0;
 
160
}
 
161
 
 
162
/**
 
163
 * Set NDIS version
 
164
 *
 
165
 * @v netvsc            NetVSC device
 
166
 * @ret rc              Return status code
 
167
 */
 
168
static int netvsc_ndis_version ( struct netvsc_device *netvsc ) {
 
169
        struct netvsc_ndis_version_message msg;
 
170
        int rc;
 
171
 
 
172
        /* Construct message */
 
173
        memset ( &msg, 0, sizeof ( msg ) );
 
174
        msg.header.type = cpu_to_le32 ( NETVSC_NDIS_VERSION_MSG );
 
175
        msg.major = cpu_to_le32 ( NETVSC_NDIS_MAJOR );
 
176
        msg.minor = cpu_to_le32 ( NETVSC_NDIS_MINOR );
 
177
 
 
178
        /* Send message and wait for completion */
 
179
        if ( ( rc = netvsc_control ( netvsc, NETVSC_NDIS_VERSION_XRID,
 
180
                                     &msg, sizeof ( msg ) ) ) != 0 ) {
 
181
                DBGC ( netvsc, "NETVSC %s could not set NDIS version: %s\n",
 
182
                       netvsc->name, strerror ( rc ) );
 
183
                return rc;
 
184
        }
 
185
 
 
186
        return 0;
 
187
}
 
188
 
 
189
/**
 
190
 * Establish data buffer
 
191
 *
 
192
 * @v netvsc            NetVSC device
 
193
 * @v buffer            Data buffer
 
194
 * @ret rc              Return status code
 
195
 */
 
196
static int netvsc_establish_buffer ( struct netvsc_device *netvsc,
 
197
                                     struct netvsc_buffer *buffer ) {
 
198
        struct netvsc_establish_buffer_message msg;
 
199
        int rc;
 
200
 
 
201
        /* Construct message */
 
202
        memset ( &msg, 0, sizeof ( msg ) );
 
203
        msg.header.type = cpu_to_le32 ( buffer->establish_type );
 
204
        msg.gpadl = cpu_to_le32 ( buffer->gpadl );
 
205
        msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
 
206
 
 
207
        /* Send message and wait for completion */
 
208
        if ( ( rc = netvsc_control ( netvsc, buffer->establish_xrid, &msg,
 
209
                                     sizeof ( msg ) ) ) != 0 ) {
 
210
                DBGC ( netvsc, "NETVSC %s could not establish buffer: %s\n",
 
211
                       netvsc->name, strerror ( rc ) );
 
212
                return rc;
 
213
        }
 
214
 
 
215
        return 0;
 
216
}
 
217
 
 
218
/**
 
219
 * Handle establish receive data buffer completion
 
220
 *
 
221
 * @v netvsc            NetVSC device
 
222
 * @v data              Data
 
223
 * @v len               Length of data
 
224
 * @ret rc              Return status code
 
225
 */
 
226
static int netvsc_rx_established_buffer ( struct netvsc_device *netvsc,
 
227
                                          const void *data, size_t len ) {
 
228
        const struct netvsc_rx_establish_buffer_completion *cmplt = data;
 
229
 
 
230
        /* Check completion */
 
231
        if ( len < sizeof ( *cmplt ) ) {
 
232
                DBGC ( netvsc, "NETVSC %s underlength buffer completion (%zd "
 
233
                       "bytes)\n", netvsc->name, len );
 
234
                return -EINVAL;
 
235
        }
 
236
        if ( cmplt->header.type != cpu_to_le32 ( NETVSC_RX_ESTABLISH_CMPLT ) ) {
 
237
                DBGC ( netvsc, "NETVSC %s unexpected buffer completion type "
 
238
                       "%d\n", netvsc->name, le32_to_cpu ( cmplt->header.type));
 
239
                return -EPROTO;
 
240
        }
 
241
        if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
 
242
                DBGC ( netvsc, "NETVSC %s buffer failure status %d\n",
 
243
                       netvsc->name, le32_to_cpu ( cmplt->status ) );
 
244
                return -EPROTO;
 
245
        }
 
246
 
 
247
        return 0;
 
248
}
 
249
 
 
250
/**
 
251
 * Revoke data buffer
 
252
 *
 
253
 * @v netvsc            NetVSC device
 
254
 * @v buffer            Data buffer
 
255
 * @ret rc              Return status code
 
256
 */
 
257
static int netvsc_revoke_buffer ( struct netvsc_device *netvsc,
 
258
                                  struct netvsc_buffer *buffer ) {
 
259
        struct netvsc_revoke_buffer_message msg;
 
260
        int rc;
 
261
 
 
262
        /* Construct message */
 
263
        memset ( &msg, 0, sizeof ( msg ) );
 
264
        msg.header.type = cpu_to_le32 ( buffer->revoke_type );
 
265
        msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
 
266
 
 
267
        /* Send message and wait for completion */
 
268
        if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
 
269
                                     &msg, sizeof ( msg ) ) ) != 0 ) {
 
270
                DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
 
271
                       netvsc->name, strerror ( rc ) );
 
272
                return rc;
 
273
        }
 
274
 
 
275
        return 0;
 
276
}
 
277
 
 
278
/**
 
279
 * Handle received control packet
 
280
 *
 
281
 * @v vmdev             VMBus device
 
282
 * @v xid               Transaction ID
 
283
 * @v data              Data
 
284
 * @v len               Length of data
 
285
 * @ret rc              Return status code
 
286
 */
 
287
static int netvsc_recv_control ( struct vmbus_device *vmdev, uint64_t xid,
 
288
                                 const void *data, size_t len ) {
 
289
        struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
 
290
        struct netvsc_device *netvsc = rndis->priv;
 
291
 
 
292
        DBGC ( netvsc, "NETVSC %s received unsupported control packet "
 
293
               "(%08llx):\n", netvsc->name, xid );
 
294
        DBGC_HDA ( netvsc, 0, data, len );
 
295
        return -ENOTSUP;
 
296
}
 
297
 
 
298
/**
 
299
 * Handle received data packet
 
300
 *
 
301
 * @v vmdev             VMBus device
 
302
 * @v xid               Transaction ID
 
303
 * @v data              Data
 
304
 * @v len               Length of data
 
305
 * @v list              List of I/O buffers
 
306
 * @ret rc              Return status code
 
307
 */
 
308
static int netvsc_recv_data ( struct vmbus_device *vmdev, uint64_t xid,
 
309
                              const void *data, size_t len,
 
310
                              struct list_head *list ) {
 
311
        struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
 
312
        struct netvsc_device *netvsc = rndis->priv;
 
313
        const struct netvsc_rndis_message *msg = data;
 
314
        struct io_buffer *iobuf;
 
315
        struct io_buffer *tmp;
 
316
        int rc;
 
317
 
 
318
        /* Sanity check */
 
319
        if ( len < sizeof ( *msg ) ) {
 
320
                DBGC ( netvsc, "NETVSC %s received underlength RNDIS packet "
 
321
                       "(%zd bytes)\n", netvsc->name, len );
 
322
                rc = -EINVAL;
 
323
                goto err_sanity;
 
324
        }
 
325
        if ( msg->header.type != cpu_to_le32 ( NETVSC_RNDIS_MSG ) ) {
 
326
                DBGC ( netvsc, "NETVSC %s received unexpected RNDIS packet "
 
327
                       "type %d\n", netvsc->name,
 
328
                       le32_to_cpu ( msg->header.type ) );
 
329
                rc = -EINVAL;
 
330
                goto err_sanity;
 
331
        }
 
332
 
 
333
        /* Send completion back to host */
 
334
        if ( ( rc = vmbus_send_completion ( vmdev, xid, NULL, 0 ) ) != 0 ) {
 
335
                DBGC ( netvsc, "NETVSC %s could not send completion: %s\n",
 
336
                       netvsc->name, strerror ( rc ) );
 
337
                goto err_completion;
 
338
        }
 
339
 
 
340
        /* Hand off to RNDIS */
 
341
        list_for_each_entry_safe ( iobuf, tmp, list, list ) {
 
342
                list_del ( &iobuf->list );
 
343
                rndis_rx ( rndis, iob_disown ( iobuf ) );
 
344
        }
 
345
 
 
346
        return 0;
 
347
 
 
348
 err_completion:
 
349
 err_sanity:
 
350
        list_for_each_entry_safe ( iobuf, tmp, list, list ) {
 
351
                list_del ( &iobuf->list );
 
352
                free_iob ( iobuf );
 
353
        }
 
354
        return rc;
 
355
}
 
356
 
 
357
/**
 
358
 * Handle received completion packet
 
359
 *
 
360
 * @v vmdev             VMBus device
 
361
 * @v xid               Transaction ID
 
362
 * @v data              Data
 
363
 * @v len               Length of data
 
364
 * @ret rc              Return status code
 
365
 */
 
366
static int netvsc_recv_completion ( struct vmbus_device *vmdev, uint64_t xid,
 
367
                                    const void *data, size_t len ) {
 
368
        struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
 
369
        struct netvsc_device *netvsc = rndis->priv;
 
370
        struct io_buffer *iobuf;
 
371
        int ( * completion ) ( struct netvsc_device *netvsc,
 
372
                               const void *data, size_t len );
 
373
        unsigned int xrid = ( xid - NETVSC_BASE_XID );
 
374
        unsigned int tx_id;
 
375
        int rc;
 
376
 
 
377
        /* Handle transmit completion, if applicable */
 
378
        tx_id = ( xrid - NETVSC_TX_BASE_XRID );
 
379
        if ( ( tx_id < NETVSC_TX_NUM_DESC ) &&
 
380
             ( ( iobuf = netvsc->tx.iobufs[tx_id] ) != NULL ) ) {
 
381
 
 
382
                /* Free buffer ID */
 
383
                netvsc->tx.iobufs[tx_id] = NULL;
 
384
                netvsc->tx.ids[ ( netvsc->tx.id_cons++ ) &
 
385
                                ( netvsc->tx.count - 1 ) ] = tx_id;
 
386
 
 
387
                /* Hand back to RNDIS */
 
388
                rndis_tx_complete ( rndis, iobuf );
 
389
                return 0;
 
390
        }
 
391
 
 
392
        /* Otherwise determine completion handler */
 
393
        if ( xrid == NETVSC_INIT_XRID ) {
 
394
                completion = netvsc_initialised;
 
395
        } else if ( xrid == NETVSC_RX_ESTABLISH_XRID ) {
 
396
                completion = netvsc_rx_established_buffer;
 
397
        } else if ( ( netvsc->wait_xrid != 0 ) &&
 
398
                    ( xrid == netvsc->wait_xrid ) ) {
 
399
                completion = netvsc_completed;
 
400
        } else {
 
401
                DBGC ( netvsc, "NETVSC %s received unexpected completion "
 
402
                       "(%08llx)\n", netvsc->name, xid );
 
403
                return -EPIPE;
 
404
        }
 
405
 
 
406
        /* Hand off to completion handler */
 
407
        rc = completion ( netvsc, data, len );
 
408
 
 
409
        /* Record completion handler result if applicable */
 
410
        if ( xrid == netvsc->wait_xrid ) {
 
411
                netvsc->wait_xrid = 0;
 
412
                netvsc->wait_rc = rc;
 
413
        }
 
414
 
 
415
        return rc;
 
416
}
 
417
 
 
418
/**
 
419
 * Handle received cancellation packet
 
420
 *
 
421
 * @v vmdev             VMBus device
 
422
 * @v xid               Transaction ID
 
423
 * @ret rc              Return status code
 
424
 */
 
425
static int netvsc_recv_cancellation ( struct vmbus_device *vmdev,
 
426
                                      uint64_t xid ) {
 
427
        struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
 
428
        struct netvsc_device *netvsc = rndis->priv;
 
429
 
 
430
        DBGC ( netvsc, "NETVSC %s received unsupported cancellation packet "
 
431
               "(%08llx):\n", netvsc->name, xid );
 
432
        return -ENOTSUP;
 
433
}
 
434
 
 
435
/** VMBus channel operations */
 
436
static struct vmbus_channel_operations netvsc_channel_operations = {
 
437
        .recv_control = netvsc_recv_control,
 
438
        .recv_data = netvsc_recv_data,
 
439
        .recv_completion = netvsc_recv_completion,
 
440
        .recv_cancellation = netvsc_recv_cancellation,
 
441
};
 
442
 
 
443
/**
 
444
 * Poll for completed and received packets
 
445
 *
 
446
 * @v rndis             RNDIS device
 
447
 */
 
448
static void netvsc_poll ( struct rndis_device *rndis ) {
 
449
        struct netvsc_device *netvsc = rndis->priv;
 
450
        struct vmbus_device *vmdev = netvsc->vmdev;
 
451
 
 
452
        /* Poll VMBus device */
 
453
        while ( vmbus_has_data ( vmdev ) )
 
454
                vmbus_poll ( vmdev );
 
455
}
 
456
 
 
457
/**
 
458
 * Transmit packet
 
459
 *
 
460
 * @v rndis             RNDIS device
 
461
 * @v iobuf             I/O buffer
 
462
 * @ret rc              Return status code
 
463
 *
 
464
 * If this method returns success then the RNDIS device must
 
465
 * eventually report completion via rndis_tx_complete().
 
466
 */
 
467
static int netvsc_transmit ( struct rndis_device *rndis,
 
468
                             struct io_buffer *iobuf ) {
 
469
        struct netvsc_device *netvsc = rndis->priv;
 
470
        struct rndis_header *header = iobuf->data;
 
471
        struct netvsc_rndis_message msg;
 
472
        unsigned int tx_id;
 
473
        unsigned int xrid;
 
474
        uint64_t xid;
 
475
        int rc;
 
476
 
 
477
        /* Sanity check */
 
478
        assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
 
479
        assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
 
480
 
 
481
        /* Check that we have space in the transmit ring */
 
482
        if ( netvsc_ring_is_full ( &netvsc->tx ) )
 
483
                return rndis_tx_defer ( rndis, iobuf );
 
484
 
 
485
        /* Allocate buffer ID and calculate transaction ID */
 
486
        tx_id = netvsc->tx.ids[ netvsc->tx.id_prod & ( netvsc->tx.count - 1 ) ];
 
487
        assert ( netvsc->tx.iobufs[tx_id] == NULL );
 
488
        xrid = ( NETVSC_TX_BASE_XRID + tx_id );
 
489
        xid = ( NETVSC_BASE_XID + xrid );
 
490
 
 
491
        /* Construct message */
 
492
        memset ( &msg, 0, sizeof ( msg ) );
 
493
        msg.header.type = cpu_to_le32 ( NETVSC_RNDIS_MSG );
 
494
        msg.channel = ( ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) ?
 
495
                        NETVSC_RNDIS_DATA : NETVSC_RNDIS_CONTROL );
 
496
        msg.buffer = cpu_to_le32 ( NETVSC_RNDIS_NO_BUFFER );
 
497
 
 
498
        /* Send message */
 
499
        if ( ( rc = vmbus_send_data ( netvsc->vmdev, xid, &msg, sizeof ( msg ),
 
500
                                      iobuf ) ) != 0 ) {
 
501
                DBGC ( netvsc, "NETVSC %s could not send RNDIS message: %s\n",
 
502
                       netvsc->name, strerror ( rc ) );
 
503
                return rc;
 
504
        }
 
505
 
 
506
        /* Store I/O buffer and consume buffer ID */
 
507
        netvsc->tx.iobufs[tx_id] = iobuf;
 
508
        netvsc->tx.id_prod++;
 
509
 
 
510
        return 0;
 
511
}
 
512
 
 
513
/**
 
514
 * Cancel transmission
 
515
 *
 
516
 * @v netvsc            NetVSC device
 
517
 * @v iobuf             I/O buffer
 
518
 * @v tx_id             Transmission ID
 
519
 */
 
520
static void netvsc_cancel_transmit ( struct netvsc_device *netvsc,
 
521
                                     struct io_buffer *iobuf,
 
522
                                     unsigned int tx_id ) {
 
523
        unsigned int xrid;
 
524
        uint64_t xid;
 
525
 
 
526
        /* Send cancellation */
 
527
        xrid = ( NETVSC_TX_BASE_XRID + tx_id );
 
528
        xid = ( NETVSC_BASE_XID + xrid );
 
529
        DBGC ( netvsc, "NETVSC %s cancelling transmission %#x\n",
 
530
               netvsc->name, tx_id );
 
531
        vmbus_send_cancellation ( netvsc->vmdev, xid );
 
532
 
 
533
        /* Report back to RNDIS */
 
534
        rndis_tx_complete_err ( netvsc->rndis, iobuf, -ECANCELED );
 
535
}
 
536
 
 
537
/**
 
538
 * Create descriptor ring
 
539
 *
 
540
 * @v netvsc            NetVSC device
 
541
 * @v ring              Descriptor ring
 
542
 * @ret rc              Return status code
 
543
 */
 
544
static int netvsc_create_ring ( struct netvsc_device *netvsc __unused,
 
545
                                struct netvsc_ring *ring ) {
 
546
        unsigned int i;
 
547
 
 
548
        /* Initialise buffer ID ring */
 
549
        for ( i = 0 ; i < ring->count ; i++ ) {
 
550
                ring->ids[i] = i;
 
551
                assert ( ring->iobufs[i] == NULL );
 
552
        }
 
553
        ring->id_prod = 0;
 
554
        ring->id_cons = 0;
 
555
 
 
556
        return 0;
 
557
}
 
558
 
 
559
/**
 
560
 * Destroy descriptor ring
 
561
 *
 
562
 * @v netvsc            NetVSC device
 
563
 * @v ring              Descriptor ring
 
564
 * @v discard           Method used to discard outstanding buffer, or NULL
 
565
 */
 
566
static void netvsc_destroy_ring ( struct netvsc_device *netvsc,
 
567
                                  struct netvsc_ring *ring,
 
568
                                  void ( * discard ) ( struct netvsc_device *,
 
569
                                                       struct io_buffer *,
 
570
                                                       unsigned int ) ) {
 
571
        struct io_buffer *iobuf;
 
572
        unsigned int i;
 
573
 
 
574
        /* Flush any outstanding buffers */
 
575
        for ( i = 0 ; i < ring->count ; i++ ) {
 
576
                iobuf = ring->iobufs[i];
 
577
                if ( ! iobuf )
 
578
                        continue;
 
579
                ring->iobufs[i] = NULL;
 
580
                ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = i;
 
581
                if ( discard )
 
582
                        discard ( netvsc, iobuf, i );
 
583
        }
 
584
 
 
585
        /* Sanity check */
 
586
        assert ( netvsc_ring_is_empty ( ring ) );
 
587
}
 
588
 
 
589
/**
 
590
 * Copy data from data buffer
 
591
 *
 
592
 * @v pages             Transfer page set
 
593
 * @v data              Data buffer
 
594
 * @v offset            Offset within page set
 
595
 * @v len               Length within page set
 
596
 * @ret rc              Return status code
 
597
 */
 
598
static int netvsc_buffer_copy ( struct vmbus_xfer_pages *pages, void *data,
 
599
                                size_t offset, size_t len ) {
 
600
        struct netvsc_buffer *buffer =
 
601
                container_of ( pages, struct netvsc_buffer, pages );
 
602
 
 
603
        /* Sanity check */
 
604
        if ( ( offset > buffer->len ) || ( len > ( buffer->len - offset ) ) )
 
605
                return -ERANGE;
 
606
 
 
607
        /* Copy data from buffer */
 
608
        copy_from_user ( data, buffer->data, offset, len );
 
609
 
 
610
        return 0;
 
611
}
 
612
 
 
613
/** Transfer page set operations */
 
614
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations = {
 
615
        .copy = netvsc_buffer_copy,
 
616
};
 
617
 
 
618
/**
 
619
 * Create data buffer
 
620
 *
 
621
 * @v netvsc            NetVSC device
 
622
 * @v buffer            Data buffer
 
623
 * @ret rc              Return status code
 
624
 */
 
625
static int netvsc_create_buffer ( struct netvsc_device *netvsc,
 
626
                                  struct netvsc_buffer *buffer ) {
 
627
        struct vmbus_device *vmdev = netvsc->vmdev;
 
628
        int gpadl;
 
629
        int rc;
 
630
 
 
631
        /* Allocate receive buffer */
 
632
        buffer->data = umalloc ( buffer->len );
 
633
        if ( ! buffer->data ) {
 
634
                DBGC ( netvsc, "NETVSC %s could not allocate %zd-byte buffer\n",
 
635
                       netvsc->name, buffer->len );
 
636
                rc = -ENOMEM;
 
637
                goto err_alloc;
 
638
        }
 
639
 
 
640
        /* Establish GPA descriptor list */
 
641
        gpadl = vmbus_establish_gpadl ( vmdev, buffer->data, buffer->len );
 
642
        if ( gpadl < 0 ) {
 
643
                rc = gpadl;
 
644
                DBGC ( netvsc, "NETVSC %s could not establish GPADL: %s\n",
 
645
                       netvsc->name, strerror ( rc ) );
 
646
                goto err_establish_gpadl;
 
647
        }
 
648
        buffer->gpadl = gpadl;
 
649
 
 
650
        /* Register transfer page set */
 
651
        if ( ( rc = vmbus_register_pages ( vmdev, &buffer->pages ) ) != 0 ) {
 
652
                DBGC ( netvsc, "NETVSC %s could not register transfer pages: "
 
653
                       "%s\n", netvsc->name, strerror ( rc ) );
 
654
                goto err_register_pages;
 
655
        }
 
656
 
 
657
        return 0;
 
658
 
 
659
        vmbus_unregister_pages ( vmdev, &buffer->pages );
 
660
 err_register_pages:
 
661
        vmbus_gpadl_teardown ( vmdev, gpadl );
 
662
 err_establish_gpadl:
 
663
        ufree ( buffer->data );
 
664
 err_alloc:
 
665
        return rc;
 
666
}
 
667
 
 
668
/**
 
669
 * Destroy data buffer
 
670
 *
 
671
 * @v netvsc            NetVSC device
 
672
 * @v buffer            Data buffer
 
673
 */
 
674
static void netvsc_destroy_buffer ( struct netvsc_device *netvsc,
 
675
                                    struct netvsc_buffer *buffer ) {
 
676
        struct vmbus_device *vmdev = netvsc->vmdev;
 
677
        int rc;
 
678
 
 
679
        /* Unregister transfer pages */
 
680
        vmbus_unregister_pages ( vmdev, &buffer->pages );
 
681
 
 
682
        /* Tear down GPA descriptor list */
 
683
        if ( ( rc = vmbus_gpadl_teardown ( vmdev, buffer->gpadl ) ) != 0 ) {
 
684
                DBGC ( netvsc, "NETVSC %s could not tear down GPADL: %s\n",
 
685
                       netvsc->name, strerror ( rc ) );
 
686
                /* Death is imminent.  The host may well continue to
 
687
                 * write to the data buffer.  The best we can do is
 
688
                 * leak memory for now and hope that the host doesn't
 
689
                 * write to this region after we load an OS.
 
690
                 */
 
691
                return;
 
692
        }
 
693
 
 
694
        /* Free buffer */
 
695
        ufree ( buffer->data );
 
696
}
 
697
 
 
698
/**
 
699
 * Open device
 
700
 *
 
701
 * @v rndis             RNDIS device
 
702
 * @ret rc              Return status code
 
703
 */
 
704
static int netvsc_open ( struct rndis_device *rndis ) {
 
705
        struct netvsc_device *netvsc = rndis->priv;
 
706
        int rc;
 
707
 
 
708
        /* Initialise receive buffer */
 
709
        if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
 
710
                goto err_create_rx;
 
711
 
 
712
        /* Open channel */
 
713
        if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
 
714
                                 PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
 
715
                DBGC ( netvsc, "NETVSC %s could not open VMBus: %s\n",
 
716
                       netvsc->name, strerror ( rc ) );
 
717
                goto err_vmbus_open;
 
718
        }
 
719
 
 
720
        /* Initialise communication with NetVSP */
 
721
        if ( ( rc = netvsc_initialise ( netvsc ) ) != 0 )
 
722
                goto err_initialise;
 
723
        if ( ( rc = netvsc_ndis_version ( netvsc ) ) != 0 )
 
724
                goto err_ndis_version;
 
725
 
 
726
        /* Initialise transmit ring */
 
727
        if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
 
728
                goto err_create_tx;
 
729
 
 
730
        /* Establish receive buffer */
 
731
        if ( ( rc = netvsc_establish_buffer ( netvsc, &netvsc->rx ) ) != 0 )
 
732
                goto err_establish_rx;
 
733
 
 
734
        return 0;
 
735
 
 
736
        netvsc_revoke_buffer ( netvsc, &netvsc->rx );
 
737
 err_establish_rx:
 
738
        netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
 
739
 err_create_tx:
 
740
 err_ndis_version:
 
741
 err_initialise:
 
742
        vmbus_close ( netvsc->vmdev );
 
743
 err_vmbus_open:
 
744
        netvsc_destroy_buffer ( netvsc, &netvsc->rx );
 
745
 err_create_rx:
 
746
        return rc;
 
747
}
 
748
 
 
749
/**
 
750
 * Close device
 
751
 *
 
752
 * @v rndis             RNDIS device
 
753
 */
 
754
static void netvsc_close ( struct rndis_device *rndis ) {
 
755
        struct netvsc_device *netvsc = rndis->priv;
 
756
 
 
757
        /* Revoke receive buffer */
 
758
        netvsc_revoke_buffer ( netvsc, &netvsc->rx );
 
759
 
 
760
        /* Destroy transmit ring */
 
761
        netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
 
762
 
 
763
        /* Close channel */
 
764
        vmbus_close ( netvsc->vmdev );
 
765
 
 
766
        /* Destroy receive buffer */
 
767
        netvsc_destroy_buffer ( netvsc, &netvsc->rx );
 
768
}
 
769
 
 
770
/** RNDIS operations */
 
771
static struct rndis_operations netvsc_operations = {
 
772
        .open = netvsc_open,
 
773
        .close = netvsc_close,
 
774
        .transmit = netvsc_transmit,
 
775
        .poll = netvsc_poll,
 
776
};
 
777
 
 
778
/**
 
779
 * Probe device
 
780
 *
 
781
 * @v vmdev             VMBus device
 
782
 * @ret rc              Return status code
 
783
 */
 
784
static int netvsc_probe ( struct vmbus_device *vmdev ) {
 
785
        struct netvsc_device *netvsc;
 
786
        struct rndis_device *rndis;
 
787
        int rc;
 
788
 
 
789
        /* Allocate and initialise structure */
 
790
        rndis = alloc_rndis ( sizeof ( *netvsc ) );
 
791
        if ( ! rndis ) {
 
792
                rc = -ENOMEM;
 
793
                goto err_alloc;
 
794
        }
 
795
        rndis_init ( rndis, &netvsc_operations );
 
796
        rndis->netdev->dev = &vmdev->dev;
 
797
        netvsc = rndis->priv;
 
798
        netvsc->vmdev = vmdev;
 
799
        netvsc->rndis = rndis;
 
800
        netvsc->name = vmdev->dev.name;
 
801
        netvsc_init_ring ( &netvsc->tx, NETVSC_TX_NUM_DESC,
 
802
                           netvsc->tx_iobufs, netvsc->tx_ids );
 
803
        netvsc_init_buffer ( &netvsc->rx, NETVSC_RX_BUF_PAGESET,
 
804
                             &netvsc_xfer_pages_operations,
 
805
                             NETVSC_RX_ESTABLISH_MSG, NETVSC_RX_ESTABLISH_XRID,
 
806
                             NETVSC_RX_REVOKE_MSG, NETVSC_RX_REVOKE_XRID,
 
807
                             NETVSC_RX_BUF_LEN );
 
808
        vmbus_set_drvdata ( vmdev, rndis );
 
809
 
 
810
        /* Register RNDIS device */
 
811
        if ( ( rc = register_rndis ( rndis ) ) != 0 ) {
 
812
                DBGC ( netvsc, "NETVSC %s could not register: %s\n",
 
813
                       netvsc->name, strerror ( rc ) );
 
814
                goto err_register;
 
815
        }
 
816
 
 
817
        return 0;
 
818
 
 
819
        unregister_rndis ( rndis );
 
820
 err_register:
 
821
        free_rndis ( rndis );
 
822
 err_alloc:
 
823
        return rc;
 
824
}
 
825
 
 
826
/**
 
827
 * Remove device
 
828
 *
 
829
 * @v vmdev             VMBus device
 
830
 */
 
831
static void netvsc_remove ( struct vmbus_device *vmdev ) {
 
832
        struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
 
833
 
 
834
        /* Unregister RNDIS device */
 
835
        unregister_rndis ( rndis );
 
836
 
 
837
        /* Free RNDIS device */
 
838
        free_rndis ( rndis );
 
839
}
 
840
 
 
841
/** NetVSC driver */
 
842
struct vmbus_driver netvsc_driver __vmbus_driver = {
 
843
        .name = "netvsc",
 
844
        .type = VMBUS_TYPE ( 0xf8615163, 0xdf3e, 0x46c5, 0x913f,
 
845
                             0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e ),
 
846
        .probe = netvsc_probe,
 
847
        .remove = netvsc_remove,
 
848
};