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:
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user