forked from pool/dynamips
e5d2285507
Fixed multicast bug OBS-URL: https://build.opensuse.org/request/show/224512 OBS-URL: https://build.opensuse.org/package/show/Education/dynamips?expand=0&rev=27
121 lines
3.8 KiB
Diff
121 lines
3.8 KiB
Diff
--- dynamips-0.2.11-source.orig/common/dev_gt.c 2014-03-02 15:22:17.881753020 +0100
|
|
+++ dynamips-0.2.11-source.patched/common/dev_gt.c 2014-03-02 15:15:55.467367795 +0100
|
|
@@ -2093,8 +2093,8 @@
|
|
int queue)
|
|
{
|
|
u_char pkt[GT_MAX_PKT_SIZE],*pkt_ptr;
|
|
- struct sdma_desc txd0,ctxd,*ptxd;
|
|
- m_uint32_t tx_start,tx_current;
|
|
+ struct sdma_desc ctxd;
|
|
+ m_uint32_t tx_current;
|
|
m_uint32_t len,tot_len;
|
|
int abort = FALSE;
|
|
|
|
@@ -2106,17 +2106,29 @@
|
|
return(FALSE);
|
|
|
|
/* Copy the current txring descriptor */
|
|
- tx_start = tx_current = port->tx_current[queue];
|
|
+ tx_current = port->tx_current[queue];
|
|
|
|
- if (!tx_start)
|
|
+ if (!tx_current)
|
|
return(FALSE);
|
|
|
|
- ptxd = &txd0;
|
|
- gt_sdma_desc_read(d,tx_start,ptxd);
|
|
+ gt_sdma_desc_read(d,tx_current,&ctxd);
|
|
|
|
/* If we don't own the first descriptor, we cannot transmit */
|
|
- if (!(txd0.cmd_stat & GT_TXDESC_OWN))
|
|
+ if (!(ctxd.cmd_stat & GT_TXDESC_OWN)) {
|
|
+ if (queue == 0) {
|
|
+ port->icr |= GT_ICR_TXENDL;
|
|
+ port->sdcmr |= GT_SDCMR_STDL;
|
|
+ port->sdcmr &= ~GT_SDCMR_TXDL;
|
|
+
|
|
+ } else {
|
|
+ port->icr |= GT_ICR_TXENDH;
|
|
+ port->sdcmr |= GT_SDCMR_STDH;
|
|
+ port->sdcmr &= ~GT_SDCMR_TXDH;
|
|
+ }
|
|
+
|
|
+ gt_eth_update_int_status(d,port);
|
|
return(FALSE);
|
|
+ }
|
|
|
|
/* Empty packet for now */
|
|
pkt_ptr = pkt;
|
|
@@ -2125,43 +2137,41 @@
|
|
for(;;) {
|
|
#if DEBUG_ETH_TX
|
|
GT_LOG(d,"gt_eth_handle_txqueue: loop: "
|
|
- "cmd_stat=0x%x, buf_size=0x%x, next_ptr=0x%x, buf_ptr=0x%x\n",
|
|
- ptxd->cmd_stat,ptxd->buf_size,ptxd->next_ptr,ptxd->buf_ptr);
|
|
+ "tx_current=0x%08x, cmd_stat=0x%08x, buf_size=0x%08x, next_ptr=0x%08x, buf_ptr=0x%08x\n",
|
|
+ tx_current, ctxd.cmd_stat, ctxd.buf_size, ctxd.next_ptr, ctxd.buf_ptr);
|
|
#endif
|
|
|
|
- if (!(ptxd->cmd_stat & GT_TXDESC_OWN)) {
|
|
+ if (!(ctxd.cmd_stat & GT_TXDESC_OWN)) {
|
|
GT_LOG(d,"gt_eth_handle_txqueue: descriptor not owned!\n");
|
|
abort = TRUE;
|
|
break;
|
|
}
|
|
|
|
/* Copy packet data to the buffer */
|
|
- len = (ptxd->buf_size & GT_TXDESC_BC_MASK) >> GT_TXDESC_BC_SHIFT;
|
|
+ len = (ctxd.buf_size & GT_TXDESC_BC_MASK) >> GT_TXDESC_BC_SHIFT;
|
|
|
|
- physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->buf_ptr,len);
|
|
+ physmem_copy_from_vm(d->vm,pkt_ptr,ctxd.buf_ptr,len);
|
|
pkt_ptr += len;
|
|
tot_len += len;
|
|
|
|
- /* Clear the OWN bit if this is not the first descriptor */
|
|
- if (!(ptxd->cmd_stat & GT_TXDESC_F)) {
|
|
- ptxd->cmd_stat &= ~GT_TXDESC_OWN;
|
|
- physmem_copy_u32_to_vm(d->vm,tx_current,ptxd->cmd_stat);
|
|
+ /* Clear the OWN bit if this is not the last descriptor */
|
|
+ if (!(ctxd.cmd_stat & GT_TXDESC_L)) {
|
|
+ ctxd.cmd_stat &= ~GT_TXDESC_OWN;
|
|
+ physmem_copy_u32_to_vm(d->vm,tx_current+4,ctxd.cmd_stat);
|
|
}
|
|
|
|
- tx_current = ptxd->next_ptr;
|
|
-
|
|
/* Last descriptor or no more desc available ? */
|
|
- if (ptxd->cmd_stat & GT_TXDESC_L)
|
|
+ if (ctxd.cmd_stat & GT_TXDESC_L)
|
|
break;
|
|
|
|
- if (!tx_current) {
|
|
+ if (!(ctxd.next_ptr)) {
|
|
abort = TRUE;
|
|
break;
|
|
}
|
|
|
|
/* Fetch the next descriptor */
|
|
+ tx_current = ctxd.next_ptr;
|
|
gt_sdma_desc_read(d,tx_current,&ctxd);
|
|
- ptxd = &ctxd;
|
|
}
|
|
|
|
if ((tot_len != 0) && !abort) {
|
|
@@ -2180,11 +2190,11 @@
|
|
port->tx_frames++;
|
|
}
|
|
|
|
- /* Clear the OWN flag of the first descriptor */
|
|
- txd0.cmd_stat &= ~GT_TXDESC_OWN;
|
|
- physmem_copy_u32_to_vm(d->vm,tx_start+4,txd0.cmd_stat);
|
|
+ /* Clear the OWN flag of the last descriptor */
|
|
+ ctxd.cmd_stat &= ~GT_TXDESC_OWN;
|
|
+ physmem_copy_u32_to_vm(d->vm,tx_current+4,ctxd.cmd_stat);
|
|
|
|
- port->tx_current[queue] = tx_current;
|
|
+ port->tx_current[queue] = tx_current = ctxd.next_ptr;
|
|
|
|
/* Notify host about transmitted packet */
|
|
if (queue == 0)
|