Subversion Repositories Kolibri OS

Rev

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

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