PDP11, VAX: Make sure to initialize amount of data processed for incoming packets which get read into multiple buffer descriptors

This commit is contained in:
Mark Pizzolato 2014-10-09 11:15:11 -07:00
parent 004fe0de62
commit 9c5df04de4
4 changed files with 21 additions and 14 deletions

View file

@ -1162,7 +1162,7 @@ t_stat xq_process_rbdl(CTLR* xq)
the physical layer (sim_ether) won't deliver any short packets the physical layer (sim_ether) won't deliver any short packets
via eth_read, so the only short packets which get here are loopback via eth_read, so the only short packets which get here are loopback
packets sent by the host diagnostics (OR short setup packets) */ packets sent by the host diagnostics (OR short setup packets) */
if ((item->type == 2) && (rbl < ETH_MIN_PACKET)) { if ((item->type == ETH_ITM_NORMAL) && (rbl < ETH_MIN_PACKET)) {
xq->var->stats.runt += 1; xq->var->stats.runt += 1;
sim_debug(DBG_WRN, xq->dev, "Runt detected, size = %d\n", rbl); sim_debug(DBG_WRN, xq->dev, "Runt detected, size = %d\n", rbl);
/* pad runts with zeros up to minimum size - this allows "legal" (size - 60) /* pad runts with zeros up to minimum size - this allows "legal" (size - 60)
@ -1172,7 +1172,7 @@ t_stat xq_process_rbdl(CTLR* xq)
}; };
/* adjust oversized non-loopback packets */ /* adjust oversized non-loopback packets */
if ((item->type != 1) && (rbl > ETH_FRAME_SIZE)) { if ((item->type != ETH_ITM_LOOPBACK) && (rbl > ETH_FRAME_SIZE)) {
xq->var->stats.giant += 1; xq->var->stats.giant += 1;
sim_debug(DBG_WRN, xq->dev, "Giant detected, size=%d\n", rbl); sim_debug(DBG_WRN, xq->dev, "Giant detected, size=%d\n", rbl);
/* trim giants down to maximum size - no documentation on how to handle the data loss */ /* trim giants down to maximum size - no documentation on how to handle the data loss */
@ -1197,7 +1197,7 @@ t_stat xq_process_rbdl(CTLR* xq)
xq->var->rbdl_buf[4] = 0; xq->var->rbdl_buf[4] = 0;
switch (item->type) { switch (item->type) {
case 0: /* setup packet */ case ETH_ITM_SETUP: /* setup packet */
xq->var->stats.setup += 1; xq->var->stats.setup += 1;
xq->var->rbdl_buf[4] = 0x2700; /* set esetup and RBL 10:8 */ xq->var->rbdl_buf[4] = 0x2700; /* set esetup and RBL 10:8 */
if (xq->var->type == XQ_T_DEQNA) { /* Strange DEQNA behavior */ if (xq->var->type == XQ_T_DEQNA) { /* Strange DEQNA behavior */
@ -1209,7 +1209,7 @@ t_stat xq_process_rbdl(CTLR* xq)
} }
} }
break; break;
case 1: /* loopback packet */ case ETH_ITM_LOOPBACK: /* loopback packet */
xq->var->stats.loop += 1; xq->var->stats.loop += 1;
xq->var->rbdl_buf[4] = XQ_RST_LASTNOERR; xq->var->rbdl_buf[4] = XQ_RST_LASTNOERR;
if (xq->var->type == XQ_T_DEQNA) if (xq->var->type == XQ_T_DEQNA)
@ -1220,7 +1220,7 @@ t_stat xq_process_rbdl(CTLR* xq)
if (xq->var->csr & XQ_CSR_EL) if (xq->var->csr & XQ_CSR_EL)
xq->var->rbdl_buf[4] |= XQ_RST_ESETUP;/* loopback flag */ xq->var->rbdl_buf[4] |= XQ_RST_ESETUP;/* loopback flag */
break; break;
case 2: /* normal packet */ case ETH_ITM_NORMAL: /* normal packet */
rbl -= 60; /* keeps max packet size in 11 bits */ rbl -= 60; /* keeps max packet size in 11 bits */
xq->var->rbdl_buf[4] = (rbl & 0x0700); /* high bits of rbl */ xq->var->rbdl_buf[4] = (rbl & 0x0700); /* high bits of rbl */
xq->var->rbdl_buf[4] |= 0x00f8; /* set reserved bits to 1 */ xq->var->rbdl_buf[4] |= 0x00f8; /* set reserved bits to 1 */
@ -1236,8 +1236,8 @@ t_stat xq_process_rbdl(CTLR* xq)
xq->var->ReadQ.loss = 0; /* reset loss counter */ xq->var->ReadQ.loss = 0; /* reset loss counter */
} }
if (((~xq->var->csr & XQ_CSR_EL) && if (((~xq->var->csr & XQ_CSR_EL) &&
((rbl + ((item->type == 2) ? 60 : 0)) > ETH_MAX_PACKET)) || ((rbl + ((item->type == ETH_ITM_NORMAL) ? 60 : 0)) > ETH_MAX_PACKET)) ||
((xq->var->csr & XQ_CSR_EL) && (item->type == 1) && ((xq->var->csr & XQ_CSR_EL) && (item->type == ETH_ITM_LOOPBACK) &&
(rbl >= XQ_LONG_PACKET))) (rbl >= XQ_LONG_PACKET)))
xq->var->rbdl_buf[4] |= XQ_RST_LASTERR; /* set Error bit (LONG) */ xq->var->rbdl_buf[4] |= XQ_RST_LASTERR; /* set Error bit (LONG) */
@ -1245,7 +1245,8 @@ t_stat xq_process_rbdl(CTLR* xq)
wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4]); wstatus = Map_WriteW(xq->var->rbdl_ba + 8, 4, &xq->var->rbdl_buf[4]);
if (wstatus) return xq_nxm_error(xq); if (wstatus) return xq_nxm_error(xq);
sim_debug(DBG_TRC, xq->dev, "xq_process_rdbl(bd=0x%X, addr=0x%X, size=0x%X, len=0x%X, st1=0x%04X, st2=0x%04X)\n", xq->var->rbdl_ba, address, b_length, rbl + ((item->type == 2) ? 60 : 0), xq->var->rbdl_buf[4], xq->var->rbdl_buf[5]); sim_debug(DBG_TRC, xq->dev, "xq_process_rdbl(bd=0x%X, addr=0x%X, size=0x%X, len=0x%X, st1=0x%04X, st2=0x%04X)\n",
xq->var->rbdl_ba, address, b_length, rbl + ((item->type == ETH_ITM_NORMAL) ? 60 : 0), xq->var->rbdl_buf[4], xq->var->rbdl_buf[5]);
/* remove packet from queue */ /* remove packet from queue */
if (item->packet.used >= item->packet.len) { if (item->packet.used >= item->packet.len) {
@ -1748,7 +1749,7 @@ t_stat xq_process_turbo_rbdl(CTLR* xq)
rbuf = &item->packet.msg[used]; rbuf = &item->packet.msg[used];
} else { } else {
/* adjust non loopback runt packets */ /* adjust non loopback runt packets */
if ((item->type != 1) && (rbl < ETH_MIN_PACKET)) { if ((item->type != ETH_ITM_LOOPBACK) && (rbl < ETH_MIN_PACKET)) {
xq->var->stats.runt += 1; xq->var->stats.runt += 1;
sim_debug(DBG_WRN, xq->dev, "Runt detected, size = %d\n", rbl); sim_debug(DBG_WRN, xq->dev, "Runt detected, size = %d\n", rbl);
/* pad runts with zeros up to minimum size - this allows "legal" (size - 60) /* pad runts with zeros up to minimum size - this allows "legal" (size - 60)
@ -1758,7 +1759,7 @@ t_stat xq_process_turbo_rbdl(CTLR* xq)
}; };
/* adjust oversized non-loopback packets */ /* adjust oversized non-loopback packets */
if ((item->type != 1) && (rbl > ETH_FRAME_SIZE)) { if ((item->type != ETH_ITM_LOOPBACK) && (rbl > ETH_FRAME_SIZE)) {
xq->var->stats.giant += 1; xq->var->stats.giant += 1;
sim_debug(DBG_WRN, xq->dev, "Giant detected, size=%d\n", rbl); sim_debug(DBG_WRN, xq->dev, "Giant detected, size=%d\n", rbl);
/* trim giants down to maximum size - no documentation on how to handle the data loss */ /* trim giants down to maximum size - no documentation on how to handle the data loss */
@ -2062,8 +2063,9 @@ void xq_read_callback(CTLR* xq, int status)
if (DBG_PCK & xq->dev->dctrl) if (DBG_PCK & xq->dev->dctrl)
eth_packet_trace_ex(xq->var->etherface, xq->var->read_buffer.msg, xq->var->read_buffer.len, "xq-recvd", DBG_DAT & xq->dev->dctrl, DBG_PCK); eth_packet_trace_ex(xq->var->etherface, xq->var->read_buffer.msg, xq->var->read_buffer.len, "xq-recvd", DBG_DAT & xq->dev->dctrl, DBG_PCK);
if ((xq->var->csr & XQ_CSR_RE) || (xq->var->mode == XQ_T_DELQA_PLUS)) { /* receiver enabled */ xq->var->read_buffer.used = 0; /* none processed yet */
if ((xq->var->csr & XQ_CSR_RE) || (xq->var->mode == XQ_T_DELQA_PLUS)) { /* receiver enabled */
/* process any packets locally that can be */ /* process any packets locally that can be */
t_stat status = xq_process_local (xq, &xq->var->read_buffer); t_stat status = xq_process_local (xq, &xq->var->read_buffer);

View file

@ -619,12 +619,14 @@ void xu_read_callback(CTLR* xu, int status)
if (DBG_PCK & xu->dev->dctrl) if (DBG_PCK & xu->dev->dctrl)
eth_packet_trace_ex(xu->var->etherface, xu->var->read_buffer.msg, xu->var->read_buffer.len, "xu-recvd", DBG_DAT & xu->dev->dctrl, DBG_PCK); eth_packet_trace_ex(xu->var->etherface, xu->var->read_buffer.msg, xu->var->read_buffer.len, "xu-recvd", DBG_DAT & xu->dev->dctrl, DBG_PCK);
xu->var->read_buffer.used = 0; /* none processed yet */
/* process any packets locally that can be */ /* process any packets locally that can be */
status = xu_process_local (xu, &xu->var->read_buffer); status = xu_process_local (xu, &xu->var->read_buffer);
/* add packet to read queue */ /* add packet to read queue */
if (status != SCPE_OK) if (status != SCPE_OK)
ethq_insert(&xu->var->ReadQ, 2, &xu->var->read_buffer, 0); ethq_insert(&xu->var->ReadQ, ETH_ITM_NORMAL, &xu->var->read_buffer, 0);
} }
void xua_read_callback(int status) void xua_read_callback(int status)
@ -1425,7 +1427,7 @@ void xu_process_transmit(CTLR* xu)
/* are we in internal loopback mode ? */ /* are we in internal loopback mode ? */
if ((xu->var->mode & MODE_LOOP) && (xu->var->mode & MODE_INTL)) { if ((xu->var->mode & MODE_LOOP) && (xu->var->mode & MODE_INTL)) {
/* just put packet in receive buffer */ /* just put packet in receive buffer */
ethq_insert (&xu->var->ReadQ, 1, &xu->var->write_buffer, 0); ethq_insert (&xu->var->ReadQ, ETH_ITM_LOOPBACK, &xu->var->write_buffer, 0);
} else { } else {
/* transmit packet synchronously - write callback sets status */ /* transmit packet synchronously - write callback sets status */
wstatus = eth_write(xu->var->etherface, &xu->var->write_buffer, xu->var->wcallback); wstatus = eth_write(xu->var->etherface, &xu->var->write_buffer, xu->var->wcallback);

View file

@ -3168,7 +3168,7 @@ if (bpf_used ? to_me : (to_me && !from_me)) {
eth_packet_trace (dev, data, len, "rcvqd"); eth_packet_trace (dev, data, len, "rcvqd");
pthread_mutex_lock (&dev->lock); pthread_mutex_lock (&dev->lock);
ethq_insert_data(&dev->read_queue, 2, data, 0, len, crc_len, crc_data, 0); ethq_insert_data(&dev->read_queue, ETH_ITM_NORMAL, data, 0, len, crc_len, crc_data, 0);
++dev->packets_received; ++dev->packets_received;
pthread_mutex_unlock (&dev->lock); pthread_mutex_unlock (&dev->lock);
free(moved_data); free(moved_data);

View file

@ -206,6 +206,9 @@ struct eth_packet {
struct eth_item { struct eth_item {
int type; /* receive (0=setup, 1=loopback, 2=normal) */ int type; /* receive (0=setup, 1=loopback, 2=normal) */
#define ETH_ITM_SETUP 0
#define ETH_ITM_LOOPBACK 1
#define ETH_ITM_NORMAL 2
struct eth_packet packet; struct eth_packet packet;
}; };