Lines Matching refs:etsec

106 static void read_buffer_descriptor(eTSEC         *etsec,  in read_buffer_descriptor()  argument
117 if (etsec->regs[DMACTRL].value & DMACTRL_LE) { in read_buffer_descriptor()
128 static void write_buffer_descriptor(eTSEC *etsec, in write_buffer_descriptor() argument
134 if (etsec->regs[DMACTRL].value & DMACTRL_LE) { in write_buffer_descriptor()
150 static void ievent_set(eTSEC *etsec, in ievent_set() argument
153 etsec->regs[IEVENT].value |= flags; in ievent_set()
155 etsec_update_irq(etsec); in ievent_set()
158 static void tx_padding_and_crc(eTSEC *etsec, uint32_t min_frame_len) in tx_padding_and_crc() argument
160 int add = min_frame_len - etsec->tx_buffer_len; in tx_padding_and_crc()
165 etsec->tx_buffer = g_realloc(etsec->tx_buffer, in tx_padding_and_crc()
166 etsec->tx_buffer_len + add); in tx_padding_and_crc()
168 memset(etsec->tx_buffer + etsec->tx_buffer_len, 0x0, add); in tx_padding_and_crc()
169 etsec->tx_buffer_len += add; in tx_padding_and_crc()
175 static void process_tx_fcb(eTSEC *etsec) in process_tx_fcb() argument
177 uint8_t flags = (uint8_t)(*etsec->tx_buffer); in process_tx_fcb()
179 uint8_t l3_header_offset = (uint8_t)*(etsec->tx_buffer + 3); in process_tx_fcb()
181 uint8_t l4_header_offset = (uint8_t)*(etsec->tx_buffer + 2); in process_tx_fcb()
183 uint8_t *l3_header = etsec->tx_buffer + 8 + l3_header_offset; in process_tx_fcb()
215 net_checksum_calculate(etsec->tx_buffer + 8, in process_tx_fcb()
216 etsec->tx_buffer_len - 8, csum); in process_tx_fcb()
220 static void process_tx_bd(eTSEC *etsec, in process_tx_bd() argument
224 hwaddr tbdbth = (hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32; in process_tx_bd()
231 if (etsec->tx_buffer_len == 0) { in process_tx_bd()
233 etsec->first_bd = *bd; in process_tx_bd()
239 etsec->tx_buffer = g_realloc(etsec->tx_buffer, in process_tx_bd()
240 etsec->tx_buffer_len + bd->length); in process_tx_bd()
241 tmp_buff = etsec->tx_buffer + etsec->tx_buffer_len; in process_tx_bd()
245 etsec->tx_buffer_len += bd->length; in process_tx_bd()
248 if (etsec->tx_buffer_len != 0 && (bd->flags & BD_LAST)) { in process_tx_bd()
249 if (etsec->regs[MACCFG1].value & MACCFG1_TX_EN) { in process_tx_bd()
253 if (etsec->first_bd.flags & BD_TX_TOEUN) { in process_tx_bd()
254 process_tx_fcb(etsec); in process_tx_bd()
257 if (etsec->first_bd.flags & BD_TX_PADCRC in process_tx_bd()
258 || etsec->regs[MACCFG2].value & MACCFG2_PADCRC) { in process_tx_bd()
261 tx_padding_and_crc(etsec, 60); in process_tx_bd()
263 } else if (etsec->first_bd.flags & BD_TX_TC in process_tx_bd()
264 || etsec->regs[MACCFG2].value & MACCFG2_CRC_EN) { in process_tx_bd()
271 qemu_log("eTSEC Send packet size:%d\n", etsec->tx_buffer_len); in process_tx_bd()
272 qemu_hexdump(stderr, "", etsec->tx_buffer, etsec->tx_buffer_len); in process_tx_bd()
275 if (etsec->first_bd.flags & BD_TX_TOEUN) { in process_tx_bd()
276 qemu_send_packet(qemu_get_queue(etsec->nic), in process_tx_bd()
277 etsec->tx_buffer + 8, in process_tx_bd()
278 etsec->tx_buffer_len - 8); in process_tx_bd()
280 qemu_send_packet(qemu_get_queue(etsec->nic), in process_tx_bd()
281 etsec->tx_buffer, in process_tx_bd()
282 etsec->tx_buffer_len); in process_tx_bd()
287 etsec->tx_buffer_len = 0; in process_tx_bd()
290 ievent_set(etsec, IEVENT_TXF); in process_tx_bd()
294 ievent_set(etsec, IEVENT_TXB); in process_tx_bd()
322 void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr) in etsec_walk_tx_ring() argument
329 if (!(etsec->regs[MACCFG1].value & MACCFG1_TX_EN)) { in etsec_walk_tx_ring()
334 ring_base = (hwaddr)(etsec->regs[TBASEH].value & 0xF) << 32; in etsec_walk_tx_ring()
335 ring_base += etsec->regs[TBASE0 + ring_nbr].value & ~0x7; in etsec_walk_tx_ring()
336 bd_addr = etsec->regs[TBPTR0 + ring_nbr].value & ~0x7; in etsec_walk_tx_ring()
339 read_buffer_descriptor(etsec, bd_addr, &bd); in etsec_walk_tx_ring()
355 process_tx_bd(etsec, &bd); in etsec_walk_tx_ring()
357 write_buffer_descriptor(etsec, bd_addr, &bd); in etsec_walk_tx_ring()
369 etsec->regs[TBPTR0 + ring_nbr].value = bd_addr; in etsec_walk_tx_ring()
372 etsec->regs[TSTAT].value |= 1 << (31 - ring_nbr); in etsec_walk_tx_ring()
381 static void fill_rx_bd(eTSEC *etsec, in fill_rx_bd() argument
388 ((hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32); in fill_rx_bd()
392 assert(etsec->rx_padding <= MAX_RX_PADDING); in fill_rx_bd()
396 bufptr, *size, etsec->rx_padding, etsec->rx_fcb_size); in fill_rx_bd()
401 if (etsec->rx_fcb_size != 0) { in fill_rx_bd()
403 cpu_physical_memory_write(bufptr, etsec->rx_fcb, etsec->rx_fcb_size); in fill_rx_bd()
405 bufptr += etsec->rx_fcb_size; in fill_rx_bd()
406 bd->length += etsec->rx_fcb_size; in fill_rx_bd()
407 etsec->rx_fcb_size = 0; in fill_rx_bd()
414 to_write = MIN(*size - etsec->rx_padding, in fill_rx_bd()
415 etsec->regs[MRBLR].value - etsec->rx_fcb_size); in fill_rx_bd()
429 if (*size == etsec->rx_padding) { in fill_rx_bd()
434 rem = MIN(etsec->regs[MRBLR].value - bd->length, etsec->rx_padding); in fill_rx_bd()
438 etsec->rx_padding -= rem; in fill_rx_bd()
446 static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size) in rx_init_frame() argument
449 uint8_t prsdep = (etsec->regs[RCTRL].value >> RCTRL_PRSDEP_OFFSET) in rx_init_frame()
454 fcb_size = 8 + ((etsec->regs[RCTRL].value >> 16) & 0x1F); in rx_init_frame()
456 etsec->rx_fcb_size = fcb_size; in rx_init_frame()
459 memset(etsec->rx_fcb, 0x0, sizeof(etsec->rx_fcb)); in rx_init_frame()
462 etsec->rx_fcb_size = 0; in rx_init_frame()
465 g_free(etsec->rx_buffer); in rx_init_frame()
468 etsec->rx_buffer = (uint8_t *)buf; in rx_init_frame()
469 etsec->rx_buffer_len = size; in rx_init_frame()
472 etsec->rx_padding = 4; in rx_init_frame()
478 if (etsec->rx_buffer_len < 60) { in rx_init_frame()
479 etsec->rx_padding += 60 - etsec->rx_buffer_len; in rx_init_frame()
482 etsec->rx_first_in_frame = 1; in rx_init_frame()
483 etsec->rx_remaining_data = etsec->rx_buffer_len; in rx_init_frame()
485 etsec->rx_buffer_len, etsec->rx_padding); in rx_init_frame()
488 ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size) in etsec_rx_ring_write() argument
492 if (etsec->rx_buffer_len != 0) { in etsec_rx_ring_write()
498 if (etsec->regs[RSTAT].value & 1 << (23 - ring_nbr)) { in etsec_rx_ring_write()
503 if (etsec->regs[DMACTRL].value & DMACTRL_GRS) { in etsec_rx_ring_write()
508 if (!(etsec->regs[MACCFG1].value & MACCFG1_RX_EN)) { in etsec_rx_ring_write()
513 if (!(etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) { in etsec_rx_ring_write()
519 rx_init_frame(etsec, buf, size); in etsec_rx_ring_write()
521 etsec_walk_rx_ring(etsec, ring_nbr); in etsec_rx_ring_write()
526 void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr) in etsec_walk_rx_ring() argument
538 if (etsec->rx_buffer_len == 0) { in etsec_walk_rx_ring()
544 remaining_data = etsec->rx_remaining_data + etsec->rx_padding; in etsec_walk_rx_ring()
545 buf = etsec->rx_buffer in etsec_walk_rx_ring()
546 + (etsec->rx_buffer_len - etsec->rx_remaining_data); in etsec_walk_rx_ring()
547 size = etsec->rx_buffer_len + etsec->rx_padding; in etsec_walk_rx_ring()
549 ring_base = (hwaddr)(etsec->regs[RBASEH].value & 0xF) << 32; in etsec_walk_rx_ring()
550 ring_base += etsec->regs[RBASE0 + ring_nbr].value & ~0x7; in etsec_walk_rx_ring()
551 start_bd_addr = bd_addr = etsec->regs[RBPTR0 + ring_nbr].value & ~0x7; in etsec_walk_rx_ring()
554 read_buffer_descriptor(etsec, bd_addr, &bd); in etsec_walk_rx_ring()
567 fill_rx_bd(etsec, &bd, &buf, &remaining_data); in etsec_walk_rx_ring()
569 if (etsec->rx_first_in_frame) { in etsec_walk_rx_ring()
571 etsec->rx_first_in_frame = 0; in etsec_walk_rx_ring()
572 etsec->rx_first_bd = bd; in etsec_walk_rx_ring()
586 if (size >= etsec->regs[MAXFRM].value) { in etsec_walk_rx_ring()
589 __func__, size, etsec->regs[MAXFRM].value); in etsec_walk_rx_ring()
603 etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr); in etsec_walk_rx_ring()
606 ievent_set(etsec, IEVENT_RXF); in etsec_walk_rx_ring()
612 ievent_set(etsec, IEVENT_RXB); in etsec_walk_rx_ring()
617 write_buffer_descriptor(etsec, bd_addr, &bd); in etsec_walk_rx_ring()
631 etsec->regs[RBPTR0 + ring_nbr].value = bd_addr; in etsec_walk_rx_ring()
637 etsec->regs[RSTAT].value |= 1 << (23 - ring_nbr); in etsec_walk_rx_ring()
642 etsec->rx_remaining_data = remaining_data; in etsec_walk_rx_ring()
646 memcpy(tmp_buf, etsec->rx_buffer, size); in etsec_walk_rx_ring()
647 etsec->rx_buffer = tmp_buf; in etsec_walk_rx_ring()
651 etsec->rx_buffer_len = 0; in etsec_walk_rx_ring()
652 etsec->rx_buffer = NULL; in etsec_walk_rx_ring()
653 if (etsec->need_flush) { in etsec_walk_rx_ring()
654 qemu_flush_queued_packets(qemu_get_queue(etsec->nic)); in etsec_walk_rx_ring()