You can now specify the link mode in the driver_settings for sis900. Supported

are duplex={full|half|auto} and speed={1|10|100|auto} - please note that you
either have to specify both as auto or none of them, or else it will fall
back to auto negotiation.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5147 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2003-10-24 16:51:24 +00:00
parent f6cb2b865e
commit 7f29148da0
3 changed files with 53 additions and 8 deletions
@@ -9,6 +9,7 @@
#include <PCI.h>
#include <SupportDefs.h>
#include <image.h>
#include <driver_settings.h>
#include <stdlib.h>
#include <string.h>
@@ -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);
@@ -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);
@@ -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];