Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
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");
}
Ejemplo n.º 4
0
void rtl8139_Clear_IRQ(uint_t interrupts)
{
	Out_Word(RTL8139_ISR, interrupts);
}
Ejemplo n.º 5
0
/*
 * 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;
}
Ejemplo n.º 6
0
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;
}