Implemented ETHER_GET_LINK_STATE and ETHER_SET_LINK_STATE_SEM for rtl8169.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29278 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3291c58044
commit
bcd9a7e1d4
|
@ -24,6 +24,10 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
#include <net/if_media.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
@ -379,6 +383,55 @@ rtl8169_rx_int(rtl8169_device *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
rtl8169_get_link_state(rtl8169_device *device)
|
||||||
|
{
|
||||||
|
bool link_ok = false;
|
||||||
|
bool full_duplex = false;
|
||||||
|
uint32 speed = 0;
|
||||||
|
bool linkStateChange = false;
|
||||||
|
uint32 phy;
|
||||||
|
|
||||||
|
dump_phy_stat(device);
|
||||||
|
print_link_status(device);
|
||||||
|
|
||||||
|
phy = read8(REG_PHY_STAT);
|
||||||
|
if (phy & PHY_STAT_EnTBI) {
|
||||||
|
link_ok = (read32(REG_TBICSR) & TBICSR_TBILinkOk);
|
||||||
|
if (link_ok) {
|
||||||
|
speed = 1000000;
|
||||||
|
full_duplex = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (phy & PHY_STAT_LinkSts) {
|
||||||
|
link_ok = true;
|
||||||
|
if (phy & PHY_STAT_1000MF) {
|
||||||
|
speed = 1000000;
|
||||||
|
full_duplex = true;
|
||||||
|
} else {
|
||||||
|
speed = (phy & PHY_STAT_100M) ? 100000 : 10000;
|
||||||
|
full_duplex = (phy & PHY_STAT_FullDup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
linkStateChange = (link_ok != device->link_ok
|
||||||
|
|| full_duplex != device->full_duplex
|
||||||
|
|| speed != device->speed);
|
||||||
|
|
||||||
|
device->link_ok = link_ok;
|
||||||
|
device->full_duplex = full_duplex;
|
||||||
|
device->speed = speed;
|
||||||
|
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
if (linkStateChange && device->linkChangeSem >= B_OK)
|
||||||
|
release_sem_etc(device->linkChangeSem, 1, B_DO_NOT_RESCHEDULE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
rtl8169_int(void *data)
|
rtl8169_int(void *data)
|
||||||
{
|
{
|
||||||
|
@ -406,8 +459,7 @@ rtl8169_int(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat & INT_PUN) {
|
if (stat & INT_PUN) {
|
||||||
dump_phy_stat(device);
|
rtl8169_get_link_state(device);
|
||||||
print_link_status(device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat & (INT_TOK | INT_TER)) {
|
if (stat & (INT_TOK | INT_TER)) {
|
||||||
|
@ -571,8 +623,11 @@ rtl8169_open(const char *name, uint32 flags, void** cookie)
|
||||||
// configure PHY
|
// configure PHY
|
||||||
phy_config(device);
|
phy_config(device);
|
||||||
|
|
||||||
dump_phy_stat(device);
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
print_link_status(device);
|
device->linkChangeSem = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rtl8169_get_link_state(device);
|
||||||
|
|
||||||
// initialize MAC address
|
// initialize MAC address
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
|
@ -914,6 +969,37 @@ rtl8169_control(void *cookie, uint32 op, void *arg, size_t len)
|
||||||
*(uint32*)arg = device->maxframesize;
|
*(uint32*)arg = device->maxframesize;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
case ETHER_GET_LINK_STATE:
|
||||||
|
{
|
||||||
|
ether_link_state_t state;
|
||||||
|
|
||||||
|
state.media = IFM_ETHER;
|
||||||
|
state.media |= (device->link_ok ? IFM_ACTIVE : 0);
|
||||||
|
state.media |= (device->full_duplex ? IFM_FULL_DUPLEX : IFM_HALF_DUPLEX);
|
||||||
|
if (device->speed == 1000000)
|
||||||
|
state.media |= IFM_1000_T;
|
||||||
|
else if (device->speed == 100000)
|
||||||
|
state.media |= IFM_100_TX;
|
||||||
|
else if (device->speed == 10000)
|
||||||
|
state.media |= IFM_10_T;
|
||||||
|
|
||||||
|
state.speed = device->speed;
|
||||||
|
state.quality = 1000;
|
||||||
|
|
||||||
|
return user_memcpy(arg, &state, sizeof(ether_link_state_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
case ETHER_SET_LINK_STATE_SEM:
|
||||||
|
{
|
||||||
|
if (user_memcpy(&device->linkChangeSem, arg, sizeof(sem_id)) < B_OK) {
|
||||||
|
device->linkChangeSem = -1;
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TRACE("rtl8169_control() Invalid command\n");
|
TRACE("rtl8169_control() Invalid command\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -92,6 +92,15 @@ typedef struct {
|
||||||
int maxframesize;
|
int maxframesize;
|
||||||
int mac_version;
|
int mac_version;
|
||||||
int phy_version;
|
int phy_version;
|
||||||
|
|
||||||
|
bool link_ok;
|
||||||
|
uint32 speed;
|
||||||
|
bool full_duplex;
|
||||||
|
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
sem_id linkChangeSem;
|
||||||
|
#endif
|
||||||
|
|
||||||
} rtl8169_device;
|
} rtl8169_device;
|
||||||
|
|
||||||
#define read8(offset) (*(volatile uint8 *) ((char *)(device->regAddr) + (offset)))
|
#define read8(offset) (*(volatile uint8 *) ((char *)(device->regAddr) + (offset)))
|
||||||
|
|
Loading…
Reference in New Issue