master
c 676 lines 20.5 KB
Raw
1 /*
2 * QEMU Freescale eTSEC Emulator
3 *
4 * Copyright (c) 2011-2013 AdaCore
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include "qemu/osdep.h"
25 #include "net/checksum.h"
26 #include "qemu/log.h"
27 #include "etsec.h"
28 #include "registers.h"
29 #include "system/physmem.h"
30 #include "exec/cpu-common.h"
31
32 /* #define ETSEC_RING_DEBUG */
33 /* #define HEX_DUMP */
34 /* #define DEBUG_BD */
35
36 #ifdef ETSEC_RING_DEBUG
37 static const int debug_etsec = 1;
38 #else
39 static const int debug_etsec;
40 #endif
41
42 #define RING_DEBUG(fmt, ...) do { \
43 if (debug_etsec) { \
44 qemu_log(fmt , ## __VA_ARGS__); \
45 } \
46 } while (0)
47
48 #ifdef DEBUG_BD
49
50 static void print_tx_bd_flags(uint16_t flags)
51 {
52 qemu_log(" Ready: %d\n", !!(flags & BD_TX_READY));
53 qemu_log(" PAD/CRC: %d\n", !!(flags & BD_TX_PADCRC));
54 qemu_log(" Wrap: %d\n", !!(flags & BD_WRAP));
55 qemu_log(" Interrupt: %d\n", !!(flags & BD_INTERRUPT));
56 qemu_log(" Last in frame: %d\n", !!(flags & BD_LAST));
57 qemu_log(" Tx CRC: %d\n", !!(flags & BD_TX_TC));
58 qemu_log(" User-defined preamble / defer: %d\n",
59 !!(flags & BD_TX_PREDEF));
60 qemu_log(" Huge frame enable / Late collision: %d\n",
61 !!(flags & BD_TX_HFELC));
62 qemu_log(" Control frame / Retransmission Limit: %d\n",
63 !!(flags & BD_TX_CFRL));
64 qemu_log(" Retry count: %d\n",
65 (flags >> BD_TX_RC_OFFSET) & BD_TX_RC_MASK);
66 qemu_log(" Underrun / TCP/IP off-load enable: %d\n",
67 !!(flags & BD_TX_TOEUN));
68 qemu_log(" Truncation: %d\n", !!(flags & BD_TX_TR));
69 }
70
71 static void print_rx_bd_flags(uint16_t flags)
72 {
73 qemu_log(" Empty: %d\n", !!(flags & BD_RX_EMPTY));
74 qemu_log(" Receive software ownership: %d\n", !!(flags & BD_RX_RO1));
75 qemu_log(" Wrap: %d\n", !!(flags & BD_WRAP));
76 qemu_log(" Interrupt: %d\n", !!(flags & BD_INTERRUPT));
77 qemu_log(" Last in frame: %d\n", !!(flags & BD_LAST));
78 qemu_log(" First in frame: %d\n", !!(flags & BD_RX_FIRST));
79 qemu_log(" Miss: %d\n", !!(flags & BD_RX_MISS));
80 qemu_log(" Broadcast: %d\n", !!(flags & BD_RX_BROADCAST));
81 qemu_log(" Multicast: %d\n", !!(flags & BD_RX_MULTICAST));
82 qemu_log(" Rx frame length violation: %d\n", !!(flags & BD_RX_LG));
83 qemu_log(" Rx non-octet aligned frame: %d\n", !!(flags & BD_RX_NO));
84 qemu_log(" Short frame: %d\n", !!(flags & BD_RX_SH));
85 qemu_log(" Rx CRC Error: %d\n", !!(flags & BD_RX_CR));
86 qemu_log(" Overrun: %d\n", !!(flags & BD_RX_OV));
87 qemu_log(" Truncation: %d\n", !!(flags & BD_RX_TR));
88 }
89
90
91 static void print_bd(eTSEC_rxtx_bd bd, int mode, uint32_t index)
92 {
93 qemu_log("eTSEC %s Data Buffer Descriptor (%u)\n",
94 mode == eTSEC_TRANSMIT ? "Transmit" : "Receive",
95 index);
96 qemu_log(" Flags : 0x%04x\n", bd.flags);
97 if (mode == eTSEC_TRANSMIT) {
98 print_tx_bd_flags(bd.flags);
99 } else {
100 print_rx_bd_flags(bd.flags);
101 }
102 qemu_log(" Length : 0x%04x\n", bd.length);
103 qemu_log(" Pointer : 0x%08x\n", bd.bufptr);
104 }
105
106 #endif /* DEBUG_BD */
107
108 static void read_buffer_descriptor(eTSEC *etsec,
109 hwaddr addr,
110 eTSEC_rxtx_bd *bd)
111 {
112 assert(bd != NULL);
113
114 RING_DEBUG("READ Buffer Descriptor @ 0x" HWADDR_FMT_plx"\n", addr);
115 physical_memory_read(addr,
116 bd,
117 sizeof(eTSEC_rxtx_bd));
118
119 if (etsec->regs[DMACTRL].value & DMACTRL_LE) {
120 bd->flags = lduw_le_p(&bd->flags);
121 bd->length = lduw_le_p(&bd->length);
122 bd->bufptr = ldl_le_p(&bd->bufptr);
123 } else {
124 bd->flags = lduw_be_p(&bd->flags);
125 bd->length = lduw_be_p(&bd->length);
126 bd->bufptr = ldl_be_p(&bd->bufptr);
127 }
128 }
129
130 static void write_buffer_descriptor(eTSEC *etsec,
131 hwaddr addr,
132 eTSEC_rxtx_bd *bd)
133 {
134 assert(bd != NULL);
135
136 if (etsec->regs[DMACTRL].value & DMACTRL_LE) {
137 stw_le_p(&bd->flags, bd->flags);
138 stw_le_p(&bd->length, bd->length);
139 stl_le_p(&bd->bufptr, bd->bufptr);
140 } else {
141 stw_be_p(&bd->flags, bd->flags);
142 stw_be_p(&bd->length, bd->length);
143 stl_be_p(&bd->bufptr, bd->bufptr);
144 }
145
146 RING_DEBUG("Write Buffer Descriptor @ 0x" HWADDR_FMT_plx"\n", addr);
147 physical_memory_write(addr,
148 bd,
149 sizeof(eTSEC_rxtx_bd));
150 }
151
152 static void ievent_set(eTSEC *etsec,
153 uint32_t flags)
154 {
155 etsec->regs[IEVENT].value |= flags;
156
157 etsec_update_irq(etsec);
158 }
159
160 static void tx_padding_and_crc(eTSEC *etsec, uint32_t min_frame_len)
161 {
162 int add = min_frame_len - etsec->tx_buffer_len;
163
164 /* Padding */
165 if (add > 0) {
166 RING_DEBUG("pad:%u\n", add);
167 etsec->tx_buffer = g_realloc(etsec->tx_buffer,
168 etsec->tx_buffer_len + add);
169
170 memset(etsec->tx_buffer + etsec->tx_buffer_len, 0x0, add);
171 etsec->tx_buffer_len += add;
172 }
173
174 /* Never add CRC in QEMU */
175 }
176
177 static void process_tx_fcb(eTSEC *etsec)
178 {
179 uint8_t flags = (uint8_t)(*etsec->tx_buffer);
180 /* L3 header offset from start of frame (FCB byte 3) */
181 uint8_t l3_header_offset = (uint8_t)*(etsec->tx_buffer + 3);
182 /* L4 header offset from start of L3 header (FCB byte 2) */
183 uint8_t l4_header_offset = (uint8_t)*(etsec->tx_buffer + 2);
184 uint8_t *l3_header;
185 uint8_t *l4_header;
186 int csum = 0;
187
188 /*
189 * Validate FCB header offsets before pointer arithmetic. The highest
190 * byte accessed is l4_header[7], at offset
191 * 8 (FCB size) + l3_header_offset + l4_header_offset + 7
192 * from tx_buffer. Drop the frame if this exceeds the buffer length.
193 */
194 if (etsec->tx_buffer_len < 8u + l3_header_offset + l4_header_offset + 8u) {
195 qemu_log_mask(LOG_GUEST_ERROR,
196 "eTSEC: FCB offsets exceed frame length, dropping\n");
197 return;
198 }
199
200 /* L3 header */
201 l3_header = etsec->tx_buffer + 8 + l3_header_offset;
202 /* L4 header */
203 l4_header = l3_header + l4_header_offset;
204
205 /* if packet is IP4 and IP checksum is requested */
206 if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
207 csum |= CSUM_IP;
208 }
209 /* TODO Check the correct usage of the PHCS field of the FCB in case the NPH
210 * flag is on */
211
212 /* if packet is IP4 and TCP or UDP */
213 if (flags & FCB_TX_IP && flags & FCB_TX_TUP) {
214 /* if UDP */
215 if (flags & FCB_TX_UDP) {
216 /* if checksum is requested */
217 if (flags & FCB_TX_CTU) {
218 /* do UDP checksum */
219 csum |= CSUM_UDP;
220 } else {
221 /* set checksum field to 0 */
222 l4_header[6] = 0;
223 l4_header[7] = 0;
224 }
225 } else if (flags & FCB_TX_CTU) { /* if TCP and checksum is requested */
226 /* do TCP checksum */
227 csum |= CSUM_TCP;
228 }
229 }
230
231 if (csum) {
232 net_checksum_calculate(etsec->tx_buffer + 8,
233 etsec->tx_buffer_len - 8, csum);
234 }
235 }
236
237 static void process_tx_bd(eTSEC *etsec,
238 eTSEC_rxtx_bd *bd)
239 {
240 uint8_t *tmp_buff = NULL;
241 hwaddr tbdbth = (hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32;
242
243 if (bd->length == 0) {
244 /* ERROR */
245 return;
246 }
247
248 if (etsec->tx_buffer_len == 0) {
249 /* It's the first BD */
250 etsec->first_bd = *bd;
251 }
252
253 /* TODO: if TxBD[TOE/UN] skip the Tx Frame Control Block*/
254
255 /* Load this Data Buffer */
256 etsec->tx_buffer = g_realloc(etsec->tx_buffer,
257 etsec->tx_buffer_len + bd->length);
258 tmp_buff = etsec->tx_buffer + etsec->tx_buffer_len;
259 physical_memory_read(bd->bufptr + tbdbth, tmp_buff, bd->length);
260
261 /* Update buffer length */
262 etsec->tx_buffer_len += bd->length;
263
264
265 if (etsec->tx_buffer_len != 0 && (bd->flags & BD_LAST)) {
266 if (etsec->regs[MACCFG1].value & MACCFG1_TX_EN) {
267 /* MAC Transmit enabled */
268
269 /* Process offload Tx FCB */
270 if (etsec->first_bd.flags & BD_TX_TOEUN) {
271 process_tx_fcb(etsec);
272 }
273
274 if (etsec->first_bd.flags & BD_TX_PADCRC
275 || etsec->regs[MACCFG2].value & MACCFG2_PADCRC) {
276
277 /* Padding and CRC (Padding implies CRC) */
278 tx_padding_and_crc(etsec, 60);
279
280 } else if (etsec->first_bd.flags & BD_TX_TC
281 || etsec->regs[MACCFG2].value & MACCFG2_CRC_EN) {
282
283 /* Only CRC */
284 /* Never add CRC in QEMU */
285 }
286
287 #if defined(HEX_DUMP)
288 qemu_log("eTSEC Send packet size:%d\n", etsec->tx_buffer_len);
289 qemu_hexdump(stderr, "", etsec->tx_buffer, etsec->tx_buffer_len);
290 #endif /* ETSEC_RING_DEBUG */
291
292 if (etsec->first_bd.flags & BD_TX_TOEUN) {
293 qemu_send_packet(qemu_get_queue(etsec->nic),
294 etsec->tx_buffer + 8,
295 etsec->tx_buffer_len - 8);
296 } else {
297 qemu_send_packet(qemu_get_queue(etsec->nic),
298 etsec->tx_buffer,
299 etsec->tx_buffer_len);
300 }
301
302 }
303
304 etsec->tx_buffer_len = 0;
305
306 if (bd->flags & BD_INTERRUPT) {
307 ievent_set(etsec, IEVENT_TXF);
308 }
309 } else {
310 if (bd->flags & BD_INTERRUPT) {
311 ievent_set(etsec, IEVENT_TXB);
312 }
313 }
314
315 /* Update DB flags */
316
317 /* Clear Ready */
318 bd->flags &= ~BD_TX_READY;
319
320 /* Clear Defer */
321 bd->flags &= ~BD_TX_PREDEF;
322
323 /* Clear Late Collision */
324 bd->flags &= ~BD_TX_HFELC;
325
326 /* Clear Retransmission Limit */
327 bd->flags &= ~BD_TX_CFRL;
328
329 /* Clear Retry Count */
330 bd->flags &= ~(BD_TX_RC_MASK << BD_TX_RC_OFFSET);
331
332 /* Clear Underrun */
333 bd->flags &= ~BD_TX_TOEUN;
334
335 /* Clear Truncation */
336 bd->flags &= ~BD_TX_TR;
337 }
338
339 void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr)
340 {
341 hwaddr ring_base = 0;
342 hwaddr bd_addr = 0;
343 eTSEC_rxtx_bd bd;
344 uint16_t bd_flags;
345
346 if (!(etsec->regs[MACCFG1].value & MACCFG1_TX_EN)) {
347 RING_DEBUG("%s: MAC Transmit not enabled\n", __func__);
348 return;
349 }
350
351 ring_base = (hwaddr)(etsec->regs[TBASEH].value & 0xF) << 32;
352 ring_base += etsec->regs[TBASE0 + ring_nbr].value & ~0x7;
353 bd_addr = etsec->regs[TBPTR0 + ring_nbr].value & ~0x7;
354
355 do {
356 read_buffer_descriptor(etsec, bd_addr, &bd);
357
358 #ifdef DEBUG_BD
359 print_bd(bd,
360 eTSEC_TRANSMIT,
361 (bd_addr - ring_base) / sizeof(eTSEC_rxtx_bd));
362
363 #endif /* DEBUG_BD */
364
365 /* Save flags before BD update */
366 bd_flags = bd.flags;
367
368 if (!(bd_flags & BD_TX_READY)) {
369 break;
370 }
371
372 process_tx_bd(etsec, &bd);
373 /* Write back BD after update */
374 write_buffer_descriptor(etsec, bd_addr, &bd);
375
376 /* Wrap or next BD */
377 if (bd_flags & BD_WRAP) {
378 bd_addr = ring_base;
379 } else {
380 bd_addr += sizeof(eTSEC_rxtx_bd);
381 }
382 } while (TRUE);
383
384 /* Save the Buffer Descriptor Pointers to last bd that was not
385 * successfully closed */
386 etsec->regs[TBPTR0 + ring_nbr].value = bd_addr;
387
388 /* Set transmit halt THLTx */
389 etsec->regs[TSTAT].value |= 1 << (31 - ring_nbr);
390 }
391
392 /*
393 * rx_init_frame() ensures we never do more padding than this
394 * (checksum plus minimum data packet size)
395 */
396 #define MAX_RX_PADDING 64
397
398 static void fill_rx_bd(eTSEC *etsec,
399 eTSEC_rxtx_bd *bd,
400 const uint8_t **buf,
401 size_t *size)
402 {
403 uint16_t to_write;
404 hwaddr bufptr = bd->bufptr +
405 ((hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32);
406 uint8_t padd[MAX_RX_PADDING];
407 uint8_t rem;
408
409 assert(etsec->rx_padding <= MAX_RX_PADDING);
410
411 RING_DEBUG("eTSEC fill Rx buffer @ 0x%016" HWADDR_PRIx
412 " size:%zu(padding + crc:%u) + fcb:%u\n",
413 bufptr, *size, etsec->rx_padding, etsec->rx_fcb_size);
414
415 bd->length = 0;
416
417 /* This operation will only write FCB */
418 if (etsec->rx_fcb_size != 0) {
419
420 physical_memory_write(bufptr, etsec->rx_fcb, etsec->rx_fcb_size);
421
422 bufptr += etsec->rx_fcb_size;
423 bd->length += etsec->rx_fcb_size;
424 etsec->rx_fcb_size = 0;
425
426 }
427
428 /* We remove padding from the computation of to_write because it is not
429 * allocated in the buffer.
430 */
431 to_write = MIN(*size - etsec->rx_padding,
432 etsec->regs[MRBLR].value - etsec->rx_fcb_size);
433
434 /* This operation can only write packet data and no padding */
435 if (to_write > 0) {
436 physical_memory_write(bufptr, *buf, to_write);
437
438 *buf += to_write;
439 bufptr += to_write;
440 *size -= to_write;
441
442 bd->flags &= ~BD_RX_EMPTY;
443 bd->length += to_write;
444 }
445
446 if (*size == etsec->rx_padding) {
447 /* The remaining bytes are only for padding which is not actually
448 * allocated in the data buffer.
449 */
450
451 rem = MIN(etsec->regs[MRBLR].value - bd->length, etsec->rx_padding);
452
453 if (rem > 0) {
454 memset(padd, 0x0, rem);
455 etsec->rx_padding -= rem;
456 *size -= rem;
457 bd->length += rem;
458 physical_memory_write(bufptr, padd, rem);
459 }
460 }
461 }
462
463 static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size)
464 {
465 uint32_t fcb_size = 0;
466 uint8_t prsdep = (etsec->regs[RCTRL].value >> RCTRL_PRSDEP_OFFSET)
467 & RCTRL_PRSDEP_MASK;
468
469 if (prsdep != 0) {
470 /* Prepend FCB (FCB size + RCTRL[PAL]) */
471 fcb_size = 8 + ((etsec->regs[RCTRL].value >> 16) & 0x1F);
472
473 etsec->rx_fcb_size = fcb_size;
474
475 /* TODO: fill_FCB(etsec); */
476 memset(etsec->rx_fcb, 0x0, sizeof(etsec->rx_fcb));
477
478 } else {
479 etsec->rx_fcb_size = 0;
480 }
481
482 g_free(etsec->rx_buffer);
483
484 /* Do not copy the frame for now */
485 etsec->rx_buffer = (uint8_t *)buf;
486 etsec->rx_buffer_len = size;
487
488 /* CRC padding (We don't have to compute the CRC) */
489 etsec->rx_padding = 4;
490
491 /*
492 * Ensure that payload length + CRC length is at least 802.3
493 * minimum MTU size bytes long (64)
494 */
495 if (etsec->rx_buffer_len < 60) {
496 etsec->rx_padding += 60 - etsec->rx_buffer_len;
497 }
498
499 etsec->rx_first_in_frame = 1;
500 etsec->rx_remaining_data = etsec->rx_buffer_len;
501 RING_DEBUG("%s: rx_buffer_len:%u rx_padding+crc:%u\n", __func__,
502 etsec->rx_buffer_len, etsec->rx_padding);
503 }
504
505 ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
506 {
507 int ring_nbr = 0; /* Always use ring0 (no filer) */
508
509 if (etsec->rx_buffer_len != 0) {
510 RING_DEBUG("%s: We can't receive now,"
511 " a buffer is already in the pipe\n", __func__);
512 return 0;
513 }
514
515 if (etsec->regs[RSTAT].value & 1 << (23 - ring_nbr)) {
516 RING_DEBUG("%s: The ring is halted\n", __func__);
517 return -1;
518 }
519
520 if (etsec->regs[DMACTRL].value & DMACTRL_GRS) {
521 RING_DEBUG("%s: Graceful receive stop\n", __func__);
522 return -1;
523 }
524
525 if (!(etsec->regs[MACCFG1].value & MACCFG1_RX_EN)) {
526 RING_DEBUG("%s: MAC Receive not enabled\n", __func__);
527 return -1;
528 }
529
530 if (!(etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) {
531 /* CRC is not in the packet yet, so short frame is below 60 bytes */
532 RING_DEBUG("%s: Drop short frame\n", __func__);
533 return -1;
534 }
535
536 rx_init_frame(etsec, buf, size);
537
538 etsec_walk_rx_ring(etsec, ring_nbr);
539
540 return size;
541 }
542
543 void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
544 {
545 hwaddr ring_base = 0;
546 hwaddr bd_addr = 0;
547 hwaddr start_bd_addr = 0;
548 eTSEC_rxtx_bd bd;
549 uint16_t bd_flags;
550 size_t remaining_data;
551 const uint8_t *buf;
552 uint8_t *tmp_buf;
553 size_t size;
554
555 if (etsec->rx_buffer_len == 0) {
556 /* No frame to send */
557 RING_DEBUG("No frame to send\n");
558 return;
559 }
560
561 remaining_data = etsec->rx_remaining_data + etsec->rx_padding;
562 buf = etsec->rx_buffer
563 + (etsec->rx_buffer_len - etsec->rx_remaining_data);
564 size = etsec->rx_buffer_len + etsec->rx_padding;
565
566 ring_base = (hwaddr)(etsec->regs[RBASEH].value & 0xF) << 32;
567 ring_base += etsec->regs[RBASE0 + ring_nbr].value & ~0x7;
568 start_bd_addr = bd_addr = etsec->regs[RBPTR0 + ring_nbr].value & ~0x7;
569
570 do {
571 read_buffer_descriptor(etsec, bd_addr, &bd);
572
573 #ifdef DEBUG_BD
574 print_bd(bd,
575 eTSEC_RECEIVE,
576 (bd_addr - ring_base) / sizeof(eTSEC_rxtx_bd));
577
578 #endif /* DEBUG_BD */
579
580 /* Save flags before BD update */
581 bd_flags = bd.flags;
582
583 if (bd_flags & BD_RX_EMPTY) {
584 fill_rx_bd(etsec, &bd, &buf, &remaining_data);
585
586 if (etsec->rx_first_in_frame) {
587 bd.flags |= BD_RX_FIRST;
588 etsec->rx_first_in_frame = 0;
589 etsec->rx_first_bd = bd;
590 }
591
592 /* Last in frame */
593 if (remaining_data == 0) {
594
595 /* Clear flags */
596
597 bd.flags &= ~0x7ff;
598
599 bd.flags |= BD_LAST;
600
601 /* NOTE: non-octet aligned frame is impossible in qemu */
602
603 if (size >= etsec->regs[MAXFRM].value) {
604 /* frame length violation */
605 qemu_log("%s frame length violation: size:%zu MAXFRM:%d\n",
606 __func__, size, etsec->regs[MAXFRM].value);
607
608 bd.flags |= BD_RX_LG;
609 }
610
611 if (size < 64) {
612 /* Short frame */
613 bd.flags |= BD_RX_SH;
614 }
615
616 /* TODO: Broadcast and Multicast */
617
618 if (bd.flags & BD_INTERRUPT) {
619 /* Set RXFx */
620 etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
621
622 /* Set IEVENT */
623 ievent_set(etsec, IEVENT_RXF);
624 }
625
626 } else {
627 if (bd.flags & BD_INTERRUPT) {
628 /* Set IEVENT */
629 ievent_set(etsec, IEVENT_RXB);
630 }
631 }
632
633 /* Write back BD after update */
634 write_buffer_descriptor(etsec, bd_addr, &bd);
635 }
636
637 /* Wrap or next BD */
638 if (bd_flags & BD_WRAP) {
639 bd_addr = ring_base;
640 } else {
641 bd_addr += sizeof(eTSEC_rxtx_bd);
642 }
643 } while (remaining_data != 0
644 && (bd_flags & BD_RX_EMPTY)
645 && bd_addr != start_bd_addr);
646
647 /* Reset ring ptr */
648 etsec->regs[RBPTR0 + ring_nbr].value = bd_addr;
649
650 /* The frame is too large to fit in the Rx ring */
651 if (remaining_data > 0) {
652
653 /* Set RSTAT[QHLTx] */
654 etsec->regs[RSTAT].value |= 1 << (23 - ring_nbr);
655
656 /* Save remaining data to send the end of the frame when the ring will
657 * be restarted
658 */
659 etsec->rx_remaining_data = remaining_data;
660
661 /* Copy the frame */
662 tmp_buf = g_malloc(size);
663 memcpy(tmp_buf, etsec->rx_buffer, size);
664 etsec->rx_buffer = tmp_buf;
665
666 RING_DEBUG("no empty RxBD available any more\n");
667 } else {
668 etsec->rx_buffer_len = 0;
669 etsec->rx_buffer = NULL;
670 if (etsec->need_flush) {
671 qemu_flush_queued_packets(qemu_get_queue(etsec->nic));
672 }
673 }
674
675 RING_DEBUG("eTSEC End of ring_write: remaining_data:%zu\n", remaining_data);
676 }