diff --git a/src/add-ons/kernel/drivers/network/sis900/device.c b/src/add-ons/kernel/drivers/network/sis900/device.c index 30fd1c4b49..328b3b9f78 100644 --- a/src/add-ons/kernel/drivers/network/sis900/device.c +++ b/src/add-ons/kernel/drivers/network/sis900/device.c @@ -1,25 +1,23 @@ -/* Device hooks for SiS 900 networking - * - * Copyright © 2001-2005 pinc Software. All Rights Reserved. +/* + * Copyright (c) 2001-2007 pinc Software. All Rights Reserved. + * Distributed under the terms of the MIT license. */ +/*! Device hooks for SiS 900 networking */ + +#include "device.h" + +#include "driver.h" +#include "interface.h" +#include "sis900.h" -#include -#include -#include -#include -#include -#include #include #include #include - -#include "ether_driver.h" -#include "driver.h" -#include "device.h" -#include "sis900.h" -#include "interface.h" +#ifdef HAIKU_TARGET_PLATFORM_HAIKU +# include +#endif /* device hooks prototypes */ @@ -362,32 +360,47 @@ device_ioctl(void *data, uint32 msg, void *buffer, size_t bufferLength) case ETHER_GETADDR: TRACE(("ioctl: get MAC address\n")); memcpy(buffer, &info->address, 6); - return B_NO_ERROR; + return B_OK; case ETHER_INIT: TRACE(("ioctl: init\n")); - return B_NO_ERROR; - + return B_OK; + case ETHER_GETFRAMESIZE: TRACE(("ioctl: get frame size\n")); *(uint32*)buffer = MAX_FRAME_SIZE; - return B_NO_ERROR; - + return B_OK; + case ETHER_SETPROMISC: TRACE(("ioctl: set promisc\n")); sis900_setPromiscuous(info, *(uint32 *)buffer != 0); return B_OK; - + case ETHER_NONBLOCK: info->blockFlag = *(int32 *)buffer ? B_TIMEOUT : 0; TRACE(("ioctl: non blocking ? %s\n", info->blockFlag ? "yes" : "no")); - return B_NO_ERROR; - + return B_OK; + case ETHER_ADDMULTI: TRACE(("ioctl: add multicast\n")); /* not yet implemented */ break; - + +#ifdef HAIKU_TARGET_PLATFORM_HAIKU + case ETHER_GETLINKSTATE: + { + ether_link_state_t state; + state.link_media = (info->link ? IFM_ACTIVE : 0) + | (info->full_duplex ? IFM_FULL_DUPLEX : IFM_HALF_DUPLEX) + | (info->speed == LINK_SPEED_100_MBIT ? IFM_100_TX : IFM_10_T); + state.link_speed = info->speed == LINK_SPEED_100_MBIT + ? 100000 : 10000; + state.link_quality = 1000; + + return user_memcpy(buffer, &state, sizeof(ether_link_state_t)); + } +#endif + default: TRACE(("ioctl: unknown message %lu (length = %ld)\n", msg, bufferLength)); break; diff --git a/src/add-ons/kernel/drivers/network/sis900/driver.h b/src/add-ons/kernel/drivers/network/sis900/driver.h index f9cc582d30..5ce05be4f3 100644 --- a/src/add-ons/kernel/drivers/network/sis900/driver.h +++ b/src/add-ons/kernel/drivers/network/sis900/driver.h @@ -1,12 +1,14 @@ -/* Kernel driver for SiS 900 networking - * - * Copyright © 2001-2005 pinc Software. All Rights Reserved. +/* + * Copyright (c) 2001-2007 pinc Software. All Rights Reserved. * Distributed under the terms of the MIT license. */ #ifndef DRIVER_H #define DRIVER_H +#include + + // PCI Communications #define IO_PORT_PCI_ACCESS true diff --git a/src/add-ons/kernel/drivers/network/sis900/sis900.c b/src/add-ons/kernel/drivers/network/sis900/sis900.c index 1186da9361..4295e514f7 100644 --- a/src/add-ons/kernel/drivers/network/sis900/sis900.c +++ b/src/add-ons/kernel/drivers/network/sis900/sis900.c @@ -434,7 +434,9 @@ sis900_setMode(struct sis_info *info, int32 mode) uint32 address = info->registers + SiS900_MAC_CONFIG; uint32 txFlags = SiS900_Tx_AUTO_PADDING | SiS900_Tx_FILL_THRES; uint32 rxFlags = 0; - int32 speed = mode & LINK_SPEED_MASK; + + info->speed = mode & LINK_SPEED_MASK; + info->full_duplex = (mode & LINK_DUPLEX_MASK) == LINK_FULL_DUPLEX; if (read32(address) & SiS900_MAC_CONFIG_EDB_MASTER) { TRACE((DEVICE_NAME ": EDB master is set!\n")); @@ -444,7 +446,7 @@ sis900_setMode(struct sis_info *info, int32 mode) // link speed FIFO thresholds - if (speed == LINK_SPEED_HOME || speed == LINK_SPEED_10_MBIT) { + if (info->speed == LINK_SPEED_HOME || info->speed == LINK_SPEED_10_MBIT) { rxFlags |= SiS900_Rx_10_MBIT_DRAIN_THRES; txFlags |= SiS900_Tx_10_MBIT_DRAIN_THRES; } else { @@ -454,7 +456,7 @@ sis900_setMode(struct sis_info *info, int32 mode) // duplex mode - if ((mode & LINK_DUPLEX_MASK) == LINK_FULL_DUPLEX) { + if (info->full_duplex) { txFlags |= SiS900_Tx_CS_IGNORE | SiS900_Tx_HB_IGNORE; rxFlags |= SiS900_Rx_ACCEPT_Tx_PACKETS; } diff --git a/src/add-ons/kernel/drivers/network/sis900/sis900.h b/src/add-ons/kernel/drivers/network/sis900/sis900.h index 2748a52aa8..4664194f1f 100644 --- a/src/add-ons/kernel/drivers/network/sis900/sis900.h +++ b/src/add-ons/kernel/drivers/network/sis900/sis900.h @@ -1,13 +1,16 @@ -/* SiS 900 driver/chip specific definitions - * - * Copyright © 2001-2005 pinc Software. All Rights Reserved. +/* + * Copyright (c) 2001-2007 pinc Software. All Rights Reserved. * Distributed under the terms of the MIT license. */ #ifndef SIS900_H #define SIS900_H +/*! SiS 900 driver/chip specific definitions */ -#include "ether_driver.h" +#include + +#include +#include #define VENDOR_ID_SiS 0x1039 @@ -98,6 +101,8 @@ struct sis_info { uint16 phy; bool autoNegotiationComplete; bool link; + bool full_duplex; + uint16 speed; uint16 fixedMode; // receive data