From cf3d356127356bde2bb95f440a4311796c4bac22 Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 3 May 2004 19:34:04 +0000 Subject: [PATCH] Unfortunately, the original via-rhine driver is buggy and may hang during high traffic transfers. These changes have been made by YellowTab and have been contributed to OpenBeOS. While it might not fix every issue, things should be much better and more stable now. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7379 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/network/via-rhine/hook.c | 122 +++++++++--------- .../kernel/drivers/network/via-rhine/pci.c | 19 ++- .../kernel/drivers/network/via-rhine/res.c | 2 +- .../kernel/drivers/network/via-rhine/util.c | 2 +- .../drivers/network/via-rhine/via-rhine.h | 3 +- 5 files changed, 70 insertions(+), 78 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/via-rhine/hook.c b/src/add-ons/kernel/drivers/network/via-rhine/hook.c index d07cad762d..19e3f5db9e 100644 --- a/src/add-ons/kernel/drivers/network/via-rhine/hook.c +++ b/src/add-ons/kernel/drivers/network/via-rhine/hook.c @@ -50,27 +50,28 @@ int32 hook_interrupt(void *_device) if (reg & IntrRxDone) { wakeup_reader++; - write16(device->addr, CmdRxDemand | device->cmd); + //write16(device->addr + ChipCmd, CmdRxDemand | read16(device->addr + ChipCmd)); handled = B_HANDLED_INTERRUPT; continue; } if (reg & IntrTxDone) { wakeup_writer++; + //write16(device->addr + ChipCmd, CmdTxDemand | read16(device->addr + ChipCmd)); handled = B_HANDLED_INTERRUPT; continue; } if (reg & (IntrRxErr | IntrRxDropped | IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) { - write16(device->addr, CmdRxDemand | device->cmd); + write16(device->addr + ChipCmd, CmdRxDemand | read16(device->addr + ChipCmd)); handled = B_HANDLED_INTERRUPT; continue; } if (reg & IntrTxAbort) { /* Just restart Tx. */ - write16(device->addr, CmdTxDemand | device->cmd); + write16(device->addr + ChipCmd, CmdTxDemand | read16(device->addr + ChipCmd)); handled = B_HANDLED_INTERRUPT; continue; } @@ -78,7 +79,7 @@ int32 hook_interrupt(void *_device) { if (device->tx_thresh < 0xE0) write8(device->addr + TxConfig, device->tx_thresh += 0x20); - write16(device->addr, CmdTxDemand | device->cmd); + write16(device->addr + ChipCmd, CmdTxDemand | read16(device->addr + ChipCmd)); handled = B_HANDLED_INTERRUPT; continue; } @@ -88,7 +89,7 @@ int32 hook_interrupt(void *_device) device->tx--; if (device->tx > 0) - write16(device->addr, CmdTxDemand | device->cmd); + write16(device->addr + ChipCmd, CmdTxDemand | read16(device->addr + ChipCmd)); } */ if (--worklimit < 0) @@ -97,7 +98,8 @@ int32 hook_interrupt(void *_device) if (wakeup_reader) { - for (i = 0, j = 0; i < RX_BUFFERS; i++) + +/* for (i = 0, j = 0; i < RX_BUFFERS; i++) { if (!(device->rx_desc[i].rx_status & DescOwn)) { @@ -106,6 +108,7 @@ int32 hook_interrupt(void *_device) } device->cur_rx = j; +*/ input_unwait(device, 1); } @@ -128,6 +131,8 @@ status_t hook_open(const char *name, uint32 flags, void **cookie) uint32 size; viarhine_private *device; + (void)flags; /* get rid of compiler warning */ + // Find Device Name for (devID = 0; (devName = pDevNameList[devID]); devID++) { @@ -189,6 +194,10 @@ status_t hook_open(const char *name, uint32 flags, void **cookie) { device->mii_phys[phy_idx++] = phy; device->mii_advertising = mdio_read(device, phy, 4); + +#ifdef __VIARHINE_DEBUG__ + debug_printf("mii status=%lx, advertising=%lx\n", mii_status, device->mii_advertising); +#endif } } @@ -294,6 +303,8 @@ status_t hook_ioctl(void *_data, uint32 msg, void *buf, size_t len) { viarhine_private *device = (viarhine_private*)_data; + (void)len; /* get rid of compiler warning */ + switch (msg) { case ETHER_GETADDR: @@ -356,40 +367,31 @@ status_t hook_read(void *_data, off_t pos, void *buf, size_t *len) { viarhine_private *device = (viarhine_private*)_data; ulong buflen; - int packet_len = 0; unsigned int entry; char *addr; uint32 data_size; uint32 desc_status; + + (void)pos; /* get rid of compiler warning */ buflen = *len; - atomic_add(&device->inrw, 1); -ReturnInLoop: - write16(device->addr, CmdRxDemand | device->cmd); - while ((device->cur_rx == 0) && (!device->nonblocking)) - { - input_wait(device); + //write16(device->addr + ChipCmd, CmdRxDemand | read16(device->addr + ChipCmd)); + input_wait(device); - if (device->interrupted) - { - *len = 0; - return B_INTERRUPTED; - } - } - - if (device->cur_rx != 0) - { - device->cur_rx--; - } - else if (device->nonblocking) + if (device->interrupted) + { + *len = 0; + return B_INTERRUPTED; + } + + if (device->nonblocking) { *len = 0; - atomic_add(&device->inrw, 1); return 0; } - entry = 0; + entry = device->cur_rx; while (device->rx_desc[entry].rx_status & DescOwn) { entry++; @@ -406,17 +408,10 @@ ReturnInLoop: addr = &device->rx_buf[entry * BUFFER_SIZE]; - if (!is_mine(device, addr)) - { - device->rx_desc[entry].desc_length = 1536; - device->rx_desc[entry].rx_status = DescOwn; - goto ReturnInLoop; - } - #ifdef __VIARHINE_DEBUG__ debug_printf("hook_read: received (%u)(%u) (%02x:%02x:%02x:%02x:%02x:%02x)\n", data_size, - device->cur_rx, + entry, (unsigned char)addr[0], (unsigned char)addr[1], (unsigned char)addr[2], @@ -431,7 +426,10 @@ ReturnInLoop: device->rx_desc[entry].desc_length = MAX_FRAME_SIZE; device->rx_desc[entry].rx_status = DescOwn; - atomic_add(&device->inrw, -1); + entry++; + entry %= RX_BUFFERS; + device->cur_rx = entry; + return B_OK; } @@ -441,56 +439,52 @@ status_t hook_write(void *_data, off_t pos, const void *buf, size_t *len) ulong buflen; status_t status; unsigned int entry; - unsigned int i, j; void *addr; - buflen = *len; - atomic_add(&device->inrw, 1); + (void)pos; /* get rid of compiler warning */ + + if (device->interrupted) + return B_INTERRUPTED; - do - { - if (device->interrupted) - { - atomic_add(&device->inrw, -1); - return B_INTERRUPTED; - } - - status = output_wait(device, ETHER_TRANSMIT_TIMEOUT); - if (status < B_NO_ERROR) - { - atomic_add(&device->inrw, -1); - return status; - } - - } while (device->tx_desc[device->cur_tx].tx_status & DescOwn); + status = output_wait(device, ETHER_TRANSMIT_TIMEOUT); + if (status != B_OK) { +#ifdef __VIARHINE_DEBUG__ + debug_printf("hook_write: leave (%s)\n", strerror(status)); +#endif + return status; + } entry = device->cur_tx; - device->cur_tx++; - device->cur_tx %= TX_BUFFERS; + while(device->tx_desc[entry].tx_status & DescOwn) + { + entry++; + entry %= RX_BUFFERS; + } + + buflen = *len; device->tx_desc[entry].tx_status = DescOwn; addr = &device->tx_buf[entry * BUFFER_SIZE]; memcpy(addr, buf, buflen); if (buflen < 60) - { buflen = 60; - } - if (buflen & 3) - { + if (buflen & 3) { buflen &= (~3); buflen += 4; } device->tx_desc[entry].desc_length = 0x00E08000 | buflen; - write16(device->addr + ChipCmd, CmdTxDemand | device->cmd); + entry++; + entry %= TX_BUFFERS; + device->cur_tx = entry; + //write16(device->addr + ChipCmd, CmdTxDemand | read16(device->addr + ChipCmd)); #ifdef __VIARHINE_DEBUG__ - debug_printf("hook_write: sent (%u)(%u)\n", buflen, device->cur_tx); + debug_printf("hook_write: sent (%u)(%u)\n", buflen, entry); #endif - atomic_add(&device->inrw, -1); *len = buflen; return B_OK; } diff --git a/src/add-ons/kernel/drivers/network/via-rhine/pci.c b/src/add-ons/kernel/drivers/network/via-rhine/pci.c index 67283616b7..c0a40883da 100644 --- a/src/add-ons/kernel/drivers/network/via-rhine/pci.c +++ b/src/add-ons/kernel/drivers/network/via-rhine/pci.c @@ -1,5 +1,5 @@ /* - * VIA VT86C100A Rhine-II and VIA VT3043 Rhine Based Card Driver By Richard Houle + * VIA VT86C100A Rhine-II and VIA VT3043 Rhine Based Card Driver * for the BeOS Release 5 */ @@ -27,18 +27,16 @@ #include "via-rhine.h" /* - * PCI Information Table (VT6102/VT6103/VT6105/VT6105M added by Karina Goddard, March 04, VT6103 and VT6105 seem to work, but buggy) + * PCI Information Table */ struct viarhine_pci_id_info pci_tbl[] = { - {"VIA VT86C100A Rhine-II", 0x1106, 0x6100, 0xffff, PCI_command_io | PCI_command_master, 128}, - {"VIA VT3042 Rhine", 0x1106, 0x3043, 0xffff, PCI_command_io | PCI_command_master, 128}, - {"VIA VT6102 Rhine-II/VT6103 Tahoe 10/100M Fast Ethernet Adapter", 0x1106, 0x3065, 0xffff, PCI_command_io | PCI_command_master, 256}, - {"VIA VT6105 Rhine-III Management Adapter", 0x1106, 0x3106, 0xffff, PCI_command_io | PCI_command_master, 256}, - {"VIA VT6105M Rhine-III Management Adapter", 0x1106, 0x3053, 0xffff, PCI_command_io | PCI_command_master, 256}, - -{0} - + {"VIA VT3042 Rhine", 0x1106, 0x3043, 0xffff, PCI_command_io | PCI_command_master, 128}, + {"VIA VT6102 Rhine-II", 0x1106, 0x3065, 0xffff, PCI_command_io | PCI_command_master, 128}, + {"VIA VT86C100A Rhine-II", 0x1106, 0x6100, 0xffff, PCI_command_io | PCI_command_master, 128}, +// {"VIA VT6105M/LOM Rhine-III", 0x1106, 0x3106, 0xffff, PCI_command_io | PCI_command_master, 128}, +// {"VIA VT6105M Rhine-III Management Adaptor", 0x1106, 0x3053, 0xffff, PCI_command_io | PCI_command_master, 128}, + {0} }; /* @@ -46,6 +44,7 @@ struct viarhine_pci_id_info pci_tbl[] = */ struct viarhine_chip_info cap_tbl[] = { + {128, CanHaveMII}, {128, CanHaveMII}, {128, CanHaveMII} }; diff --git a/src/add-ons/kernel/drivers/network/via-rhine/res.c b/src/add-ons/kernel/drivers/network/via-rhine/res.c index 9881711099..97e7a355c6 100644 --- a/src/add-ons/kernel/drivers/network/via-rhine/res.c +++ b/src/add-ons/kernel/drivers/network/via-rhine/res.c @@ -32,7 +32,7 @@ status_t res_allocate(viarhine_private *device) debug_printf("device_allocate_resources\n"); #endif - device->olock = create_sem(1, "via-rhine output"); + device->olock = create_sem(TX_BUFFERS, "via-rhine output"); set_sem_owner(device->olock, B_SYSTEM_TEAM); device->ilock = create_sem(0, "via-rhine input"); set_sem_owner(device->ilock, B_SYSTEM_TEAM); diff --git a/src/add-ons/kernel/drivers/network/via-rhine/util.c b/src/add-ons/kernel/drivers/network/via-rhine/util.c index a7e3ad0814..5d5b69551b 100644 --- a/src/add-ons/kernel/drivers/network/via-rhine/util.c +++ b/src/add-ons/kernel/drivers/network/via-rhine/util.c @@ -59,7 +59,7 @@ void rx_setmode(viarhine_private *device) write32(device->addr + MulticastFilter0, 0); write32(device->addr + MulticastFilter1, 0); - rx_mode = 0x1A; + rx_mode = 0xA; // was 0x1A => PRO should not be set #endif write8(device->addr + RxConfig, device->rx_thresh | rx_mode); diff --git a/src/add-ons/kernel/drivers/network/via-rhine/via-rhine.h b/src/add-ons/kernel/drivers/network/via-rhine/via-rhine.h index 5208267858..df8ab2cded 100644 --- a/src/add-ons/kernel/drivers/network/via-rhine/via-rhine.h +++ b/src/add-ons/kernel/drivers/network/via-rhine/via-rhine.h @@ -233,9 +233,8 @@ typedef struct unsigned char duplex_full; /* Full-Duplex Operation Requested. */ unsigned char duplex_lock; - uint8 cur_tx; uint8 cur_rx; - int32 inrw; /* In Read or Write Function */ + uint8 cur_tx; int nonblocking; /*