/* SPDX-License-Identifier: GPL-2.0-or-later */
/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
/*
Copyright ( c ) 2001 , 2002 by D - Link Corporation
Written by Edward Peng . < edward_peng @ dlink . com . tw >
Created 03 - May - 2001 , base on Linux ' sundance . c .
*/
#ifndef __DL2K_H__
#define __DL2K_H__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/bitops.h>
#include <asm /processor.h> /* Processor type for cache alignment. */
#include <asm /io.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/time.h>
#define TX_RING_SIZE 256
#define TX_QUEUE_LEN (TX_RING_SIZE - 1 ) /* Limit ring entries actually used.*/
#define RX_RING_SIZE 256
#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof (struct netdev_desc)
#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof (struct netdev_desc)
/* Offsets to the device registers.
Unlike software - only systems , device drivers interact with complex hardware .
It ' s not useful to define symbolic names for every register bit in the
device . The name can only partially document the semantics and make
the driver longer and more difficult to read .
In general , only the important configuration values or bits changed
multiple times should be defined symbolically .
*/
enum dl2x_offsets {
/* I/O register offsets */
DMACtrl = 0 x00,
RxDMAStatus = 0 x08,
TFDListPtr0 = 0 x10,
TFDListPtr1 = 0 x14,
TxDMABurstThresh = 0 x18,
TxDMAUrgentThresh = 0 x19,
TxDMAPollPeriod = 0 x1a,
RFDListPtr0 = 0 x1c,
RFDListPtr1 = 0 x20,
RxDMABurstThresh = 0 x24,
RxDMAUrgentThresh = 0 x25,
RxDMAPollPeriod = 0 x26,
RxDMAIntCtrl = 0 x28,
DebugCtrl = 0 x2c,
ASICCtrl = 0 x30,
FifoCtrl = 0 x38,
RxEarlyThresh = 0 x3a,
FlowOffThresh = 0 x3c,
FlowOnThresh = 0 x3e,
TxStartThresh = 0 x44,
EepromData = 0 x48,
EepromCtrl = 0 x4a,
ExpromAddr = 0 x4c,
Exprodata = 0 x50,
WakeEvent = 0 x51,
CountDown = 0 x54,
IntStatusAck = 0 x5a,
IntEnable = 0 x5c,
IntStatus = 0 x5e,
TxStatus = 0 x60,
MACCtrl = 0 x6c,
VLANTag = 0 x70,
PhyCtrl = 0 x76,
StationAddr0 = 0 x78,
StationAddr1 = 0 x7a,
StationAddr2 = 0 x7c,
VLANId = 0 x80,
MaxFrameSize = 0 x86,
ReceiveMode = 0 x88,
HashTable0 = 0 x8c,
HashTable1 = 0 x90,
RmonStatMask = 0 x98,
StatMask = 0 x9c,
RxJumboFrames = 0 xbc,
TCPCheckSumErrors = 0 xc0,
IPCheckSumErrors = 0 xc2,
UDPCheckSumErrors = 0 xc4,
TxJumboFrames = 0 xf4,
/* Ethernet MIB statistic register offsets */
OctetRcvOk = 0 xa8,
McstOctetRcvOk = 0 xac,
BcstOctetRcvOk = 0 xb0,
FramesRcvOk = 0 xb4,
McstFramesRcvdOk = 0 xb8,
BcstFramesRcvdOk = 0 xbe,
MacControlFramesRcvd = 0 xc6,
FrameTooLongErrors = 0 xc8,
InRangeLengthErrors = 0 xca,
FramesCheckSeqErrors = 0 xcc,
FramesLostRxErrors = 0 xce,
OctetXmtOk = 0 xd0,
McstOctetXmtOk = 0 xd4,
BcstOctetXmtOk = 0 xd8,
FramesXmtOk = 0 xdc,
McstFramesXmtdOk = 0 xe0,
FramesWDeferredXmt = 0 xe4,
LateCollisions = 0 xe8,
MultiColFrames = 0 xec,
SingleColFrames = 0 xf0,
BcstFramesXmtdOk = 0 xf6,
CarrierSenseErrors = 0 xf8,
MacControlFramesXmtd = 0 xfa,
FramesAbortXSColls = 0 xfc,
FramesWEXDeferal = 0 xfe,
/* RMON statistic register offsets */
EtherStatsCollisions = 0 x100,
EtherStatsOctetsTransmit = 0 x104,
EtherStatsPktsTransmit = 0 x108,
EtherStatsPkts64OctetTransmit = 0 x10c,
EtherStats65to127OctetsTransmit = 0 x110,
EtherStatsPkts128to255OctetsTransmit = 0 x114,
EtherStatsPkts256to511OctetsTransmit = 0 x118,
EtherStatsPkts512to1023OctetsTransmit = 0 x11c,
EtherStatsPkts1024to1518OctetsTransmit = 0 x120,
EtherStatsCRCAlignErrors = 0 x124,
EtherStatsUndersizePkts = 0 x128,
EtherStatsFragments = 0 x12c,
EtherStatsJabbers = 0 x130,
EtherStatsOctets = 0 x134,
EtherStatsPkts = 0 x138,
EtherStats64Octets = 0 x13c,
EtherStatsPkts65to127Octets = 0 x140,
EtherStatsPkts128to255Octets = 0 x144,
EtherStatsPkts256to511Octets = 0 x148,
EtherStatsPkts512to1023Octets = 0 x14c,
EtherStatsPkts1024to1518Octets = 0 x150,
};
/* Bits in the interrupt status/mask registers. */
enum IntStatus_bits {
InterruptStatus = 0 x0001,
HostError = 0 x0002,
MACCtrlFrame = 0 x0008,
TxComplete = 0 x0004,
RxComplete = 0 x0010,
RxEarly = 0 x0020,
IntRequested = 0 x0040,
UpdateStats = 0 x0080,
LinkEvent = 0 x0100,
TxDMAComplete = 0 x0200,
RxDMAComplete = 0 x0400,
RFDListEnd = 0 x0800,
RxDMAPriority = 0 x1000,
};
/* Bits in the ReceiveMode register. */
enum ReceiveMode_bits {
ReceiveUnicast = 0 x0001,
ReceiveMulticast = 0 x0002,
ReceiveBroadcast = 0 x0004,
ReceiveAllFrames = 0 x0008,
ReceiveMulticastHash = 0 x0010,
ReceiveIPMulticast = 0 x0020,
ReceiveVLANMatch = 0 x0100,
ReceiveVLANHash = 0 x0200,
};
/* Bits in MACCtrl. */
enum MACCtrl_bits {
DuplexSelect = 0 x20,
TxFlowControlEnable = 0 x80,
RxFlowControlEnable = 0 x0100,
RcvFCS = 0 x200,
AutoVLANtagging = 0 x1000,
AutoVLANuntagging = 0 x2000,
StatsEnable = 0 x00200000,
StatsDisable = 0 x00400000,
StatsEnabled = 0 x00800000,
TxEnable = 0 x01000000,
TxDisable = 0 x02000000,
TxEnabled = 0 x04000000,
RxEnable = 0 x08000000,
RxDisable = 0 x10000000,
RxEnabled = 0 x20000000,
};
enum ASICCtrl_LoWord_bits {
PhyMedia = 0 x0080,
};
enum ASICCtrl_HiWord_bits {
GlobalReset = 0 x0001,
RxReset = 0 x0002,
TxReset = 0 x0004,
DMAReset = 0 x0008,
FIFOReset = 0 x0010,
NetworkReset = 0 x0020,
HostReset = 0 x0040,
ResetBusy = 0 x0400,
};
#define IPG_AC_LED_MODE BIT(14 )
#define IPG_AC_LED_SPEED BIT(27 )
#define IPG_AC_LED_MODE_BIT_1 BIT(29 )
/* Transmit Frame Control bits */
enum TFC_bits {
DwordAlign = 0 x00000000,
WordAlignDisable = 0 x00030000,
WordAlign = 0 x00020000,
TCPChecksumEnable = 0 x00040000,
UDPChecksumEnable = 0 x00080000,
IPChecksumEnable = 0 x00100000,
FCSAppendDisable = 0 x00200000,
TxIndicate = 0 x00400000,
TxDMAIndicate = 0 x00800000,
FragCountShift = 24 ,
VLANTagInsert = 0 x0000000010000000,
TFDDone = 0 x80000000,
VIDShift = 32 ,
UsePriorityShift = 48 ,
};
/* Receive Frames Status bits */
enum RFS_bits {
RxFIFOOverrun = 0 x00010000,
RxRuntFrame = 0 x00020000,
RxAlignmentError = 0 x00040000,
RxFCSError = 0 x00080000,
RxOverSizedFrame = 0 x00100000,
RxLengthError = 0 x00200000,
VLANDetected = 0 x00400000,
TCPDetected = 0 x00800000,
TCPError = 0 x01000000,
UDPDetected = 0 x02000000,
UDPError = 0 x04000000,
IPDetected = 0 x08000000,
IPError = 0 x10000000,
FrameStart = 0 x20000000,
FrameEnd = 0 x40000000,
RFDDone = 0 x80000000,
TCIShift = 32 ,
RFS_Errors = 0 x003f0000,
};
#define MII_RESET_TIME_OUT 10000
/* MII register */
enum _mii_reg {
MII_PHY_SCR = 16 ,
};
/* PCS register */
enum _pcs_reg {
PCS_BMCR = 0 ,
PCS_BMSR = 1 ,
PCS_ANAR = 4 ,
PCS_ANLPAR = 5 ,
PCS_ANER = 6 ,
PCS_ANNPT = 7 ,
PCS_ANLPRNP = 8 ,
PCS_ESR = 15 ,
};
/* IEEE Extened Status Register */
enum _mii_esr {
MII_ESR_1000BX_FD = 0 x8000,
MII_ESR_1000BX_HD = 0 x4000,
MII_ESR_1000BT_FD = 0 x2000,
MII_ESR_1000BT_HD = 0 x1000,
};
/* PHY Specific Control Register */
#if 0
typedef union t_MII_PHY_SCR {
u16 image;
struct {
u16 disable_jabber:1 ; // bit 0
u16 polarity_reversal:1 ; // bit 1
u16 SEQ_test:1 ; // bit 2
u16 _bit_3:1 ; // bit 3
u16 disable_CLK125:1 ; // bit 4
u16 mdi_crossover_mode:2 ; // bit 6:5
u16 enable_ext_dist:1 ; // bit 7
u16 _bit_8_9:2 ; // bit 9:8
u16 force_link:1 ; // bit 10
u16 assert_CRS:1 ; // bit 11
u16 rcv_fifo_depth:2 ; // bit 13:12
u16 xmit_fifo_depth:2 ; // bit 15:14
} bits;
} PHY_SCR_t, *PPHY_SCR_t;
#endif
typedef enum t_MII_ADMIN_STATUS {
adm_reset,
adm_operational,
adm_loopback,
adm_power_down,
adm_isolate
} MII_ADMIN_t, *PMII_ADMIN_t;
/* Physical Coding Sublayer Management (PCS) */
/* PCS control and status registers bitmap as the same as MII */
/* PCS Extended Status register bitmap as the same as MII */
/* PCS ANAR */
enum _pcs_anar {
PCS_ANAR_NEXT_PAGE = 0 x8000,
PCS_ANAR_REMOTE_FAULT = 0 x3000,
PCS_ANAR_ASYMMETRIC = 0 x0100,
PCS_ANAR_PAUSE = 0 x0080,
PCS_ANAR_HALF_DUPLEX = 0 x0040,
PCS_ANAR_FULL_DUPLEX = 0 x0020,
};
/* PCS ANLPAR */
enum _pcs_anlpar {
PCS_ANLPAR_NEXT_PAGE = PCS_ANAR_NEXT_PAGE,
PCS_ANLPAR_REMOTE_FAULT = PCS_ANAR_REMOTE_FAULT,
PCS_ANLPAR_ASYMMETRIC = PCS_ANAR_ASYMMETRIC,
PCS_ANLPAR_PAUSE = PCS_ANAR_PAUSE,
PCS_ANLPAR_HALF_DUPLEX = PCS_ANAR_HALF_DUPLEX,
PCS_ANLPAR_FULL_DUPLEX = PCS_ANAR_FULL_DUPLEX,
};
typedef struct t_SROM {
__le16 config_param; /* 0x00 */
__le16 asic_ctrl; /* 0x02 */
__le16 sub_vendor_id; /* 0x04 */
__le16 sub_system_id; /* 0x06 */
__le16 pci_base_1; /* 0x08 (IP1000A only) */
__le16 pci_base_2; /* 0x0a (IP1000A only) */
__le16 led_mode; /* 0x0c (IP1000A only) */
__le16 reserved1[9 ]; /* 0x0e-0x1f */
u8 mac_addr[6 ]; /* 0x20-0x25 */
u8 reserved2[10 ]; /* 0x26-0x2f */
u8 sib[204 ]; /* 0x30-0xfb */
__le32 crc; /* 0xfc-0xff */
} SROM_t, *PSROM_t;
/* Ioctl custom data */
struct ioctl_data {
char signature[10 ];
int cmd;
int len;
char *data;
};
/* The Rx and Tx buffer descriptors. */
struct netdev_desc {
__le64 next_desc;
__le64 status;
__le64 fraginfo;
};
#define PRIV_ALIGN 15 /* Required alignment mask */
/* Use __attribute__((aligned (L1_CACHE_BYTES))) to maintain alignment
within the structure. */
struct netdev_private {
/* Descriptor rings first for alignment. */
struct netdev_desc *rx_ring;
struct netdev_desc *tx_ring;
struct sk_buff *rx_skbuff[RX_RING_SIZE];
struct sk_buff *tx_skbuff[TX_RING_SIZE];
dma_addr_t tx_ring_dma;
dma_addr_t rx_ring_dma;
struct pci_dev *pdev;
void __iomem *ioaddr;
void __iomem *eeprom_addr;
// To ensure synchronization when stats are updated.
spinlock_t stats_lock;
spinlock_t tx_lock;
spinlock_t rx_lock;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int speed; /* Operating speed */
unsigned int vlan; /* VLAN Id */
unsigned int chip_id; /* PCI table chip id */
unsigned int rx_coalesce; /* Maximum frames each RxDMAComplete intr */
unsigned int rx_timeout; /* Wait time between RxDMAComplete intr */
unsigned int tx_coalesce; /* Maximum frames each tx interrupt */
unsigned int full_duplex:1 ; /* Full-duplex operation requested. */
unsigned int an_enable:2 ; /* Auto-Negotiated Enable */
unsigned int jumbo:1 ; /* Jumbo frame enable */
unsigned int coalesce:1 ; /* Rx coalescing enable */
unsigned int tx_flow:1 ; /* Tx flow control enable */
unsigned int rx_flow:1 ; /* Rx flow control enable */
unsigned int phy_media:1 ; /* 1: fiber, 0: copper */
unsigned int link_status:1 ; /* Current link status */
struct netdev_desc *last_tx; /* Last Tx descriptor used. */
unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */
unsigned long cur_tx, old_tx;
struct timer_list timer;
int wake_polarity;
char name[256 ]; /* net device description */
u8 duplex_polarity;
u16 mcast_filter[4 ];
u16 advertising; /* NWay media advertisement */
u16 negotiate; /* Negotiated media */
int phy_addr; /* PHY addresses. */
u16 led_mode; /* LED mode read from EEPROM (IP1000A only) */
bool rmon_enable;
};
/* The station address location in the EEPROM. */
/* The struct pci_device_id consist of:
vendor , device Vendor and device ID to match ( or PCI_ANY_ID )
subvendor , subdevice Subsystem vendor and device ID to match ( or PCI_ANY_ID )
class Device class to match . The class_mask tells which bits
class_mask of the class are honored during the comparison .
driver_data Data private to the driver .
*/
#define CHIP_IP1000A 1
static const struct pci_device_id rio_pci_tbl[] = {
{0 x1186, 0 x4000, PCI_ANY_ID, PCI_ANY_ID, },
{0 x13f0, 0 x1021, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VDEVICE(SUNDANCE, 0 x1023), CHIP_IP1000A },
{ PCI_VDEVICE(SUNDANCE, 0 x2021), CHIP_IP1000A },
{ PCI_VDEVICE(DLINK, 0 x9021), CHIP_IP1000A },
{ PCI_VDEVICE(DLINK, 0 x4020), CHIP_IP1000A },
{ }
};
MODULE_DEVICE_TABLE (pci, rio_pci_tbl);
#define TX_TIMEOUT (4 *HZ)
#define PACKET_SIZE 1536
#define MAX_JUMBO 8000
#define RIO_IO_SIZE 340
#define DEFAULT_RXC 5
#define DEFAULT_RXT 750
#define DEFAULT_TXC 1
#define MAX_TXC 8
#endif /* __DL2K_H__ */
Messung V0.5 in Prozent C=83 H=96 G=89
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-10-02)
¤
*© Formatika GbR, Deutschland