Browse Source

[virtio] Consolidate virtio-net static data into a struct vring_virtqueue

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
tags/v0.9.6
Laurent Vivier 16 years ago
parent
commit
14a739ba6a
1 changed files with 64 additions and 55 deletions
  1. 64
    55
      src/drivers/net/virtio-net.c

+ 64
- 55
src/drivers/net/virtio-net.c View File

66
    QUEUE_NB
66
    QUEUE_NB
67
 };
67
 };
68
 
68
 
69
-static virtio_queue_t queue[QUEUE_NB];
70
-static struct vring vring[QUEUE_NB];
71
-static u16 free_head[QUEUE_NB];
72
-static u16 last_used_idx[QUEUE_NB];
73
-static u16 vdata[QUEUE_NB][MAX_QUEUE_NUM];
69
+struct vring_virtqueue {
70
+   virtio_queue_t queue;
71
+   struct vring vring;
72
+   u16 free_head;
73
+   u16 last_used_idx;
74
+   u16 vdata[MAX_QUEUE_NUM];
75
+   /* PCI */
76
+   int queue_index;
77
+};
78
+
79
+static struct vring_virtqueue virtqueue[QUEUE_NB];
74
 
80
 
75
 /*
81
 /*
76
  * Virtio PCI interface
82
  * Virtio PCI interface
77
  *
83
  *
78
  */
84
  */
79
 
85
 
80
-static int vp_find_vq(unsigned int ioaddr, int queue_index)
86
+static int vp_find_vq(unsigned int ioaddr, int queue_index,
87
+                      struct vring_virtqueue *vq)
81
 {
88
 {
82
-   struct vring * vr = &vring[queue_index];
89
+   struct vring * vr = &vq->vring;
83
    u16 num;
90
    u16 num;
84
 
91
 
85
    /* select the queue */
92
    /* select the queue */
106
            return -1;
113
            return -1;
107
    }
114
    }
108
 
115
 
116
+   vq->queue_index = queue_index;
117
+
109
    /* initialize the queue */
118
    /* initialize the queue */
110
 
119
 
111
-   vring_init(vr, num, (unsigned char*)&queue[queue_index]);
120
+   vring_init(vr, num, (unsigned char*)&vq->queue);
112
 
121
 
113
    /* activate the queue
122
    /* activate the queue
114
     *
123
     *
126
  *
135
  *
127
  */
136
  */
128
 
137
 
129
-static void vring_enable_cb(int queue_index)
138
+static void vring_enable_cb(struct vring_virtqueue *vq)
130
 {
139
 {
131
-   vring[queue_index].avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
140
+   vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
132
 }
141
 }
133
 
142
 
134
-static void vring_disable_cb(int queue_index)
143
+static void vring_disable_cb(struct vring_virtqueue *vq)
135
 {
144
 {
136
-   vring[queue_index].avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
145
+   vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
137
 }
146
 }
138
 
147
 
139
 /*
148
 /*
142
  * put at the begin of the free list the current desc[head]
151
  * put at the begin of the free list the current desc[head]
143
  */
152
  */
144
 
153
 
145
-static void vring_detach(int queue_index, unsigned int head)
154
+static void vring_detach(struct vring_virtqueue *vq, unsigned int head)
146
 {
155
 {
147
-   struct vring *vr = &vring[queue_index];
148
-        unsigned int i;
156
+   struct vring *vr = &vq->vring;
157
+   unsigned int i;
149
 
158
 
150
-        /* find end of given descriptor */
159
+   /* find end of given descriptor */
151
 
160
 
152
    i = head;
161
    i = head;
153
    while (vr->desc[i].flags & VRING_DESC_F_NEXT)
162
    while (vr->desc[i].flags & VRING_DESC_F_NEXT)
155
 
164
 
156
    /* link it with free list and point to it */
165
    /* link it with free list and point to it */
157
 
166
 
158
-   vr->desc[i].next = free_head[queue_index];
167
+   vr->desc[i].next = vq->free_head;
159
    wmb();
168
    wmb();
160
-   free_head[queue_index] = head;
169
+   vq->free_head = head;
161
 }
170
 }
162
 
171
 
163
 /*
172
 /*
167
  *
176
  *
168
  */
177
  */
169
 
178
 
170
-static inline int vring_more_used(int queue_index)
179
+static inline int vring_more_used(struct vring_virtqueue *vq)
171
 {
180
 {
172
    wmb();
181
    wmb();
173
-   return last_used_idx[queue_index] != vring[queue_index].used->idx;
182
+   return vq->last_used_idx != vq->vring.used->idx;
174
 }
183
 }
175
 
184
 
176
 /*
185
 /*
180
  *
189
  *
181
  */
190
  */
182
 
191
 
183
-static int vring_get_buf(int queue_index, unsigned int *len)
192
+static int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len)
184
 {
193
 {
185
-   struct vring *vr = &vring[queue_index];
194
+   struct vring *vr = &vq->vring;
186
    struct vring_used_elem *elem;
195
    struct vring_used_elem *elem;
187
    u32 id;
196
    u32 id;
188
    int ret;
197
    int ret;
189
 
198
 
190
-   BUG_ON(!vring_more_used(queue_index));
199
+   BUG_ON(!vring_more_used(vq));
191
 
200
 
192
-   elem = &vr->used->ring[last_used_idx[queue_index] % vr->num];
201
+   elem = &vr->used->ring[vq->last_used_idx % vr->num];
193
    wmb();
202
    wmb();
194
    id = elem->id;
203
    id = elem->id;
195
    if (len != NULL)
204
    if (len != NULL)
196
            *len = elem->len;
205
            *len = elem->len;
197
 
206
 
198
-   ret = vdata[queue_index][id];
207
+   ret = vq->vdata[id];
199
 
208
 
200
-   vring_detach(queue_index, id);
209
+   vring_detach(vq, id);
201
 
210
 
202
-   last_used_idx[queue_index]++;
211
+   vq->last_used_idx++;
203
 
212
 
204
    return ret;
213
    return ret;
205
 }
214
 }
206
 
215
 
207
-static void vring_add_buf(int queue_index,
216
+static void vring_add_buf(struct vring_virtqueue *vq,
208
 			  struct vring_list list[],
217
 			  struct vring_list list[],
209
 			  unsigned int out, unsigned int in,
218
 			  unsigned int out, unsigned int in,
210
 			  int index, int num_added)
219
 			  int index, int num_added)
211
 {
220
 {
212
-   struct vring *vr = &vring[queue_index];
221
+   struct vring *vr = &vq->vring;
213
    int i, avail, head, prev;
222
    int i, avail, head, prev;
214
 
223
 
215
-   BUG_ON(queue_index >= QUEUE_NB);
216
    BUG_ON(out + in == 0);
224
    BUG_ON(out + in == 0);
217
 
225
 
218
    prev = 0;
226
    prev = 0;
219
-   head = free_head[queue_index];
227
+   head = vq->free_head;
220
    for (i = head; out; i = vr->desc[i].next, out--) {
228
    for (i = head; out; i = vr->desc[i].next, out--) {
221
 
229
 
222
            vr->desc[i].flags = VRING_DESC_F_NEXT;
230
            vr->desc[i].flags = VRING_DESC_F_NEXT;
235
    }
243
    }
236
    vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;
244
    vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;
237
 
245
 
238
-   free_head[queue_index] = i;
246
+   vq->free_head = i;
239
 
247
 
240
-   vdata[queue_index][head] = index;
248
+   vq->vdata[head] = index;
241
 
249
 
242
    avail = (vr->avail->idx + num_added) % vr->num;
250
    avail = (vr->avail->idx + num_added) % vr->num;
243
    vr->avail->ring[avail] = head;
251
    vr->avail->ring[avail] = head;
244
    wmb();
252
    wmb();
245
 }
253
 }
246
 
254
 
247
-static void vring_kick(struct nic *nic, int queue_index, int num_added)
255
+static void vring_kick(struct nic *nic, struct vring_virtqueue *vq,
256
+                       int num_added)
248
 {
257
 {
249
-   struct vring *vr = &vring[queue_index];
258
+   struct vring *vr = &vq->vring;
250
 
259
 
251
    wmb();
260
    wmb();
252
    vr->avail->idx += num_added;
261
    vr->avail->idx += num_added;
253
 
262
 
254
    mb();
263
    mb();
255
    if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
264
    if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
256
-           vp_notify(nic->ioaddr, queue_index);
265
+           vp_notify(nic->ioaddr, vq->queue_index);
257
 }
266
 }
258
 
267
 
259
 /*
268
 /*
268
    int i;
277
    int i;
269
 
278
 
270
    for (i = 0; i < QUEUE_NB; i++) {
279
    for (i = 0; i < QUEUE_NB; i++) {
271
-           vring_disable_cb(i);
280
+           vring_disable_cb(&virtqueue[i]);
272
            vp_del_vq(nic->ioaddr, i);
281
            vp_del_vq(nic->ioaddr, i);
273
    }
282
    }
274
    vp_reset(nic->ioaddr);
283
    vp_reset(nic->ioaddr);
292
    struct virtio_net_hdr *hdr;
301
    struct virtio_net_hdr *hdr;
293
    struct vring_list list[2];
302
    struct vring_list list[2];
294
 
303
 
295
-   if (!vring_more_used(RX_INDEX))
304
+   if (!vring_more_used(&virtqueue[RX_INDEX]))
296
            return 0;
305
            return 0;
297
 
306
 
298
    if (!retrieve)
307
    if (!retrieve)
299
            return 1;
308
            return 1;
300
 
309
 
301
-   token = vring_get_buf(RX_INDEX, &len);
310
+   token = vring_get_buf(&virtqueue[RX_INDEX], &len);
302
 
311
 
303
    BUG_ON(len > sizeof(struct virtio_net_hdr) + ETH_FRAME_LEN);
312
    BUG_ON(len > sizeof(struct virtio_net_hdr) + ETH_FRAME_LEN);
304
 
313
 
315
    list[1].addr = (char*)&rx_buffer[token];
324
    list[1].addr = (char*)&rx_buffer[token];
316
    list[1].length = ETH_FRAME_LEN;
325
    list[1].length = ETH_FRAME_LEN;
317
 
326
 
318
-   vring_add_buf(RX_INDEX, list, 0, 2, token, 0);
319
-   vring_kick(nic, RX_INDEX, 1);
327
+   vring_add_buf(&virtqueue[RX_INDEX], list, 0, 2, token, 0);
328
+   vring_kick(nic, &virtqueue[RX_INDEX], 1);
320
 
329
 
321
    return 1;
330
    return 1;
322
 }
331
 }
362
    list[1].addr = (char*)&tx_eth_frame;
371
    list[1].addr = (char*)&tx_eth_frame;
363
    list[1].length = ETH_FRAME_LEN;
372
    list[1].length = ETH_FRAME_LEN;
364
 
373
 
365
-   vring_add_buf(TX_INDEX, list, 2, 0, 0, 0);
374
+   vring_add_buf(&virtqueue[TX_INDEX], list, 2, 0, 0, 0);
366
 
375
 
367
-   vring_kick(nic, TX_INDEX, 1);
376
+   vring_kick(nic, &virtqueue[TX_INDEX], 1);
368
 
377
 
369
    /*
378
    /*
370
     * http://www.etherboot.org/wiki/dev/devmanual
379
     * http://www.etherboot.org/wiki/dev/devmanual
373
     *    before returning from this routine"
382
     *    before returning from this routine"
374
     */
383
     */
375
 
384
 
376
-   while (!vring_more_used(TX_INDEX)) {
385
+   while (!vring_more_used(&virtqueue[TX_INDEX])) {
377
            mb();
386
            mb();
378
            udelay(10);
387
            udelay(10);
379
    }
388
    }
380
 
389
 
381
    /* free desc */
390
    /* free desc */
382
 
391
 
383
-   (void)vring_get_buf(TX_INDEX, NULL);
392
+   (void)vring_get_buf(&virtqueue[TX_INDEX], NULL);
384
 }
393
 }
385
 
394
 
386
 static void virtnet_irq(struct nic *nic __unused, irq_action_t action)
395
 static void virtnet_irq(struct nic *nic __unused, irq_action_t action)
387
 {
396
 {
388
    switch ( action ) {
397
    switch ( action ) {
389
    case DISABLE :
398
    case DISABLE :
390
-           vring_disable_cb(RX_INDEX);
391
-           vring_disable_cb(TX_INDEX);
399
+           vring_disable_cb(&virtqueue[RX_INDEX]);
400
+           vring_disable_cb(&virtqueue[TX_INDEX]);
392
            break;
401
            break;
393
    case ENABLE :
402
    case ENABLE :
394
-           vring_enable_cb(RX_INDEX);
395
-           vring_enable_cb(TX_INDEX);
403
+           vring_enable_cb(&virtqueue[RX_INDEX]);
404
+           vring_enable_cb(&virtqueue[TX_INDEX]);
396
            break;
405
            break;
397
    case FORCE :
406
    case FORCE :
398
            break;
407
            break;
409
            list[0].length = sizeof(struct virtio_net_hdr);
418
            list[0].length = sizeof(struct virtio_net_hdr);
410
            list[1].addr = (char*)&rx_buffer[i];
419
            list[1].addr = (char*)&rx_buffer[i];
411
            list[1].length = ETH_FRAME_LEN;
420
            list[1].length = ETH_FRAME_LEN;
412
-           vring_add_buf(RX_INDEX, list, 0, 2, i, i);
421
+           vring_add_buf(&virtqueue[RX_INDEX], list, 0, 2, i, i);
413
    }
422
    }
414
 
423
 
415
    /* nofify */
424
    /* nofify */
416
 
425
 
417
-   vring_kick(nic, RX_INDEX, i);
426
+   vring_kick(nic, &virtqueue[RX_INDEX], i);
418
 }
427
 }
419
 
428
 
420
 static struct nic_operations virtnet_operations = {
429
 static struct nic_operations virtnet_operations = {
464
    /* initialize emit/receive queue */
473
    /* initialize emit/receive queue */
465
 
474
 
466
    for (i = 0; i < QUEUE_NB; i++) {
475
    for (i = 0; i < QUEUE_NB; i++) {
467
-           free_head[i] = 0;
468
-           last_used_idx[i] = 0;
469
-           memset((char*)&queue[i], 0, sizeof(queue[i]));
470
-           if (vp_find_vq(nic->ioaddr, i) == -1)
476
+           virtqueue[i].free_head = 0;
477
+           virtqueue[i].last_used_idx = 0;
478
+           memset((char*)&virtqueue[i].queue, 0, sizeof(virtqueue[i].queue));
479
+           if (vp_find_vq(nic->ioaddr, i, &virtqueue[i]) == -1)
471
                    printf("Cannot register queue #%d\n", i);
480
                    printf("Cannot register queue #%d\n", i);
472
    }
481
    }
473
 
482
 

Loading…
Cancel
Save