int rtl8139_Receive() { PrintBoth("Packet Received\n"); int i; while( (In_Byte(RTL8139_CR) & RxBufEmpty) == 0){ uint_t ring_offset = cur_rx % RX_BUF_LEN; uint_t rx_status = ((uint_t)rx_buf + ring_offset); PrintBoth("RX Status = %x\n", rx_status); uint_t rx_size = (uint_t)((*(uchar_t *)(rx_status + 3) << 8) | (*(uchar_t *)(rx_status + 2))); uint_t pkt_len = rx_size - 4; PrintBoth("Packet Size = %d\n", pkt_len); for (i = 0; i < pkt_len; i++){ PrintBoth(" %x ", *((uchar_t *)(rx_status + i))); } PrintBoth("\n"); cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; Out_Word(RTL8139_CAPR, (ushort_t)(cur_rx - 16)); pkt_cntr++; PrintBoth("Packet counter at %d\n", pkt_cntr); } return 0; }
/* * Write a block at the logical block number indicated. */ int IDE_Write(int driveNum, int blockNum, char *buffer) { int i; int head; int sector; int cylinder; short *bufferW; if (driveNum < 0 || driveNum > (numDrives-1)) { return IDE_ERROR_BAD_DRIVE; } if (blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) { return IDE_ERROR_INVALID_BLOCK; } /* now compute the head, cylinder, and sector */ sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1; cylinder = blockNum / (drives[driveNum].num_Heads * drives[driveNum].num_SectorsPerTrack); head = (blockNum / drives[driveNum].num_SectorsPerTrack) % drives[driveNum].num_Heads; if (ideDebug) { Print ("request to write block %d\n", blockNum); Print (" head %d\n", head); Print (" cylinder %d\n", cylinder); Print (" sector %d\n", sector); } Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1); Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector); Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder)); Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder)); if (driveNum == 0) { Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE_0 | head); } else if (driveNum == 1) { Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE_1 | head); } Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_WRITE_SECTORS); /* wait for the drive */ while (!(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY)); bufferW = (short *) buffer; for (i=0; i < 256; i++) { Out_Word(IDE_DATA_REGISTER, bufferW[i]); } if (ideDebug) Print("About to wait for Write \n"); /* wait for the drive */ while (!(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_READY)); if (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) { Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER)); return IDE_ERROR_DRIVE_ERROR; } return IDE_ERROR_NO_ERROR; }
void Init_8139() { cur_tx = 0; cur_rx = 0; /* Reset the chip */ Out_Byte(RTL8139_CR, CmdReset); //while( In_Byte(RTL8139_CR) != 0 ) /*udelay(10)*/; /* Unlock Config[01234] and BMCR register writes */ Out_Byte(RTL8139_9346CR, Cfg9346_Unlock); /* Enable Tx/Rx before setting transfer thresholds */ Out_Byte(RTL8139_CR, CmdRxEnb | CmdTxEnb); /* Using 32K ring */ Out_DWord(RTL8139_RCR, RxCfgRcv32K | RxNoWrap | (7 << RxCfgFIFOShift) | (7 << RxCfgDMAShift) | AcceptBroadcast | AcceptMyPhys); // Out_DWord(RTL8139_TCR, RxCfgRcv32K | RxNoWrap | (7 << RxCfgFIFOShift) | (7 << RxCfgDMAShift)); Out_DWord(RTL8139_TCR, TxIFG96 | (6 << TxDMAShift) | (8 << TxRetryShift)); /* Lock Config[01234] and BMCR register writes */ Out_Byte(RTL8139_9346CR, Cfg9346_Lock); /* init Rx ring buffer DMA address */ rx_buf = Malloc(RX_BUF_LEN); Out_DWord(RTL8139_RBSTART, (uint_t)rx_buf); /* init Tx buffer DMA addresses (4 registers) */ tx_buf = Malloc(TX_BUF_SIZE * 4); int i; for(i = 0; i < 4; i++) Out_DWord(RTL8139_TSAD0 + (i * 4), ((uint_t)tx_buf) + (i * TX_BUF_SIZE)); /* missed packet counter */ Out_DWord(RTL8139_MPC, 0); // rtl8139_set_rx_mode does some stuff here. Out_DWord(RTL8139_RCR, In_DWord(RTL8139_RCR) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys); for(i = 0; i < 8; i++) Out_Byte(RTL8139_MAR0 + i, 0xff); /* no early-rx interrupts */ Out_Word(RTL8139_MULINT, In_Word(RTL8139_MULINT) & MultiIntrClear); /* make sure RxTx has started */ if(!(In_Byte(RTL8139_CR) & CmdRxEnb) || !(In_Byte(RTL8139_CR) & CmdTxEnb)) Out_Byte(RTL8139_CR, CmdRxEnb | CmdTxEnb); /* Enable all known interrupts by setting the interrupt mask. */ Out_Word(RTL8139_IMR, rtl8139_intr_mask); Install_IRQ(RTL8139_IRQ, rtl8139_interrupt); Enable_IRQ(RTL8139_IRQ); PrintBoth("8139 initialized\n"); }
void rtl8139_Clear_IRQ(uint_t interrupts) { Out_Word(RTL8139_ISR, interrupts); }
/* * Write a block at the logical block number indicated. */ static int IDE_Write(int driveNum, int blockNum, char *buffer) { int i; int head; int sector; int cylinder; short *bufferW; int reEnable = 0; if(driveNum < 0 || driveNum > (numDrives - 1)) { return IDE_ERROR_BAD_DRIVE; } if(blockNum < 0 || blockNum >= IDE_getNumBlocks(driveNum)) { return IDE_ERROR_INVALID_BLOCK; } /* now compute the head, cylinder, and sector */ sector = blockNum % drives[driveNum].num_SectorsPerTrack + 1; cylinder = blockNum / (drives[driveNum].num_Heads * drives[driveNum].num_SectorsPerTrack); head = (blockNum / drives[driveNum].num_SectorsPerTrack) % drives[driveNum].num_Heads; if(ideDebug) { Print("request to write block %d\n", blockNum); Print(" head %d\n", head); Print(" cylinder %d\n", cylinder); Print(" sector %d\n", sector); } #ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK reEnable = Begin_Int_Atomic(); #endif Out_Byte(IDE_SECTOR_COUNT_REGISTER, 1); Out_Byte(IDE_SECTOR_NUMBER_REGISTER, sector); Out_Byte(IDE_CYLINDER_LOW_REGISTER, LOW_BYTE(cylinder)); Out_Byte(IDE_CYLINDER_HIGH_REGISTER, HIGH_BYTE(cylinder)); Out_Byte(IDE_DRIVE_HEAD_REGISTER, IDE_DRIVE(driveNum) | head); Out_Byte(IDE_COMMAND_REGISTER, IDE_COMMAND_WRITE_SECTORS); /* wait for the drive */ while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ; bufferW = (short *)buffer; for(i = 0; i < 256; i++) { Out_Word(IDE_DATA_REGISTER, bufferW[i]); } if(ideDebug) Print("About to wait for Write \n"); /* wait for the drive */ while (In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_BUSY) ; if(In_Byte(IDE_STATUS_REGISTER) & IDE_STATUS_DRIVE_ERROR) { Print("ERROR: Got Read %d\n", In_Byte(IDE_STATUS_REGISTER)); #ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK End_Int_Atomic(reEnable); #endif return IDE_ERROR_DRIVE_ERROR; } if(ideDebug) Print("write completed \n"); #ifndef NS_INTERRUPTABLE_NO_GLOBAL_LOCK End_Int_Atomic(reEnable); #endif return IDE_ERROR_NO_ERROR; }
void NE2000_Transmit(struct Net_Device *device, void *buffer, ulong_t length) { ulong_t baseAddr = device->baseAddr; KASSERT(!Interrupts_Enabled()); unsigned int i; unsigned int newLength = length >> 1; unsigned short *newBuffer = (unsigned short *)buffer; /* Make sure we aren't currently transmitting */ if (In_Byte(baseAddr + NE2K_CR) & NE2K_CR_TXP) { Print("ERROR - Currently transmitting\n"); return; } /* Reset the card */ NE2000_Reset(device); /* Set the Command Register */ Out_Byte(baseAddr + NE2K_CR, 0x22); /* Handle the read before write bug */ Out_Byte(baseAddr + NE2K0W_RBCR0, 0x42); Out_Byte(baseAddr + NE2K0W_RBCR1, 0x00); Out_Byte(baseAddr + NE2K0W_RSAR0, 0x42); Out_Byte(baseAddr + NE2K0W_RSAR1, 0x00); Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RREAD + NE2K_CR_STA); Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_RDC); /* Load the packet size into the registers */ Out_Byte(baseAddr + NE2K0W_RBCR0, length & 0xFF); Out_Byte(baseAddr + NE2K0W_RBCR1, length >> 8); /* Load the page start into the RSARX registers */ Out_Byte(baseAddr + NE2K0W_RSAR0, 0x00); Out_Byte(baseAddr + NE2K0W_RSAR1, NE2K_TRANSMIT_PAGE); /* Start the remote write */ Out_Byte(baseAddr + NE2K_CR, NE2K_CR_DMA_RWRITE | NE2K_CR_STA); /* Write the data to the I/O port */ for (i = 0; i < newLength; ++i) { Out_Word(baseAddr + NE2K_IO_PORT, newBuffer[i]); } /* Send the last byte of data if we have an odd length */ if (length & 0x1) { Out_Word(baseAddr + NE2K_IO_PORT, ((uchar_t *) buffer)[length - 1]); } /* Wait for transmit remote DMA */ while ((In_Byte(baseAddr + NE2K0R_ISR) & NE2K_ISR_RDC) == 0) { Print("Waiting on remote DMA for transmit \n"); } /* Ack the interrupt */ Out_Byte(baseAddr + NE2K0R_ISR, NE2K_ISR_RDC); /* Now that Remote DMA is complete, set up the transmit */ /* Store the transmit page in the transmit register */ Out_Byte(baseAddr + NE2K0W_TPSR, NE2K_TRANSMIT_PAGE); /* Set transmit byte count */ Out_Byte(baseAddr + NE2K0W_TBCR0, length & 0xFF); Out_Byte(baseAddr + NE2K0W_TBCR1, length >> 8); /* Issue transmit command */ Out_Byte(baseAddr + NE2K_CR, NE2K_CR_NODMA | NE2K_CR_STA | NE2K_CR_TXP); device->txBytes += length; }