/** Transmit buffer over socket (non blocking). * @param[in] port = port context struct * @param[in] idx = index in tx buffer array * @return socket send result */ int ecx_outframe_red(ecx_portt *port, int idx) { ec_comt *datagramP; ec_etherheadert *ehp; int rval; ehp = (ec_etherheadert *)&(port->txbuf[idx]); /* rewrite MAC source address 1 to primary */ ehp->sa1 = oshw_htons(priMAC[1]); /* transmit over primary socket*/ rval = ecx_outframe(port, idx, 0); if (port->redstate != ECT_RED_NONE) { mtx_lock (port->tx_mutex); ehp = (ec_etherheadert *)&(port->txbuf2); /* use dummy frame for secondary socket transmit (BRD) */ datagramP = (ec_comt*)&(port->txbuf2[ETH_HEADERSIZE]); /* write index to frame */ datagramP->index = idx; /* rewrite MAC source address 1 to secondary */ ehp->sa1 = oshw_htons(secMAC[1]); /* transmit over secondary socket */ //send(sockhandle2, &ec_txbuf2, ec_txbuflength2 , 0); // OBS! redundant not ACTIVE for BFIN, just added to compile ASSERT (0); bfin_EMAC_send(&(port->txbuf2), port->txbuflength2); mtx_unlock (port->tx_mutex); port->redport->rxbufstat[idx] = EC_BUF_TX; } return rval; }
/** Transmit buffer over socket (non blocking). * @param[in] idx = index in tx buffer array * @return socket send result */ int ecx_outframe_red(ecx_portt *port, int idx) { HPESTATUS status; ec_comt *datagramP; ec_etherheadert *ehp; int rval; ehp = (ec_etherheadert *)&(port->txbuf[idx]); /* rewrite MAC source address 1 to primary */ ehp->sa1 = oshw_htons(priMAC[1]); /* transmit over primary socket*/ rval = ecx_outframe(port, idx, 0); if (port->redstate != ECT_RED_NONE) { ehp = (ec_etherheadert *)&(port->txbuf2); /* use dummy frame for secondary socket transmit (BRD) */ datagramP = (ec_comt*)&(port->txbuf2)[ETH_HEADERSIZE]; /* write index to frame */ datagramP->index = idx; /* rewrite MAC source address 1 to secondary */ ehp->sa1 = oshw_htons(secMAC[1]); /* transmit over secondary socket */ //send(sockhandle2, &ec_txbuf2, ec_txbuflength2 , 0); // OBS! redundant not ACTIVE for BFIN, just added to compile //ASSERT (0); hpeAttachTransmitBufferSet(port->redport->handle, port->tx_buffers[idx]); status = hpeStartTransmitter(port->redport->handle); port->redport->rxbufstat[idx] = EC_BUF_TX; } return rval; }
/** Fill buffer with ethernet header structure. * Destination MAC is always broadcast. * Ethertype is always ETH_P_ECAT. * @param[out] p = buffer */ void ec_setupheader(void *p) { ec_etherheadert *bp; bp = p; bp->da0 = oshw_htons(0xffff); bp->da1 = oshw_htons(0xffff); bp->da2 = oshw_htons(0xffff); bp->sa0 = oshw_htons(priMAC[0]); bp->sa1 = oshw_htons(priMAC[1]); bp->sa2 = oshw_htons(priMAC[2]); bp->etype = oshw_htons(ETH_P_ECAT); }
int ecx_portt::init_redundant(ecx_redportt *redport, const char *ifname, char *if2name) { redport = redport; setupnicPrimary(ifname); int rval = setupnicSecondary(if2name); /* prepare "dummy" BRD tx frame for redundant operation */ EtherNetHeader *ehp = (EtherNetHeader *)&(txbuf2); ehp->sa1 = oshw_htons(secMAC[0]); int zbuf = 0; setupdatagram(&(txbuf2), EC_CMD_BRD, 0, 0x0000, 0x0000, 2, &zbuf); txbuflength2 = sizeof(EtherNetHeader) + sizeof(EC_Header) + sizeof(WorkCounter) + 2; return rval; }
/** Non blocking receive frame function. Uses RX buffer and index to combine * read frame with transmitted frame. To compensate for received frames that * are out-of-order all frames are stored in their respective indexed buffer. * If a frame was placed in the buffer previously, the function retreives it * from that buffer index without calling ec_recvpkt. If the requested index * is not already in the buffer it calls ec_recvpkt to fetch it. There are * three options now, 1 no frame read, so exit. 2 frame read but other * than requested index, store in buffer and exit. 3 frame read with matching * index, store in buffer, set completed flag in buffer status and exit. * * @param[in] port = port context struct * @param[in] idx = requested index of frame * @param[in] stacknumber = 0=primary 1=secondary stack * @return Workcounter if a frame is found with corresponding index, otherwise * EC_NOFRAME or EC_OTHERFRAME. */ int ecx_inframe(ecx_portt *port, int idx, int stacknumber) { uint16 l; int rval; uint8 idxf; ec_etherheadert *ehp; ec_comt *ecp; ec_stackT *stack; ec_bufT *rxbuf; if (!stacknumber) { stack = &(port->stack); } else { stack = &(port->redport->stack); } rval = EC_NOFRAME; rxbuf = &(*stack->rxbuf)[idx]; /* check if requested index is already in buffer ? */ if ((idx < EC_MAXBUF) && ( (*stack->rxbufstat)[idx] == EC_BUF_RCVD)) { l = (*rxbuf)[0] + ((uint16)((*rxbuf)[1] & 0x0f) << 8); /* return WKC */ rval = ((*rxbuf)[l] + ((uint16)(*rxbuf)[l + 1] << 8)); /* mark as completed */ (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE; } else { mtx_lock (port->rx_mutex); /* non blocking call to retrieve frame from socket */ if (ecx_recvpkt(port, stacknumber)) { rval = EC_OTHERFRAME; ehp =(ec_etherheadert*)(stack->tempbuf); /* check if it is an EtherCAT frame */ if (ehp->etype == oshw_htons(ETH_P_ECAT)) { ecp =(ec_comt*)(&(*stack->tempbuf)[ETH_HEADERSIZE]); l = etohs(ecp->elength) & 0x0fff; idxf = ecp->index; /* found index equals reqested index ? */ if (idxf == idx) { /* yes, put it in the buffer array (strip ethernet header) */ memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idx] - ETH_HEADERSIZE); /* return WKC */ rval = ((*rxbuf)[l] + ((uint16)((*rxbuf)[l + 1]) << 8)); /* mark as completed */ (*stack->rxbufstat)[idx] = EC_BUF_COMPLETE; /* store MAC source word 1 for redundant routing info */ (*stack->rxsa)[idx] = oshw_ntohs(ehp->sa1); } else { /* check if index exist and someone is waiting for it */ if (idxf < EC_MAXBUF && (*stack->rxbufstat)[idxf] == EC_BUF_TX) { rxbuf = &(*stack->rxbuf)[idxf]; /* put it in the buffer array (strip ethernet header) */ memcpy(rxbuf, &(*stack->tempbuf)[ETH_HEADERSIZE], (*stack->txbuflength)[idxf] - ETH_HEADERSIZE); /* mark as received */ (*stack->rxbufstat)[idxf] = EC_BUF_RCVD; (*stack->rxsa)[idxf] = oshw_ntohs(ehp->sa1); } else { /* strange things happend */ } } } } mtx_unlock (port->rx_mutex); } /* WKC if mathing frame found */ return rval; }