Made receive and transmit buffer count configureable.
Made MTU configureable for net_server users. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7636 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <driver_settings.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@@ -32,6 +33,42 @@
|
|||||||
static int32 gOpenMask = 0;
|
static int32 gOpenMask = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_settings(rtl8169_device *device)
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
const char *param;
|
||||||
|
int mtu, count;
|
||||||
|
|
||||||
|
handle = load_driver_settings("rtl8169");
|
||||||
|
if (!handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
param = get_driver_parameter(handle, "mtu", "-1", "-1");
|
||||||
|
mtu = atoi(param);
|
||||||
|
if (mtu >= 50 && mtu <= 1500)
|
||||||
|
device->maxframesize = mtu + 14;
|
||||||
|
else if (mtu != -1)
|
||||||
|
dprintf("rtl8169: unsupported mtu setting '%s' ignored\n", param);
|
||||||
|
|
||||||
|
param = get_driver_parameter(handle, "rx_buffer_count", "-1", "-1");
|
||||||
|
count = atoi(param);
|
||||||
|
if (count >= 2 && count <= 1024)
|
||||||
|
device->rxBufferCount = count;
|
||||||
|
else if (count != -1)
|
||||||
|
dprintf("rtl8169: unsupported rx_buffer_count setting '%s' ignored\n", param);
|
||||||
|
|
||||||
|
param = get_driver_parameter(handle, "tx_buffer_count", "-1", "-1");
|
||||||
|
count = atoi(param);
|
||||||
|
if (count >= 2 && count <= 1024)
|
||||||
|
device->txBufferCount = count;
|
||||||
|
else if (count != -1)
|
||||||
|
dprintf("rtl8169: unsupported tx_buffer_count setting '%s' ignored\n", param);
|
||||||
|
|
||||||
|
unload_driver_settings(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_phy_reg(rtl8169_device *device, int reg, uint16 value)
|
write_phy_reg(rtl8169_device *device, int reg, uint16 value)
|
||||||
{
|
{
|
||||||
@@ -243,10 +280,10 @@ init_buf_desc(rtl8169_device *device)
|
|||||||
void *rx_buf_virt, *rx_buf_phy;
|
void *rx_buf_virt, *rx_buf_phy;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
device->txBufArea = alloc_mem(&tx_buf_virt, &tx_buf_phy, TX_DESC_COUNT * FRAME_SIZE, 0, "rtl8169 tx buf");
|
device->txBufArea = alloc_mem(&tx_buf_virt, &tx_buf_phy, device->txBufferCount * FRAME_SIZE, 0, "rtl8169 tx buf");
|
||||||
device->rxBufArea = alloc_mem(&rx_buf_virt, &rx_buf_phy, RX_DESC_COUNT * FRAME_SIZE, 0, "rtl8169 rx buf");
|
device->rxBufArea = alloc_mem(&rx_buf_virt, &rx_buf_phy, device->rxBufferCount * FRAME_SIZE, 0, "rtl8169 rx buf");
|
||||||
device->txDescArea = alloc_mem(&tx_buf_desc_virt, &tx_buf_desc_phy, TX_DESC_COUNT * sizeof(buf_desc), 0, "rtl8169 tx desc");
|
device->txDescArea = alloc_mem(&tx_buf_desc_virt, &tx_buf_desc_phy, device->txBufferCount * sizeof(buf_desc), 0, "rtl8169 tx desc");
|
||||||
device->rxDescArea = alloc_mem(&rx_buf_desc_virt, &rx_buf_desc_phy, RX_DESC_COUNT * sizeof(buf_desc), 0, "rtl8169 rx desc");
|
device->rxDescArea = alloc_mem(&rx_buf_desc_virt, &rx_buf_desc_phy, device->rxBufferCount * sizeof(buf_desc), 0, "rtl8169 rx desc");
|
||||||
if (device->txBufArea < B_OK || device->rxBufArea < B_OK || device->txDescArea < B_OK || device->rxDescArea < B_OK)
|
if (device->txBufArea < B_OK || device->rxBufArea < B_OK || device->txDescArea < B_OK || device->rxDescArea < B_OK)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -254,7 +291,7 @@ init_buf_desc(rtl8169_device *device)
|
|||||||
device->rxDesc = (buf_desc *) rx_buf_desc_virt;
|
device->rxDesc = (buf_desc *) rx_buf_desc_virt;
|
||||||
|
|
||||||
// setup transmit descriptors
|
// setup transmit descriptors
|
||||||
for (i = 0; i < TX_DESC_COUNT; i++) {
|
for (i = 0; i < device->txBufferCount; i++) {
|
||||||
device->txBuf[i] = (char *)tx_buf_virt + (i * FRAME_SIZE);
|
device->txBuf[i] = (char *)tx_buf_virt + (i * FRAME_SIZE);
|
||||||
device->txDesc[i].stat_len = TX_DESC_FS | TX_DESC_LS;
|
device->txDesc[i].stat_len = TX_DESC_FS | TX_DESC_LS;
|
||||||
device->txDesc[i].buf_low = (uint32)((char *)tx_buf_phy + (i * FRAME_SIZE));
|
device->txDesc[i].buf_low = (uint32)((char *)tx_buf_phy + (i * FRAME_SIZE));
|
||||||
@@ -263,7 +300,7 @@ init_buf_desc(rtl8169_device *device)
|
|||||||
device->txDesc[i - 1].stat_len |= TX_DESC_EOR;
|
device->txDesc[i - 1].stat_len |= TX_DESC_EOR;
|
||||||
|
|
||||||
// setup receive descriptors
|
// setup receive descriptors
|
||||||
for (i = 0; i < RX_DESC_COUNT; i++) {
|
for (i = 0; i < device->rxBufferCount; i++) {
|
||||||
device->rxBuf[i] = (char *)rx_buf_virt + (i * FRAME_SIZE);
|
device->rxBuf[i] = (char *)rx_buf_virt + (i * FRAME_SIZE);
|
||||||
device->rxDesc[i].stat_len = RX_DESC_OWN | FRAME_SIZE;
|
device->rxDesc[i].stat_len = RX_DESC_OWN | FRAME_SIZE;
|
||||||
device->rxDesc[i].buf_low = (uint32)((char *)rx_buf_phy + (i * FRAME_SIZE));
|
device->rxDesc[i].buf_low = (uint32)((char *)rx_buf_phy + (i * FRAME_SIZE));
|
||||||
@@ -293,7 +330,7 @@ rtl8169_tx_int(rtl8169_device *device)
|
|||||||
for (count = 0, limit = device->txUsed; limit > 0; limit--) {
|
for (count = 0, limit = device->txUsed; limit > 0; limit--) {
|
||||||
if (device->txDesc[device->txIntIndex].stat_len & TX_DESC_OWN)
|
if (device->txDesc[device->txIntIndex].stat_len & TX_DESC_OWN)
|
||||||
break;
|
break;
|
||||||
device->txIntIndex = (device->txIntIndex + 1) % TX_DESC_COUNT;
|
device->txIntIndex = (device->txIntIndex + 1) % device->txBufferCount;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +356,7 @@ rtl8169_rx_int(rtl8169_device *device)
|
|||||||
for (count = 0, limit = device->rxFree; limit > 0; limit--) {
|
for (count = 0, limit = device->rxFree; limit > 0; limit--) {
|
||||||
if (device->rxDesc[device->rxIntIndex].stat_len & RX_DESC_OWN)
|
if (device->rxDesc[device->rxIntIndex].stat_len & RX_DESC_OWN)
|
||||||
break;
|
break;
|
||||||
device->rxIntIndex = (device->rxIntIndex + 1) % RX_DESC_COUNT;
|
device->rxIntIndex = (device->rxIntIndex + 1) % device->rxBufferCount;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,19 +458,28 @@ rtl8169_open(const char *name, uint32 flags, void** cookie)
|
|||||||
device->pciInfo = gDevList[dev_id];
|
device->pciInfo = gDevList[dev_id];
|
||||||
device->nonblocking = (flags & O_NONBLOCK) ? true : false;
|
device->nonblocking = (flags & O_NONBLOCK) ? true : false;
|
||||||
device->closed = false;
|
device->closed = false;
|
||||||
|
|
||||||
|
// setup defaults
|
||||||
|
device->maxframesize = 1514; // not FRAME_SIZE
|
||||||
|
device->txBufferCount = DEFAULT_TX_BUF_COUNT;
|
||||||
|
device->rxBufferCount = DEFAULT_RX_BUF_COUNT;
|
||||||
|
// get modifications from settings file
|
||||||
|
read_settings(device);
|
||||||
|
|
||||||
|
device->rxBuf = (void **)malloc(sizeof(void *) * device->rxBufferCount);
|
||||||
device->rxSpinlock = 0;
|
device->rxSpinlock = 0;
|
||||||
device->rxNextIndex = 0;
|
device->rxNextIndex = 0;
|
||||||
device->rxIntIndex = 0;
|
device->rxIntIndex = 0;
|
||||||
device->rxFree = RX_DESC_COUNT;
|
device->rxFree = device->rxBufferCount;
|
||||||
device->rxReadySem = create_sem(0, "rtl8169 rx ready");
|
device->rxReadySem = create_sem(0, "rtl8169 rx ready");
|
||||||
set_sem_owner(device->rxReadySem, B_SYSTEM_TEAM);
|
set_sem_owner(device->rxReadySem, B_SYSTEM_TEAM);
|
||||||
|
|
||||||
|
device->txBuf = (void **)malloc(sizeof(void *) * device->txBufferCount);
|
||||||
device->txSpinlock = 0;
|
device->txSpinlock = 0;
|
||||||
device->txNextIndex = 0;
|
device->txNextIndex = 0;
|
||||||
device->txIntIndex = 0;
|
device->txIntIndex = 0;
|
||||||
device->txUsed = 0;
|
device->txUsed = 0;
|
||||||
device->txFreeSem = create_sem(TX_DESC_COUNT, "rtl8169 tx free");
|
device->txFreeSem = create_sem(device->txBufferCount, "rtl8169 tx free");
|
||||||
set_sem_owner(device->txFreeSem, B_SYSTEM_TEAM);
|
set_sem_owner(device->txFreeSem, B_SYSTEM_TEAM);
|
||||||
|
|
||||||
// enable busmaster and memory mapped access, disable io port access
|
// enable busmaster and memory mapped access, disable io port access
|
||||||
@@ -594,6 +640,8 @@ err:
|
|||||||
delete_area(device->rxBufArea);
|
delete_area(device->rxBufArea);
|
||||||
delete_area(device->txDescArea);
|
delete_area(device->txDescArea);
|
||||||
delete_area(device->rxDescArea);
|
delete_area(device->rxDescArea);
|
||||||
|
free(device->txBuf);
|
||||||
|
free(device->rxBuf);
|
||||||
free(device);
|
free(device);
|
||||||
atomic_and(&gOpenMask, ~(1 << dev_id));
|
atomic_and(&gOpenMask, ~(1 << dev_id));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -638,6 +686,8 @@ rtl8169_free(void* cookie)
|
|||||||
delete_area(device->rxBufArea);
|
delete_area(device->rxBufArea);
|
||||||
delete_area(device->txDescArea);
|
delete_area(device->txDescArea);
|
||||||
delete_area(device->rxDescArea);
|
delete_area(device->rxDescArea);
|
||||||
|
free(device->txBuf);
|
||||||
|
free(device->rxBuf);
|
||||||
free(device);
|
free(device);
|
||||||
atomic_and(&gOpenMask, ~(1 << device->devId));
|
atomic_and(&gOpenMask, ~(1 << device->devId));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -697,7 +747,7 @@ retry:
|
|||||||
release_spinlock(&device->rxSpinlock);
|
release_spinlock(&device->rxSpinlock);
|
||||||
restore_interrupts(cpu);
|
restore_interrupts(cpu);
|
||||||
|
|
||||||
device->rxNextIndex = (device->rxNextIndex + 1) % RX_DESC_COUNT;
|
device->rxNextIndex = (device->rxNextIndex + 1) % device->rxBufferCount;
|
||||||
|
|
||||||
TRACE("rtl8169_read() leave\n");
|
TRACE("rtl8169_read() leave\n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -760,7 +810,7 @@ retry:
|
|||||||
release_spinlock(&device->txSpinlock);
|
release_spinlock(&device->txSpinlock);
|
||||||
restore_interrupts(cpu);
|
restore_interrupts(cpu);
|
||||||
|
|
||||||
device->txNextIndex = (device->txNextIndex + 1) % TX_DESC_COUNT;
|
device->txNextIndex = (device->txNextIndex + 1) % device->txBufferCount;
|
||||||
|
|
||||||
write8(REG_TPPOLL, read8(REG_TPPOLL) | TPPOLL_NPQ); // set queue polling bit
|
write8(REG_TPPOLL, read8(REG_TPPOLL) | TPPOLL_NPQ); // set queue polling bit
|
||||||
|
|
||||||
@@ -822,8 +872,8 @@ rtl8169_control(void *cookie, uint32 op, void *arg, size_t len)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case ETHER_GETFRAMESIZE:
|
case ETHER_GETFRAMESIZE:
|
||||||
TRACE("rtl8169_control() ETHER_GETFRAMESIZE\n");
|
TRACE("rtl8169_control() ETHER_GETFRAMESIZE, framesize = %d (MTU = %d)\n", device->maxframesize, device->maxframesize - 14);
|
||||||
*(uint32*)arg = FRAME_SIZE;
|
*(uint32*)arg = device->maxframesize;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -24,10 +24,10 @@
|
|||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#define TX_TIMEOUT 6000000 // 6 seconds
|
#define TX_TIMEOUT 6000000 // 6 seconds
|
||||||
#define FRAME_SIZE 1536 // must be multiple of 8
|
#define FRAME_SIZE 1536 // must be multiple of 8
|
||||||
#define TX_DESC_COUNT 256 // must be <= 1024
|
#define DEFAULT_TX_BUF_COUNT 256 // must be <= 1024
|
||||||
#define RX_DESC_COUNT 256 // must be <= 1024
|
#define DEFAULT_RX_BUF_COUNT 256 // must be <= 1024
|
||||||
|
|
||||||
extern pci_module_info *gPci;
|
extern pci_module_info *gPci;
|
||||||
|
|
||||||
@@ -63,12 +63,14 @@ typedef struct {
|
|||||||
volatile int32 txNextIndex; // next descriptor that will be used for writing
|
volatile int32 txNextIndex; // next descriptor that will be used for writing
|
||||||
volatile int32 txIntIndex; // current descriptor that needs be checked
|
volatile int32 txIntIndex; // current descriptor that needs be checked
|
||||||
volatile int32 txUsed;
|
volatile int32 txUsed;
|
||||||
|
int txBufferCount;
|
||||||
|
|
||||||
spinlock rxSpinlock;
|
spinlock rxSpinlock;
|
||||||
sem_id rxReadySem;
|
sem_id rxReadySem;
|
||||||
volatile int32 rxNextIndex; // next descriptor that will be used for reading
|
volatile int32 rxNextIndex; // next descriptor that will be used for reading
|
||||||
volatile int32 rxIntIndex; // current descriptor that needs be checked
|
volatile int32 rxIntIndex; // current descriptor that needs be checked
|
||||||
volatile int32 rxFree;
|
volatile int32 rxFree;
|
||||||
|
int rxBufferCount;
|
||||||
|
|
||||||
volatile buf_desc * txDesc;
|
volatile buf_desc * txDesc;
|
||||||
volatile buf_desc * rxDesc;
|
volatile buf_desc * rxDesc;
|
||||||
@@ -76,8 +78,8 @@ typedef struct {
|
|||||||
area_id txDescArea;
|
area_id txDescArea;
|
||||||
area_id rxDescArea;
|
area_id rxDescArea;
|
||||||
|
|
||||||
void * txBuf[TX_DESC_COUNT];
|
void ** txBuf;
|
||||||
void * rxBuf[RX_DESC_COUNT];
|
void ** rxBuf;
|
||||||
|
|
||||||
area_id txBufArea;
|
area_id txBufArea;
|
||||||
area_id rxBufArea;
|
area_id rxBufArea;
|
||||||
@@ -87,6 +89,7 @@ typedef struct {
|
|||||||
|
|
||||||
uint8 irq;
|
uint8 irq;
|
||||||
uint8 macaddr[6];
|
uint8 macaddr[6];
|
||||||
|
int maxframesize;
|
||||||
int mac_version;
|
int mac_version;
|
||||||
int phy_version;
|
int phy_version;
|
||||||
} rtl8169_device;
|
} rtl8169_device;
|
||||||
|
|||||||
Reference in New Issue
Block a user