usb_asix driver refactoring:
* work with multicast filter table implemented; * new device lookup and creation procedure: avoid duplication of supported devices information; * coding style fixes; git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42758 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
117e135799
commit
1724ebde55
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,12 +10,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Driver.h"
|
|
||||||
#include "Settings.h"
|
|
||||||
#include "ASIXDevice.h"
|
#include "ASIXDevice.h"
|
||||||
|
|
||||||
//TODO: multicast support
|
#include <stdio.h>
|
||||||
//TODO: set media state support
|
|
||||||
|
#include "ASIXVendorRequests.h"
|
||||||
|
#include "Driver.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
|
||||||
// frame header used during transfer data
|
// frame header used during transfer data
|
||||||
@ -34,45 +36,37 @@ struct TRXHeader {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ASIXDevice::ASIXDevice(usb_device device, const char *description)
|
ASIXDevice::ASIXDevice(usb_device device, DeviceInfo& deviceInfo)
|
||||||
: fStatus(B_ERROR),
|
:
|
||||||
|
fDevice(device),
|
||||||
|
fStatus(B_ERROR),
|
||||||
fOpen(false),
|
fOpen(false),
|
||||||
fRemoved(false),
|
fRemoved(false),
|
||||||
fInsideNotify(0),
|
fHasConnection(false),
|
||||||
fDevice(device),
|
|
||||||
fDescription(description),
|
|
||||||
fNonBlocking(false),
|
fNonBlocking(false),
|
||||||
|
fInsideNotify(0),
|
||||||
fFrameSize(0),
|
fFrameSize(0),
|
||||||
fNotifyEndpoint(0),
|
fNotifyEndpoint(0),
|
||||||
fReadEndpoint(0),
|
fReadEndpoint(0),
|
||||||
fWriteEndpoint(0),
|
fWriteEndpoint(0),
|
||||||
|
fActualLengthRead(0),
|
||||||
|
fActualLengthWrite(0),
|
||||||
|
fStatusRead(B_OK),
|
||||||
|
fStatusWrite(B_OK),
|
||||||
fNotifyReadSem(-1),
|
fNotifyReadSem(-1),
|
||||||
fNotifyWriteSem(-1),
|
fNotifyWriteSem(-1),
|
||||||
fNotifyBuffer(NULL),
|
fNotifyBuffer(NULL),
|
||||||
fNotifyBufferLength(0),
|
fNotifyBufferLength(0),
|
||||||
fLinkStateChangeSem(-1),
|
fLinkStateChangeSem(-1),
|
||||||
fHasConnection(false),
|
|
||||||
fUseTRXHeader(false),
|
fUseTRXHeader(false),
|
||||||
fReadNodeIDRequest(kInvalidRequest),
|
fReadNodeIDRequest(kInvalidRequest)
|
||||||
fReadRXControlRequest(kInvalidRequest),
|
|
||||||
fWriteRXControlRequest(kInvalidRequest),
|
|
||||||
fPromiscuousBits(0)
|
|
||||||
{
|
{
|
||||||
const usb_device_descriptor
|
fDeviceInfo = deviceInfo;
|
||||||
*deviceDescriptor = gUSBModule->get_device_descriptor(device);
|
|
||||||
|
|
||||||
if (deviceDescriptor == NULL) {
|
|
||||||
TRACE_ALWAYS("Error of getting USB device descriptor.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fIPG[0] = 0x15;
|
fIPG[0] = 0x15;
|
||||||
fIPG[1] = 0x0c;
|
fIPG[1] = 0x0c;
|
||||||
fIPG[2] = 0x12;
|
fIPG[2] = 0x12;
|
||||||
|
|
||||||
fVendorID = deviceDescriptor->vendor_id;
|
|
||||||
fProductID = deviceDescriptor->product_id;
|
|
||||||
|
|
||||||
fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read");
|
fNotifyReadSem = create_sem(0, DRIVER_NAME"_notify_read");
|
||||||
if (fNotifyReadSem < B_OK) {
|
if (fNotifyReadSem < B_OK) {
|
||||||
TRACE_ALWAYS("Error of creating read notify semaphore:%#010x\n",
|
TRACE_ALWAYS("Error of creating read notify semaphore:%#010x\n",
|
||||||
@ -208,7 +202,8 @@ ASIXDevice::Read(uint8 *buffer, size_t *numBytes)
|
|||||||
result = gUSBModule->clear_feature(fReadEndpoint,
|
result = gUSBModule->clear_feature(fReadEndpoint,
|
||||||
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);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,20 +322,18 @@ ASIXDevice::Control(uint32 op, void *buffer, size_t length)
|
|||||||
|
|
||||||
case ETHER_ADDMULTI:
|
case ETHER_ADDMULTI:
|
||||||
TRACE("ETHER_ADDMULTI\n");
|
TRACE("ETHER_ADDMULTI\n");
|
||||||
return ModifyMulticastTable(true, *((uint8*)buffer));
|
return ModifyMulticastTable(true, (ether_address_t*)buffer);
|
||||||
|
|
||||||
case ETHER_REMMULTI:
|
case ETHER_REMMULTI:
|
||||||
TRACE("ETHER_REMMULTI\n");
|
TRACE("ETHER_REMMULTI\n");
|
||||||
return ModifyMulticastTable(false, *((uint8*)buffer));
|
return ModifyMulticastTable(false, (ether_address_t*)buffer);
|
||||||
|
|
||||||
#if HAIKU_TARGET_PLATFORM_HAIKU
|
|
||||||
case ETHER_SET_LINK_STATE_SEM:
|
case ETHER_SET_LINK_STATE_SEM:
|
||||||
fLinkStateChangeSem = *(sem_id *)buffer;
|
fLinkStateChangeSem = *(sem_id *)buffer;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case ETHER_GET_LINK_STATE:
|
case ETHER_GET_LINK_STATE:
|
||||||
return GetLinkState((ether_link_state *)buffer);
|
return GetLinkState((ether_link_state *)buffer);
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TRACE_ALWAYS("Unhandled IOCTL catched: %#010x\n", op);
|
TRACE_ALWAYS("Unhandled IOCTL catched: %#010x\n", op);
|
||||||
@ -389,8 +382,8 @@ ASIXDevice::SetupDevice(bool deviceReplugged)
|
|||||||
address.ebyte[3], address.ebyte[4], address.ebyte[5]);
|
address.ebyte[3], address.ebyte[4], address.ebyte[5]);
|
||||||
|
|
||||||
if (deviceReplugged) {
|
if (deviceReplugged) {
|
||||||
// this might be the same device that was replugged - read the MAC address
|
// this might be the same device that was replugged - read the MAC
|
||||||
// (which should be at the same index) to make sure
|
// address (which should be at the same index) to make sure
|
||||||
if (memcmp(&address, &fMACAddress, sizeof(address)) != 0) {
|
if (memcmp(&address, &fMACAddress, sizeof(address)) != 0) {
|
||||||
TRACE_ALWAYS("Cannot replace device with MAC address:"
|
TRACE_ALWAYS("Cannot replace device with MAC address:"
|
||||||
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
@ -416,8 +409,8 @@ ASIXDevice::CompareAndReattach(usb_device device)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceDescriptor->vendor_id != fVendorID
|
if (deviceDescriptor->vendor_id != fDeviceInfo.VendorId()
|
||||||
&& deviceDescriptor->product_id != fProductID) {
|
&& deviceDescriptor->product_id != fDeviceInfo.ProductId()) {
|
||||||
// this certainly isn't the same device
|
// this certainly isn't the same device
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
@ -477,24 +470,31 @@ ASIXDevice::_SetupEndpoints()
|
|||||||
|
|
||||||
for (size_t ep = 0; ep < interface->endpoint_count; ep++) {
|
for (size_t ep = 0; ep < interface->endpoint_count; ep++) {
|
||||||
usb_endpoint_descriptor *epd = interface->endpoint[ep].descr;
|
usb_endpoint_descriptor *epd = interface->endpoint[ep].descr;
|
||||||
if((epd->attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_INTERRUPT) {
|
if ((epd->attributes & USB_ENDPOINT_ATTR_MASK)
|
||||||
|
== USB_ENDPOINT_ATTR_INTERRUPT)
|
||||||
|
{
|
||||||
notifyEndpoint = ep;
|
notifyEndpoint = ep;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((epd->attributes & USB_ENDPOINT_ATTR_MASK) != USB_ENDPOINT_ATTR_BULK) {
|
if ((epd->attributes & USB_ENDPOINT_ATTR_MASK)
|
||||||
TRACE_ALWAYS("Error: USB endpoint type %#04x is unknown.\n", epd->attributes);
|
!= USB_ENDPOINT_ATTR_BULK)
|
||||||
|
{
|
||||||
|
TRACE_ALWAYS("Error: USB endpoint type %#04x is unknown.\n",
|
||||||
|
epd->attributes);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
|
if ((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
|
||||||
== USB_ENDPOINT_ADDR_DIR_IN) {
|
== USB_ENDPOINT_ADDR_DIR_IN)
|
||||||
|
{
|
||||||
readEndpoint = ep;
|
readEndpoint = ep;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_OUT)
|
if ((epd->endpoint_address & USB_ENDPOINT_ADDR_DIR_OUT)
|
||||||
== USB_ENDPOINT_ADDR_DIR_OUT) {
|
== USB_ENDPOINT_ADDR_DIR_OUT)
|
||||||
|
{
|
||||||
writeEndpoint = ep;
|
writeEndpoint = ep;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -548,7 +548,7 @@ ASIXDevice::ReadRXControlRegister(uint16 *rxcontrol)
|
|||||||
|
|
||||||
status_t result = gUSBModule->send_request(fDevice,
|
status_t result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||||
fReadRXControlRequest, 0, 0,
|
READ_RX_CONTROL, 0, 0,
|
||||||
sizeof(*rxcontrol), rxcontrol, &actual_length);
|
sizeof(*rxcontrol), rxcontrol, &actual_length);
|
||||||
|
|
||||||
if (sizeof(*rxcontrol) != actual_length) {
|
if (sizeof(*rxcontrol) != actual_length) {
|
||||||
@ -566,7 +566,7 @@ ASIXDevice::WriteRXControlRegister(uint16 rxcontrol)
|
|||||||
{
|
{
|
||||||
status_t result = gUSBModule->send_request(fDevice,
|
status_t result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fWriteRXControlRequest, rxcontrol, 0, 0, 0, 0);
|
WRITE_RX_CONTROL, rxcontrol, 0, 0, 0, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,14 +597,15 @@ ASIXDevice::SetPromiscuousMode(bool on)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (on)
|
if (on)
|
||||||
rxcontrol |= fPromiscuousBits;
|
rxcontrol |= RXCTL_PROMISCUOUS;
|
||||||
else
|
else
|
||||||
rxcontrol &= ~fPromiscuousBits;
|
rxcontrol &= ~RXCTL_PROMISCUOUS;
|
||||||
|
|
||||||
result = WriteRXControlRegister(rxcontrol);
|
result = WriteRXControlRegister(rxcontrol);
|
||||||
|
|
||||||
if (result != B_OK ) {
|
if (result != B_OK ) {
|
||||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
|
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
|
||||||
|
rxcontrol, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_RET(result);
|
TRACE_RET(result);
|
||||||
@ -612,12 +613,89 @@ ASIXDevice::SetPromiscuousMode(bool on)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
uint32
|
||||||
ASIXDevice::ModifyMulticastTable(bool add, uint8 address)
|
ASIXDevice::EthernetCRC32(const uint8* buffer, size_t length)
|
||||||
{
|
{
|
||||||
//TODO: !!!
|
uint32 result = 0xffffffff;
|
||||||
TRACE_ALWAYS("Call for (%d, %#02x) is not implemented\n", add, address);
|
for (size_t i = 0; i < length; i++) {
|
||||||
return B_OK;
|
uint8 data = *buffer++;
|
||||||
|
for (int bit = 0; bit < 8; bit++, data >>= 1) {
|
||||||
|
uint32 carry = ((result & 0x80000000) ? 1 : 0) ^ (data & 0x01);
|
||||||
|
result <<= 1;
|
||||||
|
if (carry != 0)
|
||||||
|
result = (result ^ 0x04c11db6) | carry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ASIXDevice::ModifyMulticastTable(bool join, ether_address_t* group)
|
||||||
|
{
|
||||||
|
char groupName[6 * 3 + 1] = { 0 };
|
||||||
|
sprintf(groupName, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
group->ebyte[0], group->ebyte[1], group->ebyte[2],
|
||||||
|
group->ebyte[3], group->ebyte[4], group->ebyte[5]);
|
||||||
|
TRACE("%s multicast group %s\n", join ? "Joining" : "Leaving", groupName);
|
||||||
|
|
||||||
|
uint32 hash = EthernetCRC32(group->ebyte, 6);
|
||||||
|
bool isInTable = fMulticastHashes.Find(hash) != fMulticastHashes.End();
|
||||||
|
|
||||||
|
if (isInTable && join)
|
||||||
|
return B_OK; // already listed - nothing to do
|
||||||
|
|
||||||
|
if (!isInTable && !join) {
|
||||||
|
TRACE_ALWAYS("Cannot leave unlisted multicast group %s!\n", groupName);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t hashLength = 8;
|
||||||
|
uint8 hashTable[hashLength] = { 0 };
|
||||||
|
|
||||||
|
if (join)
|
||||||
|
fMulticastHashes.PushBack(hash);
|
||||||
|
else
|
||||||
|
fMulticastHashes.Remove(hash);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < fMulticastHashes.Count(); i++) {
|
||||||
|
uint32 hash = fMulticastHashes[i] >> 26;
|
||||||
|
hashTable[hash / 8] |= 1 << (hash % 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 rxcontrol = 0;
|
||||||
|
|
||||||
|
status_t result = ReadRXControlRegister(&rxcontrol);
|
||||||
|
if (result != B_OK) {
|
||||||
|
TRACE_ALWAYS("Error of reading RX Control:%#010x\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fMulticastHashes.Count() > 0)
|
||||||
|
rxcontrol |= RXCTL_MULTICAST;
|
||||||
|
else
|
||||||
|
rxcontrol &= ~RXCTL_MULTICAST;
|
||||||
|
|
||||||
|
// write multicast hash table
|
||||||
|
size_t actualLength = 0;
|
||||||
|
result = gUSBModule->send_request(fDevice,
|
||||||
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
|
WRITE_MF_ARRAY, 0, 0,
|
||||||
|
hashLength, hashTable, &actualLength);
|
||||||
|
if (result != B_OK) {
|
||||||
|
TRACE_ALWAYS("Error writing hash table in MAR: %#010x.\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actualLength != hashLength)
|
||||||
|
TRACE_ALWAYS("Incomplete writing of hash table: %d bytes of %d\n",
|
||||||
|
actualLength, hashLength);
|
||||||
|
|
||||||
|
result = WriteRXControlRegister(rxcontrol);
|
||||||
|
if (result != B_OK)
|
||||||
|
TRACE_ALWAYS("Error writing %#02X to RXC:%#010x.\n", rxcontrol, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -661,7 +739,8 @@ ASIXDevice::_NotifyCallback(void *cookie, int32 status, void *data,
|
|||||||
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
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,18 +9,40 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_ASIX_DEVICE_H_
|
#ifndef _USB_ASIX_DEVICE_H_
|
||||||
#define _USB_ASIX_DEVICE_H_
|
#define _USB_ASIX_DEVICE_H_
|
||||||
|
|
||||||
#include <net/if_media.h>
|
|
||||||
|
#include <ether_driver.h>
|
||||||
|
#include <util/Vector.h>
|
||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "MIIBus.h"
|
#include "MIIBus.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct DeviceInfo {
|
||||||
|
union Id {
|
||||||
|
uint16 fIds[2];
|
||||||
|
uint32 fKey;
|
||||||
|
} fId;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
AX88172 = 0,
|
||||||
|
AX88772 = 1,
|
||||||
|
AX88178 = 2
|
||||||
|
} fType;
|
||||||
|
|
||||||
|
const char* fName;
|
||||||
|
|
||||||
|
inline uint16 VendorId() { return fId.fIds[0]; }
|
||||||
|
inline uint16 ProductId() { return fId.fIds[1]; }
|
||||||
|
inline uint32 Key() { return fId.fKey; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ASIXDevice {
|
class ASIXDevice {
|
||||||
public:
|
public:
|
||||||
ASIXDevice(usb_device device, const char *description);
|
ASIXDevice(usb_device device, DeviceInfo& devInfo);
|
||||||
virtual ~ASIXDevice();
|
virtual ~ASIXDevice();
|
||||||
|
|
||||||
status_t InitCheck() { return fStatus; };
|
status_t InitCheck() { return fStatus; };
|
||||||
@ -52,27 +74,31 @@ static void _NotifyCallback(void *cookie, int32 status,
|
|||||||
status_t _SetupEndpoints();
|
status_t _SetupEndpoints();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* overrides */
|
// overrides
|
||||||
virtual status_t StartDevice() = 0;
|
virtual status_t StartDevice() = 0;
|
||||||
virtual status_t StopDevice();
|
virtual status_t StopDevice();
|
||||||
virtual status_t OnNotify(uint32 actualLength) = 0;
|
virtual status_t OnNotify(uint32 actualLength) = 0;
|
||||||
virtual status_t GetLinkState(ether_link_state *state) = 0;
|
virtual status_t GetLinkState(ether_link_state *state) = 0;
|
||||||
virtual status_t SetPromiscuousMode(bool bOn);
|
virtual status_t SetPromiscuousMode(bool bOn);
|
||||||
virtual status_t ModifyMulticastTable(bool add, uint8 address);
|
uint32 EthernetCRC32(const uint8* buffer, size_t length);
|
||||||
|
virtual status_t ModifyMulticastTable(bool add,
|
||||||
|
ether_address_t* group);
|
||||||
status_t ReadMACAddress(ether_address_t *address);
|
status_t ReadMACAddress(ether_address_t *address);
|
||||||
status_t ReadRXControlRegister(uint16 *rxcontrol);
|
status_t ReadRXControlRegister(uint16 *rxcontrol);
|
||||||
status_t WriteRXControlRegister(uint16 rxcontrol);
|
status_t WriteRXControlRegister(uint16 rxcontrol);
|
||||||
|
|
||||||
|
// device info
|
||||||
|
usb_device fDevice;
|
||||||
|
DeviceInfo fDeviceInfo;
|
||||||
|
ether_address_t fMACAddress;
|
||||||
|
|
||||||
// state tracking
|
// state tracking
|
||||||
status_t fStatus;
|
status_t fStatus;
|
||||||
bool fOpen;
|
bool fOpen;
|
||||||
bool fRemoved;
|
bool fRemoved;
|
||||||
vint32 fInsideNotify;
|
bool fHasConnection;
|
||||||
usb_device fDevice;
|
|
||||||
uint16 fVendorID;
|
|
||||||
uint16 fProductID;
|
|
||||||
const char * fDescription;
|
|
||||||
bool fNonBlocking;
|
bool fNonBlocking;
|
||||||
|
vint32 fInsideNotify;
|
||||||
|
|
||||||
// interface and device infos
|
// interface and device infos
|
||||||
uint16 fFrameSize;
|
uint16 fFrameSize;
|
||||||
@ -92,20 +118,16 @@ const char * fDescription;
|
|||||||
|
|
||||||
uint8 * fNotifyBuffer;
|
uint8 * fNotifyBuffer;
|
||||||
uint32 fNotifyBufferLength;
|
uint32 fNotifyBufferLength;
|
||||||
|
sem_id fLinkStateChangeSem;
|
||||||
|
|
||||||
// MII bus handler
|
// MII bus handler
|
||||||
MIIBus fMII;
|
MIIBus fMII;
|
||||||
|
|
||||||
// connection data
|
// connection data
|
||||||
sem_id fLinkStateChangeSem;
|
|
||||||
ether_address_t fMACAddress;
|
|
||||||
bool fHasConnection;
|
|
||||||
bool fUseTRXHeader;
|
bool fUseTRXHeader;
|
||||||
uint8 fIPG[3];
|
uint8 fIPG[3];
|
||||||
uint8 fReadNodeIDRequest;
|
uint8 fReadNodeIDRequest;
|
||||||
uint8 fReadRXControlRequest;
|
Vector<uint32> fMulticastHashes;
|
||||||
uint8 fWriteRXControlRequest;
|
|
||||||
uint16 fPromiscuousBits;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _USB_ASIX_DEVICE_H_
|
#endif // _USB_ASIX_DEVICE_H_
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
|
* Copyright (c) 2011 S.Zharski <imker@gmx.li>
|
||||||
|
* Distributed under the terms of the MIT license.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _ASIX_VENDOR_REQUESTS_H_
|
||||||
|
#define _ASIX_VENDOR_REQUESTS_H_
|
||||||
|
|
||||||
|
|
||||||
|
// USB Vendor Requests used by all chip types
|
||||||
|
// For chip-spercific information look into
|
||||||
|
// corresponding AX88***Device.cpp files.
|
||||||
|
enum ASIXVendorRequests {
|
||||||
|
READ_RXTX_SRAM = 0x02,
|
||||||
|
WRITE_RXTX_SRAM = 0x03, // AX88178-772
|
||||||
|
WRITE_RX_SRAM = 0x03, // AX88172
|
||||||
|
WRITE_TX_SRAM = 0x04, // AX88172
|
||||||
|
SW_MII_OP = 0x06,
|
||||||
|
READ_MII = 0x07,
|
||||||
|
WRITE_MII = 0x08,
|
||||||
|
READ_MII_OP_MODE = 0x09, // AX88172-772
|
||||||
|
READ_MII_STATUS = 0x09, // AX88178
|
||||||
|
HW_MII_OP = 0x0A,
|
||||||
|
READ_SROM = 0x0B,
|
||||||
|
WRITE_SROM = 0x0C,
|
||||||
|
WRITE_SROM_ENABLE = 0x0D,
|
||||||
|
WRITE_SROM_DISABLE = 0x0E,
|
||||||
|
READ_RX_CONTROL = 0x0F,
|
||||||
|
WRITE_RX_CONTROL = 0x10,
|
||||||
|
READ_IPGS = 0x11,
|
||||||
|
WRITE_IPGS = 0x12, // AX88178-772
|
||||||
|
WRITE_IPG0 = 0x12, // AX88172
|
||||||
|
WRITE_IPG1 = 0x13, // AX88172
|
||||||
|
WRITE_IPG2 = 0x14, // AX88172
|
||||||
|
READ_NODEID = 0x13, // AX88178-772
|
||||||
|
WRITE_NODEID = 0x14, // AX88178-772
|
||||||
|
READ_MF_ARRAY = 0x15,
|
||||||
|
WRITE_MF_ARRAY = 0x16,
|
||||||
|
READ_TEST = 0x17, // AX88178-772
|
||||||
|
READ_NODEID_AX88172 = 0x17, // AX88172
|
||||||
|
WRITE_NODEID_AX88172 = 0x18, // AX88172
|
||||||
|
READ_PHYID = 0x19,
|
||||||
|
READ_MEDIUM_STATUS = 0x1A,
|
||||||
|
WRITE_MEDIUM_MODE = 0x1B,
|
||||||
|
GET_MONITOR_MODE = 0x1C,
|
||||||
|
SET_MONITOR_MODE = 0x1D,
|
||||||
|
READ_GPIOS = 0x1E,
|
||||||
|
WRITE_GPIOS = 0x1F,
|
||||||
|
WRITE_SOFT_RESET = 0x20, // AX88178-772
|
||||||
|
READ_PHY_SEL_STATE = 0x21, // AX88772
|
||||||
|
WRITE_PHY_SEL = 0x22, // AX88772
|
||||||
|
READ_MIIS_IF_STATE = 0x21, // AX88178
|
||||||
|
WRITE_MIIS_IF_STATE = 0x22 // AX88178
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// RX Control Register bits
|
||||||
|
enum ASIXRXControl {
|
||||||
|
RXCTL_PROMISCUOUS = 0x0001,
|
||||||
|
RXCTL_ALL_MULTICAT = 0x0002,
|
||||||
|
RXCTL_UNICAST = 0x0004, // AX88172
|
||||||
|
RXCTL_SEP = 0x0004, // AX88772-178
|
||||||
|
RXCTL_BROADCAST = 0x0008,
|
||||||
|
RXCTL_MULTICAST = 0x0010,
|
||||||
|
RXCTL_AP = 0x0020, // AX88772-178
|
||||||
|
RXCTL_START = 0x0080,
|
||||||
|
RXCTL_USB_MFB = 0x0100 // AX88772-178
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _ASIX_VENDOR_REQUESTS_H_
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,52 +10,60 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Settings.h"
|
|
||||||
#include "AX88172Device.h"
|
#include "AX88172Device.h"
|
||||||
|
|
||||||
|
#include <net/if_media.h>
|
||||||
|
|
||||||
enum AX88172_Requests {
|
#include "ASIXVendorRequests.h"
|
||||||
READ_RXTX_SRAM = 0x02, // C0 02 XX YY 0M 00 0200 Read Rx/Tx SRAM
|
#include "Settings.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Most of vendor requests for all supported chip types use the same
|
||||||
|
// constants (see ASIXVendorRequests.h) but the layout of request data
|
||||||
|
// may be slightly diferrent for specific chip type. Below is a quick
|
||||||
|
// reference for AX88172 vendor requests data layout.
|
||||||
|
//
|
||||||
|
// READ_RXTX_SRAM, // C0 02 XX YY 0M 00 0200 Read Rx/Tx SRAM
|
||||||
// M = 0 : Rx, M=1 : Tx
|
// M = 0 : Rx, M=1 : Tx
|
||||||
WRITE_RX_SRAM = 0x03, // 40 03 XX YY PP QQ 0000 Write Rx SRAM
|
// WRITE_RX_SRAM, // 40 03 XX YY PP QQ 0000 Write Rx SRAM
|
||||||
WRITE_TX_SRAM = 0x04, // 40 04 XX YY PP QQ 0000 Write Tx SRAM
|
// WRITE_TX_SRAM, // 40 04 XX YY PP QQ 0000 Write Tx SRAM
|
||||||
SW_MII_OP = 0x06, // 40 06 00 00 00 00 0000 Software MII Operation
|
// SW_MII_OP, // 40 06 00 00 00 00 0000 Software MII Operation
|
||||||
READ_MII = 0x07, // C0 07 PI 00 RG 00 0200 Read MII Register
|
// READ_MII, // C0 07 PI 00 RG 00 0200 Read MII Register
|
||||||
WRITE_MII = 0x08, // 40 08 PI 00 RG 00 0200 Write MII Register
|
// WRITE_MII, // 40 08 PI 00 RG 00 0200 Write MII Register
|
||||||
READ_MII_OP_MODE = 0x09, // C0 09 00 00 00 00 0100 Read MII Operation Mode
|
// READ_MII_OP_MODE, // C0 09 00 00 00 00 0100 Read MII Operation Mode
|
||||||
HW_MII_OP = 0x0A, // 40 0A 00 00 00 00 0000 Hardware MII Operation
|
// HW_MII_OP, // 40 0A 00 00 00 00 0000 Hardware MII Operation
|
||||||
READ_SROM = 0x0B, // C0 0B DR 00 00 00 0200 Read SROM
|
// READ_SROM, // C0 0B DR 00 00 00 0200 Read SROM
|
||||||
WRITE_SROM = 0x0C, // 40 0C DR 00 MM SS 0000 Write SROM
|
// WRITE_SROM, // 40 0C DR 00 MM SS 0000 Write SROM
|
||||||
WRITE_SROM_ENABLE = 0x0D, // 40 0D 00 00 00 00 0000 Write SROM Enable
|
// WRITE_SROM_ENABLE, // 40 0D 00 00 00 00 0000 Write SROM Enable
|
||||||
WRITE_SROM_DISABLE = 0x0E, // 40 0E 00 00 00 00 0000 Write SROM Disable
|
// WRITE_SROM_DISABLE, // 40 0E 00 00 00 00 0000 Write SROM Disable
|
||||||
READ_RX_CONTROL = 0x0F, // C0 0F 00 00 00 00 0200 Read Rx Control Register
|
// READ_RX_CONTROL, // C0 0F 00 00 00 00 0200 Read Rx Control Register
|
||||||
WRITE_RX_CONTROL = 0x10, // 40 10 RR 00 00 00 0000 Write Rx Control Register
|
// WRITE_RX_CONTROL, // 40 10 RR 00 00 00 0000 Write Rx Control Register
|
||||||
READ_IPGS = 0x11, // C0 11 00 00 00 00 0300 Read IPG/IPG1/IPG2 Register
|
// READ_IPGS, // C0 11 00 00 00 00 0300 Read IPG/IPG1/IPG2 Register
|
||||||
WRITE_IPG0 = 0x12, // 40 12 II 00 00 00 0000 Write IPG Register
|
// WRITE_IPG0, // 40 12 II 00 00 00 0000 Write IPG Register
|
||||||
WRITE_IPG1 = 0x13, // 40 13 II 00 00 00 0000 Write IPG1 Register
|
// WRITE_IPG1, // 40 13 II 00 00 00 0000 Write IPG1 Register
|
||||||
WRITE_IPG2 = 0x14, // 40 14 II 00 00 00 0000 Write IPG2 Register
|
// WRITE_IPG2, // 40 14 II 00 00 00 0000 Write IPG2 Register
|
||||||
READ_MF_ARRAY = 0x15, // C0 15 00 00 00 00 0800 Read Multi-Filter Array
|
// READ_MF_ARRAY, // C0 15 00 00 00 00 0800 Read Multi-Filter Array
|
||||||
WRITE_MF_ARRAY = 0x16, // 40 16 00 00 00 00 0800 Write Multi-Filter Array
|
// WRITE_MF_ARRAY, // 40 16 00 00 00 00 0800 Write Multi-Filter Array
|
||||||
READ_NODEID = 0x17, // C0 17 00 00 00 00 0600 Read Node ID
|
// READ_NODEID, // C0 17 00 00 00 00 0600 Read Node ID
|
||||||
WRITE_NODEID = 0x18, //
|
// WRITE_NODEID, //
|
||||||
READ_PHYID = 0x19, // C0 19 00 00 00 00 0200 Read Ethernet/HomePNA PhyID
|
// READ_PHYID, // C0 19 00 00 00 00 0200 Read Ethernet/HomePNA PhyID
|
||||||
READ_MEDIUM_STATUS = 0x1A, // C0 1A 00 00 00 00 0100 Read Medium Status
|
// READ_MEDIUM_STATUS, // C0 1A 00 00 00 00 0100 Read Medium Status
|
||||||
WRITE_MEDIUM_MODE = 0x1B, // 40 1B MM 00 00 00 0000 Write Medium Mode
|
// WRITE_MEDIUM_MODE, // 40 1B MM 00 00 00 0000 Write Medium Mode
|
||||||
GET_MONITOR_MODE = 0x1C, // C0 1C 00 00 00 00 0100 Get Monitor Mode Status
|
// GET_MONITOR_MODE, // C0 1C 00 00 00 00 0100 Get Monitor Mode Status
|
||||||
SET_MONITOR_MODE = 0x1D, // 40 1D MM 00 00 00 0000 Set Monitor Mode On/Off
|
// SET_MONITOR_MODE, // 40 1D MM 00 00 00 0000 Set Monitor Mode On/Off
|
||||||
READ_GPIOS = 0x1E, // C0 1E 00 00 00 00 0100 Read GPIOs
|
// READ_GPIOS, // C0 1E 00 00 00 00 0100 Read GPIOs
|
||||||
WRITE_GPIOS = 0x1F // 40 1F MM 00 00 00 0000 Write GPIOs
|
// WRITE_GPIOS, // 40 1F MM 00 00 00 0000 Write GPIOs
|
||||||
};
|
|
||||||
|
|
||||||
// RX Control Register bits
|
// RX Control Register bits
|
||||||
enum AX88172_RXControl {
|
// RXCTL_PROMISCUOUS, // forward all frames up to the host
|
||||||
RXCTL_PROMISCUOUS = 0x0001, //
|
// RXCTL_ALL_MULTICAT, // forward all multicast frames up to the host
|
||||||
RXCTL_ALL_MULTICAT = 0x0002, //
|
// RXCTL_UNICAST, // ???
|
||||||
RXCTL_UNICAST = 0x0004, // ???
|
// RXCTL_BROADCAST, // forward broadcast frames up to the host
|
||||||
RXCTL_BROADCAST = 0x0008, //
|
// RXCTL_MULTICAST, // forward all multicast frames that are
|
||||||
RXCTL_MULTICAST = 0x0010, //
|
// matching to multicast filter up to the host
|
||||||
RXCTL_START = 0x0080 //
|
// RXCTL_START, // ethernet MAC start operating
|
||||||
};
|
|
||||||
|
|
||||||
// PHY IDs request answer data layout
|
// PHY IDs request answer data layout
|
||||||
struct PhyIDs {
|
struct PhyIDs {
|
||||||
@ -63,6 +71,7 @@ struct PhyIDs {
|
|||||||
uint8 PhyID2;
|
uint8 PhyID2;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
// Medium state bits
|
// Medium state bits
|
||||||
enum AX88172_MediumState {
|
enum AX88172_MediumState {
|
||||||
MEDIUM_STATE_FULL_DUPLEX = 0x02,
|
MEDIUM_STATE_FULL_DUPLEX = 0x02,
|
||||||
@ -70,6 +79,7 @@ enum AX88172_MediumState {
|
|||||||
MEDIUM_STATE_FLOW_CONTOL_EN = 0x10
|
MEDIUM_STATE_FLOW_CONTOL_EN = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Monitor Mode bits
|
// Monitor Mode bits
|
||||||
enum AX88172_MonitorMode {
|
enum AX88172_MonitorMode {
|
||||||
MONITOR_MODE = 0x01,
|
MONITOR_MODE = 0x01,
|
||||||
@ -78,6 +88,7 @@ enum AX88172_MonitorMode {
|
|||||||
MONITOR_MODE_HS_FS = 0x10
|
MONITOR_MODE_HS_FS = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// General Purpose I/O Register
|
// General Purpose I/O Register
|
||||||
enum AX88172_GPIO {
|
enum AX88172_GPIO {
|
||||||
GPIO_OO_0EN = 0x01,
|
GPIO_OO_0EN = 0x01,
|
||||||
@ -88,6 +99,7 @@ enum AX88172_GPIO {
|
|||||||
GPIO_IO_2 = 0x20
|
GPIO_IO_2 = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Notification data layout
|
// Notification data layout
|
||||||
struct AX88172Notify {
|
struct AX88172Notify {
|
||||||
uint8 btA1;
|
uint8 btA1;
|
||||||
@ -100,16 +112,20 @@ struct AX88172Notify {
|
|||||||
uint8 bt07;
|
uint8 bt07;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
// Link-State bits
|
// Link-State bits
|
||||||
enum AX88172_LinkState {
|
enum AX88172_LinkState {
|
||||||
LINK_STATE_PHY1 = 0x01,
|
LINK_STATE_PHY1 = 0x01,
|
||||||
LINK_STATE_PHY2 = 0x02
|
LINK_STATE_PHY2 = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const uint16 maxFrameSize = 1518;
|
const uint16 maxFrameSize = 1518;
|
||||||
|
|
||||||
AX88172Device::AX88172Device(usb_device device, const char *description)
|
|
||||||
: ASIXDevice(device, description)
|
AX88172Device::AX88172Device(usb_device device, DeviceInfo& deviceInfo)
|
||||||
|
:
|
||||||
|
ASIXDevice(device, deviceInfo)
|
||||||
{
|
{
|
||||||
fStatus = InitDevice();
|
fStatus = InitDevice();
|
||||||
}
|
}
|
||||||
@ -120,11 +136,7 @@ AX88172Device::InitDevice()
|
|||||||
{
|
{
|
||||||
fFrameSize = maxFrameSize;
|
fFrameSize = maxFrameSize;
|
||||||
|
|
||||||
fReadNodeIDRequest = READ_NODEID;
|
fReadNodeIDRequest = READ_NODEID_AX88172;
|
||||||
fReadRXControlRequest = READ_RX_CONTROL;
|
|
||||||
fWriteRXControlRequest = WRITE_RX_CONTROL;
|
|
||||||
|
|
||||||
fPromiscuousBits = RXCTL_PROMISCUOUS;
|
|
||||||
|
|
||||||
fNotifyBufferLength = sizeof(AX88172Notify);
|
fNotifyBufferLength = sizeof(AX88172Notify);
|
||||||
fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength);
|
fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength);
|
||||||
@ -136,6 +148,8 @@ AX88172Device::InitDevice()
|
|||||||
TRACE_RET(B_OK);
|
TRACE_RET(B_OK);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
AX88172Device::SetupDevice(bool deviceReplugged)
|
AX88172Device::SetupDevice(bool deviceReplugged)
|
||||||
{
|
{
|
||||||
@ -144,9 +158,7 @@ AX88172Device::SetupDevice(bool deviceReplugged)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = fMII.Init(fDevice,
|
result = fMII.Init(fDevice);
|
||||||
SW_MII_OP, READ_MII, WRITE_MII,
|
|
||||||
READ_MII_OP_MODE, HW_MII_OP, READ_PHYID);
|
|
||||||
|
|
||||||
if (result == B_OK)
|
if (result == B_OK)
|
||||||
return fMII.SetupPHY();
|
return fMII.SetupPHY();
|
||||||
@ -177,11 +189,11 @@ AX88172Device::StartDevice()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 rxcontrol = RXCTL_START | RXCTL_MULTICAST
|
uint16 rxcontrol = RXCTL_START | RXCTL_UNICAST | RXCTL_BROADCAST;
|
||||||
| RXCTL_UNICAST | RXCTL_BROADCAST;
|
|
||||||
status_t result = WriteRXControlRegister(rxcontrol);
|
status_t result = WriteRXControlRegister(rxcontrol);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
|
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
|
||||||
|
rxcontrol, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_RET(result);
|
TRACE_RET(result);
|
||||||
@ -236,6 +248,7 @@ AX88172Device::OnNotify(uint32 actualLength)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
AX88172Device::GetLinkState(ether_link_state *linkState)
|
AX88172Device::GetLinkState(ether_link_state *linkState)
|
||||||
{
|
{
|
||||||
@ -264,11 +277,12 @@ AX88172Device::GetLinkState(ether_link_state *linkState)
|
|||||||
linkState->media |= mediumStatus & (ANLPAR_TX_FD | ANLPAR_10_FD) ?
|
linkState->media |= mediumStatus & (ANLPAR_TX_FD | ANLPAR_10_FD) ?
|
||||||
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
||||||
|
|
||||||
linkState->speed = mediumStatus & (ANLPAR_TX_FD | ANLPAR_TX_HD) ? 100000000 : 10000000;
|
linkState->speed = mediumStatus & (ANLPAR_TX_FD | ANLPAR_TX_HD)
|
||||||
|
? 100000000 : 10000000;
|
||||||
|
|
||||||
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,
|
linkState->speed / 1000000,
|
||||||
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,15 +9,16 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_AX88172_DEVICE_H_
|
#ifndef _USB_AX88172_DEVICE_H_
|
||||||
#define _USB_AX88172_DEVICE_H_
|
#define _USB_AX88172_DEVICE_H_
|
||||||
|
|
||||||
|
|
||||||
#include "ASIXDevice.h"
|
#include "ASIXDevice.h"
|
||||||
|
|
||||||
|
|
||||||
class AX88172Device : public ASIXDevice {
|
class AX88172Device : public ASIXDevice {
|
||||||
public:
|
public:
|
||||||
AX88172Device(usb_device device, const char *description);
|
AX88172Device(usb_device device, DeviceInfo& info);
|
||||||
protected:
|
protected:
|
||||||
status_t InitDevice();
|
status_t InitDevice();
|
||||||
virtual status_t SetupDevice(bool deviceReplugged);
|
virtual status_t SetupDevice(bool deviceReplugged);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,54 +10,63 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Settings.h"
|
|
||||||
#include "AX88178Device.h"
|
#include "AX88178Device.h"
|
||||||
|
|
||||||
// Vendor USB requests for AX88178
|
#include <net/if_media.h>
|
||||||
enum AX88178_Requests {
|
|
||||||
READ_RXTX_SRAM = 0x02, //C002_AA0B_0C00_0800 Rx/Tx SRAM Read
|
#include "ASIXVendorRequests.h"
|
||||||
WRITE_RXTX_SRAM = 0x03, //4003_AA0B_0C00_0800 Rx/Tx SRAM Write
|
#include "Settings.h"
|
||||||
SW_MII_OP = 0x06, //4006_0000_0000_0000 SW Serial Management Control
|
|
||||||
READ_MII = 0x07, //c007_aa00_cc00_0200 PHY Read
|
|
||||||
WRITE_MII = 0x08, //4008_aa00_cc00_0200 PHY Write
|
// Most of vendor requests for all supported chip types use the same
|
||||||
READ_MII_STATUS = 0x09, //c009_0000_0000_0100 Serial Management Status
|
// constants (see ASIXVendorRequests.h) but the layout of request data
|
||||||
HW_MII_OP = 0x0A, //400a_0000_0000_0000 HW Serial Management Control
|
// may be slightly diferrent for specific chip type. Below is a quick
|
||||||
READ_SROM = 0x0B, //C00B_AA00_0000_0200 SROM Read
|
// reference for AX88178 vendor requests data layout.
|
||||||
WRITE_SROM = 0x0C, //400C_AA00_CCDD_0000 SROM Write
|
|
||||||
WRITE_SROM_ENABLE = 0x0D, //400D_0000_0000_0000 SROM Write Enable
|
// READ_RXTX_SRAM, //C002_AA0B_0C00_0800 Rx/Tx SRAM Read
|
||||||
WRITE_SROM_DISABLE = 0x0E, //400E_0000_0000_0000 SROM Write Disable
|
// WRITE_RXTX_SRAM, //4003_AA0B_0C00_0800 Rx/Tx SRAM Write
|
||||||
READ_RX_CONTROL = 0x0F, //C00F_0000_0000_0200 Read Rx Control
|
// SW_MII_OP, //4006_0000_0000_0000 SW Serial Management Control
|
||||||
WRITE_RX_CONTROL = 0x10, //4010_AABB_0000_0000 Write Rx Control
|
// READ_MII, //c007_aa00_cc00_0200 PHY Read
|
||||||
READ_IPGS = 0x11, //C011_0000_0000_0300 Read IPG/IPG1/IPG2 Register
|
// WRITE_MII, //4008_aa00_cc00_0200 PHY Write
|
||||||
WRITE_IPGS = 0x12, //4012_AABB_CC00_0000 Write IPG/IPG1/IPG2 Register
|
// READ_MII_STATUS, //c009_0000_0000_0100 Serial Management Status
|
||||||
READ_NODEID = 0x13, //C013_0000_0000_0600 Read Node ID
|
// HW_MII_OP, //400a_0000_0000_0000 HW Serial Management Control
|
||||||
WRITE_NODEID = 0x14, //4014_0000_0000_0600 Write Node ID
|
// READ_SROM, //C00B_AA00_0000_0200 SROM Read
|
||||||
READ_MF_ARRAY = 0x15, //C015_0000_0000_0800 Read Multicast Filter Array
|
// WRITE_SROM, //400C_AA00_CCDD_0000 SROM Write
|
||||||
WRITE_MF_ARRAY = 0x16, //4016_0000_0000_0800 Write Multicast Filter Array
|
// WRITE_SROM_ENABLE, //400D_0000_0000_0000 SROM Write Enable
|
||||||
READ_TEST = 0x17, //4017_AA00_0000_0000 Write Test Register
|
// WRITE_SROM_DISABLE, //400E_0000_0000_0000 SROM Write Disable
|
||||||
READ_PHYID = 0x19, //C019_0000_0000_0200 Read Ethernet/HomePNA PHY Address
|
// READ_RX_CONTROL, //C00F_0000_0000_0200 Read Rx Control
|
||||||
READ_MEDIUM_STATUS = 0x1A, //C01A_0000_0000_0200 Read Medium Status
|
// WRITE_RX_CONTROL, //4010_AABB_0000_0000 Write Rx Control
|
||||||
WRITE_MEDIUM_MODE = 0x1B, //401B_AABB_0000_0000 Write Medium Mode Register
|
// READ_IPGS, //C011_0000_0000_0300 Read IPG/IPG1/IPG2 Register
|
||||||
GET_MONITOR_MODE = 0x1C, //C01C_0000_0000_0100 Read Monitor Mode Status
|
// WRITE_IPGS, //4012_AABB_CC00_0000 Write IPG/IPG1/IPG2 Register
|
||||||
SET_MONITOR_MODE = 0x1D, //401D_AA00_0000_0000 Write Monitor Mode Register
|
// READ_NODEID, //C013_0000_0000_0600 Read Node ID
|
||||||
READ_GPIOS = 0x1E, //C01E_0000_0000_0100 Read GPIOs Status
|
// WRITE_NODEID, //4014_0000_0000_0600 Write Node ID
|
||||||
WRITE_GPIOS = 0x1F, //401F_AA00_0000_0000 Write GPIOs
|
// READ_MF_ARRAY, //C015_0000_0000_0800 Read Multicast Filter Array
|
||||||
WRITE_SOFT_RESET = 0x20, //4020_AA00_0000_0000 Write Software Reset
|
// WRITE_MF_ARRAY, //4016_0000_0000_0800 Write Multicast Filter Array
|
||||||
READ_MIIS_IF_STATE = 0x21, //C021_AA00_0000_0100 Read MII/GMII/RGMII Interface Status
|
// READ_TEST, //4017_AA00_0000_0000 Write Test Register
|
||||||
WRITE_MIIS_IF_STATE = 0x22 //4022_AA00_0000_0000 Write MII/GMII/RGMII Interface Control
|
// READ_PHYID, //C019_0000_0000_0200 Read Ethernet/HomePNA PHY Address
|
||||||
};
|
// READ_MEDIUM_STATUS, //C01A_0000_0000_0200 Read Medium Status
|
||||||
|
// WRITE_MEDIUM_MODE, //401B_AABB_0000_0000 Write Medium Mode Register
|
||||||
|
// GET_MONITOR_MODE, //C01C_0000_0000_0100 Read Monitor Mode Status
|
||||||
|
// SET_MONITOR_MODE, //401D_AA00_0000_0000 Write Monitor Mode Register
|
||||||
|
// READ_GPIOS, //C01E_0000_0000_0100 Read GPIOs Status
|
||||||
|
// WRITE_GPIOS, //401F_AA00_0000_0000 Write GPIOs
|
||||||
|
// WRITE_SOFT_RESET, //4020_AA00_0000_0000 Write Software Reset
|
||||||
|
// READ_MIIS_IF_STATE, //C021_AA00_0000_0100 Read MII/GMII/RGMII Iface Status
|
||||||
|
// WRITE_MIIS_IF_STATE, //4022_AA00_0000_0000 Write MII/GMII/RGMII Iface Control
|
||||||
|
|
||||||
// RX Control Register bits
|
// RX Control Register bits
|
||||||
enum AX88178_RXControl {
|
// RXCTL_PROMISCUOUS, // forward all frames up to the host
|
||||||
RXCTL_PROMISCUOUS = 0x0001, //
|
// RXCTL_ALL_MULTICAT, // forward all multicast frames up to the host
|
||||||
RXCTL_ALL_MULTICAT = 0x0002, //
|
// RXCTL_SEP, // forward frames with CRC error up to the host
|
||||||
// RXCTL_SEP = 0x0004, // do not set it!
|
// RXCTL_BROADCAST, // forward broadcast frames up to the host
|
||||||
RXCTL_BROADCAST = 0x0008, //
|
// RXCTL_MULTICAST, // forward multicast frames that are
|
||||||
RXCTL_MULTICAST = 0x0010, //
|
// matching to multicast filter up to the host
|
||||||
RXCTL_AP = 0x0020, //
|
// RXCTL_AP, // forward unicast frames that are matching
|
||||||
RXCTL_START = 0x0080, //
|
// to multicast filter up to the host
|
||||||
RXCTL_USB_MFB = 0x0100 // Max Frame Burst TX on USB
|
// RXCTL_START, // ethernet MAC start operating
|
||||||
};
|
// RXCTL_USB_MFB, // Max Frame Burst TX on USB
|
||||||
|
|
||||||
|
|
||||||
// PHY IDs request answer data layout
|
// PHY IDs request answer data layout
|
||||||
struct AX88178_PhyIDs {
|
struct AX88178_PhyIDs {
|
||||||
@ -65,6 +74,7 @@ struct AX88178_PhyIDs {
|
|||||||
uint8 PriPhyID2;
|
uint8 PriPhyID2;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
// Medium state bits
|
// Medium state bits
|
||||||
enum AX88178_MediumState {
|
enum AX88178_MediumState {
|
||||||
MEDIUM_STATE_GM = 0x0001,
|
MEDIUM_STATE_GM = 0x0001,
|
||||||
@ -84,6 +94,7 @@ enum AX88178_MediumState {
|
|||||||
MEDIUM_STATE_SM_ON = 0x1000
|
MEDIUM_STATE_SM_ON = 0x1000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Monitor Mode bits
|
// Monitor Mode bits
|
||||||
enum AX88178_MonitorMode {
|
enum AX88178_MonitorMode {
|
||||||
MONITOR_MODE_MOM = 0x01,
|
MONITOR_MODE_MOM = 0x01,
|
||||||
@ -92,6 +103,7 @@ enum AX88178_MonitorMode {
|
|||||||
MONITOR_MODE_US = 0x10
|
MONITOR_MODE_US = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// General Purpose I/O Register
|
// General Purpose I/O Register
|
||||||
enum AX88178_GPIO {
|
enum AX88178_GPIO {
|
||||||
GPIO_OO_0EN = 0x01,
|
GPIO_OO_0EN = 0x01,
|
||||||
@ -103,6 +115,7 @@ enum AX88178_GPIO {
|
|||||||
GPIO_RSE = 0x80
|
GPIO_RSE = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Software Reset Register bits
|
// Software Reset Register bits
|
||||||
enum AX88178_SoftwareReset {
|
enum AX88178_SoftwareReset {
|
||||||
SW_RESET_RR = 0x01,
|
SW_RESET_RR = 0x01,
|
||||||
@ -113,12 +126,14 @@ enum AX88178_SoftwareReset {
|
|||||||
SW_RESET_BIT6 = 0x40 // always set to 1
|
SW_RESET_BIT6 = 0x40 // always set to 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// MII/GMII/RGMII Interface Conttrol
|
// MII/GMII/RGMII Interface Conttrol
|
||||||
enum AX88178_MIISInterfaceStatus {
|
enum AX88178_MIISInterfaceStatus {
|
||||||
MIIS_IF_STATE_DM = 0x01,
|
MIIS_IF_STATE_DM = 0x01,
|
||||||
MIIS_IF_STATE_RB = 0x02
|
MIIS_IF_STATE_RB = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Notification data layout
|
// Notification data layout
|
||||||
struct AX88178_Notify {
|
struct AX88178_Notify {
|
||||||
uint8 btA1;
|
uint8 btA1;
|
||||||
@ -129,6 +144,7 @@ struct AX88178_Notify {
|
|||||||
uint16 regEEFF;
|
uint16 regEEFF;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
// Link-State bits
|
// Link-State bits
|
||||||
enum AX88178_BBState {
|
enum AX88178_BBState {
|
||||||
LINK_STATE_PPLS = 0x01,
|
LINK_STATE_PPLS = 0x01,
|
||||||
@ -137,10 +153,13 @@ enum AX88178_BBState {
|
|||||||
LINK_STATE_MDINT = 0x08
|
LINK_STATE_MDINT = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const uint16 maxFrameSize = 1536;
|
const uint16 maxFrameSize = 1536;
|
||||||
|
|
||||||
AX88178Device::AX88178Device(usb_device device, const char *description)
|
|
||||||
: ASIXDevice(device, description)
|
AX88178Device::AX88178Device(usb_device device, DeviceInfo& deviceInfo)
|
||||||
|
:
|
||||||
|
ASIXDevice(device, deviceInfo)
|
||||||
{
|
{
|
||||||
fStatus = InitDevice();
|
fStatus = InitDevice();
|
||||||
}
|
}
|
||||||
@ -153,10 +172,6 @@ AX88178Device::InitDevice()
|
|||||||
fUseTRXHeader = true;
|
fUseTRXHeader = true;
|
||||||
|
|
||||||
fReadNodeIDRequest = READ_NODEID;
|
fReadNodeIDRequest = READ_NODEID;
|
||||||
fReadRXControlRequest = READ_RX_CONTROL;
|
|
||||||
fWriteRXControlRequest = WRITE_RX_CONTROL;
|
|
||||||
|
|
||||||
fPromiscuousBits = RXCTL_PROMISCUOUS;
|
|
||||||
|
|
||||||
fNotifyBufferLength = sizeof(AX88178_Notify);
|
fNotifyBufferLength = sizeof(AX88178_Notify);
|
||||||
fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength);
|
fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength);
|
||||||
@ -178,9 +193,7 @@ AX88178Device::SetupDevice(bool deviceReplugged)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = fMII.Init(fDevice,
|
result = fMII.Init(fDevice);
|
||||||
SW_MII_OP, READ_MII, WRITE_MII,
|
|
||||||
READ_MII_STATUS, HW_MII_OP, READ_PHYID);
|
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -317,10 +330,11 @@ AX88178Device::StartDevice()
|
|||||||
"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
|
"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 rxcontrol = RXCTL_START | RXCTL_MULTICAST | RXCTL_BROADCAST;
|
uint16 rxcontrol = RXCTL_START | RXCTL_BROADCAST;
|
||||||
result = WriteRXControlRegister(rxcontrol);
|
result = WriteRXControlRegister(rxcontrol);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
|
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
|
||||||
|
rxcontrol, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_RET(result);
|
TRACE_RET(result);
|
||||||
@ -405,13 +419,14 @@ AX88178Device::GetLinkState(ether_link_state *linkState)
|
|||||||
linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ?
|
linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ?
|
||||||
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
||||||
|
|
||||||
linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100) ? 100000000 : 10000000;
|
linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100)
|
||||||
|
? 100000000 : 10000000;
|
||||||
linkState->speed = (mediumStatus & MEDIUM_STATE_GM) ?
|
linkState->speed = (mediumStatus & MEDIUM_STATE_GM) ?
|
||||||
1000000000 : linkState->speed;
|
1000000000 : linkState->speed;
|
||||||
|
|
||||||
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,
|
linkState->speed / 1000000,
|
||||||
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,15 +9,16 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_AX88178_DEVICE_H_
|
#ifndef _USB_AX88178_DEVICE_H_
|
||||||
#define _USB_AX88178_DEVICE_H_
|
#define _USB_AX88178_DEVICE_H_
|
||||||
|
|
||||||
|
|
||||||
#include "ASIXDevice.h"
|
#include "ASIXDevice.h"
|
||||||
|
|
||||||
|
|
||||||
class AX88178Device : public ASIXDevice {
|
class AX88178Device : public ASIXDevice {
|
||||||
public:
|
public:
|
||||||
AX88178Device(usb_device device, const char *description);
|
AX88178Device(usb_device device, DeviceInfo& info);
|
||||||
protected:
|
protected:
|
||||||
status_t InitDevice();
|
status_t InitDevice();
|
||||||
virtual status_t SetupDevice(bool deviceReplugged);
|
virtual status_t SetupDevice(bool deviceReplugged);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,53 +10,63 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Settings.h"
|
|
||||||
#include "AX88772Device.h"
|
#include "AX88772Device.h"
|
||||||
|
|
||||||
enum AX88772_Requests {
|
#include <net/if_media.h>
|
||||||
READ_RXTX_SRAM = 0x02, //C002_AA0B_0C00_0800 Rx/Tx SRAM Read
|
|
||||||
WRITE_RXTX_SRAM = 0x03, //4003_AA0B_0C00_0800 Rx/Tx SRAM Write
|
#include "ASIXVendorRequests.h"
|
||||||
SW_MII_OP = 0x06, //4006_0000_0000_0000 SW Serial Management Control
|
#include "Settings.h"
|
||||||
READ_MII = 0x07, //c007_aa00_cc00_0200 PHY Read
|
|
||||||
WRITE_MII = 0x08, //4008_aa00_cc00_0200 PHY Write
|
|
||||||
READ_MII_OP_MODE = 0x09, //c009_0000_0000_0100 Serial Management Status
|
// Most of vendor requests for all supported chip types use the same
|
||||||
HW_MII_OP = 0x0A, //400a_0000_0000_0000 HW Serial Management Control
|
// constants (see ASIXVendorRequests.h) but the layout of request data
|
||||||
READ_SROM = 0x0B, //C00B_AA00_0000_0200 SROM Read
|
// may be slightly diferrent for specific chip type. Below is a quick
|
||||||
WRITE_SROM = 0x0C, //400C_AA00_CCDD_0000 SROM Write
|
// reference for AX88772 vendor requests data layout.
|
||||||
WRITE_SROM_ENABLE = 0x0D, //400D_0000_0000_0000 SROM Write Enable
|
|
||||||
WRITE_SROM_DISABLE = 0x0E, //400E_0000_0000_0000 SROM Write Disable
|
// READ_RXTX_SRAM, //C002_AA0B_0C00_0800 Rx/Tx SRAM Read
|
||||||
READ_RX_CONTROL = 0x0F, //C00F_0000_0000_0200 Read Rx Control
|
// WRITE_RXTX_SRAM, //4003_AA0B_0C00_0800 Rx/Tx SRAM Write
|
||||||
WRITE_RX_CONTROL = 0x10, //4010_AABB_0000_0000 Write Rx Control
|
// SW_MII_OP, //4006_0000_0000_0000 SW Serial Management Control
|
||||||
READ_IPGS = 0x11, //C011_0000_0000_0300 Read IPG/IPG1/IPG2 Register
|
// READ_MII, //c007_aa00_cc00_0200 PHY Read
|
||||||
WRITE_IPGS = 0x12, //4012_AABB_CC00_0000 Write IPG/IPG1/IPG2 Register
|
// WRITE_MII, //4008_aa00_cc00_0200 PHY Write
|
||||||
READ_NODEID = 0x13, //C013_0000_0000_0600 Read Node ID
|
// READ_MII_OP_MODE, //c009_0000_0000_0100 Serial Management Status
|
||||||
WRITE_NODEID = 0x14, //4014_0000_0000_0600 Write Node ID
|
// HW_MII_OP, //400a_0000_0000_0000 HW Serial Management Control
|
||||||
READ_MF_ARRAY = 0x15, //C015_0000_0000_0800 Read Multicast Filter Array
|
// READ_SROM, //C00B_AA00_0000_0200 SROM Read
|
||||||
WRITE_MF_ARRAY = 0x16, //4016_0000_0000_0800 Write Multicast Filter Array
|
// WRITE_SROM, //400C_AA00_CCDD_0000 SROM Write
|
||||||
READ_TEST = 0x17, //4017_AA00_0000_0000 Write Test Register
|
// WRITE_SROM_ENABLE, //400D_0000_0000_0000 SROM Write Enable
|
||||||
READ_PHYID = 0x19, //C019_0000_0000_0200 Read Ethernet/HomePNA PHY Address
|
// WRITE_SROM_DISABLE, //400E_0000_0000_0000 SROM Write Disable
|
||||||
READ_MEDIUM_STATUS = 0x1A, //C01A_0000_0000_0200 Read Medium Status
|
// READ_RX_CONTROL, //C00F_0000_0000_0200 Read Rx Control
|
||||||
WRITE_MEDIUM_MODE = 0x1B, //401B_AABB_0000_0000 Write Medium Mode Register
|
// WRITE_RX_CONTROL, //4010_AABB_0000_0000 Write Rx Control
|
||||||
GET_MONITOR_MODE = 0x1C, //C01C_0000_0000_0100 Read Monitor Mode Status
|
// READ_IPGS, //C011_0000_0000_0300 Read IPG/IPG1/IPG2 Register
|
||||||
SET_MONITOR_MODE = 0x1D, //401D_AA00_0000_0000 Write Monitor Mode Register
|
// WRITE_IPGS, //4012_AABB_CC00_0000 Write IPG/IPG1/IPG2 Register
|
||||||
READ_GPIOS = 0x1E, //C01E_0000_0000_0100 Read GPIOs Status
|
// READ_NODEID, //C013_0000_0000_0600 Read Node ID
|
||||||
WRITE_GPIOS = 0x1F, //401F_AA00_0000_0000 Write GPIOs
|
// WRITE_NODEID, //4014_0000_0000_0600 Write Node ID
|
||||||
WRITE_SOFT_RESET = 0x20, //4020_AA00_0000_0000 Write Software Reset
|
// READ_MF_ARRAY, //C015_0000_0000_0800 Read Multicast Filter Array
|
||||||
READ_PHY_SEL_STATE = 0x21, //C021_AA00_0000_0100 Read Software PHY Select Status
|
// WRITE_MF_ARRAY, //4016_0000_0000_0800 Write Multicast Filter Array
|
||||||
WRITE_PHY_SEL = 0x22 //4022_AA00_0000_0000 Write Software PHY Select
|
// READ_TEST, //4017_AA00_0000_0000 Write Test Register
|
||||||
};
|
// READ_PHYID, //C019_0000_0000_0200 Read Ethernet/HomePNA PHY Address
|
||||||
|
// READ_MEDIUM_STATUS, //C01A_0000_0000_0200 Read Medium Status
|
||||||
|
// WRITE_MEDIUM_MODE, //401B_AABB_0000_0000 Write Medium Mode Register
|
||||||
|
// GET_MONITOR_MODE, //C01C_0000_0000_0100 Read Monitor Mode Status
|
||||||
|
// SET_MONITOR_MODE, //401D_AA00_0000_0000 Write Monitor Mode Register
|
||||||
|
// READ_GPIOS, //C01E_0000_0000_0100 Read GPIOs Status
|
||||||
|
// WRITE_GPIOS, //401F_AA00_0000_0000 Write GPIOs
|
||||||
|
// WRITE_SOFT_RESET, //4020_AA00_0000_0000 Write Software Reset
|
||||||
|
// READ_PHY_SEL_STATE, //C021_AA00_0000_0100 Read Software PHY Select Status
|
||||||
|
// WRITE_PHY_SEL, //4022_AA00_0000_0000 Write Software PHY Select
|
||||||
|
|
||||||
// RX Control Register bits
|
// RX Control Register bits
|
||||||
enum AX88772_RXControl {
|
// RXCTL_PROMISCUOUS, // forward all frames up to the host
|
||||||
RXCTL_PROMISCUOUS = 0x0001, //
|
// RXCTL_ALL_MULTICAT, // forward all multicast frames up to the host
|
||||||
RXCTL_ALL_MULTICAT = 0x0002, //
|
// RXCTL_SEP, // forward frames with CRC error up to the host
|
||||||
// RXCTL_SEP = 0x0004, // do not set it!
|
// RXCTL_BROADCAST, // forward broadcast frames up to the host
|
||||||
RXCTL_BROADCAST = 0x0008, //
|
// RXCTL_MULTICAST, // forward multicast frames that are
|
||||||
RXCTL_MULTICAST = 0x0010, //
|
// matching to multicast filter up to the host
|
||||||
RXCTL_AP = 0x0020, //
|
// RXCTL_AP, // forward unicast frames that are matching
|
||||||
RXCTL_START = 0x0080, //
|
// to multicast filter up to the host
|
||||||
RXCTL_USB_MFB = 0x0100 // Max Frame Burst TX on USB
|
// RXCTL_START, // ethernet MAC start operating
|
||||||
};
|
// RXCTL_USB_MFB, // Max Frame Burst TX on USB
|
||||||
|
|
||||||
|
|
||||||
// PHY IDs request answer data layout
|
// PHY IDs request answer data layout
|
||||||
struct AX88772_PhyIDs {
|
struct AX88772_PhyIDs {
|
||||||
@ -64,6 +74,7 @@ struct AX88772_PhyIDs {
|
|||||||
uint8 PriPhyID2;
|
uint8 PriPhyID2;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
// Medium state bits
|
// Medium state bits
|
||||||
enum AX88772_MediumState {
|
enum AX88772_MediumState {
|
||||||
MEDIUM_STATE_FD = 0x0002,
|
MEDIUM_STATE_FD = 0x0002,
|
||||||
@ -80,6 +91,7 @@ enum AX88772_MediumState {
|
|||||||
MEDIUM_STATE_SM_ON = 0x1000
|
MEDIUM_STATE_SM_ON = 0x1000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Monitor Mode bits
|
// Monitor Mode bits
|
||||||
enum AX88772_MonitorMode {
|
enum AX88772_MonitorMode {
|
||||||
MONITOR_MODE_MOM = 0x01,
|
MONITOR_MODE_MOM = 0x01,
|
||||||
@ -88,6 +100,7 @@ enum AX88772_MonitorMode {
|
|||||||
MONITOR_MODE_US = 0x10
|
MONITOR_MODE_US = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// General Purpose I/O Register
|
// General Purpose I/O Register
|
||||||
enum AX88772_GPIO {
|
enum AX88772_GPIO {
|
||||||
GPIO_OO_0EN = 0x01,
|
GPIO_OO_0EN = 0x01,
|
||||||
@ -99,6 +112,7 @@ enum AX88772_GPIO {
|
|||||||
GPIO_RSE = 0x80
|
GPIO_RSE = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Software Reset Register bits
|
// Software Reset Register bits
|
||||||
enum AX88772_SoftwareReset {
|
enum AX88772_SoftwareReset {
|
||||||
SW_RESET_CLR = 0x00,
|
SW_RESET_CLR = 0x00,
|
||||||
@ -111,6 +125,7 @@ enum AX88772_SoftwareReset {
|
|||||||
SW_RESET_IPPD = 0x40
|
SW_RESET_IPPD = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Software PHY Select Status
|
// Software PHY Select Status
|
||||||
enum AX88772_SoftwarePHYSelStatus {
|
enum AX88772_SoftwarePHYSelStatus {
|
||||||
SW_PHY_SEL_STATUS_EXT = 0x00,
|
SW_PHY_SEL_STATUS_EXT = 0x00,
|
||||||
@ -118,6 +133,7 @@ enum AX88772_SoftwarePHYSelStatus {
|
|||||||
SW_PHY_SEL_STATUS_ASEL = 0x02
|
SW_PHY_SEL_STATUS_ASEL = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Notification data layout
|
// Notification data layout
|
||||||
struct AX88772_Notify {
|
struct AX88772_Notify {
|
||||||
uint8 btA1;
|
uint8 btA1;
|
||||||
@ -128,6 +144,7 @@ struct AX88772_Notify {
|
|||||||
uint16 regEEFF;
|
uint16 regEEFF;
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
|
||||||
// Link-State bits
|
// Link-State bits
|
||||||
enum AX88772_BBState {
|
enum AX88772_BBState {
|
||||||
LINK_STATE_PPLS = 0x01,
|
LINK_STATE_PPLS = 0x01,
|
||||||
@ -136,10 +153,13 @@ enum AX88772_BBState {
|
|||||||
LINK_STATE_MDINT = 0x08
|
LINK_STATE_MDINT = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const uint16 maxFrameSize = 1536;
|
const uint16 maxFrameSize = 1536;
|
||||||
|
|
||||||
AX88772Device::AX88772Device(usb_device device, const char *description)
|
|
||||||
: ASIXDevice(device, description)
|
AX88772Device::AX88772Device(usb_device device, DeviceInfo& deviceInfo)
|
||||||
|
:
|
||||||
|
ASIXDevice(device, deviceInfo)
|
||||||
{
|
{
|
||||||
fStatus = InitDevice();
|
fStatus = InitDevice();
|
||||||
}
|
}
|
||||||
@ -152,10 +172,6 @@ AX88772Device::InitDevice()
|
|||||||
fUseTRXHeader = true;
|
fUseTRXHeader = true;
|
||||||
|
|
||||||
fReadNodeIDRequest = READ_NODEID;
|
fReadNodeIDRequest = READ_NODEID;
|
||||||
fReadRXControlRequest = READ_RX_CONTROL;
|
|
||||||
fWriteRXControlRequest = WRITE_RX_CONTROL;
|
|
||||||
|
|
||||||
fPromiscuousBits = RXCTL_PROMISCUOUS;
|
|
||||||
|
|
||||||
fNotifyBufferLength = sizeof(AX88772_Notify);
|
fNotifyBufferLength = sizeof(AX88772_Notify);
|
||||||
fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength);
|
fNotifyBuffer = (uint8 *)malloc(fNotifyBufferLength);
|
||||||
@ -176,9 +192,7 @@ AX88772Device::SetupDevice(bool deviceReplugged)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = fMII.Init(fDevice,
|
result = fMII.Init(fDevice);
|
||||||
SW_MII_OP, READ_MII, WRITE_MII,
|
|
||||||
READ_MII_OP_MODE, HW_MII_OP, READ_PHYID);
|
|
||||||
|
|
||||||
size_t actualLength = 0;
|
size_t actualLength = 0;
|
||||||
// enable GPIO2 - magic from FreeBSD's if_axe
|
// enable GPIO2 - magic from FreeBSD's if_axe
|
||||||
@ -294,10 +308,11 @@ AX88772Device::StartDevice()
|
|||||||
"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
|
"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 rxcontrol = RXCTL_START | RXCTL_MULTICAST | RXCTL_BROADCAST;
|
uint16 rxcontrol = RXCTL_START | RXCTL_BROADCAST;
|
||||||
result = WriteRXControlRegister(rxcontrol);
|
result = WriteRXControlRegister(rxcontrol);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
|
TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
|
||||||
|
rxcontrol, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE_RET(result);
|
TRACE_RET(result);
|
||||||
@ -382,11 +397,12 @@ AX88772Device::GetLinkState(ether_link_state *linkState)
|
|||||||
linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ?
|
linkState->media |= (mediumStatus & MEDIUM_STATE_FD) ?
|
||||||
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
IFM_FULL_DUPLEX : IFM_HALF_DUPLEX;
|
||||||
|
|
||||||
linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100) ? 100000000 : 10000000;
|
linkState->speed = (mediumStatus & MEDIUM_STATE_PS_100)
|
||||||
|
? 100000000 : 10000000;
|
||||||
|
|
||||||
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,
|
linkState->speed / 1000000,
|
||||||
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
(linkState->media & IFM_FULL_DUPLEX) ? "full" : "half");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,15 +9,16 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_AX88772_DEVICE_H_
|
#ifndef _USB_AX88772_DEVICE_H_
|
||||||
#define _USB_AX88772_DEVICE_H_
|
#define _USB_AX88772_DEVICE_H_
|
||||||
|
|
||||||
|
|
||||||
#include "ASIXDevice.h"
|
#include "ASIXDevice.h"
|
||||||
|
|
||||||
|
|
||||||
class AX88772Device : public ASIXDevice {
|
class AX88772Device : public ASIXDevice {
|
||||||
public:
|
public:
|
||||||
AX88772Device(usb_device device, const char *description);
|
AX88772Device(usb_device device, DeviceInfo& info);
|
||||||
protected:
|
protected:
|
||||||
status_t InitDevice();
|
status_t InitDevice();
|
||||||
virtual status_t SetupDevice(bool deviceReplugged);
|
virtual status_t SetupDevice(bool deviceReplugged);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,71 +10,62 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
|
||||||
#include <lock.h> // for mutex
|
|
||||||
#else
|
|
||||||
#include "BeOSCompatibility.h" // for pseudo mutex
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "Settings.h"
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <lock.h> // for mutex
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
#include "AX88172Device.h"
|
#include "AX88172Device.h"
|
||||||
#include "AX88772Device.h"
|
|
||||||
#include "AX88178Device.h"
|
#include "AX88178Device.h"
|
||||||
|
#include "AX88772Device.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
|
||||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||||
static const char *sDeviceBaseName = "net/usb_asix/";
|
static const char *sDeviceBaseName = "net/usb_asix/";
|
||||||
ASIXDevice *gASIXDevices[MAX_DEVICES];
|
ASIXDevice *gASIXDevices[MAX_DEVICES];
|
||||||
char *gDeviceNames[MAX_DEVICES + 1];
|
char *gDeviceNames[MAX_DEVICES + 1];
|
||||||
usb_module_info *gUSBModule = NULL;
|
usb_module_info *gUSBModule = NULL;
|
||||||
|
|
||||||
mutex gDriverLock;
|
mutex gDriverLock;
|
||||||
// auto-release helper class
|
|
||||||
class DriverSmartLock {
|
|
||||||
public:
|
|
||||||
DriverSmartLock() { mutex_lock(&gDriverLock); }
|
|
||||||
~DriverSmartLock() { mutex_unlock(&gDriverLock); }
|
|
||||||
};
|
|
||||||
|
|
||||||
usb_support_descriptor gSupportedDevices[] = {
|
|
||||||
// AX88172
|
// IMPORTANT: keep entries sorted by ids to let the
|
||||||
{ 0, 0, 0, 0x0b95, 0x1720}, // "ASIX 88172 10/100"
|
// binary search lookup procedure work correctly !!!
|
||||||
{ 0, 0, 0, 0x07b8, 0x420a}, // "ABOCOM UF200"
|
DeviceInfo gSupportedDevices[] = {
|
||||||
{ 0, 0, 0, 0x1189, 0x0893}, // "Acer C&M EP-1427X-2"
|
{ { { 0x0411, 0x003d } }, DeviceInfo::AX88172, "Melco LUA-U2-KTX" },
|
||||||
{ 0, 0, 0, 0x0557, 0x2009}, // "ATEN UC-210T"
|
{ { { 0x04bb, 0x0930 } }, DeviceInfo::AX88178, "I/O Data ETG-US2" },
|
||||||
{ 0, 0, 0, 0x08dd, 0x90ff}, // "Billionton USB2AR"
|
{ { { 0x04f1, 0x3008 } }, DeviceInfo::AX88172, "JVC MP-PRX1" },
|
||||||
{ 0, 0, 0, 0x07aa, 0x0017}, // "Corega USB2TX"
|
{ { { 0x050d, 0x5055 } }, DeviceInfo::AX88178, "Belkin F5D5055" },
|
||||||
{ 0, 0, 0, 0x2001, 0x1A00}, // "D-Link DUB-E100"
|
{ { { 0x0557, 0x2009 } }, DeviceInfo::AX88172, "ATEN UC-210T" },
|
||||||
{ 0, 0, 0, 0x1631, 0x6200}, // "GoodWay USB2Ethernet"
|
{ { { 0x05ac, 0x1402 } }, DeviceInfo::AX88772, "Apple A1277" },
|
||||||
{ 0, 0, 0, 0x04f1, 0x3008}, // "JVC MP-PRX1"
|
{ { { 0x077b, 0x2226 } }, DeviceInfo::AX88172, "LinkSys USB 2.0" },
|
||||||
{ 0, 0, 0, 0x077b, 0x2226}, // "LinkSys USB 2.0"
|
{ { { 0x07aa, 0x0017 } }, DeviceInfo::AX88172, "Corega USB2TX" },
|
||||||
{ 0, 0, 0, 0x0411, 0x003d}, // "Melco LUA-U2-KTX"
|
{ { { 0x07b8, 0x420a } }, DeviceInfo::AX88172, "ABOCOM UF200" },
|
||||||
{ 0, 0, 0, 0x0846, 0x1040}, // "NetGear USB 2.0 Ethernet"
|
{ { { 0x07d1, 0x3c05 } }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" },
|
||||||
{ 0, 0, 0, 0x086e, 0x1920}, // "System TALKS SGC-X2UL"
|
{ { { 0x0846, 0x1040 } }, DeviceInfo::AX88172, "NetGear USB 2.0 Ethernet" },
|
||||||
{ 0, 0, 0, 0x6189, 0x182d}, // "Sitecom LN-029"
|
{ { { 0x086e, 0x1920 } }, DeviceInfo::AX88172, "System TALKS SGC-X2UL" },
|
||||||
// AX88772
|
{ { { 0x08dd, 0x90ff } }, DeviceInfo::AX88172, "Billionton USB2AR" },
|
||||||
{ 0, 0, 0, 0x0b95, 0x7720}, // "ASIX 88772 10/100"
|
{ { { 0x0b95, 0x1720 } }, DeviceInfo::AX88172, "ASIX 88172 10/100" },
|
||||||
{ 0, 0, 0, 0x13b1, 0x0018}, // "Linksys USB200M rev.2"
|
{ { { 0x0b95, 0x1780 } }, DeviceInfo::AX88178, "ASIX 88178 10/100/1000" },
|
||||||
{ 0, 0, 0, 0x07d1, 0x3c05}, // alternate D-Link DUB-E100 rev. B1
|
{ { { 0x0b95, 0x7720 } }, DeviceInfo::AX88772, "ASIX 88772 10/100" },
|
||||||
{ 0, 0, 0, 0x2001, 0x3c05}, // "D-Link DUB-E100 rev.B1"
|
{ { { 0x0df6, 0x061c } }, DeviceInfo::AX88178, "Sitecom LN-028" },
|
||||||
{ 0, 0, 0, 0x1557, 0x7720}, // "OQO 01+ Ethernet"
|
{ { { 0x1189, 0x0893 } }, DeviceInfo::AX88172, "Acer C&M EP-1427X-2" },
|
||||||
{ 0, 0, 0, 0x05ac, 0x1402}, // "Apple A1277"
|
{ { { 0x13b1, 0x0018 } }, DeviceInfo::AX88772, "Linksys USB200M rev.2" },
|
||||||
// AX88178
|
{ { { 0x14ea, 0xab11 } }, DeviceInfo::AX88178, "Planex GU-1000T" },
|
||||||
{ 0, 0, 0, 0x0b95, 0x1780}, // "ASIX 88178 10/100/1000"
|
{ { { 0x1557, 0x7720 } }, DeviceInfo::AX88772, "OQO 01+ Ethernet" },
|
||||||
{ 0, 0, 0, 0x050d, 0x5055}, // "Belkin F5D5055"
|
{ { { 0x1631, 0x6200 } }, DeviceInfo::AX88172, "GoodWay USB2Ethernet" },
|
||||||
{ 0, 0, 0, 0x04bb, 0x0930}, // "I/O Data ETG-US2"
|
{ { { 0x1737, 0x0039 } }, DeviceInfo::AX88178, "LinkSys 1000" },
|
||||||
{ 0, 0, 0, 0x1737, 0x0039}, // "LinkSys 1000"
|
{ { { 0x2001, 0x1A00 } }, DeviceInfo::AX88172, "D-Link DUB-E100" },
|
||||||
{ 0, 0, 0, 0x14ea, 0xab11}, // "Planex GU-1000T"
|
{ { { 0x2001, 0x3c05 } }, DeviceInfo::AX88772, "D-Link DUB-E100 rev.B1" },
|
||||||
{ 0, 0, 0, 0x0df6, 0x061c} // "Sitecom LN-028"
|
{ { { 0x6189, 0x182d } }, DeviceInfo::AX88172, "Sitecom LN-029" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ASIXDevice *
|
ASIXDevice *
|
||||||
create_asix_device(usb_device device)
|
lookup_and_create_device(usb_device device)
|
||||||
{
|
{
|
||||||
const usb_device_descriptor *deviceDescriptor
|
const usb_device_descriptor *deviceDescriptor
|
||||||
= gUSBModule->get_device_descriptor(device);
|
= gUSBModule->get_device_descriptor(device);
|
||||||
@ -84,39 +75,34 @@ create_asix_device(usb_device device)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IDS(__vendor, __product) (((__vendor) << 16) | (__product))
|
TRACE("trying %#06x:%#06x.\n",
|
||||||
|
deviceDescriptor->vendor_id, deviceDescriptor->product_id);
|
||||||
|
|
||||||
switch(IDS(deviceDescriptor->vendor_id, deviceDescriptor->product_id)) {
|
// use binary search to lookup device in table
|
||||||
// AX88172
|
DeviceInfo::Id id = { { deviceDescriptor->vendor_id,
|
||||||
case IDS(0x0b95, 0x1720): return new AX88172Device(device, "ASIX 88172 10/100");
|
deviceDescriptor->product_id } };
|
||||||
case IDS(0x07b8, 0x420a): return new AX88172Device(device, "ABOCOM UF200");
|
int left = -1;
|
||||||
case IDS(0x1189, 0x0893): return new AX88172Device(device, "Acer C&M EP-1427X-2");
|
int right = _countof(gSupportedDevices);
|
||||||
case IDS(0x0557, 0x2009): return new AX88172Device(device, "ATEN UC-210T");
|
while ((right - left) > 1) {
|
||||||
case IDS(0x08dd, 0x90ff): return new AX88172Device(device, "Billionton USB2AR");
|
int i = (left + right) / 2;
|
||||||
case IDS(0x07aa, 0x0017): return new AX88172Device(device, "Corega USB2TX");
|
((gSupportedDevices[i].Key() < id.fKey) ? left : right) = i;
|
||||||
case IDS(0x2001, 0x1A00): return new AX88172Device(device, "D-Link DUB-E100");
|
|
||||||
case IDS(0x1631, 0x6200): return new AX88172Device(device, "GoodWay USB2Ethernet");
|
|
||||||
case IDS(0x04f1, 0x3008): return new AX88172Device(device, "JVC MP-PRX1");
|
|
||||||
case IDS(0x077b, 0x2226): return new AX88172Device(device, "LinkSys USB 2.0");
|
|
||||||
case IDS(0x0411, 0x003d): return new AX88172Device(device, "Melco LUA-U2-KTX");
|
|
||||||
case IDS(0x0846, 0x1040): return new AX88172Device(device, "NetGear USB 2.0 Ethernet");
|
|
||||||
case IDS(0x086e, 0x1920): return new AX88172Device(device, "System TALKS SGC-X2UL");
|
|
||||||
case IDS(0x6189, 0x182d): return new AX88172Device(device, "Sitecom LN-029");
|
|
||||||
// AX88772
|
|
||||||
case IDS(0x0b95, 0x7720): return new AX88772Device(device, "ASIX 88772 10/100");
|
|
||||||
case IDS(0x13b1, 0x0018): return new AX88772Device(device, "Linksys USB200M rev.2");
|
|
||||||
case IDS(0x07d1, 0x3c05): // alternate D-Link DUB-E100 rev. B1
|
|
||||||
case IDS(0x2001, 0x3c05): return new AX88772Device(device, "D-Link DUB-E100 rev.B1");
|
|
||||||
case IDS(0x1557, 0x7720): return new AX88772Device(device, "OQO 01+ Ethernet");
|
|
||||||
case IDS(0x05ac, 0x1402): return new AX88772Device(device, "Apple A1277");
|
|
||||||
// AX88178
|
|
||||||
case IDS(0x0b95, 0x1780): return new AX88178Device(device, "ASIX 88178 10/100/1000");
|
|
||||||
case IDS(0x050d, 0x5055): return new AX88178Device(device, "Belkin F5D5055");
|
|
||||||
case IDS(0x04bb, 0x0930): return new AX88178Device(device, "I/O Data ETG-US2");
|
|
||||||
case IDS(0x1737, 0x0039): return new AX88178Device(device, "LinkSys 1000");
|
|
||||||
case IDS(0x14ea, 0xab11): return new AX88178Device(device, "Planex GU-1000T");
|
|
||||||
case IDS(0x0df6, 0x061c): return new AX88178Device(device, "Sitecom LN-028");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gSupportedDevices[right].Key() == id.fKey) {
|
||||||
|
switch (gSupportedDevices[right].fType) {
|
||||||
|
case DeviceInfo::AX88172:
|
||||||
|
return new AX88172Device(device, gSupportedDevices[right]);
|
||||||
|
case DeviceInfo::AX88772:
|
||||||
|
return new AX88772Device(device, gSupportedDevices[right]);
|
||||||
|
case DeviceInfo::AX88178:
|
||||||
|
return new AX88178Device(device, gSupportedDevices[right]);
|
||||||
|
default:
|
||||||
|
TRACE_ALWAYS("Unknown device type:%#x ignored.\n",
|
||||||
|
static_cast<int>(gSupportedDevices[right].fType));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +112,7 @@ usb_asix_device_added(usb_device device, void **cookie)
|
|||||||
{
|
{
|
||||||
*cookie = NULL;
|
*cookie = NULL;
|
||||||
|
|
||||||
DriverSmartLock driverLock; // released on exit
|
MutexLocker lock(gDriverLock); // released on exit
|
||||||
|
|
||||||
// check if this is a replug of an existing device first
|
// check if this is a replug of an existing device first
|
||||||
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
||||||
@ -142,7 +128,7 @@ usb_asix_device_added(usb_device device, void **cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no such device yet, create a new one
|
// no such device yet, create a new one
|
||||||
ASIXDevice *asixDevice = create_asix_device(device);
|
ASIXDevice *asixDevice = lookup_and_create_device(device);
|
||||||
if (asixDevice == 0) {
|
if (asixDevice == 0) {
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
@ -181,7 +167,7 @@ usb_asix_device_added(usb_device device, void **cookie)
|
|||||||
status_t
|
status_t
|
||||||
usb_asix_device_removed(void *cookie)
|
usb_asix_device_removed(void *cookie)
|
||||||
{
|
{
|
||||||
DriverSmartLock driverLock; // released on exit
|
MutexLocker lock(gDriverLock); // released on exit
|
||||||
|
|
||||||
ASIXDevice *device = (ASIXDevice *)cookie;
|
ASIXDevice *device = (ASIXDevice *)cookie;
|
||||||
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
||||||
@ -235,9 +221,17 @@ init_driver()
|
|||||||
&usb_asix_device_removed
|
&usb_asix_device_removed
|
||||||
};
|
};
|
||||||
|
|
||||||
gUSBModule->register_driver(DRIVER_NAME, gSupportedDevices,
|
const size_t count = _countof(gSupportedDevices);
|
||||||
sizeof(gSupportedDevices) / sizeof(usb_support_descriptor), NULL);
|
static usb_support_descriptor sDescriptors[count] = {{ 0 }};
|
||||||
|
|
||||||
|
for(size_t i = 0; i < count; i++) {
|
||||||
|
sDescriptors[i].vendor = gSupportedDevices[i].VendorId();
|
||||||
|
sDescriptors[i].product = gSupportedDevices[i].ProductId();
|
||||||
|
}
|
||||||
|
|
||||||
|
gUSBModule->register_driver(DRIVER_NAME, sDescriptors, count, NULL);
|
||||||
gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks);
|
gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +264,7 @@ uninit_driver()
|
|||||||
static status_t
|
static status_t
|
||||||
usb_asix_open(const char *name, uint32 flags, void **cookie)
|
usb_asix_open(const char *name, uint32 flags, void **cookie)
|
||||||
{
|
{
|
||||||
DriverSmartLock driverLock; // released on exit
|
MutexLocker lock(gDriverLock); // released on exit
|
||||||
|
|
||||||
*cookie = NULL;
|
*cookie = NULL;
|
||||||
status_t status = ENODEV;
|
status_t status = ENODEV;
|
||||||
@ -322,7 +316,7 @@ usb_asix_free(void *cookie)
|
|||||||
{
|
{
|
||||||
ASIXDevice *device = (ASIXDevice *)cookie;
|
ASIXDevice *device = (ASIXDevice *)cookie;
|
||||||
|
|
||||||
DriverSmartLock driverLock; // released on exit
|
MutexLocker lock(gDriverLock); // released on exit
|
||||||
|
|
||||||
status_t status = device->Free();
|
status_t status = device->Free();
|
||||||
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
||||||
@ -348,7 +342,7 @@ publish_devices()
|
|||||||
gDeviceNames[i] = NULL;
|
gDeviceNames[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DriverSmartLock driverLock; // released on exit
|
MutexLocker lock(gDriverLock); // released on exit
|
||||||
|
|
||||||
int32 deviceCount = 0;
|
int32 deviceCount = 0;
|
||||||
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
for (int32 i = 0; i < MAX_DEVICES; i++) {
|
||||||
@ -361,7 +355,7 @@ publish_devices()
|
|||||||
TRACE("publishing %s\n", gDeviceNames[deviceCount]);
|
TRACE("publishing %s\n", gDeviceNames[deviceCount]);
|
||||||
deviceCount++;
|
deviceCount++;
|
||||||
} else
|
} else
|
||||||
TRACE_ALWAYS("Error: out of memory during allocating device name.\n");
|
TRACE_ALWAYS("Error: out of memory during allocating dev.name.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
gDeviceNames[deviceCount] = NULL;
|
gDeviceNames[deviceCount] = NULL;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,31 +9,23 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_ASIX_DRIVER_H_
|
#ifndef _USB_ASIX_DRIVER_H_
|
||||||
#define _USB_ASIX_DRIVER_H_
|
#define _USB_ASIX_DRIVER_H_
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
#include <KernelExport.h>
|
|
||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
#include <USB3.h>
|
#include <USB3.h>
|
||||||
#include <ether_driver.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <util/kernel_cpp.h>
|
|
||||||
|
|
||||||
#define DRIVER_NAME "usb_asix"
|
#define DRIVER_NAME "usb_asix"
|
||||||
#define MAX_DEVICES 8
|
#define MAX_DEVICES 8
|
||||||
|
|
||||||
|
|
||||||
const uint8 kInvalidRequest = 0xff;
|
const uint8 kInvalidRequest = 0xff;
|
||||||
|
const char* const kVersion = "ver.0.9.1";
|
||||||
const char* const kVersion = "ver.0.8.3";
|
|
||||||
|
|
||||||
extern usb_module_info *gUSBModule;
|
extern usb_module_info *gUSBModule;
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
status_t usb_asix_device_added(usb_device device, void **cookie);
|
status_t usb_asix_device_added(usb_device device, void **cookie);
|
||||||
status_t usb_asix_device_removed(void *cookie);
|
status_t usb_asix_device_removed(void *cookie);
|
||||||
|
@ -3,6 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers network usb_asix ;
|
|||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
UsePrivateHeaders kernel net ;
|
UsePrivateHeaders kernel net ;
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
|
||||||
KernelAddon usb_asix :
|
KernelAddon usb_asix :
|
||||||
Driver.cpp
|
Driver.cpp
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,22 +10,24 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "MIIBus.h"
|
||||||
|
|
||||||
|
#include "ASIXVendorRequests.h"
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "MIIBus.h"
|
|
||||||
|
|
||||||
#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10))
|
#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10))
|
||||||
#define MII_MODEL(id2) (((id2) & 0x03f0) >> 4)
|
#define MII_MODEL(id2) (((id2) & 0x03f0) >> 4)
|
||||||
#define MII_REV(id2) ((id2) & 0x000f)
|
#define MII_REV(id2) ((id2) & 0x000f)
|
||||||
|
|
||||||
MIIBus::MIIBus() : fDevice(0),
|
|
||||||
fSelectedPHY(CurrentPHY),
|
MIIBus::MIIBus()
|
||||||
fSWOperationRequest(kInvalidRequest),
|
:
|
||||||
fReadValueRequest(kInvalidRequest),
|
fStatus(B_NO_INIT),
|
||||||
fWriteValueRequest(kInvalidRequest),
|
fDevice(0),
|
||||||
fReadStatusRequest(kInvalidRequest),
|
fSelectedPHY(CurrentPHY)
|
||||||
fHWOperationRequest(kInvalidRequest),
|
|
||||||
fReadPHYIDsRequest(kInvalidRequest)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < PHYsCount; i++) {
|
for (size_t i = 0; i < PHYsCount; i++) {
|
||||||
fPHYs[i] = PHYNotInstalled;
|
fPHYs[i] = PHYNotInstalled;
|
||||||
@ -34,21 +36,8 @@ MIIBus::MIIBus() : fDevice(0),
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MIIBus::Init(usb_device device,
|
MIIBus::Init(usb_device device)
|
||||||
uint8 SWOperationRequest,
|
|
||||||
uint8 ReadValueRequest,
|
|
||||||
uint8 WriteValueRequest,
|
|
||||||
uint8 ReadStatusRequest,
|
|
||||||
uint8 HWOperationRequest,
|
|
||||||
uint8 ReadPHYIDsRequest)
|
|
||||||
{
|
{
|
||||||
fSWOperationRequest = SWOperationRequest;
|
|
||||||
fReadValueRequest = ReadValueRequest;
|
|
||||||
fWriteValueRequest = WriteValueRequest;
|
|
||||||
fReadStatusRequest = ReadStatusRequest;
|
|
||||||
fHWOperationRequest = HWOperationRequest;
|
|
||||||
fReadPHYIDsRequest = ReadPHYIDsRequest;
|
|
||||||
|
|
||||||
// reset to default state
|
// reset to default state
|
||||||
fDevice = 0;
|
fDevice = 0;
|
||||||
fSelectedPHY = CurrentPHY;
|
fSelectedPHY = CurrentPHY;
|
||||||
@ -59,7 +48,7 @@ MIIBus::Init(usb_device device,
|
|||||||
size_t actual_length = 0;
|
size_t actual_length = 0;
|
||||||
status_t result = gUSBModule->send_request(device,
|
status_t result = gUSBModule->send_request(device,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||||
fReadPHYIDsRequest, 0, 0, sizeof(fPHYs), fPHYs, &actual_length);
|
READ_PHYID, 0, 0, sizeof(fPHYs), fPHYs, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Request of the PHYIDs failed:%#010x\n", result);
|
TRACE_ALWAYS("Request of the PHYIDs failed:%#010x\n", result);
|
||||||
@ -81,7 +70,7 @@ MIIBus::Init(usb_device device,
|
|||||||
fSelectedPHY = SecondaryPHY;
|
fSelectedPHY = SecondaryPHY;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("PHYs are configured: Selected:%#02x; Primary:%#02x; Secondary:%#02x\n",
|
TRACE("PHYs are configured: Selected:%#02x; Primary:%#02x; 2ndary:%#02x\n",
|
||||||
PHYID(CurrentPHY), PHYID(PrimaryPHY), PHYID(SecondaryPHY));
|
PHYID(CurrentPHY), PHYID(PrimaryPHY), PHYID(SecondaryPHY));
|
||||||
if (fSelectedPHY == CurrentPHY) {
|
if (fSelectedPHY == CurrentPHY) {
|
||||||
TRACE_ALWAYS("No PHYs found!\n");
|
TRACE_ALWAYS("No PHYs found!\n");
|
||||||
@ -89,8 +78,9 @@ MIIBus::Init(usb_device device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fDevice = device;
|
fDevice = device;
|
||||||
|
fStatus = result;
|
||||||
|
|
||||||
return result;
|
return fStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +99,8 @@ MIIBus::SetupPHY()
|
|||||||
control &= ~BMCR_Isolate;
|
control &= ~BMCR_Isolate;
|
||||||
result = Write(MII_BMCR, control);
|
result = Write(MII_BMCR, control);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of writing control word %#04x:%#010x.\n", control, result);
|
TRACE_ALWAYS("Error of writing control word %#04x:%#010x.\n",
|
||||||
|
control, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Write(MII_BMCR, BMCR_Reset);
|
result = Write(MII_BMCR, BMCR_Reset);
|
||||||
@ -144,16 +135,7 @@ MIIBus::InitCheck()
|
|||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fSWOperationRequest == kInvalidRequest ||
|
return fStatus;
|
||||||
fReadValueRequest == kInvalidRequest ||
|
|
||||||
fWriteValueRequest == kInvalidRequest ||
|
|
||||||
fReadStatusRequest == kInvalidRequest ||
|
|
||||||
fHWOperationRequest == kInvalidRequest ||
|
|
||||||
fReadPHYIDsRequest == kInvalidRequest) {
|
|
||||||
return B_NO_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -161,8 +143,8 @@ uint8
|
|||||||
MIIBus::PHYID(PHYIndex phyIndex /*= CurrentPHY*/)
|
MIIBus::PHYID(PHYIndex phyIndex /*= CurrentPHY*/)
|
||||||
{
|
{
|
||||||
if (phyIndex == CurrentPHY) {
|
if (phyIndex == CurrentPHY) {
|
||||||
return (fSelectedPHY == CurrentPHY ?
|
return (fSelectedPHY == CurrentPHY
|
||||||
0 : fPHYs[fSelectedPHY]) & PHYIDMask;
|
? 0 : fPHYs[fSelectedPHY]) & PHYIDMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fPHYs[phyIndex] & PHYIDMask;
|
return fPHYs[phyIndex] & PHYIDMask;
|
||||||
@ -173,15 +155,16 @@ uint8
|
|||||||
MIIBus::PHYType(PHYIndex phyIndex /*= CurrentPHY*/)
|
MIIBus::PHYType(PHYIndex phyIndex /*= CurrentPHY*/)
|
||||||
{
|
{
|
||||||
if (phyIndex == CurrentPHY) {
|
if (phyIndex == CurrentPHY) {
|
||||||
return (fSelectedPHY == CurrentPHY ?
|
return (fSelectedPHY == CurrentPHY
|
||||||
PHYNotInstalled : fPHYs[fSelectedPHY]) & PHYTypeMask;
|
? PHYNotInstalled : fPHYs[fSelectedPHY]) & PHYTypeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fPHYs[phyIndex] & PHYTypeMask;
|
return fPHYs[phyIndex] & PHYTypeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MIIBus::Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex /*= CurrentPHY*/)
|
MIIBus::Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex /*= CurrPHY*/)
|
||||||
{
|
{
|
||||||
status_t result = InitCheck();
|
status_t result = InitCheck();
|
||||||
if (B_OK != result) {
|
if (B_OK != result) {
|
||||||
@ -200,7 +183,7 @@ MIIBus::Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
// switch to SW operation mode
|
// switch to SW operation mode
|
||||||
result = gUSBModule->send_request(fDevice,
|
result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fSWOperationRequest, 0, 0, 0, 0, &actual_length);
|
SW_MII_OP, 0, 0, 0, 0, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of switching MII to SW op.mode: %#010x\n", result);
|
TRACE_ALWAYS("Error of switching MII to SW op.mode: %#010x\n", result);
|
||||||
@ -210,7 +193,7 @@ MIIBus::Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
// read register value
|
// read register value
|
||||||
status_t op_result = gUSBModule->send_request(fDevice,
|
status_t op_result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||||
fReadValueRequest, phyId, miiRegister,
|
READ_MII, phyId, miiRegister,
|
||||||
sizeof(*value), value, &actual_length);
|
sizeof(*value), value, &actual_length);
|
||||||
|
|
||||||
if (op_result != B_OK) {
|
if (op_result != B_OK) {
|
||||||
@ -227,7 +210,7 @@ MIIBus::Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
// switch to HW operation mode
|
// switch to HW operation mode
|
||||||
result = gUSBModule->send_request(fDevice,
|
result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fHWOperationRequest, 0, 0, 0, 0, &actual_length);
|
HW_MII_OP, 0, 0, 0, 0, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of switching MII to HW op.mode: %#010x\n", result);
|
TRACE_ALWAYS("Error of switching MII to HW op.mode: %#010x\n", result);
|
||||||
@ -238,7 +221,7 @@ MIIBus::Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MIIBus::Write(uint16 miiRegister, uint16 value, PHYIndex phyIndex /*= CurrentPHY*/)
|
MIIBus::Write(uint16 miiRegister, uint16 value, PHYIndex phyIndex /*= CurrPHY*/)
|
||||||
{
|
{
|
||||||
size_t actual_length = 0;
|
size_t actual_length = 0;
|
||||||
|
|
||||||
@ -258,7 +241,7 @@ MIIBus::Write(uint16 miiRegister, uint16 value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
// switch to SW operation mode
|
// switch to SW operation mode
|
||||||
result = gUSBModule->send_request(fDevice,
|
result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fSWOperationRequest, 0, 0, 0, 0, &actual_length);
|
SW_MII_OP, 0, 0, 0, 0, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of switching MII to SW op.mode: %#010x\n", result);
|
TRACE_ALWAYS("Error of switching MII to SW op.mode: %#010x\n", result);
|
||||||
@ -268,7 +251,7 @@ MIIBus::Write(uint16 miiRegister, uint16 value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
// write register value
|
// write register value
|
||||||
status_t op_result = gUSBModule->send_request(fDevice,
|
status_t op_result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fWriteValueRequest, phyId, miiRegister,
|
WRITE_MII, phyId, miiRegister,
|
||||||
sizeof(value), &value, &actual_length);
|
sizeof(value), &value, &actual_length);
|
||||||
|
|
||||||
if (op_result != B_OK) {
|
if (op_result != B_OK) {
|
||||||
@ -285,7 +268,7 @@ MIIBus::Write(uint16 miiRegister, uint16 value, PHYIndex phyIndex /*= CurrentPHY
|
|||||||
// switch to HW operation mode
|
// switch to HW operation mode
|
||||||
result = gUSBModule->send_request(fDevice,
|
result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fHWOperationRequest, 0, 0, 0, 0, &actual_length);
|
HW_MII_OP, 0, 0, 0, 0, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of switching MII to HW op.mode: %#010x\n", result);
|
TRACE_ALWAYS("Error of switching MII to HW op.mode: %#010x\n", result);
|
||||||
@ -301,6 +284,7 @@ MIIBus::Status(uint16 *status, PHYIndex phyIndex /*= CurrentPHY*/)
|
|||||||
return Read(MII_BMSR, status, phyIndex);
|
return Read(MII_BMSR, status, phyIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
MIIBus::Dump()
|
MIIBus::Dump()
|
||||||
{
|
{
|
||||||
@ -321,7 +305,7 @@ MIIBus::Dump()
|
|||||||
// switch to SW operation mode
|
// switch to SW operation mode
|
||||||
result = gUSBModule->send_request(fDevice,
|
result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fSWOperationRequest, 0, 0, 0, 0, &actual_length);
|
SW_MII_OP, 0, 0, 0, 0, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of switching MII to SW op.mode: %#010x\n", result);
|
TRACE_ALWAYS("Error of switching MII to SW op.mode: %#010x\n", result);
|
||||||
@ -337,7 +321,7 @@ MIIBus::Dump()
|
|||||||
// read register value
|
// read register value
|
||||||
status_t op_result = gUSBModule->send_request(fDevice,
|
status_t op_result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_IN,
|
||||||
fReadValueRequest, phyId, regs[i],
|
READ_MII, phyId, regs[i],
|
||||||
sizeof(value), &value, &actual_length);
|
sizeof(value), &value, &actual_length);
|
||||||
|
|
||||||
if (op_result != B_OK) {
|
if (op_result != B_OK) {
|
||||||
@ -357,7 +341,7 @@ MIIBus::Dump()
|
|||||||
// switch to HW operation mode
|
// switch to HW operation mode
|
||||||
result = gUSBModule->send_request(fDevice,
|
result = gUSBModule->send_request(fDevice,
|
||||||
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
fHWOperationRequest, 0, 0, 0, 0, &actual_length);
|
HW_MII_OP, 0, 0, 0, 0, &actual_length);
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
TRACE_ALWAYS("Error of switching MII to HW op.mode: %#010x\n", result);
|
TRACE_ALWAYS("Error of switching MII to HW op.mode: %#010x\n", result);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,12 +9,13 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_MII_BUS_H_
|
#ifndef _USB_MII_BUS_H_
|
||||||
#define _USB_MII_BUS_H_
|
#define _USB_MII_BUS_H_
|
||||||
|
|
||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
|
|
||||||
|
|
||||||
enum MII_Register {
|
enum MII_Register {
|
||||||
MII_BMCR = 0x00,
|
MII_BMCR = 0x00,
|
||||||
MII_BMSR = 0x01,
|
MII_BMSR = 0x01,
|
||||||
@ -25,6 +26,7 @@ enum MII_Register {
|
|||||||
MII_ANER = 0x06
|
MII_ANER = 0x06
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum MII_BMCR {
|
enum MII_BMCR {
|
||||||
BMCR_Reset = 0x8000,
|
BMCR_Reset = 0x8000,
|
||||||
BMCR_Loopback = 0x4000,
|
BMCR_Loopback = 0x4000,
|
||||||
@ -37,24 +39,26 @@ enum MII_BMCR {
|
|||||||
BMCR_CollTest = 0x0080
|
BMCR_CollTest = 0x0080
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum MII_BMSR {
|
enum MII_BMSR {
|
||||||
BMSR_CAP_100BASE_T4 = 0x8000, // PHY is able to perform 100base-T4
|
BMSR_CAP_100BASE_T4 = 0x8000, // PHY is able to perform 100base-T4
|
||||||
BMSR_CAP_100BASE_TXFD = 0x4000, // PHY is able to perform 100base-TX full duplex
|
BMSR_CAP_100BASE_TXFD = 0x4000, // PHY is able to perform 100base-TX FD
|
||||||
BMSR_CAP_100BASE_TXHD = 0x2000, // PHY is able to perform 100base-TX half duplex
|
BMSR_CAP_100BASE_TXHD = 0x2000, // PHY is able to perform 100base-TX HD
|
||||||
BMSR_CAP_10BASE_TXFD = 0x1000, // PHY is able to perform 10base-TX full duplex
|
BMSR_CAP_10BASE_TXFD = 0x1000, // PHY is able to perform 10base-TX FD
|
||||||
BMSR_CAP_10BASE_TXHD = 0x0800, // PHY is able to perform 10base-TX half duplex
|
BMSR_CAP_10BASE_TXHD = 0x0800, // PHY is able to perform 10base-TX HD
|
||||||
BMSR_MFPS = 0x0040, // Management frame preamble supression
|
BMSR_MFPS = 0x0040, // Management frame preamble supression
|
||||||
BMSR_ANC = 0x0020, // Auto-negotiation complete
|
BMSR_ANC = 0x0020, // Auto-negotiation complete
|
||||||
BMSR_RF = 0x0010, // Remote fault
|
BMSR_RF = 0x0010, // Remote fault
|
||||||
BMSR_CAP_AN = 0x0008, // PHY is able to perform auto-negotiation
|
BMSR_CAP_AN = 0x0008, // PHY is able to perform a-negotiation
|
||||||
BMSR_Link = 0x0004, // link state
|
BMSR_Link = 0x0004, // link state
|
||||||
BMSR_Jabber = 0x0002, // Jabber condition detected
|
BMSR_Jabber = 0x0002, // Jabber condition detected
|
||||||
BMSR_CAP_Ext = 0x0001 // Extended register capable
|
BMSR_CAP_Ext = 0x0001 // Extended register capable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum MII_ANAR {
|
enum MII_ANAR {
|
||||||
ANAR_NP = 0x8000, // Next page available
|
ANAR_NP = 0x8000, // Next page available
|
||||||
ANAR_ACK = 0x4000, // Link partner data reception ability acknowledged
|
ANAR_ACK = 0x4000, // Link partner data reception ability ack-ed
|
||||||
ANAR_RF = 0x2000, // Fault condition detected and advertised
|
ANAR_RF = 0x2000, // Fault condition detected and advertised
|
||||||
ANAR_PAUSE = 0x0400, // Pause operation enabled for full-duplex links
|
ANAR_PAUSE = 0x0400, // Pause operation enabled for full-duplex links
|
||||||
ANAR_T4 = 0x0200, // 100BASE-T4 supported
|
ANAR_T4 = 0x0200, // 100BASE-T4 supported
|
||||||
@ -62,32 +66,34 @@ enum MII_ANAR {
|
|||||||
ANAR_TX_HD = 0x0080, // 100BASE-TX half duplex supported
|
ANAR_TX_HD = 0x0080, // 100BASE-TX half duplex supported
|
||||||
ANAR_10_FD = 0x0040, // 10BASE-TX full duplex supported
|
ANAR_10_FD = 0x0040, // 10BASE-TX full duplex supported
|
||||||
ANAR_10_HD = 0x0020, // 10BASE-TX half duplex supported
|
ANAR_10_HD = 0x0020, // 10BASE-TX half duplex supported
|
||||||
ANAR_SELECTOR = 0x0001 // Protocol selection bits (hardcoded to ethernet)
|
ANAR_SELECTOR = 0x0001 // Protocol sel. bits (hardcoded to ethernet)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum MII_ANLPAR {
|
enum MII_ANLPAR {
|
||||||
ANLPAR_NP = 0x8000, // Link partner next page enabled
|
ANLPAR_NP = 0x8000, // Link partner next page enabled
|
||||||
ANLPAR_ACK = 0x4000, // Link partner data reception ability acknowledged
|
ANLPAR_ACK = 0x4000, // Link partner data reception ability ack-ed
|
||||||
ANLPAR_RF = 0x2000, // Remote fault indicated by link partner
|
ANLPAR_RF = 0x2000, // Remote fault indicated by link partner
|
||||||
ANLPAR_PAUSE = 0x0400, // Pause operation supported by link partner
|
ANLPAR_PAUSE = 0x0400, // Pause operation supported by link partner
|
||||||
ANLPAR_T4 = 0x0200, // 100BASE-T4 supported by link partner
|
ANLPAR_T4 = 0x0200, // 100BASE-T4 supported by link partner
|
||||||
ANLPAR_TX_FD = 0x0100, // 100BASE-TX full duplex supported by link partner
|
ANLPAR_TX_FD = 0x0100, // 100BASE-TX FD supported by link partner
|
||||||
ANLPAR_TX_HD = 0x0080, // 100BASE-TX half duplex supported by link partner
|
ANLPAR_TX_HD = 0x0080, // 100BASE-TX HD supported by link partner
|
||||||
ANLPAR_10_FD = 0x0040, // 10BASE-TX full duplex supported by link partner
|
ANLPAR_10_FD = 0x0040, // 10BASE-TX FD supported by link partner
|
||||||
ANLPAR_10_HD = 0x0020, // 10BASE-TX half duplex supported by link partner
|
ANLPAR_10_HD = 0x0020, // 10BASE-TX HD supported by link partner
|
||||||
ANLPAR_SELECTOR = 0x0001 // Link partner's binary encoded protocol selector
|
ANLPAR_SELECTOR = 0x0001 // Link partner's bin. encoded protocol selector
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// index used to different PHY on MII bus
|
// index used to different PHY on MII bus
|
||||||
enum PHYIndex {
|
enum PHYIndex {
|
||||||
CurrentPHY = -1, // currently selected PHY.
|
CurrentPHY = -1, // currently selected PHY.
|
||||||
// Internally used as default index in case on PHYs found.
|
// Internally used as def. index in case no PHYs found.
|
||||||
SecondaryPHY = 0, // secondary PHY
|
SecondaryPHY = 0, // secondary PHY
|
||||||
PrimaryPHY = 1, // primary PHY
|
PrimaryPHY = 1, // primary PHY
|
||||||
PHYsCount = 2 // maximal count of PHYs on bus
|
PHYsCount = 2 // maximal count of PHYs on bus
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// PHY type and id constants and masks.
|
// PHY type and id constants and masks.
|
||||||
enum PHYType {
|
enum PHYType {
|
||||||
PHYTypeMask = 0xe0, // mask for PHY type bits
|
PHYTypeMask = 0xe0, // mask for PHY type bits
|
||||||
@ -105,13 +111,7 @@ class MIIBus {
|
|||||||
public:
|
public:
|
||||||
MIIBus();
|
MIIBus();
|
||||||
|
|
||||||
status_t Init(usb_device device,
|
status_t Init(usb_device device);
|
||||||
uint8 SWOperationRequest,
|
|
||||||
uint8 ReadValueRequest,
|
|
||||||
uint8 WriteValueRequest,
|
|
||||||
uint8 ReadStatusRequest,
|
|
||||||
uint8 HWOperationRequest,
|
|
||||||
uint8 ReadPHYIDsRequest);
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
status_t SetupPHY();
|
status_t SetupPHY();
|
||||||
@ -120,23 +120,20 @@ public:
|
|||||||
uint8 PHYType(PHYIndex phyIndex = CurrentPHY);
|
uint8 PHYType(PHYIndex phyIndex = CurrentPHY);
|
||||||
PHYIndex ActivePHY() { return fSelectedPHY; }
|
PHYIndex ActivePHY() { return fSelectedPHY; }
|
||||||
|
|
||||||
status_t Read(uint16 miiRegister, uint16 *value, PHYIndex phyIndex = CurrentPHY);
|
status_t Read(uint16 miiRegister, uint16 *value,
|
||||||
status_t Write(uint16 miiRegister, uint16 value, PHYIndex phyIndex = CurrentPHY);
|
PHYIndex phyIndex = CurrentPHY);
|
||||||
|
status_t Write(uint16 miiRegister, uint16 value,
|
||||||
|
PHYIndex phyIndex = CurrentPHY);
|
||||||
|
|
||||||
status_t Status(uint16 *status, PHYIndex phyIndex = CurrentPHY);
|
status_t Status(uint16 *status,
|
||||||
|
PHYIndex phyIndex = CurrentPHY);
|
||||||
status_t Dump();
|
status_t Dump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
status_t fStatus;
|
||||||
usb_device fDevice;
|
usb_device fDevice;
|
||||||
uint8 fPHYs[PHYsCount];
|
uint8 fPHYs[PHYsCount];
|
||||||
PHYIndex fSelectedPHY;
|
PHYIndex fSelectedPHY;
|
||||||
|
|
||||||
uint8 fSWOperationRequest;
|
|
||||||
uint8 fReadValueRequest;
|
|
||||||
uint8 fWriteValueRequest;
|
|
||||||
uint8 fReadStatusRequest;
|
|
||||||
uint8 fHWOperationRequest;
|
|
||||||
uint8 fReadPHYIDsRequest;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _USB_MII_BUS_H_
|
#endif // _USB_MII_BUS_H_
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008,2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -10,10 +10,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <lock.h> // for mutex
|
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <driver_settings.h>
|
||||||
|
#include <lock.h>
|
||||||
|
|
||||||
|
|
||||||
bool gTraceOn = false;
|
bool gTraceOn = false;
|
||||||
bool gTruncateLogFile = false;
|
bool gTruncateLogFile = false;
|
||||||
bool gAddTimeStamp = true;
|
bool gAddTimeStamp = true;
|
||||||
@ -33,6 +40,7 @@ void create_log()
|
|||||||
mutex_init(&gLogLock, DRIVER_NAME"-logging");
|
mutex_init(&gLogLock, DRIVER_NAME"-logging");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void load_settings()
|
void load_settings()
|
||||||
{
|
{
|
||||||
void *handle = load_driver_settings(DRIVER_NAME);
|
void *handle = load_driver_settings(DRIVER_NAME);
|
||||||
@ -40,7 +48,8 @@ void load_settings()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
gTraceOn = get_driver_boolean_parameter(handle, "trace", gTraceOn, true);
|
gTraceOn = get_driver_boolean_parameter(handle, "trace", gTraceOn, true);
|
||||||
gTraceFlow = get_driver_boolean_parameter(handle, "trace_flow", gTraceFlow, true);
|
gTraceFlow = get_driver_boolean_parameter(handle, "trace_flow",
|
||||||
|
gTraceFlow, true);
|
||||||
gTruncateLogFile = get_driver_boolean_parameter(handle, "truncate_logfile",
|
gTruncateLogFile = get_driver_boolean_parameter(handle, "truncate_logfile",
|
||||||
gTruncateLogFile, true);
|
gTruncateLogFile, true);
|
||||||
gAddTimeStamp = get_driver_boolean_parameter(handle, "add_timestamp",
|
gAddTimeStamp = get_driver_boolean_parameter(handle, "add_timestamp",
|
||||||
@ -56,6 +65,7 @@ void load_settings()
|
|||||||
create_log();
|
create_log();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void release_settings()
|
void release_settings()
|
||||||
{
|
{
|
||||||
if (gLogFilePath != NULL) {
|
if (gLogFilePath != NULL) {
|
||||||
@ -64,6 +74,7 @@ void release_settings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void usb_asix_trace(bool force, const char* func, const char *fmt, ...)
|
void usb_asix_trace(bool force, const char* func, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
if (!(force || gTraceOn)) {
|
if (!(force || gTraceOn)) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
* ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
|
||||||
* Copyright (c) 2008 S.Zharski <imker@gmx.li>
|
* Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Heavily based on code of the
|
* Heavily based on code of the
|
||||||
@ -9,19 +9,28 @@
|
|||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_ASIX_SETTINGS_H_
|
#ifndef _USB_ASIX_SETTINGS_H_
|
||||||
#define _USB_ASIX_SETTINGS_H_
|
#define _USB_ASIX_SETTINGS_H_
|
||||||
|
|
||||||
|
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _countof
|
||||||
|
#warning "_countof(...) WAS ALREADY DEFINED!!! Remove local definition!"
|
||||||
|
#undef _countof
|
||||||
|
#endif
|
||||||
|
#define _countof(array)(sizeof(array) / sizeof(array[0]))
|
||||||
|
|
||||||
|
|
||||||
void load_settings();
|
void load_settings();
|
||||||
void release_settings();
|
void release_settings();
|
||||||
|
|
||||||
void usb_asix_trace(bool force, const char *func, const char *fmt, ...);
|
void usb_asix_trace(bool force, const char *func, const char *fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
#define TRACE(x...) usb_asix_trace(false, __func__, x)
|
#define TRACE(x...) usb_asix_trace(false, __func__, x)
|
||||||
#define TRACE_ALWAYS(x...) usb_asix_trace(true, __func__, x)
|
#define TRACE_ALWAYS(x...) usb_asix_trace(true, __func__, x)
|
||||||
|
|
||||||
@ -31,4 +40,5 @@ extern bool gTraceFlow;
|
|||||||
#define TRACE_RET(result) usb_asix_trace(false, __func__, \
|
#define TRACE_RET(result) usb_asix_trace(false, __func__, \
|
||||||
"Returns:%#010x\n", result);
|
"Returns:%#010x\n", result);
|
||||||
|
|
||||||
#endif /*_USB_ASIX_SETTINGS_H_*/
|
|
||||||
|
#endif // _USB_ASIX_SETTINGS_H_
|
||||||
|
Loading…
Reference in New Issue
Block a user