ethernet: Get rid of the read/write buffers for scattered I/O.

This (mostly) reverts commit 3ea7c99119.

We no longer need this code after introducing the calls to send
net_buffers to drivers directly.

Change-Id: I31a2fdbbbe8203c53dbcc1e3b1fab2492c8651bd
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7914
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-07-30 17:03:36 +00:00
committed by waddlesplash
parent b07cf30aee
commit e49b2154fe
@@ -31,18 +31,9 @@
struct ethernet_device : net_device, DoublyLinkedListLinkImpl<ethernet_device> { struct ethernet_device : net_device, DoublyLinkedListLinkImpl<ethernet_device> {
~ethernet_device()
{
free(read_buffer);
free(write_buffer);
}
int fd; int fd;
uint32 frame_size; uint32 frame_size;
bool supports_net_buffer; bool supports_net_buffer;
void* read_buffer, *write_buffer;
mutex read_buffer_lock, write_buffer_lock;
}; };
static const bigtime_t kLinkCheckInterval = 1000000; static const bigtime_t kLinkCheckInterval = 1000000;
@@ -165,9 +156,6 @@ ethernet_init(const char *name, net_device **_device)
device->media = IFM_ACTIVE | IFM_ETHER; device->media = IFM_ACTIVE | IFM_ETHER;
device->header_length = ETHER_HEADER_LENGTH; device->header_length = ETHER_HEADER_LENGTH;
device->fd = -1; device->fd = -1;
device->read_buffer = device->write_buffer = NULL;
device->read_buffer_lock = MUTEX_INITIALIZER("ethernet read_buffer"),
device->write_buffer_lock = MUTEX_INITIALIZER("ethernet write_buffer");
*_device = device; *_device = device;
return B_OK; return B_OK;
@@ -232,19 +220,6 @@ ethernet_up(net_device *_device)
sCheckList.Add(device); sCheckList.Add(device);
} }
if (device->frame_size > ETHER_MAX_FRAME_SIZE) {
free(device->read_buffer);
free(device->write_buffer);
device->read_buffer = malloc(device->frame_size);
device->write_buffer = malloc(device->frame_size);
if (device->read_buffer == NULL || device->write_buffer == NULL) {
errno = B_NO_MEMORY;
goto err;
}
}
device->address.length = ETHER_ADDRESS_LENGTH; device->address.length = ETHER_ADDRESS_LENGTH;
device->mtu = device->frame_size - device->header_length; device->mtu = device->frame_size - device->header_length;
return B_OK; return B_OK;
@@ -303,38 +278,25 @@ ethernet_send_data(net_device *_device, net_buffer *buffer)
net_buffer *allocated = NULL; net_buffer *allocated = NULL;
net_buffer *original = buffer; net_buffer *original = buffer;
MutexLocker bufferLocker;
struct iovec iovec;
if (gBufferModule->count_iovecs(buffer) > 1) { if (gBufferModule->count_iovecs(buffer) > 1) {
if (device->write_buffer != NULL) { // Create a new buffer containing the data.
bufferLocker.SetTo(device->write_buffer_lock, false); buffer = gBufferModule->duplicate(original);
if (buffer == NULL)
return ENOBUFS;
status_t status = gBufferModule->read(buffer, 0, allocated = buffer;
device->write_buffer, buffer->size);
if (status != B_OK)
return status;
iovec.iov_base = device->write_buffer;
iovec.iov_len = buffer->size;
} else {
// Fall back to creating a new buffer.
allocated = gBufferModule->duplicate(original);
if (allocated == NULL)
return ENOBUFS;
buffer = allocated; if (gBufferModule->count_iovecs(buffer) > 1) {
dprintf("ethernet: net_buffer I/O is not supported by underlying device\n");
if (gBufferModule->count_iovecs(allocated) > 1) { gBufferModule->free(buffer);
dprintf("ethernet_send_data: no write buffer, cannot perform scatter I/O\n"); device->stats.send.errors++;
gBufferModule->free(allocated); return B_NOT_SUPPORTED;
return EMSGSIZE;
}
gBufferModule->get_iovecs(buffer, &iovec, 1);
} }
} else {
gBufferModule->get_iovecs(buffer, &iovec, 1);
} }
struct iovec iovec;
gBufferModule->get_iovecs(buffer, &iovec, 1);
//dump_block((const char *)iovec.iov_base, buffer->size, " "); //dump_block((const char *)iovec.iov_base, buffer->size, " ");
ssize_t bytesWritten = write(device->fd, iovec.iov_base, iovec.iov_len); ssize_t bytesWritten = write(device->fd, iovec.iov_base, iovec.iov_len);
//dprintf("sent: %ld\n", bytesWritten); //dprintf("sent: %ld\n", bytesWritten);
@@ -366,45 +328,32 @@ ethernet_receive_data(net_device *_device, net_buffer **_buffer)
return 0; return 0;
} }
// TODO: better header space // read/write only works for standard ethernet frames. For larger frames,
// the driver should support send/receive of net_buffers directly, above.
net_buffer *buffer = gBufferModule->create(256); net_buffer *buffer = gBufferModule->create(256);
if (buffer == NULL) if (buffer == NULL)
return ENOBUFS; return ENOBUFS;
MutexLocker bufferLocker;
struct iovec iovec;
ssize_t bytesRead; ssize_t bytesRead;
status_t status; void *data;
if (device->read_buffer != NULL) {
bufferLocker.SetTo(device->read_buffer_lock, false);
iovec.iov_base = device->read_buffer; status_t status = gBufferModule->append_size(buffer, device->frame_size, &data);
iovec.iov_len = device->frame_size; if (status == B_OK && data == NULL) {
} else { dprintf("ethernet: net_buffer I/O is not supported by underlying device\n");
void *data; status = B_NOT_SUPPORTED;
status = gBufferModule->append_size(buffer, device->frame_size, &data);
if (status == B_OK && data == NULL) {
dprintf("ethernet_receive_data: no read buffer, cannot perform scattered I/O!\n");
status = B_NOT_SUPPORTED;
}
if (status < B_OK)
goto err;
iovec.iov_base = data;
iovec.iov_len = device->frame_size;
} }
if (status < B_OK)
goto err;
bytesRead = read(device->fd, iovec.iov_base, iovec.iov_len); bytesRead = read(device->fd, data, device->frame_size);
if (bytesRead < 0) { if (bytesRead < 0) {
status = errno; status = errno;
goto err; goto err;
} }
//dump_block((const char *)data, bytesRead, "rcv: "); //dump_block((const char *)data, bytesRead, "rcv: ");
if (iovec.iov_base == device->read_buffer) status = gBufferModule->trim(buffer, bytesRead);
status = gBufferModule->append(buffer, iovec.iov_base, bytesRead);
else
status = gBufferModule->trim(buffer, bytesRead);
if (status < B_OK) { if (status < B_OK) {
atomic_add((int32*)&device->stats.receive.dropped, 1); atomic_add((int32*)&device->stats.receive.dropped, 1);
goto err; goto err;