Subversion Repositories Kolibri OS

Rev

Rev 2934 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2934 Rev 2935
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  i8254x driver for KolibriOS                                    ;;
6
;;  i8254x driver for KolibriOS                                    ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  based on i8254x.asm from baremetal os                          ;;
8
;;  based on i8254x.asm from baremetal os                          ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr (hidnplayr@gmail.com)                   ;;
10
;;    Written by hidnplayr (hidnplayr@gmail.com)                   ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
        ; TODO: make better use of the available descriptors
17
        ; TODO: make better use of the available descriptors
18
 
18
 
19
format MS COFF
19
format MS COFF
20
 
20
 
21
        API_VERSION             = 0x01000100
21
        API_VERSION             = 0x01000100
22
        DRIVER_VERSION          = 5
22
        DRIVER_VERSION          = 5
23
 
23
 
24
        MAX_DEVICES             = 16
24
        MAX_DEVICES             = 16
25
 
25
 
26
        DEBUG                   = 1
26
        DEBUG                   = 1
27
        __DEBUG__               = 1
27
        __DEBUG__               = 1
28
        __DEBUG_LEVEL__         = 1
28
        __DEBUG_LEVEL__         = 1
29
 
29
 
30
        MAX_PKT_SIZE            = 16384         ; Maximum packet size
30
        MAX_PKT_SIZE            = 16384         ; Maximum packet size
31
 
31
 
32
 
32
 
33
include 'proc32.inc'
33
include 'proc32.inc'
34
include 'imports.inc'
34
include 'imports.inc'
35
include 'fdo.inc'
35
include 'fdo.inc'
36
include '../struct.inc'
36
include '../struct.inc'
37
include 'netdrv.inc'
37
include 'netdrv.inc'
38
 
38
 
39
public START
39
public START
40
public service_proc
40
public service_proc
41
public version
41
public version
42
 
42
 
43
 
43
 
44
 
44
 
45
; Register list
45
; Register list
46
REG_CTRL                = 0x0000 ; Control Register
46
REG_CTRL                = 0x0000 ; Control Register
47
REG_STATUS              = 0x0008 ; Device Status Register
47
REG_STATUS              = 0x0008 ; Device Status Register
48
REG_CTRLEXT             = 0x0018 ; Extended Control Register
48
REG_CTRLEXT             = 0x0018 ; Extended Control Register
49
REG_MDIC                = 0x0020 ; MDI Control Register
49
REG_MDIC                = 0x0020 ; MDI Control Register
50
REG_FCAL                = 0x0028 ; Flow Control Address Low
50
REG_FCAL                = 0x0028 ; Flow Control Address Low
51
REG_FCAH                = 0x002C ; Flow Control Address High
51
REG_FCAH                = 0x002C ; Flow Control Address High
52
REG_FCT                 = 0x0030 ; Flow Control Type
52
REG_FCT                 = 0x0030 ; Flow Control Type
53
REG_VET                 = 0x0038 ; VLAN Ether Type
53
REG_VET                 = 0x0038 ; VLAN Ether Type
54
REG_ICR                 = 0x00C0 ; Interrupt Cause Read
54
REG_ICR                 = 0x00C0 ; Interrupt Cause Read
55
REG_ITR                 = 0x00C4 ; Interrupt Throttling Register
55
REG_ITR                 = 0x00C4 ; Interrupt Throttling Register
56
REG_ICS                 = 0x00C8 ; Interrupt Cause Set Register
56
REG_ICS                 = 0x00C8 ; Interrupt Cause Set Register
57
REG_IMS                 = 0x00D0 ; Interrupt Mask Set/Read Register
57
REG_IMS                 = 0x00D0 ; Interrupt Mask Set/Read Register
58
REG_IMC                 = 0x00D8 ; Interrupt Mask Clear Register
58
REG_IMC                 = 0x00D8 ; Interrupt Mask Clear Register
59
REG_RCTL                = 0x0100 ; Receive Control Register
59
REG_RCTL                = 0x0100 ; Receive Control Register
60
REG_FCTTV               = 0x0170 ; Flow Control Transmit Timer Value
60
REG_FCTTV               = 0x0170 ; Flow Control Transmit Timer Value
61
REG_TXCW                = 0x0178 ; Transmit Configuration Word
61
REG_TXCW                = 0x0178 ; Transmit Configuration Word
62
REG_RXCW                = 0x0180 ; Receive Configuration Word
62
REG_RXCW                = 0x0180 ; Receive Configuration Word
63
REG_TCTL                = 0x0400 ; Transmit Control Register
63
REG_TCTL                = 0x0400 ; Transmit Control Register
64
REG_TIPG                = 0x0410 ; Transmit Inter Packet Gap
64
REG_TIPG                = 0x0410 ; Transmit Inter Packet Gap
65
 
65
 
66
REG_LEDCTL              = 0x0E00 ; LED Control
66
REG_LEDCTL              = 0x0E00 ; LED Control
67
REG_PBA                 = 0x1000 ; Packet Buffer Allocation
67
REG_PBA                 = 0x1000 ; Packet Buffer Allocation
68
 
68
 
69
REG_RDBAL               = 0x2800 ; RX Descriptor Base Address Low
69
REG_RDBAL               = 0x2800 ; RX Descriptor Base Address Low
70
REG_RDBAH               = 0x2804 ; RX Descriptor Base Address High
70
REG_RDBAH               = 0x2804 ; RX Descriptor Base Address High
71
REG_RDLEN               = 0x2808 ; RX Descriptor Length
71
REG_RDLEN               = 0x2808 ; RX Descriptor Length
72
REG_RDH                 = 0x2810 ; RX Descriptor Head
72
REG_RDH                 = 0x2810 ; RX Descriptor Head
73
REG_RDT                 = 0x2818 ; RX Descriptor Tail
73
REG_RDT                 = 0x2818 ; RX Descriptor Tail
74
REG_RDTR                = 0x2820 ; RX Delay Timer Register
74
REG_RDTR                = 0x2820 ; RX Delay Timer Register
75
REG_RXDCTL              = 0x3828 ; RX Descriptor Control
75
REG_RXDCTL              = 0x3828 ; RX Descriptor Control
76
REG_RADV                = 0x282C ; RX Int. Absolute Delay Timer
76
REG_RADV                = 0x282C ; RX Int. Absolute Delay Timer
77
REG_RSRPD               = 0x2C00 ; RX Small Packet Detect Interrupt
77
REG_RSRPD               = 0x2C00 ; RX Small Packet Detect Interrupt
78
 
78
 
79
REG_TXDMAC              = 0x3000 ; TX DMA Control
79
REG_TXDMAC              = 0x3000 ; TX DMA Control
80
REG_TDBAL               = 0x3800 ; TX Descriptor Base Address Low
80
REG_TDBAL               = 0x3800 ; TX Descriptor Base Address Low
81
REG_TDBAH               = 0x3804 ; TX Descriptor Base Address High
81
REG_TDBAH               = 0x3804 ; TX Descriptor Base Address High
82
REG_TDLEN               = 0x3808 ; TX Descriptor Length
82
REG_TDLEN               = 0x3808 ; TX Descriptor Length
83
REG_TDH                 = 0x3810 ; TX Descriptor Head
83
REG_TDH                 = 0x3810 ; TX Descriptor Head
84
REG_TDT                 = 0x3818 ; TX Descriptor Tail
84
REG_TDT                 = 0x3818 ; TX Descriptor Tail
85
REG_TIDV                = 0x3820 ; TX Interrupt Delay Value
85
REG_TIDV                = 0x3820 ; TX Interrupt Delay Value
86
REG_TXDCTL              = 0x3828 ; TX Descriptor Control
86
REG_TXDCTL              = 0x3828 ; TX Descriptor Control
87
REG_TADV                = 0x382C ; TX Absolute Interrupt Delay Value
87
REG_TADV                = 0x382C ; TX Absolute Interrupt Delay Value
88
REG_TSPMT               = 0x3830 ; TCP Segmentation Pad & Min Threshold
88
REG_TSPMT               = 0x3830 ; TCP Segmentation Pad & Min Threshold
89
 
89
 
90
REG_RXCSUM              = 0x5000 ; RX Checksum Control
90
REG_RXCSUM              = 0x5000 ; RX Checksum Control
91
 
91
 
92
; Register list for i8254x
92
; Register list for i8254x
93
I82542_REG_RDTR         = 0x0108 ; RX Delay Timer Register
93
I82542_REG_RDTR         = 0x0108 ; RX Delay Timer Register
94
I82542_REG_RDBAL        = 0x0110 ; RX Descriptor Base Address Low
94
I82542_REG_RDBAL        = 0x0110 ; RX Descriptor Base Address Low
95
I82542_REG_RDBAH        = 0x0114 ; RX Descriptor Base Address High
95
I82542_REG_RDBAH        = 0x0114 ; RX Descriptor Base Address High
96
I82542_REG_RDLEN        = 0x0118 ; RX Descriptor Length
96
I82542_REG_RDLEN        = 0x0118 ; RX Descriptor Length
97
I82542_REG_RDH          = 0x0120 ; RDH for i82542
97
I82542_REG_RDH          = 0x0120 ; RDH for i82542
98
I82542_REG_RDT          = 0x0128 ; RDT for i82542
98
I82542_REG_RDT          = 0x0128 ; RDT for i82542
99
I82542_REG_TDBAL        = 0x0420 ; TX Descriptor Base Address Low
99
I82542_REG_TDBAL        = 0x0420 ; TX Descriptor Base Address Low
100
I82542_REG_TDBAH        = 0x0424 ; TX Descriptor Base Address Low
100
I82542_REG_TDBAH        = 0x0424 ; TX Descriptor Base Address Low
101
I82542_REG_TDLEN        = 0x0428 ; TX Descriptor Length
101
I82542_REG_TDLEN        = 0x0428 ; TX Descriptor Length
102
I82542_REG_TDH          = 0x0430 ; TDH for i82542
102
I82542_REG_TDH          = 0x0430 ; TDH for i82542
103
I82542_REG_TDT          = 0x0438 ; TDT for i82542
103
I82542_REG_TDT          = 0x0438 ; TDT for i82542
104
 
104
 
105
; CTRL - Control Register (0x0000)
105
; CTRL - Control Register (0x0000)
106
CTRL_FD                 = 0x00000001 ; Full Duplex
106
CTRL_FD                 = 0x00000001 ; Full Duplex
107
CTRL_LRST               = 0x00000008 ; Link Reset
107
CTRL_LRST               = 0x00000008 ; Link Reset
108
CTRL_ASDE               = 0x00000020 ; Auto-speed detection
108
CTRL_ASDE               = 0x00000020 ; Auto-speed detection
109
CTRL_SLU                = 0x00000040 ; Set Link Up
109
CTRL_SLU                = 0x00000040 ; Set Link Up
110
CTRL_ILOS               = 0x00000080 ; Invert Loss of Signal
110
CTRL_ILOS               = 0x00000080 ; Invert Loss of Signal
111
CTRL_SPEED_MASK         = 0x00000300 ; Speed selection
111
CTRL_SPEED_MASK         = 0x00000300 ; Speed selection
112
CTRL_SPEED_SHIFT        = 8
112
CTRL_SPEED_SHIFT        = 8
113
CTRL_FRCSPD             = 0x00000800 ; Force Speed
113
CTRL_FRCSPD             = 0x00000800 ; Force Speed
114
CTRL_FRCDPLX            = 0x00001000 ; Force Duplex
114
CTRL_FRCDPLX            = 0x00001000 ; Force Duplex
115
CTRL_SDP0_DATA          = 0x00040000 ; SDP0 data
115
CTRL_SDP0_DATA          = 0x00040000 ; SDP0 data
116
CTRL_SDP1_DATA          = 0x00080000 ; SDP1 data
116
CTRL_SDP1_DATA          = 0x00080000 ; SDP1 data
117
CTRL_SDP0_IODIR         = 0x00400000 ; SDP0 direction
117
CTRL_SDP0_IODIR         = 0x00400000 ; SDP0 direction
118
CTRL_SDP1_IODIR         = 0x00800000 ; SDP1 direction
118
CTRL_SDP1_IODIR         = 0x00800000 ; SDP1 direction
119
CTRL_RST                = 0x04000000 ; Device Reset
119
CTRL_RST                = 0x04000000 ; Device Reset
120
CTRL_RFCE               = 0x08000000 ; RX Flow Ctrl Enable
120
CTRL_RFCE               = 0x08000000 ; RX Flow Ctrl Enable
121
CTRL_TFCE               = 0x10000000 ; TX Flow Ctrl Enable
121
CTRL_TFCE               = 0x10000000 ; TX Flow Ctrl Enable
122
CTRL_VME                = 0x40000000 ; VLAN Mode Enable
122
CTRL_VME                = 0x40000000 ; VLAN Mode Enable
123
CTRL_PHY_RST            = 0x80000000 ; PHY reset
123
CTRL_PHY_RST            = 0x80000000 ; PHY reset
124
 
124
 
125
; STATUS - Device Status Register (0x0008)
125
; STATUS - Device Status Register (0x0008)
126
STATUS_FD               = 0x00000001 ; Full Duplex
126
STATUS_FD               = 0x00000001 ; Full Duplex
127
STATUS_LU               = 0x00000002 ; Link Up
127
STATUS_LU               = 0x00000002 ; Link Up
128
STATUS_TXOFF            = 0x00000010 ; Transmit paused
128
STATUS_TXOFF            = 0x00000010 ; Transmit paused
129
STATUS_TBIMODE          = 0x00000020 ; TBI Mode
129
STATUS_TBIMODE          = 0x00000020 ; TBI Mode
130
STATUS_SPEED_MASK       = 0x000000C0 ; Link Speed setting
130
STATUS_SPEED_MASK       = 0x000000C0 ; Link Speed setting
131
STATUS_SPEED_SHIFT      = 6
131
STATUS_SPEED_SHIFT      = 6
132
STATUS_ASDV_MASK        = 0x00000300 ; Auto Speed Detection
132
STATUS_ASDV_MASK        = 0x00000300 ; Auto Speed Detection
133
STATUS_ASDV_SHIFT       = 8
133
STATUS_ASDV_SHIFT       = 8
134
STATUS_PCI66            = 0x00000800 ; PCI bus speed
134
STATUS_PCI66            = 0x00000800 ; PCI bus speed
135
STATUS_BUS64            = 0x00001000 ; PCI bus width
135
STATUS_BUS64            = 0x00001000 ; PCI bus width
136
STATUS_PCIX_MODE        = 0x00002000 ; PCI-X mode
136
STATUS_PCIX_MODE        = 0x00002000 ; PCI-X mode
137
STATUS_PCIXSPD_MASK     = 0x0000C000 ; PCI-X speed
137
STATUS_PCIXSPD_MASK     = 0x0000C000 ; PCI-X speed
138
STATUS_PCIXSPD_SHIFT    = 14
138
STATUS_PCIXSPD_SHIFT    = 14
139
 
139
 
140
; CTRL_EXT - Extended Device Control Register (0x0018)
140
; CTRL_EXT - Extended Device Control Register (0x0018)
141
CTRLEXT_PHY_INT         = 0x00000020 ; PHY interrupt
141
CTRLEXT_PHY_INT         = 0x00000020 ; PHY interrupt
142
CTRLEXT_SDP6_DATA       = 0x00000040 ; SDP6 data
142
CTRLEXT_SDP6_DATA       = 0x00000040 ; SDP6 data
143
CTRLEXT_SDP7_DATA       = 0x00000080 ; SDP7 data
143
CTRLEXT_SDP7_DATA       = 0x00000080 ; SDP7 data
144
CTRLEXT_SDP6_IODIR      = 0x00000400 ; SDP6 direction
144
CTRLEXT_SDP6_IODIR      = 0x00000400 ; SDP6 direction
145
CTRLEXT_SDP7_IODIR      = 0x00000800 ; SDP7 direction
145
CTRLEXT_SDP7_IODIR      = 0x00000800 ; SDP7 direction
146
CTRLEXT_ASDCHK          = 0x00001000 ; Auto-Speed Detect Chk
146
CTRLEXT_ASDCHK          = 0x00001000 ; Auto-Speed Detect Chk
147
CTRLEXT_EE_RST          = 0x00002000 ; EEPROM reset
147
CTRLEXT_EE_RST          = 0x00002000 ; EEPROM reset
148
CTRLEXT_SPD_BYPS        = 0x00008000 ; Speed Select Bypass
148
CTRLEXT_SPD_BYPS        = 0x00008000 ; Speed Select Bypass
149
CTRLEXT_RO_DIS          = 0x00020000 ; Relaxed Ordering Dis.
149
CTRLEXT_RO_DIS          = 0x00020000 ; Relaxed Ordering Dis.
150
CTRLEXT_LNKMOD_MASK     = 0x00C00000 ; Link Mode
150
CTRLEXT_LNKMOD_MASK     = 0x00C00000 ; Link Mode
151
CTRLEXT_LNKMOD_SHIFT    = 22
151
CTRLEXT_LNKMOD_SHIFT    = 22
152
 
152
 
153
; MDIC - MDI Control Register (0x0020)
153
; MDIC - MDI Control Register (0x0020)
154
MDIC_DATA_MASK          = 0x0000FFFF ; Data
154
MDIC_DATA_MASK          = 0x0000FFFF ; Data
155
MDIC_REG_MASK           = 0x001F0000 ; PHY Register
155
MDIC_REG_MASK           = 0x001F0000 ; PHY Register
156
MDIC_REG_SHIFT          = 16
156
MDIC_REG_SHIFT          = 16
157
MDIC_PHY_MASK           = 0x03E00000 ; PHY Address
157
MDIC_PHY_MASK           = 0x03E00000 ; PHY Address
158
MDIC_PHY_SHIFT          = 21
158
MDIC_PHY_SHIFT          = 21
159
MDIC_OP_MASK            = 0x0C000000 ; Opcode
159
MDIC_OP_MASK            = 0x0C000000 ; Opcode
160
MDIC_OP_SHIFT           = 26
160
MDIC_OP_SHIFT           = 26
161
MDIC_R                  = 0x10000000 ; Ready
161
MDIC_R                  = 0x10000000 ; Ready
162
MDIC_I                  = 0x20000000 ; Interrupt Enable
162
MDIC_I                  = 0x20000000 ; Interrupt Enable
163
MDIC_E                  = 0x40000000 ; Error
163
MDIC_E                  = 0x40000000 ; Error
164
 
164
 
165
; ICR - Interrupt Cause Read (0x00c0)
165
; ICR - Interrupt Cause Read (0x00c0)
166
ICR_TXDW                = 0x00000001 ; TX Desc Written back
166
ICR_TXDW                = 0x00000001 ; TX Desc Written back
167
ICR_TXQE                = 0x00000002 ; TX Queue Empty
167
ICR_TXQE                = 0x00000002 ; TX Queue Empty
168
ICR_LSC                 = 0x00000004 ; Link Status Change
168
ICR_LSC                 = 0x00000004 ; Link Status Change
169
ICR_RXSEQ               = 0x00000008 ; RX S=  ence Error
169
ICR_RXSEQ               = 0x00000008 ; RX S=  ence Error
170
ICR_RXDMT0              = 0x00000010 ; RX Desc min threshold reached
170
ICR_RXDMT0              = 0x00000010 ; RX Desc min threshold reached
171
ICR_RXO                 = 0x00000040 ; RX Overrun
171
ICR_RXO                 = 0x00000040 ; RX Overrun
172
ICR_RXT0                = 0x00000080 ; RX Timer Interrupt
172
ICR_RXT0                = 0x00000080 ; RX Timer Interrupt
173
ICR_MDAC                = 0x00000200 ; MDIO Access Complete
173
ICR_MDAC                = 0x00000200 ; MDIO Access Complete
174
ICR_RXCFG               = 0x00000400
174
ICR_RXCFG               = 0x00000400
175
ICR_PHY_INT             = 0x00001000 ; PHY Interrupt
175
ICR_PHY_INT             = 0x00001000 ; PHY Interrupt
176
ICR_GPI_SDP6            = 0x00002000 ; GPI on SDP6
176
ICR_GPI_SDP6            = 0x00002000 ; GPI on SDP6
177
ICR_GPI_SDP7            = 0x00004000 ; GPI on SDP7
177
ICR_GPI_SDP7            = 0x00004000 ; GPI on SDP7
178
ICR_TXD_LOW             = 0x00008000 ; TX Desc low threshold hit
178
ICR_TXD_LOW             = 0x00008000 ; TX Desc low threshold hit
179
ICR_SRPD                = 0x00010000 ; Small RX packet detected
179
ICR_SRPD                = 0x00010000 ; Small RX packet detected
180
 
180
 
181
; RCTL - Receive Control Register (0x0100)
181
; RCTL - Receive Control Register (0x0100)
182
RCTL_EN                 = 0x00000002 ; Receiver Enable
182
RCTL_EN                 = 0x00000002 ; Receiver Enable
183
RCTL_SBP                = 0x00000004 ; Store Bad Packets
183
RCTL_SBP                = 0x00000004 ; Store Bad Packets
184
RCTL_UPE                = 0x00000008 ; Unicast Promiscuous Enabled
184
RCTL_UPE                = 0x00000008 ; Unicast Promiscuous Enabled
185
RCTL_MPE                = 0x00000010 ; Xcast Promiscuous Enabled
185
RCTL_MPE                = 0x00000010 ; Xcast Promiscuous Enabled
186
RCTL_LPE                = 0x00000020 ; Long Packet Reception Enable
186
RCTL_LPE                = 0x00000020 ; Long Packet Reception Enable
187
RCTL_LBM_MASK           = 0x000000C0 ; Loopback Mode
187
RCTL_LBM_MASK           = 0x000000C0 ; Loopback Mode
188
RCTL_LBM_SHIFT          = 6
188
RCTL_LBM_SHIFT          = 6
189
RCTL_RDMTS_MASK         = 0x00000300 ; RX Desc Min Threshold Size
189
RCTL_RDMTS_MASK         = 0x00000300 ; RX Desc Min Threshold Size
190
RCTL_RDMTS_SHIFT        = 8
190
RCTL_RDMTS_SHIFT        = 8
191
RCTL_MO_MASK            = 0x00003000 ; Multicast Offset
191
RCTL_MO_MASK            = 0x00003000 ; Multicast Offset
192
RCTL_MO_SHIFT           = 12
192
RCTL_MO_SHIFT           = 12
193
RCTL_BAM                = 0x00008000 ; Broadcast Accept Mode
193
RCTL_BAM                = 0x00008000 ; Broadcast Accept Mode
194
RCTL_BSIZE_MASK         = 0x00030000 ; RX Buffer Size
194
RCTL_BSIZE_MASK         = 0x00030000 ; RX Buffer Size
195
RCTL_BSIZE_SHIFT        = 16
195
RCTL_BSIZE_SHIFT        = 16
196
RCTL_VFE                = 0x00040000 ; VLAN Filter Enable
196
RCTL_VFE                = 0x00040000 ; VLAN Filter Enable
197
RCTL_CFIEN              = 0x00080000 ; CFI Enable
197
RCTL_CFIEN              = 0x00080000 ; CFI Enable
198
RCTL_CFI                = 0x00100000 ; Canonical Form Indicator Bit
198
RCTL_CFI                = 0x00100000 ; Canonical Form Indicator Bit
199
RCTL_DPF                = 0x00400000 ; Discard Pause Frames
199
RCTL_DPF                = 0x00400000 ; Discard Pause Frames
200
RCTL_PMCF               = 0x00800000 ; Pass MAC Control Frames
200
RCTL_PMCF               = 0x00800000 ; Pass MAC Control Frames
201
RCTL_BSEX               = 0x02000000 ; Buffer Size Extension
201
RCTL_BSEX               = 0x02000000 ; Buffer Size Extension
202
RCTL_SECRC              = 0x04000000 ; Strip Ethernet CRC
202
RCTL_SECRC              = 0x04000000 ; Strip Ethernet CRC
203
 
203
 
204
; TCTL - Transmit Control Register (0x0400)
204
; TCTL - Transmit Control Register (0x0400)
205
TCTL_EN                 = 0x00000002 ; Transmit Enable
205
TCTL_EN                 = 0x00000002 ; Transmit Enable
206
TCTL_PSP                = 0x00000008 ; Pad short packets
206
TCTL_PSP                = 0x00000008 ; Pad short packets
207
TCTL_SWXOFF             = 0x00400000 ; Software XOFF Transmission
207
TCTL_SWXOFF             = 0x00400000 ; Software XOFF Transmission
208
 
208
 
209
; PBA - Packet Buffer Allocation (0x1000)
209
; PBA - Packet Buffer Allocation (0x1000)
210
PBA_RXA_MASK            = 0x0000FFFF ; RX Packet Buffer
210
PBA_RXA_MASK            = 0x0000FFFF ; RX Packet Buffer
211
PBA_RXA_SHIFT           = 0
211
PBA_RXA_SHIFT           = 0
212
PBA_TXA_MASK            = 0xFFFF0000 ; TX Packet Buffer
212
PBA_TXA_MASK            = 0xFFFF0000 ; TX Packet Buffer
213
PBA_TXA_SHIFT           = 16
213
PBA_TXA_SHIFT           = 16
214
 
214
 
215
; Flow Control Type
215
; Flow Control Type
216
FCT_TYPE_DEFAULT        = 0x8808
216
FCT_TYPE_DEFAULT        = 0x8808
217
 
217
 
218
; === TX Descriptor fields ===
218
; === TX Descriptor fields ===
219
 
219
 
220
; TX Packet Length (word 2)
220
; TX Packet Length (word 2)
221
TXDESC_LEN_MASK         = 0x0000ffff
221
TXDESC_LEN_MASK         = 0x0000ffff
222
 
222
 
223
; TX Descriptor CMD field (word 2)
223
; TX Descriptor CMD field (word 2)
224
TXDESC_IDE              = 0x80000000 ; Interrupt Delay Enable
224
TXDESC_IDE              = 0x80000000 ; Interrupt Delay Enable
225
TXDESC_VLE              = 0x40000000 ; VLAN Packet Enable
225
TXDESC_VLE              = 0x40000000 ; VLAN Packet Enable
226
TXDESC_DEXT             = 0x20000000 ; Extension
226
TXDESC_DEXT             = 0x20000000 ; Extension
227
TXDESC_RPS              = 0x10000000 ; Report Packet Sent
227
TXDESC_RPS              = 0x10000000 ; Report Packet Sent
228
TXDESC_RS               = 0x08000000 ; Report Status
228
TXDESC_RS               = 0x08000000 ; Report Status
229
TXDESC_IC               = 0x04000000 ; Insert Checksum
229
TXDESC_IC               = 0x04000000 ; Insert Checksum
230
TXDESC_IFCS             = 0x02000000 ; Insert FCS
230
TXDESC_IFCS             = 0x02000000 ; Insert FCS
231
TXDESC_EOP              = 0x01000000 ; End Of Packet
231
TXDESC_EOP              = 0x01000000 ; End Of Packet
232
 
232
 
233
; TX Descriptor STA field (word 3)
233
; TX Descriptor STA field (word 3)
234
TXDESC_TU               = 0x00000008 ; Transmit Underrun
234
TXDESC_TU               = 0x00000008 ; Transmit Underrun
235
TXDESC_LC               = 0x00000004 ; Late Collision
235
TXDESC_LC               = 0x00000004 ; Late Collision
236
TXDESC_EC               = 0x00000002 ; Excess Collisions
236
TXDESC_EC               = 0x00000002 ; Excess Collisions
237
TXDESC_DD               = 0x00000001 ; Descriptor Done
237
TXDESC_DD               = 0x00000001 ; Descriptor Done
238
 
238
 
239
; === RX Descriptor fields ===
239
; === RX Descriptor fields ===
240
 
240
 
241
; RX Packet Length (word 2)
241
; RX Packet Length (word 2)
242
RXDESC_LEN_MASK         = 0x0000ffff
242
RXDESC_LEN_MASK         = 0x0000ffff
243
 
243
 
244
; RX Descriptor STA field (word 3)
244
; RX Descriptor STA field (word 3)
245
RXDESC_PIF              = 0x00000080 ; Passed In-exact Filter
245
RXDESC_PIF              = 0x00000080 ; Passed In-exact Filter
246
RXDESC_IPCS             = 0x00000040 ; IP cksum calculated
246
RXDESC_IPCS             = 0x00000040 ; IP cksum calculated
247
RXDESC_TCPCS            = 0x00000020 ; TCP cksum calculated
247
RXDESC_TCPCS            = 0x00000020 ; TCP cksum calculated
248
RXDESC_VP               = 0x00000008 ; Packet is 802.1Q
248
RXDESC_VP               = 0x00000008 ; Packet is 802.1Q
249
RXDESC_IXSM             = 0x00000004 ; Ignore cksum indication
249
RXDESC_IXSM             = 0x00000004 ; Ignore cksum indication
250
RXDESC_EOP              = 0x00000002 ; End Of Packet
250
RXDESC_EOP              = 0x00000002 ; End Of Packet
251
RXDESC_DD               = 0x00000001 ; Descriptor Done
251
RXDESC_DD               = 0x00000001 ; Descriptor Done
252
 
252
 
253
 
253
 
254
virtual at ebx
254
virtual at ebx
255
        device:
255
        device:
256
        ETH_DEVICE
256
        ETH_DEVICE
257
 
257
 
258
        .mmio_addr      dd ?
258
        .mmio_addr      dd ?
259
        .pci_bus        dd ?
259
        .pci_bus        dd ?
260
        .pci_dev        dd ?
260
        .pci_dev        dd ?
261
        .irq_line       db ?
261
        .irq_line       db ?
262
 
262
 
263
        .cur_tx         dd ?
263
        .cur_tx         dd ?
264
        .last_tx        dd ?
264
        .last_tx        dd ?
265
 
265
 
266
                        rb 0x100 - (($ - device) and 0xff)
266
                        rb 0x100 - (($ - device) and 0xff)
267
        .rx_desc        rd 256/8
267
        .rx_desc        rd 256/8
268
 
268
 
269
                        rb 0x100 - (($ - device) and 0xff)
269
                        rb 0x100 - (($ - device) and 0xff)
270
        .tx_desc        rd 256/8
270
        .tx_desc        rd 256/8
271
 
271
 
272
        sizeof.device_struct = $ - device
272
        sizeof.device_struct = $ - device
273
 
273
 
274
end virtual
274
end virtual
275
 
275
 
276
section '.flat' code readable align 16
276
section '.flat' code readable align 16
277
 
277
 
278
 
278
 
279
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
279
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
280
;;                        ;;
280
;;                        ;;
281
;; proc START             ;;
281
;; proc START             ;;
282
;;                        ;;
282
;;                        ;;
283
;; (standard driver proc) ;;
283
;; (standard driver proc) ;;
284
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
284
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
285
 
285
 
286
align 4
286
align 4
287
proc START stdcall, state:dword
287
proc START stdcall, state:dword
288
 
288
 
289
        cmp [state], 1
289
        cmp [state], 1
290
        jne .exit
290
        jne .exit
291
 
291
 
292
  .entry:
292
  .entry:
293
 
293
 
294
        DEBUGF  2,"Loading %s driver\n", my_service
294
        DEBUGF  2,"Loading %s driver\n", my_service
295
        stdcall RegService, my_service, service_proc
295
        stdcall RegService, my_service, service_proc
296
        ret
296
        ret
297
 
297
 
298
  .fail:
298
  .fail:
299
  .exit:
299
  .exit:
300
        xor eax, eax
300
        xor eax, eax
301
        ret
301
        ret
302
 
302
 
303
endp
303
endp
304
 
304
 
305
 
305
 
306
 
306
 
307
 
307
 
308
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
308
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
309
;;                        ;;
309
;;                        ;;
310
;; proc SERVICE_PROC      ;;
310
;; proc SERVICE_PROC      ;;
311
;;                        ;;
311
;;                        ;;
312
;; (standard driver proc) ;;
312
;; (standard driver proc) ;;
313
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
313
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314
 
314
 
315
align 4
315
align 4
316
proc service_proc stdcall, ioctl:dword
316
proc service_proc stdcall, ioctl:dword
317
 
317
 
318
        mov     edx, [ioctl]
318
        mov     edx, [ioctl]
319
        mov     eax, [IOCTL.io_code]
319
        mov     eax, [IOCTL.io_code]
320
 
320
 
321
;------------------------------------------------------
321
;------------------------------------------------------
322
 
322
 
323
        cmp     eax, 0 ;SRV_GETVERSION
323
        cmp     eax, 0 ;SRV_GETVERSION
324
        jne     @F
324
        jne     @F
325
 
325
 
326
        cmp     [IOCTL.out_size], 4
326
        cmp     [IOCTL.out_size], 4
327
        jl      .fail
327
        jl      .fail
328
        mov     eax, [IOCTL.output]
328
        mov     eax, [IOCTL.output]
329
        mov     [eax], dword API_VERSION
329
        mov     [eax], dword API_VERSION
330
 
330
 
331
        xor     eax, eax
331
        xor     eax, eax
332
        ret
332
        ret
333
 
333
 
334
;------------------------------------------------------
334
;------------------------------------------------------
335
  @@:
335
  @@:
336
        cmp     eax, 1 ;SRV_HOOK
336
        cmp     eax, 1 ;SRV_HOOK
337
        jne     .fail
337
        jne     .fail
338
 
338
 
339
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
339
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
340
        jl      .fail
340
        jl      .fail
341
 
341
 
342
        mov     eax, [IOCTL.input]
342
        mov     eax, [IOCTL.input]
343
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
343
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
344
        jne     .fail                                   ; other types arent supported for this card yet
344
        jne     .fail                                   ; other types arent supported for this card yet
345
 
345
 
346
; check if the device is already listed
346
; check if the device is already listed
347
 
347
 
348
        mov     esi, device_list
348
        mov     esi, device_list
349
        mov     ecx, [devices]
349
        mov     ecx, [devices]
350
        test    ecx, ecx
350
        test    ecx, ecx
351
        jz      .firstdevice
351
        jz      .firstdevice
352
 
352
 
353
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
353
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
354
        mov     ax, [eax+1]                             ;
354
        mov     ax, [eax+1]                             ;
355
  .nextdevice:
355
  .nextdevice:
356
        mov     ebx, [esi]
356
        mov     ebx, [esi]
357
        cmp     al, byte [device.pci_bus]
357
        cmp     al, byte [device.pci_bus]
358
        jne     .next
358
        jne     .next
359
        cmp     ah, byte [device.pci_dev]
359
        cmp     ah, byte [device.pci_dev]
360
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
360
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
361
  .next:
361
  .next:
362
        add     esi, 4
362
        add     esi, 4
363
        loop    .nextdevice
363
        loop    .nextdevice
364
 
364
 
365
 
365
 
366
; This device doesnt have its own eth_device structure yet, lets create one
366
; This device doesnt have its own eth_device structure yet, lets create one
367
  .firstdevice:
367
  .firstdevice:
368
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
368
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
369
        jge     .fail
369
        jge     .fail
370
 
370
 
371
        allocate_and_clear ebx, sizeof.device_struct, .fail      ; Allocate the buffer for device structure
371
        allocate_and_clear ebx, sizeof.device_struct, .fail      ; Allocate the buffer for device structure
372
 
372
 
373
; Fill in the direct call addresses into the struct
373
; Fill in the direct call addresses into the struct
374
 
374
 
375
        mov     [device.reset], reset
375
        mov     [device.reset], reset
376
        mov     [device.transmit], transmit
376
        mov     [device.transmit], transmit
377
        mov     [device.get_MAC], read_mac
377
        mov     [device.get_MAC], read_mac
378
        mov     [device.set_MAC], .fail
378
        mov     [device.set_MAC], .fail
379
        mov     [device.unload], unload
379
        mov     [device.unload], unload
380
        mov     [device.name], my_service
380
        mov     [device.name], my_service
381
 
381
 
382
; save the pci bus and device numbers
382
; save the pci bus and device numbers
383
 
383
 
384
        mov     eax, [IOCTL.input]
384
        mov     eax, [IOCTL.input]
385
        movzx   ecx, byte [eax+1]
385
        movzx   ecx, byte [eax+1]
386
        mov     [device.pci_bus], ecx
386
        mov     [device.pci_bus], ecx
387
        movzx   ecx, byte [eax+2]
387
        movzx   ecx, byte [eax+2]
388
        mov     [device.pci_dev], ecx
388
        mov     [device.pci_dev], ecx
389
 
389
 
390
; Now, it's time to find the base mmio addres of the PCI device
390
; Now, it's time to find the base mmio addres of the PCI device
391
 
391
 
392
        find_mmio32 [device.pci_bus], [device.pci_dev], [device.mmio_addr]
392
        find_mmio32 [device.pci_bus], [device.pci_dev], [device.mmio_addr]
393
 
393
 
394
; Create virtual mapping of the physical memory
394
; Create virtual mapping of the physical memory
395
 
395
 
396
        push    1Bh             ; PG_SW+PG_NOCACHE
396
        push    1Bh             ; PG_SW+PG_NOCACHE
397
        push    10000h          ; size of the map
397
        push    10000h          ; size of the map
398
        push    eax
398
        push    eax
399
        call    MapIoMem
399
        call    MapIoMem
400
        mov     [device.mmio_addr], eax
400
        mov     [device.mmio_addr], eax
401
 
401
 
402
; We've found the mmio address, find IRQ now
402
; We've found the mmio address, find IRQ now
403
 
403
 
404
        find_irq byte [device.pci_bus], byte [device.pci_dev], [device.irq_line]
404
        find_irq byte [device.pci_bus], byte [device.pci_dev], [device.irq_line]
405
 
405
 
406
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
406
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
407
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.mmio_addr]:8
407
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.mmio_addr]:8
408
 
408
 
409
; Ok, the eth_device structure is ready, let's probe the device
409
; Ok, the eth_device structure is ready, let's probe the device
410
        call    probe                                                   ; this function will output in eax
410
        call    probe                                                   ; this function will output in eax
411
        test    eax, eax
411
        test    eax, eax
412
        jnz     .err                                                    ; If an error occured, exit
412
        jnz     .err                                                    ; If an error occured, exit
413
 
413
 
414
        mov     eax, [devices]                                          ; Add the device structure to our device list
414
        mov     eax, [devices]                                          ; Add the device structure to our device list
415
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
415
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
416
        inc     [devices]                                               ;
416
        inc     [devices]                                               ;
417
 
417
 
418
        call    start_i8254x
418
        call    start_i8254x
419
 
419
 
420
        mov     [device.type], NET_TYPE_ETH
420
        mov     [device.type], NET_TYPE_ETH
421
        call    NetRegDev
421
        call    NetRegDev
422
 
422
 
423
        cmp     eax, -1
423
        cmp     eax, -1
424
        je      .destroy
424
        je      .destroy
425
 
425
 
426
        ret
426
        ret
427
 
427
 
428
; If the device was already loaded, find the device number and return it in eax
428
; If the device was already loaded, find the device number and return it in eax
429
 
429
 
430
  .find_devicenum:
430
  .find_devicenum:
431
        DEBUGF  1,"Trying to find device number of already registered device\n"
431
        DEBUGF  1,"Trying to find device number of already registered device\n"
432
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
432
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
433
                                                                        ; into a device number in edi
433
                                                                        ; into a device number in edi
434
        mov     eax, edi                                                ; Application wants it in eax instead
434
        mov     eax, edi                                                ; Application wants it in eax instead
435
        DEBUGF  1,"Kernel says: %u\n", eax
435
        DEBUGF  1,"Kernel says: %u\n", eax
436
        ret
436
        ret
437
 
437
 
438
; If an error occured, remove all allocated data and exit (returning -1 in eax)
438
; If an error occured, remove all allocated data and exit (returning -1 in eax)
439
 
439
 
440
  .destroy:
440
  .destroy:
441
        ; todo: reset device into virgin state
441
        ; todo: reset device into virgin state
442
 
442
 
443
  .err:
443
  .err:
444
        stdcall KernelFree, ebx
444
        stdcall KernelFree, ebx
445
 
445
 
446
  .fail:
446
  .fail:
447
        or      eax, -1
447
        or      eax, -1
448
        ret
448
        ret
449
 
449
 
450
;------------------------------------------------------
450
;------------------------------------------------------
451
endp
451
endp
452
 
452
 
453
 
453
 
454
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
454
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
455
;;                                                                        ;;
455
;;                                                                        ;;
456
;;        Actual Hardware dependent code starts here                      ;;
456
;;        Actual Hardware dependent code starts here                      ;;
457
;;                                                                        ;;
457
;;                                                                        ;;
458
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
458
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
459
 
459
 
460
 
460
 
461
align 4
461
align 4
462
unload:
462
unload:
463
        ; TODO: (in this particular order)
463
        ; TODO: (in this particular order)
464
        ;
464
        ;
465
        ; - Stop the device
465
        ; - Stop the device
466
        ; - Detach int handler
466
        ; - Detach int handler
467
        ; - Remove device from local list (device_list)
467
        ; - Remove device from local list (device_list)
468
        ; - call unregister function in kernel
468
        ; - call unregister function in kernel
469
        ; - Remove all allocated structures and buffers the card used
469
        ; - Remove all allocated structures and buffers the card used
470
 
470
 
471
        or      eax, -1
471
        or      eax, -1
472
 
472
 
473
ret
473
ret
474
 
474
 
475
 
475
 
476
 
476
 
477
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
478
;;
478
;;
479
;;  probe: enables the device (if it really is I8254X)
479
;;  probe: enables the device (if it really is I8254X)
480
;;
480
;;
481
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
481
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
482
align 4
482
align 4
483
probe:
483
probe:
484
 
484
 
485
        DEBUGF  1,"Probe\n"
485
        DEBUGF  1,"Probe\n"
486
 
486
 
487
        make_bus_master byte [device.pci_bus], byte [device.pci_dev]
487
        make_bus_master byte [device.pci_bus], byte [device.pci_dev]
488
 
488
 
489
        ; TODO: validate the device
489
        ; TODO: validate the device
490
 
490
 
491
        call    read_mac
491
        call    read_mac
492
 
492
 
493
        movzx   eax, [device.irq_line]
493
        movzx   eax, [device.irq_line]
494
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
494
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
495
        stdcall AttachIntHandler, eax, int_handler, dword 0
495
        stdcall AttachIntHandler, eax, int_handler, dword 0
496
        test    eax, eax
496
        test    eax, eax
497
        jnz     @f
497
        jnz     @f
498
        DEBUGF  1,"\nCould not attach int handler!\n"
498
        DEBUGF  1,"\nCould not attach int handler!\n"
499
;        or      eax, -1
499
;        or      eax, -1
500
;        ret
500
;        ret
501
  @@:
501
  @@:
502
 
502
 
503
 
503
 
504
reset_dontstart:
504
reset_dontstart:
505
        DEBUGF  1,"Reset\n"
505
        DEBUGF  1,"Reset\n"
506
 
506
 
507
        mov     esi, [device.mmio_addr]
507
        mov     esi, [device.mmio_addr]
508
 
508
 
509
        mov     dword [esi + REG_IMC], 0xffffffff       ; Disable all interrupt causes
509
        mov     dword [esi + REG_IMC], 0xffffffff       ; Disable all interrupt causes
510
        mov     eax, dword [esi + REG_ICR]              ; Clear any pending interrupts
510
        mov     eax, dword [esi + REG_ICR]              ; Clear any pending interrupts
511
        mov     dword [esi + REG_ITR], 0                ; Disable interrupt throttling logic
511
        mov     dword [esi + REG_ITR], 0                ; Disable interrupt throttling logic
512
 
512
 
513
        mov     dword [esi + REG_PBA], 0x00000030       ; PBA: set the RX buffer size to 48KB (TX buffer is calculated as 64-RX buffer)
513
        mov     dword [esi + REG_PBA], 0x00000030       ; PBA: set the RX buffer size to 48KB (TX buffer is calculated as 64-RX buffer)
514
        mov     dword [esi + REG_RDTR], 0               ; RDTR: set no delay
514
        mov     dword [esi + REG_RDTR], 0               ; RDTR: set no delay
515
 
515
 
516
        mov     dword [esi + REG_TXCW], 0x08008060      ; TXCW: set ANE, TxConfigWord (Half/Full duplex, Next Page Reqest)
516
        mov     dword [esi + REG_TXCW], 0x08008060      ; TXCW: set ANE, TxConfigWord (Half/Full duplex, Next Page Reqest)
517
 
517
 
518
        mov     eax, [esi + REG_CTRL]
518
        mov     eax, [esi + REG_CTRL]
519
        or      eax, 1 shl 6 + 1 shl 5
519
        or      eax, 1 shl 6 + 1 shl 5
520
        and     eax, not (1 shl 3 + 1 shl 7 + 1 shl 30 + 1 shl 31)
520
        and     eax, not (1 shl 3 + 1 shl 7 + 1 shl 30 + 1 shl 31)
521
        mov     dword [esi + REG_CTRL], eax             ; CTRL: clear LRST, set SLU and ASDE, clear RSTPHY, VME, and ILOS
521
        mov     dword [esi + REG_CTRL], eax             ; CTRL: clear LRST, set SLU and ASDE, clear RSTPHY, VME, and ILOS
522
 
522
 
523
        lea     edi, [esi + 0x5200]                     ; MTA: reset
523
        lea     edi, [esi + 0x5200]                     ; MTA: reset
524
        mov     eax, 0xffffffff
524
        mov     eax, 0xffffffff
525
        stosd
525
        stosd
526
        stosd
526
        stosd
527
        stosd
527
        stosd
528
        stosd
528
        stosd
529
 
529
 
530
        stdcall KernelAlloc, 48*1024
530
        stdcall KernelAlloc, 48*1024
531
        mov     dword [device.rx_desc + 16], eax
531
        mov     dword [device.rx_desc + 16], eax
532
        GetRealAddr
532
        GetRealAddr
533
        mov     dword [device.rx_desc], eax
533
        mov     dword [device.rx_desc], eax
534
        mov     dword [device.rx_desc + 4], 0
534
        mov     dword [device.rx_desc + 4], 0
535
 
535
 
536
        lea     eax, [device.rx_desc]
536
        lea     eax, [device.rx_desc]
537
        GetRealAddr
537
        GetRealAddr
538
        mov     dword [esi + REG_RDBAL], eax            ; Receive Descriptor Base Address Low
538
        mov     dword [esi + REG_RDBAL], eax            ; Receive Descriptor Base Address Low
539
        mov     dword [esi + REG_RDBAH], 0              ; Receive Descriptor Base Address High
539
        mov     dword [esi + REG_RDBAH], 0              ; Receive Descriptor Base Address High
540
        mov     dword [esi + REG_RDLEN], (1 * 128)      ; Receive Descriptor Length
540
        mov     dword [esi + REG_RDLEN], (1 * 128)      ; Receive Descriptor Length
541
        mov     dword [esi + REG_RDH], 0                ; Receive Descriptor Head
541
        mov     dword [esi + REG_RDH], 0                ; Receive Descriptor Head
542
        mov     dword [esi + REG_RDT], 1                ; Receive Descriptor Tail
542
        mov     dword [esi + REG_RDT], 1                ; Receive Descriptor Tail
543
        mov     dword [esi + REG_RCTL], 0x04008006      ; Receiver Enable, Store Bad Packets, Broadcast Accept Mode, Strip Ethernet CRC from incoming packet
543
        mov     dword [esi + REG_RCTL], 0x04008006      ; Receiver Enable, Store Bad Packets, Broadcast Accept Mode, Strip Ethernet CRC from incoming packet
544
 
544
 
545
        mov     dword [device.tx_desc], 0
545
        mov     dword [device.tx_desc], 0
546
        mov     dword [device.tx_desc + 4], 0
546
        mov     dword [device.tx_desc + 4], 0
547
        mov     dword [device.tx_desc + 16], 0
547
        mov     dword [device.tx_desc + 16], 0
548
 
548
 
549
        lea     eax, [device.tx_desc]
549
        lea     eax, [device.tx_desc]
550
        GetRealAddr
550
        GetRealAddr
551
        mov     dword [esi + REG_TDBAL], eax            ; Transmit Descriptor Base Address Low
551
        mov     dword [esi + REG_TDBAL], eax            ; Transmit Descriptor Base Address Low
552
        mov     dword [esi + REG_TDBAH], 0              ; Transmit Descriptor Base Address High
552
        mov     dword [esi + REG_TDBAH], 0              ; Transmit Descriptor Base Address High
553
        mov     dword [esi + REG_TDLEN], (1 * 128)      ; Transmit Descriptor Length
553
        mov     dword [esi + REG_TDLEN], (1 * 128)      ; Transmit Descriptor Length
554
        mov     dword [esi + REG_TDH], 0                ; Transmit Descriptor Head
554
        mov     dword [esi + REG_TDH], 0                ; Transmit Descriptor Head
555
        mov     dword [esi + REG_TDT], 0                ; Transmit Descriptor Tail
555
        mov     dword [esi + REG_TDT], 0                ; Transmit Descriptor Tail
556
        mov     dword [esi + REG_TCTL], 0x010400fa      ; Enabled, Pad Short Packets, 15 retrys, 64-byte COLD, Re-transmit on Late Collision
556
        mov     dword [esi + REG_TCTL], 0x010400fa      ; Enabled, Pad Short Packets, 15 retrys, 64-byte COLD, Re-transmit on Late Collision
557
        mov     dword [esi + REG_TIPG], 0x0060200A      ; IPGT 10, IPGR1 8, IPGR2 6
557
        mov     dword [esi + REG_TIPG], 0x0060200A      ; IPGT 10, IPGR1 8, IPGR2 6
558
 
558
 
559
        xor     eax, eax
559
        xor     eax, eax
560
        ret
560
        ret
561
 
561
 
562
start_i8254x:
562
start_i8254x:
563
 
563
 
564
        xor     eax, eax
564
        xor     eax, eax
565
        mov     [esi + REG_RDTR], eax                   ; Clear the Receive Delay Timer Register
565
        mov     [esi + REG_RDTR], eax                   ; Clear the Receive Delay Timer Register
566
        mov     [esi + REG_RADV], eax                   ; Clear the Receive Interrupt Absolute Delay Timer
566
        mov     [esi + REG_RADV], eax                   ; Clear the Receive Interrupt Absolute Delay Timer
567
        mov     [esi + REG_RSRPD], eax                  ; Clear the Receive Small Packet Detect Interrupt
567
        mov     [esi + REG_RSRPD], eax                  ; Clear the Receive Small Packet Detect Interrupt
568
        or      eax, 1 shl 0 + 1 shl 7                  ; TXDW + RXT0
568
        or      eax, 1 shl 0 + 1 shl 7                  ; TXDW + RXT0
569
        mov     eax, -1 ;;;; hack!
569
        mov     eax, -1 ;;;; hack!
570
        mov     [esi + REG_IMS], eax                    ; Enable interrupt types
570
        mov     [esi + REG_IMS], eax                    ; Enable interrupt types
571
 
571
 
572
        mov     [device.mtu], 1514
572
        mov     [device.mtu], 1514
573
 
573
 
574
        xor     eax, eax
574
        xor     eax, eax
575
        ret
575
        ret
576
 
576
 
577
align 4
577
align 4
578
reset:
578
reset:
579
        call    reset_dontstart
579
        call    reset_dontstart
580
        call    start_i8254x
580
        call    start_i8254x
581
 
581
 
582
        ret
582
        ret
583
 
583
 
584
 
584
 
585
 
585
 
586
align 4
586
align 4
587
read_mac:
587
read_mac:
588
 
588
 
589
        DEBUGF  1,"Read MAC\n"
589
        DEBUGF  1,"Read MAC\n"
590
 
590
 
591
        mov     esi, [device.mmio_addr]
591
        mov     esi, [device.mmio_addr]
592
 
592
 
593
        mov     eax, [esi+0x5400]                       ; RAL
593
        mov     eax, [esi+0x5400]                       ; RAL
594
        test    eax, eax
594
        test    eax, eax
595
        jz      .try_eeprom
595
        jz      .try_eeprom
596
 
596
 
597
        mov     dword [device.mac], eax
597
        mov     dword [device.mac], eax
598
        mov     eax, [esi+0x5404]                       ; RAH
598
        mov     eax, [esi+0x5404]                       ; RAH
599
        mov     word [device.mac+4], ax
599
        mov     word [device.mac+4], ax
600
 
600
 
601
        jmp     .mac_ok
601
        jmp     .mac_ok
602
 
602
 
603
  .try_eeprom:
603
  .try_eeprom:
604
        mov     dword [esi+0x14], 0x00000001
604
        mov     dword [esi+0x14], 0x00000001
605
        mov     eax, [esi+0x14]
605
        mov     eax, [esi+0x14]
606
        shr     eax, 16
606
        shr     eax, 16
607
        mov     word [device.mac], ax
607
        mov     word [device.mac], ax
608
 
608
 
609
        mov     dword [esi+0x14], 0x00000101
609
        mov     dword [esi+0x14], 0x00000101
610
        mov     eax, [esi+0x14]
610
        mov     eax, [esi+0x14]
611
        shr     eax, 16
611
        shr     eax, 16
612
        mov     word [device.mac+2], ax
612
        mov     word [device.mac+2], ax
613
 
613
 
614
        mov     dword [esi+0x14], 0x00000201
614
        mov     dword [esi+0x14], 0x00000201
615
        mov     eax, [esi+0x14]
615
        mov     eax, [esi+0x14]
616
        shr     eax, 16
616
        shr     eax, 16
617
        mov     word [device.mac+4], ax
617
        mov     word [device.mac+4], ax
618
 
618
 
619
  .mac_ok:
619
  .mac_ok:
620
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
620
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
621
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
621
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
622
 
622
 
623
        ret
623
        ret
624
 
624
 
625
 
625
 
626
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
626
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
627
;;                                         ;;
627
;;                                         ;;
628
;; Transmit                                ;;
628
;; Transmit                                ;;
629
;;                                         ;;
629
;;                                         ;;
630
;; In: buffer pointer in [esp+4]           ;;
630
;; In: buffer pointer in [esp+4]           ;;
631
;;     size of buffer in [esp+8]           ;;
631
;;     size of buffer in [esp+8]           ;;
632
;;     pointer to device structure in ebx  ;;
632
;;     pointer to device structure in ebx  ;;
633
;;                                         ;;
633
;;                                         ;;
634
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
634
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
635
align 4
635
align 4
636
transmit:
636
transmit:
637
        DEBUGF  2,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
637
        DEBUGF  2,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
638
        mov     eax, [esp+4]
638
        mov     eax, [esp+4]
639
        DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
639
        DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
640
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
640
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
641
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
641
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
642
        [eax+13]:2,[eax+12]:2
642
        [eax+13]:2,[eax+12]:2
643
 
643
 
644
        cmp     dword [esp + 8], 1514
644
        cmp     dword [esp + 8], 1514
645
        jg      .fail
645
        jg      .fail
646
        cmp     dword [esp + 8], 60
646
        cmp     dword [esp + 8], 60
647
        jl      .fail
647
        jl      .fail
648
 
648
 
649
 
649
 
650
; Program the descriptor (use legacy mode)
650
; Program the descriptor (use legacy mode)
651
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
651
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
652
        mov     dword [edi + 16], eax                   ; Store the data location (for driver)
652
        mov     dword [edi + 16], eax                   ; Store the data location (for driver)
653
        GetRealAddr                                     ;
653
        GetRealAddr                                     ;
654
        mov     dword [edi], eax                        ; Real addr (for i8254x)
654
        mov     dword [edi], eax                        ; Real addr (for i8254x)
655
        mov     dword [edi + 4], 0x00000000             ;
655
        mov     dword [edi + 4], 0x00000000             ;
656
 
656
 
657
        mov     ecx, [esp + 8]
657
        mov     ecx, [esp + 8]
658
        or      ecx, 1 shl 24 + 1 shl 25 + 1 shl 27     ; EOP + IFCS + RS
658
        or      ecx, 1 shl 24 + 1 shl 25 + 1 shl 27     ; EOP + IFCS + RS
659
        mov     dword [edi + 8], ecx                    ; Packet size
659
        mov     dword [edi + 8], ecx                    ; Packet size
660
        mov     dword [edi + 12], 0x00000000
660
        mov     dword [edi + 12], 0x00000000
661
 
661
 
662
; Tell i8254x wich descriptor(s) we programmed
662
; Tell i8254x wich descriptor(s) we programmed
663
        mov     edi, [device.mmio_addr]
663
        mov     edi, [device.mmio_addr]
664
        mov     dword [edi + REG_TDH], 0                ; TDH - Transmit Descriptor Head
664
        mov     dword [edi + REG_TDH], 0                ; TDH - Transmit Descriptor Head
665
        mov     dword [edi + REG_TDT], 1                ; TDT - Transmit Descriptor Tail
665
        mov     dword [edi + REG_TDT], 1                ; TDT - Transmit Descriptor Tail
666
 
666
 
667
; Update stats
667
; Update stats
668
        inc     [device.packets_tx]
668
        inc     [device.packets_tx]
669
        mov     eax, [esp + 8]
669
        mov     eax, [esp + 8]
670
        add     dword [device.bytes_tx], eax
670
        add     dword [device.bytes_tx], eax
671
        adc     dword [device.bytes_tx + 4], 0
671
        adc     dword [device.bytes_tx + 4], 0
672
 
672
 
673
        ret     8
673
        ret     8
674
 
674
 
675
  .fail:
675
  .fail:
676
        DEBUGF  1,"Send failed\n"
676
        DEBUGF  1,"Send failed\n"
677
        ret     8
677
        ret     8
678
 
678
 
679
 
679
 
680
;;;;;;;;;;;;;;;;;;;;;;;
680
;;;;;;;;;;;;;;;;;;;;;;;
681
;;                   ;;
681
;;                   ;;
682
;; Interrupt handler ;;
682
;; Interrupt handler ;;
683
;;                   ;;
683
;;                   ;;
684
;;;;;;;;;;;;;;;;;;;;;;;
684
;;;;;;;;;;;;;;;;;;;;;;;
-
 
685
 
685
align 4
686
align 4
686
int_handler:
687
int_handler:
687
        DEBUGF  2,"\nIRQ %x\n", eax:2   ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
-
 
-
 
688
 
688
 
689
        DEBUGF  1,"\n%s int\n", my_service
689
;-------------------------------------------
690
;-------------------------------------------
690
; Find pointer of device wich made IRQ occur
691
; Find pointer of device wich made IRQ occur
691
 
-
 
692
        mov     esi, device_list
692
 
693
        mov     ecx, [devices]
693
        mov     ecx, [devices]
694
        test    ecx, ecx
694
        test    ecx, ecx
-
 
695
        jz      .nothing
695
        jz      .fail
696
        mov     esi, device_list
696
  .nextdevice:
697
  .nextdevice:
697
        mov     ebx, dword [esi]
698
        mov     ebx, [esi]
-
 
699
 
698
 
700
        mov     edi, [device.mmio_addr]
-
 
701
        mov     eax, [edi + REG_ICR]
-
 
702
        test    eax, eax
-
 
703
        jnz     .got_it
-
 
704
  .continue:
699
        mov     edi, [device.mmio_addr]
705
        add     esi, 4
-
 
706
        dec     ecx
-
 
707
        jnz     .nextdevice
700
        test    edi, edi
-
 
701
        jz      .nextdevice
708
  .nothing:
702
 
-
 
703
;--------------------
709
        ret
704
; Get interrupt cause
710
 
705
 
711
  .got_it:
706
        mov     eax, [edi + REG_ICR]
712
 
707
        DEBUGF  2,"interrupt cause=%x\n", eax
713
        DEBUGF  1,"Device: %x Status: %x ", ebx, eax
708
 
714
 
709
;---------
715
;---------
710
; RX done?
716
; RX done?
711
 
717
 
712
        test    eax, ICR_RXDMT0
718
        test    eax, ICR_RXDMT0
713
        jz      .no_rx
719
        jz      .no_rx
714
 
720
 
715
        push    eax
721
        push    eax
716
        push    .retaddr
722
        push    .retaddr
717
 
723
 
718
; Get last descriptor addr
724
; Get last descriptor addr
719
        lea     esi, [device.rx_desc]
725
        lea     esi, [device.rx_desc]
720
 
726
 
721
        cmp     byte [esi + 12], 0                      ; Check status field
727
        cmp     byte [esi + 12], 0                      ; Check status field
722
        je      .retaddr
728
        je      .retaddr
723
 
729
 
724
        movzx   ecx, word [esi + 8]                     ; Get the packet length
730
        movzx   ecx, word [esi + 8]                     ; Get the packet length
725
        DEBUGF  2,"got %u bytes\n", ecx
731
        DEBUGF  2,"got %u bytes\n", ecx
726
        push    ecx
732
        push    ecx
727
        push    dword [esi + 16]                        ; Get packet pointer
733
        push    dword [esi + 16]                        ; Get packet pointer
728
 
734
 
729
; Update stats
735
; Update stats
730
        add     dword [device.bytes_rx], ecx
736
        add     dword [device.bytes_rx], ecx
731
        adc     dword [device.bytes_rx + 4], 0
737
        adc     dword [device.bytes_rx + 4], 0
732
        inc     dword [device.packets_rx]
738
        inc     dword [device.packets_rx]
733
 
739
 
734
; allocate new descriptor
740
; allocate new descriptor
735
        stdcall KernelAlloc, 48*1024
741
        stdcall KernelAlloc, 48*1024
736
        mov     dword [esi + 16], eax
742
        mov     dword [esi + 16], eax
737
        GetRealAddr
743
        GetRealAddr
738
        mov     dword [esi], eax
744
        mov     dword [esi], eax
739
 
745
 
740
; reset descriptor status
746
; reset descriptor status
741
        mov     esi, [device.mmio_addr]
747
        mov     esi, [device.mmio_addr]
742
        mov     dword [esi + REG_RDH], 0x00000000       ; Receive Descriptor Head
748
        mov     dword [esi + REG_RDH], 0x00000000       ; Receive Descriptor Head
743
        mov     dword [esi + REG_RDT], 0x00000001       ; Receive Descriptor Tail
749
        mov     dword [esi + REG_RDT], 0x00000001       ; Receive Descriptor Tail
744
 
750
 
745
        jmp     EthReceiver
751
        jmp     EthReceiver
746
  .retaddr:
752
  .retaddr:
747
        pop     eax
753
        pop     eax
748
 
754
 
749
  .no_rx:
755
  .no_rx:
750
 
756
 
751
;--------------
757
;--------------
752
; Link Changed?
758
; Link Changed?
753
 
759
 
754
        test    eax, ICR_LSC
760
        test    eax, ICR_LSC
755
        jz      .no_link
761
        jz      .no_link
756
 
762
 
757
        DEBUGF  2,"Link Changed\n"
763
        DEBUGF  2,"Link Changed\n"
758
 
764
 
759
  .no_link:
765
  .no_link:
760
 
766
 
761
;---------------
767
;---------------
762
; Transmit done?
768
; Transmit done?
763
 
769
 
764
        test    eax, ICR_TXDW
770
        test    eax, ICR_TXDW
765
        jz      .no_tx
771
        jz      .no_tx
766
 
772
 
767
        DEBUGF  2,"Transmit done\n"
773
        DEBUGF  2,"Transmit done\n"
768
 
774
 
769
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
775
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
770
        push    dword [edi + 16]                        ; Store the data location (for driver)
776
        push    dword [edi + 16]                        ; Store the data location (for driver)
771
        call    KernelFree
777
        call    KernelFree
772
 
778
 
773
  .no_tx:
779
  .no_tx:
774
  .fail:
780
  .fail:
775
        ret
781
        ret
776
 
782
 
777
 
783
 
778
 
784
 
779
 
785
 
780
; End of code
786
; End of code
781
 
787
 
782
section '.data' data readable writable align 16
788
section '.data' data readable writable align 16
783
align 4
789
align 4
784
 
790
 
785
devices         dd 0
791
devices         dd 0
786
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
792
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
787
my_service      db 'I8254X',0                   ; max 16 chars include zero
793
my_service      db 'I8254X',0                   ; max 16 chars include zero
788
 
794
 
789
include_debug_strings                           ; All data wich FDO uses will be included here
795
include_debug_strings                           ; All data wich FDO uses will be included here
790
 
796
 
791
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
797
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling