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 <PCI.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include <driver_settings.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -144,6 +145,7 @@ createSemaphores(struct sis_info *info)
|
|||||||
{
|
{
|
||||||
if ((info->rxSem = create_sem(0, "sis900 receive")) < B_OK)
|
if ((info->rxSem = create_sem(0, "sis900 receive")) < B_OK)
|
||||||
return info->rxSem;
|
return info->rxSem;
|
||||||
|
|
||||||
set_sem_owner(info->rxSem, B_SYSTEM_TEAM);
|
set_sem_owner(info->rxSem, B_SYSTEM_TEAM);
|
||||||
|
|
||||||
if ((info->txSem = create_sem(NUM_Tx_DESCR, "sis900 transmit")) < B_OK)
|
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 -
|
// #pragma mark -
|
||||||
// the device will be accessed through the following functions (a.k.a. device hooks)
|
// 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;
|
area_id area;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
// verify device access
|
// verify device access (we only allow one user at a time)
|
||||||
{
|
{
|
||||||
char *thisName;
|
char *thisName;
|
||||||
int32 mask;
|
int32 mask;
|
||||||
@@ -224,6 +259,8 @@ device_open(const char *name, uint32 flags, void **cookie)
|
|||||||
else
|
else
|
||||||
dprintf(DEVICE_NAME ": could not get MAC address\n");
|
dprintf(DEVICE_NAME ": could not get MAC address\n");
|
||||||
|
|
||||||
|
readSettings(info);
|
||||||
|
|
||||||
if (createSemaphores(info) == B_OK) {
|
if (createSemaphores(info) == B_OK) {
|
||||||
status_t status = sis900_initPHYs(info);
|
status_t status = sis900_initPHYs(info);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
|
|||||||
@@ -425,7 +425,7 @@ sis900_selectPHY(struct sis_info *info)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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 address = (uint32)info->registers + SiS900_MAC_CONFIG;
|
||||||
uint32 txFlags = SiS900_Tx_AUTO_PADDING | SiS900_Tx_FILL_THRES;
|
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;
|
rxFlags |= SiS900_Rx_ACCEPT_Tx_PACKETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
write32((uint32)info->registers + SiS900_MAC_Tx_CONFIG,txFlags);
|
write32((uint32)info->registers + SiS900_MAC_Tx_CONFIG, txFlags);
|
||||||
write32((uint32)info->registers + SiS900_MAC_Rx_CONFIG,rxFlags);
|
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;
|
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"));
|
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));
|
write32(address, ~SiS900_MAC_CONFIG_EXCESSIVE_DEFERRAL & read32(address));
|
||||||
|
|
||||||
sis900_setAutoNegotiationCapabilities(info);
|
sis900_setAutoNegotiationCapabilities(info);
|
||||||
@@ -549,7 +556,7 @@ sis900_checkMode(struct sis_info *info)
|
|||||||
} else {
|
} else {
|
||||||
TRACE((DEVICE_NAME ": PHY type is not LAN\n"));
|
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));
|
write32(address, SiS900_MAC_CONFIG_EXCESSIVE_DEFERRAL | read32(address));
|
||||||
|
|
||||||
sis900_setMode(info, LINK_SPEED_HOME | LINK_HALF_DUPLEX);
|
sis900_setMode(info, LINK_SPEED_HOME | LINK_HALF_DUPLEX);
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ struct sis_info {
|
|||||||
uint16 phy;
|
uint16 phy;
|
||||||
bool autoNegotiationComplete;
|
bool autoNegotiationComplete;
|
||||||
bool link;
|
bool link;
|
||||||
|
uint16 fixedMode;
|
||||||
|
|
||||||
// receive data
|
// receive data
|
||||||
volatile struct buffer_desc rxDescriptor[NUM_Rx_DESCR];
|
volatile struct buffer_desc rxDescriptor[NUM_Rx_DESCR];
|
||||||
|
|||||||
Reference in New Issue
Block a user