Subversion Repositories Kolibri OS

Rev

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

Rev 3545 Rev 3788
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2013. 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__         = 2
28
        __DEBUG_LEVEL__         = 2
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 Sence Error
169
ICR_RXSEQ               = 0x00000008 ; RX Sence 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
        jb      .fail
327
        jb      .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
        jb      .fail
340
        jb      .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
        jae     .fail
369
        jae     .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.unload], unload
377
        mov     [device.unload], unload
378
        mov     [device.name], my_service
378
        mov     [device.name], my_service
379
 
379
 
380
; save the pci bus and device numbers
380
; save the pci bus and device numbers
381
 
381
 
382
        mov     eax, [IOCTL.input]
382
        mov     eax, [IOCTL.input]
383
        movzx   ecx, byte [eax+1]
383
        movzx   ecx, byte [eax+1]
384
        mov     [device.pci_bus], ecx
384
        mov     [device.pci_bus], ecx
385
        movzx   ecx, byte [eax+2]
385
        movzx   ecx, byte [eax+2]
386
        mov     [device.pci_dev], ecx
386
        mov     [device.pci_dev], ecx
387
 
387
 
388
; Now, it's time to find the base mmio addres of the PCI device
388
; Now, it's time to find the base mmio addres of the PCI device
389
 
389
 
390
        PCI_find_mmio32
390
        PCI_find_mmio32
391
 
391
 
392
; Create virtual mapping of the physical memory
392
; Create virtual mapping of the physical memory
393
 
393
 
394
        push    1Bh             ; PG_SW+PG_NOCACHE
394
        push    1Bh             ; PG_SW+PG_NOCACHE
395
        push    10000h          ; size of the map
395
        push    10000h          ; size of the map
396
        push    eax
396
        push    eax
397
        call    MapIoMem
397
        call    MapIoMem
398
        mov     [device.mmio_addr], eax
398
        mov     [device.mmio_addr], eax
399
 
399
 
400
; We've found the mmio address, find IRQ now
400
; We've found the mmio address, find IRQ now
401
 
401
 
402
        PCI_find_irq
402
        PCI_find_irq
403
 
403
 
404
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
404
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
405
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.mmio_addr]:8
405
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.mmio_addr]:8
406
 
406
 
407
; Ok, the eth_device structure is ready, let's probe the device
407
; Ok, the eth_device structure is ready, let's probe the device
408
        call    probe                                                   ; this function will output in eax
408
        call    probe                                                   ; this function will output in eax
409
        test    eax, eax
409
        test    eax, eax
410
        jnz     .err                                                    ; If an error occured, exit
410
        jnz     .err                                                    ; If an error occured, exit
411
 
411
 
412
        mov     eax, [devices]                                          ; Add the device structure to our device list
412
        mov     eax, [devices]                                          ; Add the device structure to our device list
413
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
413
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
414
        inc     [devices]                                               ;
414
        inc     [devices]                                               ;
415
 
415
 
416
        call    start_i8254x
416
        call    start_i8254x
417
 
417
 
418
        mov     [device.type], NET_TYPE_ETH
418
        mov     [device.type], NET_TYPE_ETH
419
        call    NetRegDev
419
        call    NetRegDev
420
 
420
 
421
        cmp     eax, -1
421
        cmp     eax, -1
422
        je      .destroy
422
        je      .destroy
423
 
423
 
424
        ret
424
        ret
425
 
425
 
426
; If the device was already loaded, find the device number and return it in eax
426
; If the device was already loaded, find the device number and return it in eax
427
 
427
 
428
  .find_devicenum:
428
  .find_devicenum:
429
        DEBUGF  1,"Trying to find device number of already registered device\n"
429
        DEBUGF  1,"Trying to find device number of already registered device\n"
430
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
430
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
431
                                                                        ; into a device number in edi
431
                                                                        ; into a device number in edi
432
        mov     eax, edi                                                ; Application wants it in eax instead
432
        mov     eax, edi                                                ; Application wants it in eax instead
433
        DEBUGF  1,"Kernel says: %u\n", eax
433
        DEBUGF  1,"Kernel says: %u\n", eax
434
        ret
434
        ret
435
 
435
 
436
; If an error occured, remove all allocated data and exit (returning -1 in eax)
436
; If an error occured, remove all allocated data and exit (returning -1 in eax)
437
 
437
 
438
  .destroy:
438
  .destroy:
439
        ; todo: reset device into virgin state
439
        ; todo: reset device into virgin state
440
 
440
 
441
  .err:
441
  .err:
442
        stdcall KernelFree, ebx
442
        stdcall KernelFree, ebx
443
 
443
 
444
  .fail:
444
  .fail:
445
        or      eax, -1
445
        or      eax, -1
446
        ret
446
        ret
447
 
447
 
448
;------------------------------------------------------
448
;------------------------------------------------------
449
endp
449
endp
450
 
450
 
451
 
451
 
452
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
452
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
453
;;                                                                        ;;
453
;;                                                                        ;;
454
;;        Actual Hardware dependent code starts here                      ;;
454
;;        Actual Hardware dependent code starts here                      ;;
455
;;                                                                        ;;
455
;;                                                                        ;;
456
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
456
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
457
 
457
 
458
 
458
 
459
align 4
459
align 4
460
unload:
460
unload:
461
        ; TODO: (in this particular order)
461
        ; TODO: (in this particular order)
462
        ;
462
        ;
463
        ; - Stop the device
463
        ; - Stop the device
464
        ; - Detach int handler
464
        ; - Detach int handler
465
        ; - Remove device from local list (device_list)
465
        ; - Remove device from local list (device_list)
466
        ; - call unregister function in kernel
466
        ; - call unregister function in kernel
467
        ; - Remove all allocated structures and buffers the card used
467
        ; - Remove all allocated structures and buffers the card used
468
 
468
 
469
        or      eax, -1
469
        or      eax, -1
470
 
470
 
471
ret
471
ret
472
 
472
 
473
 
473
 
474
 
474
 
475
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
475
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
476
;;
476
;;
477
;;  probe: enables the device (if it really is I8254X)
477
;;  probe: enables the device (if it really is I8254X)
478
;;
478
;;
479
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
479
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
480
align 4
480
align 4
481
probe:
481
probe:
482
 
482
 
483
        DEBUGF  1,"Probe\n"
483
        DEBUGF  1,"Probe\n"
484
 
484
 
485
        PCI_make_bus_master
485
        PCI_make_bus_master
486
 
486
 
487
        ; TODO: validate the device
487
        ; TODO: validate the device
488
 
488
 
489
        call    read_mac
489
        call    read_mac
490
 
490
 
491
        movzx   eax, [device.irq_line]
491
        movzx   eax, [device.irq_line]
492
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
492
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
493
        stdcall AttachIntHandler, eax, int_handler, dword 0
493
        stdcall AttachIntHandler, eax, int_handler, dword 0
494
        test    eax, eax
494
        test    eax, eax
495
        jnz     @f
495
        jnz     @f
496
        DEBUGF  1,"\nCould not attach int handler!\n"
496
        DEBUGF  1,"\nCould not attach int handler!\n"
497
;        or      eax, -1
497
;        or      eax, -1
498
;        ret
498
;        ret
499
  @@:
499
  @@:
500
 
500
 
501
 
501
 
502
reset_dontstart:
502
reset_dontstart:
503
        DEBUGF  1,"Reset\n"
503
        DEBUGF  1,"Reset\n"
504
 
504
 
505
        mov     esi, [device.mmio_addr]
505
        mov     esi, [device.mmio_addr]
506
 
506
 
507
        or      dword [esi + REG_CTRL], CTRL_RST        ; reset device
507
        or      dword [esi + REG_CTRL], CTRL_RST        ; reset device
508
  .loop:
508
  .loop:
509
        push    esi
509
        push    esi
510
        xor     esi, esi
510
        xor     esi, esi
511
        inc     esi
511
        inc     esi
512
        call    Sleep
512
        call    Sleep
513
        pop     esi
513
        pop     esi
514
        test    dword [esi + REG_CTRL], CTRL_RST
514
        test    dword [esi + REG_CTRL], CTRL_RST
515
        jnz     .loop
515
        jnz     .loop
516
 
516
 
517
        mov     dword [esi + REG_IMC], 0xffffffff       ; Disable all interrupt causes
517
        mov     dword [esi + REG_IMC], 0xffffffff       ; Disable all interrupt causes
518
        mov     eax, dword [esi + REG_ICR]              ; Clear any pending interrupts
518
        mov     eax, dword [esi + REG_ICR]              ; Clear any pending interrupts
519
        mov     dword [esi + REG_ITR], 0                ; Disable interrupt throttling logic
519
        mov     dword [esi + REG_ITR], 0                ; Disable interrupt throttling logic
520
 
520
 
521
        mov     dword [esi + REG_PBA], 0x00000030       ; PBA: set the RX buffer size to 48KB (TX buffer is calculated as 64-RX buffer)
521
        mov     dword [esi + REG_PBA], 0x00000030       ; PBA: set the RX buffer size to 48KB (TX buffer is calculated as 64-RX buffer)
522
        mov     dword [esi + REG_RDTR], 0               ; RDTR: set no delay
522
        mov     dword [esi + REG_RDTR], 0               ; RDTR: set no delay
523
 
523
 
524
        mov     dword [esi + REG_TXCW], 0x08008060      ; TXCW: set ANE, TxConfigWord (Half/Full duplex, Next Page Reqest)
524
        mov     dword [esi + REG_TXCW], 0x08008060      ; TXCW: set ANE, TxConfigWord (Half/Full duplex, Next Page Reqest)
525
 
525
 
526
        mov     eax, [esi + REG_CTRL]
526
        mov     eax, [esi + REG_CTRL]
527
        or      eax, 1 shl 6 + 1 shl 5
527
        or      eax, 1 shl 6 + 1 shl 5
528
        and     eax, not (1 shl 3 + 1 shl 7 + 1 shl 30 + 1 shl 31)
528
        and     eax, not (1 shl 3 + 1 shl 7 + 1 shl 30 + 1 shl 31)
529
        mov     dword [esi + REG_CTRL], eax             ; CTRL: clear LRST, set SLU and ASDE, clear RSTPHY, VME, and ILOS
529
        mov     dword [esi + REG_CTRL], eax             ; CTRL: clear LRST, set SLU and ASDE, clear RSTPHY, VME, and ILOS
530
 
530
 
531
        lea     edi, [esi + 0x5200]                     ; MTA: reset
531
        lea     edi, [esi + 0x5200]                     ; MTA: reset
532
        mov     eax, 0xffffffff
532
        mov     eax, 0xffffffff
533
        stosd
533
        stosd
534
        stosd
534
        stosd
535
        stosd
535
        stosd
536
        stosd
536
        stosd
537
 
537
 
538
        stdcall KernelAlloc, 48*1024
538
        stdcall KernelAlloc, 48*1024
539
        mov     dword [device.rx_desc + 16], eax
539
        mov     dword [device.rx_desc + 16], eax
540
        GetRealAddr
540
        GetRealAddr
541
        mov     dword [device.rx_desc], eax
541
        mov     dword [device.rx_desc], eax
542
        mov     dword [device.rx_desc + 4], 0
542
        mov     dword [device.rx_desc + 4], 0
543
 
543
 
544
        lea     eax, [device.rx_desc]
544
        lea     eax, [device.rx_desc]
545
        GetRealAddr
545
        GetRealAddr
546
        mov     dword [esi + REG_RDBAL], eax            ; Receive Descriptor Base Address Low
546
        mov     dword [esi + REG_RDBAL], eax            ; Receive Descriptor Base Address Low
547
        mov     dword [esi + REG_RDBAH], 0              ; Receive Descriptor Base Address High
547
        mov     dword [esi + REG_RDBAH], 0              ; Receive Descriptor Base Address High
548
        mov     dword [esi + REG_RDLEN], (1 * 128)      ; Receive Descriptor Length
548
        mov     dword [esi + REG_RDLEN], (1 * 128)      ; Receive Descriptor Length
549
        mov     dword [esi + REG_RDH], 0                ; Receive Descriptor Head
549
        mov     dword [esi + REG_RDH], 0                ; Receive Descriptor Head
550
        mov     dword [esi + REG_RDT], 1                ; Receive Descriptor Tail
550
        mov     dword [esi + REG_RDT], 1                ; Receive Descriptor Tail
551
        mov     dword [esi + REG_RCTL], RCTL_EN or RCTL_SBP or RCTL_BAM or RCTL_SECRC or RCTL_UPE or RCTL_MPE
551
        mov     dword [esi + REG_RCTL], RCTL_EN or RCTL_SBP or RCTL_BAM or RCTL_SECRC or RCTL_UPE or RCTL_MPE
552
        ; Receiver Enable, Store Bad Packets, Broadcast Accept Mode, Strip Ethernet CRC from incoming packet, Promiscuous mode
552
        ; Receiver Enable, Store Bad Packets, Broadcast Accept Mode, Strip Ethernet CRC from incoming packet, Promiscuous mode
553
 
553
 
554
        mov     dword [device.tx_desc], 0
554
        mov     dword [device.tx_desc], 0
555
        mov     dword [device.tx_desc + 4], 0
555
        mov     dword [device.tx_desc + 4], 0
556
        mov     dword [device.tx_desc + 16], 0
556
        mov     dword [device.tx_desc + 16], 0
557
 
557
 
558
        lea     eax, [device.tx_desc]
558
        lea     eax, [device.tx_desc]
559
        GetRealAddr
559
        GetRealAddr
560
        mov     dword [esi + REG_TDBAL], eax            ; Transmit Descriptor Base Address Low
560
        mov     dword [esi + REG_TDBAL], eax            ; Transmit Descriptor Base Address Low
561
        mov     dword [esi + REG_TDBAH], 0              ; Transmit Descriptor Base Address High
561
        mov     dword [esi + REG_TDBAH], 0              ; Transmit Descriptor Base Address High
562
        mov     dword [esi + REG_TDLEN], (1 * 128)      ; Transmit Descriptor Length
562
        mov     dword [esi + REG_TDLEN], (1 * 128)      ; Transmit Descriptor Length
563
        mov     dword [esi + REG_TDH], 0                ; Transmit Descriptor Head
563
        mov     dword [esi + REG_TDH], 0                ; Transmit Descriptor Head
564
        mov     dword [esi + REG_TDT], 0                ; Transmit Descriptor Tail
564
        mov     dword [esi + REG_TDT], 0                ; Transmit Descriptor Tail
565
        mov     dword [esi + REG_TCTL], 0x010400fa      ; Enabled, Pad Short Packets, 15 retrys, 64-byte COLD, Re-transmit on Late Collision
565
        mov     dword [esi + REG_TCTL], 0x010400fa      ; Enabled, Pad Short Packets, 15 retrys, 64-byte COLD, Re-transmit on Late Collision
566
        mov     dword [esi + REG_TIPG], 0x0060200A      ; IPGT 10, IPGR1 8, IPGR2 6
566
        mov     dword [esi + REG_TIPG], 0x0060200A      ; IPGT 10, IPGR1 8, IPGR2 6
567
 
567
 
568
        xor     eax, eax
568
        xor     eax, eax
569
        ret
569
        ret
570
 
570
 
571
align 4
571
align 4
572
reset:
572
reset:
573
        call    reset_dontstart
573
        call    reset_dontstart
574
 
574
 
575
start_i8254x:
575
start_i8254x:
576
 
576
 
577
        xor     eax, eax
577
        xor     eax, eax
578
        mov     [esi + REG_RDTR], eax                   ; Clear the Receive Delay Timer Register
578
        mov     [esi + REG_RDTR], eax                   ; Clear the Receive Delay Timer Register
579
        mov     [esi + REG_RADV], eax                   ; Clear the Receive Interrupt Absolute Delay Timer
579
        mov     [esi + REG_RADV], eax                   ; Clear the Receive Interrupt Absolute Delay Timer
580
        mov     [esi + REG_RSRPD], eax                  ; Clear the Receive Small Packet Detect Interrupt
580
        mov     [esi + REG_RSRPD], eax                  ; Clear the Receive Small Packet Detect Interrupt
581
;        or      eax, 1 shl 0 + 1 shl 7                  ; TXDW + RXT0
581
;        or      eax, 1 shl 0 + 1 shl 7                  ; TXDW + RXT0
582
        mov     eax, 1+4+16 ;;;; hack!
582
        mov     eax, 1+4+16 ;;;; hack!
583
        mov     [esi + REG_IMS], eax                    ; Enable interrupt types
583
        mov     [esi + REG_IMS], eax                    ; Enable interrupt types
584
 
584
 
585
        mov     [device.mtu], 1514
585
        mov     [device.mtu], 1514
586
 
586
 
587
; Set link state to unknown
587
; Set link state to unknown
588
        mov     [device.state], ETH_LINK_UNKOWN
588
        mov     [device.state], ETH_LINK_UNKOWN
589
 
589
 
590
        xor     eax, eax
590
        xor     eax, eax
591
        ret
591
        ret
592
 
592
 
593
 
593
 
594
 
594
 
595
 
595
 
596
align 4
596
align 4
597
read_mac:
597
read_mac:
598
 
598
 
599
        DEBUGF  1,"Read MAC\n"
599
        DEBUGF  1,"Read MAC\n"
600
 
600
 
601
        mov     esi, [device.mmio_addr]
601
        mov     esi, [device.mmio_addr]
602
 
602
 
603
        mov     eax, [esi+0x5400]                       ; RAL
603
        mov     eax, [esi+0x5400]                       ; RAL
604
        test    eax, eax
604
        test    eax, eax
605
        jz      .try_eeprom
605
        jz      .try_eeprom
606
 
606
 
607
        mov     dword [device.mac], eax
607
        mov     dword [device.mac], eax
608
        mov     eax, [esi+0x5404]                       ; RAH
608
        mov     eax, [esi+0x5404]                       ; RAH
609
        mov     word [device.mac+4], ax
609
        mov     word [device.mac+4], ax
610
 
610
 
611
        jmp     .mac_ok
611
        jmp     .mac_ok
612
 
612
 
613
  .try_eeprom:
613
  .try_eeprom:
614
        mov     dword [esi+0x14], 0x00000001
614
        mov     dword [esi+0x14], 0x00000001
615
        mov     eax, [esi+0x14]
615
        mov     eax, [esi+0x14]
616
        shr     eax, 16
616
        shr     eax, 16
617
        mov     word [device.mac], ax
617
        mov     word [device.mac], ax
618
 
618
 
619
        mov     dword [esi+0x14], 0x00000101
619
        mov     dword [esi+0x14], 0x00000101
620
        mov     eax, [esi+0x14]
620
        mov     eax, [esi+0x14]
621
        shr     eax, 16
621
        shr     eax, 16
622
        mov     word [device.mac+2], ax
622
        mov     word [device.mac+2], ax
623
 
623
 
624
        mov     dword [esi+0x14], 0x00000201
624
        mov     dword [esi+0x14], 0x00000201
625
        mov     eax, [esi+0x14]
625
        mov     eax, [esi+0x14]
626
        shr     eax, 16
626
        shr     eax, 16
627
        mov     word [device.mac+4], ax
627
        mov     word [device.mac+4], ax
628
 
628
 
629
  .mac_ok:
629
  .mac_ok:
630
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
630
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
631
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
631
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
632
 
632
 
633
        ret
633
        ret
634
 
634
 
635
 
635
 
636
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
636
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
637
;;                                         ;;
637
;;                                         ;;
638
;; Transmit                                ;;
638
;; Transmit                                ;;
639
;;                                         ;;
639
;;                                         ;;
640
;; In: buffer pointer in [esp+4]           ;;
640
;; In: buffer pointer in [esp+4]           ;;
641
;;     size of buffer in [esp+8]           ;;
641
;;     size of buffer in [esp+8]           ;;
642
;;     pointer to device structure in ebx  ;;
642
;;     pointer to device structure in ebx  ;;
643
;;                                         ;;
643
;;                                         ;;
644
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
644
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
645
align 4
645
align 4
646
transmit:
646
transmit:
647
        DEBUGF  2,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
647
        DEBUGF  1,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
648
        mov     eax, [esp+4]
648
        mov     eax, [esp+4]
649
        DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
649
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
650
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
650
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
651
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
651
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
652
        [eax+13]:2,[eax+12]:2
652
        [eax+13]:2,[eax+12]:2
653
 
653
 
654
        cmp     dword [esp + 8], 1514
654
        cmp     dword [esp + 8], 1514
655
        ja      .fail
655
        ja      .fail
656
        cmp     dword [esp + 8], 60
656
        cmp     dword [esp + 8], 60
657
        jb      .fail
657
        jb      .fail
658
 
658
 
659
 
659
 
660
; Program the descriptor (use legacy mode)
660
; Program the descriptor (use legacy mode)
661
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
661
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
662
        mov     dword [edi + 16], eax                   ; Store the data location (for driver)
662
        mov     dword [edi + 16], eax                   ; Store the data location (for driver)
663
        GetRealAddr                                     ;
663
        GetRealAddr                                     ;
664
        mov     dword [edi], eax                        ; Real addr (for i8254x)
664
        mov     dword [edi], eax                        ; Real addr (for i8254x)
665
        mov     dword [edi + 4], 0x00000000             ;
665
        mov     dword [edi + 4], 0x00000000             ;
666
 
666
 
667
        mov     ecx, [esp + 8]
667
        mov     ecx, [esp + 8]
668
        or      ecx, 1 shl 24 + 1 shl 25 + 1 shl 27     ; EOP + IFCS + RS
668
        or      ecx, 1 shl 24 + 1 shl 25 + 1 shl 27     ; EOP + IFCS + RS
669
        mov     dword [edi + 8], ecx                    ; Packet size
669
        mov     dword [edi + 8], ecx                    ; Packet size
670
        mov     dword [edi + 12], 0x00000000
670
        mov     dword [edi + 12], 0x00000000
671
 
671
 
672
; Tell i8254x wich descriptor(s) we programmed
672
; Tell i8254x wich descriptor(s) we programmed
673
        mov     edi, [device.mmio_addr]
673
        mov     edi, [device.mmio_addr]
674
        mov     dword [edi + REG_TDH], 0                ; TDH - Transmit Descriptor Head
674
        mov     dword [edi + REG_TDH], 0                ; TDH - Transmit Descriptor Head
675
        mov     dword [edi + REG_TDT], 1                ; TDT - Transmit Descriptor Tail
675
        mov     dword [edi + REG_TDT], 1                ; TDT - Transmit Descriptor Tail
676
 
676
 
677
; Update stats
677
; Update stats
678
        inc     [device.packets_tx]
678
        inc     [device.packets_tx]
679
        mov     eax, [esp + 8]
679
        mov     eax, [esp + 8]
680
        add     dword [device.bytes_tx], eax
680
        add     dword [device.bytes_tx], eax
681
        adc     dword [device.bytes_tx + 4], 0
681
        adc     dword [device.bytes_tx + 4], 0
682
 
682
 
683
        ret     8
683
        ret     8
684
 
684
 
685
  .fail:
685
  .fail:
686
        DEBUGF  1,"Send failed\n"
686
        DEBUGF  2,"Send failed\n"
687
        ret     8
687
        ret     8
688
 
688
 
689
 
689
 
690
;;;;;;;;;;;;;;;;;;;;;;;
690
;;;;;;;;;;;;;;;;;;;;;;;
691
;;                   ;;
691
;;                   ;;
692
;; Interrupt handler ;;
692
;; Interrupt handler ;;
693
;;                   ;;
693
;;                   ;;
694
;;;;;;;;;;;;;;;;;;;;;;;
694
;;;;;;;;;;;;;;;;;;;;;;;
695
 
695
 
696
align 4
696
align 4
697
int_handler:
697
int_handler:
698
 
698
 
699
        push    ebx esi edi
699
        push    ebx esi edi
700
 
700
 
701
        DEBUGF  1,"\n%s int\n", my_service
701
        DEBUGF  1,"\n%s int\n", my_service
702
;-------------------------------------------
702
;-------------------------------------------
703
; Find pointer of device wich made IRQ occur
703
; Find pointer of device wich made IRQ occur
704
 
704
 
705
        mov     ecx, [devices]
705
        mov     ecx, [devices]
706
        test    ecx, ecx
706
        test    ecx, ecx
707
        jz      .nothing
707
        jz      .nothing
708
        mov     esi, device_list
708
        mov     esi, device_list
709
  .nextdevice:
709
  .nextdevice:
710
        mov     ebx, [esi]
710
        mov     ebx, [esi]
711
 
711
 
712
        mov     edi, [device.mmio_addr]
712
        mov     edi, [device.mmio_addr]
713
        mov     eax, [edi + REG_ICR]
713
        mov     eax, [edi + REG_ICR]
714
        test    eax, eax
714
        test    eax, eax
715
        jnz     .got_it
715
        jnz     .got_it
716
  .continue:
716
  .continue:
717
        add     esi, 4
717
        add     esi, 4
718
        dec     ecx
718
        dec     ecx
719
        jnz     .nextdevice
719
        jnz     .nextdevice
720
  .nothing:
720
  .nothing:
721
        pop     edi esi ebx
721
        pop     edi esi ebx
722
        xor     eax, eax
722
        xor     eax, eax
723
 
723
 
724
        ret
724
        ret
725
 
725
 
726
  .got_it:
726
  .got_it:
727
 
727
 
728
        DEBUGF  1,"Device: %x Status: %x ", ebx, eax
728
        DEBUGF  1,"Device: %x Status: %x ", ebx, eax
729
 
729
 
730
;---------
730
;---------
731
; RX done?
731
; RX done?
732
 
732
 
733
        test    eax, ICR_RXDMT0
733
        test    eax, ICR_RXDMT0
734
        jz      .no_rx
734
        jz      .no_rx
735
 
735
 
736
        push    eax ebx
736
        push    eax ebx
737
        push    .retaddr
737
        push    .retaddr
738
 
738
 
739
; Get last descriptor addr
739
; Get last descriptor addr
740
        lea     esi, [device.rx_desc]
740
        lea     esi, [device.rx_desc]
741
 
741
 
742
        cmp     byte [esi + 12], 0                      ; Check status field
742
        cmp     byte [esi + 12], 0                      ; Check status field
743
        je      .retaddr
743
        je      .retaddr
744
 
744
 
745
        movzx   ecx, word [esi + 8]                     ; Get the packet length
745
        movzx   ecx, word [esi + 8]                     ; Get the packet length
746
        DEBUGF  2,"got %u bytes\n", ecx
746
        DEBUGF  1,"got %u bytes\n", ecx
747
        push    ecx
747
        push    ecx
748
        push    dword [esi + 16]                        ; Get packet pointer
748
        push    dword [esi + 16]                        ; Get packet pointer
749
 
749
 
750
; Update stats
750
; Update stats
751
        add     dword [device.bytes_rx], ecx
751
        add     dword [device.bytes_rx], ecx
752
        adc     dword [device.bytes_rx + 4], 0
752
        adc     dword [device.bytes_rx + 4], 0
753
        inc     dword [device.packets_rx]
753
        inc     dword [device.packets_rx]
754
 
754
 
755
; allocate new descriptor
755
; allocate new descriptor
756
        stdcall KernelAlloc, 48*1024
756
        stdcall KernelAlloc, 48*1024
757
        mov     dword [esi + 16], eax
757
        mov     dword [esi + 16], eax
758
        GetRealAddr
758
        GetRealAddr
759
        mov     dword [esi], eax
759
        mov     dword [esi], eax
760
 
760
 
761
; reset descriptor status
761
; reset descriptor status
762
        mov     esi, [device.mmio_addr]
762
        mov     esi, [device.mmio_addr]
763
        mov     dword [esi + REG_RDH], 0x00000000       ; Receive Descriptor Head
763
        mov     dword [esi + REG_RDH], 0x00000000       ; Receive Descriptor Head
764
        mov     dword [esi + REG_RDT], 0x00000001       ; Receive Descriptor Tail
764
        mov     dword [esi + REG_RDT], 0x00000001       ; Receive Descriptor Tail
765
 
765
 
766
        jmp     Eth_input
766
        jmp     Eth_input
767
  .retaddr:
767
  .retaddr:
768
        pop     ebx eax
768
        pop     ebx eax
769
 
769
 
770
  .no_rx:
770
  .no_rx:
771
 
771
 
772
;--------------
772
;--------------
773
; Link Changed?
773
; Link Changed?
774
 
774
 
775
        test    eax, ICR_LSC
775
        test    eax, ICR_LSC
776
        jz      .no_link
776
        jz      .no_link
777
 
777
 
778
        DEBUGF  2,"Link Changed\n"
778
        DEBUGF  1,"Link Changed\n"
779
 
779
 
780
  .no_link:
780
  .no_link:
781
 
781
 
782
;---------------
782
;---------------
783
; Transmit done?
783
; Transmit done?
784
 
784
 
785
        test    eax, ICR_TXDW
785
        test    eax, ICR_TXDW
786
        jz      .no_tx
786
        jz      .no_tx
787
 
787
 
788
        DEBUGF  2,"Transmit done\n"
788
        DEBUGF  1,"Transmit done\n"
789
 
789
 
790
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
790
        lea     edi, [device.tx_desc]                   ; Transmit Descriptor Base Address
791
        push    dword [edi + 16]                        ; Store the data location (for driver)
791
        push    dword [edi + 16]                        ; Store the data location (for driver)
792
        call    KernelFree
792
        call    KernelFree
793
 
793
 
794
  .no_tx:
794
  .no_tx:
795
  .fail:
795
  .fail:
796
        pop     edi esi ebx
796
        pop     edi esi ebx
797
        xor     eax, eax
797
        xor     eax, eax
798
        inc     eax
798
        inc     eax
799
 
799
 
800
        ret
800
        ret
801
 
801
 
802
 
802
 
803
 
803
 
804
 
804
 
805
; End of code
805
; End of code
806
 
806
 
807
section '.data' data readable writable align 16
807
section '.data' data readable writable align 16
808
align 4
808
align 4
809
 
809
 
810
devices         dd 0
810
devices         dd 0
811
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
811
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
812
my_service      db 'I8254X',0                   ; max 16 chars include zero
812
my_service      db 'I8254X',0                   ; max 16 chars include zero
813
 
813
 
814
include_debug_strings                           ; All data wich FDO uses will be included here
814
include_debug_strings                           ; All data wich FDO uses will be included here
815
 
815
 
816
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
816
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling