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 15 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,20 +66,27 @@ enum {
66 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 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 90
    u16 num;
84 91
 
85 92
    /* select the queue */
@@ -106,9 +113,11 @@ static int vp_find_vq(unsigned int ioaddr, int queue_index)
106 113
            return -1;
107 114
    }
108 115
 
116
+   vq->queue_index = queue_index;
117
+
109 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 122
    /* activate the queue
114 123
     *
@@ -126,14 +135,14 @@ static int vp_find_vq(unsigned int ioaddr, int queue_index)
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,12 +151,12 @@ static void vring_disable_cb(int queue_index)
142 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 161
    i = head;
153 162
    while (vr->desc[i].flags & VRING_DESC_F_NEXT)
@@ -155,9 +164,9 @@ static void vring_detach(int queue_index, unsigned int head)
155 164
 
156 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 168
    wmb();
160
-   free_head[queue_index] = head;
169
+   vq->free_head = head;
161 170
 }
162 171
 
163 172
 /*
@@ -167,10 +176,10 @@ static void vring_detach(int queue_index, unsigned int head)
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 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,43 +189,42 @@ static inline int vring_more_used(int queue_index)
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 195
    struct vring_used_elem *elem;
187 196
    u32 id;
188 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 202
    wmb();
194 203
    id = elem->id;
195 204
    if (len != NULL)
196 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 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 217
 			  struct vring_list list[],
209 218
 			  unsigned int out, unsigned int in,
210 219
 			  int index, int num_added)
211 220
 {
212
-   struct vring *vr = &vring[queue_index];
221
+   struct vring *vr = &vq->vring;
213 222
    int i, avail, head, prev;
214 223
 
215
-   BUG_ON(queue_index >= QUEUE_NB);
216 224
    BUG_ON(out + in == 0);
217 225
 
218 226
    prev = 0;
219
-   head = free_head[queue_index];
227
+   head = vq->free_head;
220 228
    for (i = head; out; i = vr->desc[i].next, out--) {
221 229
 
222 230
            vr->desc[i].flags = VRING_DESC_F_NEXT;
@@ -235,25 +243,26 @@ static void vring_add_buf(int queue_index,
235 243
    }
236 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 250
    avail = (vr->avail->idx + num_added) % vr->num;
243 251
    vr->avail->ring[avail] = head;
244 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 260
    wmb();
252 261
    vr->avail->idx += num_added;
253 262
 
254 263
    mb();
255 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,7 +277,7 @@ static void virtnet_disable(struct nic *nic)
268 277
    int i;
269 278
 
270 279
    for (i = 0; i < QUEUE_NB; i++) {
271
-           vring_disable_cb(i);
280
+           vring_disable_cb(&virtqueue[i]);
272 281
            vp_del_vq(nic->ioaddr, i);
273 282
    }
274 283
    vp_reset(nic->ioaddr);
@@ -292,13 +301,13 @@ static int virtnet_poll(struct nic *nic, int retrieve)
292 301
    struct virtio_net_hdr *hdr;
293 302
    struct vring_list list[2];
294 303
 
295
-   if (!vring_more_used(RX_INDEX))
304
+   if (!vring_more_used(&virtqueue[RX_INDEX]))
296 305
            return 0;
297 306
 
298 307
    if (!retrieve)
299 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 312
    BUG_ON(len > sizeof(struct virtio_net_hdr) + ETH_FRAME_LEN);
304 313
 
@@ -315,8 +324,8 @@ static int virtnet_poll(struct nic *nic, int retrieve)
315 324
    list[1].addr = (char*)&rx_buffer[token];
316 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 330
    return 1;
322 331
 }
@@ -362,9 +371,9 @@ static void virtnet_transmit(struct nic *nic, const char *destaddr,
362 371
    list[1].addr = (char*)&tx_eth_frame;
363 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 379
     * http://www.etherboot.org/wiki/dev/devmanual
@@ -373,26 +382,26 @@ static void virtnet_transmit(struct nic *nic, const char *destaddr,
373 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 386
            mb();
378 387
            udelay(10);
379 388
    }
380 389
 
381 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 395
 static void virtnet_irq(struct nic *nic __unused, irq_action_t action)
387 396
 {
388 397
    switch ( action ) {
389 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 401
            break;
393 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 405
            break;
397 406
    case FORCE :
398 407
            break;
@@ -409,12 +418,12 @@ static void provide_buffers(struct nic *nic)
409 418
            list[0].length = sizeof(struct virtio_net_hdr);
410 419
            list[1].addr = (char*)&rx_buffer[i];
411 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 424
    /* nofify */
416 425
 
417
-   vring_kick(nic, RX_INDEX, i);
426
+   vring_kick(nic, &virtqueue[RX_INDEX], i);
418 427
 }
419 428
 
420 429
 static struct nic_operations virtnet_operations = {
@@ -464,10 +473,10 @@ static int virtnet_probe(struct nic *nic, struct pci_device *pci)
464 473
    /* initialize emit/receive queue */
465 474
 
466 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 480
                    printf("Cannot register queue #%d\n", i);
472 481
    }
473 482
 

Loading…
Cancel
Save