3,8 → 3,10 |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PCnet32 driver for KolibriOS ;; |
;; PCnet driver for KolibriOS ;; |
;; ;; |
;; By hidnplayr & clevermouse ;; |
;; ;; |
;; Based on the PCnet32 driver for MenuetOS, by Jarek Pelczar ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
12,45 → 14,30 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
; $Revision$ |
|
format MS COFF |
|
API_VERSION equ 0x01000100 |
DRIVER_VERSION equ 5 |
|
MAX_DEVICES equ 16 |
|
DEBUG equ 1 |
__DEBUG__ equ 1 |
__DEBUG_LEVEL__ equ 1 |
|
TX_RING_SIZE equ 4 |
RX_RING_SIZE equ 4 |
PKT_BUF_SZ equ 1544 |
MAX_DEVICES equ 4 |
MAX_ETH_FRAME_SIZE equ 1514 |
|
|
include 'proc32.inc' |
include 'imports.inc' |
include 'fdo.inc' |
include 'netdrv.inc' |
|
|
public START |
public service_proc |
public version |
|
struc buf_head { |
.base dd ? |
.length dw ? |
.status dw ? |
.msg_length dw ? |
.misc dw ? |
.reserved dd ? |
.size: |
} |
|
virtual at 0 |
buf_head buf_head |
end virtual |
|
virtual at ebx |
|
device: |
57,26 → 44,8 |
|
ETH_DEVICE |
|
.rx_buffer dd ? |
.tx_buffer dd ? |
; device specific |
|
.io_addr dd ? |
.irq_line db ? |
.pci_bus db ? |
.pci_dev db ? |
db ? ; align 4 |
|
.access_read_csr dd ? |
.access_write_csr dd ? |
.access_read_bcr dd ? |
.access_write_bcr dd ? |
.access_read_rap dd ? |
.access_write_rap dd ? |
.access_reset dd ? |
|
; The following fields up to .tx_ring_phys inclusive form |
; initialization block for hardware; do not modify (must be 4-aligned) |
|
.private: |
.mode_ dw ? |
.tlen_rlen dw ? |
86,9 → 55,6 |
.rx_ring_phys dd ? |
.tx_ring_phys dd ? |
|
.rx_ring rb RX_RING_SIZE * buf_head.size |
.tx_ring rb TX_RING_SIZE * buf_head.size |
|
.cur_rx db ? |
.cur_tx db ? |
.dirty_rx dd ? |
103,294 → 69,286 |
.fset db ? |
.fdx db ? |
|
.size = $ - device |
.rx_buffer dd ? |
.tx_buffer dd ? |
|
end virtual |
.io_addr dd ? |
.irq_line db ? |
.pci_bus db ? |
.pci_dev db ? |
|
|
struc rx_desc_2 { ; Swstyle 2 |
.access_read_csr dd ? |
.access_write_csr dd ? |
.access_read_bcr dd ? |
.access_write_bcr dd ? |
.access_read_rap dd ? |
.access_write_rap dd ? |
.access_reset dd ? |
|
.rbadr dd ? |
.status dd ? |
.rfrtag dd ? |
device_size = $ - device |
|
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |Address | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |19-16|15-12|11-0 | |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |CRDA+00h| RBADR[31:0] | |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |CRDA+04h| OWN | ERR |FRAM |OFLO | CRC |BUFF | STP | ENP | BPE | PAM |LAFM | BAM | RES |1111 |BCNT | |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |CRDA+08h| RES | RFRTAG[14:0] |0000 |MCNT | |
; +--------+-----+-----------------------------------------------------------------------+-----+-----+ |
; |CRDA+0Ch| USER SPACE | | | |
; +--------+-----------------------------------------------------------------------------+-----+-----+ |
end virtual |
|
} |
struc buf_head { |
.base dd ? |
.length dw ? |
.status dw ? |
.msg_length dw ? |
.misc dw ? |
.reserved dd ? |
|
struc rx_desc_3 { ; Swstyle 3 |
|
.mcnt dd ? |
.status dd ? |
.rbadr dd ? |
|
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |Address | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 |22-16|15-12|11-0 | |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |CRDA+00h| RES | RES | RES |0000 |MCNT | |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |CRDA+04h| OWN | ERR |FRAM |OFLO | CRC |BUFF | STP | ENP | BPE | RES |1111 |BCNT | |
; +--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
; |CRDA+08h| RBADR[31:0] | |
; +--------+-----------------------------------------------------------------------+ |
; |CRDA+0Ch| USER SPACE | |
; +--------+-----------------------------------------------------------------------+ |
|
.size: |
} |
|
virtual at 0 |
rx_desc rx_desc_2 |
buf_head buf_head |
end virtual |
|
PORT_AUI equ 0x00 |
PORT_10BT equ 0x01 |
PORT_GPSI equ 0x02 |
PORT_MII equ 0x03 |
PORT_PORTSEL equ 0x03 |
PORT_ASEL equ 0x04 |
PORT_100 equ 0x40 |
PORT_FD equ 0x80 |
PCNET_PORT_AUI equ 0x00 |
PCNET_PORT_10BT equ 0x01 |
PCNET_PORT_GPSI equ 0x02 |
PCNET_PORT_MII equ 0x03 |
PCNET_PORT_PORTSEL equ 0x03 |
PCNET_PORT_ASEL equ 0x04 |
PCNET_PORT_100 equ 0x40 |
PCNET_PORT_FD equ 0x80 |
|
DMA_MASK equ 0xffffffff |
PCNET_DMA_MASK equ 0xffffffff |
|
LOG_TX_BUFFERS equ 2 |
LOG_RX_BUFFERS equ 2 |
PCNET_LOG_TX_BUFFERS equ 2 |
PCNET_LOG_RX_BUFFERS equ 2 |
|
TX_RING_MOD_MASK equ (TX_RING_SIZE-1) |
TX_RING_LEN_BITS equ (LOG_TX_BUFFERS shl 12) |
PCNET_TX_RING_SIZE equ 4 |
PCNET_TX_RING_MOD_MASK equ (PCNET_TX_RING_SIZE-1) |
PCNET_TX_RING_LEN_BITS equ (PCNET_LOG_TX_BUFFERS shl 12) |
|
RX_RING_MOD_MASK equ (RX_RING_SIZE-1) |
RX_RING_LEN_BITS equ (LOG_RX_BUFFERS shl 4) |
PCNET_RX_RING_SIZE equ 4 |
PCNET_RX_RING_MOD_MASK equ (PCNET_RX_RING_SIZE-1) |
PCNET_RX_RING_LEN_BITS equ (PCNET_LOG_RX_BUFFERS shl 4) |
|
WIO_RDP equ 0x10 |
WIO_RAP equ 0x12 |
WIO_RESET equ 0x14 |
WIO_BDP equ 0x16 |
DWIO_RDP equ 0x10 |
DWIO_RAP equ 0x14 |
DWIO_RESET equ 0x18 |
DWIO_BDP equ 0x1C |
TOTAL_SIZE equ 0x20 |
PCNET_PKT_BUF_SZ equ 1544 |
PCNET_PKT_BUF_SZ_NEG equ 0xf9f8 |
|
PCNET_WIO_RDP equ 0x10 |
PCNET_WIO_RAP equ 0x12 |
PCNET_WIO_RESET equ 0x14 |
PCNET_WIO_BDP equ 0x16 |
PCNET_DWIO_RDP equ 0x10 |
PCNET_DWIO_RAP equ 0x14 |
PCNET_DWIO_RESET equ 0x18 |
PCNET_DWIO_BDP equ 0x1C |
PCNET_TOTAL_SIZE equ 0x20 |
|
; CSR registers |
|
CSR_CSR equ 0x00 |
CSR_IAB0 equ 0x01 |
CSR_IAB1 equ 0x02 |
CSR_IMR equ 0x03 |
CSR_TFEAT equ 0x04 |
CSR_EXTCTL1 equ 0x05 |
CSR_DTBLLEN equ 0x06 |
CSR_EXTCTL2 equ 0x07 |
CSR_MAR0 equ 0x08 |
CSR_MAR1 equ 0x09 |
CSR_MAR2 equ 0x0A |
CSR_MAR3 equ 0x0B |
CSR_PAR0 equ 0x0C |
CSR_PAR1 equ 0x0D |
CSR_PAR2 equ 0x0E |
CSR_MODE equ 0x0F |
CSR_RXADDR0 equ 0x18 |
CSR_RXADDR1 equ 0x19 |
CSR_TXADDR0 equ 0x1E |
CSR_TXADDR1 equ 0x1F |
CSR_TXPOLL equ 0x2F |
CSR_RXPOLL equ 0x31 |
CSR_RXRINGLEN equ 0x4C |
CSR_TXRINGLEN equ 0x4E |
CSR_DMACTL equ 0x50 |
CSR_BUSTIMER equ 0x52 |
CSR_MEMERRTIMEO equ 0x64 |
CSR_ONNOWMISC equ 0x74 |
CSR_ADVFEAT equ 0x7A |
CSR_MACCFG equ 0x7D |
CSR_CHIPID0 equ 0x58 |
CSR_CHIPID1 equ 0x59 |
PCNET_CSR_CSR equ 0x00 |
PCNET_CSR_IAB0 equ 0x01 |
PCNET_CSR_IAB1 equ 0x02 |
PCNET_CSR_IMR equ 0x03 |
PCNET_CSR_TFEAT equ 0x04 |
PCNET_CSR_EXTCTL1 equ 0x05 |
PCNET_CSR_DTBLLEN equ 0x06 |
PCNET_CSR_EXTCTL2 equ 0x07 |
PCNET_CSR_MAR0 equ 0x08 |
PCNET_CSR_MAR1 equ 0x09 |
PCNET_CSR_MAR2 equ 0x0A |
PCNET_CSR_MAR3 equ 0x0B |
PCNET_CSR_PAR0 equ 0x0C |
PCNET_CSR_PAR1 equ 0x0D |
PCNET_CSR_PAR2 equ 0x0E |
PCNET_CSR_MODE equ 0x0F |
PCNET_CSR_RXADDR0 equ 0x18 |
PCNET_CSR_RXADDR1 equ 0x19 |
PCNET_CSR_TXADDR0 equ 0x1E |
PCNET_CSR_TXADDR1 equ 0x1F |
PCNET_CSR_TXPOLL equ 0x2F |
PCNET_CSR_RXPOLL equ 0x31 |
PCNET_CSR_RXRINGLEN equ 0x4C |
PCNET_CSR_TXRINGLEN equ 0x4E |
PCNET_CSR_DMACTL equ 0x50 |
PCNET_CSR_BUSTIMER equ 0x52 |
PCNET_CSR_MEMERRTIMEO equ 0x64 |
PCNET_CSR_ONNOWMISC equ 0x74 |
PCNET_CSR_ADVFEAT equ 0x7A |
PCNET_CSR_MACCFG equ 0x7D |
PCNET_CSR_CHIPID0 equ 0x58 |
PCNET_CSR_CHIPID1 equ 0x59 |
|
; Control and Status Register (CSR0) |
|
CSR_INIT equ 1 shl 0 |
CSR_START equ 1 shl 1 |
CSR_STOP equ 1 shl 2 |
CSR_TX equ 1 shl 3 |
CSR_TXON equ 1 shl 4 |
CSR_RXON equ 1 shl 5 |
CSR_INTEN equ 1 shl 6 |
CSR_INTR equ 1 shl 7 |
CSR_IDONE equ 1 shl 8 |
CSR_TINT equ 1 shl 9 |
CSR_RINT equ 1 shl 10 |
CSR_MERR equ 1 shl 11 |
CSR_MISS equ 1 shl 12 |
CSR_CERR equ 1 shl 13 |
PCNET_CSR_INIT equ 1 shl 0 |
PCNET_CSR_START equ 1 shl 1 |
PCNET_CSR_STOP equ 1 shl 2 |
PCNET_CSR_TX equ 1 shl 3 |
PCNET_CSR_TXON equ 1 shl 4 |
PCNET_CSR_RXON equ 1 shl 5 |
PCNET_CSR_INTEN equ 1 shl 6 |
PCNET_CSR_INTR equ 1 shl 7 |
PCNET_CSR_IDONE equ 1 shl 8 |
PCNET_CSR_TINT equ 1 shl 9 |
PCNET_CSR_RINT equ 1 shl 10 |
PCNET_CSR_MERR equ 1 shl 11 |
PCNET_CSR_MISS equ 1 shl 12 |
PCNET_CSR_CERR equ 1 shl 13 |
|
; Interrupt masks and deferral control (CSR3) |
|
IMR_BSWAP equ 0x0004 |
IMR_ENMBA equ 0x0008 ; enable modified backoff alg |
IMR_DXMT2PD equ 0x0010 |
IMR_LAPPEN equ 0x0020 ; lookahead packet processing enb |
IMR_DXSUFLO equ 0x0040 ; disable TX stop on underflow |
IMR_IDONE equ 0x0100 |
IMR_TINT equ 0x0200 |
IMR_RINT equ 0x0400 |
IMR_MERR equ 0x0800 |
IMR_MISS equ 0x1000 |
PCNET_IMR_BSWAP equ 0x0004 |
PCNET_IMR_ENMBA equ 0x0008 ; enable modified backoff alg |
PCNET_IMR_DXMT2PD equ 0x0010 |
PCNET_IMR_LAPPEN equ 0x0020 ; lookahead packet processing enb |
PCNET_IMR_DXSUFLO equ 0x0040 ; disable TX stop on underflow |
PCNET_IMR_IDONE equ 0x0100 |
PCNET_IMR_TINT equ 0x0200 |
PCNET_IMR_RINT equ 0x0400 |
PCNET_IMR_MERR equ 0x0800 |
PCNET_IMR_MISS equ 0x1000 |
|
IMR equ IMR_TINT+IMR_RINT+IMR_IDONE+IMR_MERR+IMR_MISS |
PCNET_IMR equ PCNET_IMR_TINT+PCNET_IMR_RINT+PCNET_IMR_IDONE+PCNET_IMR_MERR+PCNET_IMR_MISS |
|
; Test and features control (CSR4) |
|
TFEAT_TXSTRTMASK equ 0x0004 |
TFEAT_TXSTRT equ 0x0008 |
TFEAT_RXCCOFLOWM equ 0x0010 ; Rx collision counter oflow |
TFEAT_RXCCOFLOW equ 0x0020 |
TFEAT_UINT equ 0x0040 |
TFEAT_UINTREQ equ 0x0080 |
TFEAT_MISSOFLOWM equ 0x0100 |
TFEAT_MISSOFLOW equ 0x0200 |
TFEAT_STRIP_FCS equ 0x0400 |
TFEAT_PAD_TX equ 0x0800 |
TFEAT_TXDPOLL equ 0x1000 |
TFEAT_DMAPLUS equ 0x4000 |
PCNET_TFEAT_TXSTRTMASK equ 0x0004 |
PCNET_TFEAT_TXSTRT equ 0x0008 |
PCNET_TFEAT_RXCCOFLOWM equ 0x0010 ; Rx collision counter oflow |
PCNET_TFEAT_RXCCOFLOW equ 0x0020 |
PCNET_TFEAT_UINT equ 0x0040 |
PCNET_TFEAT_UINTREQ equ 0x0080 |
PCNET_TFEAT_MISSOFLOWM equ 0x0100 |
PCNET_TFEAT_MISSOFLOW equ 0x0200 |
PCNET_TFEAT_STRIP_FCS equ 0x0400 |
PCNET_TFEAT_PAD_TX equ 0x0800 |
PCNET_TFEAT_TXDPOLL equ 0x1000 |
PCNET_TFEAT_DMAPLUS equ 0x4000 |
|
; Extended control and interrupt 1 (CSR5) |
|
EXTCTL1_SPND equ 0x0001 ; suspend |
EXTCTL1_MPMODE equ 0x0002 ; magic packet mode |
EXTCTL1_MPENB equ 0x0004 ; magic packet enable |
EXTCTL1_MPINTEN equ 0x0008 ; magic packet interrupt enable |
EXTCTL1_MPINT equ 0x0010 ; magic packet interrupt |
EXTCTL1_MPPLBA equ 0x0020 ; magic packet phys. logical bcast |
EXTCTL1_EXDEFEN equ 0x0040 ; excessive deferral interrupt enb. |
EXTCTL1_EXDEF equ 0x0080 ; excessive deferral interrupt |
EXTCTL1_SINTEN equ 0x0400 ; system interrupt enable |
EXTCTL1_SINT equ 0x0800 ; system interrupt |
EXTCTL1_LTINTEN equ 0x4000 ; last TX interrupt enb |
EXTCTL1_TXOKINTD equ 0x8000 ; TX OK interrupt disable |
PCNET_EXTCTL1_SPND equ 0x0001 ; suspend |
PCNET_EXTCTL1_MPMODE equ 0x0002 ; magic packet mode |
PCNET_EXTCTL1_MPENB equ 0x0004 ; magic packet enable |
PCNET_EXTCTL1_MPINTEN equ 0x0008 ; magic packet interrupt enable |
PCNET_EXTCTL1_MPINT equ 0x0010 ; magic packet interrupt |
PCNET_EXTCTL1_MPPLBA equ 0x0020 ; magic packet phys. logical bcast |
PCNET_EXTCTL1_EXDEFEN equ 0x0040 ; excessive deferral interrupt enb. |
PCNET_EXTCTL1_EXDEF equ 0x0080 ; excessive deferral interrupt |
PCNET_EXTCTL1_SINTEN equ 0x0400 ; system interrupt enable |
PCNET_EXTCTL1_SINT equ 0x0800 ; system interrupt |
PCNET_EXTCTL1_LTINTEN equ 0x4000 ; last TX interrupt enb |
PCNET_EXTCTL1_TXOKINTD equ 0x8000 ; TX OK interrupt disable |
|
; RX/TX descriptor len (CSR6) |
|
DTBLLEN_RLEN equ 0x0F00 |
DTBLLEN_TLEN equ 0xF000 |
PCNET_DTBLLEN_RLEN equ 0x0F00 |
PCNET_DTBLLEN_TLEN equ 0xF000 |
|
; Extended control and interrupt 2 (CSR7) |
|
EXTCTL2_MIIPDTINTE equ 0x0001 |
EXTCTL2_MIIPDTINT equ 0x0002 |
EXTCTL2_MCCIINTE equ 0x0004 |
EXTCTL2_MCCIINT equ 0x0008 |
EXTCTL2_MCCINTE equ 0x0010 |
EXTCTL2_MCCINT equ 0x0020 |
EXTCTL2_MAPINTE equ 0x0040 |
EXTCTL2_MAPINT equ 0x0080 |
EXTCTL2_MREINTE equ 0x0100 |
EXTCTL2_MREINT equ 0x0200 |
EXTCTL2_STINTE equ 0x0400 |
EXTCTL2_STINT equ 0x0800 |
EXTCTL2_RXDPOLL equ 0x1000 |
EXTCTL2_RDMD equ 0x2000 |
EXTCTL2_RXFRTG equ 0x4000 |
EXTCTL2_FASTSPNDE equ 0x8000 |
PCNET_EXTCTL2_MIIPDTINTE equ 0x0001 |
PCNET_EXTCTL2_MIIPDTINT equ 0x0002 |
PCNET_EXTCTL2_MCCIINTE equ 0x0004 |
PCNET_EXTCTL2_MCCIINT equ 0x0008 |
PCNET_EXTCTL2_MCCINTE equ 0x0010 |
PCNET_EXTCTL2_MCCINT equ 0x0020 |
PCNET_EXTCTL2_MAPINTE equ 0x0040 |
PCNET_EXTCTL2_MAPINT equ 0x0080 |
PCNET_EXTCTL2_MREINTE equ 0x0100 |
PCNET_EXTCTL2_MREINT equ 0x0200 |
PCNET_EXTCTL2_STINTE equ 0x0400 |
PCNET_EXTCTL2_STINT equ 0x0800 |
PCNET_EXTCTL2_RXDPOLL equ 0x1000 |
PCNET_EXTCTL2_RDMD equ 0x2000 |
PCNET_EXTCTL2_RXFRTG equ 0x4000 |
PCNET_EXTCTL2_FASTSPNDE equ 0x8000 |
|
; Mode (CSR15) |
|
MODE_RXD equ 0x0001 ; RX disable |
MODE_TXD equ 0x0002 ; TX disable |
MODE_LOOP equ 0x0004 ; loopback enable |
MODE_TXCRCD equ 0x0008 |
MODE_FORCECOLL equ 0x0010 |
MODE_RETRYD equ 0x0020 |
MODE_INTLOOP equ 0x0040 |
MODE_PORTSEL equ 0x0180 |
MODE_RXVPAD equ 0x2000 |
MODE_RXNOBROAD equ 0x4000 |
MODE_PROMISC equ 0x8000 |
PCNET_MODE_RXD equ 0x0001 ; RX disable |
PCNET_MODE_TXD equ 0x0002 ; TX disable |
PCNET_MODE_LOOP equ 0x0004 ; loopback enable |
PCNET_MODE_TXCRCD equ 0x0008 |
PCNET_MODE_FORCECOLL equ 0x0010 |
PCNET_MODE_RETRYD equ 0x0020 |
PCNET_MODE_INTLOOP equ 0x0040 |
PCNET_MODE_PORTSEL equ 0x0180 |
PCNET_MODE_RXVPAD equ 0x2000 |
PCNET_MODE_RXNOBROAD equ 0x4000 |
PCNET_MODE_PROMISC equ 0x8000 |
|
; BCR (Bus Control Registers) |
|
BCR_MMRA equ 0x00 ; Master Mode Read Active |
BCR_MMW equ 0x01 ; Master Mode Write Active |
BCR_MISCCFG equ 0x02 |
BCR_LED0 equ 0x04 |
BCR_LED1 equ 0x05 |
BCR_LED2 equ 0x06 |
BCR_LED3 equ 0x07 |
BCR_DUPLEX equ 0x09 |
BCR_BUSCTL equ 0x12 |
BCR_EECTL equ 0x13 |
BCR_SSTYLE equ 0x14 |
BCR_PCILAT equ 0x16 |
BCR_PCISUBVENID equ 0x17 |
BCR_PCISUBSYSID equ 0x18 |
BCR_SRAMSIZE equ 0x19 |
BCR_SRAMBOUND equ 0x1A |
BCR_SRAMCTL equ 0x1B |
BCR_MIICTL equ 0x20 |
BCR_MIIADDR equ 0x21 |
BCR_MIIDATA equ 0x22 |
BCR_PCIVENID equ 0x23 |
BCR_PCIPCAP equ 0x24 |
BCR_DATA0 equ 0x25 |
BCR_DATA1 equ 0x26 |
BCR_DATA2 equ 0x27 |
BCR_DATA3 equ 0x28 |
BCR_DATA4 equ 0x29 |
BCR_DATA5 equ 0x2A |
BCR_DATA6 equ 0x2B |
BCR_DATA7 equ 0x2C |
BCR_ONNOWPAT0 equ 0x2D |
BCR_ONNOWPAT1 equ 0x2E |
BCR_ONNOWPAT2 equ 0x2F |
BCR_PHYSEL equ 0x31 |
PCNET_BCR_MMRA equ 0x00 ; Master Mode Read Active |
PCNET_BCR_MMW equ 0x01 ; Master Mode Write Active |
PCNET_BCR_MISCCFG equ 0x02 |
PCNET_BCR_LED0 equ 0x04 |
PCNET_BCR_LED1 equ 0x05 |
PCNET_BCR_LED2 equ 0x06 |
PCNET_BCR_LED3 equ 0x07 |
PCNET_BCR_DUPLEX equ 0x09 |
PCNET_BCR_BUSCTL equ 0x12 |
PCNET_BCR_EECTL equ 0x13 |
PCNET_BCR_SSTYLE equ 0x14 |
PCNET_BCR_PCILAT equ 0x16 |
PCNET_BCR_PCISUBVENID equ 0x17 |
PCNET_BCR_PCISUBSYSID equ 0x18 |
PCNET_BCR_SRAMSIZE equ 0x19 |
PCNET_BCR_SRAMBOUND equ 0x1A |
PCNET_BCR_SRAMCTL equ 0x1B |
PCNET_BCR_MIICTL equ 0x20 |
PCNET_BCR_MIIADDR equ 0x21 |
PCNET_BCR_MIIDATA equ 0x22 |
PCNET_BCR_PCIVENID equ 0x23 |
PCNET_BCR_PCIPCAP equ 0x24 |
PCNET_BCR_DATA0 equ 0x25 |
PCNET_BCR_DATA1 equ 0x26 |
PCNET_BCR_DATA2 equ 0x27 |
PCNET_BCR_DATA3 equ 0x28 |
PCNET_BCR_DATA4 equ 0x29 |
PCNET_BCR_DATA5 equ 0x2A |
PCNET_BCR_DATA6 equ 0x2B |
PCNET_BCR_DATA7 equ 0x2C |
PCNET_BCR_ONNOWPAT0 equ 0x2D |
PCNET_BCR_ONNOWPAT1 equ 0x2E |
PCNET_BCR_ONNOWPAT2 equ 0x2F |
PCNET_BCR_PHYSEL equ 0x31 |
|
; RX status register |
|
RXSTAT_BPE equ 0x0080 ; bus parity error |
RXSTAT_ENP equ 0x0100 ; end of packet |
RXSTAT_STP equ 0x0200 ; start of packet |
RXSTAT_BUFF equ 0x0400 ; buffer error |
RXSTAT_CRC equ 0x0800 ; CRC error |
RXSTAT_OFLOW equ 0x1000 ; rx overrun |
RXSTAT_FRAM equ 0x2000 ; framing error |
RXSTAT_ERR equ 0x4000 ; error summary |
RXSTAT_OWN equ 0x8000 |
PCNET_RXSTAT_BPE equ 0x0080 ; bus parity error |
PCNET_RXSTAT_ENP equ 0x0100 ; end of packet |
PCNET_RXSTAT_STP equ 0x0200 ; start of packet |
PCNET_RXSTAT_BUFF equ 0x0400 ; buffer error |
PCNET_RXSTAT_CRC equ 0x0800 ; CRC error |
PCNET_RXSTAT_OFLOW equ 0x1000 ; rx overrun |
PCNET_RXSTAT_FRAM equ 0x2000 ; framing error |
PCNET_RXSTAT_ERR equ 0x4000 ; error summary |
PCNET_RXSTAT_OWN equ 0x8000 |
|
; TX status register |
|
TXSTAT_TRC equ 0x0000000F ; transmit retries |
TXSTAT_RTRY equ 0x04000000 ; retry |
TXSTAT_LCAR equ 0x08000000 ; lost carrier |
TXSTAT_LCOL equ 0x10000000 ; late collision |
TXSTAT_EXDEF equ 0x20000000 ; excessive deferrals |
TXSTAT_UFLOW equ 0x40000000 ; transmit underrun |
TXSTAT_BUFF equ 0x80000000 ; buffer error |
PCNET_TXSTAT_TRC equ 0x0000000F ; transmit retries |
PCNET_TXSTAT_RTRY equ 0x04000000 ; retry |
PCNET_TXSTAT_LCAR equ 0x08000000 ; lost carrier |
PCNET_TXSTAT_LCOL equ 0x10000000 ; late collision |
PCNET_TXSTAT_EXDEF equ 0x20000000 ; excessive deferrals |
PCNET_TXSTAT_UFLOW equ 0x40000000 ; transmit underrun |
PCNET_TXSTAT_BUFF equ 0x80000000 ; buffer error |
|
TXCTL_OWN equ 0x80000000 |
TXCTL_ERR equ 0x40000000 ; error summary |
TXCTL_ADD_FCS equ 0x20000000 ; add FCS to pkt |
TXCTL_MORE_LTINT equ 0x10000000 |
TXCTL_ONE equ 0x08000000 |
TXCTL_DEF equ 0x04000000 |
TXCTL_STP equ 0x02000000 |
TXCTL_ENP equ 0x01000000 |
TXCTL_BPE equ 0x00800000 |
TXCTL_MBO equ 0x0000F000 |
TXCTL_BUFSZ equ 0x00000FFF |
PCNET_TXCTL_OWN equ 0x80000000 |
PCNET_TXCTL_ERR equ 0x40000000 ; error summary |
PCNET_TXCTL_ADD_FCS equ 0x20000000 ; add FCS to pkt |
PCNET_TXCTL_MORE_LTINT equ 0x10000000 |
PCNET_TXCTL_ONE equ 0x08000000 |
PCNET_TXCTL_DEF equ 0x04000000 |
PCNET_TXCTL_STP equ 0x02000000 |
PCNET_TXCTL_ENP equ 0x01000000 |
PCNET_TXCTL_BPE equ 0x00800000 |
PCNET_TXCTL_MBO equ 0x0000F000 |
PCNET_TXCTL_BUFSZ equ 0x00000FFF |
|
MAX_ETH_FRAME_SIZE equ 1514 |
|
|
|
section '.flat' code readable align 16 |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
400,7 → 358,6 |
;; (standard driver proc) ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
align 4 |
proc START stdcall, state:dword |
|
cmp [state], 1 |
480,12 → 437,7 |
cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
jge .fail |
|
push edx |
stdcall KernelAlloc, device.size ; Allocate the buffer for eth_device structure |
pop edx |
test eax, eax |
jz .fail |
mov ebx, eax ; ebx is always used as a pointer to the structure (in driver, but also in kernel code) |
allocate_and_clear ebx, device_size, .fail |
|
; Fill in the direct call addresses into the struct |
|
515,8 → 467,8 |
DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ |
[device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 |
|
allocate_and_clear [device.tx_buffer], (RX_RING_SIZE * PKT_BUF_SZ), .err |
allocate_and_clear [device.rx_buffer], (TX_RING_SIZE * PKT_BUF_SZ), .err |
allocate_and_clear [device.tx_buffer], PCNET_RX_RING_SIZE * (PCNET_PKT_BUF_SZ + buf_head.size), .err |
allocate_and_clear [device.rx_buffer], PCNET_TX_RING_SIZE * (PCNET_PKT_BUF_SZ + buf_head.size), .err |
|
; Ok, the eth_device structure is ready, let's probe the device |
; Because initialization fires IRQ, IRQ handler must be aware of this device |
530,7 → 482,6 |
|
mov [device.type], NET_TYPE_ETH |
call NetRegDev |
|
cmp eax, -1 |
je .destroy |
|
551,6 → 502,7 |
|
.destroy: |
; todo: reset device into virgin state |
|
dec [devices] |
.err: |
DEBUGF 1,"Error, removing all data !\n" |
595,55 → 547,8 |
|
align 4 |
probe: |
mov edx, [device.io_addr] |
|
; make the device a bus master |
|
make_bus_master [device.pci_bus], [device.pci_dev] |
|
; create the RX-ring |
|
lea edi, [device.rx_ring] |
mov ecx, RX_RING_SIZE |
mov eax, [device.rx_buffer] |
call GetPgAddr |
.rx_init: |
mov [edi + buf_head.base], eax |
mov [edi + buf_head.length], - PKT_BUF_SZ |
mov [edi + buf_head.status], 0x8000 |
and dword [edi + buf_head.msg_length], 0 |
and dword [edi + buf_head.reserved], 0 |
add eax, PKT_BUF_SZ |
add edi, buf_head.size |
loop .rx_init |
|
lea eax, [device.rx_ring] |
GetRealAddr |
mov [device.rx_ring_phys], eax |
|
; create the Tx-ring |
|
lea edi, [device.tx_ring] |
mov ecx, TX_RING_SIZE |
mov eax, [device.tx_buffer] |
call GetPgAddr |
.tx_init: |
mov [edi + buf_head.base], eax |
and dword [edi + buf_head.length], 0 |
and dword [edi + buf_head.msg_length], 0 |
and dword [edi + buf_head.reserved], 0 |
add eax, PKT_BUF_SZ |
add edi, buf_head.size |
loop .tx_init |
|
lea eax, [device.tx_ring] |
GetRealAddr |
mov [device.tx_ring_phys], eax |
|
mov [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS) |
|
; First, we must try to use Word operations |
call switch_to_wio |
set_io 0 |
call wio_reset |
|
xor ecx, ecx |
653,26 → 558,22 |
|
; Try Word I/O |
mov ax, 88 |
set_io WIO_RAP |
add edx, PCNET_WIO_RAP |
out dx, ax |
nop |
nop |
in ax, dx |
set_io 0 |
sub edx, PCNET_WIO_RAP |
cmp ax, 88 |
jne .try_dwio |
|
DEBUGF 1,"Using WIO\n" |
|
call switch_to_wio |
|
jmp .L1 |
|
; If WIO fails, try to use DWIO |
.try_dwio: |
call dwio_reset |
|
set_io 0 |
xor ecx, ecx |
call dwio_read_csr |
cmp eax, 4 |
679,34 → 580,32 |
jne .no_dev |
|
; Try Dword I/O |
set_io DWIO_RAP |
add edx, PCNET_DWIO_RAP |
mov eax, 88 |
out dx, eax |
nop |
nop |
in eax, dx |
set_io 0 |
cmp ax, 88 |
sub edx, PCNET_DWIO_RAP |
and eax, 0xffff |
cmp eax, 88 |
jne .no_dev |
|
DEBUGF 1,"Using DWIO\n" |
|
call switch_to_dwio |
|
jmp .L1 |
|
; If both methods fail, something is wrong! |
.no_dev: |
DEBUGF 1,"PCnet device not found!\n" |
mov eax, -1 |
mov eax, 1 |
ret |
.L1: |
|
.L1: |
mov ecx, CSR_CHIPID0 |
mov ecx, PCNET_CSR_CHIPID0 |
call [device.access_read_csr] |
mov esi, eax |
|
mov ecx, CSR_CHIPID1 |
mov ecx, PCNET_CSR_CHIPID1 |
call [device.access_read_csr] |
shl eax, 16 |
or eax, esi |
720,8 → 619,7 |
and eax, 0xffff |
mov [device.chip_version], eax |
|
DEBUGF 1,"chip version: %x\n", eax |
|
DEBUGF 1,"chip version ok\n" |
mov [device.fdx], 0 |
mov [device.mii], 0 |
mov [device.fset], 0 |
778,9 → 676,9 |
.L8: |
mov [device.name], device_l8 |
; mov [device.fdx], 1 |
mov ecx, CSR_RXPOLL |
call [device.access_read_bcr] |
call [device.access_write_bcr] |
mov ecx, PCNET_CSR_RXPOLL |
call dword [device.access_read_bcr] |
call dword [device.access_write_bcr] |
jmp .L10 |
.L9: |
mov [device.name], device_l9 |
791,13 → 689,15 |
|
cmp [device.fset], 1 |
jne .L11 |
mov ecx, BCR_BUSCTL |
mov ecx, PCNET_BCR_BUSCTL |
call [device.access_read_bcr] |
or ax, 0x800 |
or eax, 0x800 |
call [device.access_write_bcr] |
|
mov ecx, CSR_DMACTL |
mov ecx, PCNET_CSR_DMACTL |
call [device.access_read_csr] |
; and eax, 0xc00 |
; or eax, 0xc00 |
mov eax, 0xc00 |
call [device.access_write_csr] |
|
805,24 → 705,23 |
mov [device.ltint],1 |
.L11: |
|
mov eax, PORT_ASEL ; Auto-select |
make_bus_master [device.pci_bus], [device.pci_dev] |
|
mov eax, PCNET_PORT_ASEL |
mov [device.options], eax |
mov [device.mode_], word 0x0003 |
mov [device.tlen_rlen], word (TX_RING_LEN_BITS or RX_RING_LEN_BITS) |
mov [device.tlen_rlen], word (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS) |
|
mov dword [device.filter], 0 |
mov dword [device.filter+4], 0 |
|
mov eax, IMR |
mov ecx, CSR_IMR ; Write interrupt mask |
mov eax, PCNET_IMR |
mov ecx, PCNET_CSR_IMR ; Write interrupt mask |
call [device.access_write_csr] |
|
|
align 4 |
reset: |
|
DEBUGF 1,"Resetting PCnet device: %x\n", ebx |
|
; attach int handler |
|
movzx eax, [device.irq_line] |
835,49 → 734,21 |
; ret |
@@: |
|
set_io 0 |
call [device.access_reset] ; after a reset, device will be in WIO mode! |
|
; Switch to dword operations |
|
DEBUGF 1,"Switching to 32-bit mode\n" |
|
mov ecx, DWIO_RDP |
xor eax, eax |
call wio_write_csr |
|
call switch_to_dwio |
|
; Lets find out if we are really in 32-bit mode now.. |
|
set_io 0 |
set_io DWIO_RAP |
mov eax, 88 |
out dx, eax |
nop |
nop |
in eax, dx |
set_io 0 |
cmp ax, 88 |
je .yes_dwio |
|
call switch_to_wio ; it seems to have failed, reset device again and use wio |
set_io 0 |
mov edx, [device.io_addr] |
call [device.access_reset] |
|
.yes_dwio: |
set_io 0 |
mov ecx, BCR_SSTYLE ; Select Software style 2 ;;; |
; Switch pcnet32 to 32bit mode |
mov ecx, PCNET_BCR_SSTYLE |
mov eax, 2 |
call [device.access_write_bcr] |
|
; set/reset autoselect bit |
mov ecx, BCR_MISCCFG |
mov ecx, PCNET_BCR_MISCCFG |
call [device.access_read_bcr] |
|
test [device.options], PORT_ASEL |
jnz .L1 |
and eax, not 2 |
test [device.options], PCNET_PORT_ASEL |
jz .L1 |
or eax, 2 |
.L1: |
call [device.access_write_bcr] |
|
885,24 → 756,24 |
; Handle full duplex setting |
cmp byte [device.full_duplex], 0 |
je .L2 |
mov ecx, BCR_DUPLEX |
mov ecx, PCNET_BCR_DUPLEX |
call [device.access_read_bcr] |
and eax, not 3 |
test [device.options], PORT_FD |
test [device.options], PCNET_PORT_FD |
jz .L3 |
or eax, 1 |
cmp [device.options], PORT_FD or PORT_AUI |
cmp [device.options], PCNET_PORT_FD or PCNET_PORT_AUI |
jne .L4 |
or eax, 2 |
jmp .L4 |
.L3: |
test [device.options], PORT_ASEL |
test [device.options], PCNET_PORT_ASEL |
jz .L4 |
cmp [device.chip_version], 0x2627 |
jne .L4 |
or eax, 3 |
.L4: |
mov ecx, BCR_DUPLEX |
mov ecx, PCNET_BCR_DUPLEX |
call [device.access_write_bcr] |
.L2: |
|
911,8 → 782,8 |
mov ecx, 124 |
call [device.access_read_csr] |
mov ecx, [device.options] |
and ecx, PORT_PORTSEL |
cmp ecx, PORT_GPSI |
and ecx, PCNET_PORT_PORTSEL |
cmp ecx, PCNET_PORT_GPSI |
jne .L5 |
or eax, 0x10 |
.L5: |
919,16 → 790,16 |
call [device.access_write_csr] |
cmp [device.mii], 0 |
je .L6 |
test [device.options], PORT_ASEL |
test [device.options], PCNET_PORT_ASEL |
jnz .L6 |
mov ecx, BCR_MIICTL |
mov ecx, PCNET_BCR_MIICTL |
call [device.access_read_bcr] |
and eax,not 0x38 |
test [device.options], PORT_FD |
test [device.options], PCNET_PORT_FD |
jz .L7 |
or eax, 0x10 |
.L7: |
test [device.options], PORT_100 |
test [device.options], PCNET_PORT_100 |
jz .L8 |
or eax, 0x08 |
.L8: |
935,9 → 806,9 |
call [device.access_write_bcr] |
jmp .L9 |
.L6: |
test [device.options], PORT_ASEL |
test [device.options], PCNET_PORT_ASEL |
jz .L9 |
mov ecx, BCR_MIICTL |
mov ecx, PCNET_BCR_MIICTL |
DEBUGF 1,"ASEL, enable auto-negotiation\n" |
call [device.access_read_bcr] |
and eax, not 0x98 |
952,7 → 823,7 |
call [device.access_write_csr] |
.L10: |
mov eax, [device.options] |
and eax, PORT_PORTSEL |
and eax,PCNET_PORT_PORTSEL |
shl eax, 7 |
mov [device.mode_], ax |
mov dword [device.filter], -1 |
965,8 → 836,11 |
movsd |
movsw |
|
call init_ring |
|
lea eax, [device.private] |
GetRealAddr |
|
push eax |
and eax, 0xffff |
mov ecx, 1 |
980,7 → 854,7 |
mov eax, 0x0915 |
call [device.access_write_csr] |
|
xor ecx, ecx |
mov ecx,0 |
mov eax, 1 |
call [device.access_write_csr] |
|
996,16 → 870,12 |
xor ecx, ecx |
call [device.access_read_csr] |
pop ecx |
push esi |
mov esi, 100 |
call Sleep |
pop esi |
test ax, 0x100 |
jnz .L12 |
loop .L11 |
.L12: |
|
DEBUGF 1,"Starting up device\n" |
DEBUGF 1,"hardware reset\n" |
xor ecx, ecx |
mov eax, 0x0002 |
call [device.access_write_csr] |
1014,19 → 884,53 |
call [device.access_read_csr] |
|
xor ecx, ecx |
mov eax, CSR_INTEN or CSR_START |
mov eax, PCNET_CSR_INTEN or PCNET_CSR_START |
call [device.access_write_csr] |
|
; Set the mtu, kernel will be able to send now |
mov [device.mtu], 1514 |
|
DEBUGF 1,"PCNET reset complete\n" |
xor eax, eax |
; clear packet/byte counters |
lea edi, [device.bytes_tx] |
mov ecx, 6 |
rep stosd |
ret |
|
; Set the mtu, kernel will be able to send now |
mov [device.mtu], 1514 |
|
align 4 |
init_ring: |
|
mov ecx, PCNET_RX_RING_SIZE |
mov edi, [device.rx_buffer] |
mov eax, edi |
GetRealAddr |
mov [device.rx_ring_phys], eax |
add eax, PCNET_RX_RING_SIZE * buf_head.size |
.rx_init: |
mov [edi + buf_head.base], eax |
mov [edi + buf_head.length], PCNET_PKT_BUF_SZ_NEG |
mov [edi + buf_head.status], 0x8000 |
and dword [edi + buf_head.msg_length], 0 |
and dword [edi + buf_head.reserved], 0 |
add eax, PCNET_PKT_BUF_SZ |
add edi, buf_head.size |
loop .rx_init |
|
mov ecx, PCNET_TX_RING_SIZE |
mov edi, [device.tx_buffer] |
mov eax, edi |
GetRealAddr |
mov [device.tx_ring_phys], eax |
add eax, PCNET_TX_RING_SIZE * buf_head.size |
.tx_init: |
mov [edi + buf_head.base], eax |
and dword [edi + buf_head.length], 0 |
and dword [edi + buf_head.msg_length], 0 |
and dword [edi + buf_head.reserved], 0 |
add eax, PCNET_PKT_BUF_SZ |
add edi, buf_head.size |
loop .tx_init |
|
mov [device.tlen_rlen], (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS) |
|
ret |
|
|
1058,15 → 962,14 |
|
; check descriptor |
movzx eax, [device.cur_tx] |
imul edi, eax, PKT_BUF_SZ |
imul edi, eax, PCNET_PKT_BUF_SZ |
shl eax, 4 |
add eax, [device.tx_buffer] |
add edi, [device.tx_buffer] |
add edi, PCNET_TX_RING_SIZE * buf_head.size |
|
lea eax, [eax + device.tx_ring] |
|
test byte [eax + buf_head.status + 1], 80h |
jnz .nospace |
|
; descriptor is free, copy data |
mov esi, [esp+4] |
mov ecx, [esp+8] |
1076,7 → 979,6 |
rep movsd |
mov ecx, edx |
rep movsb |
|
; set length |
mov ecx, [esp+8] |
neg ecx |
1087,7 → 989,7 |
; trigger an immediate send |
xor ecx, ecx ; CSR0 |
call [device.access_read_csr] |
or eax, CSR_TX |
or eax, PCNET_CSR_TX |
call [device.access_write_csr] |
|
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... |
1096,14 → 998,7 |
DEBUGF 2," - Packet Sent! " |
|
.finish: |
; update statistics |
inc [device.packets_tx] |
|
mov ecx, [esp+8] |
add dword [device.bytes_tx], ecx |
adc dword [device.bytes_tx + 4], 0 |
DEBUGF 2," - Done!\n" |
|
stdcall KernelFree, [esp+4] |
ret 8 |
|
1110,7 → 1005,6 |
.nospace: |
DEBUGF 1, 'ERROR: no free transmit descriptors\n' |
; todo: maybe somehow notify the kernel about the error? |
|
stdcall KernelFree, [esp+4] |
ret 8 |
|
1125,7 → 1019,7 |
align 4 |
int_handler: |
|
DEBUGF 1,"IRQ=%x ", eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO |
; DEBUGF 1,"IRQ %x ",eax:2 ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO |
|
; find pointer of device wich made IRQ occur |
|
1134,16 → 1028,16 |
test ecx, ecx |
jz .abort |
.nextdevice: |
mov ebx, [esi] |
set_io 0 |
mov ebx, dword [esi] |
mov edx, [device.io_addr] ; get IRQ reason |
|
push ecx |
xor ecx, ecx ; CSR0 |
call [device.access_read_csr] ; get IRQ reason |
call [device.access_read_csr] |
pop ecx |
|
test ax , ax |
jnz .got_it |
test al , al |
js .got_it |
|
add esi, 4 |
loop .nextdevice |
1151,7 → 1045,6 |
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver |
|
.got_it: |
DEBUGF 1,"csr=%x\n", ax |
;------------------------------------------------------- |
; Possible reasons: |
; initialization done - ignore |
1164,33 → 1057,30 |
call [device.access_write_csr] |
; Received packet ok? |
|
test ax, CSR_RINT |
test ax, PCNET_CSR_RINT |
jz @f |
|
push ax |
|
DEBUGF 1,"packet received!\n" |
|
.receiver_test_loop: |
movzx eax, [device.cur_rx] |
; and eax, RX_RING_MOD_MASK |
; and eax, PCNET_RX_RING_MOD_MASK |
mov edi, eax |
|
imul esi, eax, PKT_BUF_SZ ; |
imul esi, eax, PCNET_PKT_BUF_SZ ; |
add esi, [device.rx_buffer] ; esi now points to rx buffer |
add esi, PCNET_RX_RING_SIZE * buf_head.size |
|
shl edi, 4 ; desc * 16 (16 is size of one ring entry) |
lea edi, [edi + device.rx_ring] ; edi now points to current rx ring entry |
add edi, [device.rx_buffer] ; edi now points to current rx ring entry |
|
mov cx , [edi + buf_head.status] |
|
test cx , RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do |
test cx , PCNET_RXSTAT_OWN ; If this bit is set, the controller OWN's the packet, if not, we do |
jnz .abort |
|
test cx , RXSTAT_ENP |
test cx , PCNET_RXSTAT_ENP |
jz .abort |
|
test cx , RXSTAT_STP |
test cx , PCNET_RXSTAT_STP |
jz .abort |
|
movzx ecx, [edi + buf_head.msg_length] ; get packet length in ecx |
1206,54 → 1096,27 |
push ecx ; for eth_receiver |
push eax ; |
|
; update statistics |
inc [device.packets_rx] |
|
add dword [device.bytes_rx], ecx |
adc dword [device.bytes_rx + 4], 0 |
|
xchg edi, eax |
|
; copy packet data |
shr cx , 1 |
jnc .nb |
movsb |
.nb: |
shr cx , 1 |
jnc .nw |
movsw |
.nw: |
push ecx |
shr ecx, 2 |
cld |
rep movsd |
pop ecx |
and ecx, 3 |
rep movsb |
|
; mov word [eax + buf_head.length], PKT_BUF_SZ_NEG |
mov word [eax + buf_head.status], RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now) |
; mov word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG |
mov word [eax + buf_head.status], PCNET_RXSTAT_OWN ; Set OWN bit back to 1 (controller may write to tx-buffer again now) |
|
inc [device.cur_rx] ; update descriptor |
and [device.cur_rx], 3 ; |
|
DEBUGF 1,"Inserting packet\n" |
jmp EthReceiver ; Send the copied packet to kernel |
|
.abort: |
pop ax |
@@: |
|
test ax, IMR_TINT |
jz @f |
|
DEBUGF 1,"Transmit OK!\n" |
|
@@: |
|
test ax, IMR_MISS |
jz @f |
|
DEBUGF 1,"We missed a frame! (RX ring full?)\n" |
|
@@: |
|
DEBUGF 1,"done\n" |
|
ret |
|
|
1270,16 → 1133,17 |
|
DEBUGF 1,"Writing MAC: %x-%x-%x-%x-%x-%x",[esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2 |
|
set_io 0 |
; set_io 2 |
mov edx, [device.io_addr] |
add dx, 2 |
xor eax, eax |
mov ecx, CSR_PAR0 |
|
mov ecx, PCNET_CSR_PAR0 |
@@: |
pop ax |
call [device.access_write_csr] |
DEBUGF 1,"." |
inc ecx |
cmp ecx, CSR_PAR2 |
cmp ecx, PCNET_CSR_PAR2 |
jl @r |
|
DEBUGF 1,"\n" |
1291,12 → 1155,12 |
;; Read MAC address ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;; |
|
align 4 |
read_mac: |
DEBUGF 1,"Reading MAC" |
|
set_io 0 |
set_io 6 |
mov edx, [device.io_addr] |
add dx, 6 |
@@: |
dec dx |
dec dx |
1318,10 → 1182,11 |
|
ret |
|
|
align 4 |
switch_to_wio: |
DEBUGF 1,"Switch to WIO\n" |
|
DEBUGF 1,"Switching to 16-bit mode\n" |
|
mov [device.access_read_csr], wio_read_csr |
mov [device.access_write_csr], wio_write_csr |
mov [device.access_read_bcr], wio_read_bcr |
1332,9 → 1197,11 |
|
ret |
|
align 4 |
switch_to_dwio: |
DEBUGF 1,"Switch to DWIO\n" |
|
DEBUGF 1,"Switching to 32-bit mode\n" |
|
mov [device.access_read_csr], dwio_read_csr |
mov [device.access_write_csr], dwio_write_csr |
mov [device.access_read_bcr], dwio_read_bcr |
1346,21 → 1213,19 |
ret |
|
|
|
|
|
; ecx - index |
; return: |
; eax - data |
align 4 |
wio_read_csr: |
|
add edx, WIO_RAP |
add edx, PCNET_WIO_RAP |
mov ax , cx |
out dx , ax |
add edx, WIO_RDP - WIO_RAP |
add edx, PCNET_WIO_RDP - PCNET_WIO_RAP |
in ax , dx |
and eax, 0xffff |
sub edx, WIO_RDP |
sub edx, PCNET_WIO_RDP |
|
ret |
|
1367,15 → 1232,16 |
|
; eax - data |
; ecx - index |
align 4 |
wio_write_csr: |
|
add edx, WIO_RAP |
add edx, PCNET_WIO_RAP |
xchg eax, ecx |
out dx , ax |
xchg eax, ecx |
add edx, WIO_RDP - WIO_RAP |
add edx, PCNET_WIO_RDP - PCNET_WIO_RAP |
out dx , ax |
sub edx, WIO_RDP |
sub edx, PCNET_WIO_RDP |
|
ret |
|
1383,15 → 1249,16 |
; ecx - index |
; return: |
; eax - data |
align 4 |
wio_read_bcr: |
|
add edx, WIO_RAP |
add edx, PCNET_WIO_RAP |
mov ax , cx |
out dx , ax |
add edx, WIO_BDP - WIO_RAP |
add edx, PCNET_WIO_BDP - PCNET_WIO_RAP |
in ax , dx |
and eax, 0xffff |
sub edx, WIO_BDP |
sub edx, PCNET_WIO_BDP |
|
ret |
|
1398,60 → 1265,65 |
|
; eax - data |
; ecx - index |
align 4 |
wio_write_bcr: |
|
add edx, WIO_RAP |
add edx, PCNET_WIO_RAP |
xchg eax, ecx |
out dx , ax |
xchg eax, ecx |
add edx, WIO_BDP - WIO_RAP |
add edx, PCNET_WIO_BDP - PCNET_WIO_RAP |
out dx , ax |
sub edx, WIO_BDP |
sub edx, PCNET_WIO_BDP |
|
ret |
|
|
align 4 |
wio_read_rap: |
|
add edx, WIO_RAP |
add edx, PCNET_WIO_RAP |
in ax , dx |
and eax, 0xffff |
sub edx, WIO_RAP |
sub edx, PCNET_WIO_RAP |
|
ret |
|
; eax - val |
align 4 |
wio_write_rap: |
|
add edx, WIO_RAP |
add edx, PCNET_WIO_RAP |
out dx , ax |
sub edx, WIO_RAP |
sub edx, PCNET_WIO_RAP |
|
ret |
|
align 4 |
wio_reset: |
|
push eax |
add edx, WIO_RESET |
add edx, PCNET_WIO_RESET |
in ax , dx |
pop eax |
sub edx, WIO_RESET |
sub edx, PCNET_WIO_RESET |
|
ret |
|
|
|
; ecx - index |
; return: |
; eax - data |
align 4 |
dwio_read_csr: |
|
add edx, DWIO_RAP |
add edx, PCNET_DWIO_RAP |
mov eax, ecx |
out dx , eax |
add edx, DWIO_RDP - DWIO_RAP |
add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP |
in eax, dx |
and eax, 0xffff |
sub edx, DWIO_RDP |
sub edx, PCNET_DWIO_RDP |
|
ret |
|
1458,15 → 1330,16 |
|
; ecx - index |
; eax - data |
align 4 |
dwio_write_csr: |
|
add edx, DWIO_RAP |
add edx, PCNET_DWIO_RAP |
xchg eax, ecx |
out dx , eax |
add edx, DWIO_RDP - DWIO_RAP |
add edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP |
xchg eax, ecx |
out dx , eax |
sub edx, DWIO_RDP |
sub edx, PCNET_DWIO_RDP |
|
ret |
|
1473,15 → 1346,16 |
; ecx - index |
; return: |
; eax - data |
align 4 |
dwio_read_bcr: |
|
add edx, DWIO_RAP |
add edx, PCNET_DWIO_RAP |
mov eax, ecx |
out dx , eax |
add edx, DWIO_BDP - DWIO_RAP |
add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP |
in eax, dx |
and eax, 0xffff |
sub edx, DWIO_BDP |
sub edx, PCNET_DWIO_BDP |
|
ret |
|
1488,46 → 1362,48 |
|
; ecx - index |
; eax - data |
align 4 |
dwio_write_bcr: |
|
add edx, DWIO_RAP |
add edx, PCNET_DWIO_RAP |
xchg eax, ecx |
out dx , eax |
add edx, DWIO_BDP - DWIO_RAP |
add edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP |
xchg eax, ecx |
out dx , eax |
sub edx, DWIO_BDP |
sub edx, PCNET_DWIO_BDP |
|
ret |
|
|
align 4 |
dwio_read_rap: |
|
add edx, DWIO_RAP |
add edx, PCNET_DWIO_RAP |
in eax, dx |
and eax, 0xffff |
sub edx, DWIO_RAP |
sub edx, PCNET_DWIO_RAP |
|
ret |
|
|
; eax - val |
align 4 |
dwio_write_rap: |
|
add edx, DWIO_RAP |
add edx, PCNET_DWIO_RAP |
out dx , eax |
sub edx, DWIO_RAP |
sub edx, PCNET_DWIO_RAP |
|
ret |
|
|
align 4 |
dwio_reset: |
|
push eax |
add edx, DWIO_RESET |
add edx, PCNET_DWIO_RESET |
in eax, dx |
pop eax |
sub edx, DWIO_RESET |
sub edx, PCNET_DWIO_RESET |
|
ret |
|
1534,10 → 1410,11 |
|
|
; End of code |
|
align 4 ; Place all initialised data here |
|
devices dd 0 |
version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
my_service db 'PCnet',0 ; max 16 chars include zero |
|
device_l2 db "PCnet/PCI 79C970",0 |
1549,22 → 1426,22 |
device_l9 db "PCnet/FAST III 79C975",0 |
|
options_mapping: |
dd PORT_ASEL ; 0 Auto-select |
dd PORT_AUI ; 1 BNC/AUI |
dd PORT_AUI ; 2 AUI/BNC |
dd PORT_ASEL ; 3 not supported |
dd PORT_10BT or PORT_FD ; 4 10baseT-FD |
dd PORT_ASEL ; 5 not supported |
dd PORT_ASEL ; 6 not supported |
dd PORT_ASEL ; 7 not supported |
dd PORT_ASEL ; 8 not supported |
dd PORT_MII ; 9 MII 10baseT |
dd PORT_MII or PORT_FD ; 10 MII 10baseT-FD |
dd PORT_MII ; 11 MII (autosel) |
dd PORT_10BT ; 12 10BaseT |
dd PORT_MII or PORT_100 ; 13 MII 100BaseTx |
dd PORT_MII or PORT_100 or PORT_FD ; 14 MII 100BaseTx-FD |
dd PORT_ASEL ; 15 not supported |
dd PCNET_PORT_ASEL ; 0 Auto-select |
dd PCNET_PORT_AUI ; 1 BNC/AUI |
dd PCNET_PORT_AUI ; 2 AUI/BNC |
dd PCNET_PORT_ASEL ; 3 not supported |
dd PCNET_PORT_10BT or PCNET_PORT_FD ; 4 10baseT-FD |
dd PCNET_PORT_ASEL ; 5 not supported |
dd PCNET_PORT_ASEL ; 6 not supported |
dd PCNET_PORT_ASEL ; 7 not supported |
dd PCNET_PORT_ASEL ; 8 not supported |
dd PCNET_PORT_MII ; 9 MII 10baseT |
dd PCNET_PORT_MII or PCNET_PORT_FD ; 10 MII 10baseT-FD |
dd PCNET_PORT_MII ; 11 MII (autosel) |
dd PCNET_PORT_10BT ; 12 10BaseT |
dd PCNET_PORT_MII or PCNET_PORT_100 ; 13 MII 100BaseTx |
dd PCNET_PORT_MII or PCNET_PORT_100 or PCNET_PORT_FD ; 14 MII 100BaseTx-FD |
dd PCNET_PORT_ASEL ; 15 not supported |
|
include_debug_strings ; All data wich FDO uses will be included here |
|