/************************************************************************** RECV - Receive a frame ***************************************************************************/ static int rtl_recv(struct eth_device *dev) { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ int cur_rx; int length = 0; #ifdef DEBUG_RTL8169_RX printf ("%s\n", __FUNCTION__); #endif ioaddr = dev->iobase; cur_rx = tpc->cur_rx; rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]); if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { unsigned char rxdata[RX_BUF_LEN]; length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. status) & 0x00001FFF) - 4; rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length); memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); if (cur_rx == NUM_RX_DESC - 1) tpc->RxDescArray[cur_rx].status = cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); else tpc->RxDescArray[cur_rx].status = cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx])); rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); net_process_received_packet(rxdata, length); } else { puts("Error Rx"); } cur_rx = (cur_rx + 1) % NUM_RX_DESC; tpc->cur_rx = cur_rx; return 1; } else { ushort sts = RTL_R8(IntrStatus); RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); udelay(100); /* wait */ } tpc->cur_rx = cur_rx; return (0); /* initially as this is called to flush the input */ }
static void rtl8169_init_ring(pci_dev_t dev) #endif { int i; #ifdef DEBUG_RTL8169 int stime = currticks(); printf ("%s\n", __FUNCTION__); #endif tpc->cur_rx = 0; tpc->cur_tx = 0; tpc->dirty_tx = 0; memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc)); memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc)); for (i = 0; i < NUM_TX_DESC; i++) { tpc->Tx_skbuff[i] = &txb[i]; } for (i = 0; i < NUM_RX_DESC; i++) { if (i == (NUM_RX_DESC - 1)) tpc->RxDescArray[i].status = cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); else tpc->RxDescArray[i].status = cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; #ifdef CONFIG_DM_ETH tpc->RxDescArray[i].buf_addr = cpu_to_le32(dm_pci_mem_to_phys( dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i])); #else tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys( dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i])); #endif rtl_flush_rx_desc(&tpc->RxDescArray[i]); } #ifdef DEBUG_RTL8169 printf("%s elapsed time : %lu\n", __func__, currticks()-stime); #endif }
static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase, uchar **packetp) #endif { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ /* nic->packetlen should contain length of data */ int cur_rx; int length = 0; #ifdef DEBUG_RTL8169_RX printf ("%s\n", __FUNCTION__); #endif ioaddr = dev_iobase; cur_rx = tpc->cur_rx; rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]); if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. status) & 0x00001FFF) - 4; rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length); memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); if (cur_rx == NUM_RX_DESC - 1) tpc->RxDescArray[cur_rx].status = cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); else tpc->RxDescArray[cur_rx].status = cpu_to_le32(OWNbit + RX_BUF_SIZE); #ifdef CONFIG_DM_ETH tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32( dm_pci_mem_to_phys(dev, (pci_addr_t)(unsigned long) tpc->RxBufferRing[cur_rx])); #else tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32( pci_mem_to_phys(dev, (pci_addr_t)(unsigned long) tpc->RxBufferRing[cur_rx])); #endif rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); #ifdef CONFIG_DM_ETH *packetp = rxdata; #else net_process_received_packet(rxdata, length); #endif } else { puts("Error Rx"); length = -EIO; } cur_rx = (cur_rx + 1) % NUM_RX_DESC; tpc->cur_rx = cur_rx; return length; } else { ushort sts = RTL_R8(IntrStatus); RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); udelay(100); /* wait */ } tpc->cur_rx = cur_rx; return (0); /* initially as this is called to flush the input */ }