//**************************************************************************** // // Low-Level transmit routine. Should do the actual transmission of the // packet. The packet is contained in the pbuf that is passed to the function. // This pbuf might be chained. // //**************************************************************************** err_t low_level_output(struct netif *netif, struct pbuf *p) { struct pbuf *q; int i; unsigned char *pucBuf; unsigned long ulTemp; unsigned char *pucTemp = (unsigned char *)&ulTemp; // // Wait for space available in the TX FIFO. // while(!EthernetSpaceAvail(ETH_BASE)) { } // // Fill in the first two bytes of the payload data (configured as padding // with ETH_PAD_SIZE = 2) with the total length of the payload data // (minus the Ethernet MAC layer header). // pucBuf = p->payload; ulTemp = p->tot_len - 16; *pucBuf++ = pucTemp[0]; *pucBuf++ = pucTemp[1]; // // Copy data from the pbuf(s) into the TX Fifo. // For now, assume every pbuf is full, except possibly the last one. // for(q = p; q != NULL; q = q->next) { pucBuf = q->payload; // // Send the data from the pbuf to the interface, one pbuf at a // time. The size of the data in each pbuf is kept in the ->len // variable. // for(i = 0; i < q->len; i += 4) { pucTemp[0] = *pucBuf++; pucTemp[1] = *pucBuf++; pucTemp[2] = *pucBuf++; pucTemp[3] = *pucBuf++; HWREG(ETH_BASE + MAC_O_DATA) = ulTemp; } } // // Wakeup the transmitter. // HWREG(ETH_BASE + MAC_O_TR) = MAC_TR_NEWTX; #if LINK_STATS lwip_stats.link.xmit++; #endif return ERR_OK; }
//**************************************************************************** // // Low-Level transmit routine. Should do the actual transmission of the // packet. The packet is contained in the pbuf that is passed to the function. // This pbuf might be chained. // //**************************************************************************** rt_err_t luminaryif_tx(rt_device_t dev, struct pbuf *p) { int iBuf; unsigned char *pucBuf; unsigned long *pulBuf; struct pbuf *q; int iGather; unsigned long ulGather; unsigned char *pucGather; unsigned long ulTemp; /* lock tx operation */ rt_sem_take(&tx_sem, RT_WAITING_FOREVER); // // Wait for space available in the TX FIFO. // while(!EthernetSpaceAvail(ETH_BASE)) { } // // Fill in the first two bytes of the payload data (configured as padding // with ETH_PAD_SIZE = 2) with the total length of the payload data // (minus the Ethernet MAC layer header). // *((unsigned short *)(p->payload)) = p->tot_len - 16; // // Initialize the gather register. // iGather = 0; pucGather = (unsigned char *)&ulGather; ulGather = 0; // // Copy data from the pbuf(s) into the TX Fifo. // for(q = p; q != NULL; q = q->next) { // // Intialize a char pointer and index to the pbuf payload data. // pucBuf = (unsigned char *)q->payload; iBuf = 0; // // If the gather buffer has leftover data from a previous pbuf // in the chain, fill it up and write it to the Tx FIFO. // while((iBuf < q->len) && (iGather != 0)) { // // Copy a byte from the pbuf into the gather buffer. // pucGather[iGather] = pucBuf[iBuf++]; // // Increment the gather buffer index modulo 4. // iGather = ((iGather + 1) % 4); } // // If the gather index is 0 and the pbuf index is non-zero, // we have a gather buffer to write into the Tx FIFO. // if((iGather == 0) && (iBuf != 0)) { HWREG(ETH_BASE + MAC_O_DATA) = ulGather; ulGather = 0; } // // Copy words of pbuf data into the Tx FIFO, but don't go past // the end of the pbuf. // if((iBuf % 4) != 0) { while((iBuf + 4) <= q->len) { ulTemp = (pucBuf[iBuf++] << 0); ulTemp |= (pucBuf[iBuf++] << 8); ulTemp |= (pucBuf[iBuf++] << 16); ulTemp |= (pucBuf[iBuf++] << 24); HWREG(ETH_BASE + MAC_O_DATA) = ulTemp; } } else { // // Initialze a long pointer into the pbuf for 32-bit access. // pulBuf = (unsigned long *)&pucBuf[iBuf]; while((iBuf + 4) <= q->len) { HWREG(ETH_BASE + MAC_O_DATA) = *pulBuf++; iBuf += 4; } } // // Check if leftover data in the pbuf and save it in the gather // buffer for the next time. // while(iBuf < q->len) { // // Copy a byte from the pbuf into the gather buffer. // pucGather[iGather] = pucBuf[iBuf++]; // // Increment the gather buffer index modulo 4. // iGather = ((iGather + 1) % 4); } } // // Send any leftover data to the FIFO. // HWREG(ETH_BASE + MAC_O_DATA) = ulGather; // // Wakeup the transmitter. // HWREG(ETH_BASE + MAC_O_TR) = MAC_TR_NEWTX; #if LINK_STATS lwip_stats.link.xmit++; #endif return(ERR_OK); }