diff --git a/src/add-ons/kernel/drivers/network/sis900/device.c b/src/add-ons/kernel/drivers/network/sis900/device.c index a52aa96908..69931c9fd6 100644 --- a/src/add-ons/kernel/drivers/network/sis900/device.c +++ b/src/add-ons/kernel/drivers/network/sis900/device.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -144,6 +145,7 @@ createSemaphores(struct sis_info *info) { if ((info->rxSem = create_sem(0, "sis900 receive")) < B_OK) return info->rxSem; + set_sem_owner(info->rxSem, B_SYSTEM_TEAM); if ((info->txSem = create_sem(NUM_Tx_DESCR, "sis900 transmit")) < B_OK) @@ -165,6 +167,39 @@ createSemaphores(struct sis_info *info) } +static void +readSettings(struct sis_info *info) +{ + const char *parameter; + + void *handle = load_driver_settings("sis900"); + if (handle == NULL) + return; + + parameter = get_driver_parameter(handle, "duplex", "auto", "auto"); + if (!stricmp(parameter, "full")) + info->fixedMode = LINK_FULL_DUPLEX; + else if (!stricmp(parameter, "half")) + info->fixedMode = LINK_HALF_DUPLEX; + + parameter = get_driver_parameter(handle, "speed", "auto", "auto"); + if (!stricmp(parameter, "100")) + info->fixedMode |= LINK_SPEED_100_MBIT; + else if (!stricmp(parameter, "10")) + info->fixedMode |= LINK_SPEED_10_MBIT; + else if (!stricmp(parameter, "1")) + info->fixedMode |= LINK_SPEED_HOME; + + // it's either all or nothing + + if ((info->fixedMode & LINK_DUPLEX_MASK) == 0 + || (info->fixedMode & LINK_SPEED_MASK) == 0) + info->fixedMode = 0; + + unload_driver_settings(handle); +} + + //-------------------------------------------------------------------------- // #pragma mark - // the device will be accessed through the following functions (a.k.a. device hooks) @@ -177,7 +212,7 @@ device_open(const char *name, uint32 flags, void **cookie) area_id area; int id; - // verify device access + // verify device access (we only allow one user at a time) { char *thisName; int32 mask; @@ -224,10 +259,12 @@ device_open(const char *name, uint32 flags, void **cookie) else dprintf(DEVICE_NAME ": could not get MAC address\n"); + readSettings(info); + if (createSemaphores(info) == B_OK) { status_t status = sis900_initPHYs(info); if (status == B_OK) { - TRACE((DEVICE_NAME ": MII status = %d\n", mdio_read(info, MII_STATUS))); + TRACE((DEVICE_NAME ": MII status = %d\n", mdio_read(info, MII_STATUS))); //sis900_configFIFOs(info); sis900_reset(info); diff --git a/src/add-ons/kernel/drivers/network/sis900/sis900.c b/src/add-ons/kernel/drivers/network/sis900/sis900.c index b1ee1385d5..8caebf3667 100644 --- a/src/add-ons/kernel/drivers/network/sis900/sis900.c +++ b/src/add-ons/kernel/drivers/network/sis900/sis900.c @@ -425,7 +425,7 @@ sis900_selectPHY(struct sis_info *info) void -sis900_setMode(struct sis_info *info,int32 mode) +sis900_setMode(struct sis_info *info, int32 mode) { uint32 address = (uint32)info->registers + SiS900_MAC_CONFIG; uint32 txFlags = SiS900_Tx_AUTO_PADDING | SiS900_Tx_FILL_THRES; @@ -455,8 +455,8 @@ sis900_setMode(struct sis_info *info,int32 mode) rxFlags |= SiS900_Rx_ACCEPT_Tx_PACKETS; } - write32((uint32)info->registers + SiS900_MAC_Tx_CONFIG,txFlags); - write32((uint32)info->registers + SiS900_MAC_Rx_CONFIG,rxFlags); + write32((uint32)info->registers + SiS900_MAC_Tx_CONFIG, txFlags); + write32((uint32)info->registers + SiS900_MAC_Rx_CONFIG, rxFlags); } @@ -538,10 +538,17 @@ sis900_checkMode(struct sis_info *info) { uint32 address = (uint32)info->registers + SiS900_MAC_CONFIG; - if (info->currentPHY->types == MII_LAN) { + if (info->fixedMode != 0) { + TRACE((DEVICE_NAME ": link mode set via settings\n")); + + // ToDo: what about the excessive deferral timer? + + sis900_setMode(info, info->fixedMode); + info->autoNegotiationComplete = true; + } else if (info->currentPHY->types == MII_LAN) { TRACE((DEVICE_NAME ": PHY type is LAN\n")); - // enable excessive defferal timer + // enable excessive deferral timer write32(address, ~SiS900_MAC_CONFIG_EXCESSIVE_DEFERRAL & read32(address)); sis900_setAutoNegotiationCapabilities(info); @@ -549,7 +556,7 @@ sis900_checkMode(struct sis_info *info) } else { TRACE((DEVICE_NAME ": PHY type is not LAN\n")); - // disable excessive defferal timer + // disable excessive deferral timer write32(address, SiS900_MAC_CONFIG_EXCESSIVE_DEFERRAL | read32(address)); sis900_setMode(info, LINK_SPEED_HOME | LINK_HALF_DUPLEX); diff --git a/src/add-ons/kernel/drivers/network/sis900/sis900.h b/src/add-ons/kernel/drivers/network/sis900/sis900.h index 9bfe609b64..83c69a9d43 100644 --- a/src/add-ons/kernel/drivers/network/sis900/sis900.h +++ b/src/add-ons/kernel/drivers/network/sis900/sis900.h @@ -96,6 +96,7 @@ struct sis_info { uint16 phy; bool autoNegotiationComplete; bool link; + uint16 fixedMode; // receive data volatile struct buffer_desc rxDescriptor[NUM_Rx_DESCR];