More work on davicom driver : I got it to the point where I don't know why it fails :)
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34991 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -30,13 +30,18 @@
|
|||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
#define NCR 0x00 // Network control
|
#define NCR 0x00 // Network control
|
||||||
|
#define NSR 0x01 // Network status
|
||||||
#define RCR 0x05 // RX Control
|
#define RCR 0x05 // RX Control
|
||||||
#define PAR 0x10 // 6 bits - Physical address (MAC)
|
#define PAR 0x10 // 6 bits - Physical address (MAC)
|
||||||
#define GPCR 0x1E // General purpose control
|
#define GPCR 0x1E // General purpose control
|
||||||
#define GPR 0x1F // General purpose
|
#define GPR 0x1F // General purpose
|
||||||
|
|
||||||
|
#define NCR_FDX 0x08 // Full duplex
|
||||||
#define NCR_LBK 0x06 // Loopback mode
|
#define NCR_LBK 0x06 // Loopback mode
|
||||||
|
|
||||||
|
#define NSR_SPEED 0x80 // 0 = 100MBps, 1 = 10MBps
|
||||||
|
#define NSR_LINKST 0x40 // 1 = link up
|
||||||
|
|
||||||
#define RCR_DIS_LONG 0x20 // Discard long packet
|
#define RCR_DIS_LONG 0x20 // Discard long packet
|
||||||
#define RCR_DIS_CRC 0x10 // Discard CRC error packet
|
#define RCR_DIS_CRC 0x10 // Discard CRC error packet
|
||||||
#define RCR_ALL 0x08 // Pass all multicast
|
#define RCR_ALL 0x08 // Pass all multicast
|
||||||
@@ -119,7 +124,6 @@ DavicomDevice::DavicomDevice(usb_device device, const char *description)
|
|||||||
fNotifyReadSem(-1),
|
fNotifyReadSem(-1),
|
||||||
fNotifyWriteSem(-1),
|
fNotifyWriteSem(-1),
|
||||||
fNotifyBuffer(NULL),
|
fNotifyBuffer(NULL),
|
||||||
fNotifyBufferLength(0),
|
|
||||||
fLinkStateChangeSem(-1),
|
fLinkStateChangeSem(-1),
|
||||||
fHasConnection(false),
|
fHasConnection(false),
|
||||||
fUseTRXHeader(false),
|
fUseTRXHeader(false),
|
||||||
@@ -157,6 +161,12 @@ DavicomDevice::DavicomDevice(usb_device device, const char *description)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fNotifyBuffer = (uint8*)malloc(8);
|
||||||
|
if (fNotifyBuffer == NULL) {
|
||||||
|
TRACE_ALWAYS("Error allocating notify buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_SetupEndpoints() != B_OK) {
|
if (_SetupEndpoints() != B_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -197,7 +207,7 @@ DavicomDevice::Open(uint32 flags)
|
|||||||
|
|
||||||
// setup state notifications
|
// setup state notifications
|
||||||
result = gUSBModule->queue_interrupt(fNotifyEndpoint, fNotifyBuffer,
|
result = gUSBModule->queue_interrupt(fNotifyEndpoint, fNotifyBuffer,
|
||||||
fNotifyBufferLength, _NotifyCallback, this);
|
8, _NotifyCallback, this);
|
||||||
if(result != B_OK) {
|
if(result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of requesting notify interrupt:%#010x\n", result);
|
TRACE_ALWAYS("Error of requesting notify interrupt:%#010x\n", result);
|
||||||
return result;
|
return result;
|
||||||
@@ -601,40 +611,10 @@ DavicomDevice::ReadMACAddress(ether_address_t *address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
DavicomDevice::ReadRXControlRegister(uint16 *rxcontrol)
|
|
||||||
{
|
|
||||||
size_t actual_length = 0;
|
|
||||||
*rxcontrol = 0;
|
|
||||||
|
|
||||||
status_t result = gUSBModule->send_request(fDevice,
|
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
|
||||||
fReadRXControlRequest, 0, 0,
|
|
||||||
sizeof(*rxcontrol), rxcontrol, &actual_length);
|
|
||||||
|
|
||||||
if(sizeof(*rxcontrol) != actual_length) {
|
|
||||||
TRACE_ALWAYS("Mismatch during reading RX control register."
|
|
||||||
"Read %d bytes instead of %d.\n",
|
|
||||||
actual_length, sizeof(*rxcontrol));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
DavicomDevice::WriteRXControlRegister(uint16 rxcontrol)
|
|
||||||
{
|
|
||||||
status_t result = gUSBModule->send_request(fDevice,
|
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
|
||||||
fWriteRXControlRequest, rxcontrol, 0, 0, 0, 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DavicomDevice::StopDevice()
|
DavicomDevice::StopDevice()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
status_t result = WriteRXControlRegister(0);
|
status_t result = WriteRXControlRegister(0);
|
||||||
|
|
||||||
if(result != B_OK) {
|
if(result != B_OK) {
|
||||||
@@ -643,6 +623,9 @@ DavicomDevice::StopDevice()
|
|||||||
|
|
||||||
TRACE_RET(result);
|
TRACE_RET(result);
|
||||||
return result;
|
return result;
|
||||||
|
*/
|
||||||
|
TRACE_ALWAYS("Stop device not implemented\n");
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -721,10 +704,12 @@ DavicomDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
|||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE_ALWAYS("Device status error:%#010x\n", status);
|
TRACE_ALWAYS("Device status error:%#010x\n", status);
|
||||||
|
/*
|
||||||
status_t result = gUSBModule->clear_feature(device->fNotifyEndpoint,
|
status_t result = gUSBModule->clear_feature(device->fNotifyEndpoint,
|
||||||
USB_FEATURE_ENDPOINT_HALT);
|
USB_FEATURE_ENDPOINT_HALT);
|
||||||
if(result != B_OK)
|
if(result != B_OK)
|
||||||
TRACE_ALWAYS("Error during clearing of HALT state:%#010x.\n", result);
|
TRACE_ALWAYS("Error during clearing of HALT state:%#010x.\n", result);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse data in overriden class
|
// parse data in overriden class
|
||||||
@@ -732,7 +717,7 @@ DavicomDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
|||||||
|
|
||||||
// schedule next notification buffer
|
// schedule next notification buffer
|
||||||
gUSBModule->queue_interrupt(device->fNotifyEndpoint, device->fNotifyBuffer,
|
gUSBModule->queue_interrupt(device->fNotifyEndpoint, device->fNotifyBuffer,
|
||||||
device->fNotifyBufferLength, _NotifyCallback, device);
|
8, _NotifyCallback, device);
|
||||||
atomic_add(&device->fInsideNotify, -1);
|
atomic_add(&device->fInsideNotify, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,89 +785,70 @@ DavicomDevice::StartDevice()
|
|||||||
status_t
|
status_t
|
||||||
DavicomDevice::OnNotify(uint32 actualLength)
|
DavicomDevice::OnNotify(uint32 actualLength)
|
||||||
{
|
{
|
||||||
/*
|
if (actualLength < 8) {
|
||||||
if (actualLength < sizeof(AX88172Notify)) {
|
TRACE_ALWAYS("Data underrun error. %d of 8 bytes received\n",
|
||||||
TRACE_ALWAYS("Data underrun error. %d of %d bytes received\n",
|
actualLength);
|
||||||
actualLength, sizeof(AX88172Notify));
|
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
AX88172Notify *notification = (AX88172Notify *)fNotifyBuffer;
|
|
||||||
|
|
||||||
if(notification->btA1 != 0xa1) {
|
// 0 = Network status
|
||||||
TRACE_ALWAYS("Notify magic byte is invalid: %#02x\n",
|
// 1:2 = TX status
|
||||||
notification->btA1);
|
// 3 = RX status
|
||||||
}
|
// 4 = Receive overflow counter
|
||||||
|
// 5 = Received packet counter
|
||||||
|
// 6 = Transmit packet counter
|
||||||
|
// 7 = GPR
|
||||||
|
|
||||||
uint phyIndex = 0;
|
bool linkIsUp = (fNotifyBuffer[0] & 0x40) != 0;
|
||||||
bool linkIsUp = fHasConnection;
|
|
||||||
switch(fMII.ActivePHY()) {
|
|
||||||
case PrimaryPHY:
|
|
||||||
phyIndex = 1;
|
|
||||||
linkIsUp = (notification->btNN & LINK_STATE_PHY1) == LINK_STATE_PHY1;
|
|
||||||
break;
|
|
||||||
case SecondaryPHY:
|
|
||||||
phyIndex = 2;
|
|
||||||
linkIsUp = (notification->btNN & LINK_STATE_PHY2) == LINK_STATE_PHY2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case CurrentPHY:
|
|
||||||
TRACE_ALWAYS("Error: PHY is not initialized.\n");
|
|
||||||
return B_NO_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool linkStateChange = linkIsUp != fHasConnection;
|
bool linkStateChange = linkIsUp != fHasConnection;
|
||||||
fHasConnection = linkIsUp;
|
fHasConnection = linkIsUp;
|
||||||
|
|
||||||
if(linkStateChange) {
|
if(linkStateChange) {
|
||||||
TRACE("Link state of PHY%d has been changed to '%s'\n",
|
TRACE("Link is now %s at %s Mb/s\n",
|
||||||
phyIndex, fHasConnection ? "up" : "down");
|
fHasConnection ? "up" : "down", fNotifyBuffer[0]&0x80?"10":"100");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linkStateChange && fLinkStateChangeSem >= B_OK)
|
if (linkStateChange && fLinkStateChangeSem >= B_OK)
|
||||||
release_sem_etc(fLinkStateChangeSem, 1, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(fLinkStateChangeSem, 1, B_DO_NOT_RESCHEDULE);
|
||||||
*/
|
return B_OK;
|
||||||
TRACE_ALWAYS("OnNotify not implemented\n");
|
|
||||||
return B_ERROR; // shoulb be B_OK when implemented :)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DavicomDevice::GetLinkState(ether_link_state *linkState)
|
DavicomDevice::GetLinkState(ether_link_state *linkState)
|
||||||
{
|
{
|
||||||
/*
|
uint8 tmp_reg;
|
||||||
uint16 miiANAR = 0;
|
status_t result = _ReadRegister(NSR,1,&tmp_reg);
|
||||||
uint16 miiANLPAR = 0;
|
if (result != B_OK)
|
||||||
|
|
||||||
status_t result = fMII.Read(MII_ANAR, &miiANAR);
|
|
||||||
if(result != B_OK) {
|
|
||||||
TRACE_ALWAYS("Error reading MII ANAR register:%#010x\n", result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
result = fMII.Read(MII_ANLPAR, &miiANLPAR);
|
if (tmp_reg & NSR_SPEED)
|
||||||
if(result != B_OK) {
|
linkState->speed = 10000;
|
||||||
TRACE_ALWAYS("Error reading MII ANLPAR register:%#010x\n", result);
|
else
|
||||||
return result;
|
linkState->speed = 100000;
|
||||||
}
|
|
||||||
|
|
||||||
TRACE_FLOW("ANAR:%04x ANLPAR:%04x\n", miiANAR, miiANLPAR);
|
|
||||||
|
|
||||||
uint16 mediumStatus = miiANAR & miiANLPAR;
|
|
||||||
|
|
||||||
linkState->quality = 1000;
|
linkState->quality = 1000;
|
||||||
|
|
||||||
linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0);
|
uint16 mediumStatus = IFM_ETHER | IFM_100_TX;
|
||||||
linkState->media |= mediumStatus & (ANLPAR_TX_FD | ANLPAR_10_FD) ?
|
if (tmp_reg & NSR_LINKST) {
|
||||||
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
mediumStatus |= IFM_ACTIVE;
|
||||||
|
result = _ReadRegister(NCR,1,&tmp_reg);
|
||||||
linkState->speed = mediumStatus & (ANLPAR_TX_FD | ANLPAR_TX_HD) ? 100000 : 10000;
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (tmp_reg & NCR_FDX)
|
||||||
|
mediumStatus |= IFM_FULL_DUPLEX;
|
||||||
|
else
|
||||||
|
mediumStatus |= IFM_HALF_DUPLEX;
|
||||||
|
|
||||||
|
if (tmp_reg & NCR_LBK)
|
||||||
|
mediumStatus |= IFM_LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE_FLOW("Medium state: %s, %lld MBit/s, %s duplex.\n",
|
TRACE_FLOW("Medium state: %s, %lld MBit/s, %s duplex.\n",
|
||||||
(linkState->media & IFM_ACTIVE) ? "active" : "inactive",
|
(linkState->media & IFM_ACTIVE) ? "active" : "inactive",
|
||||||
linkState->speed / 1000,
|
linkState->speed / 1000,
|
||||||
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
||||||
*/
|
return B_OK;
|
||||||
TRACE_ALWAYS("GetLinkState not implemented\n");
|
|
||||||
return B_ERROR; // B_OK
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,6 @@ virtual status_t GetLinkState(ether_link_state *state) ;
|
|||||||
virtual status_t SetPromiscuousMode(bool bOn);
|
virtual status_t SetPromiscuousMode(bool bOn);
|
||||||
virtual status_t ModifyMulticastTable(bool add, uint8 address);
|
virtual status_t ModifyMulticastTable(bool add, uint8 address);
|
||||||
status_t ReadMACAddress(ether_address_t *address);
|
status_t ReadMACAddress(ether_address_t *address);
|
||||||
status_t ReadRXControlRegister(uint16 *rxcontrol);
|
|
||||||
status_t WriteRXControlRegister(uint16 rxcontrol);
|
|
||||||
|
|
||||||
// state tracking
|
// state tracking
|
||||||
status_t fStatus;
|
status_t fStatus;
|
||||||
@@ -98,7 +96,6 @@ const char * fDescription;
|
|||||||
sem_id fNotifyWriteSem;
|
sem_id fNotifyWriteSem;
|
||||||
|
|
||||||
uint8 * fNotifyBuffer;
|
uint8 * fNotifyBuffer;
|
||||||
uint32 fNotifyBufferLength;
|
|
||||||
|
|
||||||
// connection data
|
// connection data
|
||||||
sem_id fLinkStateChangeSem;
|
sem_id fLinkStateChangeSem;
|
||||||
|
|||||||
Reference in New Issue
Block a user