The RTL8139 driver is now fully WORKING!!!

I have made an (ugly) hack around the transmit problem (but then again, aren't
hacks ugly all the time?). I still don't know if this is the proper thing, but
the point is that it seems to work now. I don't know if it is my mistake or
the cards mistake that I cannot schedule more than one write at a time, but
I'm looking into this. I don't know the difference in performance between this
driver and the one in R5, but I'm guessing this one's still a bit slower. I'll
continue to hack the driver in order to maximize performance.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4364 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Niels Sascha Reedijk
2003-08-23 10:56:44 +00:00
parent efb0209b94
commit 6a7f7ee06f
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2002, Niels S. Reedijk // Copyright (c) 2003, Niels Sascha Reedijk
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@@ -21,6 +21,13 @@
// Parts of the code: Copyright (c) 1998 Be, Inc. All Rights Reserved // Parts of the code: Copyright (c) 1998 Be, Inc. All Rights Reserved
/*
I'd like to thank the following people that have assisted me in one way
or another in writing this driver:
- Marcus Overhagen: This driver is here because of your help
Thanks adamk, instaner, maximov and ilzu for your feedback.
*/
/* ++++++++++ /* ++++++++++
driver.c driver.c
Implementation of the Realtek 8139 Chipset Implementation of the Realtek 8139 Chipset
@@ -180,6 +187,7 @@ typedef struct rtl8139_properties
ether_address_t address; /* holds the MAC address */ ether_address_t address; /* holds the MAC address */
sem_id lock; /* lock this structure: still interrupt */ sem_id lock; /* lock this structure: still interrupt */
sem_id input_wait; /* locked until there is a packet to be read */ sem_id input_wait; /* locked until there is a packet to be read */
sem_id output_wait; /* locked if there are already four packets in the wait */
uint8 nonblocking; /* determines if the card blocks on read requests */ uint8 nonblocking; /* determines if the card blocks on read requests */
} rtl8139_properties_t; } rtl8139_properties_t;
@@ -206,7 +214,6 @@ static status_t close_hook( void * );
void rtl8139_init_registers( rtl8139_properties_t *data ) void rtl8139_init_registers( rtl8139_properties_t *data )
{ {
data->reg_base = data->pcii->u.h0.base_registers[0]; data->reg_base = data->pcii->u.h0.base_registers[0];
//TRACE( "NIELX@@: registers %lu\n" , data->reg_base );
} }
#else /* PPC */ #else /* PPC */
#include <ByteOrder.h> #include <ByteOrder.h>
@@ -400,6 +407,8 @@ open_hook(const char *name, uint32 flags, void** cookie)
set_sem_owner( data->lock , B_SYSTEM_TEAM ); set_sem_owner( data->lock , B_SYSTEM_TEAM );
data->input_wait = create_sem( 0 , "rtl8139_nielx read wait" ); data->input_wait = create_sem( 0 , "rtl8139_nielx read wait" );
set_sem_owner( data->input_wait , B_SYSTEM_TEAM ); set_sem_owner( data->input_wait , B_SYSTEM_TEAM );
data->output_wait = create_sem( 1 , "rtl8139_nielx write wait" );
set_sem_owner( data->output_wait , B_SYSTEM_TEAM );
//Set up the cookie //Set up the cookie
data->pcii = m_devices[data->device_id]; data->pcii = m_devices[data->device_id];
@@ -700,9 +709,9 @@ write_hook (void* cookie, off_t position, const void* buffer, size_t* num_bytes)
TRACE( "rtl8139_nielx write_hook()\n" ); TRACE( "rtl8139_nielx write_hook()\n" );
acquire_sem( data->lock ); acquire_sem( data->lock );
acquire_sem_etc( data->output_wait , 1 , B_CAN_INTERRUPT , 0 );
//Get spinlock //Get spinlock
WRITE_16( IMR , 0 );
former = lock(); former = lock();
if ( data->writes == 4 ) if ( data->writes == 4 )
@@ -752,10 +761,7 @@ write_hook (void* cookie, off_t position, const void* buffer, size_t* num_bytes)
data->queued_packets++; data->queued_packets++;
unlock( former ); unlock( former );
WRITE_16( IMR ,
ReceiveOk | ReceiveError | TransmitOk | TransmitError |
ReceiveOverflow | ReceiveUnderflow | ReceiveFIFOOverrun |
TimeOut | SystemError );
release_sem_etc( data->lock , 1 , B_DO_NOT_RESCHEDULE ); release_sem_etc( data->lock , 1 , B_DO_NOT_RESCHEDULE );
//Done //Done
@@ -841,15 +847,12 @@ rtl8139_interrupt( void *cookie )
cpu_status status; cpu_status status;
status = lock(); status = lock();
WRITE_16( IMR , 0 ); //Disable interrupts
for (;;) for (;;)
{ {
isr_contents = READ_16( ISR ); isr_contents = READ_16( ISR );
if ( isr_contents == 0 ) if ( isr_contents == 0 )
break; break;
else
WRITE_16( ISR , isr_contents );
TRACE( "NIELX INTERRUPT: %u \n" , isr_contents ); TRACE( "NIELX INTERRUPT: %u \n" , isr_contents );
if( isr_contents & ReceiveOk ) if( isr_contents & ReceiveOk )
@@ -903,6 +906,7 @@ rtl8139_interrupt( void *cookie )
data->writes--; data->writes--;
data->finished_packets++; data->finished_packets++;
checks--; checks--;
release_sem_etc( data->output_wait , 1 , B_DO_NOT_RESCHEDULE );
//update next transmitid //update next transmitid
continue; continue;
} }
@@ -950,14 +954,9 @@ rtl8139_interrupt( void *cookie )
// //
; ;
} }
WRITE_16( ISR , isr_contents );
} }
//Re-enable interrupts
WRITE_16( IMR ,
ReceiveOk | ReceiveError | TransmitOk | TransmitError |
ReceiveOverflow | ReceiveUnderflow | ReceiveFIFOOverrun |
TimeOut | SystemError );
unlock( status ); unlock( status );
return retval; return retval;