These files were missing from a previous commit.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34953 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+183
-39
@@ -1,9 +1,13 @@
|
||||
/*
|
||||
* Davicom DM9601 USB 1.1 Ethernet Driver.
|
||||
* Copyright (c) 2009 Adrien Destugues <pulkomandy@gmail.com>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Heavily based on code of
|
||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Heavily based on code of the
|
||||
* Driver for USB Ethernet Control Model devices
|
||||
* Copyright (C) 2008 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
@@ -12,7 +16,20 @@
|
||||
|
||||
#include "Driver.h"
|
||||
#include "Settings.h"
|
||||
#include "ASIXDevice.h"
|
||||
#include "DavicomDevice.h"
|
||||
|
||||
|
||||
// Vendor commands
|
||||
#define READ_REGISTER 0
|
||||
#define WRITE_REGISTER 1
|
||||
#define WRITE1_REGISTER 3
|
||||
#define READ_MEMORY 2
|
||||
#define WRITE_MEMORY 5
|
||||
#define WRITE1_MEMORY 7
|
||||
|
||||
|
||||
// Registers
|
||||
#define PAR 0x10 // 6 bits - Physical address (MAC)
|
||||
|
||||
//TODO: multicast support
|
||||
//TODO: set media state support
|
||||
@@ -34,7 +51,20 @@ struct TRXHeader {
|
||||
};
|
||||
|
||||
|
||||
ASIXDevice::ASIXDevice(usb_device device, const char *description)
|
||||
status_t
|
||||
DavicomDevice::_ReadRegister(uint8 reg, size_t size, uint8* buffer)
|
||||
{
|
||||
if (size > 255) return B_BAD_VALUE;
|
||||
size_t actualLength;
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||
READ_REGISTER, 0, reg, size, buffer, &actualLength);
|
||||
if (size != actualLength) TRACE_ALWAYS("Size mismatch reading register ! asked %d got %d",size,actualLength);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
DavicomDevice::DavicomDevice(usb_device device, const char *description)
|
||||
: fStatus(B_ERROR),
|
||||
fOpen(false),
|
||||
fRemoved(false),
|
||||
@@ -91,12 +121,13 @@ ASIXDevice::ASIXDevice(usb_device device, const char *description)
|
||||
return;
|
||||
}
|
||||
|
||||
// must be set in derived class constructor
|
||||
// fStatus = B_OK;
|
||||
// TODO : others inits here ?
|
||||
|
||||
fStatus = B_OK;
|
||||
}
|
||||
|
||||
|
||||
ASIXDevice::~ASIXDevice()
|
||||
DavicomDevice::~DavicomDevice()
|
||||
{
|
||||
if (fNotifyReadSem >= B_OK)
|
||||
delete_sem(fNotifyReadSem);
|
||||
@@ -112,7 +143,7 @@ ASIXDevice::~ASIXDevice()
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::Open(uint32 flags)
|
||||
DavicomDevice::Open(uint32 flags)
|
||||
{
|
||||
if (fOpen)
|
||||
return B_BUSY;
|
||||
@@ -139,7 +170,7 @@ ASIXDevice::Open(uint32 flags)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::Close()
|
||||
DavicomDevice::Close()
|
||||
{
|
||||
if (fRemoved) {
|
||||
fOpen = false;
|
||||
@@ -160,14 +191,14 @@ ASIXDevice::Close()
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::Free()
|
||||
DavicomDevice::Free()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::Read(uint8 *buffer, size_t *numBytes)
|
||||
DavicomDevice::Read(uint8 *buffer, size_t *numBytes)
|
||||
{
|
||||
size_t numBytesToRead = *numBytes;
|
||||
*numBytes = 0;
|
||||
@@ -244,7 +275,7 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::Write(const uint8 *buffer, size_t *numBytes)
|
||||
DavicomDevice::Write(const uint8 *buffer, size_t *numBytes)
|
||||
{
|
||||
size_t numBytesToWrite = *numBytes;
|
||||
*numBytes = 0;
|
||||
@@ -302,7 +333,7 @@ ASIXDevice::Write(const uint8 *buffer, size_t *numBytes)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
DavicomDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
{
|
||||
switch (op) {
|
||||
case ETHER_INIT:
|
||||
@@ -351,7 +382,7 @@ ASIXDevice::Control(uint32 op, void *buffer, size_t length)
|
||||
|
||||
|
||||
void
|
||||
ASIXDevice::Removed()
|
||||
DavicomDevice::Removed()
|
||||
{
|
||||
fRemoved = true;
|
||||
fHasConnection = false;
|
||||
@@ -375,7 +406,7 @@ ASIXDevice::Removed()
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::SetupDevice(bool deviceReplugged)
|
||||
DavicomDevice::SetupDevice(bool deviceReplugged)
|
||||
{
|
||||
ether_address address;
|
||||
status_t result = ReadMACAddress(&address);
|
||||
@@ -406,7 +437,7 @@ ASIXDevice::SetupDevice(bool deviceReplugged)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::CompareAndReattach(usb_device device)
|
||||
DavicomDevice::CompareAndReattach(usb_device device)
|
||||
{
|
||||
const usb_device_descriptor *deviceDescriptor
|
||||
= gUSBModule->get_device_descriptor(device);
|
||||
@@ -449,7 +480,7 @@ ASIXDevice::CompareAndReattach(usb_device device)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::_SetupEndpoints()
|
||||
DavicomDevice::_SetupEndpoints()
|
||||
{
|
||||
const usb_configuration_info *config
|
||||
= gUSBModule->get_nth_configuration(fDevice, 0);
|
||||
@@ -518,30 +549,20 @@ ASIXDevice::_SetupEndpoints()
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::ReadMACAddress(ether_address_t *address)
|
||||
DavicomDevice::ReadMACAddress(ether_address_t *address)
|
||||
{
|
||||
size_t actual_length = 0;
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||
fReadNodeIDRequest, 0, 0, sizeof(ether_address),
|
||||
address, &actual_length);
|
||||
status_t result = _ReadRegister(PAR, sizeof(ether_address), (uint8*)address);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error of reading MAC address:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(actual_length != sizeof(ether_address)) {
|
||||
TRACE_ALWAYS("Mismatch of NODE ID data size: %d instead of %d bytes\n",
|
||||
actual_length, sizeof(ether_address));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::ReadRXControlRegister(uint16 *rxcontrol)
|
||||
DavicomDevice::ReadRXControlRegister(uint16 *rxcontrol)
|
||||
{
|
||||
size_t actual_length = 0;
|
||||
*rxcontrol = 0;
|
||||
@@ -562,7 +583,7 @@ ASIXDevice::ReadRXControlRegister(uint16 *rxcontrol)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::WriteRXControlRegister(uint16 rxcontrol)
|
||||
DavicomDevice::WriteRXControlRegister(uint16 rxcontrol)
|
||||
{
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
@@ -572,7 +593,7 @@ ASIXDevice::WriteRXControlRegister(uint16 rxcontrol)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::StopDevice()
|
||||
DavicomDevice::StopDevice()
|
||||
{
|
||||
status_t result = WriteRXControlRegister(0);
|
||||
|
||||
@@ -586,7 +607,7 @@ ASIXDevice::StopDevice()
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::SetPromiscuousMode(bool on)
|
||||
DavicomDevice::SetPromiscuousMode(bool on)
|
||||
{
|
||||
uint16 rxcontrol = 0;
|
||||
|
||||
@@ -613,7 +634,7 @@ ASIXDevice::SetPromiscuousMode(bool on)
|
||||
|
||||
|
||||
status_t
|
||||
ASIXDevice::ModifyMulticastTable(bool add, uint8 address)
|
||||
DavicomDevice::ModifyMulticastTable(bool add, uint8 address)
|
||||
{
|
||||
//TODO: !!!
|
||||
TRACE_ALWAYS("Call for (%d, %#02x) is not implemented\n", add, address);
|
||||
@@ -622,11 +643,11 @@ ASIXDevice::ModifyMulticastTable(bool add, uint8 address)
|
||||
|
||||
|
||||
void
|
||||
ASIXDevice::_ReadCallback(void *cookie, int32 status, void *data,
|
||||
DavicomDevice::_ReadCallback(void *cookie, int32 status, void *data,
|
||||
uint32 actualLength)
|
||||
{
|
||||
TRACE_FLOW("ReadCB: %d bytes; status:%#010x\n", actualLength, status);
|
||||
ASIXDevice *device = (ASIXDevice *)cookie;
|
||||
DavicomDevice *device = (DavicomDevice *)cookie;
|
||||
device->fActualLengthRead = actualLength;
|
||||
device->fStatusRead = status;
|
||||
release_sem_etc(device->fNotifyReadSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
@@ -634,11 +655,11 @@ ASIXDevice::_ReadCallback(void *cookie, int32 status, void *data,
|
||||
|
||||
|
||||
void
|
||||
ASIXDevice::_WriteCallback(void *cookie, int32 status, void *data,
|
||||
DavicomDevice::_WriteCallback(void *cookie, int32 status, void *data,
|
||||
uint32 actualLength)
|
||||
{
|
||||
TRACE_FLOW("WriteCB: %d bytes; status:%#010x\n", actualLength, status);
|
||||
ASIXDevice *device = (ASIXDevice *)cookie;
|
||||
DavicomDevice *device = (DavicomDevice *)cookie;
|
||||
device->fActualLengthWrite = actualLength;
|
||||
device->fStatusWrite = status;
|
||||
release_sem_etc(device->fNotifyWriteSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
@@ -646,10 +667,10 @@ ASIXDevice::_WriteCallback(void *cookie, int32 status, void *data,
|
||||
|
||||
|
||||
void
|
||||
ASIXDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
||||
DavicomDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
||||
uint32 actualLength)
|
||||
{
|
||||
ASIXDevice *device = (ASIXDevice *)cookie;
|
||||
DavicomDevice *device = (DavicomDevice *)cookie;
|
||||
atomic_add(&device->fInsideNotify, 1);
|
||||
if (status == B_CANCELED || device->fRemoved) {
|
||||
atomic_add(&device->fInsideNotify, -1);
|
||||
@@ -673,3 +694,126 @@ ASIXDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
||||
atomic_add(&device->fInsideNotify, -1);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DavicomDevice::StartDevice()
|
||||
{
|
||||
size_t actualLength = 0;
|
||||
/*ASX
|
||||
for(size_t i = 0; i < sizeof(fIPG)/sizeof(fIPG[0]); i++) {
|
||||
|
||||
status_t result = gUSBModule->send_request(fDevice,
|
||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||
WRITE_IPG0, 0, 0, sizeof(fIPG[i]), &fIPG[i], &actualLength);
|
||||
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error writing IPG%d: %#010x\n", i, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(actualLength != sizeof(fIPG[i])) {
|
||||
TRACE_ALWAYS("Mismatch of written IPG%d data. "
|
||||
"%d bytes of %d written.\n", i, actualLength, sizeof(fIPG[i]));
|
||||
}
|
||||
}
|
||||
uint16 rxcontrol = RXCTL_START | RXCTL_MULTICAST
|
||||
| RXCTL_UNICAST | RXCTL_BROADCAST;
|
||||
status_t result = WriteRXControlRegister(rxcontrol);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
|
||||
}
|
||||
|
||||
TRACE_RET(result);
|
||||
return result;
|
||||
*/
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DavicomDevice::OnNotify(uint32 actualLength)
|
||||
{
|
||||
/*
|
||||
if (actualLength < sizeof(AX88172Notify)) {
|
||||
TRACE_ALWAYS("Data underrun error. %d of %d bytes received\n",
|
||||
actualLength, sizeof(AX88172Notify));
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
AX88172Notify *notification = (AX88172Notify *)fNotifyBuffer;
|
||||
|
||||
if(notification->btA1 != 0xa1) {
|
||||
TRACE_ALWAYS("Notify magic byte is invalid: %#02x\n",
|
||||
notification->btA1);
|
||||
}
|
||||
|
||||
uint phyIndex = 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;
|
||||
fHasConnection = linkIsUp;
|
||||
|
||||
if(linkStateChange) {
|
||||
TRACE("Link state of PHY%d has been changed to '%s'\n",
|
||||
phyIndex, fHasConnection ? "up" : "down");
|
||||
}
|
||||
|
||||
if (linkStateChange && fLinkStateChangeSem >= B_OK)
|
||||
release_sem_etc(fLinkStateChangeSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
*/
|
||||
return B_ERROR; // shoulb be B_OK when implemented :)
|
||||
}
|
||||
|
||||
status_t
|
||||
DavicomDevice::GetLinkState(ether_link_state *linkState)
|
||||
{
|
||||
/*
|
||||
uint16 miiANAR = 0;
|
||||
uint16 miiANLPAR = 0;
|
||||
|
||||
status_t result = fMII.Read(MII_ANAR, &miiANAR);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error reading MII ANAR register:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fMII.Read(MII_ANLPAR, &miiANLPAR);
|
||||
if(result != B_OK) {
|
||||
TRACE_ALWAYS("Error reading MII ANLPAR register:%#010x\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
TRACE_FLOW("ANAR:%04x ANLPAR:%04x\n", miiANAR, miiANLPAR);
|
||||
|
||||
uint16 mediumStatus = miiANAR & miiANLPAR;
|
||||
|
||||
linkState->quality = 1000;
|
||||
|
||||
linkState->media = IFM_ETHER | (fHasConnection ? IFM_ACTIVE : 0);
|
||||
linkState->media |= mediumStatus & (ANLPAR_TX_FD | ANLPAR_10_FD) ?
|
||||
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
||||
|
||||
linkState->speed = mediumStatus & (ANLPAR_TX_FD | ANLPAR_TX_HD) ? 100000 : 10000;
|
||||
|
||||
TRACE_FLOW("Medium state: %s, %lld MBit/s, %s duplex.\n",
|
||||
(linkState->media & IFM_ACTIVE) ? "active" : "inactive",
|
||||
linkState->speed / 1000,
|
||||
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
||||
*/
|
||||
return B_ERROR; // B_OK
|
||||
}
|
||||
|
||||
+15
-13
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* Davicom DM9601 USB 1.1 Ethernet Driver.
|
||||
* Copyright (c) 2009 Adrien Destugues <pulkomandy@gmail.com>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
||||
* Distributed under the terms of the MIT license.
|
||||
@@ -10,18 +14,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _USB_ASIX_DEVICE_H_
|
||||
#define _USB_ASIX_DEVICE_H_
|
||||
#ifndef _USB_Davicom_DEVICE_H_
|
||||
#define _USB_Davicom_DEVICE_H_
|
||||
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include "Driver.h"
|
||||
#include "MIIBus.h"
|
||||
|
||||
class ASIXDevice {
|
||||
class DavicomDevice {
|
||||
public:
|
||||
ASIXDevice(usb_device device, const char *description);
|
||||
virtual ~ASIXDevice();
|
||||
DavicomDevice(usb_device device, const char *description);
|
||||
virtual ~DavicomDevice();
|
||||
|
||||
status_t InitCheck() { return fStatus; };
|
||||
|
||||
@@ -51,12 +54,14 @@ static void _NotifyCallback(void *cookie, int32 status,
|
||||
|
||||
status_t _SetupEndpoints();
|
||||
|
||||
status_t _ReadRegister(uint8 reg, size_t size, uint8* buffer);
|
||||
|
||||
protected:
|
||||
/* overrides */
|
||||
virtual status_t StartDevice() = 0;
|
||||
virtual status_t StartDevice() ;
|
||||
virtual status_t StopDevice();
|
||||
virtual status_t OnNotify(uint32 actualLength) = 0;
|
||||
virtual status_t GetLinkState(ether_link_state *state) = 0;
|
||||
virtual status_t OnNotify(uint32 actualLength) ;
|
||||
virtual status_t GetLinkState(ether_link_state *state) ;
|
||||
virtual status_t SetPromiscuousMode(bool bOn);
|
||||
virtual status_t ModifyMulticastTable(bool add, uint8 address);
|
||||
status_t ReadMACAddress(ether_address_t *address);
|
||||
@@ -93,9 +98,6 @@ const char * fDescription;
|
||||
uint8 * fNotifyBuffer;
|
||||
uint32 fNotifyBufferLength;
|
||||
|
||||
// MII bus handler
|
||||
MIIBus fMII;
|
||||
|
||||
// connection data
|
||||
sem_id fLinkStateChangeSem;
|
||||
ether_address_t fMACAddress;
|
||||
@@ -108,4 +110,4 @@ const char * fDescription;
|
||||
uint16 fPromiscuousBits;
|
||||
};
|
||||
|
||||
#endif //_USB_ASIX_DEVICE_H_
|
||||
#endif //_USB_Davicom_DEVICE_H_
|
||||
@@ -10,7 +10,7 @@
|
||||
trace on
|
||||
|
||||
## logfile [full path to private log file]
|
||||
## default path value: /var/log/usb_asix.log
|
||||
## default path value: /var/log/usb_davicom.log
|
||||
## if disabled - all output goes to syslog
|
||||
|
||||
logfile /var/log/usb_davicom.log
|
||||
|
||||
Reference in New Issue
Block a user